Arduino freezes when using push button. I2C related - SOLVED -

Hi everyone, hope my post fits in this section.
I will not post all my code cause is huge and wouldnt expect anyone to look into all of it.

Basically, I have had a project running for a long long time, but now I have added 2 push buttons and when pushing them, from time to time arduino freezes.
I have disabled pieces of code until found where the problem comes from, seems to be related to I2C (i use rtc clock and I2C lcd)

When I push the buttons intensively my code reports RTC time error (based on this check)

    if (  (years > 2030) ||  (months > 12)    ||  (days > 31)    ||  (hours > 24)    ||    (minutes >= 60)  ||  (seconds > 60)   )

Also I have noticed that if I disable all LCD printing code, then I dont get Arduino freezes.

I think I2C goes crazy but maybe it has something to do with some calculations been done in the update lcd function (although i tried removing them and also happended)
example of lcd screen print..

void LCD_Screen_1()
{ 
  double Percentage_Energy = ((  (SumPower_1Month + ct1.SumPower)  / Max_Month_wh) * 100.0);
                                // Time passed this month                   /   number of hours in this month   *   percentage
  double Percentage_M_Time = ((  (((days-1) * 24) + hours + (minutes/60.0)) / (daysInMonths[months - 1] * 24)) * 100.0);
  double Cost = (SumPower_1Month/1000.0) * PriceEnergyKwh;
  
    	lcd.setCursor(0, 0);
          lcd.print("** MONTHLY INFO **");

        lcd.setCursor(0, 1);    lcd.print("Power: ");   printlcdspaces(ct1.Irms*230.0);    lcd.print(ct1.Irms*230.0,0);  lcd.print("W ");
                                                        printlcdspaces(Cost);              lcd.print(Cost,1);            lcd.print("E ");
        
    	lcd.setCursor(0, 2);
          lcd.print("Energy: ");    lcd.print(Percentage_Energy,2); lcd.print(" % ");      
    
        lcd.setCursor(0, 3);
          lcd.print("M.Time: ");    lcd.print(Percentage_M_Time,2); lcd.print(" % ");  lcd.print("    "); 

}

declaration

double SumPower_1Month;
    long hours;    long minutes;    long seconds;    // I have declare them as long instead of int because I think that if RTC fails it can read bigger than int size numbers and try to save them in the int, and cause problem
    long years;    long months;     long days;

  double PriceEnergyKwh = 0.20;
  double Max_Month_wh = 450000;

I know its a long post, but please any hint is very welcome.

resume:
- Why would a push-button (internal pullup resistor used) caused a I2C misreading?
- Do my formulas have a problem with data types?

Thank you eveyone

Sergegsx:
my code cause is huge

Why would a push-button (internal pullup resistor used) caused a I2C misreading?

Perhaps you're running out of RAM - the sort of symptoms you describe are typical. You could add a call to measure the free memory to see whether that's likely to be the problem - google "Arduino freeMemory".

Do you use the String class? Also what PeterH said.

Thanks both, I am running a MEGA and check RAM every 10 minutes or so.
I have 3428 left using FreeMem library
thanks for the suggestion.

I only use this for strings.

strcpy(str,....

but dont think the problem comes from there as I was able to identify that if I comment the function that updates the LCD then there is no problem of freezing.

please any further help is much appreciated.

I can't comment after only seeing snippets.

Where are the buttons connected? What wiring in general is used? Do you have I2C pull-up resistors?

Having spare RAM does not prove much. The String corruption I mentioned can corrupt memory, even if there is plenty left.

You need to post all your code. What you don't think is relevant, might be.

Ok Nick, thanks

I will try to see if I can reduce the amount of code and still get the freeze when pushing the button, then I will upload it.

I am using a RTC and LCD in I2C, the RTC comes with 10K resistors for pull up

http://www.ebay.com/itm/DS1307-RTC-Module-Real-Time-Clock-For-AVR-Arduino-PIC-/170658532131?ssPageName=ADME%3AX%3AAAQ%3AUS%3A1123&nma=true&si=rDPYmK90eVqvYCewvfLhj2%252FqYfg%253D&orig_cvip=true&rt=nc&_trksid=p2047675.l2557

the lcd is this, I dont think it has pullup resistors
http://www.ebay.com/itm/I2C-Serial-2004-LCD-Module-20X4-IIC-TWI-LCD-for-ATmega328-1280-2560-board-/160700138365?pt=LH_DefaultDomain_0&hash=item256a79837d

maybe the resistor value is not good?

You should only need one lot of pull-up resistors (typically, 4.7K). There are some diagrams on this page that show the effect:

Hello Nick and everyone,

I manage to find the source of the problem, it has been a nightmare for the last days to try to figure this out. I was most certain my code had some memory or calculation issue which caused the uC to freeze, but then it was only happening when using the buttons.
So what i did after hours and hours of disabling code, enabling parts of code, doing 150 push button presses in each test, etc...

  1. I setup another arduino mega + ethernet shield and loaded the script with only the two boards, a lcd and 2 push buttons. (no more wires, sensors, leds etc)
    Surprise, there was no freezing !! Could this mean the code is OK?

  2. I went back to my project and at first I thought the problem was the type of pushbutton (as in step 1 I used a different one)
    Nop, same problem

  3. I finally stripped out everything out of my main project....SAME PROBLEM !! wtf !

i was again stuck...thinking again my code was the source of the problem.

Finally I decided to mount the new push buttons and everything was OK! wtf again ! pushbutton causing the problem?

well to shorten the story....

I had a 6 wire cable (3 meters) to extend the LCD wires to a more suitable location for the lcd mounting. I was doing, pinout:

  • 5V
  • ground
  • sda
  • scl
  • pushbutton 1 input (internal resistor)
  • pushbutton 2 input (internal resistor)

The problem was that running the 2 pushbuttons wires inside the cable created some sort of problem on the I2C line, causing the lcd not to work properly and ending up freezing the arduino !!

I can not believe it still. I must have done over 2000 or 3000 push button presses trying to debug this problem. I could only get the arduino to freeze after 70 or 100 presses it time, so it has been a pain to figure out.

I would like to know your opinion on this issue. Why is using 2 of the 6 wires of the cable causing this problem? The cable is similair to a cat 5 cable but the wire inside are thinner and are NOT one
wire but multiwire (sorry dont know how they are named officialy).

I also noticed that reading the voltage of the pushbutton it stands at 4,9V when not pressed, then I press and goes to 0 V, when I release my multimeter jumps to around 8V for miliseconds (at least thats what I see in the multimeter screen) Is this normal? misreading or is it real?

Why I am getting this interference causing I2C to fail and causing my arduino to freeze?

btw, Nick thanks a lot for trying to help me, I ended up using 4K7 resistors just in case, but didnt help.

I took some time to write this up just in case someone experiences the same problem in the future.

thanks all.

Well done for working it out!

My guess is that the 6-wire cable is acting as some sort of massive capacitor. Causing a transition (pushing the button) is inducing some sort of reaction in the cable. Just for interest I would try terminating the wires that are not in use (eg. connect them all together, and to the ground).

I might be wrong, the electronics experts might have other ideas.

Thanks Nick for your nice words and for trying to help me.

Actually the cable is 6 wires and I needed all 6 as you can see in my previous post, so I can not try what you said. Now I have the pushbuttons using other wires outside the LCD extension cable. I will try to get a cat5 cable and try again to see what happens.

Lets see if any electronics expert can throw some physics into this :wink:

I know I2C is not intended to be very long wired, but never expected to have this problem when adding basic pushbuttons to the cable.

Your idea on the "massive capacitor" sounds good, that could also explain the peak on voltage I get when releasing the pushbutton. Maybe there is a way of avoiding this,

Any electronic experts can give us some more information about this?

I also found this ...
http://iterativecode.com/blog/2012/03/19/reduce-noise-on-arduino-400-khz-i2c-with-external-pull-up-resistors/

Your idea on the "massive capacitor" sounds good, that could also explain the peak on voltage I get when releasing the pushbutton

Massive inductor then. They are well known for producing a spike when the magnetic field collapses. :slight_smile:

Of course, inductor, sorry.

Anyone knows of a solution so I can use the 2 wires inside the cable of 6 wires?
Change the type of cable? cat 5? Add something to the circuit to remove the inductive of the wires?

thanks !! :wink:

I don't think I2C is really designed to work over that length, without some sort of I2C extender.

From my page here on I2C I note:

Note also that the Atmega specifies a maximum bus capacitance of 400 pf, so that would rule out long cable runs.