Last night, I thought about the fact that the new display module I have been sent, with its driver circuitry, only uses 4 pins rather than the 12 I was expecting on the naked 4 digit LED. That means that I can connect the display module, the HC-SR04 ultrasonic sensor, AND the DS3231 RTC to the Uno all at the same time (and still have pins to spare). By shuffling things up a bit on my breadboard, I could fit the RTC module alongside the ultrasonic module, so that a) it has a semi-permanent home and I don't have to worry about it getting shorted out any more, and b) I can use the display for either the clock or the rainwater tank gauge just by reloading the required sketch. So I set to, and did just that.
Unfortunately, the combination of my poor eyesight, low light in the evening, and trying to line up small cables with small holes means - inevitably - I did something wrong - with style and panache! Actually, it turns out I did a couple of somethings wrong, but please, read on...
Eager to see if the RTC was still keeping time after a week in its little bag, I plugged it all in and reloaded my little clock sketch. Nothing... Zip... Nada! Well - what a let down. So, hoping I had simply dislodged a wire to the display, I reloaded the tank gauge sketch as a test, but that worked OK. I tried the clock again, but still nothing. So it must be the RTC wiring or the RTC itself
I decided to pull out the RTC and the DuPont cables to it and start again. I grabbed the RTC and burned my thumb on the battery - it was very hot! I figured this meant I had a power problem and quickly found that I had reversed the Vcc and GND connections to the RTC board... I'm really surprised I hadn't buggered up everything else on the breadboard - my Uno included!
Anyway - I removed the battery and let everything cool down and swapped the connections back the way they should be, then tried again. This time, the display came back to life (whoopee!), but I was a little disappointed and somewhat surprised to see the time was 13:65!
I guess that just maybe, reversing the polarity and almost setting fire to the module may have had a slightly adverse affect on the data - possibly - so I reloaded the set time sketch, reset the time and tried again. It was still showing 13:65 - weird... Uh oh - I started to get that feeling of dread again - you know, the one I got just seconds after hitting the button to buy a Pro Mini that I realised I knew nothing about..? After the first RTC I bought being DOA, perhaps I've now killed this RTC as well.
I reloaded the tank gauge sketch, just to make sure I hadn't fried the Uno as well, but that seemed to be working OK. I tried the clock once more - and the time was still 13:65 - DAMMIT! What was worse, was that the time display seemed static - even after 5 minutes (carefully keeping an eye on the temperature of the battery), it was still apparently 13:65 - I kind of hoped it might tick over each minute and show 13:70.
Well - I had removed and reseated the RTC module, and the Vcc/GND wires had been swapped, but I hadn't touched the SDA and SCL cables yet... Yes, you've guessed it - I had them round the wrong way too! Good grief, just how much wronger (yes - its a word) could I possibly have got this? After swapping those two around, and running the set sketch again, the display finally shows the correct time. Just to make sure, I pulled the rest of the clock data (YYMMDD, DoW, and hhmmss) and displayed them on the Serial console - phew - all seems ok. I haven't destroyed the chip after all, despite my best efforts. Mind you, having abused the battery like that, I'm not sure how long that is going to last now. It has kept the RTC going for around 24 hrs at the time of writing this, and the time is still correct to within about a second. I'm just counting my blessings, and vow that I am not going to touch that module again until it goes into its permanent home on my portable workbench.
Lesson learned? Accept that I'm getting older and my eyesight ain't what it used to be. Don't struggle in dim light where you can't see the difference between a grey and lilac cable, or manage to line up the red and black cables with the appropriate pins on the Uno... TURN SOME LIGHTS ON!
An introduction to basic elctronics, and designing circuits and programs to be used with an Arduino microcontroller board such as the Arduino Uno. Learn with me as I take things apart, investigate, research, and gradually build my own knowledge.
Showing posts with label PCF8574. Show all posts
Showing posts with label PCF8574. Show all posts
Thursday, 9 November 2017
Monday, 19 June 2017
Finally... I have a display module
Yes, it has finally arrived today. Just 9 weeks after I ordered it - and guess what? According to the shipping reference on the label, it IS the original, not the replacement! So you never know - in another 4-6 weeks, I could end up with a second display after all!
Of course, the first thing I was tempted to do after connecting it up, was to run my thermometer sketch, but I'm glad I didn't, as I would have been very upset when it didn't work. Thankfully, I remembered to run the I2C scanner sketch first, and yes - my I2C backpack has the 'AT' variant of the control chip I mentioned in the previous post, so the unit address is 0x3F, not 0x27. In the picture, you can also see the three sets of alternate address pads.
So, then I loaded up my sketch, changed the address in the LCD declaration to 0x3F, and fired it up. The backlight came on, but nothing else, so I twiddled the potentiometer on the backpack (the blue box thing in the image above, which controls the contrast of the screen), and up came my min/max display, just as I imagined it. Obviously, it had garbage figures, because in my impatience, I hadn't bothered to connect it up to the breadboard with the LM35, so the analogReads on pin A0 were getting random floating values - but it was enough just to prove the display works.
Now I have connected it up properly, and found a few bugs in my code, so I spent this evening debugging my theory, and adding a new feature.
The first thing I noticed was that the 5 minute average figure was always the same as the current reading. I added a few Serial.print lines to show all the values used in my calculations, and found that the counter was always 1. This led me to the conclusion that the problem must be in the reset area, which is only supposed to run every 5 minutes, but appeared to be running every loop.
The code looked fine except there was something niggling me about the IF statement having a calculation in it... The line read
if (fiveMinCount >= ((5 * 60 * 1000) / loopPeriod))
Now, I've come across this somewhere before, but can't remember why or where... I changed the (5 * 60 * 1000) to just read 300000 instead, and the average calculations started working properly - so it appears that IF statements don't like their mathematical comparisons to be too complicated.
The other little change I made was inspired by a similar kind of project I saw in a youtube tutorial by Martin Lorton, who made a very similar looking current/max/min type display for an Arduino based voltage meter. He added a function that showed an asterisk next to the max/min values when they changed, and also flashed an LED. He suggested you could also use a piezo transducer and the tone command, to make a little beep. I didn't go that far, but did add the asterisk, and flash the little onboard LED. Here is the code that does that...
Obviously, this code is repeated for the new LOW value as well.
We also need to declare an int variable called led and assign the number 13 to it, then declare the pinmode as output at the beginning of the sketch, and also turn the led OFF at the end of each loop.
So finally, after a couple of months of planning, theorising, pontificating, researching, and changing my mind countless times, here is the actual thermometer working as planned. Sorry I didn't get a picture with the asterisk and LED indicating a new Max or Min figure.
My next plan is to mount all this stuff onto a board, so I have a proper little test bed. Unfortunately, the display does not work from 3.3v, and the I2C interface pin breakout set on my Arduino only offers 3.3v, so I'll have to think how to connect the display to the Arduino semi-permanently once mounted on the board. But that's a problem for another day. I'm off to bed know, and will leave my thermometer running to see just how cold it gets in my lounge overnight...
...and I know what I said, but I can feel a fridge/freezer experiment coming on 😀
Of course, the first thing I was tempted to do after connecting it up, was to run my thermometer sketch, but I'm glad I didn't, as I would have been very upset when it didn't work. Thankfully, I remembered to run the I2C scanner sketch first, and yes - my I2C backpack has the 'AT' variant of the control chip I mentioned in the previous post, so the unit address is 0x3F, not 0x27. In the picture, you can also see the three sets of alternate address pads.
So, then I loaded up my sketch, changed the address in the LCD declaration to 0x3F, and fired it up. The backlight came on, but nothing else, so I twiddled the potentiometer on the backpack (the blue box thing in the image above, which controls the contrast of the screen), and up came my min/max display, just as I imagined it. Obviously, it had garbage figures, because in my impatience, I hadn't bothered to connect it up to the breadboard with the LM35, so the analogReads on pin A0 were getting random floating values - but it was enough just to prove the display works.
Now I have connected it up properly, and found a few bugs in my code, so I spent this evening debugging my theory, and adding a new feature.
The first thing I noticed was that the 5 minute average figure was always the same as the current reading. I added a few Serial.print lines to show all the values used in my calculations, and found that the counter was always 1. This led me to the conclusion that the problem must be in the reset area, which is only supposed to run every 5 minutes, but appeared to be running every loop.
The code looked fine except there was something niggling me about the IF statement having a calculation in it... The line read
if (fiveMinCount >= ((5 * 60 * 1000) / loopPeriod))
Now, I've come across this somewhere before, but can't remember why or where... I changed the (5 * 60 * 1000) to just read 300000 instead, and the average calculations started working properly - so it appears that IF statements don't like their mathematical comparisons to be too complicated.
The other little change I made was inspired by a similar kind of project I saw in a youtube tutorial by Martin Lorton, who made a very similar looking current/max/min type display for an Arduino based voltage meter. He added a function that showed an asterisk next to the max/min values when they changed, and also flashed an LED. He suggested you could also use a piezo transducer and the tone command, to make a little beep. I didn't go that far, but did add the asterisk, and flash the little onboard LED. Here is the code that does that...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // if "Temp now" is a new high... if (celsius > maxTemp) { //store current value as new high maxTemp=celsius; // and change value on display lcd.setCursor(12,1); if (maxTemp < 10) lcd.print("0"); // Add leading 0 if < 10C lcd.print(maxTemp,1); lcd.setCursor(19,1); lcd.print("*"); digitalWrite(led,HIGH); } else { lcd.setCursor(19,1); lcd.print(" "); } |
We also need to declare an int variable called led and assign the number 13 to it, then declare the pinmode as output at the beginning of the sketch, and also turn the led OFF at the end of each loop.
So finally, after a couple of months of planning, theorising, pontificating, researching, and changing my mind countless times, here is the actual thermometer working as planned. Sorry I didn't get a picture with the asterisk and LED indicating a new Max or Min figure.
My next plan is to mount all this stuff onto a board, so I have a proper little test bed. Unfortunately, the display does not work from 3.3v, and the I2C interface pin breakout set on my Arduino only offers 3.3v, so I'll have to think how to connect the display to the Arduino semi-permanently once mounted on the board. But that's a problem for another day. I'm off to bed know, and will leave my thermometer running to see just how cold it gets in my lounge overnight...
...and I know what I said, but I can feel a fridge/freezer experiment coming on 😀
Monday, 12 June 2017
I2C and Multiple Devices.
It's been a while since my last post, and since I did anything much with the Arduino too. Unfortunately, I had to go on a 'short' business trip that went wrong and ended up doubling in length. While I was away, I know that two more of my component purchases have turned up from China, so I am hoping that one of them is my long lost LCD display. I'll find out when I get into work in the morning.Talking of the LCD display, I started wondering - what if I end up with both the original AND the replacement arriving, would it be possible to use them both at the same time ? So I started investigating...
The answer is "YES". The IIC (I2C) interface mechanism allows for this by sending instructions out on the I2C interface bus along with the address that is related to the specific device the instruction is meant for. So you can have many different devices attached to the I2C bus - they don't even need to all be the same type - and as long as each has its own 'address', then each will see its own instructions.
Think of a mailman walking down the road, dropping off letters to each house... Dr Jones at number 10 only gets his own post, and not the post for Mr Smith at number 19 (well, as long as the postman is doing his job properly). This analogy is near enough, but not quite accurate - and because I am a pedant, this is how the mailman analogy has to be changed... He walks down the street (I2C interface bus), and goes to house (device) number 1. Mr Andrews from number 1 comes out and checks through the mailbag to see if there is any mail (data instruction) with his address on it. If there is, he takes it, and the mailman moves on to number 2. Mrs Brown from number 2 comes out and checks through all the mail to see if there is any with her address, then the mailman goes to see Mr Connor at number 3, Miss Davies at number 4, Mrs Edwards at number 5, and so on all down the street. Each person has the chance to look and see if there is mail for them, regardless of whether there is or not.
I used the word 'bus' just now - and since I didn't mean a bus to take you to work (though the concept is kind of appropriate), maybe I should explain? In electrical terms, a bus is a single long common electrical contact that several devices or components can be connected to. Your breadboard probably has +ve and -ve strips that run all the way down the edge - these are examples of an electrical bus. A device interface bus is similar in concept (and relies on the same electrical principal). The I2C interface bus consists of just 4 connections (+ve and -ve obviously, a clock line that carries timing signals, called SCL, and then the actual data line, called SDA, that actually carries the address and instructions). These 4 connections go from the Arduino to device one, then to the next device, and the next device, and so on. So, not only could I have 2 LCDs, it seems I could have 8!! In fact, I could have up to 127 different devices, as long as I was able to give each one a unique address - but there are some limiting constraints - read on.
Here's a picture I found during my investigations, of 8 LCD displays all connected to a single microcontroller (not an Arduino family unit though) and all showing something different, and an article from 'Embedded Lab' about it (that explains it all much better than me). You can see the 4 wires that form the bus, visiting each device in turn, but delivering only the instructions relevant to that particular device.
It looks as though every device that has an I2C interface, has a controller that defines a base address BUT... note that each type of device could potentially use a different controller that has been programmed with a different base address, such as the I2C Real Time Clock (RTC) module DS1307, which has a default base address of 0x68..
When you purchase them, by default every device of that type, with that controller, will have the SAME address. When you look at Arduino code samples for an I2C LCD display, for example, you will probably see a line of code that looks something like...
LiquidCrystal_I2C lcd(0x27,16,2);
...where LiquidCrystal_I2C is the name of the external library of commands; lcd is the object reference you will use in your sketch; 0x27 is the address of the LCD device; and 16,2 is the number of characters and lines.
By the way, the 0x prefix indicates the number is in hexadecimal (base 16), so the value 255 in hexadecimal would be 0xFF. I am not really sure why the convention is to use hexadecimal values for the interface addresses - but it is - so get used to it...
Since the 16x2 LCD is such a common device, and they mostly tend to use variants of the PCF8574 controller, then you're on a fairly safe bet that 0x27 will be the correct base address. However, some versions of the PCF8574 - (the AT for example, I think), use different addresses such as 0x3F, or they may even use completely different controllers, which also may not use that address. A quick look at the various Arduino and other electronics forums, will reveal that many many people seem to have problems with addressing, when they get LCD 16x2 units that do NOT have that base address - maybe it is due to cheap clone devices from China, that have to be slightly different so as to avoid copyright infringements? Worry not dear reader, one of the sample sketches that comes with the LiquidCrystal_I2C library, is a scanner that will locate any I2C devices attached to your Arduino, and show you the address they are using.
So it looks relatively easy to use a single LCD device, even if it's base address isn't 0x27... but what about if we want to use 2 (or 8) LCD devices? How do we change that 0x27 base address, to something that is unique per device? Well, you are going to have to get your soldering iron heated up, for a start... If you look carefully at the I2C interface board, you should see 3 pairs of solder pads, or jumper pins, that are labelled A0, A1, A2, or something similar.
If you know anything about binary, you will probably recognise that a 3 bit binary number can hold the values 0 to 7 in decimal - which is 8 different numbers. This is what gives us our potential for 8 different addresses. The number given by these three connections (all open by default - e.g. value = 000) is added to the base address of the controller, and this in turn gives us 8 possible unique addresses that we could use. For example, add a blob of solder across the A0 contacts, and your binary number is now 001 (1), which would give this device an address of 0x28 instead of 0x27. The image above is from an Adafruit article about changing I2C addresses, that you may want to look at.
So - if I do end up with both LCD units arriving, I will certainly be giving this a go... Look out for a sketch with...
LiquidCrystal_I2C lcd1(0x27,20,4);
LiquidCrystal_I2C lcd2(0x28,20,4);
😁
Joke for the day
There are 10 types of people in the world...
Those that understand binary, and those that don't
😁
Joke for the day
There are 10 types of people in the world...
Those that understand binary, and those that don't
Subscribe to:
Posts (Atom)



