Premendo un pulsante arduino resetta. Perchè?

Sto procedendo alla fase installativa del mio progetto lcd e sensori in automobile. Collegato tutto lo schermo lcd funziona (cavi da arduino a schermo di circa 3 metri) ma quando premo il pulsante che dovrebbe far cambiare la schermata (stessi cavi 3 metri) arduino si resetta. Dalle prove al banco funzionava…

Ecco il codice:

// Ultima revisione, completamente funzionante 31-01-10
/* Accensione RME e Amplificatori
 * Per accendere gli amplificatori inviare "s 0 1" e per spegnerli "s 0 0"
 * Per accendere la scheda audio inviare "s 1 1" e per spegnerli "s 1 0"
 * Connettere i rele' per gli ampli al pin 4 e quello per la scheda audio al 2
 * Pulsante per monitor lcd su pin 7 e GND
*/

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

byte data[56];
char orario[16];
char dataOdierna[16];
int rtc[7];
int anno;
int changeScreen = 0;
int LCDbuttonState;
int LCDbuttonVal;
int switchPin=7;  

int relayPinRME = 2;     // RME Relay is connected to pin 2
int relayPinAMP = 4;     // AMP Relay is connected to pin 4
char AMP='0'; // Ho messo il carattere 0 e non il valore 0
char RME='1'; // Attenzione alla differenza tra caratteri e interi!

//indirizzo del ds1624
//DS1624_ADDRESS 0b1001[A2-A1-A0] --> 0X4F +5+5+5 | 0X48 GNDGNDGND | 0X4B +5+5GND

#define expander 0x20  // Address with three address pins grounded (B0100000).
                     // Note that the R/W bit is not part of this address.
volatile byte count = 0;

uint8_t bell[8]  = {0x4,0xe,0xe,0xe,0x1f,0x0,0x4};
uint8_t note[8]  = {0x2,0x3,0x2,0xe,0x1e,0xc,0x0};
uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0};
uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0};
uint8_t duck[8]  = {0x0,0xc,0x1d,0xf,0xf,0x6,0x0};
uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0};
uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0};
uint8_t retarrow[8] = {      0x1,0x1,0x5,0x9,0x1f,0x8,0x4};
  
LiquidCrystal_I2C lcd(expander,8,2);  // set the LCD address to 0x20 for a 16 chars and 2 line display


void setup()
{
  Wire.begin();
  
  delay(100);
  ds1624_config(0x4F);
  ds1624_config(0x4B);
  ds1624_config(0x48);
  delay(100);
  ds1624_startconvert(0x4F);
  ds1624_startconvert(0x4B);
  ds1624_startconvert(0x48);
  
  
  pinMode(switchPin, INPUT);    // Set the BUTTON pin as input
  pinMode(relayPinRME, OUTPUT); // Set the RME pin as output
  pinMode(relayPinAMP, OUTPUT); // Set the AMP pin as output
   
  LCDbuttonState = digitalRead(switchPin);
  
  Serial.begin(9600); 
  lcd.init();        // initialize the lcd 
  lcd.noBacklight(); // accende e spegne l'uscita sul pin 12.
                     // lcd.backlight();
                     // sink current +5V------+LED-------330Rresistor------P8574pin
  
  lcd.createChar(0, bell);
  lcd.createChar(1, note);
  lcd.createChar(2, clock);
  lcd.createChar(3, heart);
  lcd.createChar(4, duck);
  lcd.createChar(5, check);
  lcd.createChar(6, cross);
  lcd.createChar(7, retarrow);
  lcd.home();
  
  lcd.print(" System");
  lcd.setCursor(0, 1);
  lcd.print(" Ready.");
  delay(1000);
  for(int i=0; i<9; i++)  {
    lcd.scrollDisplayLeft();
    delay(100);
  }
  lcd.clear();
  lcd.home();
  
  //RTC SETUP 
  /*RTC.stop();
  RTC.set(DS1307_SEC,1);
  RTC.set(DS1307_MIN,50);
  RTC.set(DS1307_HR,17);
  RTC.set(DS1307_DOW,7);
  RTC.set(DS1307_DATE,31);
  RTC.set(DS1307_MTH,1);
  RTC.set(DS1307_YR,10);
  RTC.start();*/
  
  for(int i=0; i<56; i++)  {
    RTC.set_sram_byte(65,i);
  }

}

void loop()
{
  if (Serial.available()>=5) {
    char cmd,apparato,stato;
    
    cmd=Serial.read();Serial.read();
    apparato=Serial.read();Serial.read();
    stato=Serial.read();
    
    // esegue le operazioni indicate dalla lettura della seriale
    if (apparato == AMP && stato=='0'){
       digitalWrite(relayPinAMP, LOW);
       Serial.println("Spengo Amplificatori..."); 
    }
    else if (apparato == AMP && stato=='1'){
       digitalWrite(relayPinAMP, HIGH);
       Serial.println("Accendo Amplificatori...");
    }
    else if (apparato == RME && stato=='0'){
       digitalWrite(relayPinRME, LOW);
       Serial.println("Spengo Rme...");
    }
    else if (apparato == RME && stato=='1'){
       digitalWrite(relayPinRME, HIGH);
       Serial.println("Accendo Rme...");
    } 
  }
  
  LCDbuttonVal = digitalRead(switchPin);      // read input value and store it in val
  if (LCDbuttonVal != LCDbuttonState) {       // the button state has changed!
    if (LCDbuttonVal == LOW) {                // check if the button is pressed
      //Serial.println("Bottone premuto");
      changeScreen=!changeScreen;
      lcd.clear();
    }
  }
  LCDbuttonState = LCDbuttonVal;              // save the new state in our variable

  if (changeScreen==0) {
    RTC.get(rtc,true);
    /*for(int i=0; i<7; i++) {
      Serial.println(rtc[i]);
      Serial.print(" ");
      }
      Serial.println();*/

    //rtc[0] --> secondi
    //Tramite questo IF faccio lampeggiare il : per i secondi
    if (rtc[0]%2) {
      sprintf(orario,"%02d:%02d",rtc[2],rtc[1]); //%02d converte 9 in 09 e 32 in 32
    }
    else {
      sprintf(orario,"%02d %02d",rtc[2],rtc[1]);
    }
    //Serial.println(orario);
  
    anno=rtc[6]-2000;
    sprintf(dataOdierna,"%02d/%02d/%02d",rtc[4],rtc[5],anno);
    
    lcd.setCursor(1,0);
    lcd.print(orario);
    lcd.setCursor(7,0);
    lcd.print(2, BYTE);
    lcd.setCursor(0,1);
    lcd.print(dataOdierna);
  }
  else  {
    lcd.setCursor(0,0);
    lcd.print(1, BYTE);
    lcd.setCursor(1,0);
    lcd.print(int(ds1624_readtemp(0x4F)));
    lcd.setCursor(3,0);
    lcd.print(" ");
    lcd.setCursor(4,0);
    lcd.print(4, BYTE);
    lcd.setCursor(5,0);
    lcd.print(int(ds1624_readtemp(0x4B)));
    lcd.setCursor(7,0);
    lcd.print(" ");
    lcd.setCursor(0,1);
    lcd.print("hcca");
    lcd.setCursor(5,1);
    lcd.print(int(ds1624_readtemp(0x48)));
    lcd.setCursor(7,1);
    lcd.print(" ");    
  }
     
}

Sostanzialmente quello che avviene e’ che quando premo il pulsante collegato al pin 7 lo schermo lcd mi mostra quello che dovrebbe fare questa riga  lcd.print(1, BYTE); e poi resetta, e lo capisco perche’ vedo quello che fa questa parte di codice

lcd.print(" System");
  lcd.setCursor(0, 1);
  lcd.print(" Ready.");

che si trova nel setup()

Il pulsante sostanzialmente e’ collegato tramite un cavo di 3metri al pin 7 e al gnd di arduino e una resistenza da 3.3k e’ collegata tra il positivo di arduino e il pin7.

Qualche idea del perche’ faccia questo? Ho possibilita’ relativamente poche di debuggare il codice lavorando in macchina, sospetto qualcosa che ha a che vedere con la lunghezza dei cavi e la resistenza di pullup sul pulsante… Mi domando, e’ possibile che arduino si resetti per via di questo? Lo fa anche a pc spento ed e’ sempre alimentato esternamente.

Fede

L'unica cosa che mi viene da dirti a getto e':

Hai provato ad usare un cavo schermato ?

Il cavo che uso e' un cavo cat5 che e' schermato, e nello stesso cavo porto il segnale per accendere il pusante del computer, che funziona, il segnale per accendere lo schermo lcd e il segnale i2c dell'lcd, e tutti funzionano (secondo me se funziona lo schermo lcd non e' possibile che sia la schermatura che non mi fa funzionare un bottone) ...

Vorrei provare domani a verificare la messa a terra del sistema...

Qualsiasi consiglio e' accettato!

Se il cavo è FTP è schermato, se UTP no, attenzione a collegare lo schermo a massa solo da un lato mai da entrmbe . :)

se premi il pulsante il led verde PWR si spegne (o cambia luminosità)

mi sembra piu che altro un corto....

m

Ciao Federico, Perchè non alzi quella resistenza di pull up che hai messo sul pin 7 d 3,3 k. Io la porterei a 10 K. Poi dove l'hai piazzata a monte del pulsante, o a monte di arduino? Poi aggiungi un condensatore di filtro sull'alimentazione di Arduino.

Non credo sia un corto perche' col tester solo se premo il pulsante "suona" e a casa funziona... Ho provato a invertire lo schema di collegamento del pulsante (al posto di rilevare un high rilevo un low) ma il risultato non cambia. Provo oggi spero a cambiare la resistenza e metterla piu' elevata (si trova vicino all'arduino, non vicino al pulsante) ed eventualmente smontare un po' di roba e mandare a terra il pulsante il piu' vicino possibile al pulsante stesso. Provo anche a cambiare il punto di alimentazione di arduino... e magari un pulsante volante extra...

Per verificare la lucina verde devo trovare un amico che mi aiuti! :-[

Mi sento gia' frustrato :'(