
Come probabilmente avrete avuto modo di verificare gestendo i due servomotori a rotazione continua, pur provenendo dal medesimo costruttore e impostando le medesime configurazione di velocità, hanno un comportamento non sempre identico. Ricordo che si tratta di apparati economici che devono rispondere a specifiche esigenze didattiche, ma in ogni caso è possibile effettuare alcune regolazioni che ne possono migliorare le prestazioni.
Un’altra funzionalità utile è quella dello start/stop del robot che potrebbe servire per evitare immediati movimenti non appena trasferiamo il codice sul robot.
In questa lezione vi dettaglio gli sketch di esempio, lasciando a voi modifiche e miglioramenti.
Regolazione dei motori
Per poter valutare la velocità e l’angolo di rotazione da impostare all’interno dello sketch è possibile attivare la funzione di calibrazione collegando a GND il pin 3, in questo modo sarà possibile dalla Serial Monitor verificare quali sono i giusti valori per:
- velocità di rotazione;
- durata della rotazione;
- motore/i da impostare
e quindi ciò consentirà di impostare i parametri corretti per le funzioni:
- orarioRobot()
- antiorarioRobot()
Pertanto da serial monitor potremo comprendere come far compiere una rotazione di 90° in un senso, oppure come far avanzare di una certa quantità di centimetri il robot e molto altro, tenendo però bene a mente che tutto ciò dipenderà fortemente dalla carica della batteria.
La scelta del pin3 è puramente casuale se ritenete potete scegliere un altro pin digitale.
Esempio 1
45 | bool abilitaMessaggio = 0; |
48 | bool startCalibrazione = 1; |
61 | motoreDX.attach(pinDx); |
62 | motoreSX.attach(pinSx); |
64 | pinMode(pinCal, INPUT); |
70 | if (digitalRead(pinCal) == LOW) { |
77 | antiorarioRobot(150, 250); |
90 | if (abilitaMessaggio == 0) { |
93 | Serial.println( "Calibrazione tempo rotazione" ); |
94 | Serial.println( "velocità (0-180), durata(ms), motore(1: DX, 2: SX, 3: SX+DX)" ); |
104 | if (Serial.available()) { |
111 | int velocita = Serial.parseInt(); |
112 | int durata = Serial.parseInt(); |
113 | int motore = Serial.parseInt(); |
117 | calMotoreRobot(velocita, durata, motore); |
124 | void calMotoreRobot( int calVel, int calDurata, int nMotore) { |
126 | motoreDX.write(calVel); |
130 | Serial.println( "Fine calibrazione motore DX" ); |
134 | motoreSX.write(calVel); |
138 | Serial.println( "Fine calibrazione motore SX" ); |
142 | motoreDX.write(calVel); |
143 | motoreSX.write(calVel); |
147 | Serial.println( "Fine calibrazione motore DX e SX" ); |
156 | void antiorarioRobot( int velMaxAntioraria, int durata) { |
157 | motoreDX.write(velMaxAntioraria); |
158 | motoreSX.write(velMaxAntioraria); |
166 | void orarioRobot( int velMaxOraria, int durata) { |
167 | motoreDX.write(velMaxOraria); |
168 | motoreSX.write(velMaxOraria); |
175 | void stopRobot( int ferma) { |
La calibrazione viene attivata se la condizione ad inizio loop è vera:
3 | if (digitalRead(pinCal) == LOW) { |
10 | antiorarioRobot(150, 250); |
Se la condizione dell’if risulta vera viene attivata la calibrazione:
3 | if (digitalRead(pinCal) == LOW) { |
10 | antiorarioRobot(150, 250); |
In tal caso viene chiamata la funzione calibrazione:
6 | if (abilitaMessaggio == 0) { |
9 | Serial.println( "Calibrazione tempo rotazione" ); |
10 | Serial.println( "velocità (0-180), durata(ms), motore(1: DX, 2: SX, 3: SX+DX)" ); |
20 | if (Serial.available()) { |
27 | int velocita = Serial.parseInt(); |
28 | int durata = Serial.parseInt(); |
29 | int motore = Serial.parseInt(); |
33 | calMotoreRobot(velocita, durata, motore); |
La prima parte della funzione calibrazione() esegue una sola volta la stampa sulla Serial Monitor dell’help che spiega come inserire i dati:
velocità (0-180), durata(ms), motore(1: DX, 2: SX, 3: SX+DX)
che sono tutti valori interi separati da virgola.
Nella parte restante del codice della funzione viene verificato con il metodo available() se sono presenti sulla seriale caratteri. Serial.available() restituisce TRUE se sono presenti caratteri e il corpo dell’if verrà eseguito. I valori inseriti vengono letti utilizzando la funzione parseInt() di cui trovate spiegazione approfondita con esercizi seguendo il link.
2 | if (Serial.available()) { |
9 | int velocita = Serial.parseInt(); |
10 | int durata = Serial.parseInt(); |
11 | int motore = Serial.parseInt(); |
15 | calMotoreRobot(velocita, durata, motore); |
Non appena premiamo invio sulla tastiera, questi valori vegono acquisiti e passati alla funzione calMotoreRobot()
2 | calMotoreRobot(velocita, durata, motore); |
Tra i parametri che vengono passati alla funzione calMotoreRobot() è presente l’indicazione di quale/i motore/i devono essere controllati, questo parametro può assumere i valori: 1, 2, 3 e questi valori vengono utilizzati per selezionare, tramite i blocchi if corrispondenti, quale azione è da compiere. Nei commenti i dettagli di funzionamento.
2 | void calMotoreRobot( int calVel, int calDurata, int nMotore) { |
4 | motoreDX.write(calVel); |
8 | Serial.println( "Fine calibrazione motore DX" ); |
12 | motoreSX.write(calVel); |
16 | Serial.println( "Fine calibrazione motore SX" ); |
20 | motoreDX.write(calVel); |
21 | motoreSX.write(calVel); |
25 | Serial.println( "Fine calibrazione motore DX e SX" ); |
La parte restante dello sketch riguarda funzioni già analizzate spiegate nelle lezioni precedenti.
Start/stop del robot
Questa semplice funzionalità viene ottenuta nel medesimo modo della calibrazione, utilizziamo il pin2 cortocircuitato a massa per evitare l’avvio del robot, secondo questa regola:
- Pin 2 a GND: robot fermo
- Pin 2 a Vcc: robot start
Questo lo sketch generale:
45 | motoreDX.attach(pinDx); |
46 | motoreSX.attach(pinSx); |
48 | pinMode(pinStart, INPUT); |
54 | if (digitalRead(pinStart) == LOW) { |
63 | antiorarioRobot(130, 500); |
73 | void antiorarioRobot( int velMaxAntioraria, int durata) { |
74 | motoreDX.write(velMaxAntioraria); |
75 | motoreSX.write(velMaxAntioraria); |
83 | void orarioRobot( int velMaxOraria, int durata) { |
84 | motoreDX.write(velMaxOraria); |
85 | motoreSX.write(velMaxOraria); |
92 | void stopRobot( int ferma) { |
Come si può notare lo start/stop è regolato dalla parte di codice:
3 | if (digitalRead(pinStart) == LOW) { |
12 | antiorarioRobot(130, 500); |
Se il pin è collegato a GND, quindi al LOW il robot è in stop, infatti viene chiamata la funzione stopRobot(1);
Nella prossima lezione vedremo come integrare le due funzionalità:
Buon Making a tutti 