Problema funzione Millis() e servo

Salve a tutti, ho costruito un piccolo faretto a led RGB collegato ha due micro servo per il pan/tilt,
ho testato tutto e funziona perfettamente, non essendo però ancora molto esperta nella programmazione avrei bisogno di aiuto,
in pratica dovrei far lampeggiare i led rgb, in sequenza oppure tutti assieme e contemporaneamente far muovere i 2 micro servo da 0 a 180 gradi,
sono riuscito a far lampeggiare i led con la funzione millis() ma non riesco a far muovere i 2 servo contemporaneamente...
questo è il codice che ho scritto fino ad ora:

#include <IRremote.h>
#include <Servo.h>

// CONTROLLO IR
#define tasto_0 0x33B808F7
#define tasto_1 0x33B88877
#define tasto_2 0x33B848B7
#define tasto_3 0x33B8C837
#define tasto_4 0x33B828D7
#define tasto_5 0x33B8A857
#define tasto_6 0x33B86897
#define tasto_7 0x33B8E817
#define tasto_8 0x33B89867
#define tasto_9 0x33B8C03F

const short RECV_PIN = 4;
IRrecv irrecv(RECV_PIN);
decode_results results;

// SET PRESCALE PORTE ANALOGICHE
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

// SERVO PAN/TILT
Servo pan;  
Servo tilt; 
int pos1 = 0;
int pos2 = 0;

// LED RGB
int ledR = 3;
int ledG = 5;
int ledB = 6;

//Intervallo di tempo per  far lampeggiare il LED(millisecondi)
int interval = 50;  

//Valore precedente del LED
int valueR = HIGH;
int valueG = HIGH;
int valueB = HIGH;

//Memorizza l'ultima volta che il led è stato aggiornato
long previousMillsR = 0;
long previousMillsG = 0;
long previousMillsB = 0;

// MIC
int MIC = 0;
int NOISE_MARGIN1 = 620;
int NOISE_MARGIN2 = 680;
int NOISE_MARGIN3 = 710;
int SAMPLING = 5;
int SOUND = 0;

// VARIABILI DI FUNZIONAMENTO
int funzione_1 = 0;
int funzione_2 = 0;
int funzione_3 = 0;
int funzione_4 = 0;
int funzione_5 = 0;
int funzione_6 = 0;

void setup() {
  pinMode(MIC, INPUT);
  pinMode(ledR, OUTPUT);
  pinMode(ledG, OUTPUT);
  pinMode(ledB, OUTPUT);
  digitalWrite(ledR, HIGH);
  digitalWrite(ledG, HIGH);
  digitalWrite(ledB, HIGH);
  pan.attach(7);
  tilt.attach(8);
  pan.write(85);
  tilt.write(20);
  // setta  prescale a 32 
  // riduci la durata della lettura analogica da 128 micros (standard) a 32
  sbi(ADCSRA,ADPS2); 
  cbi(ADCSRA,ADPS1); 
  sbi(ADCSRA,ADPS0);
  Serial.begin(9600);
  //Avvia la ricezione IR
  irrecv.enableIRIn();
}

void loop() {
  SOUND = analogRead(MIC);
  if (irrecv.decode(&results)) {
    //Serial.println("Codice IR:"); 
    //Serial.println(results.value, HEX);
    //Serial.println(value);
    if (results.value == tasto_1) {
      funzione_1 = 1;
    }
    else if (results.value == tasto_2) {
      funzione_2 = 1;
    }
    else if (results.value == tasto_3) {
      funzione_3 = 1;
    }
    else if (results.value == tasto_4) {
    }
    else if (results.value == tasto_5) {
    }
    else if (results.value == tasto_6) {
    }
    else if (results.value == tasto_7) { 
    }
    else if (results.value == tasto_8) {  
    }
    else if (results.value == tasto_9) { 
    }
    else if (results.value == tasto_0) { 
      funzione_1 = 0;
      funzione_2 = 0;
      funzione_3 = 0;
      servo_posizione_zero();
      RGB_off();
    }
    irrecv.resume();
  }  
  if(funzione_1 == 1) {
    programma_1();
    servo_posizione_zero;
  }
  else if(funzione_2 == 1) {
    programma_2();
  }
  else if(funzione_3 == 1) {
    programma_3();
  }
}

void servo_posizione_zero()
{
  pan.write(85);
  tilt.write(20);
}

void RGB_off()
{
  digitalWrite(ledR, HIGH);
  digitalWrite(ledG, HIGH);
  digitalWrite(ledB, HIGH);
}
  
void programma_1() 
{
  if(SOUND > 550) {
    pan.write(SOUND);
    tilt.write(SOUND);
  } 
  else {
    pan.write(180);
    tilt.write(180);
  }
  if(SOUND > NOISE_MARGIN1) {
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, HIGH);
  } 
  else {
    digitalWrite(ledR,HIGH);
  }
  if(SOUND > NOISE_MARGIN2) {
    digitalWrite(ledG, LOW);
    digitalWrite(ledR, HIGH);
  } 
  else {
    digitalWrite(ledG,HIGH);
  }
  if(SOUND > NOISE_MARGIN3) {
    digitalWrite(ledB, LOW);
    digitalWrite(ledG, HIGH);
  } 
  else {
    digitalWrite(ledB,HIGH);
  }
  delay(SAMPLING);
}

void programma_2()
{
  if(SOUND > 500) {
    pan.write(SOUND);
    tilt.write(SOUND);
  } 
  else {
    pan.write(180);
    tilt.write(180);
  }
  if(SOUND > NOISE_MARGIN1 & SOUND < NOISE_MARGIN2) {
    digitalWrite(ledB, LOW);
    digitalWrite(ledR, HIGH);
    digitalWrite(ledG, HIGH);
  }
  else if(SOUND > NOISE_MARGIN2 & SOUND < NOISE_MARGIN3) {
    digitalWrite(ledG, LOW);
    digitalWrite(ledR, HIGH);
    digitalWrite(ledB, HIGH);
  }
  else if(SOUND > NOISE_MARGIN3) {  
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, HIGH);
    digitalWrite(ledB, HIGH);
  }
  delay(SAMPLING);
}

void programma_3()
{
  digitalWrite(ledR, valueR);
  digitalWrite(ledG, valueG);
  digitalWrite(ledB, valueB);

  if (millis() -  previousMillsR > interval ) {   
    previousMillsR = millis();
    if(valueR == HIGH) {
      valueR = LOW;
    } 
    else {
      valueR = HIGH;
    }
  }
  if (millis() -  previousMillsG > interval ) {   
    previousMillsG = millis();
    if(valueG == HIGH) {
      valueG = LOW;
    } 
    else {
      valueG = HIGH;
    }
  }
  if (millis() -  previousMillsB > interval ) {   
    previousMillsB = millis();
    if(valueB == HIGH) {
      valueB = LOW;
    } 
    else {
      valueB = HIGH;
    }
  }
}

Ringrazio in anticipo chi mi risponde ciao...

Nel loop usa uno switch case al posto di tutti gli if
--> Programmazione in C: switch-case
--> Switch Case C e operatori ternari: sintassi ed esempi| HTML.it

if(SOUND > 550) {
    pan.write(SOUND);
    tilt.write(SOUND);

Per la funzione write sono definiti solo valori tra 0 e 180.

Non so cosa succede se il valore é fuori da quel range.

ps ho messo i Code Tags

Ciao Uwe

Salve a tutti, Ringrazio PaoloP ed uwefed per avermi risposto e dato consigli,
proverò a riscrivere il codice sfruttando la funzione switch case anziché del solito if per rendere più pulito il codice...

Per quando riguarda la seguente funzione:

if(SOUND > 550) {
    pan.write(SOUND);
    tilt.write(SOUND);

In pratica alla porta analogica 0 di arduino è collegato un un circuito con un integrato lm358
che funge da sensore di suono a cui ho assegnato la variabile SOUND,
quando la variabile SOUND supera un certo valore inizia a muovere i servo a ritmo di musica,
so che la funzione write accetta solo valori da 0 a 180 però funziona tutto perfettamente...

per quando riguarda il problema che avevo non sono ancora riuscito a risolverlo,
dovrei far muovere i servo da 0 a 180 gradi in loop (come nell'esempio sweep di arduino), e contemporaneamente accendere e spegnere in sequenza i led RGB,
penso debba usare la funzione millis() ma non so in che modo, cioè sono riuscito ad usare la seguente funzione per
accendere e spegnere i led, nel programma_3 del codice che ho passato sopra, ma non per far muovere i 2 servo...

Ci sarebbe qualcuno che potrebbe aiutarmi?

Grazie un saluto a tutti.

Puoi usare la macro map per restringere il campo del valore SERVO.
--> http://arduino.cc/en/Reference/Map

Ho aggiunto una variabile SERVO

#include <IRremote.h>
#include <Servo.h>

// CONTROLLO IR
#define tasto_0 0x33B808F7
#define tasto_1 0x33B88877
#define tasto_2 0x33B848B7
#define tasto_3 0x33B8C837
#define tasto_4 0x33B828D7
#define tasto_5 0x33B8A857
#define tasto_6 0x33B86897
#define tasto_7 0x33B8E817
#define tasto_8 0x33B89867
#define tasto_9 0x33B8C03F

const short RECV_PIN = 4;
IRrecv irrecv(RECV_PIN);
decode_results results;

// SET PRESCALE PORTE ANALOGICHE
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

// SERVO PAN/TILT
Servo pan;  
Servo tilt; 
int pos1 = 0;
int pos2 = 0;

// LED RGB
int ledR = 3;
int ledG = 5;
int ledB = 6;

//Intervallo di tempo per  far lampeggiare il LED(millisecondi)
int interval = 50;  

//Valore precedente del LED
int valueR = HIGH;
int valueG = HIGH;
int valueB = HIGH;

//Memorizza l'ultima volta che il led è stato aggiornato
long previousMillsR = 0;
long previousMillsG = 0;
long previousMillsB = 0;

// MIC
int MIC = 0;
int NOISE_MARGIN1 = 620;
int NOISE_MARGIN2 = 680;
int NOISE_MARGIN3 = 710;
int SAMPLING = 5;
int SOUND = 0;
int SERVO = 0;

// VARIABILI DI FUNZIONAMENTO
int funzione_1 = 0;
int funzione_2 = 0;
int funzione_3 = 0;
int funzione_4 = 0;
int funzione_5 = 0;
int funzione_6 = 0;

void setup() {
  pinMode(MIC, INPUT);
  pinMode(ledR, OUTPUT);
  pinMode(ledG, OUTPUT);
  pinMode(ledB, OUTPUT);
  digitalWrite(ledR, HIGH);
  digitalWrite(ledG, HIGH);
  digitalWrite(ledB, HIGH);
  pan.attach(7);
  tilt.attach(8);
  pan.write(85);
  tilt.write(20);
  // setta  prescale a 32 
  // riduci la durata della lettura analogica da 128 micros (standard) a 32
  sbi(ADCSRA,ADPS2); 
  cbi(ADCSRA,ADPS1); 
  sbi(ADCSRA,ADPS0);
  Serial.begin(9600);
  //Avvia la ricezione IR
  irrecv.enableIRIn();
}

void loop() {
  SOUND = analogRead(MIC);
  SERVO = map(SOUND, 0, 1023, 0, 180);  
  if (irrecv.decode(&results)) {
    //Serial.println("Codice IR:"); 
    //Serial.println(results.value, HEX);
    //Serial.println(value);
    if (results.value == tasto_1) {
      funzione_1 = 1;
    }
    else if (results.value == tasto_2) {
      funzione_2 = 1;
    }
    else if (results.value == tasto_3) {
      funzione_3 = 1;
    }
    else if (results.value == tasto_4) {
    }
    else if (results.value == tasto_5) {
    }
    else if (results.value == tasto_6) {
    }
    else if (results.value == tasto_7) { 
    }
    else if (results.value == tasto_8) {  
    }
    else if (results.value == tasto_9) { 
    }
    else if (results.value == tasto_0) { 
      funzione_1 = 0;
      funzione_2 = 0;
      funzione_3 = 0;
      servo_posizione_zero();
      RGB_off();
    }
    irrecv.resume();
  }  
  if(funzione_1 == 1) {
    programma_1();
    servo_posizione_zero;
  }
  else if(funzione_2 == 1) {
    programma_2();
  }
  else if(funzione_3 == 1) {
    programma_3();
  }
}

void servo_posizione_zero()
{
  pan.write(85);
  tilt.write(20);
}

void RGB_off()
{
  digitalWrite(ledR, HIGH);
  digitalWrite(ledG, HIGH);
  digitalWrite(ledB, HIGH);
}
  
void programma_1() 
{
  if(SOUND > 550) {
    pan.write(SERVO);
    tilt.write(SERVO);
  } 
  else {
    pan.write(180);
    tilt.write(180);
  }
  if(SOUND > NOISE_MARGIN1) {
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, HIGH);
  } 
  else {
    digitalWrite(ledR,HIGH);
  }
  if(SOUND > NOISE_MARGIN2) {
    digitalWrite(ledG, LOW);
    digitalWrite(ledR, HIGH);
  } 
  else {
    digitalWrite(ledG,HIGH);
  }
  if(SOUND > NOISE_MARGIN3) {
    digitalWrite(ledB, LOW);
    digitalWrite(ledG, HIGH);
  } 
  else {
    digitalWrite(ledB,HIGH);
  }
  delay(SAMPLING);
}

void programma_2()
{
  if(SOUND > 500) {
    pan.write(SERVO);
    tilt.write(SERVO);
  } 
  else {
    pan.write(180);
    tilt.write(180);
  }
  if(SOUND > NOISE_MARGIN1 & SOUND < NOISE_MARGIN2) {
    digitalWrite(ledB, LOW);
    digitalWrite(ledR, HIGH);
    digitalWrite(ledG, HIGH);
  }
  else if(SOUND > NOISE_MARGIN2 & SOUND < NOISE_MARGIN3) {
    digitalWrite(ledG, LOW);
    digitalWrite(ledR, HIGH);
    digitalWrite(ledB, HIGH);
  }
  else if(SOUND > NOISE_MARGIN3) {  
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, HIGH);
    digitalWrite(ledB, HIGH);
  }
  delay(SAMPLING);
}

void programma_3()
{
  digitalWrite(ledR, valueR);
  digitalWrite(ledG, valueG);
  digitalWrite(ledB, valueB);

  if (millis() -  previousMillsR > interval ) {   
    previousMillsR = millis();
    if(valueR == HIGH) {
      valueR = LOW;
    } 
    else {
      valueR = HIGH;
    }
  }
  if (millis() -  previousMillsG > interval ) {   
    previousMillsG = millis();
    if(valueG == HIGH) {
      valueG = LOW;
    } 
    else {
      valueG = HIGH;
    }
  }
  if (millis() -  previousMillsB > interval ) {   
    previousMillsB = millis();
    if(valueB == HIGH) {
      valueB = LOW;
    } 
    else {
      valueB = HIGH;
    }
  }
}

L'ultima versione della libreria IRremote la trovi qui --> GitHub - Arduino-IRremote/Arduino-IRremote: Infrared remote library for Arduino: send and receive infrared signals with multiple protocols

Ciao a tutti, PaoloP grazie per avermi risposto e per aver aggiornato il mio codice,
per quando riguarda l'altro problema che avevo e un po che ci sbatto la testa
e non riesco propio a capire come gestire più cose contemporaneamente con la funzione millis()
eppure sono sicuro che non dovrebbe essere niente di tanto complicato, ma non sono molto espero in programmazione.

In poche parole io ho questa funzione:

void programma_3()
{
  digitalWrite(ledR, valueR);
  digitalWrite(ledG, valueG);
  digitalWrite(ledB, valueB);

  if (millis() -  previousMillsR > interval ) {   
    previousMillsR = millis();
    if(valueR == HIGH) {
      valueR = LOW;
    } 
    else {
      valueR = HIGH;
    }
  }
  if (millis() -  previousMillsG > interval ) {   
    previousMillsG = millis();
    if(valueG == HIGH) {
      valueG = LOW;
    } 
    else {
      valueG = HIGH;
    }
  }
  if (millis() -  previousMillsB > interval ) {   
    previousMillsB = millis();
    if(valueB == HIGH) {
      valueB = LOW;
    } 
    else {
      valueB = HIGH;
    }
  }
}

questa funzione non fa altro che accendere e spegnere tutti i colori dei led rgb con la funzione millis()
ora io in questa funzione dovrei fare in modo che i servo ruotino da 0 a 180 gradi in loop, e contemporaneamente
continuare ad accendere e spegnere i led...

In che modo potrei risolvere questo problema??

Grazie un saluto a tutti.

Potresti usare le librerie di Leo, cosi non impazzisci con il codice.
Dai uno sguardo qui --> Arduino Forum
oppure potresti usare la versione semplificata "looper" --> looper, uno schedulatore software per Arduino – Leonardo Miliani

Ciao PaoloP grazie 1000 ancora per avermi risposto e per l'aiuto che mi stai dando :slight_smile:
Adesso scarico le librerie che mi hai indicato, e le studio un po per provare a buttare giù un po di codice funzionante

Non è che potresti farmi un'esempio di codice su come utilizzare quella libreria per fare ciò che mi serve?

Grazie ciao...

Davide-1991:
Non è che potresti farmi un'esempio di codice su come utilizzare quella libreria per fare ciò che mi serve?

Per esempi e funzionamento chiedi a Leo72. :grin:

PaoloP:

Davide-1991:
Non è che potresti farmi un'esempio di codice su come utilizzare quella libreria per fare ciò che mi serve?

Per esempi e funzionamento chiedi a Leo72. :grin:

Abbiamo una discussione di qualche decina di pagine su questo forum :stuck_out_tongue_closed_eyes:
Ho allegato alla leOS/leOS2 un manualetto utente in formato Pdf che spiega le librerie in modo chiaro :wink:
Allegati alla leOS, alla leOS2 ed alla looper ci sono diversi esempi supercommentati. :stuck_out_tongue:

Se volete di più, vi do un Lucano! :wink:

leo72:

PaoloP:

Davide-1991:
Non è che potresti farmi un'esempio di codice su come utilizzare quella libreria per fare ciò che mi serve?

Per esempi e funzionamento chiedi a Leo72. :grin:

Abbiamo una discussione di qualche decina di pagine su questo forum :stuck_out_tongue_closed_eyes:
Ho allegato alla leOS/leOS2 un manualetto utente in formato Pdf che spiega le librerie in modo chiaro :wink:
Allegati alla leOS, alla leOS2 ed alla looper ci sono diversi esempi supercommentati. :stuck_out_tongue:

Se volete di più, vi do un Lucano! :wink:

Ciao Leo72, grazie mille per essere intervenuto e per il tuo aiuto, ho appena scaricato la tua libreria, sembra davvero ben fatta!!
appena posso la studio e cerco di mettere in pratica riscrivendo il mio codice,
comunque ti faccio i miei più sinceri complimenti per la libreria che hai scritto è davvero utilissima!! :slight_smile:

Un saluto a tutti, e sopratutto BUON NATALE!!

Davide-1991:
Ciao Leo72, grazie mille per essere intervenuto e per il tuo aiuto, ho appena scaricato la tua libreria, sembra davvero ben fatta!!
appena posso la studio e cerco di mettere in pratica riscrivendo il mio codice,
comunque ti faccio i miei più sinceri complimenti per la libreria che hai scritto è davvero utilissima!! :slight_smile:

Più che ben fatta e basta, spero che sia anche utile :wink:

Un saluto a tutti, e sopratutto BUON NATALE!!

Anche a te