// 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 myservo; #include ; 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