Go Down

Topic: mettere in pausa arduino finchè non riceve un dato da seriale (Read 691 times) previous topic - next topic

aureliusss

Oct 26, 2012, 04:47 pm Last Edit: Oct 26, 2012, 04:52 pm by aureliusss Reason: 1
ciao a tutti,
questo è il codice che ho di riferimento
Code: [Select]
#define RELAY_PIN 3 //digital pin to control the relay
#define c_pin A1    //capacitor analog pin
#define ps_pin A0   //power supply analog pin
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif



void setup()
{
 // set prescale to 16
 sbi(ADCSRA,ADPS2) ;
 cbi(ADCSRA,ADPS1) ;
 cbi(ADCSRA,ADPS0) ;

 pinMode(RELAY_PIN, OUTPUT);
 Serial.begin(9600); // open serial
 Serial.println("Press the spacebar to toggle relay on/off");
}


void loop()
{
 static int relayVal = 0;
 int cmd;
 float c_voltage, ps_voltage, current;
 static float res = 4.464;
 unsigned long time1, time2, time_0;
 
 
 while (Serial.available() > 0)
 {
   cmd = Serial.read();
     
   switch (cmd)
   {
   case ' ':
     {
       relayVal ^= 1; // xor current value with 1 (causes value to toggle)
       if (relayVal)
         Serial.println("Relay on");
       
       break;
     }
   default:
     {
       Serial.println("Press the spacebar to toggle relay on/off");
     }
   }
     
   if (relayVal)
   {
     digitalWrite(RELAY_PIN, HIGH);
     delay(20);            // relay transition time
     time_0 = micros();    // time the measure start
     do
     {
       c_voltage = analogRead(c_pin);
       time1 = micros()-time_0; //time c_voltage measurement
       ps_voltage = analogRead(ps_pin);
       time2 = micros() - time_0; //time ps_voltage measurement
       
       c_voltage = c_voltage *5 /1023;
       ps_voltage = ps_voltage * 5 / 1023;
       
       current = (ps_voltage - c_voltage)/res;
       
       Serial.println(ps_voltage);
       Serial.println(time1);
       Serial.println(c_voltage);
       Serial.println(time2);
       Serial.println(current);
       Serial.print('\n');
       
       
     
     }
     while(current >0.000001);
     
     Serial.println("Please wait for the capacitor to discharge");
     digitalWrite(RELAY_PIN, LOW);
     do
     {
       c_voltage = analogRead(A1);
       c_voltage = c_voltage * 5 / 1023;
       
       Serial.println(c_voltage);
       delay(50);  // just a delay to not print all the values
       
     }
     while(c_voltage > 0.001);
     
     relayVal = 0;  // reinitialze the relayVal
     Serial.println("\nThe relay is off, press the spacebar");
     Serial.println("again if you want to repeat the measure\n");
   }  
     

   }
}

questo codice mi permette di acquisire la misura ogni volta che premo la spacebar
ho provato a modificarlo chiedendo direttamente il numero di misure che si vogliono effettuare ma non capisco perchè, appena carico il codice, tutto va in automatico senza aspettare che io inserisca il numero. dove sbaglio???
Code: [Select]
#define RELAY_PIN 3 //digital pin to control the relay
#define c_pin A1    //capacitor analog pin
#define ps_pin A0   //power supply analog pin
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif



void setup()
{
 // set prescale to 16
 sbi(ADCSRA,ADPS2) ;
 cbi(ADCSRA,ADPS1) ;
 cbi(ADCSRA,ADPS0) ;

 pinMode(RELAY_PIN, OUTPUT);
 Serial.begin(9600); // open serial
 Serial.println("How many measure do you want to take?");
}


void loop()
{
 static int relayVal = 0;
 int num_misure;
 float c_voltage, ps_voltage, current;
 static float res = 3.59;
 unsigned long time1, time2, time0;
 int i ;
 
 
 if(Serial.available() > 0)
 {
       num_misure = Serial.read();
   
 }
       
 
  num_misure = int( num_misure);
   
   for(i=1; i<=num_misure;i++)
   {
     Serial.print("Misura n.");
     Serial.println(i);
     
     digitalWrite(RELAY_PIN, HIGH);
     delay(20);            // relay transition time::::::: problema, ho impostato questo ritardo per aspettare la commutazione del ralay, ma questo non ha un tempo fisso
     time0 = micros();    // time the measure start
     do
     {
       c_voltage = analogRead(c_pin);
       time1 = micros()-time0; //time c_voltage measurement
       ps_voltage = analogRead(ps_pin);
       time2 = micros() - time0; //time ps_voltage measurement
       
       c_voltage = c_voltage *5 /1023;
       ps_voltage = ps_voltage * 5 / 1023;
       
       current = (ps_voltage - c_voltage)/res;
       
       Serial.println(ps_voltage);
       Serial.println(time1);
       Serial.println(c_voltage);
       Serial.println(time2);
       Serial.println(current);
       Serial.print('\n');
     }
     while(current >0.000001);
     
     Serial.println("Please wait for the capacitor to discharge");
     digitalWrite(RELAY_PIN, LOW);
     do
     {
       c_voltage = analogRead(A1);
       c_voltage = c_voltage * 5 / 1023;
       
       Serial.println(c_voltage);
       delay(50);  // just a delay to not print all the values
       
     }
     while(c_voltage > 0.001);
     Serial.print("\n\n");
       
     
   
   }  
 }
     

leo72

Il primo if legge un valore dalla seriale ma poi il codice continua anche se tale valore non è stato ricevuto.

Ci sono tanti modi, uno è quello di mettere un secondo if e far eseguire la lettura solo se il valore di num_misure è maggiore di 0, ad esempio.
Code: [Select]
if (Serial.available() > 0) {
    num_misure = Serial.read();
    if (num_misure > 0) {
        .......
    }
}

aureliusss

grazie mille, ma esiste proprio un modo per far stoppare l'esecuzione finchè non si riceve un valore?
vorrei capire perchè il codice di riferimento si ferma mentre il secondo continua

PaoloP

Si. Puoi bloccare l'esecuzione con un while. Come scritto nel primo codice.
Code: [Select]
while (Serial.available() > 0);

Finché non si riceve un carattere dalla seriale il codice rimane bloccato nel ciclo while

aureliusss

damn, altro problema, se inserisco un numero con più cifre me le legge una alla volta

PaoloP

Quote
This not a bug, this is a features!


La seriale legge un carattere alla volta.
Per ricomporlo devi crearti un buffer e caricare su di esso i caratteri letti.
Sul forum trovi 1000 esempi di codice per questo problema.

Go Up