Pages: [1]   Go Down
Author Topic: Problema funzione Millis() e servo  (Read 1318 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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...
« Last Edit: December 20, 2012, 07:11:47 pm by UweFederer » Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7210
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nel loop usa uno switch case al posto di tutti gli if
--> http://ennebi.solira.org/c-lang/pag25.html
--> http://www.html.it/pag/15404/controlli-condizionali-switch-e-operatori-ternari/
« Last Edit: December 21, 2012, 05:51:22 am by PaoloP » Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 271
Posts: 21879
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.
« Last Edit: December 21, 2012, 11:17:05 am by Davide-1991 » Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7210
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Ho aggiunto una variabile SERVO
Code:
#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
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
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.
 
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7210
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Potresti usare le librerie di Leo, cosi non impazzisci con il codice.
Dai uno sguardo qui --> http://arduino.cc/forum/index.php?topic=111732.0
oppure potresti usare la versione semplificata "looper" --> http://www.leonardomiliani.com/?p=543
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao PaoloP grazie 1000 ancora per avermi risposto e per l'aiuto che mi stai dando  smiley
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...
Logged

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 114
Posts: 7210
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.  smiley-mr-green
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22973
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.  smiley-mr-green
Abbiamo una discussione di qualche decina di pagine su questo forum  smiley-yell
Ho allegato alla leOS/leOS2 un manualetto utente in formato Pdf che spiega le librerie in modo chiaro  smiley-wink
Allegati alla leOS, alla leOS2 ed alla looper ci sono diversi esempi supercommentati.  smiley-razz

Se volete di più, vi do un Lucano!  smiley-wink
Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.  smiley-mr-green
Abbiamo una discussione di qualche decina di pagine su questo forum  smiley-yell
Ho allegato alla leOS/leOS2 un manualetto utente in formato Pdf che spiega le librerie in modo chiaro  smiley-wink
Allegati alla leOS, alla leOS2 ed alla looper ci sono diversi esempi supercommentati.  smiley-razz

Se volete di più, vi do un Lucano!  smiley-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!!  smiley

Un saluto a tutti, e sopratutto BUON NATALE!!
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22973
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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!!  smiley
Più che ben fatta e basta, spero che sia anche utile  smiley-wink

Quote
Un saluto a tutti, e sopratutto BUON NATALE!!
Anche a te
Logged


Pages: [1]   Go Up
Jump to: