interruzione di un ciclo for alla pressione di un pulsante

ciao a tutti, abbiate pazienza , sono alla prima esperienza con arduino, sto giocando per cercare d'imparare...

vorrei che "ricordasse" la pressione del pulsante e in base al numero di volte che è premuto facesse un'operazione diversa utilizzando lo switch, il tutto funziona soltanto che quando premo il pulsante durante un ciclo for non lo "sente", lo devo tener premuto fino a quando il ciclo for non è finito, mi potete dire cosa devo modificare in modo da renderlo sensibile alla pressione del pulsante?

grazie in anticipo e scusate per la banalità della domanda

const int fotoresistenzaPin = A0;
const int redPin = 3;
const int yellowPin = 5;
const int intPin = 2;
int valpuls;
int prevvalpuls;
int npuls;



void setup(){
Serial.begin(9600);
pinMode(fotoresistenzaPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
pinMode(intPin, INPUT);

for (int i=0; i<3; i++){
digitalWrite(redPin,HIGH);
digitalWrite(yellowPin, HIGH);
delay(300);
digitalWrite(redPin,LOW);
digitalWrite(yellowPin, LOW);
delay(300);
}
npuls=0;
}

void loop(){
  
 valpuls= digitalRead(intPin);
 delay(10);
if ((valpuls == HIGH) && (prevvalpuls == LOW)){
npuls ++;
}
if (npuls == 4){
npuls=0;
}
switch (npuls){

case 0:

digitalWrite(yellowPin, LOW);
digitalWrite (redPin, LOW);
break;
  
case 1:   // caso zero
for (int i=0; i<4; i++){

digitalWrite(yellowPin, HIGH);
delay(300);
digitalWrite(yellowPin, LOW);
delay(300);
break;
}

case 2:
for (int i=0; i<4; i++){
digitalWrite(redPin, HIGH);
delay(300);
digitalWrite(redPin, LOW);
delay(300);
break;

}


}
prevvalpuls = valpuls;
Serial.print (valpuls);
Serial.print (", ");
Serial.println(npuls);



}

Ci sono due problemi in gioco,

1- il for ad ogni giro va a valutare alcune cose, esempio se i<4, per uscirbe devi avere i>4, quindi internamente al for puoi andare a leggere il pulsante, oltre a gestire i led, e se è premuto incrementi i o lo setti direttamente a 4.

2- nel for usi il delay, questo ti blocca definitivsmente ed in nessun modo puoi leggere il pulsante, quindi divredti sostituire i delay con millis, vedi esempio blink whitout delay

ho risolto, se così si può dire,togliendo i for che non servivano e diminuendo i delay così ha tempo di uscire dal case per controllare il pulsante, però non è quello che volevo fare

const int fotoresistenzaPin = A0;
const int redPin = 3;
const int yellowPin = 5;
const int intPin = 2;
int valpuls;
int prevvalpuls;
int npuls;



void setup(){
Serial.begin(9600);
pinMode(fotoresistenzaPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
pinMode(intPin, INPUT);

for (int i=0; i<3; i++){
digitalWrite(redPin,HIGH);
digitalWrite(yellowPin, HIGH);
delay(300);
digitalWrite(redPin,LOW);
digitalWrite(yellowPin, LOW);
delay(300);
}
}

void loop(){
 valpuls= digitalRead(intPin);
 //delay(10);
if ((valpuls == HIGH) && (prevvalpuls == LOW)){
npuls ++;
}
if (npuls == 4){
npuls=0;
}
switch (npuls){
case 0:                    // caso zero

break;

case 1:
//for (int i=0; i<4; i++){
  digitalWrite(redPin, HIGH);
delay(50);
digitalWrite(redPin, LOW);
delay(50);


//}
break;
case 2:                    // caso zero
//for (int i=0; i<4; i++){
  digitalWrite(yellowPin, HIGH);
delay(50);
digitalWrite(yellowPin, LOW);
delay(50);
//}
break;

case 3:                    // caso zero
//for (int i=0; i<4; i++){
  digitalWrite(yellowPin, HIGH);
  digitalWrite(redPin, HIGH);
delay(30);
digitalWrite(yellowPin, LOW);
digitalWrite(redPin, LOW);
delay(30);
//}
break;


}
prevvalpuls = valpuls;
Serial.print (valpuls);
Serial.print (", ");
Serial.println(npuls);



}

La risposta te l'ha già data Testato al punto 2- ...

... NON devi usare la delay() ma devi studiarti come si usa la millis() prima QUI, poi QUI ed infine leggi anche QUI ... vedrai che ti sarà tutto più chiaro.

Guglielmo

vado, mi dovete "imbeccare" tutto...
abbiate pazienza:(

cosa fa : " ^= "?
ledState ^= 1;

elevamento a potenza? non credo...

ho scopiazzato dal web e cercato di adattare ma l'unica cosa che funziona è il contatore dell'interruttore ma non mi esegue quello dentro il case.

const int fotoresistenzaPin = A0;
const int redPin = 3;
const int yellowPin = 5;
const int intPin = 2;
int valpuls;
int prevvalpuls;
int npuls;
unsigned long previousMillis = 0;
int ledState = 0;
unsigned long interval1 = 1000;
unsigned long interval2 = 1000;
unsigned long interval3 = 1000;
unsigned long currentMillis = millis();



void setup(){
Serial.begin(9600);
pinMode(fotoresistenzaPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
pinMode(intPin, INPUT);

for (int i=0; i<3; i++){
digitalWrite(redPin,HIGH);
digitalWrite(yellowPin, HIGH);
delay(300);
digitalWrite(redPin,LOW);
digitalWrite(yellowPin, LOW);
delay(300);
}
}

void loop(){
 valpuls= digitalRead(intPin);
if ((valpuls == HIGH) && (prevvalpuls == LOW)){
npuls ++;
}
if (npuls == 4){
npuls=0;
}
switch (npuls){
case 0:                    // caso zero

break;

case 1:

  if(currentMillis - previousMillis > interval1) {
       previousMillis = currentMillis;  

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(redPin, ledState);
  }



break;
case 2:                    
    if(currentMillis - previousMillis > interval2) {
    previousMillis = currentMillis; 
    ledState ^= 1;
    digitalWrite(yellowPin, ledState);
     }
break;

case 3:                   
  if(currentMillis - previousMillis > interval3) {
    previousMillis = currentMillis; 
    ledState ^= 1;
    digitalWrite(redPin, ledState);
    digitalWrite(yellowPin, ledState);
    }
break;


}
prevvalpuls = valpuls;
Serial.print (currentMillis);
Serial.print (", ");
Serial.print (valpuls);
Serial.print (", ");
Serial.print(ledState);
Serial.print (", ");
Serial.println(npuls);



}

cosa fa : " ^= "?
ledState ^= 1;

elevamento a potenza? non credo...

No. Operatore logico equivalente allo xor, cioè "or esclusivo". Cerca in qualche manuale C.

L'unione dell'operatore di assegnamento e un altro operatore è tipico del C++.

Il senso è: Inverti il risultato dell'operazione:
"0 ^= 1" = 1
"1 ^= 1" = 0
"0 ^= 1" = 1

Ciao.

MauroTec:
No. Operatore logico equivalente allo xor, cioè "or esclusivo". Cerca in qualche manuale C.

L'unione dell'operatore di assegnamento e un altro operatore è tipico del C++.

Il senso è: Inverti il risultato dell'operazione:
"0 ^= 1" = 1
"1 ^= 1" = 0
"0 ^= 1" = 1

Ciao.

grazie!

smilzon:
cosa fa : " ^= "?
ledState ^= 1;

elevamento a potenza? non credo...

Mmm ... ho idea che devi prenderti un bel testo di C e cominciare a studiare, poi ti riavvicinerai, sicuramente più produttivo, al tuo programma. :wink:

Puoi cominciare con QUESTO e puoi scaricarti QUESTO libro (... tranquillo, è un sito legale, purché ciò che scarichi sia per esclusivo uso PERSONALE).

Guglielmo

gpb01:
Mmm ... ho idea che devi prenderti un bel testo di C e cominciare a studiare, poi ti riavvicinerai, sicuramente più produttivo, al tuo programma. :wink:

Puoi cominciare con QUESTO e puoi scaricarti QUESTO libro (... tranquillo, è un sito legale, purché ciò che scarichi sia per esclusivo uso PERSONALE).

Guglielmo

al secondo avevo già dato una letta ....

grazie all'aiuto di un collega ho evoluto il programma , ho introdotto i millis per tenerlo libero ed ho inserito il conteggio delle volte che il pulsante è premuto e mandato al case diverso , E FUNZIONA!!

anche se per voi è una ca**ta, io sono contento!!

const int fotoresistenzaPin = A0;
const int redPin = 3;
const int yellowPin = 5;
const int intPin = 2;
int valpuls;
int prevvalpuls;
int npuls;
int pulsTemp=0;
unsigned long previousMillis2 = 0;
unsigned long previousMillis = 0;
unsigned long currentMillis2 = 0;
int ledState = 0;
unsigned long intervall = 2000;
unsigned long interval1 = 2000;
unsigned long interval2 = 250;
unsigned long interval3 = 100;
unsigned long currentMillis ;
int numeroSwitch =0;



void setup(){
Serial.begin(9600);
pinMode(fotoresistenzaPin, INPUT);
pinMode(redPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
pinMode(intPin, INPUT);

for (int i=0; i<3; i++){
digitalWrite(redPin,HIGH);
digitalWrite(yellowPin, HIGH);
delay(100);
digitalWrite(redPin,LOW);
digitalWrite(yellowPin, LOW);
delay(100);
}
}

void loop(){
delay(100);
currentMillis = millis();
valpuls= digitalRead(intPin);
  if ((valpuls == HIGH) && (prevvalpuls == LOW)){
   pulsTemp++;
   previousMillis2 = currentMillis;    
  }
  
  if(pulsTemp!=0){
    if (currentMillis-previousMillis2 > 2000){
      npuls = pulsTemp;
      pulsTemp = 0;
        }
   }
     

 




switch (npuls){
case 0:                    // caso zero
digitalWrite(yellowPin, LOW);
digitalWrite(redPin, LOW);

break;

case 1:
digitalWrite(yellowPin, LOW);

  if(currentMillis - previousMillis > interval1) {
       previousMillis = currentMillis;  

    
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

  
    digitalWrite(redPin, ledState);
  }



break;
case 2:   
digitalWrite(redPin, LOW);
    if(currentMillis - previousMillis > interval2) {
    previousMillis = currentMillis; 
    ledState ^= 1;
    digitalWrite(yellowPin, ledState);
     }
break;

case 3: 

  if(currentMillis - previousMillis > interval3) {
    previousMillis = currentMillis; 
    ledState ^= 1;
    digitalWrite(redPin, ledState);
    digitalWrite(yellowPin, ledState);
    }
break;


}
prevvalpuls = valpuls;
Serial.print (currentMillis);
Serial.print (", ");
Serial.print (valpuls);
Serial.print (", ");
Serial.print(ledState);
Serial.print (", ");
Serial.print(numeroSwitch);
Serial.print (", ");
Serial.println(npuls);



}

EDIT BY MOD: corretto post

Bravo :slight_smile:

anche se per voi è una ca**ta, io sono contento!!

Evvivaaaa!!! Mi stappo una birra!! :grin: :grin:

pablos:
Evvivaaaa!!! Mi stappo una birra!! :grin: :grin:

Testato:
Bravo :slight_smile:

:grin: :grin:

@smilzon, un consiglio. Nell'IDE premi CTRL+T e vedrai che l'editor ti fa indentazione automatica, migliorando la leggibilità di quello che hai scritto.
Ti consiglio anche di eliminare quelle mila e mila righe vuote che non servono a nulla. Ad esempio prima della istruzione switch hai 6 righe vuote inutili.

nid69ita:
@smilzon, un consiglio. Nell'IDE premi CTRL+T e vedrai che l'editor ti fa indentazione automatica, migliorando la leggibilità di quello che hai scritto.
Ti consiglio anche di eliminare quelle mila e mila righe vuote che non servono a nulla. Ad esempio prima della istruzione switch hai 6 righe vuote inutili.

ok, grazie, stasera provo

si impagina così? è troppo attaccato?

adesso devo capire come funziona la macchina ad elementi finiti (o qualcosa del genere)

edit: stati finiti

const int fotoresistenzaPin = A0;
const int redPin = 3;
const int yellowPin = 5;
const int intPin = 2;
int valpuls;
int prevvalpuls;
int npuls=1;
int pulsTemp=0;
unsigned long previousMillis2 = 0;
unsigned long previousMillis = 0;
unsigned long currentMillis2 = 0;
int ledState = 0;
unsigned long intervall = 2000;
unsigned long interval1 = 2000;
unsigned long interval2 = 250;
unsigned long interval3 = 100;
unsigned long currentMillis ;
int numeroSwitch =0;

void setup(){
  Serial.begin(9600);
  pinMode(fotoresistenzaPin, INPUT);
  pinMode(redPin, OUTPUT);
  pinMode(yellowPin, OUTPUT);
  pinMode(intPin, INPUT);
  for (int i=0; i<3; i++){
    digitalWrite(redPin,HIGH);
    digitalWrite(yellowPin, HIGH);
    delay(100);
    digitalWrite(redPin,LOW);
    digitalWrite(yellowPin, LOW);
    delay(100);
  }
}

void loop(){
  delay(100);
  currentMillis = millis();
  valpuls= digitalRead(intPin);
  if ((valpuls == HIGH) && (prevvalpuls == LOW)){
    pulsTemp++;
    previousMillis2 = currentMillis;    
  }
  if(pulsTemp!=0){
    if (currentMillis-previousMillis2 > 1000){
      npuls = pulsTemp;
      pulsTemp = 0;
    }
  }
  switch (npuls){
  case 1:                    // caso zero
    digitalWrite(yellowPin, LOW);
    digitalWrite(redPin, LOW);
    break;
  case 2:
    digitalWrite(yellowPin, LOW);
    if(currentMillis - previousMillis > interval1) {
      previousMillis = currentMillis;  
      if (ledState == LOW)
        ledState = HIGH;
      else
        ledState = LOW;
      digitalWrite(redPin, ledState);
    }
    break;
  case 3:   
    digitalWrite(redPin, LOW);
    if(currentMillis - previousMillis > interval2) {
      previousMillis = currentMillis; 
      ledState ^= 1;
      digitalWrite(yellowPin, ledState);
    }
    break;
  case 4: 
    if(currentMillis - previousMillis > interval3) {
      previousMillis = currentMillis; 
      ledState ^= 1;
      digitalWrite(redPin, ledState);
      digitalWrite(yellowPin, ledState);
    }
    break;
  }
  prevvalpuls = valpuls;
  Serial.print (currentMillis);
  Serial.print (", ");
  Serial.print (valpuls);
  Serial.print (", ");
  Serial.print(ledState);
  Serial.print (", ");
  Serial.print(numeroSwitch);
  Serial.print (", ");
  Serial.println(npuls);
}

No va benone. :slight_smile:

http://www.lucadentella.it/2013/04/30/macchina-a-stati-finiti-e-arduino/

purtroppo il collega(nonchè mio guru) che mi aiuta di solito è attualmente molto indaffarato e non ha tempo da dedicarmi, sono quindi qui a chiedervi aiuto di nuovo, sto facendo qualche esperimento con l'RFID ho trovato 2 sketch on line uno per la lettura dei tag e l'altro per il confronto, ho letto i 2 tag e inserito questi 2 valori nello sketch sotto ( sostituiti con xxx perchè sono i transponder del mio allarme) ho il seguente problema:

  • ogni volta che metto un tag, sia giusto che sbagliato, mi esegue 2 volte il programma ( ho fatto un video ma non saprei come postarlo)

il secondo problema(marginale) sarebbe quello di fargli comporre una melodia mentre il relay e il servo sono azionati, non saprei dove/come inserire la funzione musica, per il momento l'ho inserita nel loop per vedere cosa suonasse , emette qualche suono ma non è sicuramente per elisa infatti mi sto studiando sta cosa http://www.arduino.cc/en/Tutorial/melody

ciao e grazie in anticipo

//-------------------------------------------------------------------------------------------------------------
#include <SoftwareSerial.h>
#include <Servo.h>
SoftwareSerial RFID(2, 3); // RX and TX
int data1 = 0;
int TApertura = 3000;  // tempo che il raly deve essere eccitato int ok = -1; int yes = 13; int no = 12; int relay = 8; int pinServo = 11; // use first sketch in http://wp.me/p3LK05-3Gk to get your tag numbers int tag1[14] = {XXX};
int tag2[14] = {XXX };
int newtag[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // used for read comparisons Servo myServo;
   unsigned long time= millis();
   unsigned long prevtime = time;
   int nota;
   int i=0;

int DO=1046;
int DOd=1109;
int RE=1175;
int REd=1245;
int MI=1319;
int FA=1397;
int FAd=1480;
int SOL=1568;
int SOLd=1661;
int LA=1760;
int LAd=1865;
int SI=1976;
char perElisa[]={'MI','REd','MI','REd', 'MI', 'SI', 'RE', 'DO', 'LA', 'DO', 'MI', 'LA', 'SI', 'MI', 'SOL', 'SI', 'DO', 'MI', 'REd', 'MI', 'REd', 'MI', 'SI', 'RE', 'DO', 'LA', 'DO', 'MI', 'LA', 'SI', 'MI', 'DO', 'SI', 'LA', 'SI', 'DO', 'RE', 'MI'};//, 'SOL', 'FA', 'MI', 'RE', 'FA', 'MI', 'RE','DO', 'MI', 'RE', 'DO', 'SI', 'MI', 'REd', 'MI' 'REd', 'MI','SI', 'RE', 'DO', 'LA', 'DO', 'MI', 'LA', 'SI', 'MI', 'DO', 'SI', 'LA'};



void setup()
{
   myServo.write(0); // imposta lo stato iniziale del servo all'avvio
   RFID.begin(9600); // start serial to RFID reader
   Serial.begin(9600); // start serial to PC
   pinMode(yes, OUTPUT); // for status LEDs
   pinMode(no, OUTPUT);
   myServo.attach(pinServo);
}
boolean comparetag(int aa[14], int bb[14]) {
   boolean ff = false;
   int fg = 0;
   for (int cc = 0 ; cc < 14 ; cc++)
   {
     if (aa[cc] == bb[cc])
     {
       fg++;
     }
   }
   if (fg == 14)
   {
     ff = true;
   }
   return ff;
}
void checkmytags() // compares each tag against the tag just read {
   ok = 0; // this variable helps decision-making,
   // if it is 1 we have a match, zero is a read but no match,
   // -1 is no read attempt made
   if (comparetag(newtag, tag1) == true)
   {
     ok++;
   }
   if (comparetag(newtag, tag2) == true)
   {
     ok++;
   }


}
void readTags()
{

   ok = -1;
   if (RFID.available() > 0)
   {
     // read tag numbers
     delay(100); // needed to allow time for the data to come in from the serial buffer.
     for (int z = 0 ; z < 14 ; z++) // read the rest of the tag
     {
       data1 = RFID.read();
       newtag[z] = data1;
     }
     RFID.flush(); // stops multiple reads
     // do the tags match up?
     checkmytags();
   }
  // now do something based on tag type
if (ok > 0) // if we had a match
{
Serial.println("Accepted");
digitalWrite(yes, HIGH);
digitalWrite(relay, HIGH);
myServo.write(180);
delay(TApertura);
digitalWrite(yes, LOW);
digitalWrite(relay, HIGH);
myServo.write(0);
ok = -1;
}
else if (ok == 0) // if we didn't have a match
   {
     Serial.println("Rejected");
     digitalWrite(no, HIGH);
     delay(1000);
     digitalWrite(no, LOW);
     ok = -1;
   }
}

void musica(){
   //i=0;


   if (time-prevtime <TApertura){
     nota=perElisa[i];
     if (i>=20){
     i=0;
      noTone(3);
      delay (2000);
     }
   if (i<20){
   tone(3,nota,1000);
   delay(250);
   noTone(3);
   i++;
   }
   }


}
void loop()
{
   readTags();
   musica();

}