Archivi tag: servomotore+

PCTO A.S. 2020 – 2021 – SumoBot – lezione 3

In questa lezione mostrerò uno sketch di esempio in cui la velocità, il senso di rotazione e la durata di rotazione vengono passati come parametri alle funzioni che controllano il movimento del robot. Ovviamente potrete modificare e migliorare l’esempio proposto.
Si tenga in conto che questo tipo di controllo, sia per la bassa qualità dei servomotori utilizzati, e sia per la scelta del tipo di motore, non consente una regolazione precisa, ma in ogni caso ci permette di raggiungere gli obiettivi esposti nella lezione 1.

Lo schema di collegamento a cui farò riferimento sarà quello utilizzato nella lezione precedente, che indico di seguito.

L’inizializzazione dei servomotori viene eseguita nella stessa modalità come illustrato nella lezione 2.

Le funzioni principali di orientamento del robot permettono di controllare con discreta precisione:

  • la velocità di rotazione;
  • il senso di rotazione;
  • il tempo di rotazione;

Le funzioni di controllo sono:

1antiorarioRobot()
2orarioRobot()
3stopRobot()

Le tre funzioni al loro interno utilizzano il metodo write() sugli oggetti motoreDx e motoreSx.

Le funzioni prevedono due parametri di ingresso: velocità e durata della rotazione.
Con l’impostazione della velocità impostiamo anche il senso di rotazione. Nel caso di rotazione antioraria il valore dovrà essere compreso tra 90 e 180 ed il valore scelto stabilirà anche la velocità di rotazione.

La funzione antiorarioRobot() accetta due parametri di ingresso:

  • velMaxAntioraria, massima velocità oraria
  • durata, indica la durata della rotazione in millisecondi

in questo caso i valori inseriti per la velocità dovranno essere compresi tra 0 e 90:

1void antiorarioRobot(int velMaxAntioraria, int durata) {
2  motoreDX.write(velMaxAntioraria);  // Rotazione antioraria del motore DX
3  motoreSX.write(velMaxAntioraria);  // Rotazione antioraria del motore SX
4  delay(durata);                     // durata: durata della rotazione
5}

La funzione orarioRobot() funzionerà in modo simile:

1void orarioRobot(int velMaxOraria, int durata) {
2  motoreDX.write(velMaxOraria);    // Rotazione oraria del motore DX
3  motoreSX.write(velMaxOraria);    // Rotazione oraria del motore SX
4  delay(durata);                   // durata: durata della rotazione
5}

Come esercizio invito gli studenti a realizzare un’unica funzione di comando che ingloba le due precedenti in grado di realizzare qualsiasi tipo di movimento.

La funzione stopRobot() accetta come unico parametro la durata dello stop.

1void stopRobot(int ferma) {
2  motoreDX.write(90);   // Ferma il motore DX
3  motoreSX.write(90);   // Ferma il motore SX
4  delay(ferma);         // Durata dello stop
5}

Lo sketch completo è il seguente:

1/*
2 * Prof. Maffucci Michele
3 * SumoRobot
4 * Data: 26.01.2021
5 *
6 * Sketch 02: rotazione oraria e antioraria continua
7 *            con funzioni parametrizzate
8 *
9 * Note:
10 *          L'orientamento dei motori è fatto
11 *          guardano il robot anteriormente
12 *      
13 *          180: max velocità in senso antiorario
14 *          90 : servomotori fermi
15 *          0  : max velocità in senso orario
16 *           
17 */
18 
19// inclusione della libreria servo.h per il controllo dei servomotori
20#include <Servo.h>
21 
22// Creazione oggetti servo
23Servo motoreDX;  // Inizializzazione del servomotore destro
24Servo motoreSX;  // Inizializzazione del servomotore sinistro
25 
26byte pinDx = 4;     // Inizializza del pin 4 a cui è connesso il pin segnale del servo destro
27byte pinSx = 5;     // Inizializza del pin 5 a cui è connesso il pin segnale del servo sinistro
28 
29void setup() {
30 
31  // attach() consente di definire a quale pin viene connesso il servomotore
32  // e lo collega all'oggetto che gestisce il servomotore
33   
34  motoreDX.attach(pinDx); // pinDx collegato al motore destro
35  motoreSX.attach(pinSx); // pinSx collegato al motore sinistro
36}
37 
38void loop() {
39  orarioRobot(30, 250);      // Rotazione in senso orario del robot
40  stopRobot(3000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
41  antiorarioRobot(150, 250); // Rotazione in senso antiorario del robot
42  stopRobot(3000);           // Stop rotazione per un tempo fissato (vedere variabile ferma)
43}
44 
45// rotazione del robot in senso antiorario
46// velMaxOraria: velocità massima in senso antiorario
47// durata: durata della rotazione
48 
49void antiorarioRobot(int velMaxAntioraria, int durata) {
50  motoreDX.write(velMaxAntioraria);  // Rotazione antioraria del motore DX
51  motoreSX.write(velMaxAntioraria);  // Rotazione antioraria del motore SX
52  delay(durata);                     // durata: durata della rotazione
53}
54 
55// rotazione del robot in senso orario
56// velMaxOraria: velocità massima in senso orario
57// durata: durata della rotazione
58 
59void orarioRobot(int velMaxOraria, int durata) {
60  motoreDX.write(velMaxOraria);    // Rotazione oraria del motore DX
61  motoreSX.write(velMaxOraria);    // Rotazione oraria del motore SX
62  delay(durata);                   // durata: durata della rotazione
63}
64 
65// stop del robot
66// ferma: durata dello stop del robot
67 
68void stopRobot(int ferma) {
69  motoreDX.write(90);   // Ferma il motore DX
70  motoreSX.write(90);   // Ferma il motore SX
71  delay(ferma);         // Durata dello stop
72}

I tempi indicati inseriti nelle funzioni all’interno del loop potranno essere modificati secondo necessità.

Esercizio 01
Elenca le cause che provocano errori nel far ruotare precisamente di un determinato angolo scelto il robot.

Esercizio 02
Utilizzando un filo di connessione e modificando lo sketch precedente siete in grado di realizzare n sistema di START/STOP del robot.

Buon Coding a tutti 🙂

PCTO A.S. 2020 – 2021 – SumoBot – lezione 2

In questa lezione vedremo come collegare e controllare i servomotori a rotazione continua di SumoBot.
Fate riferimento allo schema di collegamento che segue, in cui i servomotori vengono connessi ai pin 4 e 5 della Sensor Shield per Arduino Uno Nano V3, come si nota a fianco di ogni pin è disponibile l’alimentazione, infatti troviamo sempre il positivo, indicato con la lettera V e il GND indicato con la lettera G. Come ribadito nella lezione 1 utilizziamo una Sensor Shield perchè permette rapidamente di realizzare tutti i collegamenti senza la necessità i dover ricorrere ad una breadboard oppure alla saldatura dei cavi.

Per questa lezione vengono indicati solo i collegamenti ai motori, non verranno collegati ne il sensore ad ultrasuoni e ne i sensori ad infrarossi.

Per quanto riguarda l’utilizzo dei servomotori a rotazione continua fare riferimento alla slide: Alfabeto di Arduino – Lezione 6, ma per completezza riporto di seguito la spiegazione adattandola all’utilizzo con SumoBot.

Il servomotore è costituito in genere da tre cavi connessi ad un connettore femmina con passo standard tra i fori di 2,54 mm quindi facilmente utilizzabile con qualsiasi strip che ne permette il collegamento ad esempio su una breadboard oppure ai pin maschio della Sensor Shield che utilizziamo per SumoBot.

I fili di connessione possono assumere colori diversi in funzione della marca del servo.

Pinout del servomotore

  • Filo ROSSO: +V
  • Filo NERO o MARRONE: GND
  • Filo BIANCO o ARANCIO o BIANCO o BLU: Segnale

Nel servomotori adottati per questa esperienza i fili di connessione sono:

  • Filo ROSSO: +V
  • Filo MARRONE: GND
  • Filo ARANCIO: Segnale

Collegamenti

Guardando SumoBot frontalmente, collegheremo il motore di destra al pin 4 e il motore di sinistra al pin 5.

Principio di funzionamento del servomotore a rotazione continua

Notoriamente i servomotori possono effettuare una rotazione che oscilla tipicamente da 0 a 180, esistono inoltre modelli che consentono una rotazione inferiore tra 0 e 120 gradi, questi tipi di servomotori possono essere modificati facendo in modo che possano effettuare una rotazione continua, ovvero tra 0 e 360 gradi, ma in commercio sono disponibili servomotori di diverse dimensioni che funzionano in questa modalità. Nel kit utilizzato per la realizzazione di SumoBot utilizziamo due servomotori FS90R.

Sul servomotore a rotazione continua possiamo controllare da programma il senso di rotazione e in modo non molto preciso anche la velocità.

Il funzionamento di un servomotore a rotazione continua è simile a quella di un motore in corrente continua con la differenza che non necessitano di appositi shield per poter funzionare.
Rispetto ad altri tipi di motori in CC offrono scelte limitate per il controllo della velocità e limitazioni di alimentazione.

L’alimentazione potrà avvenire direttamente Attraverso Arduino o mediante alimentazione esterna. L’alimentazione dei motori di SumoBot avverrà direttamente dalla scheda Arduino.

Caratteristiche tecniche

  • Velocità di funzionamento a 4,8V: 110RPM
  • Velocità di funzionamento a 6V: 130RPM
  • Coppia di stallo a 4,8V: 1.3kg.cm/18.09oz.in
  • Coppia di stallo a 6V: 1.5kg.cm/20.86oz.in
  • Tensione operativa: 4.8-6V
  • Sistema di controllo: Analogico
  • Angolo di rotazione: 360 gradi
  • Impulso richiesto: 900-2100us
  • Materiale ingranaggi: Plastica
  • Dimensioni: 2,32×1,25×2,2 cm
  • Peso: 9g

Programmazione

1/*
2 * Prof. Maffucci Michele
3 * SumoRobot
4 * Data: 26.01.2021
5 *
6 * Sketch 01: rotazione oraria e antioraria continua
7 *
8 * Note:
9 *          Per l'orientamento del robot
10 *          guardare SumoBot anteriormente
11 *      
12 *          180: max velocità in senso antiorario
13 *          90 : servomotori fermi
14 *          0  : max velocità in senso orario
15 *           
16 */
17 
18// inclusione della libreria servo.h per il controllo dei servomotori
19#include <Servo.h>
20 
21// Creazione oggetti servo
22Servo motoreDX;  // Inizializzazione del servomotore destro
23Servo motoreSX;  // Inizializzazione del servomotore sinistro
24 
25byte pinDx = 4;     // Inizializza del pin 4 a cui è connesso il pin segnale del servo destro
26byte pinSx = 5;     // Inizializza del pin 5 a cui è connesso il pin segnale del servo sinistro
27int  durata = 250;  // Durata movimento (orario/antiorario)
28int  ferma = 3000;  // Durata dello stop
29 
30void setup() {
31 
32  // attach() consente di definire a quale pin viene connesso il servomotore
33  // e lo collega all'oggetto che gestisce il servomotore
34   
35  motoreDX.attach(pinDx); // pinDx collegato al motore destro
36  motoreSX.attach(pinSx); // pinSxcollega to al motore sinistro
37}
38 
39void loop() {
40  orarioRobot();     // Rotazione in senso orario del robot
41  stopRobot();       // Stop rotazione per un tempo fissato (vedere variabile ferma)
42  antiorarioRobot(); // Rotazione in senso antiorario del robot
43  stopRobot();       // Stop rotazione per un tempo fissato (vedere variabile ferma)
44}
45 
46// rotazione del robot in senso antiorario
47void antiorarioRobot(void) {
48  motoreDX.write(150);  // Rotazione oraria del motore DX
49  motoreSX.write(150);  // Rotazione antioraria del motore SX
50  delay(durata);        // durata: durata della rotazione
51}
52 
53// rotazione del robot in senso orario
54void orarioRobot(void) {
55  motoreDX.write(30);    // Rotazione antioraria del motore DX
56  motoreSX.write(30);    // Rotazione oraria del motore SX
57  delay(durata);         // durata: durata della rotazione
58}
59 
60// stop del robot
61void stopRobot(void) {
62  motoreDX.write(90);   // Ferma il motore DX
63  motoreSX.write(90);   // Ferma il motore SX
64  delay(ferma);         // Durata dello stop
65}

Per quanto riguarda il controllo dei servomotori seguire la spiegazione inserita come commento all’interno del codice, ricordo comunque che per controllare i servomotori sono necessarie  4 operazioni:

  1. includere la libreria Servo.h
  2. creazione dell’oggetto Servo. motoreDx e motoreSx saranno i due oggetti su cui opererete
  3. assegnare un nome al pin di controllo del servomotore (filo arancione nello schema)
  4. indicare nel setup il metodo attach() che permette di legare gli oggetti motoreDx e motoreSx ai pin su Arduino nell’esempio 4 e 5 a cui abbiamo assegnato i nomi pinDx e pinSx.

All’interno del codice utilizziamo il metodo write() che per i servomotori a rotazione continua permette il passaggio, all’oggetto motoreDx e motoreSx, la direzione e la velocità di rotazione del motore:

  • passando il valore 0 gradi al metodo write() il servo ruota alla massima velocità in una direzione.
  • passando il valore 90 gradi al metodo write() poniamo il servo in stop (posizione “neutra”)
  • passando il valore 180 gradi al metodo write() il servo di ruotare in senso opposto alla massima velocità.

Nel codice che segue SumoBot ripeterà continuamente una rotazione oraria di 250 millisecondi, si fermerà per 3 secondi e riprenderà la rotazione in senso antiorario per 250 millisecondi.

Per effettuare questa operazione vengono definite 3 funzioni:

  • orarioRobot()
  • stopRobot()
  • antiorarioRobot()

Nel codice si può notare che nella funzione antiorarioRobot() viene passato al metodo write() non il valore 180 che farebbe ruotare il robot alla massima velocità, ma un valore inferiore, nel nostro caso 150, ciò ridurrà la velocità di rotazione.

In  modo analogo accade per la funzione orarioRobot() in cui invece di passare il valore 0 alla metodo write(), che lo farebbe ruotare alla massima velocità in senso orario, passiamo un valore maggiore, 30, che lo farà ruotare ad una velocità inferiore.

La fermata del robot avviene utilizzando la funzione stopRobot() in cui viene passato il valore 90 al metodo write(), ciò fermerà i motori.

Si noti che i motori potranno ruoteranno in un senso o in un altro, oppure potranno essere fermati non solo invocando il metodo write, ma bisognerà sempre inserire un delay() in cui viene specificato per quanto tempo il metodo deve agire.

Esercizio 01

Far compiere a SumoBot rotazioni continue di 90 gradi in senso orario inserendo un intervallo di 3 secondi ad ogni quarto di giro

Esercizio 02

Far compiere a SumoBot una rotazione continua di 360° con intervalli di 3 secondi ad ogni quarto di giro, raggiunti i 360° far cambiare il senso di rotazione ripetendo le fermate di 3 secondi ad ogni quarto di giro.

Esercizio 03

Individuare quanto tempo necessita per far effettuare una rotazione di 45° in senso orario a SumoBot e realizzare un programma che permetta di fare le seguenti operazioni:

  1. rotazione di 45° in senso orario
  2. fermate di 3 secondi
  3. rotazione in senso antiorario di 90°
  4. fermata

Buon Making a tutti 🙂

Arduino – Esercizio: Realizzare un timer per il lavaggio delle mani

Di seguito mostro parte della soluzione agli esercizi assegnati ai miei studenti negli scorsi giorni in riferimento alla progettazione di un semplice dispositivo di automazione da collocare in bagno in prossimità del lavandino, in grado di rilevare ad una distanza minima fissata la presenza delle mani e l’avvio di un timer che mostra il trascorrere del tempo. L’indicazione del tempo che trascorre viene realizzata con un servomotore a cui dovrà poi essere fissata una lancetta e che mostra il trascorrere del tempo su una scala graduata. Il tempo di lavaggio viene fissato a 30 secondi. Sulla serial monitor dovrà essere indicato lo stato di avvio del sistema ed il tempo.

Soluzione

Controllo servomotore

1// Prof. Maffucci Michele
2// gestione servomotore
3 
4#include <Servo.h>
5 
6int pos = 0;
7 
8Servo mioServo;
9 
10// scrivere pos +=1 è la stessa cosa che scrivere pos = pos + 1
11 
12void setup()
13{
14  mioServo.attach(9);
15}
16 
17void loop()
18{
19  // muove il servo da 0 a 180 gradi
20  // con passi di 1 grado
21   
22 for (pos = 0; pos <= 180; pos += 1) {
23    // viene detto al servo di posizionarsi
24    // nella posizione inserita nella variabile 'pos'
25    mioServo.write(pos);
26    // attende 15 ms wait 15 ms
27    // per far raggiungere il sevo la posizione
28    delay(15); // attesa di 15 millisecondi
29  }
30  for (pos = 180; pos >= 0; pos -= 1) {
31    // viene detto al servo di posizionarsi
32    // nella posizione inserita nella variabile 'pos'
33    mioServo.write(pos);
34    // attende 15 ms wait 15 ms
35    // per far raggiungere il sevo la posizione
36    delay(15); // attesa di 15 millisecondi
37  
38}

Controllo sensore ultrasuoni

1// Prof. Maffucci Michele
2// Impostazione sensore ultrasuoni
3 
4// distanza minima dell'ostacolo (in cm)
5 
6const int distanzaMinima = 20;
7int misuraDistanza = 0;
8 
9long durata;          // durata dell'impulso
10long distanza;        // distanza dell'oggetto
11int pin_segnale = 7;  // pin Arduino a cui è collegato il sensore SR04
12int pin_trig = 10;    // pin Arduino a cui è collegato il sensore SR04
13 
14 
15void setup()
16{
17    Serial.begin(9600);
18    pinMode(pin_trig, OUTPUT);
19    pinMode(pin_segnale, INPUT);
20    Serial.println("Sensore ad ultrasuini");
21}
22 
23void loop()
24{
25  Serial.print("Distanza ostacolo: ");
26  Serial.println(distanzaOstacolo());
27  delay(100);
28}
29 
30// rilevazione distanza ostacolo
31 
32// misura la distanza dell'ostacolo
33long distanzaOstacolo()
34{
35  digitalWrite(pin_trig, LOW);
36  delayMicroseconds(2);
37  digitalWrite(pin_trig, HIGH);
38  delayMicroseconds(10);
39  digitalWrite(pin_trig, LOW);
40  durata = pulseIn(pin_segnale, HIGH);
41  distanza = (durata / 2) / 29.1;
42  delay(100);
43  return distanza;
44}

Timer lavaggio mani

1// Prof. Maffucci Michele
2// realizzazione di un timer
3// per il lavaggio delle mani
4// in un tempo di 30 secondi
5 
6#include <Servo.h>
7 
8// Impostazione servomotore
9int pos = 0;
10 
11Servo mioServo;
12 
13// Impostazione sensore ultrasuoni
14 
15// distanza minima dell'ostacolo (in cm)
16 
17const int distanzaOstacolo = 20;
18int misuraDistanza = 0;
19 
20long durata;          // durata dell'impulso
21long distanza;        // distanza dell'oggetto
22int pin_echo = 7;     // pin Arduino a cui è collegato il sensore SR04
23int pin_trig = 10;    // pin Arduino a cui è collegato il sensore SR04
24 
25void setup() {
26    Serial.begin(9600);
27    mioServo.attach(9);
28    pinMode(pin_trig, OUTPUT);
29    pinMode(pin_echo, INPUT);
30     
31// Posizionamento iniziale del servo
32   
33  mioServo.write(180);
34  delay(500);
35  mioServo.write(0);
36  delay(500);
37  mioServo.write(180);
38 
39// Avvio alla partenza
40   
41  Serial.println("Avvio programma lavaggio mani");
42}
43 
44void loop() {
45   
46  // Se la distanza delle mani dal rubinetto è
47  // inferiore alla distanzaOstacolo si avvia il timer
48   
49    if (misuraDistanzaOstacolo() < distanzaOstacolo) {
50        contoAllaRovesciaServo();
51  }
52  delay(100);
53}
54 
55 
56// Conto alla rovescia
57// sposta il servo di 6 gradi ogni secondo
58 
59void contoAllaRovesciaServo() {
60  Serial.println("Conto alla rovescia: ");
61  int passi = 30;
62   
63  for (int i = passi; i >= 0; i--) {
64 
65    mioServo.write(i * 6);
66    delay(1000);
67    Serial.print(i);
68    Serial.println(" sec");
69 
70  }
71 
72  // azzeramento del servo.
73  // Le mani sono pulite
74  mioServo.write(180);
75  delay(500);
76}
77 
78// misura la distanza dell'ostacolo
79long misuraDistanzaOstacolo()
80{
81  digitalWrite(pin_trig, LOW);
82  delayMicroseconds(2);
83  digitalWrite(pin_trig, HIGH);
84  delayMicroseconds(10);
85  digitalWrite(pin_trig, LOW);
86  durata = pulseIn(pin_echo, HIGH);
87  distanza = (durata / 2) / 29.1;
88  delay(100);
89  return distanza;
90}

Esercizio 1

Modificare lo sketch precedente aggiungendo due LED, verde e rosso. Lo stato di riposo, timer non funzionante, deve essere indicato dal LED verde acceso e Led rosso spento, mentre lo stato di funzionamento del timer deve essere evidenziato dal LED verde spento e LED rosso acceso.

Esercizio 2

Modificare lo sketch precedente aggiungendo due LED, verde e rosso e un buzzer. Lo stato di riposo, timer non funzionante, deve essere indicato dal LED verde acceso e Led rosso spento, all’avvio del timer il buzzer deve emettere una nota ad una frequenza fissata per un tempo di  1 secondo. Lo stato di funzionamento del timer deve essere evidenziato dal LED verde spento e LED rosso acceso, allo scadere del tempo di lavaggio deve essere emessa una nota di durata 1 secondo ad una frequenza diversa dalla nota di avvio.

Esercizio 3

Realizzare l’esercizio 2 con le medesime caratteristiche e componenti, però sostituendo il servomotore usato come indicatore, con un display LCD 16×2 che indichi il trascorrere del tempo.

Buon lavoro 🙂

On-line le slide: Alfabeto di Arduino – lezione 6

In occasione della lezione 2 del corso: “Arduino avanzato” di cui sono relatore presso il FabLab di Biella, ho pubblicato le slide utilizzate durante la lezione: Alfabeto di Arduino – lezione 6. Questa nuova collezione di slide va ad aggiungersi alle precedenti lezioni pubblicate su slideshare ed insieme costituiscono un percorso alternativo a quelli che potete trovare nelle sezioni Arduino di questo sito.
Come per le precedenti lezioni all’interno della lezione 6 troverete sperimentazioni che fanno riferimenti a sketch disponibili su GitHub.

Spero possa servire.
Saluti.