Arduino e gestione Seriale.....

Salve utilizzo il mio primo post anche per la presentazione, è da molto che vi leggo e cerco di capirne sempre di più su Arduino e le varie implementazioni.... ed è bello trovare cosi tante persone appassionate....

Veniamo al problema.... ho scritto un programma su arduino che oltre a gestire un LCD 40x4 fa da Voltmetro e fa varie misure e comparazioni che poi scrive perfettamente sull'lcd con caratteri personalizzati (presente i BIG font) ... il tutto funziona perfettamente.... due potenziometri per la scelta del menu due pulsanti per dare l'ok e il torna indietro..... tutto perfetto....

Il problema sorge sull'ultima implementazione che volevo fare... ho ricreato l'interfaccia che ho realizzato con arduino in flash.... ho importato il tutto in VB e leggendo la seriale, volevo far fare al pc le stesse cose che fa arduino... per fare questo ho stabilito una serie di protocollo che arduino dovrebbe inviare al pc con la stringa

Serial.print("comandodainviare");

Anche questo ... preso singolarmente funziona e flash e vb rispondono egregiamente ... il problema sorge che quando inserisco il comando Serial.print nel bel mezzo del mio programmone (dove è richiesto inserirlo) l'LCD smatta e il programma sull'arduino Crasha.... qualcuno sa dirmi da cosa potrebbe dipendere? darmi una dritta su cosa controllare? qualsiasi cosa.....

La scheda ho provato ad alimentarla sia con solo l'USB sia con l'ingresso indipendente... ma fa lo stesso
HELPPPPPPP MEEEEEEEEEEEEEE vi prego :slight_smile:

un piccolo up per una giusta causa :grin:

Ciao Ang3ls

Potrebbe essere un errore di programma o di ciscuito elettrico.

La Tua descrizione di quello che fai é bella e esaustiva, ma manca la descrizione come hai collegato tutto e il codice completo.

Gli stessi sintomi ci sono se aumenti la velocitá della seriale?

Ciao Uwe

il codice completo è decisamente troppo lungo.... la seriale la faccio lavorare a 115200 .....

Se tolgo tutto il codice relativo alla seriale, il programma gira perfettamente e non si blocca mai.... come aggiungo l'invio del protocollo tramite la seriale, tutto sembra impazzire... i comandi sono relativamente stupidi per quanto posso aver capito come utilizzarli....

io inserisco nella void setup l'apertura della seriale: Serial.begin(115200);
poi dove voglio inviare i valori inserisco: Serial.print("comandodainviare");

Preciso che utilizzo come seriale lo stesso usb che utilizzo per la programmazione... che ho provato anche con l'alimentazione stabilizzata a 9V ottenuta da un alimentatore esterno e che stò impazzendo a cercare il perchè singolarmente tutto funziona.... pure la seriale... ma se metto insieme il tutto improvvisamente il display impazzisce e non sempre allo stesso punto.... il punto di blocco varia sempre nel tempo....

DAI SUSUSUSSU DATEMI CONSIGLI VI PREGO.... grazie UWE

dalla sfera di cristallo direi che stai usando i pin della seriale (digital 0 e 1) come pin per il led, o per le misurazioni.

grazie per il tentativo lesto.... ma non è così, il pin 0 e 1 sono regolarmente "NON USATI" per tali scopi.... anzi non sono usati affatto... e commentando il begin della seriale e tutti gli altri comandi inerenti la seriale... il programma gira regolarmente e fa tutte le sue misurazioni perfettamente....

Cmq grazie veramente per il tentativo.... e se ti serve qualche dato in più per non usare la sfera di cristallo non fai che chiedere... io pensavo che forse usare la stessa usb che uso per la programmazione non è che funzioni molto bene.... ma da qui ad esserne certo, e soprattutto da qui a far piantare tutto, mi sembra un passo decisamente troppo lungo....

Sto facendo prove su prove... fatevi sentire ragazzi, ho bisogno di voi

Sono ripresi i tentativi di prima mattina,volevo aggiungere che visto che ho ordinato un altro ARDUINO UNO ieri sera ho provato a cambiare il micro con nessun risultato (leggendo il lato positivo vuol dire che anche l'altro micro è integro) e altro tentativo fatto è stato quello di inserire nel codice al posto di Serial.print("COMANDO") il richiamo ad una funzione esterna che facesse ugualmente l'invio sulla seriale.... risultato? come ci insegnavano in matematica CAMBIANDO L'ORDINE DEGLI ADDENDI IL RISULTATO NON CAMBIA....

Altri tentativi che posso fare?

Domanda. Come comunichi con l'LCD?

#include <LiquidCrystal440.h>

poi ho impostato due set personalizzati di caratteri per formare scritte e numeri in stile BIG FONT.... ma l'LCD lavora perfettamente se tolgo le varie operazioni sulla seriale....

Qualche idea Leo ?

Mi viene da pensare a qualche problema tra la LiquidCrystal e la Seriale ma siccome non ho usato mai la prima, non so dirti.
Cmq è difficile senza vedere tutto il codice. Perché non vuoi pubblicarlo? Basta metterlo fra i tag CODE.

Non l'ho pubblicato solo perchè lunghissimo e pieno cmq di dati "sensibili" ... cmq hai pienamente ragione... ti posto una parte del codice che uso per TEST in quanto mi da sempre errore.... è una simulazione di un amperometro su una linea telefonica... tieni presente che quando viene visualizzato il messaggio "Sollevare o riagganciare la cornetta" dovrebbe inviare i comandi sulla seriale che è stata aperta nel void setup.... vedi se riesci a vedere un ORRORE di programmazione, anche se credo che non ce ne siano di grossolani perchè il codice senza il Serial.print funziona egregiamente.... ma mai dire mai... magari 4 occhi vedono meglio di 2

void Amperometro() {
  int primocontrollo = 0;
  int secondocontrollo = 0;
  int value = analogRead(analogInput);
  while (value < 250) {
    lcd.setCursor(2,1);
    lcd.print("Riagganciare la Cornetta per il Test"); 
    if (cornetta != 0) {
    Serial.print("***COFF,0,END###");
    cornetta = 0;
    }
    value = analogRead(analogInput);
    delay(50);
  }
  lcd.clear();
  while (strumentazione == 1) {
  for (int amp_contaJ = 0; amp_contaJ < 3; amp_contaJ++) { 
     if (cornetta != 2) {
  Serial.print("***RUN,0,END###");
  cornetta = 2;
  } 
  lcd.setCursor(0,1);
  lcd.print("                      ");
  lcd.setCursor(0,1);
  for (int amp_contai = 0; amp_contai < 22; amp_contai++) {
  lcd.setCursor(amp_contai,1);
  lcd.print(char(255)); 
  tone(buzzers, 1200, 100);
  
   value = analogRead(analogInput);
  
   if (digitalRead(pulsante2) == HIGH) {
   digitalWrite(leds, HIGH);   // set the LED on
   lcd.clear();
   caratteri = 1;
   cambiacarattere(1);
   strumentazione = 0;
   jalias = 4;
   delay(100);
   digitalWrite(leds, LOW);
   DisegnaMenu();
   lcdpubblicita();
   return;
   }
   int ritardoscans = analogRead(analogInput3);
   lcd.setCursor(0,0);
   lcd.print("Scansione: " ); //+ String(ritardoscans) + " ms  ");
   lcd.print(String(ritardoscans));
   lcd.print(" ms ");
   lcd.setCursor(27,0);
   lcd.print("Milliampere");
   lcd.setCursor(0,3);
   lcd.print("Stato della Linea: ");
   if (value > 250) {
   lcd.setCursor(19,3);
   lcd.print("OFF");
   scrivilcd(30,0);                      // 30 VIENE RICONOSCIUTO COME CARATTERE DI START
   scrivilcd(48,0);
   scrivilcd(48,1);
   scrivilcd(48,2);
   scrivilcd(48,3);
   scrivilcd(31,0);                      // 31 VIENE RICONOSCIUTO COME CARATTERE DI STOP
   } else {
   lcd.setCursor(19,3);
   lcd.print("ON ");
   scrivilcd(30,0);                      // 30 VIENE RICONOSCIUTO COME CARATTERE DI START
   scrivilcd(48,0);
   scrivilcd(48,1);
   if (alarm_flag == 0) {
   scrivilcd(50,2);                      //SCRIVI UN 2
   scrivilcd(random(52,58),3);           //SCRIVI UN NUMERO VARIABILE DA 4 A 9
   scrivilcd(31,0);                      // 31 VIENE RICONOSCIUTO COME CARATTERE DI STOP
   } else {
        scrivilcd(random(52,53),2);
        scrivilcd(random(48,58),3);
        scrivilcd(31,0);
      }
    }

    delay(ritardoscans);
    }
    }
    delay(500);
    primocontrollo = 1;
    if ((primocontrollo == 1) && (secondocontrollo == 1)) {
      lcd.clear();
      esito_test();
      strumentazione = 0;
      caratteri = 1;
      cambiacarattere(1);
      DisegnaMenu();
      lcdpubblicita();
      return;
    }
delay(1000);
value = analogRead(analogInput);
while (value>250) {
  lcd.clear();
  lcd.setCursor(2,1);
  lcd.print("Sollevare la Cornetta per Continuare"); 
  if (cornetta != 1) {
  Serial.print("***CON,0,END###");
  cornetta = 1;
  }
  value = analogRead(analogInput);
  delay(100);
}
   secondocontrollo = 1;
   lcd.clear();
  }

   lcd.clear();
   caratteri = 1;
   cambiacarattere(1);
   strumentazione = 0;
   jalias = 4;
   delay(100);
   DisegnaMenu();
   lcdpubblicita();
   return;
}

Io non vedo "Sollevare o riagganciare la cornetta" nella porzione di codice da te pubblicato.
Ma in che punto esatto ti da il problema?

Se vedi intorno al 10 rigo trovi "Riagganciare la cornetta per continuare" e dopo un if ho inserito l'invio sulla seriale del protocollo che ho adottato .... quel ***CON,0,END## ....

in pratica spesso (perchè non crasha mai nello stesso punto) se la cornetta del telefono è su... mi chiede di riagganciare... inizia il ciclo ma dopo 3 o 4 volte si blocca... raramente è andato oltre....

l'altro comando lo trovi sul finire del codice....

spero di essere stato chiaro

Vediamo se ho capito.
Tu leggi un pin analogico per capire quando l'utente ha agganciato la cornetta. Forse il problema è lì? Cioè che non riesci a leggere un valore sotto alla soglia che ti serve per uscire dal ciclo while?
Cos'hai collegato al pin analogico? E come?

al pin ho collegato un partitore di tensione per leggere valori da 0 a 5.... ma riesco a leggerlo perfettamente perchè senza la seriale il tutto funziona perfettamente.... e non vado in un loop infinito non uscendo dal while.... ma semplicemente si blocca l'esecuzione del codice... quasi comese si congelasse il programma.... e dopo un pò l'LCD inizia a smattare....

Sono sempre più in alto mare uff

ma stai usando arduino mega?

allora, riassumendo, senza serial funziona tutto bene, ma se metti la serial impazzisce...
Ma il PC riceve il messaggio dalla serial? impazzisce subito, o dopo vari test consecutivi??
per caso usi molte variabili globali/array?

si di variabili globali ne uso abbastanza.... lo ammetto.... uso arduino UNO .... senza seriale però funziona tutto alla meraviglia e non mi spiego perchè delle semplici righe lo fanno impazzire.... specie se inserite nel blocco che ti ho inviato... negli altri blocchi e funzioni se inserisco un Serial.print lo processa regolarmente... sembra proprio che in quel blocco per i vari cicli gli dia fastidio fermarsi per inviare il comando sulla seriale... ma non ne vedo il motivo.... secondo te?

La libreria Serial si ciuccia un sacco di ram come buffer per la seriale...
togli la serial, e fai un test della ram disponibile con il codice che trovi quì:
http://forum.pololu.com/viewtopic.php?f=10&t=989#p4218
(a quanto pare per valori molto piccoli di ram disponibile, < 29byte, sballa, quindi prova senza serial)

posta il risultato dell'operazione.

non riesco a capire come fare cio che mi chiedi..... ufff mi sa che sto fondendo

aggiungi questa funzione al tuo codice:

    extern void __bss_end;
    extern void *__brkval;

    int get_free_memory()
    {
      int free_memory;

      if((int)__brkval == 0)
        free_memory = ((int)&free_memory) - ((int)&__bss_end);
      else
        free_memory = ((int)&free_memory) - ((int)__brkval);

      return free_memory;
    }

poi al posto delle serial fai (probabilmente il codice sottostante non è giusto, sistematelo :D):

lcd.print("Ram disponibile:"); 
lcd.print( get_free_memory() );