Event listener?

Salve, premetto già da ora di essere alle prime armi con arduino, e di avere conoscenze di programmazione elementari (C++: operatori logici, if, cicli, array, matrici, matrici vettoriali); stavo cercando un modo per memorizzare un valore numerico da conservare anche quando la scheda è spenta (Arduino UNO), da poter ritrovare poi anche nelle successive esecuzioni, e mi hanno suggerito di usare la libreria EEPROM. Fatte le dovute ricerche, sperando di aver acquisito informazioni giuste, volevo sperimentare la libreria in modo “simpatico”: sfruttando un display LCD, interagire con Arduino mandandogli input mediante il monitor seriale (dato che non saprei come collegare ne tastiere ne tastierini ad Arduino UNO), memorizzare questi valori e, se richiesto, leggerli sempre su monitor LCD, tutto questo creando una specie di “menù”. Come risultato avrei voluto vedere se alla prima esecuzione del programma mi memorizzasse i dati, e se alla seconda mi sarebbe riuscito a leggere i dati inseriti nella precedente esecuzione del programma, sperando che la libreria funzionasse e che i miei dati non fossero andati persi al termine del programma precedente. Ma la funzione void “loop”, come mi aspettavo, mi ha creato problemi! Le istruzioni nella funzione venivano ripetute all’infinito senza aspettare i miei input, e per evitare questo problema, ho sentito parlare di questi “event listener”, sotto-programmi scritti in C da inserire nello sketch, ma io non so assolutamente come si scrivano, dove si scrivano, e come si aggiungano agli sketch di Arduino. Il codice che ho scritto io fino ad ora, tanto per rendere un idea di quel che voglio fare, è questo:

#include <LiquidCrystal.h>

#include <SoftwareSerial.h>

#include <EEPROM.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int comando = 0;
int a, b, valore;

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);
}

do{
  lcd.print("1=Scrivi 2=Leggi");
  comando = Serial.read();

  if (comando==1){
    lcd.print("Inserisci locazione");
    a = Serial.read();       
    lcd.print("Inserisci valore");
    b = Serial.read();
    EEPROM.write(a, b);
    }

    if (comando==2){
      lcd.print("Inserisci locazione");
      a = Serial.read();
      valore = EEPROM.read(a);
      lcd.print(valore);
      }

    lcd.print("Vuoi terminare? s/n");
    comando = Serial.read();
  } while(comando=='n');

Se qualcosa che ho detto non vi è chiara, o magari pensate che abbia sbagliato a capire, ditemelo, sono ben accetti consigli e sopratutto critiche!

Saluti a tutti, SadaZ.

  1. Il codice va messo tra i tags relativi. Usa il pulsante con simbolo #
  2. Qual codice non compila. La funzione loop() è obbligatoria. E non puoi scrivere del codice brutalmente dove vuoi. Da quella do{ in poi deve stare dentro ad una funzione.

  3. La struttura di un programma per Arduino è obbligatoria, in quanto in realtà il programma principale di nascosto stà da un'altra parte:

void main()
{ setup();
  while(1) loop();
}

Questo è circa lo scheletro (non è completo). La funzione seup() e quindi tutto quello che ci scrivi dentro viene eseguita 1 volta sola. La funzione loop() viene eseguita in maniera infinita, in loop come dice il nome stesso. Su Arduino non sei su un PC dove il programma può finire, il codice nella loop() viene ripetuto all'infinito.

nid69ita:

  1. Il codice va messo tra i tags relativi. Usa il pulsante con simbolo #

  2. Qual codice non compila. La funzione loop() è obbligatoria.
    E non puoi scrivere del codice brutalmente dove vuoi. Da quella do{ in poi deve stare dentro ad una funzione.

  3. La struttura di un programma per Arduino è obbligatoria, in quanto in realtà il programma principale di nascosto stà da un’altra parte:

void main()

{ setup();
  while(1) loop();
}



Questo è circa lo scheletro (non è completo). La funzione seup() e quindi tutto quello che ci scrivi dentro viene eseguita 1 volta sola.
La funzione loop() viene eseguita in maniera infinita, in loop come dice il nome stesso.
Su Arduino non sei su un PC dove il programma può finire, il codice nella loop() viene ripetuto all'infinito.

Quindi la funzione loop è obbligatoria, e per eseguire passo passo i comandi che vorrei far eseguire, interrompendo il programma in attesa dei miei input, dovrei mettere il tutto dentro un’altra funzione all’interno di quella “loop”?

@SadaZ: quando ti consigliano qualcosa, è bene farlo ;)

nid69ita: 1. Il codice va messo tra i tags relativi. Usa il pulsante con simbolo #

Ti invito a leggere il regolamento del forum. Sei nuovo e magari ti è sfuggito :P

leo72: @SadaZ: quando ti consigliano qualcosa, è bene farlo ;)

nid69ita: 1. Il codice va messo tra i tags relativi. Usa il pulsante con simbolo #

Ti invito a leggere il regolamento del forum. Sei nuovo e magari ti è sfuggito :P

Si xD ho visto il punto 1 della prima risposta xD infatti sono nuovo xD ora che lo so, farò così xD leggerò il regolamento comunque

come ben detto da nid viene prima eseguita solo una volta la funzione setup() e dopo infinite volte la funzione loop(). All'interno del loop devi leggere continuamente i valori dei pin(DIGITALI,ANALOGICI) ed effettuare i tuoi controlli ES:

#define PIN 2
void setup(){
    pinMode(PIN,INPUT);
}

void loop(){
    byte stato = digitalRead(PIN);
    if(stato == HIGH){
        //Se il tasto è premuto vado qui
    }else{
        //Se il tasto non è premuto vado qui
    }
}

Come vedi è "in continuo ascolto" dato che cicla infinite volte ad una velocità variabile in base agli hz del micro.. Spero di esserti stato utile.. :)

Ok, ho capito che la funzione setup viene ripetuta una sola volta e la loop infinite volte ad una velocità di tempo variabile a seconda della velocità del processore della scheda, ma come faccio ad eseguire il codice che ho scritto io, passo passo? Lo devo mettere nella funzione setup e lasciare la loop vuota, oppure c'è un istruzione precisa per stoppare il programma in un punto in cui voglio io in attesa di input? Oppure bisogna fare addirittura tutt'e due? Scusate se rompo xD ma la programmazione in Arduino è diversa da quella che ho affrontato nell'ambiente del C, e lì ogni volta che volevo dare un input, il programma aspettava che lo facessi xD ma qui no :(

la tua richiesta è abbastanza ardua da affrontare se sei alle prime armi.. ad ogni modo ti consiglio di dare una lettura a questo tutorial: http://www.coagula.org/content/pages/tutorial-manage-menu-and-lcd-display-arduino Se vuoi affrontare la tua problematica in maniera più scarna dovresti scrivere un while per ogni richiesta. Occhio però ad effettuare una pulizia del buffer della porta seriale facendo un Serial.flush();

SadaZ: .... ma la programmazione in Arduino è diversa da quella che ho affrontato nell'ambiente del C, e lì ogni volta che volevo dare un input, il programma aspettava che lo facessi xD ma qui no :(

Perché ti veniva NASCOSTO, da qualche funziona ad alto livello, quello che realmente dietro accadeva ...

Te la puoi fare anche tu ... crei una piccola funzione in cui chiuso dentro un loop while controlli se c'è qualche cosa sulla seriale (... puoi usare la Serial.available()), se non c'è nulla rimani nel loop altrimenti leggi il carattere (... così svuoti il buffer) e ritorni. Fatta questa, ogni passo dove ti vuoi fermare la chiami e, finché non arriva un carattere sulla seriale, il tuo programma non avanza ;)

Guglielmo

Come detto da Guglielmo lo trasformo in codice 8)

byte attendi(){
    Serial.flush();
    while(1){
        if (Serial.available() > 0) {
                return Serial.read();
        }
    }
}

Byeeeeee ]:D

Antroid: Come detto da Guglielmo lo trasformo in codice 8) ...

Antroid ... mai fornire agli iniziandi la "pappa fatta" ... fai più danni che altro, visto che non imparano nulla e non fanno lo sforzo per imparare ... ;)

Guglielmo

gpb01:

Antroid: Come detto da Guglielmo lo trasformo in codice 8) ...

Antroid ... mai fornire agli iniziandi la "pappa fatta" ... fai più danni che altro, visto che non imparano nulla e non fanno lo sforzo per imparare ... ;)

Guglielmo

sorry ma ho visto SadaZ in difficoltà.... scusami ancora Guglielmo..

mmmm… sono cotto, ho scritto un posto e come un tonto ho pigiato il tasto sbagliato e ho perso il contenuto.

Riepilogo, in breve:

comando = Serial.read();

  if (comando==1){

questo funziona solo se riesci a spedire il carattere non stampabile che ha codice ascii 1, meglio lavorare con i caratteri stampabili.

comando = Serial.read();

  if (comando == 'A') {
      .... 
  } else if (comando == 'B') {
      ....
  } else if ....

Ovviamente da PC via seriale devi inviare il carattere A o B.

Facendo il paragone automobilistico, sei su una sportiva trazione posteriore priva di assistenza alla guida, niente ABS, idroguida ecc e tutto nelle tue mani e c’è a malappena una cosa che somiglia vagamente ad un volante e ci sono anche altri modi di sterzare frenare e accellerare. Lo stile di programmazione arduinico aiuta parecchio, ma siamo lontanissimi dalla programmazione lato PC.

Ciao.

Antroid: ... sorry ma ho visto SadaZ in difficoltà.... scusami ancora Guglielmo..

ehi ... non c'è mica bisogno di scuse ... ci mancherebbe ... ;)

Era solo un'indicazione da tenere sempre presente ... :)

Guglielmo

SadaZ hai risolto? :)