Arduino si inchioda

Ciao, sto cercando di debuggare un software che prima di qualche modifica fa funzionava, ma non sono piu' in grado di capire perche' ora non va :slight_smile: Siccome il codice e' abbastanza corposo mi chiedevo, se inserisco un paio di print arrivo a fare un giro di codice e poi non printa piu', fa un solo giro del loop. E' possibile che qualche variabile incrementata accidentalmente in modo esagerato causi questo blocco? Tanto per capire di cosa devo preoccuparmi e di cosa no...
Fede

senza il codice è difficile aiutarti....

ciao federico
senza codice é impossibile aiutarti.
Puó essere un loop come un while o for dove la condizione di uscita non arriva mai.
Manda dei messaggio di stato via seriale al terminale del PC e metti per esempio Serial.print("1"); incrementando il numero ogni volta che scrivi il comando.
l' ultimo numero trasmesso corrisponde al ultima riga eseguita correttemente.
Aggiungi al inizio il Serial.print a intervalli grandi (ogni 10 righe) e una volta trovato la parte che blocca mettilo piú frequente da avere alla fine ogni seconda riga un Serial.print.
Cosí determini esattamente il punto dove si blocca.
ciao Uwe

Posto il mio codice per completezza e mi preparo al debug, la grande fregatura del tutto e' che ho sempre bisogno di due piattaforme hardware per lo sviluppo, perche' una e' installata e difficilmente verificabile e riprogrammabile, l'altra e' in casa ed e' quella che uso per il debug...

/* 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
*/

#include <WProgram.h>
#include <Wire.h> //i2c
#include <LiquidCrystal_I2C.h> //LCD
#include <DS1307.h> //RTC
#include <DS1803.h> //Digital Pot

byte data[56];
char orario[16];
char dataOdierna[16];
int rtc[7];
int anno;
int changeScreen = 0;
int LCDbuttonState;
int LCDbuttonVal;
int switchPin=7;         // BUTTON is connected to pin 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
DS1803 pot(0x28);

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  
  pot.setPot(255,0); //backlight
  pot.setPot(20,1);
  
  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);
  
  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);

    //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(" ");    
  }
     
}

void ds1624_config(int DS1624_ADDRESS) 
{ 
  // START CONDITION + ADDRESS + MODE
  Wire.beginTransmission(DS1624_ADDRESS);
  // SEND ACCESS CONFIG PROTOCOL
  Wire.send(0xAC);
  // SEND CONTINUOUS CONVERSION COMMAND
  Wire.send(0x00);
  // STOP CONDITION
  Wire.endTransmission();
}

void ds1624_startconvert(int DS1624_ADDRESS) 
{ 
  // START CONDITION + ADDRESS + MODE
  Wire.beginTransmission(DS1624_ADDRESS);
  // SEND CONTINUOUS CONVERSION COMMAND
  Wire.send(0xEE);
  // STOP CONDITION
  Wire.endTransmission();
}

float ds1624_readtemp(int DS1624_ADDRESS) 
{ 
  float temperature = 0;
  int tempmsb = 0;
  int templsb = 0;
  int temp2 = 0;

  // START CONDITION + ADDRESS + MODE
  Wire.beginTransmission(DS1624_ADDRESS);
  // SEND READ TEMP COMMAND
  Wire.send(0xAA);
  // GET THE TEMP MSB AND LSB
  Wire.requestFrom(DS1624_ADDRESS, 2);

  if (Wire.available()) {
    tempmsb = Wire.receive();
  }

  if (Wire.available()) {
    templsb = Wire.receive();
  }

  temp2 = templsb >> 3;
  temperature = (float(tempmsb) + (float(temp2) * 0.03125));
  // STOP CONDITION
  Wire.endTransmission();
  return temperature;
}

Le ultime funzioni per il DS1624 dovrebbero essere giuste, ne ho scritto una versione "Libreria" ma ancora non l'ho implementata in questo codice che avrei voluto cambiare il meno possibile :slight_smile:

Federico

sicuramente c'hai già pensato ma, hai provato a stampare "cmd" e "apparato" per vedere che valori hanno?

cmd=Serial.read();Serial.read();
apparato=Serial.read();Serial.read();
stato=Serial.read();

il Comando è "s * *" quindi il Serial.read() che metti è per leggere lo spazio?

Allora, dopo MOLTE ore di debug, attraversate da un cavo che non funzionava (e ci ho messo una vita a capirlo) e cose strane che ho provato, e dubbi di chip rotti ho individuato che tutto va a farsi benedire nel momento in cui ISTANZIO questo: (Ne sono quasi sicuro, ma ancora ci sto lavorando)

DS1803 pot(0x28);

E' una libreria che ho scritto io, questo ne e' il codice:

.h

/*
  Library for controlling the DS1803 ic with Arduino
  Tested with arduino-0018
  22/02/2010 Release 0.1
  Written by Federico and Riccardo Galli
  http://www.sideralis.org
*/

#ifndef DS1803_h
#define DS1803_h
#include "WProgram.h"
#include <Wire.h>

#define WIPER_0 0xA9
#define WIPER_1 0xAA
#define WIPER_01 0xAF


class DS1803
{
  int8_t addr;
  public:
    DS1803(int8_t addr);
    void setPot(int value, int wiper);
    int8_t *getValue();
  //private:
    //;
};

#endif

.cpp

/*
  Library for controlling the DS1803 ic with Arduino
  Tested with arduino-0018
  22/02/2010 Release 0.1
  Written by Federico and Riccardo Galli
  http://www.sideralis.org
*/

#include "WProgram.h"
#include "DS1803.h"
#include <Wire.h>

DS1803::DS1803(int8_t addr)
{
  this->addr=addr;
  Wire.begin();
}

/* Set the values of the wiper (potentiometers)
    wiper 0 is pot0, wiper 1 is pot1 and wiper2 is pot0 and pot1
    Value is between 0 and 255
*/
void DS1803::setPot(int value,int wiper)
{
    Wire.beginTransmission(this->addr);
    
    if (wiper==2) Wire.send(WIPER_01);
    else Wire.send(wiper ? WIPER_1 : WIPER_0);
    
    Wire.send(value);
    Wire.endTransmission();
}

// Return an array of two values read from the IC
int8_t *DS1803::getValue()
{
      Wire.requestFrom(this->addr,2);
      int8_t *values=(int8_t*)malloc(sizeof(int8_t)*2);
      
      int k=0;
      while (Wire.available()) {
            values[k]=Wire.receive();
      }

      return values;
}

C'e' qualche errore che salta all'occhio? La libreria funziona perche' l'ho provata e funziona anche assieme a i2c Liquidcrystal perche' li avevo provati assieme (e ora non ho un doppione del circuito in oggetto), ma non avevo mai provato assieme al resto di questo codice.

Fede

Sospetto un conflitto tra la mia libreria e quella DS1307 RTC ...
Che stress...