Archivi tag: L298N

Controllo di un motore passo-passo bipolare NEMA17 con Driver L298N

I motori “passo-passo” o “stepper” sono motori elettrici sincroni il cui avanzamento avviene a passo singolo corrispondente ad uno specifico angolo di rotazione, pertanto è possibile farli ruotare a piacimento di un angolo preciso. Uno stepper è in grado di mantenere con precisione velocità di rotazione e posizione senza la necessitò di utilizzo di trasduttori di feedback come dinamo tachimetriche o encoder.
I motori passo-passo sono ampiamente utilizzati nell’ambito dell’automazione industriale: robotica, stampanti, scanner, o per esempio come stanno facendo alcuni miei allievi, per regolare l’inclinazione di un pannello solare per realizzare un inseguitore solare.

Rispetto ad altre tipologie di motori elettrici il motore passo-passo non modifica la velocità di rotazione in funzione della coppia a cui è sottoposto l’albero rotante, la mantiene costante e nel caso in cui la coppia aumenti il motore si ferma.

I motori stepper per essere pilotati richiedono una sequenza di impulsi generati da appositi circuiti elettronici di controllo.

In laboratorio vedremo come controllare il movimento di un motore passo-passo bipolare con Arduino mediante l’uso di un Motor Driver L298N. Su questo sito ho dettagliato l’uso di questa scheda per controllare motori in CC per robot didattici, però con questo tutorial voglio indicare ai miei studenti come effettuare il controllo di un motore passo passo NEMA17 che dovranno utilizzare nelle prossime esperienze di laboratorio.

Richiami teorici

Lo stepper motor o motore passo-passo è definito anche come “trasduttore elettromeccanico” in quanto converte impulsi elettrici di comando in passi elementari (step) di ampiezza angolare fissata in funzione del tipo di motore.

Questo tipo di motore elettrico per poter funzionare deve essere collegato ad un circuito di alimentazione specifico e ad un sistema di controllo elettronico in grado di governare l’angolo e la velocità di rotazione.
Come per tutti i motori elettrici anche il motore passo-passo è costituito da una parte fissa detta statore ed una parte mobile detta rotore su cui è connesso un albero di rotazione dotato di cuscinetti:

Nello statore sono disposti gli avvolgimenti di rame, costituiti da bobine di rame smaltato (isolato), mentre il rotore è costituito da materiale magnetico.

Esistono tre tipi di motori passo passo:

  • a magnete permanente (PM)
  • a riluttanza variabile (VR)ibrido (HY)

Gli avvolgimenti dello statore sono collegati in modo da realizzare un sistema bifase, ma esistono anche sistemi trifase e polifase ma sono più rari.

I motori passo-passo si suddividono a loro volta in due famiglie:

  • motori bipolari (la corrente negli avvolgimenti statorici scorre nei due versi)
  • motori unipolari (la corrente negli avvolgimenti statorici scorre in un solo verso)

In questa guida prenderà in considerazione solamente i motori a magneti permanenti (PM) e di questi considereremo solamente i motori passo-passo bipolari. La spiegazione teorica e l’utilizzo delle altre tipologie di motori sarà argomento di successive lezioni.

Motore a magnete permanente – motore passo-passo bipolare

Il principio di funzionamento di questa tipologia di motori è basato sull’attrazione di due poli magnetici che presentano polarità differenti. Un polo è costituito da un magnete permanete (calamita) mentre l’altro è il polo di un elettromagnete il cui magnetismo è generato da una corrente che fluisce in spire avvolte su un materiale ferromagnetico.

Si ricorda che facendo scorrere una corrente su una bobina avvolta su un nucleo di ferro viene generato un campo magnetico che presenterà una polarità Nord-Sud secondo la “regola della mano destra”:

immaginiamo di impugnare l’avvolgimento con la mano destra in modo che le dita indichino il verso di percorrenza della corrente, il pollice indicherà la direzione del vettore campo elettromagnetico e la punta del pollice indica il verso del vettore individuando il Nord magnetico:

Per far muovere il rotore dovremo quindi modificare il verso di percorrenza della corrente nelle bobine dello statore in modo che la forza di attrazione Nord-Sud tra i poli dello statore e del rotore generi il moto rotatorio.

Nello statore sono presenti due magneti disposti in maniera ortogonale uno rispetto all’altro su cui sono avvolte due bobina i cui terminali sono nominati: A+ e A-, B+ e B- così sono indicati nelle tabelle tecniche di questi dispositivi (i segni + e – a fianco alle lettere A e B non sono da confondere con la polarità), mentre il rotore è costituito da un magnete permanente costituito quindi da un polo Nord e un polo Sud.

Movimento del rotore

Facendo circolare una corrente continua nell’avvolgimento statorico A+ e A- viene generato un campo magnetico che porterà il rotore a ruotare e a bloccarsi nella posizione in cui le polarità magnetiche saranno opposte, così come indicato nel disegno che segue:

Togliendo alimentazione all’avvolgimento statorico A+ A- e alimentando l’avvolgimento statorico B+ B- si avrà una configurazione differente dei magneti statorici ed una conseguente rotazione di 90° del rotore in senso antiorario, come indicato nel disegno che segue:

Togliendo alimentazione all’avvolgimento statorico B+ B- e alimentando in senso opposto (polarità inversa) l’avvolgimento statorico A+ A- si invertiranno le polarità del campo magnetico ed una rotazione di 90° in senso antiorario del rotore così come indicato nel disegno che segue:

Da ciò si comprende che invertendo il verso di percorrenza della corrente prima prima in un avvolgimento statorico e poi nell’altro si otterrà ogni volta una rotazione di 90° del rotore.
L’alimentazione di una fase alla volta (di un avvolgimento statorico alla volta) è detto a “full step”, cioè passo intero.

La sequenza completa di rotazione è costituita da 4 passi (o 4 fasi) e quindi per ottenere una rotazione continua del rotore bisognerà realizzare la seguente sequenza di alimentazione:

La sequenza di movimento, secondo la tabella sopra indicata, sarà quella dell’immagine che segue dove per semplicità di esposizione è stato semplificato il disegno del motore:

Per invertire il senso di rotazione degli elettromagneti sarà sufficiente quindi invertire la sequenza con cui vengono alimentate le bobine statoriche.

Il movimento del motore può avvenire anche alimentando contemporaneamente entrambe le bobine statoriche, in questo modo il rotore si disporrà a 45° rispetto alla posizione precedente. La tabella delle singole fasi diventa:

la posizione del rotore sarà quella descritta dai disegni che seguono:

Controllo

I fili che costituisco i due poli sono distinti da colori diversi e il controllo del motore passo-passo deve essere effettuato da un driver bipolare, nel nostro caso un L298N.

La sequenza di eccitazione, sarà realizzata da un microcontrollore, nel nostro caso Arduino ed in una successivamente lezione vedremo come controllare uno stepper mediante PLC Siemens 1200 con un’altro tipo di driver.

Il driver bipolare, può essere paragonato in estrema sintesi a 8 interruttori, 4 interruttori per ogni bobina statorica

Elettronicamente il driver bipolare è costituito da un circuito elettronico a doppio ponte H, il nostro L298N, che consente di invertire il senso della corrente nelle bobine statoriche. Gli interruttori del circuito precedente vengono realizzati con transitor mosfet o bjt. Comandando la polarizzazione di coppie di transitor per ogni ponte H sarà possibile alimentare le bobine con polarità diverse.

Nell’esempio che segue viene preso in considerazione un solo ponte H.

Nel circuito sono presenti 4 transitor due NPN (Tr2 e Tr3) e due PNP (Tr1 e Tr4), collegati come indicato nel disegno che segue:

Mediante l’utilizzo di due output digitali di un microcontrollore invieremo sui pin IN1 e IN2 valori HIGH e LOW (tensioni di 5V e 0V) in modo da controllare la polarizzazione dei transitor e il conseguente verso di percorrenza della corrente che circola nella bobina statorica del motore.

Quando nel punto IN1 si ha un valore HIGH e su IN2 un valore LOW, andranno in conduzionei transistor Tr4 e Tr2 provocando la rotazione in un senso del motore

quando nel punto IN1 il segnale è LOW e su IN2 il segnale è HIGH i transistor che andranno in conduzione saranno il Tr1 e il Tr3, provocando la rotazione nel senso opposto al passo precedente:

La modalità di collegamento del circuito impedisce di alimentare contemporaneamente la coppia di transitor evitando così cortocircuiti.
I quattro diodi sono detti diodi di ricircolo ed il loro scopo è quello di proteggere i transistor dalla sovratensione generata dalla bobina statorica (induttanze) nel momento dell’apertura del circuito, infatti quando i transitor passano dalla condizione di conduzione a quella di interdizione (si apre l’interruttore) la corrente circolante dovrebbe andare istantaneamente a zero, ma l’induttore (la bobina statorica del motore) tende ad impedire questa brusca variazione, la tensione sul collettore del transitor tende ad aumentare a valori molto elevati.

Se immaginate il transitor in interdizione come ad un interruttore aperto, che quindi assume una resistenza elevatissima, l’induttore si comporterà per un breve istante come un generatore di tensione cercando di far passare in questa resistenza elevatissima la stessa corrente che era presente quando il bjt si comportava come interruttore chiuso, ma per la legge di ohm (V = RxI) la tensione sul collettore del bjt raggiunge valori molto alti, superiori alla tensione di alimentazione danneggiando il bjt.
Per evitare la distruzione del bjt viene inserito un diodo con catodo rivolto verso il positivo dell’alimentazione.

Durante la conduzione del transistor, il diodo non sarà polarizzato direttamente, mentre quando non sarà polarizzato (interruttore aperto) la corrente non passerà più attraverso il transistor, ma attraverso il diodo polarizzato direttamente.

Realizzazione del circuito

Il NEMA 17 richiede un’alimentazione tipica di 12V. La rotazione completa di 360° del rotore si ottiene facendo compiere 200 passi al motore. Ogni passo corrisponderà ad un angolo di 1,8°. La velocità massima che questo tipo di motore può raggiungere è di 60 RPM (dall’inglese revolutions per minute in italiano rotazioni per minuto giri/min).

Prima di collegare il motore alla scheda motori è necessario individuare i cavi A+, A-, B+ e B- sul motore. La maniera migliore è quella di consultare la scheda tecnica del motore in cui vi è una corrispondenza tra colore filo e cavo. In alternativa potete utilizzare un multimetro in modalità ohmmetro e misurare la resistenza tra le coppie dei cavi, quando misurerete un valore tra i 2 e i 4 ohm tra due terminali avrete individuato una delle bobine.

Collegare l’alimentazione esterna a 12V al terminale VCC e mantenere posizionare i jumper (i ponticelli) ENA ed ENB come indicato nell’immagine che segue in modo che il motore passo passo sia sempre abilitato al funzionamento.

Effettuare il collegamento dei pin di ingresso (IN1, IN2, IN3 e IN4) del modulo L298N a quattro pin di uscita digitale Arduino, nell’esempio sono stati utilizzati i pin: 8, 9, 10 e 11.

Collegare i fili A +, A-, B + e B- dal motore passo-passo al modulo come mostrato nell’immagine che segue.

Lo sketch indicato di seguito, che potrete utilizzare come base di partenza per le vostre sperimentazioni, permetterà di controllare il motore passo-passo facendogli compiere ripetutamente un giro in senso orario ed uno in senso antiorario.

// Inclusione della libreria stopper
#include <Stepper.h>

// Numero di step (passi) per effettuare una rotazione completa
const int stepPerRotazione = 200;

// Creazione dell’istanza dello Stepper
Stepper mioStepper(stepPerRotazione, 8, 9, 10, 11);

void setup()
{
    // impostazione della rotazione a 60 rpm:
    mioStepper.setSpeed(60);
    // inizializzazione della porta seriale:
    Serial.begin(9600);
}

void loop() 
{
    // una rotazione in una direzione
    Serial.println("Rotazione oraria");
    mioStepper.step(stepPerRotazione);
    delay(500);

    // una rotazione in una direzione
    Serial.println("Rotazione antioraria");
    mioStepper.step(-stepPerRotazione);
    delay(500);
}

Questo sketch include la libreria Stepper https://www.arduino.cc/en/Reference/Stepper.
La libreria avrà il compito di sequenziare gli impulsi verranno inviati al motore stepper.

// Inclusione della libreria stopper
#include <Stepper.h>

Definizione della variabile stepPerRotazione che stabilisce il numero di passi per un’intera rivoluzione, in questo caso 200 che corrispondono a 1,8 gradi per passo.

// Numero di step (passi) per effettuare una rotazione completa
const int stepPerRotazione = 200;

Creazione di un’istanza della libreria stepper. La creazione dell’istanza prevede l’indicazione del numero di step per rivoluzione e l’indicazione dei 4 pin digitali di Arduino a cui dovranno essere collegati i pin IN1, IN2, IN3, IN4 della scheda L298N.

// Creazione dell’istanza dello Stepper
Stepper mioStepper(stepPerRotazione, 8, 9, 10, 11);

Nel setup:

  • impostiamo la velocità del motore passo-passo invocando la funzione setSpeed()
  • impostiamo la velocità di comunicazione della Serial Monitor
void setup()
{
    // impostazione della rotazione a 60 rpm:
    mioStepper.setSpeed(60);
    // inizializzazione della porta seriale:
    Serial.begin(9600);
}

Nel loop() invochiamo la funzione step() che permette di stabilire il numero di passi, valori negativi consentono di invertire il senso di rotazione del motore.

void loop() 
{
    // una rotazione in una direzione
    Serial.println("Rotazione oraria");
    mioStepper.step(stepPerRotazione);
    delay(500);

    // una rotazione in una direzione
    Serial.println("Rotazione antioraria");
    mioStepper.step(-stepPerRotazione);
    delay(500);
}

Esercizi per i miei studenti

Esercizio 1
Realizzare un sistema che permetta la marcia e l’arresto del motore passo passo mediante l’uso di due pulsanti.

Esercizio 2
Realizzare un sistema che permetta la marci e l’arresto ed il controllo del senso di rotazione del motore. Usare pulsanti per il controllo della marcia e dell’arresto e dell’inversione di marcia.

Esercizio 3
Realizzare un sistema che mediante serial monitor permetta l’impostazione del numero di rotazioni e del senso di rotazione.

Esercizio 4
Realizzare un sistema che mediante tastierino esterno consenta di impostare il numero di rotazioni del sistema e il senso di rotazione del motore.
Utilizzare un display 16×2 I2C da usare per messaggi e allarmi.

Sul display dovrà essere visualizzato:

  • Numero di giri in tempo reale
  • Passi del motore
  • Senso di rotazione

Esercizio 5
Svolgere le stesse funzionalità dell’esercizio 4 ed aggiungere un sensore di temperatura TPM36 che superato un valore limite di temperatura di riscaldamento del motore passo passo attivi una ventola che lo raffreddi riportando la temperatura nel range di sicurezza stabilito, cessato l’allarme la ventola di raffreddamento si deve fermare.

EduRobot – ASL (Alternanza Scuola Lavoro) – Manuale di costruzione – 3/3

Nella guida che segue illustro un schema molto semplice per la realizzazione del controllo di EduRobot effettuata con Arduino. Fornirò passo passo gli sketch di esempio che dovrete migliorare. è può essere considerato la base di partenza per ogni sperimentazione basata appunto su Arduino.
Per il pilotaggio dei motori ho utilizzato e L298N Dual H-Bridge Motor Controller di cui vi ho dato indicazioni nella lezione precedente.

Ovviamente anche la soluzione proposta in questo tutorial potranno essere migliorate da voi, lo scopo è quello di svolgere l’attività di Alternanza Scuola Lavoro di questi giorni, ma nelle settimane che seguiranno potrete migliorare ogni aspetto del robot in quanto il corso su Arduino che state svolgendo nelle mie ore sarà svolto proprio sulla piattaforma EduRobot.

Potrete sostituire alle batterie che io ho utilizzato, batterie ricarrabili, o pacchi batterie con autonomia maggiore che potrete fissare utilizzando gli appositi fori predisposti sullo chassis, durante le lezioni in classe vi fornirò suggerimenti e modalità diverse di utilizzo della scheda L298N.

Nelle parti che seguono costruiamo passo passo il programma che consente la realizzaizone di un robot che si muove in modo autonomo.

Negli esempio che seguono verranno di volta aggiunte nuove funzioni, la lista completa è la seguente:

rotazioneOraria(tempo necessario per effettuare una determinata rotazione, velocità con cui ruota il robot)

Rotazione oraria di EduRobot sul proprio asse

stopEduRobot()

Blocca il movimento del robot

distanzaOstacolo()

restituisce la distanza in cm dell’ostacolo rilevato

paragonaDistanze()

verifica la distanza dell’ostacolo che si trova a distanza maggiore dal robot

scegliDirezione()

sceglie la direzione da prendere in funzione della distanza a cui si trova l’ostacolo

La spiegazione del funzionamento d ogni parte del codice è inclusa all’interno dello sketch come commento.

Nota per lo studio:

i 6 sketch proposti variano solo nel loop per la realizzazione delle funzioni richieste, la variazione tra uno sketch e l’altro consiste nell’aggiunta di poche linee di codice, sarà quindi necessario effettuare uno studio preliminare di tutte le parti dello sketch 1.

Sketch 1

Rotazione di 90° in senso orario del robot sul proprio asse e ritorno alla posizione di partenza con intervallo di stop di 3 secondi.

/*
  Prof. Maffucci Michele
  21.01.19

  EduRobot - Programma test n. 4
  Rotazione di 90° in senso orario del robot sul proprio asse
  e ritorno alla posizione di partenza con intervallo di stop di 3 secondi.

  Collegamenti:

  L298N -->  Arduino

  ENB  -->  Pin 10
  IN4  -->  Pin 5
  IN3  -->  Pin 4
  IN2  -->  Pin 3
  IN1  -->  Pin 2
  ENA  -->  Pin 9
  +12V -->  Vin
  GND  -->  GND
*/

// Impostazione pin motori

// motore 1 (sx)

int direzione1_M1 = 2;
int direzione2_M1 = 3;
int velocita_M1 = 9; // pin di tipo PWM per controllare la velocità del motore

// motore 2 (dx)

int direzione1_M2 = 4;
int direzione2_M2 = 5;
int velocita_M2 = 10; // pin di tipo PWM per controllare la velocità del motore

int velocita = 200;               // velocità di rotazione dei motori. Valore compreso tra 0 e 255
int velocita_scelta_dir = 150;    // velocità di rotazione dei motori per la scelta direzione. Valore compreso tra 0 e 255

int tempo_rotazione = 500;        // quantità di tempo di rotazione o di fermo motore

int tempo_rotazione_angolo = 350; // tempo per far ruotare il motore di 90°. Da variare in funzione della carica della batteria.
int velocita_rotazione = 150;     // velocità di rotazione di EduRobot sul proprio asse

int attesa = 3000; // tempo di attesa prima che il robot si muova

void setup() {

  // modalità di utilizzo dei pin di controllo
  pinMode(direzione1_M1, OUTPUT);
  pinMode(direzione2_M1, OUTPUT);
  pinMode(velocita_M1, OUTPUT);
  pinMode(direzione1_M2, OUTPUT);
  pinMode(direzione2_M2, OUTPUT);
  pinMode(velocita_M2, OUTPUT);

  delay(attesa);
}

// rotazione oraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneAntioraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) avanti - senso antiorario
  // Motore 2 (Dx) avanti - senso orario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso antiorario
  // per far girare il motore M2 (Dx) in senso orario

  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, HIGH);
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo);
}

// rotazione antioraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneOraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) - senso orario
  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  // per far girare il motore M2 (Dx) in senso antiorario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
  delay(tempo);
}

// ferma i motori
void stopEduRobot() {
  // Per fermare il motore impostare a 0 il secondo parametro
  analogWrite(velocita_M1, 0);
  analogWrite(velocita_M2, 0);
}

void loop() {
  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(3000);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(3000);
}

Dalla lezione precedente si sono utilizzati le parti di sketch che permettono la rotazione in senso antiorario ed orario dei motori.

La funzione rotazioneOraria e rotazioneAntioraria, di seguito evidenziate, consentono la rotazione di EduRobot sul proprio asse in una delle due direzioni. Le funzioni accettano due parametri:

  • tempo: tempo per compiere uno specifico angolo di rotazione
  • velocita_rotazione: velocità con cui gira il robot

Il tempo per compiere un angolo di 90° deve essere valutato sperimentalmente in quanto funzione della carica della batteria. Per regolare il tempo di rotazione per un angolo di 90° variare il valore della variabile globale: tempo_rotazione_angolo che trovate all’inizio dello sketch.

...
void rotazioneOraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) - senso orario
  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  // per far girare il motore M2 (Dx) in senso antiorario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
  delay(tempo);
}
...
...
void rotazioneOraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) - senso orario
  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  // per far girare il motore M2 (Dx) in senso antiorario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
  delay(tempo);
}
...

Per interrompere la rotazione di EduRobot è sufficiente inviare sui pin 9 e 5 di Arduino di tipo PWM il valore 0

...
void stopEduRobot() {
  // Per fermare il motore impostare a 0 il secondo parametro
  analogWrite(velocita_M1, 0);
  analogWrite(velocita_M2, 0);
}
...

Sketch 2

Rotazione di 180° in senso orario del robot sul proprio asse e ritorno alla posizione di partenza con intervallo di stop di 3 secondi.

Per eseguire questa esercitazione sarà sufficiente aggiungere allo sketch precedente un’ulteriore chiamata alle funzioni rotazioneOraria e rotazioneAntioraria, oppure variare il valore della variabile tempo_rotazione_angolo per un tempo doppio rispetto al tempo necessario per compiere una rotazione di 90°.

/*
  Prof. Maffucci Michele
  21.01.19

  EduRobot - Programma test n. 5
  Rotazione di 180° in senso orario del robot sul proprio asse e
  ritorno alla posizione di partenza con intervallo di stop di 3 secondi.

  Collegamenti:

  L298N -->  Arduino

  ENB  -->  Pin 10
  IN4  -->  Pin 5
  IN3  -->  Pin 4
  IN2  -->  Pin 3
  IN1  -->  Pin 2
  ENA  -->  Pin 9
  +12V -->  Vin
  GND  -->  GND
*/

// Impostazione pin motori

// motore 1 (sx)

int direzione1_M1 = 2;
int direzione2_M1 = 3;
int velocita_M1 = 9; // pin di tipo PWM per controllare la velocità del motore

// motore 2 (dx)

int direzione1_M2 = 4;
int direzione2_M2 = 5;
int velocita_M2 = 10; // pin di tipo PWM per controllare la velocità del motore

int velocita = 200;               // velocità di rotazione dei motori. Valore compreso tra 0 e 255
int velocita_scelta_dir = 150;    // velocità di rotazione dei motori per la scelta direzione. Valore compreso tra 0 e 255

int tempo_rotazione = 500;        // quantità di tempo di rotazione o di fermo motore

int tempo_rotazione_angolo = 350; // tempo per far ruotare il motore di 90°. Da variare in funzione della carica della batteria.
int velocita_rotazione = 150;     // velocità di rotazione di EduRobot sul proprio asse

int attesa = 3000; // tempo di attesa prima che il robot si muova

void setup() {

  // modalità di utilizzo dei pin di controllo
  pinMode(direzione1_M1, OUTPUT);
  pinMode(direzione2_M1, OUTPUT);
  pinMode(velocita_M1, OUTPUT);
  pinMode(direzione1_M2, OUTPUT);
  pinMode(direzione2_M2, OUTPUT);
  pinMode(velocita_M2, OUTPUT);

  delay(attesa);
}

// rotazione oraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneAntioraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) avanti - senso antiorario
  // Motore 2 (Dx) avanti - senso orario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso antiorario
  // per far girare il motore M2 (Dx) in senso orario

  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, HIGH);
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo);
}

// rotazione antioraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneOraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) - senso orario
  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  // per far girare il motore M2 (Dx) in senso antiorario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
  delay(tempo);
}

// ferma i motori
void stopEduRobot() {
  // Per fermare il motore impostare a 0 il secondo parametro
  analogWrite(velocita_M1, 0);
  analogWrite(velocita_M2, 0);
}

void loop() {
  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(3000);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(3000);
}

Sketch 3

Rotazione di 360° in senso orario del robot sul proprio asse, rotazione di 360° in senso antiorario del robot sul proprio asse con intervallo di stop a 180° di 1 secondo e stop di 3 secondi a 360°.

/*
  Prof. Maffucci Michele
  21.01.19

  EduRobot - Programma test n. 6
  Rotazione di 360° in senso orario del robot sul proprio asse, rotazione di 360°
  in senso antiorario del robot sul proprio asse con intervallo di stop a 180°
  di 1 secondo e stop di 3 secondi a 360°.

  Collegamenti:

  L298N -->  Arduino

  ENB  -->  Pin 10
  IN4  -->  Pin 5
  IN3  -->  Pin 4
  IN2  -->  Pin 3
  IN1  -->  Pin 2
  ENA  -->  Pin 9
  +12V -->  Vin
  GND  -->  GND
*/

// Impostazione pin motori

// motore 1 (sx)

int direzione1_M1 = 2;
int direzione2_M1 = 3;
int velocita_M1 = 9; // pin di tipo PWM per controllare la velocità del motore

// motore 2 (dx)

int direzione1_M2 = 4;
int direzione2_M2 = 5;
int velocita_M2 = 10; // pin di tipo PWM per controllare la velocità del motore

int velocita = 200;               // velocità di rotazione dei motori. Valore compreso tra 0 e 255
int velocita_scelta_dir = 150;    // velocità di rotazione dei motori per la scelta direzione. Valore compreso tra 0 e 255

int tempo_rotazione = 500;        // quantità di tempo di rotazione o di fermo motore

int tempo_rotazione_angolo = 350; // tempo per far ruotare il motore di 90°. Da variare in funzione della carica della batteria.
int velocita_rotazione = 150;     // velocità di rotazione di EduRobot sul proprio asse

int attesa = 3000; // tempo di attesa prima che il robot si muova

void setup() {

  // modalità di utilizzo dei pin di controllo
  pinMode(direzione1_M1, OUTPUT);
  pinMode(direzione2_M1, OUTPUT);
  pinMode(velocita_M1, OUTPUT);
  pinMode(direzione1_M2, OUTPUT);
  pinMode(direzione2_M2, OUTPUT);
  pinMode(velocita_M2, OUTPUT);

  delay(attesa);
}

// rotazione oraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneAntioraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) avanti - senso antiorario
  // Motore 2 (Dx) avanti - senso orario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso antiorario
  // per far girare il motore M2 (Dx) in senso orario

  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, HIGH);
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo);
}

// rotazione antioraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneOraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) - senso orario
  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  // per far girare il motore M2 (Dx) in senso antiorario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
  delay(tempo);
}

// ferma i motori
void stopEduRobot() {
  // Per fermare il motore impostare a 0 il secondo parametro
  analogWrite(velocita_M1, 0);
  analogWrite(velocita_M2, 0);
}

void loop() {

  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(1000);
  
  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(3000);

  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(1000);
  
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(3000);
}

Facendo eseguire ad EduRobot i medesimi spostamenti, ottimizzare il codice presente nel loop riducendo il numero di istruzioni.

Sketch 4

Ripetere la sequenza: avanti per 500 millisecondi, stop per 3 secondi, rotazione di 180° in senso orario del robot, stop di 1 secondo, avanti per 500 millisecondi, stop di 3 secondi, rotazione di 180° in senso antiorario, stop di 1 secondo, movimento in avanti per 500 millisecondi.

/*
  Prof. Maffucci Michele
  21.01.19

  EduRobot - Programma test n. 7
  Sequenza: avanti per 500 millisecondi, stop per 3 secondi, rotazione di 180° in senso orario del robot,
  stop di 1 secondo, avanti per 500 millisecondi, stop di 3 secondi, rotazione di 180° in senso antiorario,
  stop di 1 secondo, movimento in avanti per 500 millisecondi.

  Collegamenti:

  L298N -->  Arduino

  ENB  -->  Pin 10
  IN4  -->  Pin 5
  IN3  -->  Pin 4
  IN2  -->  Pin 3
  IN1  -->  Pin 2
  ENA  -->  Pin 9
  +12V -->  Vin
  GND  -->  GND
*/

// Impostazione pin motori

// motore 1 (sx)

int direzione1_M1 = 2;
int direzione2_M1 = 3;
int velocita_M1 = 9; // pin di tipo PWM per controllare la velocità del motore

// motore 2 (dx)

int direzione1_M2 = 4;
int direzione2_M2 = 5;
int velocita_M2 = 10; // pin di tipo PWM per controllare la velocità del motore

int velocita = 200;               // velocità di rotazione dei motori. Valore compreso tra 0 e 255
int velocita_scelta_dir = 150;    // velocità di rotazione dei motori per la scelta direzione. Valore compreso tra 0 e 255

int tempo_rotazione = 500;        // quantità di tempo di rotazione o di fermo motore

int tempo_rotazione_angolo = 350; // tempo per far ruotare il motore di 90°. Da variare in funzione della carica della batteria.
int velocita_rotazione = 150;     // velocità di rotazione di EduRobot sul proprio asse
int velocita_avanti = 150;        // velocità di avanzamento in avanti di EduRobot

int attesa = 3000; // tempo di attesa prima che il robot si muova

void setup() {

  // modalità di utilizzo dei pin di controllo
  pinMode(direzione1_M1, OUTPUT);
  pinMode(direzione2_M1, OUTPUT);
  pinMode(velocita_M1, OUTPUT);
  pinMode(direzione1_M2, OUTPUT);
  pinMode(direzione2_M2, OUTPUT);
  pinMode(velocita_M2, OUTPUT);

  delay(attesa);
}

// rotazione oraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneAntioraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) avanti - senso antiorario
  // Motore 2 (Dx) avanti - senso orario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso antiorario
  // per far girare il motore M2 (Dx) in senso orario

  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, HIGH);
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo);
}

// rotazione antioraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneOraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) - senso orario
  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  // per far girare il motore M2 (Dx) in senso antiorario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
  delay(tempo);
}

// ferma i motori
void stopEduRobot() {
  // Per fermare il motore impostare a 0 il secondo parametro
  analogWrite(velocita_M1, 0);
  analogWrite(velocita_M2, 0);
}

// Movimento in Avanti di EduRobot
void avantiPer(int tempo_avanti)
{
  // Motore 1 (Sx) avanti - senso antiorario
  // Motore 2 (Dx) avanti - senso orario

  analogWrite(velocita_M1, velocita_avanti); // Imposta la velocità del motore M1 a velocita_avanti
  analogWrite(velocita_M2, velocita_avanti); // Imposta la velocità del motore M2 a velocita_avanti

  // per far girare il motore M1 (Sx) in senso antiorario
  // per far girare il motore M2 (Dx) in senso orario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo_avanti);

}

void loop() {

  // avanti per 500 millisecondi, stop per 3 secondi
  avantiPer(500);
  stopEduRobot();
  delay(3000);

  // rotazione di 180° in senso orario del robot, stop di 1 secondo
  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  rotazioneOraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(1000);

  // avanti per 500 millisecondi, stop di 3 secondi
  avantiPer(500);
  stopEduRobot();
  delay(3000);

  // rotazione di 180° in senso antiorario, stop di 1 secondo
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_rotazione);
  stopEduRobot();
  delay(1000);

}

Sketch 5

Realizzare uno sketch che permetta di realizzare in sequenza le tre rotazioni:

  1. 45° in senso antiorario del robot
  2. dalla posizione raggiunta rotazione di 90° in senso orario
  3. dalla posizione raggiunta, rotazione di 45° in senso antiorario

Sketch 6

Utilizzando il sensore ad ultrasuoni HC-SR04 per rilevare gli ostacoli ed effettuare la scelta della direzione da intraprendere in funzione dell’ostacolo che si trova a distanza maggiore dal robot.

Funzionamento del sensore HC-SR04

Per l’utilizzo del sensore ad ultrasuoni ne avevo già dato spiegazione in EduRobot UNO – Come costruire il vostro primo Arduino Robot – Lezione 2  ma per permetterne un’agevole studio duplico quanto già scritto nel tutorial in modo che abbiate un punto unico di riferimento.

Per far evitare gli ostacoli al nostro robot utilizzeremo un sensore ad ultrasuoni, in altro modo useremo questo sensore per misurare la distanza dell’ostacolo, ma potremo anche pensare di usare questo sensore, ad esempio, in un sistema anti-intrusione che deve far suonare un allarme. In questa lezione viene utilizzato il sensore HC-SR04, dispositivo economico e con un buon range operativo, ha una sensibilità dichiarata nei datasheet che va da 2 centimetri a 4,5 metri circa, in realtà la massima distanza da esperimenti che ho effettuato arriva a circa 3,5 metri, molto comunque dipende dai materiali colpiti e dalla loro capacità di assorbimento sonoro.

Ma come funziona un sensore di questo tipo?

I sensori ad ultrasuoni non forniscono direttamente la misura della distanza dell’oggetto più vicino, ma misurano il tempo impiegato da un segnale sonoro a raggiungere l’oggetto e ritornare al sensore.

L’impulso ad ultrasuoni inviato all’HC-SR04 è di circa 40KHz il tempo viene misurato in microsecondi, la tensione di funzionamento è di 5V, quindi potremo alimentarlo direttamente utilizzando Arduino.

L’HC-SR04 è dotato di 4 piedini: GND, eco, trigger, +Vcc.

Per convertire l’intervallo di tempo misurato in una lunghezza, bisogna ricordare che la velocità del suono è di 331,5 m/s a 0 °C e di 343,4 m/s a 20 °C ed in generale varia secondo la relazione:

v = 331,4 + 0,62 T

dove la temperatura T è misurata in °C.

Per effettuare una misura di distanza di un ostacolo assumiamo di lavorare ad una temperatura ambiente di 20 °C e quindi la velocità del suono sarà di 343 m/s (approssimiamo) che vuol dire anche 0,0343 cm/microsecondi.

Quindi, ricordando che v=s/t (v: velocità, s: spazio, t: tempo) allora lo spazio percorso sarà:

s = v*t

da cui

s = 0,0343 *t

però, per calcolare lo spazio percorso, bisogna tener conto che il suono percorre due volte la distanza da misurare (giunge sull’oggetto e ritorna indietro al sensore) quindi il valore di t ottenuto deve essere diviso per 2. La formula corretta per la misura dello spazio percorso è:

s = 0,0343 * t/2

eseguendo la divisione di 0,0343/2 possiamo scrivere:

s = 0,01715 * t

oppure:

s = t/58,31

approssimando

s = t/58

formula più semplice da ricordare.

Per calcolare la distanza dell’oggetto dal sensore sarà sufficiente dividere il tempo t (tempo impiegato dal segnale per giungere sull’oggetto e tornare al sensore) per 58.

Per poter effettuare una misurazione viene mantenuto a livello basso il pin Trigger, dopo di che viene fornito un impulso a livello alto della durata minima di 10µs riportandolo poi a livello basso, dopo questo momento la capsula trasmittente emette un burst (sequenza di livelli alti/bassi) a circa 40KHz, l’onda ultrasonica generata (burst) colpisce l’ostacolo, torna indietro venendo rilevata dalla capsula ricevente. L’elettronica del sensore effettua un calcolo del tempo di andata e ritorno del segnale emettendo sul pin Echo, normalmente a livello basso, un segnale a livello alto direttamente proporzionale alla distanza dell’ostacolo:

/*
  Prof. Maffucci Michele
  21.01.19

  EduRobot - Programma test n. 8
  Utilizzando il sensore ad ultrasuoni rilevare gli ostacoli ed effettuare la scelta
  della direzione da intraprendere in funzione dell’ostacolo che si
  trova a distanza maggiore dal robot.

  Collegamenti:

  L298N -->  Arduino

  ENB  -->  Pin 10
  IN4  -->  Pin 5
  IN3  -->  Pin 4
  IN2  -->  Pin 3
  IN1  -->  Pin 2
  ENA  -->  Pin 9
  +12V -->  Vin
  GND  -->  GND
*/

// Impostazione pin motori

// motore 1 (sx)

int direzione1_M1 = 2;
int direzione2_M1 = 3;
int velocita_M1 = 9; // pin di tipo PWM per controllare la velocità del motore

// motore 2 (dx)

int direzione1_M2 = 4;
int direzione2_M2 = 5;
int velocita_M2 = 10; // pin di tipo PWM per controllare la velocità del motore

int velocita = 200;               // velocità di rotazione dei motori. Valore compreso tra 0 e 255
int velocita_scelta_dir = 150;    // velocità di rotazione dei motori per la scelta direzione. Valore compreso tra 0 e 255

int tempo_rotazione = 500;        // quantità di tempo di rotazione o di fermo motore

int tempo_rotazione_angolo = 350; // tempo per far ruotare il motore di 90°. Da variare in funzione della carica della batteria.
int velocita_rotazione = 150;     // velocità di rotazione di EduRobot sul proprio asse
int velocita_avanti = 150;        // velocità di avanzamento in avanti di EduRobot

int attesa = 3000; // tempo di attesa prima che il robot si muova

// Impostazione sensore ultrasuoni
const int distanzaPericolo = 20;      // distanza minima dell'ostacolo (in cm)
int distanzaSinistra, distanzaDestra; // distanza sinistra e destra
int misuraDistanza = 0;

long durata;            // durata dell'impulso
long distanza;          // distanza dell'oggetto
int pin_segnale = 7;    // pin Arduino a cui è collegato il sensore SR04
int pin_trig = 6;       // pin Arduino a cui è collegato il sensore SR04

void setup() {

  // modalità di utilizzo dei pin di controllo
  pinMode(direzione1_M1, OUTPUT);
  pinMode(direzione2_M1, OUTPUT);
  pinMode(velocita_M1, OUTPUT);
  pinMode(direzione1_M2, OUTPUT);
  pinMode(direzione2_M2, OUTPUT);
  pinMode(velocita_M2, OUTPUT);

  // impostazione pin per sensore ultrasuoni SR04
  pinMode(pin_trig, OUTPUT);
  pinMode(pin_segnale, INPUT);

  delay(attesa);
}

// rotazione oraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneAntioraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) avanti - senso antiorario
  // Motore 2 (Dx) avanti - senso orario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso antiorario
  // per far girare il motore M2 (Dx) in senso orario

  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, HIGH);
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo);
}

// rotazione antioraria di EduRobot sul proprio asse
// tempo: tempo per compiere uno specifico angolo di rotazione
// velocita_rotazione: velocità con cui gira il robot

void rotazioneOraria(int tempo, int velocita_rotazione) {

  // Motore 1 (Sx) - senso orario
  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M1, velocita_rotazione); // Imposta la velocità del motore M1 a velocità = 200
  analogWrite(velocita_M2, velocita_rotazione); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  // per far girare il motore M2 (Dx) in senso antiorario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
  delay(tempo);
}

// ferma i motori
void stopEduRobot() {
  // Per fermare il motore impostare a 0 il secondo parametro
  analogWrite(velocita_M1, 0);
  analogWrite(velocita_M2, 0);
}

// Movimento in Avanti di EduRobot
void avantiPer(int tempo_avanti)
{
  // Motore 1 (Sx) avanti - senso antiorario
  // Motore 2 (Dx) avanti - senso orario

  analogWrite(velocita_M1, velocita_avanti); // Imposta la velocità del motore M1 a velocita_avanti
  analogWrite(velocita_M2, velocita_avanti); // Imposta la velocità del motore M2 a velocita_avanti

  // per far girare il motore M1 (Sx) in senso antiorario
  // per far girare il motore M2 (Dx) in senso orario

  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo_avanti);

}

void avantiSempre(int velocita)
{

  // Motore 1 (Sx) - senso antiorario

  analogWrite(velocita_M1, velocita); // Imposta la velocità del motore M1 a velocità = 200

  // per far girare il motore M1 (Sx) in senso antiorario
  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);

  // Motore 2 (Dx) - senso orario

  analogWrite(velocita_M2, velocita); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M2 (Dx) in senso orario
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
}

// Indietro senza stop
void indietroSempre(int velocita)
{

  // Motore 1 (Sx) - in senso orario

  analogWrite(velocita_M1, velocita); // Imposta la velocità del motore M1 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, HIGH);

  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M2, velocita); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M2 (Dx) in senso antiorario
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
}

// restituisce la distanza in cm dell’ostacolo rilevato
long distanzaOstacolo()
{
  digitalWrite(pin_trig, LOW);
  delayMicroseconds(2);
  digitalWrite(pin_trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(pin_trig, LOW);
  durata = pulseIn(pin_segnale, HIGH);
  distanza = (durata / 2) / 29.1;
  delay(100);
  return distanza;
}

// verifica la distanza dell’ostacolo che si trova a distanza maggiore dal robot
void paragonaDistanze()
{
  if (distanzaSinistra > distanzaDestra) // vai a sinistra perchè ostacolo a sx più lontano
  {
    rotazioneAntioraria(tempo_rotazione_angolo, velocita_scelta_dir);
    delay(500);
  }
  else if (distanzaDestra < distanzaSinistra) // vai a destra perchè ostacolo a dx più lontano
  {
    rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
    delay(500);
  }
  else // se le distanze degli ostacoli a
  { // sx e dx sono uguali gira di 180 gradi (circa)
    rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
    rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
    delay(1000);
  }
}

// sceglie la direzione da prendere in funzione della distanza a cui si trova l’ostacolo
void scegliDirezione() {
  rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
  distanzaDestra = distanzaOstacolo();   // lettura distanza ostacolo di dx
  delay(500);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_scelta_dir);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_scelta_dir);
  distanzaSinistra = distanzaOstacolo(); // lettura distanza ostacolo di sx
  delay(500);
  rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
  delay(100);
  paragonaDistanze();
}

void loop() {
  misuraDistanza = distanzaOstacolo();
  if (misuraDistanza > distanzaPericolo) // vai avanti
  {
    avantiSempre(velocita_avanti);                      // se non ci sono ostacoli vai avanti
  }
  // valutazione dell'ostacolo che si trova a distanza maggiore
  // se l'ostacolo si trova a distanza minore di "distanzaPericolo"
  // bisogna scegliere la direzione
  else
  {
    stopEduRobot();
    scegliDirezione();
  }
}

Descrizione sketch 6

Nota: si descrivono solo le sezioni aggiunte rispetto agli sketch precedenti.

Impostazione del sensore ad ultrasuoni

...
// Impostazione sensore ultrasuoni
const int distanzaPericolo = 20;      // distanza minima dell'ostacolo (in cm)
int distanzaSinistra, distanzaDestra; // distanza sinistra e destra
int misuraDistanza = 0;

long durata;            // durata dell'impulso
long distanza;          // distanza dell'oggetto
int pin_segnale = 7;    // pin Arduino a cui è collegato il sensore SR04
int pin_trig = 6;       // pin Arduino a cui è collegato il sensore SR04
...

Questa sezione è dedicata all’impostazione del sensore ad ultrasuoni.

La variabile “durata” è il tempo impiegato dall’onda ultrasonica per giungere al rilevatore, questo valore verrà utilizzato per il calcolo della distanza dell’oggetto.
Le due variabili: pin_segnale e pin_trig sono quelle associate ai pin signal e trigger del sensore ad ultrasuoni.

Descrizione funzionamento loop()

...
void loop() {
  misuraDistanza = distanzaOstacolo();
  if (misuraDistanza > distanzaPericolo) // vai avanti
  {
    avantiSempre(velocita_avanti);       // se non ci sono ostacoli vai avanti
  }
  // valutazione dell'ostacolo che si trova a distanza maggiore
  // se l'ostacolo si trova a distanza minore di "distanzaPericolo"
  // bisogna scegliere la direzione
  else
  {
    stopEduRobot();
    scegliDirezione();
  }
}
...

Nel loop() come prima azione viene memorizzata nella variabile misuraDistanza il valore restituito dalla funzione che calcola la distanza dell’ostacolo: distanzaOstacolo() che riceve le informazioni dal sensore ad ultrasuoni.
Se la distanza misurata è maggiore della distanzaPericolo, la minima distanza dall’ostacolo, allora vuol dire che EduRobot può continuare ad andare avanti, altrimenti se la misuraDistanza è inferiore alla distanza di pericolo bisogna fermare EduRobot ed effettuare il cambio di direzione.

...
  {
    stopEduRobot();
    scegliDirezione();
  }
...

Scelta della direzione da prendere

...
// sceglie la direzione da prendere in funzione della distanza a cui si trova l’ostacolo
void scegliDirezione() {
  rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
  distanzaDestra = distanzaOstacolo();   // lettura distanza ostacolo di dx
  delay(500);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_scelta_dir);
  rotazioneAntioraria(tempo_rotazione_angolo, velocita_scelta_dir);
  distanzaSinistra = distanzaOstacolo(); // lettura distanza ostacolo di sx
  delay(500);
  rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
  delay(100);
  paragonaDistanze();
}
...

EduRobot effettua una rotazione di 90° a destra, effettua la lettura ed assegna il valore letto alla variabile distanzaDestra, si ferma nella posizione per mezzo secondo.
EduRobot effettua una rotazione di 180° in senso antiorario rispetto alla precedente posizione effettua la lettura della distanza dell’ostacolo che viene memorizzata nella variabile distanzaSinistra, si ferma nella posizione per mezzo secondo.
Si pone nuovamente in posizione frontale ruotando in senso orario di 90°, mantiene la posizione ed invoca la funzione paragonaDistanze() che verifica quale delle due misure risulta maggiore.

Lettura della distanza dell’ostacolo

...
// restituisce la distanza in cm dell’ostacolo rilevato
long distanzaOstacolo()
{
  digitalWrite(pin_trig, LOW);
  delayMicroseconds(2);
  digitalWrite(pin_trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(pin_trig, LOW);
  durata = pulseIn(pin_segnale, HIGH);
  distanza = (durata / 2) / 29.1;
  delay(100);
  return distanza;
}
...

La modalità di funzionamento di questa funzione è stata descritta nella parte iniziale della sezione dedicata allo sketch 6.

Paragonare le distanze per la scelta del percorso

...
// verifica la distanza dell’ostacolo che si trova a distanza maggiore dal robot
void paragonaDistanze()
{
  if (distanzaSinistra > distanzaDestra) // vai a sinistra perchè ostacolo a sx più lontano
  {
    rotazioneAntioraria(tempo_rotazione_angolo, velocita_scelta_dir);
    delay(500);
  }
  else if (distanzaDestra < distanzaSinistra) // vai a destra perchè ostacolo a dx più lontano
  {
    rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
    delay(500);
  }
  else // se le distanze degli ostacoli a
  { // sx e dx sono uguali gira di 180 gradi (circa)
    rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
    rotazioneOraria(tempo_rotazione_angolo, velocita_scelta_dir);
    delay(1000);
  }
}
...

Nel caso in cui l’ostacolo che si trova a sinistra è ad una distanza maggiore da quello dell’ostacolo di destra, allora EduRobot ruoterà in senso antiorario di 90° e manterrà la posizione raggiunta per mezzo secondo.

Se invece l’ostacolo che si trova a destra si trova a distanza maggiore di quello di sinistra, allora EduRobot ruoterà in senso orario di 90° e manterrà la posizione raggiunta per mezzo secondo.

Se le distanze degli ostacoli a sinistra e a destra sono identiche, EduRobot ruota di 180° in senso orario e mantiene la posizione per 1 secondo.

Movimento continuo in avanti e indietro alla velocità scelta

...
void avantiSempre(int velocita)
{

  // Motore 1 (Sx) - senso antiorario

  analogWrite(velocita_M1, velocita); // Imposta la velocità del motore M1 a velocità = 200

  // per far girare il motore M1 (Sx) in senso antiorario
  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);

  // Motore 2 (Dx) - senso orario

  analogWrite(velocita_M2, velocita); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M2 (Dx) in senso orario
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
}

// Indietro senza stop
void indietroSempre(int velocita)
{

  // Motore 1 (Sx) - in senso orario

  analogWrite(velocita_M1, velocita); // Imposta la velocità del motore M1 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, HIGH);

  // Motore 2 (Dx) - senso antiorario

  analogWrite(velocita_M2, velocita); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M2 (Dx) in senso antiorario
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
}
...

Nel codice sopra indicato avantiSempre(int velocita) permette di movimentare EduRobot in avanti ad una specifica velocità è necessario far girare la ruota sinistra in senso antiorario e lo destra in senso orario, mentre indietroSempre(int velocita) permette di muovere indietro (in retromarcia) EduRobot alla specifica velociotà è necessario far girare la ruota sinistra in senso orario e lo destra in senso antiorario.

Esercizi

Esercizio 1

Ad ogni stop del robot si accendere un led rosso.

Esercizio 2

Ad ogni stop si accendere un led rosso e durante la scelta della direzione lampeggia un led giallo.

Esercizio 3

Ad ogni stop si accendere un led rosso e durante la scelta della direzione lampeggia un led giallo, mentre il movimento in avanti ed indietro è evidenziato da un led verde acceso che dovrà spegnersi durante la scelta della direzione.

Esercizio 4

Aggiungere al circuito dell’esercizio precedente un buzzer che all’avvio del robot per 2 secondi, vengano suonate alcune note musicali.

Esercizio 5

Aggiungere al circuito dell’esercizio precedente un buzzer che all’avvio del robot per 2 secondi,emetta un jingle musicale ed ogni volta che viene effettuata la rilevazione del percorso da intraprendere vengano suonate alcune note musicali.

Esercizio 6

Aggiungere una funzione di casualità che ad intervalli prestabiliti fa cambiare direzione al robot indipendentemente dalla scelta della direzione verso l’ostacolo più lontano.

Esercizio 7

EduRobot non è dotato di un encoder, ovvero un sistema in grado di regolare la velocità delle due in modo da far andare dritto il robot, avrai notato che un motore gira ad una velocità superiore rispetto ad un’altro.

Saresti in grado di realizzare un semplice programma di calibrazione da eseguire in fase iniziale in grado di migliorare leggermente il movimento rettilineo del robot?

Buona sperimentazione a tutti 🙂

EduRobot – ASL (Alternanza Scuola Lavoro) – Manuale di costruzione – 2/3

In questo seconda parte del manuale di costruzione di EduRobot – ASL vedremo come effettuare tutti i collegamenti elettrici tra motori, Arduino, L298N e proporrò alcuni esercizi.

Durante questa fase non collegate la batteria di alimentazione alla scheda, accertatevi che tutti i collegamenti siano corretti e prima di procedere con i test di funzionamento chiedete un controllo al docente presente in aula oppure contattatemi.

L298N Dual H-Bridge Motor Controller

Per poter pilotare i motori in corrente continua di EduRobot è necessario utilizzare un driver motori costituito da due ponti H, se sei uno dei miei studenti di 3′ che sta svolgendo questa esercitazione per l’Alternanza Scuola Lavoro, ti ricordo che questo argomento di elettronica sarà affrontato al 4′ anno, ma se vuoi avere dettagli sul controllo dei motori in CC puoi consultare la mia dispensa: Alfabeto di Arduino – Lezione 6 alla pagina n. 39 dove spiego come usare un driver L293D e fornisco alcuni sketch di esempio, il funzionamento è molto simile al driver L298N.

Inoltre ti ricordo che per comprendere esattamente il controllo della velocità e della direzione dei motori è essenziale leggere la dispensa: Alfabeto di Arduino – Lezione 2 alla pagina 85 in cui parlo di Modulazione di larghezza di impulso (PWM). Per i miei allievi di 3′ affronterò questo argomento nelle prossime lezioni di Laboratorio di Sistemi.

Per lo svolgimento di questa esercitazione sarà sufficiente seguire gli esempi è fornirò, in maniera molto più semplice la modalità per controllare velocità e direzione di EduRobot.

Ponte H

Per controllare la direzione di rotazione del motore abbiamo bisogno di invertire la direzione del flusso di corrente attraverso il motore, il metodo più comune per fare questa operazione è quella che fa uso di un ponte H.
Un ponte H è costituito da quattro elementi di commutazione che possono essere dei transistor o dei mosfet, per semplicità, poiché hai incominciato elettronica quest’anno, non conosci ancora questi componenti elettronici, per ora assumi la loro funzione a degli interruttori che possiamo comandare attraverso Arduino, nei prossimi mesi ti spiegherò come funzionano.
Al centro del ponte H è collocato il motore elettrico e come puoi vedere dall’immagine, attivando contemporaneamente due interruttori alla volta è possibile modificare la direzione della corrente modificando in questo modo modifichiamo anche la direzione di rotazione del motore.
Nella scheda che ti ho consegnato sono presenti due ponti H uno per ogni motore, inoltre con questa scheda possiamo anche controllare la velocità di rotazione dei motori.

Per ora tutto ciò può essere sufficiente per svolgere l’esercitazione.

L298N Dual H-Bridge Motor Controller è presente in commercio in forme diverse ma con stesse funzionalità, ha una dimensione estremamente contenuta:

L298N Dual H-Bridge Motor Controller

All’interno della scheda sono presenti due ponti H in grado di controllare velocità e senso di rotazione di due motori in CC (quelli gialli che trovate nel kit allegato, a lezioni vi spiegheremo il funzionamento teorico) oppure controllare un motore passo-passo (come quelli presenti nella stampante 3D che vi ho mostrato a scuola). La scheda può essere usata per motori con tensione di alimentazione dai 5 ai 35V e corrente massima di lavoro di 2A.

Ogni ponte H può essere abilitato o disabilitato attraverso i pin enable, quelli che sulla scheda sono indicati con ENA e ENB. Abilitare o meno il ponte H è come dire: “comando o non comando il motore”, per fare un’analogia possiamo considerarlo ENA e ENB all’aceleratore dei motori A e B, vedremo che se viene inviato su di essi un valore MAGGIORE DI 0, permettiamo la rotazione del motore (premiamo l’acceleratore), se invece viene inviato il VALORE 0 ad uno degli EN non permettiamo la rotazione del motore (non premiamo l’acceleratore).

Descrizione dei pin della scheda

Di seguito trovate i riferimenti per la scheda L298N tra numero del pin e la sua funzione:

  1. Motore 1 CC: [OUT1: +]. Motore passo-passo: A+
  2. Motore 1 CC: [OUT2: -]. Motore passo-passo: A-
  3. Jumper da rimuovere se la tensione di alimentazione dei motori risulta superiore ai 12V.
  4. Alimentazione del/dei motori. Il pin accetta una tensione massima di 35V CC. Se la tensione di funzionamento dei motori è superiore ai 12V è necessario rimuovere il ponticello 3
  5. GND – il ground
  6. Uscita a 5 V tensione stabilizzata che può essere usata per alimentare direttamente Arduino
  7. ENA – permette l’abilitazione o la disabilitazione del motore A in CC (Corrente Continua), quello connesso ai pin nominati OUT1 e OUT2. Se si vuole comandare un motore in CC togliere il ponticello o posizionarlo come indicato nell’immagine che segue. Nel caso si voglia pilotare un motore passo passo non rimuovere il ponticello. Il pin ENA dovrà essere connesso ad un pin Arduino di tipo PWM per il controllo della velocità di un motore in CC.
  8. IN1 – per il controllo della direzione di rotazione
  9. IN2 – per il controllo della direzione di rotazione
  10. IN3 – per il controllo della direzione di rotazione
  11. IN4 – per il controllo della direzione di rotazione
  12. ENB – permette l’abilitazione o la disabilitazione del motore A in CC (Corrente Continua), quello connesso ai pin nominati OUT3 e OUT4. Se si vuole comandare un motore in CC togliere il ponticello o posizionarlo come indicato nell’immagine che segue. Nel caso si voglia pilotare un motore passo passo non rimuovere il ponticello. Il pin ENA dovrà essere connesso ad un pin Arduino di tipo PWM per il controllo della velocità di un motore in CC.
  13. Motore 2 CC: [OUT3: +]. Motore passo-passo: B+
  14. Motore 2 CC: [OUT4: +]. Motore passo-passo: B-
Jumper ENA e ENB in modalità motore passo-passo
Jumper ENA e ENB in modalità motore motore in CC

Circuito n. 1 – schema di collegamento

Il collegamento dei motori di EduRobot avranno polarità invertita (ricordate che il motore di sinistra per andara avanti deve girare in senso antiorario e il motore di destra in senso orario), così come indicato nell’immagine che segue, se invertite la polarità la rotazione sarà opposta.

Seguire le indicazioni di collegamento per effettuare i primi test di funzionamento.

I collegamenti tra scheda L298N e Arduino devono essere quelli riportati nello schema e dettagliati nell’immagine che segue. I pin ENA e ENB dovranno essere collegati ai pin 10 e 9 di Arduino che sono pin di tipo PWM con essi controlleremo l’attivazione dei motori e la loro velocità. I pin Arduino di tipo PWM sono quelli indicati dal segno “~“.

Dettaglio collegamento tra L298N ed Arduino UNO

Fate attenzione al collegamento che segue: Pin +12V della Scheda motori con VIN scheda Arduino, ciò consentirà di alimentare direttamente tutta l’elettronica mediante la tensione applicata al Jack di alimentazione di Arduino.

Dettaglio collegamento alimentazione L298N a scheda Arduino UNO (GND – VIN)

L’alimentazione dei motori, della scheda motori e della scheda Arduino UNO avviene collegando una batteria da 9V al Jack di alimentazione di Arduino.

Modalità di alimentazione circuiti

Programmi di test 1

Specifiche: si realizzi la sequenza che ripete ciclicamente la rotazione avanti e indietro delle due ruote del robot:

  • Il motore Sx ruota in senso antiorario (in avanti) per 500 millisecondi (o,5 secondi).
  • Il motore Sx si ferma per 500 millisecondi.
  • Il motore Sx ruota in senso orario (indietro) per 500 millisecondi
  • Il motore Sx si ferma per 500 millisecondi
  • Il motore Dx ruota in senso antiorario (in avanti) per 500 millisecondi (o,5 secondi).
  • Il motore Dx si ferma per 500 millisecondi.
  • Il motore Dx ruota in senso orario (indietro) per 500 millisecondi
  • Il motore Dx si ferma per 500 millisecondi

Quando effettuate l’upload del programma sulla scheda Arduino scollegate la batteria di alimentazione di EduRobot.

Per collegare il cavo USB alla scheda Arduino potrebbe essere necessario togliere la ruota SX.

Per il test del programma posizionate il robot in una modalità in cui le ruote non toccano la superficie di appoggio, per esempio come rappresentato in figura:

Ricordate che la polarità di collegamento dei motori alla scheda L298N è opposta, nel caso di discordanza di rotazione rispetto a quanto indicato nel programma provate ad invertire la modalità di collegamento dei motori sulla breadboard oppure variate il programma.

/*
  Prof. Maffucci Michele
  20.01.19
  
  EduRobot - Programma test n. 1

  Collegamenti:

  L298N -->  Arduino

  ENB  -->  Pin 10
  IN4  -->  Pin 5
  IN3  -->  Pin 4
  IN2  -->  Pin 3
  IN1  -->  Pin 2
  ENA  -->  Pin 9
  +12V -->  Vin
  GND  -->  GND
*/

// Impostazione pin motori

// motore 1 (sx)

int direzione1_M1 = 2;
int direzione2_M1 = 3;
int velocita_M1 = 9; // pin di tipo PWM per controllare la velocità del motore

// motore 2 (dx)

int direzione1_M2 = 4;
int direzione2_M2 = 5;
int velocita_M2 = 10; // pin di tipo PWM per controllare la velocità del motore

int velocita = 200;         // velocità di rotazione dei motori. Valore compreso tra 0 e 255
int tempo_rotazione = 500; // quantità di tempo di rotazione o di fermo motore

int attesa = 3000; // tempo di attesa prima che parta la rotazione dei motori

void setup() {

  // modalità di utilizzo dei pin di controllo
  pinMode(direzione1_M1, OUTPUT);
  pinMode(direzione2_M1, OUTPUT);
  pinMode(velocita_M1, OUTPUT);
  pinMode(direzione1_M2, OUTPUT);
  pinMode(direzione2_M2, OUTPUT);
  pinMode(velocita_M2, OUTPUT);

  delay(attesa);
}

void loop() {

// --- Motore 1 ---

  // Motore 1 (Sx) avanti - senso antiorario

  analogWrite(velocita_M1, velocita); // Imposta la velocità del motore M1 a velocità = 200

  // per far girare il motore M1 (Sx) in senso antiorario
  digitalWrite(direzione1_M1, HIGH);
  digitalWrite(direzione2_M1, LOW);
  delay(tempo_rotazione);

  // Motore 1 (Sx) fermo

  analogWrite(velocita_M1, 0); // Per fermare il motore impostare a 0 il secondo parametro

  // fermare il motore M1 (Sx)
  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, LOW);
  delay(tempo_rotazione);

  // Motore 1 (Sx) indietro - in senso orario

  analogWrite(velocita_M1, velocita); // Imposta la velocità del motore M1 a velocità = 200

  // per far girare il motore M1 (Sx) in senso orario
  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, HIGH);
  delay(tempo_rotazione);

  // Motore 1 (Sx) fermo

  analogWrite(velocita_M1, 0); // Per fermare il motore impostare a 0 il secondo parametro

  // fermare il motore M1 (Sx)
  digitalWrite(direzione1_M1, LOW);
  digitalWrite(direzione2_M1, LOW);
  delay(tempo_rotazione);

// --- Motore 2 ---

  // Motore 2 (Dx) avanti - senso orario

  analogWrite(velocita_M2, velocita); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M2 (Dx) in senso orario
  digitalWrite(direzione1_M2, HIGH);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo_rotazione);

  // Motore 2 (Dx) fermo

  analogWrite(velocita_M2, 0); // Per fermare il motore impostare a 0 il secondo parametro

  // fermare il motore M2 (Dx)
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo_rotazione);

  // Motore 2 (Dx) indietro - senso antiorario

  analogWrite(velocita_M2, velocita); // Imposta la velocità del motore M2 a velocità = 200

  // per far girare il motore M2 (Dx) in senso antiorario
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, HIGH);
  delay(tempo_rotazione);

  // Motore 2 (Dx) fermo

  analogWrite(velocita_M2, 0); // Per fermare il motore impostare a 0 il secondo parametro

  // fermare il motore M2 (Dx)
  digitalWrite(direzione1_M2, LOW);
  digitalWrite(direzione2_M2, LOW);
  delay(tempo_rotazione);
}

Esercizio 1

Realizzare un programma che ciclicamente esegua la sequenza: avanzamento di EduRobot in avanti per 500 millisecondi, si ferma nella posizione per 500 millisecondi e successivamente torna indietro (in retromarcia) per 500 millisecondi e si ferma nella posizione per 500 millisecondi.

Esercizio 2

Realizzare un programma che faccia compiere ciclicamente a EduRobot il perimetro di un quadrato. Il tempo di percorrenza di ogni singolo lato deve essere di 500 millisecondi e la velocità di rotazione deve essere ridotta a 150 (variabile: velocita = 150).

Semplifichiamo la gestione dei motori

Per semplificare la gestione dei motori utilizziamo una specifica libreria sviluppata da yohendry e che dovrà essere prelevata dal seguente link: https://github.com/yohendry/arduino_L298N

Il file zip scaricato dovrà essere installato all’interno di Arduino (per i miei allievi questa operazione richiede le password di amministratore del computer, chiedere il supporto dell’Assistente di Laboratorio).

Per installare la libreria: Sketch > Include library > Add ZIP Library… e caricare il file ZIP precedentemente scaricato:

All’interno della libreria troverete una cartella con due esempi che potete utilizzare per comprendere il funzionamento della libreria:

Programma test n. 2

Specifiche: Utilizzando la libreria appena installata per realizzare un programma che ciclicamente esegua i seguenti passi:

  • avanti per 500 millisecondi
  • sosta di 500 millisecondi
  • indietro per 500 millisecondi
  • sosta di 500 millisecondi.
/*
  Prof. Maffucci Michele
  20.01.19

  EduRobot - Programma test n. 2
  Avanti e indietro

  Collegamenti:

  L298N -->  Arduino

  ENB  -->  Pin 10
  IN4  -->  Pin 5
  IN3  -->  Pin 4
  IN2  -->  Pin 3
  IN1  -->  Pin 2
  ENA  -->  Pin 9
  +12V -->  Vin
  GND  -->  GND
*/

#include <L298N.h>

const int ENB = 10;
const int IN4 = 5;
const int IN3 = 4;
const int IN2 = 3;
const int IN1 = 2;
const int ENA = 9;


L298N driver(ENA, IN1, IN2, IN3, IN4, ENB);

int tempo_rotazione = 500;
int velocita = 200;

void setup() {
}

void loop()
{
  driver.forward(velocita, tempo_rotazione);  // avanti per per 500 millisecondi alla velocità 200
  driver.full_stop(tempo_rotazione);          // fermata di 500 millisecondi
  driver.backward(velocita, tempo_rotazione); // indietro per per 500 millisecondi alla velocità 200
  driver.full_stop(tempo_rotazione);          // fermata di 500 millisecondi
}

Programma test n. 3

Specifiche: Utilizzando la libreria appena installata per realizzare un programma che ciclicamente esegua i seguenti passi:

  • avanti per 500 millisecondi
  • sosta di 500 millisecondi
  • rotazione a destra per 500 millisecondi
  • sosta di 500 millisecondi
  • rotazione a sinistra per 500 millisecondi
  • sosta di 500 millisecondi
  • indietro per 500 millisecondi.

Impostare la velocità dei motori a 100.

/*
  Prof. Maffucci Michele
  20.01.19

  EduRobot - Programma test n. 3
  Movimento

  Collegamenti:

  L298N -->  Arduino

  ENB  -->  Pin 10
  IN4  -->  Pin 5
  IN3  -->  Pin 4
  IN2  -->  Pin 3
  IN1  -->  Pin 2
  ENA  -->  Pin 9
  +12V -->  Vin
  GND  -->  GND
*/

#include <L298N.h>

const int ENB = 10;
const int IN4 = 5;
const int IN3 = 4;
const int IN2 = 3;
const int IN1 = 2;
const int ENA = 9;


L298N driver(ENA, IN1, IN2, IN3, IN4, ENB);

int tempo_rotazione = 500;
int velocita = 100;
void setup() {
}

void loop()
{
  driver.forward(velocita, tempo_rotazione);    // avanti per per 500 millisecondi alla velocità 200
  driver.full_stop(tempo_rotazione);            // fermata di 500 millisecondi
  driver.turn_right(velocita, tempo_rotazione); // rotazione a destra per 500 millisecondi
  driver.full_stop(tempo_rotazione);            // fermata di 500 millisecondi
  driver.turn_left(velocita, tempo_rotazione); // rotazione a sinistra per 500 millisecondi
  driver.full_stop(tempo_rotazione);            // fermata di 500 millisecondi
  driver.backward(velocita, tempo_rotazione);   // indietro per per 500 millisecondi alla velocità 200
}

Esercizio 3

Dovreste aver notato che il robot accelerando in avanti si alza bruscamente (impenna) siete in grado di realizzare un programma che faccia accelerare gradualmente in avanti il robot?

Esercizio 4

Utilizzando la libreria appena installata realizzare un programma che faccia muovere EduRobot lungo il perimetro di un quadrato.

Buon lavoro.

EduRobot – ASL (Alternanza Scuola Lavoro) – Manuale di costruzione – 1/3

Al terzo anno, presso l’istituto dove attualmente lavoro, l’ITIS G.B. Pininfarina di Moncalieri (To), gli studenti svolgono un’attività di azienda simulata e per l’occasione, visto i tempi brevi di cui si dispone ho ripreso un progetto di qualche anno fa EduRobot (trovate i riferimenti seguendo il link), un kit robotico con struttura in legno a bassissimo costo che sviluppai come parte di un modulo di automazioni che svolsi in altra scuola.

L’idea è quella di simulare un’azienda che sviluppa e produce kit robotici per la didattica per l’insegnamento del Coding per gli studenti di scuola media. Gli studenti sulla base del kit che ho prodotto, dovranno costruirlo, programmarlo, pensare a soluzioni per migliorarlo sia dal punto di vista hardware che software, realizzare la manualistica e depliant pubblicitari in lingua inglese.

Questo manuale di lavoro vuole essere la guida per i miei allievi di 3A Automazione e 3B Automazione e per tutti coloro che intendono realizzare un robot.

La struttura è costituita da un supporto in legno su cui collocare tutta l’elettronica, la struttura potrete realizzarla di qualsiasi altro materiale o forma in quanto gli elementi di base sono realizzati in 3D e si adattano a qualsiasi supporto, per recuperare il materiale precedente acquistato riutilizzerò la base di EduRobot.

Per chi desidera stampare gli elementi seguite il link alla pagina di Thingiverse dove ho reso disponibile tutti i file, troverete gli elementi che si adattano ad EduRobot e gli elementi generici che potrete usare per qualsiasi robot.

Per i miei allievi: tutti gli elementi sono stati già stampati e la breadboard è già fissata su un supporto in legno.

Nei file stl che trovate su Thingiverse ho aggiunto un il file: Supporti-Motori-Universale.stl da sostituire a Supporti-Motori-EduRobot.stl nel caso in cui voi non basate la vostra costruzione su EduRobot.

Nel prossimo futuro sostituirò la batteria di alimentazione da 9V con una batteria LiPo.

Il manuale è strutturato in 3 parti

  1. Manuale di costruzione (questa pagina)
  2. Manuale collegamenti elettrici
  3. Manuale di programmazione

Per i miei studenti del Pininfarina

  • Tutta l’attività sarà valutata.
  • Sarà fornito un kit già montato che dovrà essere condiviso tra la 3A Automazione e 3B Automazione in modo che, nel caso di dubbi, possiate usarlo come riferimento.
  • Tutti gli elementi stampati in 3D dovranno essere fissati con delle viti metalliche. Ricordo a tutti di non forzare troppo il serraggio delle viti in quanto potreste rompere gli elementi stampati in 3D.
  • Tutti gli elementi consegnati sono di proprietà del sottoscritto e poiché userò questi elementi anche in altre classi vi chiedo la massima cura nella gestione dei materiali, nel caso di problemi non esitate a contattarmi.
  • Questa manualistica di assemblaggio sarà conservata nella sezione EduRobot di questo sito.
  • Attenzione alla gestione dei motori! I cavi di collegamento sono saldati ai due poli del motore, questi sono estremamente delicati, per evitare rotture ho utilizzato una fascetta di plastica che dovrebbe evitare il distacco.
  • Nella kit fornito aggiungerò un quantitativo di dadi e viti maggiore a quello realmente necessario, saranno tutti di misura M3.
  • Non sono richiesti attrezzi aggiuntivi, all’interno del kit avete ha disposizione anche un piccolo cacciavite a stella sufficiente per la costruzione del robot, se preferite potete utilizzare anche gli strumenti disponibili in laboratorio.
  • Nel caso di rotture di qualsiasi apparato comunicare tempestivamente al docente presente in aula e poi a me in modo da poter sostituire tempestivamente l’oggetto (ma spero ciò non accadrà 😉 ).
  • Al termine di ogni lezione riporre all’interno del contenitore fornito tutti i semilavorati.
  • Ogni scatola è numerata, su di essa è indicato il numero del gruppo e la classe.
  • In ogni scatola troverete un piccolo contenitore dove riporre le minuterie.
  • Ogni robot è numerato. Il numero del robot NON coincide con il numero della scatola.
  • Non sono richieste saldature.

Procedimento

Orientamento del robot

Nelle spiegazioni si farà riferimento all’orientamento specificato nelle immagini che seguono:

Passo 1

Per questa fase avrete bisogno di:

  • breadboard
  • alloggiamento batteria di scorta
  • due dadi M3
  • due viti M3 da 12 mm
  • giravite a stella

Fissare sulla basetta di compensato con due viti da 12 mm la breadboard (già fissata su basetta di legno) e l’alloggiamento per la batteria di riserva.

Passo 2

Per questa fase avrete bisogno di:

  • caster ball
  • due dadi M3
  • due viti M3 da 10 mm
  • giravite a stella

Fissare la caster ball facendo attenzione all’orientamento, l’elemento di rinforzo obliquo deve essere orientato come riportato in figura, i dadi M3 devono entrare nella sede della struttura della caster ball, serrare il tutto con viti da 10 mm.

Passo 3

Per questa fase avrete bisogno di:

  • elementi realizzati al passo precedente
  • due supporti motori
  • quattro dadi M3
  • quattro viti M3 da 12 mm
  • giravite a stella

Fissare i motori alla basetta di compensato mantenendo la testa delle viti verso il lato inferiore del robot così come indicato nell’immagine.

Passo 4

Per questa fase avrete bisogno di:

  • elementi realizzati al passo precedente
  • due motori
  • quattro dadi M3
  • quattro viti M3 da 25 mm
  • giravite a stella

Fissare i motori ai supporti usando due viti da 25 mm. L’orientamento dei motori deve essere con i punti di saldatura dei fili verso l’interno della struttura, così come indicato nell’immagine che segue. Far passare i cavi dei motori attraverso i fori quadrati.

Passo 5

Per questa fase avrete bisogno di:

  • scheda motori L298N
  • supporto scheda motori
  • 3 dadi M3
  • 3 viti M3 da 10 mm
  • giravite a stella

Avvitare la scheda motori L298N con 3 viti da 12 mm.

Verificate che i jumper siano disposti come rappresentati nell’immagine che segue:

Passo 6

Per questa fase avrete bisogno di:

  • elementi assemblati del passo precedente
  • scheda Arduino
  • supporto compensato
  • 4 dadi M3
  • 4 viti M3 da 35 mm
  • supporto scheda Arduino
  • giravite a stella

Sul lato superiore della basetta di compensato posizionare il supporto per la scheda Arduino ed inserire le 4 viti M3 da 35 mm e su di esso inserire la scheda L298N in modo da realizzare una struttura a sagwitch.

Passo 7

Per questa fase avrete bisogno di:

  • elementi assemblati del passo precedente
  • 2 dadi M3
  • 2 viti M3 da 10 mm
  • batteria da 9V
  • jack connessione batteria
  • giravite a stella

Avvitare con due viti da 10 mm l’alloggiamento per la batteria da 9V mantenendo i due svasi del supporto batteria verso il lato sinistro come indicato nell’immagine.

Passo 8

Per questa fase avrete bisogno di:

  • elementi assemblati del passo precedente
  • 2 ruote

Inserire le ruote. Fate attenzione! Non spingete con forza. Il profilo del foro e del mozzo sono costituiti da un mozzo smussato è l’inserimento può avvenire in un solo modo.

Passo 9

Per questa fase avrete bisogno di:

  • elementi assemblati del passo precedente
  • batteria 9V di riserva

Inserire la batteria aggiuntiva nella sede al di sotto del robot. Questa batteria servirà inoltre per appesantire il robot nella parte anteriore ed evitare che in accelerazione il robot si alzi anteriormente.

Buon lavoro 🙂