Practical Guide to PCF8574: Adding Extra Pins for Arduino

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
when I started this channel one of the very first popular videos was this one about shift registers a lot of people watched it and quite a few of them liked it but one person wrote me a following comment make your life easy use pcf8574 instead it made me feel silly for a while for two reasons the first one nobody likes to be criticize and the second one I didn't have a freaking clue which electronic part is he talking about after doing the investigation I realized that he is talking about I Square C IO exander I immediately bought it on AliExpress got it put it in a drawer where it was sitting for close to 2 years now and I think it's high time to do a tutorial on it if this is a Content that you're interested in Stick [Music] [Applause] [Music] Around now let's take a closer look at the io expander you can obtain it as a standalone chip or you can do what I did and get the expander module which is essentially a breakout board for this chip you can see it here in the SMD version let's go through the pin out or the expander for both variants starting with Arduino connectivity you can power the expander by connecting VCC and ground to the Arduino 5 volt and ground pins next we have two I Square connections for data and clock that we connect to Arduino pins A4 and A5 then we have three pins used to set the address of the expander in the module version this corresponds to three jumpers that we can use to set up the address following that we have eight IO pins p 0 to p7 and finally there is an interrupt pin I will cover how to use it later on the expander modules can be Daisy chained using these female header pins let's take a closer look at selecting the address for the expander in the pinout section I discussed the three pins jumpers used for this purpose I will now connect the expander to Arduino by connecting VCC ground and I Square C pins to Arduino pins A4 and A5 the address of our module is comprised of three common prefix bits followed by bits defined by the state of our three jumpers additionally there is one more bit that defines two complementary addresses for read and write operations when this bit is set to zero we end up with the address for writing and if it is one we get the address for reading I don't believe we need those complimentary addresses when writing Arduino sketches just sticking to the address defined by the six bits only let's examine our example currently all three jumpers are set to zero so we have three common bits plus three zero bits giving us the address of 20 hex if we want to write address we attach zero at the end resulting in the address of 40 hex for the read address we attach one at the end giving us 41 hex this way we can populate the rest of the table as I'm not certain which jumper is which we can confirm it by running the ice sarec scanner you can download the code from this address the scanner scans I Square C bus and reports any connected I Square C modules currently our jumpers are in a position 00 0 and we would expect to see the address of 20 he let's load the scanner onto Arduino and as you can see the module is properly reported now let's switch the bottom jumper to one assuming it should be the least significant one a z after running the scanner again we should see the address of 21 and indeed I was correct I Square C devices connect to the I Square C bus where they are identified by their unique address for the Arduino Uno I Square C devices can be connected to analog pins A4 and A5 where A5 is a clock and A4 is a data pin here is our IO expander let's connect pin to the clock line and the SDA pin to the data line of the I Square C bus with all address jumper set to zero it has address of 20 if the eight extra pins provided by this module are not enough we can add another one and connect it to the I Square C bus in the same way however a problem arises there is an address conflict as it also has an address of 20 this problem can can be resolved by toggling the first jumper to one this way we change the address to 21 these IO expanders can coexist on the I sarec bus with other devices such as this OLED display here we can daisy chain these uh IO expander modules by connecting subsequent modules using female header pins for power and I Square C connectivity each time we need to make sure to assign a unique address to the new module we need a dedicated library to work with this type of expander there are a few different options available online but I opted for this particular one when you open the GitHub link you will be able to download the zip file containing the library in the Arduino IDE you can then open the zip file and the library will be installed like any other Library it comes with a variety of examples that provide plenty of information on different ways you can utilize this IO expander let's demonstrate how to use the io expander to control an LED in a sample Arduino sketch I'll start with a standard blink sketch and then extend it to make two LEDs blink one connected to the Arduino and the other one to the expander for this demonstration we'll be using Arduino Uno the expander will be powered from the arduino's 5vt and ground pins and connected to the I Square cbas through pins A4 and A5 the LED we want to control is a lilyt LED which is often used in my videos due to its built-in current limiting resistor making the wiring simpler to enable blinking for this led we'll connect cathode to Arduino ground and anode to digital pin 3 in this setup the standard blink sketch would look like this first we Define LED pin in the setup function we configure this pin as an output and in the loop we toggle the signal to turn the LED on and off with a 1 second delay between each state change let's end to the microcontroller and voila LED is blinking now let's add one more led into the equation this time we'll connect the cathode to Arduino ground and the anode will go to the P0 pin on the expander to make both LEDs blink interchangeably we will need to make specific changes to the code we need to declare two libraries one of which is the one we have just installed then we declare the io expander available at address 21 on the I Square C bus additionally we Define one more LED pin this time on the expander in the setup we initialize the expander module and Report both success or failure in the serial monitor here we also configur the second LED pin as output please note that the command looks similar to the one We R R for the first pin with the only difference being pcf8574 prefix in the loop we add lines that will toggle the signal on the P0 pin we do it in a way that this led will blink interchangeably with the first one again we need to use the PCF 8574 prefix in this section let's load this code onto the Arduino and well the good thing is that it works the downside is that LED connected to the expander is less bright after reviewing the data sheet I realized that the expander cannot draw sufficient current to fully illuminate the LED however Arduino can currently we have connected the LED's cathode to Arduino ground and the anode through a current limiting resistor to the expander P0 pin what if we disconnect the LED from the Arduino ground turn it around and connect the anode through the current limiting resistor to Arduino 5 Vols while connecting the cathode to expander spin P0 this way we would be drawing current from Arduino obviously to change the logic here now we would turn on the led by providing low signal at the P0 pin and vice versa let's load the code to Arduino and see if it makes any difference and indeed it does the LED is now nice and bright and with the changed logic it blinks together with the other one okay so we were able to control a single LED from the io expander if we make it seven LEDs then we can try to control seven segment display in the setup we have the expander connected to Arduino in the same manner as previously then we connect expander pins P1 to p7 to the segment pins of the display the common anode pin of the display is connected through the 220 Ohm resistor to 5 volts drawing current from Arduino in the past I created a tutorial on how to control a seven segment display from Arduino let's use the code from that video as a basis here's the table storing segment States for each digit and a function that extracts those States and sends them to appropriate pins first we need to adjust display digit function to send information to expander pins instead of Arduino I won't show the entire code here I skipping lines like Library declarations expander declaration and initialization for the entire code check the link in the description of this video I will just show the assignment of expander pins to the segment pins of the display all these pins must be declared as output then in a loop we have a simple for Loop that executes display digit function for digits from 0 to 9 in 1 second intervals let's send this code to the microcontroller and see if it works and it does so far we are only looking at expanding the number of output pins with the expander let's configure a single pin to be the input pin and try to connect a push button to it and with this push button try to control our seven segment display let's edit in our setup one side of it will be connected to the P0 pin of the expander and the other one will be connected to Arduino ground when using the pens as inputs the pin are set to High by the MCU which turns on the pullup to VCC okay what changes do we need to make to the code let's label the P0 pin as button and set it to input we can also set it to input pullup I think in this scenario there is no difference as input pins are always pulled up to 5 volts there is one important detail though you have to declare the expander pins as input before initializing the expander otherwise this would not work we need to change the loop function we store the value read from the button pin to a variable and if the value is low we increment I variable so the next time the loop function is run the next digit in line will be displayed if we go beyond nine we reset I back to zero we keep the delay of 1 second let's load the code to the microcontroller and observe the result it works but it is clear that the seven segment display reacts to the button press with a delay and at times it does not react at all this issues are caused by the use of delays in your code clearly this is not the optimal way to program such functionality this is where interrupts come into play the the expander offer just one interrupt pin that handles changes on a single or multiple pins which are set as an input let's connect this interrupt pin to the Arduino interrupt pin D2 in the code we start by declaring libraries first then we label the Arduino interrupt pin we want to use which in our case will be digital pin 2 here is a peculiar line of code the Declaration of the interrupt service routine without any Associated code afterwards we declare the i s c expander similar to what we did in the previous code but now we need to do it differently in this case we also specify the Arduino interrupt pin to which the expand interrupt pin will be connected along with the interrupt service routine to execute when a change on any of the expander input pins is detected here is an integer variable that will hold the current digit to be displayed on the seven segment display next we label all seven pins of the expander corresponding to the seven segments of the display and one pin that will be used to connect to the button in the setup we configure seven pins as output and one as input and only then initialize the expander the display digit function remains unchanged in the loop we only execute the display digit function for the current value of the I variable now there is another peculiar moment where we declare the interrupt service routine again this time with specified code to be executed in our case we increment the I variable and reset it back to zero when it surpasses nine let's check if this code would work and more importantly if it would work better than the one from the previous example it does work but the button is super sensitive so with one press we jump through several digits but this is the problem we can easily fix by introducing a simple button The Bouncing me method let's introduce a variable that will hold the time stamp of the button press in the setup we populate this variable with M now in the ISR all we need is a simple condition that checks the time stamp against the current value returned by mes the ISR will be executed only if 300 milliseconds have passed since the previous button press after incrementing the I variable we update the time stamp variable with the current value returned by mes which becomes the Tim stamp of the most recent button press it is possible to use the interrupt to serve several input pin when the state of any of the pins p 0 to p7 changes the PCF 8574 will generate an interrupt on the int pin the microcontroller can then read the current state of the input pins to determine which pin cost the interrupt let's upload the code to the Arduino and see if it makes any difference as you can see it does now when I press the button it results in immediate change of the digit shown on the seven segment display so we managed to control this display without exhausting they available Arduino output pins this concludes this video I don't know whether you notice but I'm getting close to 10,000 subscribers I virtually need 400 more so if you're watching my content and not yet subscribed please do so and help me to Cross this line I will see you guys in my next video [Music] [Applause] [Music] ciao
Info
Channel: Mario's Ideas
Views: 4,612
Rating: undefined out of 5
Keywords: arduino, PCF8574, io expander, 7 segment display, interrupts, extra pins, input pins, output pins, tutorial, how to, instructable, arduino programming
Id: HtX2o0UQelI
Channel Id: undefined
Length: 16min 46sec (1006 seconds)
Published: Sun Feb 04 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.