Arduino freezes on lcd.begin()

Hi guys! Not sure if his is the correct subforum..

I am developing standalone special-purpose thermostat unit with ATMega328p-pu, programmed by pulling the chip out from socket into arduino, so I can't really use serial debugging etc...

I am using standard I2C adapter into 16x2 LCD display. I had to sniff the address (by modifying the SPI_CHECK, i was able to identify the DEC adress by reading number of LED blinks...), it was 0x3F instead of standard 0x20/0x27. So, the LCD is responding, backlight works and 1st row is full, just as it is supposed to do with no data. Yes, I played with the contrast pot..

But I got stuck somewhere in the initialisation, i found out that the micro freezes at the lcd.begin(16, 2), because the led blinks no more...

I will gladly provide any additional information, just to fix this, because I am running out of time a bit :stuck_out_tongue:

Here is the code - not completed, but working:

/*
 * Thermostat build 1
 * Calibrated: null
 * Maroš Macko 2016
 */

//Pin lookup
#define rLed  9
#define gLed  10 
#define button1  5
#define button2  6
#define button3  7
#define button4  8
#define buttonPress  3 // interrupt
#define ThermistorPIN1 A0
#define ThermistorPIN2 A1   //Read temperature
#define relay  A2 //A2

#include <math.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  //A5 - SCL

float vcc = 5;                          // only used for display purposes, if used set to the measured Vcc.
float pad = 9850;                       // balance/pad resistor value, set this to the measured resistance of your pad resistor
float thermr = 10000;                   // thermistor nominal resistance

float inT;
float ouT;
bool relayState = 0;
volatile byte manual = LOW;
                              
void setup() 
{ 
  delay(1000);
  
  //display
  gblink();
  lcd.begin(16, 2);
  rblink();
  lcd.backlight();
  gblink();
  lcd.setCursor(0, 0);
  rblink();
  lcd.print("  Thermostat v1");
  gblink();
  lcd.setCursor(0, 1);
  lcd.print(" by Maros Macko");
  delay(3000);

  
  //Pin setup
  pinMode(rLed, OUTPUT);
  pinMode(gLed, OUTPUT);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  pinMode(button3, INPUT_PULLUP);
  pinMode(button4, INPUT_PULLUP);
  pinMode(buttonPress, INPUT);
  pinMode(ThermistorPIN1, INPUT);
  pinMode(ThermistorPIN2, INPUT);
  pinMode(relay, OUTPUT);
    
  //Test flashes
  digitalWrite(rLed, HIGH);
  delay(500);
  digitalWrite(rLed, LOW);
  digitalWrite(gLed, HIGH);
  delay(500);
  digitalWrite(gLed, LOW);
  delay(500);

  //attachInterrupt(digitalPinToInterrupt(3), intmanual, FALLING);
  
}

void rblink()
{
  digitalWrite(rLed, HIGH);
  delay(200);
  digitalWrite(rLed, LOW);
}

void gblink()
{
  digitalWrite(gLed, HIGH);
  delay(200);
  digitalWrite(gLed, LOW);
}

void loop() 
{
  Sensors();
  if(manual = HIGH)
  {
    relayState == 1;
    digitalWrite(relay, HIGH);
  }
  else if(relayState == 0)
  {
    if((inT > 5) && (inT - ouT > 1.5))
    {
      relayState = 1;
      digitalWrite(relay, HIGH);
    }
  }
  else
  {
    if(inT < 3)
    {
      relayState = 0;
      digitalWrite(relay, LOW);
    }
    else if ((inT > 5) && (ouT - inT > 1.5))
    {
      relayState = 0;
      digitalWrite(relay, LOW);
    }
  }

  displayInfo();
  delay(5000); //(5s)
}

void Sensors() {
  inT = Thermistor(analogRead(ThermistorPIN1));
  ouT = Thermistor(analogRead(ThermistorPIN2));
}

void displayInfo()
{
  gblink();
  lcd.clear();
  //lcd.print("inT=".inT."°C ouT=".ouT."°C");
  lcd.setCursor(0,1);
  if(manual == HIGH) lcd.print("Vent: ON manual");
  else if(relayState == 0) lcd.print("Vent: OFF");
  else if(relayState == 1) lcd.print("Vent: ON");
  
  
}

float Thermistor(int RawADC) {
  long Resistance;  
  float Temp;

  Resistance=pad*((1024.0 / RawADC) - 1); 
  Temp = log(Resistance);
  Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  //K to C                    
  return Temp;
}

Thanks!

I am using standard I2C adapter . . .

There is no such thing as a standard I2C adapter.

. . . it was 0x3F instead of standard 0x20/0x27.

0x38/0x3F is just as standard as 0x20/0x27. It all depends on which chip the manufacturer happened to use in that 'standard' I2C adapter on that particular production run.

. . . LCD is responding, backlight works and 1st row is full, just as it is supposed to do with no data.

Actually the LCD is not responding. The backlight has nothing whatsoever to do with the LCD and your program has not progressed to the point where you turn it on. The single row of blocks indicates that the LCD controller has not been properly initialized so you probably are not even communicating with it. Where did you come up with the numbers for the constructor?

Does your standalone board include the required bypass capacitors for the ATMega328p-pu power pins?

Don

In addition to what Don already said, have a look at the following wiki, where you might identify your I2C backpack and the right constructor for it:

https://arduino-info.wikispaces.com/LCD-Blue-I2C

Sorry I was unclear, by standard I mean the most common one, using the PCF8547P and all the required stuff like SPI pull-ups, backlight control etc..

Well, by responding I mean that I was able to detect the SPI address, so something works I guess?

My board has got big electrolytic cap for filtering (10 000uF after diode rectifier and 220uF after 7805 together with 100nF), and then every IC has its own 100nF as close as possible to its VCC pins.

Not sure what numbers for which constructor you mean?

Edit: @rpt007 yes, judging that page I have "I2C LCD DISPLAY VERSION 1", matches 100% by the picture.

I am using newest LiquidCrystal library, and all other LCD libraries are removed, even the native, I am 100% sure on that.

Thanks

I am developing standalone special-purpose thermostat unit with ATMega328p-pu, programmed by pulling the chip out from socket into arduino, so I can't really use serial debugging etc...

Can you please provide a schematic and photograph of your board and setup with the i2c adaptor and lcd?

I believe that the sketch freezing at lcd.begin() with no rblink or gblink after the call is likely to indicate a problem on the i2c bus.

How did you determine the address of the i2c backpack?

had to sniff the address (by modifying the SPI_CHECK, i was able to identify the DEC adress by reading number of LED blinks...), it was 0x3F instead of standard 0x20/0x27

SPI_CHECK makes no sense for an i2c device.

You should be using this program modified to show blinks, and with the chip programmed to run it within the actual circuit.

// I2C Scanner
// Written by Nick Gammon
// Date: 20th April 2011

#include <Wire.h>

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

  // Leonardo: wait for serial port to connect
  while (!Serial) 
    {
    }

  Serial.println ();
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;
  
  Wire.begin();
  for (byte i = 8; i < 120; i++)
  {
    Wire.beginTransmission (i);
    if (Wire.endTransmission () == 0)
      {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);
      Serial.println (")");
      count++;
      delay (1);  // maybe unneeded?
      } // end of good response
  } // end of for loop
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");
}  // end of setup

void loop() {}

Wor3d,
The PCF8574 uses i2c not SPI. If the i2c bus is missing pullups all kinds of odd & strange things can happen including having the AVR chip i2c h/w and and/or Wire s/w library lock up.

Some backpacks have the pullups on them and some don't and while the Wire library turns on the AVR pullups attached to the SDA and SCL pins, they are too large and do not provide the proper pullup required by the i2c spec. In many cases i2c devices will appear to work without proper pullups, but in reality it is WAY out of spec and in some cases it doesn't work at all or causes very odd things to happen.

If the lcd.begin() is hanging, my guess would be that the i2c bus is missing the required pullups.

--- bill

Hi guys, sorry for the late reply.

Sorry I misworded myself, or better said, I had the I2C_CHECK test program saved as SPI_CHECK... my dumb mistake... I used Gammon's modified code to determine the address, the -60 is there just to confirm the address is really DEC 63 = 0x3F HEX - eliminate human mistake counting LED blinks :smiley:

Here is how I sniffed the address:

#include <Wire.h>

void setup() {

  pinMode(10, OUTPUT);
  digitalWrite(10, LOW);

  delay(3000);

  byte count = 0;
  
  Wire.begin();
  for (byte i = 8; i < 120; i++)
  {
    Wire.beginTransmission (i);
    if (Wire.endTransmission () == 0)
      {
      count++;
      delay (1);
      if(i>59) for(int j = i - 60; j > 0; j--) //dirty, but quick way me programming...
        {
          digitalWrite(10, HIGH);
          delay(1000);
          digitalWrite(10, LOW);
          delay(1000);  
        }
        if (i<60) for(int j = i; j > 0; j--)
        {
          digitalWrite(9, HIGH);
          delay(1000);
          digitalWrite(9, LOW);
          delay(1000);  
        }
        delay(3000); //delay possible multiple addresses on the SPI line (together with blinks below)
        for(int k = 10; k>0; k--)
        {
          digitalWrite(10, HIGH);
          delay(200);
          digitalWrite(10, LOW);
          delay(200); 
        }
        delay(2000);
      } 
  } 
} 

void loop() {}

@cattledog Sorry I cannot provide schematics nor good photos, because the display was a afterthought really, and I had luck that I wasn't using A5&A4 pins... I soldered mod wires directly on ATmega socket and PCF8574's pins, and tripple-checked the connections with continuity tester (and checked for shorts between lines, and to VCC/GND/near stuff), plus tripple-checked if I dont have SCL/SDA lines swapped. VCC and GND are also directly soldered, I measure spot-on 5.000V on the module while it is drawing current (decoupling only before the mod wires going to the module, but this really shouldn't be a problem...).

That said, THANKS for ALL the input, I will try to add additional pull-ups and a little tweak bill PMmed me with and will report back, prob tomorrow...

Good night :wink:

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

What's all this then?

Update on situation!

@INTP, not sure what do you mean...

I added other 10k pullups, didn't help... The board has its owh 4k7 pullups so I think that should be fine..
Then I disassembled the display to be able to troubleshoot more, and I was able to detect i2c display through serial - confirmed 0x3F. Everythings run smoothly, the LCD backlight is solid on and I see the "no connection" blank line. Display is drawing 3mA.

But, here are things getting weird... I upload the basic test check sketch from https://arduino-info.wikispaces.com/LCD-Blue-I2C and change the address to 0x3F and remove the backlight flash loop (You'll se why). After arduino reset I am not able to see anything in the serial and after a second or two the backlight turns off and the back power LED seems to be very very dimmed. Display current drops down to 1.4mA. I can still see the line in the display, but the serial window is empty, and if I write sth into it, Arduino RX led flashes but nothing happens.. Only when I press the reset button, the cycle repeats (Display lights up for 2secs, then freeze...)

I hope this will be little bit more helpful for finding the answer, thanks for helping me so far :slight_smile:

@INTP:

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

This is the full constructor with:
(addr, EN, RW, RS, D4, D5, D6, D7, BL, Type of BL) -> more flexible due to the flexible arrangements of the internal I2C to the display connections (there is no standard connection scheme ...)

@Wor3d:

I am using standard I2C adapter into 16x2 LCD display

I must disappoint you: there is NO standard 16x2 LCD display, especially when it comes readymade with backpack I2C.

Questions:

  1. Did you solder the I2C backpack to the display or was it a readymade package?
  2. How did you make sure, what backpack you own? Pls post a picture of your I2C backpack device - especially when you soldered it yourself magnify the soldering.
  3. Did you also try some other constructors of that site?

Pls post your full test code.

Can you post some clear photos of your setup, (backpack and LCD). So we can see it and look at the solder connections.

And also post the exact sketch code you are using for this test.

What really concerns me is that the diag code I gave you reported that pullups were missing but you are saying that it has pullups.
It located the PCF8574, but then locked up when attempting to write/read registers in the chip.

It sounds like there may be some h/w issues.
Perhaps a soldering issue?
Perhaps it is possible that your LCD does not have current limiting resistors and is pulling too much current?

Just a few guesses off the top of my head.

Seeing actual photos and code might help diagnose the issue.

--- bill

Thanks for giving me such a quick response, I will shoot some photos when I will get home. I don't think it's my soldering issue, but I understand that is common problem sometimes :stuck_out_tongue:

The I2C adapter came soldered and unfortunately the pin header for connections (VCC SCL SDA GND) was broken so I soldered mod wires directly somewhere else, you'll see when I will post the photos (approx 7PM CEST)

This is the sketch code I used for testing:

```
~~/* YourDuino.com Example Software Sketch
16 character 2 line I2C Display
Backpack Interface labelled "A0 A1 A2" at lower right.
..and
Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
MOST use address 0x27, a FEW use 0x3F
terry@yourduino.com */

/-----( Import needed libraries )-----/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

/-----( Declare Constants )-----/
/-----( Declare objects )-----/
// set the LCD address to 0x27 for a 16 chars 2 line display
// A FEW use address 0x3F
// Set the pins on the I2C chip used for LCD connections:
//                    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

/-----( Declare Variables )-----/
//NONE

void setup()  /----( SETUP: RUNS ONCE )----/
{
  Serial.begin(9600);  // Used to type in characters

lcd.begin(16,2);  // initialize the lcd for 16 chars 2 lines, turn on backlight

//-------- Write characters on the display ------------------
// NOTE: Cursor Position: (CHAR, LINE) start at 0 
  lcd.setCursor(0,0); //Start at character 4 on line 0
  lcd.print("Hello, world!");
  delay(1000);
  lcd.setCursor(0,1);
  lcd.print("HI!YourDuino.com");
  delay(8000);

// Wait and then tell user they can start the Serial Monitor and type in characters to
// Display. (Set Serial Monitor option to "No Line Ending")
  lcd.clear();
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print("Use Serial Mon");
  lcd.setCursor(0,1);
  lcd.print("Type to display");

}/--(end setup )---/

void loop()  /----( LOOP: RUNS CONSTANTLY )----/
{
  {
    // when characters arrive over the serial port...
    if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
      // clear the screen
      lcd.clear();
      // read all the available characters
      while (Serial.available() > 0) {
        // display each character to the LCD
        lcd.write(Serial.read());
      }
    }
  }

}/* --(end main loop )-- */

/* ( THE END ) */~~
```

Will report back with photos! Thanks

Hi guys! There are the promised photos - display is already in the enclosure glued up :smiley: I checked the other end of the cables (as well as solder connections) with the continuity tester on my multimeter. I determined places to solder by reading the PCF datasheet, finding the I2C connection pins (that wire soldered to the resistor (pull-up btw) is connected on pcb with required pin - checked. The VCC is soldered directly on header and the GND is connected to ground side of unpopulated A0/A1/A2 "programming" "jumpers".

At this point I am just suspecting some irreparable HW fault in display/I2C board from the seller....

Thanks!

Edit: ZIP too large, posting imgur album here.

Uh.....after looking at those photos, I have to ask: How did you end up with such a mess?

How did you verify that you were soldering to the proper side of the resistors for SDA and for the ground of the address pads?

I'd be very concerned about some of the wires:

  • the SCL red wire on pin 14 shorting out to the the /INT signal on pin 13.
    The insulation is peeled back quite a bit and there is nothing to prevent it shorting should the wire move around a bit.

  • The red wire connected to hd44780 pin 2, (vcc) shorting Vo (contrast input) hd44780 pin 3
    The insulation is peeled back quite a bit and there is nothing to prevent it shorting should the wire move around a bit.

Even if the header was broken, why couldn't you use the holes from the 4 pin header? or a trace leading to them over on that side of the board rather than soldering directly to components.

And if all else failed, a new board is less than $1 USD shipped to your house so why not get a new one?

--- bill

WTF is that? Please tell me you weren't following some guide and instead just decided to practice soldering random things for the hell of it.
I don't even . . . . this can't be real. Must be a troll.

Seriously. Massacres a board and then
"At this point I am just suspecting some irreparable HW fault in display/I2C board from the seller...."

I second Bill's opinion. Start fresh, verify the new lcd and i2c module before installation, use the header pins or header pads when connecting.

It located the PCF8574, but then locked up when attempting to write/read registers in the chip.

Yes, the fact the you can find the i2c address, but can't communicate further with the chip and the power seems to be affected would lead me away from trying to salvage what you have.

Hi guys, well...

  1. Not a troll. Didn't solder random things... Massacre a board? Well, just finding the best place to solder the cables...

  2. I ordered other lcd display and the adapternalready, but I really cannot wait for it, so I am attempting an repair...

  3. Isolation, shorting - yes, possible as you see it on the photo. But I moved them like that just to get a good shot how the soldering looks, everytime I plug it in I secure the cables from shorting out.

  4. Couldn't use the header connection as the via and pad was broken...

  5. Where to connect? Why to that resistor? I found the PCF datasheet - found SCL/SDA pins and soldered one wire on the pin, the second on the pull-up just to make less confusion (for me at least...) Tested the trace with continuity tester, as I said. Nothing done willy-nilly, everything's soldered where it should be. Ground? Easy, you can see the ground fill with thermal relief around that side. And again, continuity rester. The LCD pinout is standard, so I was reffering to that.

Sorry to see you disapointed but I am doing my best with what I have... May look like I wasn't thinking or what, but the opposite is the truth...

If you don't like it - what would YOU do in my place? I will wait another +-2 weaks for a new adapter and I have to do it ASAP. What I did horribly wrong??? I think nothing. Never shorted the cables out, I am sure on that....

Awaiting your answer, Thanks.

Wor3d:
If you don't like it - what would YOU do in my place? I will wait another +-2 weaks for a new adapter and I have to do it ASAP. What I did horribly wrong??? I think nothing. Never shorted the cables out, I am sure on that....

With wires and soldering like that there is no way to know for sure that they haven't or wont' short.
Those wires are very precarious and there is no protection from shorting.

And why solder to SMD components when other alternatives are available?
There are other places to solder to on that backpack PCB that are not directly to SMD components.

Those backpacks are really tough.
Did the header really come broken from the vendor or did you accidentally break it?

I would have done it very differently.
First:
I would have used the holes from the original 4 pin header and/or the traces that lead up to them.
More than likely it was repairable. (I've repaired things like that before)
I would have tried to replace and repair the header to be able to use it. Even if meant replacing it with a straight header vs one like the original 90 if there wasn't room in the case for the 90.
More than likely it could haven repaired by laying wires on top of the broken traces going to the header pins.
In the worst case scenario,
either a new header could have been glued/expoxied in place and wires routed and soldered to the pins. This would allow using a header again to offer a mechanically stable connection for the 4 connections.
OR, a pig tail could have been soldered using the existing holes and wires run to those 4 wires.
The point being to restore a mechanically stable connection for the 4 connections.

2nd:
I wouldn't have used such a crazy amount of glue. A few tacks around the edges should have been plenty to hold things in place.
Not sure what type of glue you used (expoxy or aquarium cement) but that much was not necessary and if it is epoxy, it may be impossible to ever service anything should something go bad or need to be changed or modified.

I, try to use screws in PCB mounting holes whenever possible.
When that isn't possible, I've done things like created mounting points or used screws through small pieces of PCB that are then attached/expoxied to the case to provide the screw studs for mounting.

In the larger picture, I would not have mounted anything with cement/epoxy until the power issues were resolved and the circuit was working like it is supposed to.
From post #8 there is still some very serious power issues.
This would imply some kind of miswiring either on this backpack, or on the main board.

--- bill

For address jumpers, A0, A1, A2.

They're jumpers. You only have to bridge the two pads associated with each if you want to jump them to change the address. But seeing as how you have absolutely no reason to change the address since you only have the one display and your code is trying to use 0x3F, just leave all of those alone.

When I first saw the pictures, I gave you the benefit of a doubt and tried to consider maybe you were trying to control the address somehow intentionally. That clearly was not the case.
It seemed like you read on some tutorial "you can solder jumpers A0, A1, A2" and took that as "solder the shit out of these things when you see them".

INTP,
I think he was simply using the bottom row of of the solder jumper pads as a place to provide ground into the PCB, which is totally unrelated to trying to set or change the i2c address.

Assuming that the wire was soldered to the correct side of the solder pads, it isn't that awful but I'd still have used somewhere else, like over at the original 4 pin header pads.

--- bill