- // versione 2
- #define TIC_STERZO 10 // millisecondi di intervallo per ogni grado di movimento sterzo
- #define TIC_MOTORE 100 // mililsecondi di durata singolo passo movimento motore
- #define TRATTO_MOTORE 2000 // millisecondi di durata totale azionamento motore
- // un paio di costanti per rendere chiaro il senso del movimento
- #define AVANTI 1
- #define INDIETRO 0
- #include <Servo.h>
- Servo myservo;
- #include <IRremote.h>;
- IRrecv irrecv(11);
- decode_results res;
- #define ENABLE 5
- #define DIRA 3
- #define DIRB 4
- #define ENABLE2 8
- #define DIRA2 6
- #define DIRB2 7
- // variabili globali per le temporizzazioni e per la gestione dello stato
- long istanteUltimoMovSterzo = 0;
- long istantePartenzaMotore = 0;
- long istanteUltimoMovMotore = 0;
- int destinazioneSterzo = 90;
- boolean motoreMovimento = false;
- byte direzioneMotore = AVANTI;
- int led = 10 ;
- int buzzer = 12 ;
- int i;
- int pos = 0;
- void setup() {
- pinMode(led,OUTPUT);
- pinMode(buzzer,OUTPUT);
- pinMode(ENABLE2,OUTPUT);
- pinMode(DIRA2,OUTPUT);
- pinMode(DIRB2,OUTPUT);
- pinMode(ENABLE,OUTPUT);
- pinMode(DIRA,OUTPUT);
- pinMode(DIRB,OUTPUT);
- Serial.begin(9600);
- irrecv.enableIRIn();
- // inizializzo servo su pin 9
- myservo.attach(9);
- // IMPORTANTE: porto il servo nella posizione centrale
- myservo.write(90);
- }
- void loop() {
- if(irrecv.decode(&res)){
- Serial.println(res.value,HEX);
- irrecv.resume();
- switch( res.value ) {
- case 0xAD586662: // tasto avanzamento: motore avanti per TRATTO_MOTORE millisecondi
- // abilitiamo le uscite per il motore
- digitalWrite(ENABLE2,HIGH);
- digitalWrite(ENABLE,HIGH); // enable on
- // impostiamo l'istante di partenza del motore, così potremo fermarlo a fine intervallo
- istantePartenzaMotore = millis();
- // impostiamo la direzione
- direzioneMotore = AVANTI;
- // dichiariamo il motore in movimento
- motoreMovimento = true;
- break;
- case 0x6825E53E: // tasto retromarcia: motore indietro per TRATTO_MOTORE millisecondi
- // abilitiamo le uscite per il motore
- digitalWrite(ENABLE2,HIGH);
- digitalWrite(ENABLE,HIGH); // enable on
- // impostiamo l'istante di partenza del motore
- istantePartenzaMotore = millis();
- // impostiamo la direzione
- direzioneMotore = INDIETRO;
- // dichiariamo il motore in movimento
- motoreMovimento = true;
- break;
- case 0xE13DDA28: // tasto stop: ferma il motore
- // disabilitiamo le uscite per il motore
- digitalWrite(ENABLE2,LOW);
- digitalWrite(ENABLE,LOW); // disable
- // dichiariamo il motore fermo
- motoreMovimento = false;
- break;
- case 0x2C452C6C: // tasto sterza tutto a DESTRA
- // imposto il punto di arrivo dello sterzo: 0 gradi -> tutto a sinistra
- destinazioneSterzo = 0;
- break;
- case 0xF5999288: // tasto sterza tutto a SINISTRA
- // imposto il punto di arrivo dello sterzo: 180 gradi -> tutto a sinistra
- destinazioneSterzo = 180;
- break;
- case 0x731A3E02 : // tasto porta lo sterzo al centro
- // imposto il punto di arrivo dello sterzo: 180 gradi -> tutto a sinistra
- destinazioneSterzo = 90;
- break;
- case 0xF4BA2988 :
- digitalWrite (led,HIGH);
- break;
- case 0x2D25D203 :
- digitalWrite (led,LOW);
- break;
- case 0xAE2FF30 :
- for(int i = 0; i<3; i++){
- digitalWrite (buzzer,HIGH);
- delay(200);
- digitalWrite (buzzer,LOW);
- }
- break;
- } // switch
- } // if(irrecv.decode(&res))
- manageSterzo(); // gestione movimento sterzo
- manageMotore(); // gestione movimento motore
- } // loop
- void manageSterzo() {
- /*
- * questa funzione è richiamata da dentro al loop. Quindi deve durare pochissimo, fare una singola operazione e ritornare
- * in particolare, se la destinazione dello sterzo non coincide con la posizione attuale, muove lo sterzo di 1 grado nella destinazione giusta,
- * comunque solo se è passato abbastanza tempo (TIC_STERZO) dall'ultimo movimento dello sterzo
- */
- int posizioneAttuale;
- int passo;
- // se abbiamo già mosso lo sterzo da troppo poco tempo non facciamo nulla e ritorniamo
- if (( millis() - istanteUltimoMovSterzo ) < TIC_STERZO ) return;
- // è passato abbastanza tempo dall'ultimo movimento dello sterzo. Vediamo se è necessario muoverlo, cominciando a leggere dove si trova
- posizioneAttuale = myservo.read();
- // se si trova già dove deve essere non facciamo nulla e usciamo
- if ( posizioneAttuale == destinazioneSterzo ) return;
- // arriviamo qui se lo sterzo non è ancora dove deve essere; decidiamo se il passo deve essere positivo o negativo
- if ( destinazioneSterzo > posizioneAttuale ) passo = 1;
- else passo = -1;
- // ora muoviamo lo sterzo di 1 grado nella direzione già decisa
- myservo.write( posizioneAttuale + passo );
- // prendiamo il tempo in cui lo abbiamo mosso
- istanteUltimoMovSterzo = millis();
- }
- void manageMotore() {
- /*
- * questa funzione è richiamata da dentro al loop. Quindi deve durare pochissimo, fare una singola operazione e ritornare
- * in pratica move il motore nella direzione giusta per un passo.
- * I passi verranno ripetuto ogni TIC_MOTORE millisecondi, sino a una durata massima di TRATTO_MOTORE millisecondi
- */
- // se il motore non è dichiarato in movimento non facciamo nulla e ritorniamo subito
- if ( !motoreMovimento ) return;
- // se il motore ha già girato per tutto il tempo previsto lo fermiamo
- if (( millis() - istantePartenzaMotore ) > TRATTO_MOTORE ) {
- // fine del tratto, spegnere il motore
- digitalWrite(ENABLE2,LOW);
- digitalWrite(ENABLE,LOW); // disable
- // dichiariamo che il motore è fermo
- motoreMovimento = false;
- return;
- }
- // se abbiamo già fatto un passo per il motore da troppo poco tempo non facciamo nulla e ritorniamo
- if (( millis() - istanteUltimoMovMotore ) < TIC_MOTORE ) return;
- // OK, arriviamo qui se c'è da fare un movimento del motore, in una direzione o nell'altra
- if ( direzioneMotore == AVANTI ) {
- // muoviamo il motore IN avanti
- digitalWrite(DIRA,LOW); //one way
- digitalWrite(DIRB,HIGH);
- digitalWrite(DIRA2,LOW); //one way
- digitalWrite(DIRB2,HIGH);
- }
- else {
- // direzioneMotore deve essere INDIETRO
- digitalWrite(DIRA,HIGH); //one way
- digitalWrite(DIRB,LOW);
- digitalWrite(DIRA2,HIGH); //one way
- digitalWrite(DIRB2,LOW);
- }
- // in ogni caso prendiamo il tempo dell'ultimo azionamento del motore
- istanteUltimoMovMotore = millis();
- } // manageMotore