Go Down

Topic: arduino si riavvia da solo ... poca ram? (Read 3379 times) previous topic - next topic

Schwibby

Oct 15, 2012, 05:42 pm Last Edit: Oct 15, 2012, 05:43 pm by Schwibby Reason: 1
premessa : a pezzi il codice "dovrebbe" funzionare correttamnete , una volta assemblato l'arduino si resetta.... credo sia un problema di ram mancante.... mi date una mano a ottimizzarlo? ho un arduino eth rev 3 e un uno+ shield rev 3 .. .stesso difetto su entrambi gli hardware

posto il codice sperando che qualcuno mi sveli perchè si inchioda/resetta tutto !

Code: [Select]

#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include "RTClib.h"
#include <SdFat.h>

byte mac[] = {  0x90, 0xA2, 0xDA, 0xCA, 0xCA, 0xCA };  // Indirizzo MAC Arduino Shield
byte ip[] = { 172, 31, 100, 101 };                      // Indirizzo IP Ethernet
byte gateway[] = { 172, 31, 0, 4 };                 // Indirizzo gateway
byte subnet[] = { 255, 255, 0, 0 };                  // indirizzo Subnet
byte mydns[] = { 212, 216, 112, 112 };                 // Indirizzo dns Internet
IPAddress server(62,220,xx,xx);                      // Indirizzo Server Google

byte pirPin1 = 2; // Sensore 1 in configurazione pull-up
byte pirPin2 = 3; // Sensore 2 in configurazione pull-up
byte Conta_In = 0; // Conta Persone in Ingresso
byte Conta_Out = 0; // Conta Presone in uscita
byte Accesso = 0;  // Descrimina se si è attivato prima il sensore1 o il sensore2,  1 = Sensore1, 0 = Sensore2, 2 = Reset sensori
byte pirVal1 = LOW;    //Imposta la variabile a livello logico basso all'avvio
byte pirVal2 = LOW;    //Imposta la variabile a livello logico basso all'avvio
byte In = 0;    //Variabile Ingresso
byte Out = 0;   //Variabile Uscita    
byte C_Sens1 = 0;  //Controllo su Sensore 1
byte C_Sens2 = 0;  //Controllo su Sensore 2
byte Controllo = 0;  //Confronta con il valore in ingresso dai sensori

byte calibrationTime = 30;    //Variabile per il tempo di calibrazione Sensori
byte Count_Sens = 30;         //Variabile per il conta alla rovescia per la calibrazione sensori
const byte chipSelect = 4;    //Imposta il piedino 4 per l'SD

char line[100];    //Variabile lettura stringa SD
byte n = 0;         //Variabile per numero incrementale di righe su SD

char Ora[10];      //variabile per l'orario
char Data[10];     //variabile per la data


const unsigned long postingInterval = 60*1000;  // tvariabile per il tempo di attesa alla riconnessione Ethernet di 1 minuto

EthernetClient client;    // Associa EthernetCliente nella variabile Client

RTC_DS1307 RTC;    // Dichiara la Variabile RTC come RTC_DS1307
SdFat sd;          //Associa la variabile sd alla libreria SDFat
SdFile myFile;     //Associa la variabile myFile alla libreria SDFat

char Host[] = "Host: www.miohost.it";    // dichiara la variabile Host come char

void setup(){

Serial.begin(9600);
 
 Wire.begin();    //Inizializza la libreria Wire
 RTC.begin();     //Inizializza l'RTC real Time Clock
 
 Serial.println("Inizializzo Ethernet...");
 Ethernet.begin(mac, ip, mydns, gateway, subnet);    // Inizializza l'Ethernet con MAC IP DNS GATEWAY SUBNET
 delay(500);  //Attendi 1/2 sec.
 
 Serial.println("Inizializzo SD...");  // Scrivo che inizializzo l'SD
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();    //Controllo se è inizializzaro l'SD
 delay(500);   // Attendi 1/2 sec.
 
 if (!RTC.isrunning()) {
       RTC.adjust(DateTime(__DATE__,__TIME__));    //setta l'RTC cone la data e l'ora di compilazione
       Serial.println("Settaggio Data e Ora... "), Serial.print(__DATE__), Serial.print(" "), Serial.println(__TIME__);
       delay(500);
 }
 
  //give the sensor some time to calibrate
/*  Serial.print("Calibrazione Sensore PIR tra: ");
  for(byte i = 0; i < calibrationTime; i++){
     Count_Sens--;
     Serial.print(Count_Sens);
     delay(1000);
     }
 */
 
pinMode(pirPin1, INPUT);    // Imposta il pin2 come Input
pinMode(pirPin2, INPUT);    // Imposta il pin3 come Input

pinMode(5,OUTPUT);          // Imposta il pin5 come Output
digitalWrite(5,LOW);        // Imposta il pin5 basso

pinMode(6,OUTPUT);          // Imposta il pin6 come Output
digitalWrite(6,HIGH);       // Imposta il pin6 alto

Serial.println("Avvio Sistema");
}

void loop(){
 pirVal1 = digitalRead(pirPin1);    //Leggi il valore in ingrsso dal pirPin1
 pirVal2 = digitalRead(pirPin2);    //Leggi il valore in ingrsso dal pirPin2
 
 if (pirVal1 > Controllo) C_Sens1 = 1;  //esegui un contronto con la variabile controllo preimpostata
 if (pirVal2 > Controllo) C_Sens2 = 1;  //esegui un contronto con la variabile controllo preimpostata
 
 if (C_Sens1 > C_Sens2)In = 1;      //Serial.println("setto persona in entrata");
 if (C_Sens2 > C_Sens1)Out = 1;    //Serial.println("setto persona in uscita");
   
 if ((C_Sens1 + C_Sens2) == 2){    
   if (In == 1){
         Conta_In++;
         Accesso=1;
         
         Serial.print("N. Entrate: ");
         Serial.println(Conta_In);
         
         Orologio();
         Scrivi_SD();
         delay(300);
   }  
   else if (Out == 1){  
         Conta_Out++;
         Accesso=0;
         
         Serial.print("N. Uscite: ");
         Serial.println(Conta_Out);
         
         Orologio();
         Scrivi_SD();
         delay(300);
         
 }
 
   C_Sens1 = 0;
   C_Sens2 = 0;
   //Serial.println("Cancello");
   //delay(100);
 }
 
 
  Orologio();
  delay(50);
 
 }


void Orologio(){
 DateTime now = RTC.now();
 
  sprintf(Ora,  "%02d%02d%02d", now.hour(), now.minute(), now.second());      // Formattazione Orario in HHMMSS
  sprintf(Data,  "%d%02d%02d", now.year(), now.month(), now.day());           // Formattazione Data in YYYYMMDD
 
  String(C_HTTP) = "230000";
  String(C_Reset) = "235900";

  if (C_HTTP == Ora){
     Serial.println("Vado a Leggere SD");
      delay(1000);
      Leggi_SD();
  }
 
  if (C_Reset == Ora){
    Serial.println("Resetto HW");
       reset();
  }
}


void Scrivi_SD(){
 
 Serial.println("Scrittura SD");
 delay(1000);
 if (!myFile.open ("KKKVigne.txt", O_WRITE | O_CREAT | O_APPEND)) {
       Serial.println ("Apertura File fallita per la scrittura");
 }
 
 //Costruisci Stringa da Salvare su SD
 myFile.print("Get /index.php?Data=");
 myFile.print(Data);
 myFile.print("&Ora=");
 myFile.print(Ora);
 myFile.print("&Ingresso=");
 myFile.print(Conta_In);
 myFile.print("&Uscita=");
 myFile.print(Conta_Out);
 myFile.print("&Accesso=");
 myFile.print(Accesso);
 myFile.println(" HTTP/1.1");
 myFile.close();
 
//Stampa a video la costruzione della strinda WEB
 Serial.print("Get /index.php?Data=");
 Serial.print(Data);
 Serial.print("&Ora=");
 Serial.print(Ora);
 Serial.print("&Ingresso=");
 Serial.print(Conta_In);
 Serial.print("&Uscita=");
 Serial.print(Conta_Out);
 Serial.print("&Accesso=");
 Serial.print(Accesso);
 Serial.println(" HTTP/1.1");

 Serial.println("Scrittura Eseguita..");
 delay(100);
 
}

void Leggi_SD(){

Serial.println("Inizio a Leggere da SD..");

delay(100);  
SdFile rdfile("KKKVigne.TXT", O_READ);

// check for open error
// if (!rdfile.isOpen()) error("Errore di apertura File o file non esistente");
 if (client.connect(server, 80)){
     Serial.println("Connesso al Server");  // Esegui la chiamata al Server e conferma l'avvenuta connessione
     delay(1000);
 
 // read lines from the file
    Ritenta_Scritta:
     while ((n = rdfile.fgets(line, sizeof(line))) > 0) {
       if (line[n - 1] == '\n') {
          Scrivi_WEB();
          delay(200);  //pausa di 200 millisecondi tra una lettura ed un altra
       }  
     }
     Serial.println("Ho finito di Leggere e Inviare");
   client.stop();
 }
   else {
     
      for (byte a = 0; a < 5; a++){        
        Serial.println("Ritento Connessione");
        delay(postingInterval);
        if (client.connect(server,80)){
              Serial.println("Collegato Invio Dati");
              goto Ritenta_Scritta ;
              break;
        }
      }
   
     Serial.println("Esco");
 
  }
}
 
void Scrivi_WEB(){
 
   client.print(line);
   client.println(Host);
   client.println();
   
   Serial.print(line);
   Serial.println(Host);
   Serial.println();
   
}

void reset(){
 digitalWrite(6,LOW);
 delay(1000);
 digitalWrite(6,HIGH);
 
}

void watchdog(){
 digitalWrite(5,HIGH);
 delay(100);
 digitalWrite(5,LOW);
 
}

lesto

uhmm c'è ben poco da tagliare. diminuisci line da 100 a 10, sperando che basti.
Altrimenti bisognerà iniziare a salvare li stringhe su flash con la F()
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Schwibby

eventualmente il loop è stato studioato in questa forma
(che non so perchè usa meno byte nello sketch)

Code: [Select]
void loop(){
 
  pirVal1 = digitalRead(pirPin1);    //Leggo valore pulsante 1
  pirVal2 = digitalRead(pirPin2);    //Leggo valore pulsante 2
  delay(100);                        //attendo 100ms
 
  if (pirVal1 > value){
    a=1;
  } 
  if (pirVal2 > value){
    b=1;   
  }
  if (a > b){
      entering = 1;
      //Serial.println("setto persona in entrata");
  } else if (b > a ){
      leaving = 1;
      //Serial.println("setto persona in uscita");
    }
  if ((a+b) ==2){
  if (entering == 1){
    Conta_In++;
    Accesso=1;
      Serial.print("N. Entrate: ");
      Serial.println(Conta_In);
    Orologio();
    Scrivi_SD();
    delay(200);
  } else if (leaving == 1){ 
      Conta_Out++;
      Accesso=0;
      Serial.print("N. Uscite: ");
      Serial.println(Conta_Out);
     
      Orologio();
      Scrivi_SD();
      delay(100);
  }
   
    entering=0;
    a=0;
    b=0;
    //delay(100);
  }
   
   
   Orologio();
   delay(100);
  }

Schwibby

il line però non è la lunghezza della mia srtringa ? ora è lunga 70 caratteri , se metto 10 non mi viene tagliata?

lesto

quella line è quello che leggi da file e ributti su socket, il fatto che tu faccia questo processo con 1 o 10, 100,1000 caratteri alla volta non ti cambia niente visto che tanto rieffettui questa operazione di lettura fino a file fine. Sicuramente dover ripetere più volte la richiesta rallenta l'esecuzione del codice di qualche ms ma hey, l'importante è farlo andare no?
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Schwibby

in realtà leggo la riga quindi mi serve lunga quanto la mia riga.. a 85 lo posso calare... ora con qualche modifica tipo quella del if postata il codice è piu leggero per arduino... e si resetta molto meno....

le lib sdfat rispetto le normali sono consigliate? oppure le sd normali sono piu leggere?

lesto

se non erro le sd normali sono le sdfat  ufficializzate
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

pablos

cambia la sdfat.h con SD.h
togli i serialPrint
è un inizio di risparmio :)
no comment

Schwibby

meglio le sd? hanno le stesse funzioni?

Schwibby

posso fare una domanda a voi esperti?

le sdfat mi leggono da un file di testo tutta la linea fino al /n con questa funzione

Code: [Select]
while ((n = rdfile.fgets(line, sizeof(line))) > 0) {
        if (line[n - 1] == '\n') {


tramite le sd normali posso farlo lo stesso?

lesto

main site -> reference -> Libraries -> SD

http://arduino.cc/en/Reference/SD
:smiley-mr-green:
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lesto

Quote
se uso le sd.h non ho piu la funzione fget e quindi dovrei creare un array immagino contenente la mia stringa per intero da inviare poi in un secondo momento


non serve che invii la stringa per intero. Puoi anche scrivere una lettera alla volta, basta che non chiudi la comunicazione con i client. Il modulo ethernet/wifi ha un buffer interno che viene svuotato quando chiudi la comunicazione (in tal caso inviando anche i messaggi di comunicazione terminata) o quando il buffer è pieno. Nel mondo delle comunicazioni non è da dare per scontato che un messaggio viene inviato per intero, poi spesso ci sono delle astrazioni de codice che fanno sembrare che ciò avvenga.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Schwibby

allora vediamo un po di tradurre il tutto cercando di capire meglio (in termini pratici di linguaggio di programmazione) cio che hai espresso a parole :) :smiley-yell: :smiley-yell: :smiley-yell: :smiley-yell: :smiley-yell: :smiley-yell: :smiley-yell: :smiley-yell: :smiley-yell:
ci sentiamo piu tardi che torno al debug :)

Schwibby

niente da fare appena entra qui si resetta anche il  :smiley-red: :smiley-red: :smiley-red:

Code: [Select]
void Leggi_SD(){

  myFile = SD.open("KKKVigne.txt", FILE_READ);
  if (myFile) {
    Serial.println("Inizio a Leggere KKKVigne:");
   
    // read from the file until there's nothing else in it:
    if (client.connect(server, 80)){
      Serial.println("Connesso al Server");  // Esegui la chiamata al Server e conferma l'avvenuta connessione
    while (myFile.available()) {
      if (String("#") == (String(myFile.read()))){
      client.println(Host);
      client.println();
      client.stop();
      Serial.print((String(myFile.read())));
      Serial.println("fine");
    } else {
    client.print(String(myFile.read()));
        //Serial.write(myFile.read());
        Serial.print((String(myFile.read())));
        Serial.println("fine");
    }
    }
    // close the file:
    myFile.close();
    }
   
  else {
  // if the file didn't open, print an error:
    Serial.println("Errore invio");
  }
} else {
  // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}//fine leggi sd

lesto

perchè forzi i caratteri ad essere String? tienili come caratteri che risparmi ram e cpu

in oltrecon available() tu ti assicuri che ci sia almeno UN carattere, ma poi fai DUE read, quindi potresti bloccarti semplicemente perchè i byte nel file sono dispari...
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up