Giter VIP home page Giter VIP logo

xreef / pcf8575_library Goto Github PK

View Code? Open in Web Editor NEW
45.0 5.0 18.0 2.03 MB

i2c 16bits digital expander with i2c digital expander for Arduino, Raspberry Pi Pico and rp2040 boards, esp32, SMT32 and ESP8266. Can read write digital values with only 2 wire. Very simple and encoder support. Uncommet NOT_SEQUENTIAL_PINOUT define to have pins like datasheet and not sequential one.

License: MIT License

C++ 93.92% C 6.08%
arduino arduino-library esp8266 esp32 library i2c expander 16bit pin digital

pcf8575_library's Introduction

Support forum pcf8575 English
Forum supporto pcf8575 italiano

###Additional information and document update here on my site: pcf8575 Article.

###If you need less pins here you can find pcf8574 discrete 8bit version of the IC.

Library to use i2c analog IC with arduino and esp8266. Can read and write digital value with only 2 wire (perfect for ESP-01).

Tutorial:

To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder PCF8575. Check that the PCF8575 folder contains PCF8575\\.cpp and PCF8575.h. Place the DHT library folder your <arduinosketchfolder>/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.

Reef complete PCF8575 PCF8575AP digital input and output expander with i2c bus.

I try to simplify the use of this IC, with a minimal set of operation.

PCF8575 address map 0x20 default

Constructor: you must pas the address of i2c (to check the adress use this guide I2cScanner)

	PCF8575(uint8_t address);

for esp8266 if you want specify SDA e SCL pin use this:

	PCF8575(uint8_t address, uint8_t sda, uint8_t scl);

You must set input/output mode:

	pcf8575.pinMode(P0, OUTPUT);
	pcf8575.pinMode(P1, INPUT);
	pcf8575.pinMode(P2, INPUT);

then IC as you can see in the image have 8 digital input/output:

PCF8575 schema

So to read all analog input in one trasmission you can do (even if I use a 10millis debounce time to prevent too much read from i2c):

	PCF8575::DigitalInput di = PCF8575.digitalReadAll();
	Serial.print(di.p0);
	Serial.print(" - ");
	Serial.print(di.p1);
	Serial.print(" - ");
	Serial.print(di.p2);
	Serial.print(" - ");
	Serial.println(di.p3);

To follow a request (you can see It on issue #5) I create a define variable to work with low memori device, if you decomment this line on .h file of the library:

// #define PCF8575_LOW_MEMORY

Enable low memory props and gain about 7byte of memory, and you must use the method to read all like so:

   byte di = pcf8575.digitalReadAll();
   Serial.print("READ VALUE FROM PCF: ");
   Serial.println(di, BIN);

where di is a byte like 11100011110001, so you must do a bitwise operation to get the data, operation that I already do in the "normal" mode, here an example:

   p0 = ((di & bit(0))>0)?HIGH:LOW;
   p1 = ((di & bit(1))>0)?HIGH:LOW;
   p2 = ((di & bit(2))>0)?HIGH:LOW;
   p3 = ((di & bit(3))>0)?HIGH:LOW;
   p4 = ((di & bit(4))>0)?HIGH:LOW;
   p5 = ((di & bit(5))>0)?HIGH:LOW;
   p6 = ((di & bit(6))>0)?HIGH:LOW;
   p7 = ((di & bit(7))>0)?HIGH:LOW;

if you want read a single input:

	int p1Digital = PCF8575.digitalRead(P1); // read P1

If you want write a digital value you must do:

	PCF8575.digitalWrite(P1, HIGH);

or:

	PCF8575.digitalWrite(P1, LOW);

You can also use interrupt pin: You must initialize the pin and the function to call when interrupt raised from PCF8575

	// Function interrupt
void keyPressedOnPCF8575();

// Set i2c address
PCF8575 pcf8575(0x39, ARDUINO_UNO_INTERRUPT_PIN, keyPressedOnPCF8575);

Remember you can't use Serial or Wire on interrupt function.

The better way is to set only a variable to read on loop:

void keyPressedOnPCF8575(){
	// Interrupt called (No Serial no read no wire in this function, and DEBUG disabled on PCF library)
	 keyPressed = true;
}

For the examples I use this wire schema on breadboard: Breadboard

Test pcf8575

pcf8575_library's People

Contributors

xreef avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pcf8575_library's Issues

create array of PCF8575

I would to declare an array of multiple PCF8575 devices within a struct, something like:

PCF8575 PCF[DEVICES];

Then, in another part of my code do something like:

PCF[0].digitalRead(PINNUM);

I cannot figure out how to do this with this library as it appears at minimum I need to assign an address with the constructor.

Any suggestions would be greatly appreciated.

Thanks.

how to set pin mode

Hi,

From datasheet, I only figured out if I want to set a pin (e.g P17) to output LOW, I can use I2C to write 3 bytes as the following:
0100 A2A1A00
0xxx xxxx
xxxx xxxx

Is it correct? But I cannot figure out how to set P17 to output mode.

Esp32 - changing pins

I am trying to add a PCF8575 (well actually a PCF8574) to an esp32cam . But should be the same...
(note I am a little new at this...)

I am trying to map to different pins for the SDA and SCL - since the esp32cam SDA and SCL pins are not avaialbe. But I believe I should be able to map them to most any pin.
But can't make it work.

I wanted to change pins for the SDA and SCL on an esp32.
I wanted to use pins 27 and 14 for an esp32 for testing (but really I wanted this for an esp32cam using pins 12 and 2).

I tried using the wire.h library and the PCF8574 lib...but for some reason it keep son forcing pins 21 and 22 as the SDA and SCL...and I did read that I need to sort out the .cpp files to make sure it is not being forced to set SDL and SCL pins... on this tutorial https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/ but I have no clue how to do that!!

And I see on a different sensor - the libraries will allow you to change pins...with the twowires...

"In those cases, you need to take a closer look at the .cpp library files and see how to pass your own TwoWire parameters." https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/ . But I cannot figure out how to do this...

For testing I was using the code below.

using I2C scanner I get address for PCF as 0x38
running below sketch - SDA and SCL are still using pins 21 and 22 ...and it works - the LED blinks on/off using pins 21 and 22...

But pins should be mapped to 27 and 14....
How to fix??
Can you update library to allow mapping?? Or am I doing something wrong?
Thanks!


#include "Wire.h"
#include "Arduino.h"
#include "PCF8574.h"

TwoWire I2Cone = TwoWire(0);

PCF8574 pcf8574(&I2Cone, 0x38);

(note your tutorial it think it has typo... line 39 >> PCF8574 pcf8574(&I2Ctwo, 0x20); >>> I think it should be PCF8574 pcf8574(&2Ctwo, 0x20); ) Your editor is added letters...

void setup(){

Serial.begin(115200);
delay (100);

I2Cone.begin(27,14,100000);

// Set the pinModes
pcf8574.pinMode(P0, OUTPUT);
pcf8574.pinMode(P1, OUTPUT);
pcf8574.begin();
}

void loop(){
pcf8574.digitalWrite(P0, HIGH);
pcf8574.digitalWrite(P1, LOW);
delay(1000);
pcf8574.digitalWrite(P0, LOW);
pcf8574.digitalWrite(P1, HIGH);
delay(1000);
}

Keypress Wiring Not registering low

Hi,
I tried the keypress on a switch button and followed the wiring on your home page.
I then used the code here https://github.com/xreef/PCF8575_library/blob/master/examples/keyPressedPin1/keyPressedPin1.ino
I am using an ESP32 and it actually does not work for me.

If I removed the 10K pull-down resistor connected to the ground then it now work.
I brought out my tester and I noticed that when the switch is open the reading at the P1 pin is around 4.2V (HIGH) but when I pressed the button it goes down to 3.9V which still registers as a HIGH which is not registering a LOW.

I tried removing the 10K resistor and everything is ok?

Can you comment on this or if the wiring is correct? Or I could be missing some setup on my end. Thank you.

Digital write on ESP32 with I2C 16,17

I have the digitalread on all pins working on my esp32, I followed the example but is not working. When I measure the pin to ground it stays low on digitalwrite.

This is the expansion board I am using
2022-01-24_004035

I have solderd vcc to vdd (for not using the voltage regulator)
2022-01-24_004205

In the library I did

#define NOT_SEQUENTIAL_PINOUT

#include <PCF8575.h>
#include <Wire.h>

TwoWire I2Cone = TwoWire(0);
//TwoWire I2Ctwo = TwoWire(1);
PCF8575 PCF(&I2Cone, 0x20, 16,17);

void setup() {
	Serial.begin(115200);
	while (!Serial);
	//PCF.pinMode(P00, INPUT);

	I2Cone.begin(16, 17, 400000); // SDA pin 16, SCL pin 17, 400kHz frequency

	for (int i = 0; i < 8; i++) {
		PCF.pinMode(i, OUTPUT);
	}
	
	//PCF.begin(16, 17);

	PCF.begin();

	write();
}
void loop() {
	delay(1000);
	//read();
}
void read() {
	Serial.print("val: ");
	Serial.println(PCF.digitalRead(P00));
}
void write() {
	//PCF.digitalWrite(P07, HIGH);

	for (int i = 0; i < 8; i++) {
		PCF.digitalWrite(i, HIGH);
	}
}

pin labels

Hi, great libray, thank you!

PCF8575.h define device pins as P0 - P15, see lines 68 - 83 contain:

#define P0  	0
#define P1  	1
#define P2  	2
#define P3  	3
#define P4  	4
#define P5  	5
#define P6  	6
#define P7  	7
#define P8  	8
#define P9  	9
#define P10  	10
#define P11  	11
#define P12  	12
#define P13  	13
#define P14  	14
#define P15  	15

but in real world PCF8575 device pins are labeled P00 - P07 and then P10 - P17, would you consider changing the code to:

#define P00  	0
#define P01  	1
#define P02  	2
#define P03  	3
#define P04  	4
#define P05  	5
#define P06  	6
#define P07  	7
#define P10  	8
#define P11  	9
#define P12  	10
#define P13  	11
#define P14  	12
#define P15  	13
#define P16  	14
#define P17  	15

so P0 -> P00, P1 -> P01 .. P7 -> P07, then there is no P8 and P9, insted 8th pin is P10, 9th pin is P11, etc...

not sure if you'd want to commit to this change. Posting this in hopes someone will find this usefull as it may be confusing...

When I must use BEGIN

I have ESP32 and 2 PCF8575 like inputs + 2 PCF8575 like outputs on standart 21-22 SDA SSL.

`//Все GPIO могут быть настроены для обработки прерываний.
#define ESP32_INTERRUPTED_PIN1 2
#define ESP32_INTERRUPTED_PIN2 3

//адреса расширителей
#define addrIn1 0x20
#define addrIn2 0x21
#define addrOut1 0x22
#define addrOut2 0x23

// Function interrupt
void keyChangedOnPCF1();
void keyChangedOnPCF2();

bool keyChanged1 = false;
bool keyChanged2 = false;

PCF8575 in1(addrIn1, ESP32_INTERRUPTED_PIN1, keyChangedOnPCF1);
PCF8575 in2(addrIn2, ESP32_INTERRUPTED_PIN2, keyChangedOnPCF2);
PCF8575 out1(addrOut1);
PCF8575 out2(addrOut2);

//uint32_t click_st, dbl_st, hold_st; // переменные для текуших статусов входных сигналов

struct Button {
const uint8_t PIN;
bool pressed;
bool dbl;
bool hold;
};

unsigned long timeElapsed;

byte mac[] = {
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
};

void setup() {
Serial.begin(112560);

// Set pinMode to OUTPUT
for (uint8_t i = 0; i < 16; i++) {
in1.pinMode(i, INPUT);
in2.pinMode(i, INPUT);
out1.pinMode(i, INPUT);
out2.pinMode(i, INPUT);
}
//in1.begin(); //
//in2.begin();
//out1.begin();
//out2.begin();`

I need using *.begin 4 times or no need begin for esp32 and 21-22 SDA-SCL?

Request: initial pin state on begin

Any chance you can do the same fix you did here xreef/PCF8574_library#15 to the PCF8575 library ?
This would allow setting the pin state on .begin().

Currently I hacked the .cpp file on line 179 as follows:
uint16_t usedPin = readMode; //writeMode |
And this works (as per datasheet 0 on a write call sets the pin low) but have not fully tested it.

Forum issue

Hi there, your forum is apparently not accepting registrations... Is it still active?

digitalReadAll

Hi.
Why doesn't it work?
Am I making a mistake somewhere?

void loop()
{
pcf8575.digitalWrite(P10, HIGH);
int p10Digital = pcf8575.digitalRead(P10);
Serial.println(p10Digital);
PCF8575::DigitalInput di = pcf8575.digitalReadAll();
Serial.print(di.p10);
Serial.print(" - ");
Serial.print(di.p11);
Serial.print(" - ");
Serial.print(di.p12);
Serial.print(" - ");
Serial.println(di.p13);
delay(5000);
//---------------------------------------------------
pcf8575.digitalWrite(P10, LOW);
int p10Digital1 = pcf8575.digitalRead(P10);
Serial.println(p10Digital1);
PCF8575::DigitalInput di1 = pcf8575.digitalReadAll();
Serial.print(di1.p10);
Serial.print(" - ");
Serial.print(di1.p11);
Serial.print(" - ");
Serial.print(di1.p12);
Serial.print(" - ");
Serial.println(di1.p13);
delay(5000);
}

ser.monitor
1
0 - 0 - 0 - 0
0
0 - 0 - 0 - 0
1
0 - 0 - 0 - 0
0
0 - 0 - 0 - 0
1
0 - 0 - 0 - 0
0
0 - 0 - 0 - 0
1
0 - 0 - 0 - 0
0
0 - 0 - 0 - 0
1

They need to write the status P10 - P17 via the ser.monitor 00000000

DigitalWrite not work on ESP32

My code

PCF8575 pcf8575(0x20);

long in =0;
void setup() {

// put your setup code here, to run once:

pcf8575.pinMode(P0, OUTPUT);
pcf8575.begin();

pcf8575.digitalWrite(P0, HIGH);
in = millis();

}
void loop() {

if(Serial.available())
{
int valA = Serial.parseInt();
Serial.println(valA);

if( valA == 2){
pcf8575.digitalWrite(P0, HIGH);

}

Serial.flush();
}

if(millis() - in >= 1000){

// put your main code here, to run repeatedly:

uint8_t val =  pcf8575.digitalRead(P0);
if( val == LOW) {
  Serial.print("P0: ");
  Serial.print( "LOW");
 Serial.println();
 }

in = millis();

}
}

Although I write pcf8575.digitalWrite(P0, HIGH), it always prints LOW.

Ports as inputs not work at all

Hi,
First of all, thanks for all your hard work on this and the PCF8574. That one I use all the time with no problems. Recently, I tried to do the same things with the PCF8575. All the ports work as expected as OUTPUT like this:

void setup(){
    Wire.begin(SDA_GPIO, SCL_GPIO);

    for (size_t i = 0; i < 16; i++)
        pcf.pinMode(i, OUTPUT);

    for (size_t i = 0; i < 16; i++)
        pcf.digitalWrite(i, HIGH);

    pcf.begin();
}

void loop(){
    if (millis() - i2cMillis > 250)
    {
        for (size_t i = 0; i < 16; i++)
            pcf.digitalWrite(i, 1 - pcf.digitalRead(i));

        i2cMillis = millis();
    }
}

Awesome! But when I try to use the ports as input they fail miserably:

void setup(){
    Wire.begin(SDA_GPIO, SCL_GPIO);

    for (size_t i = 0; i < 16; i++)
        pcf.pinMode(i, INPUT);

    pcf.begin();
}

void loop(){
    PCF8575::DigitalInput di = pcf.digitalReadAll();
    SerialMon.printf("%u - %u - %u - %u - %u - %u - %u - %u\r\n", di.p0, di.p1, di.p2, di.p3, di.p4, di.p5, di.p6, di.p7);
}

resulting in this:

0 - 0 - 0 - 0 - 0 - 0 - 0 - 0

Looking at the circuit with an oscilloscope I can see that although all the pins are pulled up to 3.3V with a 10k resistor, the PCF8575 pulls them down constantly to Gnd.

I have already spent 2 days on trying to figure out what went wrong, but I'm stuck. Any idea what I'm missing?

Thanks for any pointers!

ps: my environment is Windows 11 64 bit, VS Code with PlatformIO. and this is the relevant bit of platformio.ini:

##################################################
#   ENVIRONMENT
##################################################

[env:esp32s3]
board = esp32-s3-devkitc-1

platform = espressif32
framework = arduino

##################################################
#   PRE-BUILD
##################################################
extra_scripts = 
    pre:../../scripts/preIncrementBuildNumber.py
    platformio_upload.py

##################################################
#   BUILD
##################################################

build_type = release

board_build.filesystem = littlefs

lib_deps =
    ; xreef/PCF8574 library @ ^2.3.6    
    xreef/PCF8575 library @ ^1.1.1


##################################################
#   UPLOAD
##################################################

upload_protocol = esptool
upload_port = COM5
upload_speed = 921600


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.