gestione eventi

dalve a tutti ecco il mio problema....ho scritto un programma su arduino e funziona fa il suo dovere.... adesso dovrei inserire le routine per delle simulazioni... cioè io ho 3 pulsanti.... quando non premo nulla deve andare in loop il programma principale... quando ne premo uno deve andare in loop un programa di simulazione... quando premo l'altro( solo l'altro) ne deve andare un altra di simulazione... quando premo il terzo(solo il 3) ne deve girare un altra di simulazione.... ho provato a gestire il tutto con la lettura digitale e gli if... ma arduino è come se si impallasse non va.... solo con i programma principale gira, se inserisco le routine di dimulazione non funziona neanche il principale... come potrei fare?

Se non inserisci il tuo sorgente non possiamo aiutarti così d'un colpo :D Prova a inserirlo e vediamo cosa possiam fare

eccolo

#include <hcf4511be.h>
hcf4511be unita(2,3,4,5);
hcf4511be deci(6,7,8,9);
int bpm;
int decine;
int centinaia;
int unit;
int A;
int bt=A1;
int bt2=A2;
int bt3=A3;
int allarme=10;
int tappetopin = 11;
const int  CardioPin = A0;    
const int ledPin = 13;       

long oldMillis;
long oldMillis_antiBounce;

byte contatore = 0;
byte stato = 0;
byte ultimoStato = 0;


void setup() {
  pinMode(bt, INPUT);
  pinMode(bt2, INPUT);
  pinMode(bt3, INPUT);
  pinMode(allarme, OUTPUT);
  pinMode(tappetopin, OUTPUT);
  pinMode(CardioPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(12, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
  oldMillis = millis();
  oldMillis_antiBounce = oldMillis;
  
}


void loop() {
  digitalRead(bt);
  digitalRead(bt2);
  digitalRead(bt3);
  
  if ((bt==LOW) && (bt2==LOW)&& (bt3==LOW)){
  
   
  stato = digitalRead(CardioPin);
  if (stato != ultimoStato) {

    if (stato == HIGH) {
      //sistole...fronte di salita...
      digitalWrite(ledPin, HIGH);
      if ( millis()- oldMillis_antiBounce  > 10)
              {  // se impiega meno di 10 millisecondi per cambiare di stato è un rimbalzo e non lo conto
              contatore ++;
              oldMillis_antiBounce = millis();

              };
                    
      } else {
      // else stato = low significa che sono in diastole
              digitalWrite(ledPin, LOW);
     
      
    } 
    ultimoStato = stato;  // lo stato è variato
  }

   if ( millis()- oldMillis  > 15000) {
     //15 secodi di statistica... calcolo media
   
     Serial.print ("bpm:");
     Serial.println ( contatore * 4);
       bpm= contatore*4;

centinaia= bpm/100;
A= bpm- (centinaia*100);
 decine= A/10;
 unit= A- (decine*10);
 Serial.print ("CENTINAIA:");
  Serial.println(centinaia);
 Serial.print ("DECINE:");
 Serial.println(decine);
 Serial.print ("UNITA:");
  Serial.println(unit);
  unita.sendOut(unit);
  deci.sendOut(decine);
  if(centinaia > 0)
  {
    digitalWrite(12, HIGH);
}
  else
{
  digitalWrite(12,LOW);
}
     contatore = 0;
     oldMillis = millis();
     oldMillis_antiBounce =      oldMillis;
     }
  if ( bpm < 60)  //in cascata//
  { analogWrite(tappetopin, 255);}
 else if ( bpm < 80)
  { analogWrite(tappetopin, 229);}
    else if ( bpm < 100) 
    {analogWrite(tappetopin, 204);}
    else if ( bpm < 120)
  { analogWrite(tappetopin, 178);} 
      else if ( bpm < 140)
  { analogWrite(tappetopin, 153);}
 else if ( bpm <= 180)
  { analogWrite(tappetopin, 125);} 
else if ( bpm > 180)
  { analogWrite(tappetopin, 0);
tone(allarme, 2400);
  delay(500);
  noTone(allarme);
  delay(500);
}

}
else if ((bt==HIGH) && (bt2==LOW)&& (bt3==LOW))
 {
  analogWrite(tappetopin, 0);
tone(allarme, 2400);
  delay(500);
  noTone(allarme);
  delay(500);
  unita.sendOut(0);
  deci.sendOut(9);
  digitalWrite(12, HIGH);
  }
  else if ((bt==LOW) && (bt2==HIGH)&& (bt3==LOW)){
    analogWrite(tappetopin, 178);
     unita.sendOut(0);
  deci.sendOut(1);
  digitalWrite(12, HIGH);  } 
  else if ((bt==LOW) && (bt2==LOW)&& (bt3==HIGH)){
    analogWrite(tappetopin, 204);
    unita.sendOut(0);
  deci.sendOut(9);
  digitalWrite(12, LOW);}
  
  }

nessuno puo aiutarmi?

Sull'Arduino non esiste il concetto di più programmi che girano o che vengono lanciati. Il programma è unico, lo sketch che carichi, che può contenere più "funzioni". Per far ciò che vuoi devi solo mettere nel loop un controllo sulla pressione dei pin a cui hai collegato i tuoi pulsanti e poi chiamare le corrispondenti routine.

Non ho esaminato a fondo il tuo codice ma lì dentro non ho visto grosse funzioni da richiamare.

ok ma come faccio a fare questo controllo? ci ho provato ma il risultato è che non funziona piu niente!

prova ad usare il costrutto switch case. Scrivi un’altro programma che usa lo switch case e intercetta la pressione dei tasti e per ogni case dello switch invia qualcosa di indicativo via seriale, postalo così lo commentiamo.

Tutto il codice che hai postato è di intralcio al momento e lo integrerai dopo.

Ciao.

Per fare il controllo dei pulsanti devi definire tante variabili di tipo INT quanti sono i tuoi pulsanti; esempio int p1,p2,p3;

ad ogni variabile associ la pressione di un pulsante cosi' (questo in setup() ) int a1=pinMode(p1,INPUT), e cosi via con a2,a3....

Nel loop() controlli se a1,a2 o a3 passano da false a true (ovvero se vengono premuti)

if(a1 == true) { delay(500); //funzione 1 } else if(a2== true) { //delay //funzione 2 } else if(a3 == true) { //delay //funzione 3 }

Mi sono dimenticato che nel loop() , prima di verificare il valore di a1,a2,a3, devi definirli cosi :

a1=digitalRead(p1); a2=digitalRead(p2); a3=digitalRead(p3);

e poi come prima:

if(a1 ==true ) {// funzione 1 ..} else if ....

Si possono premere 2 pulsanti in contemporanea? se si il costrutto

if(a1==TRUE){}
else if(a2==TRUE){}
else if(a3 == true) {}

è sbagliato perchè non permette la gestione corretta di piú tasti premuti insieme. Ciao Uwe

No, il mio esempio non include la pressione contemporanea di tasti; non ho mai provato a realizzarlo …
Pero’ tieni conto che quando tu premi un tasto, la variabile intera che gli hai associato resta TRUE per un certo numero di millisecondi, da quel che ho visto sono circa una decina di loop() ; quindi in teoria se premi ‘insieme’ due pulsanti c’è caso che venga riconosciuta la pressione contemporanea dei due tasti…
mi sono spiegato?

Buongiorno a tutti, mi sto avvicinando ora al mondo Arduino per la realizzazione di alcuni, semplici, progetti modellistici.
Avendo la necessità di riprodurre casualmente dei file .mp3, ho scritto uno sketch il quale per ogni pressione su un tasto, ne riproduce uno, a caso da un gruppo di 16. Funziona.
L’appetito vien mangiando e quindi ho pensato che abbinare un movimento casuale di un servo alla riproduzione degli mp3 potesse rendere più “vivo” il progetto. Quindi usando lo stesso sketch con le opportune modifiche, riesco a far fare rotazioni di 16 angoli diversi, a caso, al braccio del servo. Quello che non riesco a fare sono le due cose insieme; ossia riprodurre un mp3 a caso e far eseguire un movimento casuale al servo. Viene sempre e solo riprodotto un file mp3. Di seguito lo sketch dove sono attivi i comandi per gli mp3 e disattivati quelli per i movimenti del servo:

#include <Servo.h>
#include <SdFat.h>
#include <MP3Player.h>
Servo myservo;               // creo l'oggetto myservo

int grado = 85;                // variabile per la posizione iniziale del servo
int pinServo = 9;              // variabile per il pin di collegamento del servo
int RS;                           // variabile random per servo
int RA;                           // variabile random per mp3
int tasto = 6;                  // variabile per il pin di collegamento del tasto

void setup() {
 pinMode (tasto, INPUT_PULLUP);  
 randomSeed(analogRead(A0));       //generazione di un valore random in base allo stato di A0 non in uso

 RS = random(1, 17);                    // valori random da 1 a 16
 RA = random(1, 17);                    // valori random da 1 a 16
 
 mp3.Init(3, 2);                            // inizializzazione scheda mp3 (MP3Shield della Cytron)
 myservo.attach( pinServo );          // servo collegato al pin della variabile pinServo (9)
 myservo.write( grado );                // posizione iniziale del servo in base alla variabile grado (85)

}

void loop()
{

 RS = random(1, 17);
 RA = random(1, 17);
 int val = digitalRead (tasto);        // variabile che registra lo stato del tasto
 
 if (val == LOW && RA == 1)  { mp3.PlayTrack("1.mp3");     delay(1000);  }
//if (val == LOW && RS == 1){myservo.write(0) ;delay(500);}
 if (val == LOW && RA == 2)  { mp3.PlayTrack("2.mp3");     delay(1000);  }
//if (val == LOW && RS == 2){myservo.write(85) ;delay(500);}
 if (val == LOW && RA == 3)  { mp3.PlayTrack("3.mp3");     delay(1000);  }
//if (val == LOW && RS == 3){myservo.write(170) ;delay(500);}
 if (val == LOW && RA == 4)  { mp3.PlayTrack("4.mp3");     delay(1000);  }
//if (val == LOW && RS == 4){myservo.write(0) ;delay(500);}
 if (val == LOW && RA == 5)  { mp3.PlayTrack("5.mp3");    delay(1000);  }
//if (val == LOW && RS == 5){myservo.write(85) ;delay(500);}
 if (val == LOW && RA == 6)  { mp3.PlayTrack("6.mp3");    delay(1000);  }
//if (val == LOW && RS == 6){myservo.write(170) ;delay(500);}
 if (val == LOW && RA == 7)  { mp3.PlayTrack("7.mp3");    delay(1000);  }
//if (val == LOW && RS == 7){myservo.write(0) ;delay(500);}
 if (val == LOW && RA == 8)  { mp3.PlayTrack("8.mp3");    delay(1000);  }
//if (val == LOW && RS == 8){myservo.write(85) ;delay(500);}
 if (val == LOW && RA == 9)  { mp3.PlayTrack("9.mp3");    delay(1000);  }
//if (val == LOW && RS == 9){myservo.write(170) ;delay(500);}
 if (val == LOW && RA == 10)  { mp3.PlayTrack("10.mp3");    delay(1000);  }
//if (val == LOW && RS == 10){myservo.write(0) ;delay(500);}
 if (val == LOW && RA == 11)  { mp3.PlayTrack("11.mp3");    delay(1000);  }
//if (val == LOW && RS == 11){myservo.write(85) ;delay(500);}
 if (val == LOW && RA == 12)  { mp3.PlayTrack("12.mp3");    delay(1000);  }
//if (val == LOW && RS == 12){myservo.write(170) ;delay(500);}
 if (val == LOW && RA == 13)  { mp3.PlayTrack("13.mp3");    delay(1000);  }
//if (val == LOW && RS == 13){myservo.write(0) ;delay(500);}
 if (val == LOW && RA == 14)  { mp3.PlayTrack("14.mp3");    delay(1000);  }
//if (val == LOW && RS == 14){myservo.write(85) ;delay(500);}
 if (val == LOW && RA == 15)  { mp3.PlayTrack("15.mp3");     delay(1000);  }
//if (val == LOW && RS == 15){myservo.write(170) ;delay(500);}
 if (val == LOW && RA == 16)  { mp3.PlayTrack("16.mp3");     delay(1000);  }
//if (val == LOW && RS == 16){myservo.write(0) ;delay(500);}
//myservo.write( 85) ;
}

Ciò che ho provato, ma non funziona, nel senso che viene solo riprodotto il file, è stata la seguente stringa:

if (val == LOW && RA == 1){ mp3.PlayTrack("X.mp3");delay(500);myservo.write(Y);delay(1000);}

dove X è il nome del file e Y l’angolo del braccio del servo diversi per ogni stringa. Le schede che sto usando sono:
Arduino Uno rev. 3
MP3Shield della Cytron Technologies

Qualche dritta?

>peterbod: Prima di tutto, essendo il tuo primo post, nel rispetto del regolamento, ti chiedo di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione … possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il su citato REGOLAMENTO

… poi, in conformità al suddetto regolamento, punto 7, edita (in basso a destra del post, bottone More → Modify) il tuo post e racchiudi il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone fatto così: </>, tutto a sinistra).

Grazie,

Guglielmo

Beh, come inizio non c'è male, :) . Grazie per tutte le segnalazioni, ho provveduto di conseguenza...

Sicuro che l'istruzione di play del mp3 non sia bloccante, ovvero finchè suona quel mp3 il micro è fermo in quel lavoro ? Poi... dire che suoni dei mp3 è poco. Più info. Che Mp3 player usi ? Che libreria ? Non c'e' una shield "standard" per Arduino quindi se non dici che hardware usi, difficile aiutare.

P.S. inoltre meglio aprire un proprio thread, più visibile che non agganciarsi a quello di un altro. E non mi pare poi così attinente. ;)

Ho aggiunto nel post l’hardware in uso. Comunque la scheda è la MP3Shield di Cytron Technologies. I files mp3 durano pochi secondi (riproducono rumori). Anche aumentando il delay, comunque dopo la riproduzione dell’mp3 non viene attuato il servo.

Per prova, metti il comando del servo e poi il play del file

La libreria mp3 potrebbe andare in conflitto con la libreria servo. Solo ipotesi la mia.

Fatto.
In questo caso viene eseguito lo spostamento del servo e a seguire la riproduzione dell’mp3, ma solo alla prima pressione del tasto. Le volte successive solo l’mp3. :o

Per quanto riguarda i post, ho pensato di pubblicarli qui perchè si tratta di gestione eventi, ma se non va bene sposto la domanda in un topic nuovo.