SainSmart 20 x 4 I2C - not resetting?

I'm at wit's end....

Using IDE 1.0.5. Arduino Uno R3

This is the device: http://www.amazon.com/gp/product/B00AE0FRDQ/ref=oh_details_o08_s00_i00?ie=UTF8&psc=1
However, the picture of the backpack isn't exactly the same. Mine has LCD2004 printed on the board.
The I2C expander is a PCF8574. Data sheet here: http://www.nxp.com/documents/data_sheet/PCF8574.pdf

This is the driver: https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home

This is the code:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

void setup()
{
     
  lcd.begin(20,4);               // initialize the lcd 

  lcd.home ();                   // go home
  lcd.print("Hello, ARDUINO ");  
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print (" FORUM - fm   ");
  delay ( 1000 );
}

void loop()
{
  
}

The pin assignment were verified with an ohmmeter (except for the backlight pin).

Display works fine after uploading code. After a power cycle it displays blocks on lines 1 and 3.

I've tried several drivers. The one listed above and this one: http://hmario.home.xs4all.nl/arduino/LiquidCrystal_I2C/ work similarly although I'm not sure how to control the backlight with the new liquid crystal driver.

The LCD is the only device connected. 5V to Vcc, Gnd to Gnd, A4 to SDA, A5 to SCL.

I have read numerous threads in this forum and they seem to point to driver issues.
http://forum.arduino.cc/index.php?topic=176457.0
http://forum.arduino.cc/index.php?topic=174860.0
http://forum.arduino.cc/index.php?topic=158312.0
http://forum.arduino.cc/index.php?topic=138674.0

The information here: http://web.alfredstate.edu/weimandn/lcd/lcd_initialization/lcd_initialization_index.html seems to describe my problem.....

Most of the people reading this are probably tinkering with an LCD module that is connected to a microcontroller and is powered by the same power supply that is powering the microcontroller. Let's assume the best case, where the power supply does satisfy the requirements for an internal reset of the LCD controller, and where the program in the microcontroller doesn't attempt to send any information to the LCD module until that internal reset is finshed. What happens when the the reset button on the microcontroller is pushed? Answer: The program code will run again, but the LCD module will not be re-initialized since it's power was never interrupted. Here's the problem: The program code contains a Function Set instruction, and this instruction should only be executed once, immediately after the LCD module is initialized. Well it already ran once, when the power was applied, and here it is running it again, after the reset button is pushed and the microcomputer code restarts. When this instruction is executed a second time the status of the LCD controller may be indeterminate or, in plain language, the LCD controller may stop responding.

Any help appreciated...

I've tried several drivers. The one listed above (https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
) and this one: http://hmario.home.xs4all.nl/arduino/LiquidCrystal_I2C/ work similarly although I'm not sure how to control the backlight with the new liquid crystal driver.

Both of those libraries appear to have a missing time delay and I am really surprised that the error slipped past fm since he has done such a conscientious job on his library.

There is a delay missing from the flowchart in the HD44780U datasheet and both library authors have therefore omitted that delay in their resulting code. The missing delay is after the three function set instructions that reset the controller (and in 4-bit mode the fourth one that switches modes) and just before the actual function set instruction that also sets the number of lines. The flowchart does clearly state that the busy flag can be read after the function set instruction, thus implying that it cannot be read before the instruction, but it omits showing the delay that is required in place of reading that flag.

If you look further down in the 'LCD Initialization' link you will see that I use a 100 uS delay at that point.

Don

Thanks for looking at this. I'm not sure how to add the delay you refer to. I do see it in your flowchart.

I gave the following a try:
Edit LCD.cpp in the ..\Arduino\libraries\LiquidCrystal
recompile and run the code above

Unfortunately I get the same result.

This is the edit I made (delays commented with "added"):

   // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
   // according to datasheet, we need at least 40ms after power rises above 2.7V
   // before sending commands. Arduino can turn on way before 4.5V so we'll wait 
   // 50
   // ---------------------------------------------------------------------------
   delay (100); // 100ms delay
   
   //put the LCD into 4 bit or 8 bit mode
   // -------------------------------------
   if (! (_displayfunction & LCD_8BITMODE)) 
   {
      // this is according to the hitachi HD44780 datasheet
      // figure 24, pg 46
      
      // we start in 8bit mode, try to set 4 bit mode
      send(0x03, FOUR_BITS);
      delayMicroseconds(4500); // wait min 4.1ms
      
      // second try
      send ( 0x03, FOUR_BITS );
      delayMicroseconds(4500); // wait min 4.1ms
      
      // third go!
      send( 0x03, FOUR_BITS );
      delayMicroseconds(150);
      
      // finally, set to 4-bit interface
      send ( 0x02, FOUR_BITS ); 
	  delayMicroseconds(150); // added
   } 
   else 
   {
      // this is according to the hitachi HD44780 datasheet
      // page 45 figure 23
      
      // Send function set command sequence
      command(LCD_FUNCTIONSET | _displayfunction);
      delayMicroseconds(4500);  // wait more than 4.1ms
      
      // second try
      command(LCD_FUNCTIONSET | _displayfunction);
      delayMicroseconds(150);
      
      // third go
      command(LCD_FUNCTIONSET | _displayfunction);
	  delayMicroseconds(100); // added
   }

-Russ

Read this post.

http://forum.arduino.cc/index.php?topic=186965.0

This is the edit I made (delays commented with "added"):

You put the delays in the correct locations so you have a different or an additional problem.

You obviously have the I2C configured with the correct address and on the correct pins but did you use external pull-up resistors? It's an outside chance that the internal ones may be on the borderline as far as size goes so I would try adding external pull-ups and see what happens.

Read this post.

There's four pages in that thread (so far) so could you point out which part might apply here?

Don

I tried 4.7k and 10k pullups. No difference.

@1ChicagoDave: After weeding through everything, I took two things from that thread. One is the driver used and the other is to power down the board periodically. I'm using the same driver as the OP finally used. My problem shows itself when powering up.

I have another UNO R3, same result. Using a 9V wall-wart didn't help either.

I've noticed that the pin13 led blinks in sets of 3 after a power up (with the test sketch above). However, when the display is working correctly there is no activity on that pin. Pin13 isn't used for I2C, right? Seems odd.

I don't have a scope or logic analyzer, but may use a problem with a $14 part to buy something. :wink:

-Russ

Try opening the serial monitor after you connect the Arduino to the USB port.
Sounds like it could be something wrong with the bootloader on the chip.

I took two things from that thread. One is the driver used and the other is to power down the board periodically.

You should have taken only one thing from that thread. If you have to power down the board periodically then something is wrong with the program or the display, most likely the program.

I've noticed that the pin13 led blinks in sets of 3 after a power up (with the test sketch above). However, when the display is working correctly there is no activity on that pin. Pin13 isn't used for I2C, right? Seems odd.

That's not odd at all and it could be a clue to your problem.

The Optiboot bootloader causes the LED on pin 13 to blink three times before it runs your program code. If it blinks in sets of three then there is something in your code that is causing the bootloader to run over and over again.

With a sketch that does not explicitly deal with pin 13 you should see no activity on the LED after the initial three blinks. This is the case when your display is working properly.

Don

Success!! So I hooked up another Uno R3 and the display comes up fine. It comes up with the same blocks in lines 1 and 3 and then re-initializes and works as expected.

I reported that I did this earlier, but I don't recall the exact state of the configuration at the time. I've changed so many things trying to get this thing working.

Thanks floresta Don and TheCoolest, you guys nailed it. I guess I'll try to burn a new bootloader onto the "bad" chip.

-Russ