Go Down

Topic: Problema funzione Millis() e servo (Read 1 time) previous topic - next topic

Davide-1991

Dec 20, 2012, 07:31 pm Last Edit: Dec 21, 2012, 01:11 am by UweFederer Reason: 1
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:

Code: [Select]
#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...

PaoloP

#1
Dec 20, 2012, 11:04 pm Last Edit: Dec 21, 2012, 11:51 am by PaoloP Reason: 1
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

uwefed

Code: [Select]
if(SOUND > 550) {
   pan.write(SOUND);
   tilt.write(SOUND);


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

http://arduino.cc/en/Reference/ServoWrite

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

ps ho messo i Code Tags

Ciao Uwe

Davide-1991

#3
Dec 21, 2012, 05:15 pm Last Edit: Dec 21, 2012, 05:17 pm by Davide-1991 Reason: 1
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:

Code: [Select]

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.

PaoloP

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

Ho aggiunto una variabile SERVO
Code: [Select]
#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 --> https://github.com/shirriff/Arduino-IRremote
Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Go Up