10 Numerazione capitolo

10 - ZOOTROPIO

CREA IMMAGINI IN MOVIMENTO CON ARDUINO COLLEGANDO UN MOTORE A UN PONTE H E AD ALCUNE IMMAGINI FISSE

Scopri: i ponti H

Tempo: 30 MINUTI Livello: ■ ■ ■ □ □ Basato sui progetti: 1, 2, 3, 4, 9

Prima ancora di internet, della televisione e del cinema, le immagini in movimento erano state create con uno strumento chiamato zootropio. Lo zootropio crea l’illusione del movimento a partire da un gruppo di immagini fisse che si distinguono l’una dalle altre per poche differenze. Normalmente è un cilindro con delle fessure ai lati. Quando il cilindro gira e guardi attraverso le fessure, i tuoi occhi percepiscono le immagini fisse come animate. Le fessure aiutano a evitare che le immagini siano sfocate e la velocità con cui appaiono le immagini spiega perché sembrano muoversi. Originariamente, era fatto a mano o con un meccanismo a manovella.

Ingredienti

INGREDIENTI

  • Potenziometro

  • Ponte H (L293D)

  • 2 Resistenze da 10 Kilo Ohm

  • 2 Pulsanti

  • Motore

  • Connettore per batteria 9V

In questo progetto, costruirai il tuo zootropio che anima una pianta carnivora. Creerai il movimento con un motore. Per rendere il sistema ancora più avanzato, aggiungerai un interruttore che consente di controllare la direzione, un altro per spegnerlo e accenderlo e un potenziometro per il controllo della velocità.

Nel progetto della girandola motorizzata avevi un motore da girare in una sola direzione. Se si dovesse invertire l’alimentazione e la massa del motore, il motore girerebbe nella direzione opposta. Non è molto pratico farlo ogni volta che si desidera far girare qualcosa in una direzione diversa, quindi dovrai utilizzare un componente chiamato ponte H per invertire la polarità del motore.

Ponte H

I ponti H sono componenti conosciuti come circuiti integrati (IC). I circuiti integrati sono componenti che contengono circuiti complessi in un contenitore molto piccolo. Questi possono contribuire a semplificare i circuiti più complessi inserendoli in un componente facilmente sostituibile. Per esempio, il ponte H che stai utilizzando in questo progetto contiene un certo numero di transistor. Per costruire il circuito contenuto all’interno del ponte H avresti bisogno di un’altra breadboard.

Ponte H
Puoi accedere al circuito contenuto nel circuito integrato attraverso i piedini che escono dai lati. Circuiti integrati diversi hanno un diverso numero di piedini e non tutti sono utilizzati in ogni circuito. A volte è conveniente riferirsi ai piedini per numero piuttosto che con la funzione. Guardando un circuito integrato, la parte con la tacca è la parte in alto. Puoi identificare i numeri dei piedini contando dall’alto a sinistra in senso antiorario come in Fig. 1.

COSTRUISCI IL CIRCUITO

Schema del circuito e montaggio

  1. Collega alimentazione e massa da un lato della breadboard ad Arduino.

  2. Aggiungi 2 pulsanti alla breadboard collegando un lato di ciascuno all’alimentazione. Aggiungi una resistenza pull-down da 10 kilo ohm in serie con la massa sul piedino di uscita di entrambi gli interruttori. L’interruttore sul piedino 4 controlla la direzione, l’interruttore sul piedino 5 accende e spegne il motore.

  3. Collega il potenziometro alla breadboard. Collega 5V da un lato e la massa dall’altro. Collega il piedino centrale all’input analogico 0 sull’Arduino. Questo serve per controllare la velocità del motore.

  4. Metti il ponte H sulla breadboard in modo che sia al centro (vedi la Fig. 2 per il dettaglio della posizione). Collega il piedino 1 del ponte H al piedino digitale 9 di Arduino. Questo è il piedino di abilitazione sul ponte H. Quando riceve 5V accende il motore, quando riceve 0V spegne il motore. Usa questo piedino per la modulazione di larghezza di impulso del ponte H e regolare la velocità del motore.

  5. Collega il piedino 2 del ponte H al piedino digitale 3 di Arduino. Collega il piedino 7 al piedino digitale 2. Questi piedini servono per comunicare con il ponte H, comunicandogli in quale direzione girare. Se il piedino 3 è LOW e il piedino 2 è HIGH, il motore gira in una direzione. Se il piedino 2 è LOW e il piedino 3 è HIGH, il motore gira nella direzione opposta. Se entrambi i piedini sono HIGH o LOW nello stesso tempo, il motore si ferma.

  6. Il ponte H si alimenta dal piedino 16 (vedi Fig. 1); collegalo a 5V. I piedini 4 e 5 vanno entrambi a massa.

  7. Collega il motore ai piedini 3 e 6 del ponte H. Questi due piedini si accendono o si spengono a seconda dei segnali che mandi ai piedini 2 e 7.

  8. Inserisci il connettore della batteria (senza la batteria collegata!) alla massa sulla breadboard. Collega la massa da Arduino alla massa della batteria. Collega il piedino 8 del ponte H all’alimentazione della batteria. Questo è il piedino dal quale il ponte H alimenta il motore. Assicurati di non avere collegate tra loro le linee di alimentazione 9V e 5V. Devono essere separate, solo le masse devono essere collegate tra loro.

Schema elettrico
Fig.3: schema elettrico.

IL CODICE

Crea le costanti

Crea le costanti per i piedini di ingresso e uscita.

const int controlPin1 = 2;
const int controlPin2 = 3;
const int enablePin = 9;
const int directionSwitchPin = 4;
const int onOffSwitchStateSwitchPin = 5;
const int potPin = A0;

Crea le variabili per ricordare lo stato del programma

Usa le variabili per memorizzare i valori degli ingressi. Potrai fare la rilevazione del cambio di stato per entrambi gli interruttori, confrontando lo stato da un loop all’altro, come nel progetto della clessidra. Oltre a memorizzare lo stato attuale, è necessario registrare il precedente stato di ogni interruttore.

int onOffSwitchState = 0;
int previousOnOffSwitchState = 0;
int directionSwitchState = 0;
int previousDirectionSwitchState = 0;

Crea le variabili per il controllo del motore

motorDirection tiene traccia della direzione in cui gira il motore e motorPower tiene traccia se il motore sta girando oppure no.

int motorEnabled = 0;
int motorSpeed = 0;
int motorDirection = 1;

Dichiara i piedini digitali come input e output

Nel setup(), imposta la direzione di ogni piedino di ingresso e uscita.

void setup(){
  pinMode(directionSwitchPin, INPUT);
  pinMode(onOffSwitchStateSwitchPin, INPUT);
  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);
}

Spegni il motore

Imposta il piedino di abilitazione a LOW per iniziare, in modo che il motore non giri subito.

  digitalWrite(enablePin, LOW);
}

Leggi il sensore

Nel tuo loop(), leggi lo stato dell’interruttore acceso/spento e immagazzinalo nella variabile onOffSwitchState.

void loop(){
  onOffSwitchState =
    digitalRead(onOffSwitchStateSwitchPin);
  delay(1);
  directionSwitchState =
    digitalRead(directionSwitchPin);
  motorSpeed = analogRead(potPin)/4;

Controlla se il sensore acceso/spento è cambiato

Se c’è una differenza tra lo stato attuale e precedente dell’interruttore e l’interruttore è attualmente HIGH, imposta la variabile motorPower a 1. Se è LOW, imposta la variabile a 0. Leggi i valori del pulsante di direzione e del potenziometro. Conserva i valori nelle loro rispettive variabili.

  if(onOffSwitchState != previousOnOffSwitchState){
    if(onOffSwitchState == HIGH){
      motorEnabled = !motorEnabled;
    }
  }

Controlla se la direzione è cambiata

Controlla se il pulsante di direzione è in una posizione differente rispetto a prima. Se è diversa, cambia la variabile di direzione del motore. Ci sono solo 2 modi in cui il motore può girare, alterna così la variabile tra i due stati. Per raggiungere questo obiettivo utilizza l’operatore di inversione in questo modo: motorDirection = !motorDirection.

  if (directionSwitchState !=
    previousDirectionSwitchState) {
    if (directionSwitchState == HIGH) {
      motorDirection = !motorDirection;
    }
  }

Cambia i piedini per far girare il motore nella giusta direzione

La variabile motorDirection determina in quale direzione il motore sta girando. Per determinare la direzione, imposta i piedini di controllo, uno HIGH e l’altro LOW. Quando motorDirection cambia, inverte gli stati dei piedini di controllo.

Se il pulsante di direzione viene premuto, gira il motore nella direzione opposta invertendo lo stato del controlPin.

  if (motorDirection == 1) {
    digitalWrite(controlPin1, HIGH);
    digitalWrite(controlPin2, LOW);
  }
  else {
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, HIGH);
  }

Modula il motore se è attivo

Se la variabile motorEnabled è 1, imposta la velocità del motore usando la funzione analogWrite() per modulare a larghezza di impulso il piedino. Se motorEnabled è 0, spegni il motore impostando il valore analogWrite a 0.

  if (motorEnabled == 1) {
    analogWrite(enablePin, motorSpeed);
  }
  else {
    analogWrite(enablePin, 0);
  }

Salva lo stato attuale per il prossimo loop()

Prima di uscire dal loop(), salva lo stato attuale degli interruttori come stato precedente per la prossima parte del programma.

  previousDirectionSwitchState =
    directionSwitchState;
  previousOnOffSwitchState = onOffSwitchState;
}

USALO

Collega Arduino al computer. Collega la batteria al connettore. Quando premi l’interruttore acceso/spento, il motore dovrebbe iniziare a girare. Se giri il potenziometro, dovrebbe accelerare e rallentare. Premendo il tasto acceso/spento un’altra volta si ferma il motore. Prova a premere il tasto di direzione e verifica che il motore gira in entrambe le direzioni. Inoltre, se ruoti la manopola del potenziometro dovresti vedere la velocità del motore aumentare o diminuire a seconda del valore che sta inviando.

Dopo aver verificato che il circuito funziona come previsto, scollega la batteria e il cavo USB dal circuito.

Forbici e colla

Per costruire il tuo zootropio, prendi la girandola che hai utilizzato nel progetto 09 e il ritaglio con le fessure verticali che è incluso nel kit. Una volta che il CD è saldamente collegato all’albero motore, collega tutto. Tieni il progetto in alto, in modo da poter guardare attraverso le fessure (ma assicurati che il CD sia fissato ma non troppo vicino al motore). Dovresti vedere la sequenza di immagini fisse «in movimento»! Se lo zootropio sta andando troppo velocemente o troppo lentamente, ruota la manopola del potenziometro per regolare la velocità dell’animazione.

Prova a premere l’interruttore che cambia la direzione per vedere come appare l’animazione riprodotta al contrario. Lo zootropio e le immagini fornite nel kit sono solo il punto di partenza: prova a sperimentare con le tue animazioni, utilizzando il ritaglio come riferimento.

Inizia con una immagine semplice. Individua un punto fisso in essa, e fai piccoli cambiamenti in ogni frame. Cerca gradualmente di tornare all’immagine originale in modo che l’animazione prosegua in un ciclo continuo.
Trovi il modello da ritagliare nel capitolo PAPERCRAFT, in fondo al testo.

Istruzioni di assemblaggio zootropio 1

Istruzioni di assemblaggio zootropio 2

1. Fissa il CD sulla base di legno. Aggiungi un po” di colla per assicurarti che non si stacchi quando si avvia il motore.
2. Usa le linguette per chiudere il cartone, formando un cerchio.
3. Inserisci le quattro linguette nella base dello zootropio.
4. Inserisci la striscia di carta con le immagini nello zootropio.

Lente

Gli zootropi funzionano grazie a un fenomeno chiamato «persistenza della visione» (in inglese abbreviato con l’acronimo POV): l’illusione del movimento che si crea quando i nostri occhi osservano le immagini fisse, con minime variazioni in rapida successione. Se ricerchi online «POV Display», trovi molti progetti che utilizzano questo effetto, molti dei quali con i LED e con Arduino.

Cervello

Fai una base per sostenere il motore. Una scatola di cartone di piccole dimensioni con un foro potrebbe funzionare come base, lasciando le mani libere di giocare con gli interruttori e le manopole. In questo modo sarà più facile mostrare il tuo lavoro a tutti.

Con un po” di lavoro, puoi fare in modo che il tuo zootropio funzioni anche in situazioni di scarsa luminosità. Collega un LED e una resistenza a uno dei piedini di uscita digitali liberi. Aggiungi anche un secondo potenziometro e collegalo a un ingresso analogico. Metti la luce in modo che illumini le immagini. Utilizzando l’ingresso analogico per misurare il tempo dei lampeggi del LED, prova e riprova in modo che la spia lampeggi quando la fessura è davanti ai tuoi occhi. Questo potrebbe richiedere un po” di lavoro con le manopole, ma l’effetto che ne risulta è davvero spettacolare!

Pianta carnivora

CODICE COMPLETO

/*
  Arduino Starter Kit example
  Project 10 - Zoetrope

  This sketch is written to accompany Project 10 in the Arduino Starter Kit

  Parts required:
  - two 10 kilohm resistors
  - two momentary pushbuttons
  - one 10 kilohm potentiometer
  - motor
  - 9V battery
  - H-Bridge

  created 13 Sep 2012
  by Scott Fitzgerald
  Thanks to Federico Vanzati for improvements

  https://store.arduino.cc/genuino-starter-kit

  This example code is part of the public domain.
*/

const int controlPin1 = 2;                // connected to pin 7 on the H-bridge
const int controlPin2 = 3;                // connected to pin 2 on the H-bridge
const int enablePin = 9;                  // connected to pin 1 on the H-bridge
const int directionSwitchPin = 4;         // connected to the switch for direction
const int onOffSwitchStateSwitchPin = 5;  // connected to the switch for turning the motor on and off
const int potPin = A0;                    // connected to the potentiometer's output

// create some variables to hold values from your inputs
int onOffSwitchState = 0;              // current state of the on/off switch
int previousOnOffSwitchState = 0;      // previous position of the on/off switch
int directionSwitchState = 0;          // current state of the direction switch
int previousDirectionSwitchState = 0;  // previous state of the direction switch

int motorEnabled = 0;    // Turns the motor on/off
int motorSpeed = 0;      // speed of the motor
int motorDirection = 1;  // current direction of the motor

void setup() {
  // initialize the inputs and outputs
  pinMode(directionSwitchPin, INPUT);
  pinMode(onOffSwitchStateSwitchPin, INPUT);
  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);

  // pull the enable pin LOW to start
  digitalWrite(enablePin, LOW);
}

void loop() {
  // read the value of the on/off switch
  onOffSwitchState = digitalRead(onOffSwitchStateSwitchPin);
  delay(1);

  // read the value of the direction switch
  directionSwitchState = digitalRead(directionSwitchPin);

  // read the value of the pot and divide by 4 to get a value that can be
  // used for PWM
  motorSpeed = analogRead(potPin) / 4;

  // if the on/off button changed state since the last loop()
  if (onOffSwitchState != previousOnOffSwitchState) {
    // change the value of motorEnabled if pressed
    if (onOffSwitchState == HIGH) {
      motorEnabled = !motorEnabled;
    }
  }

  // if the direction button changed state since the last loop()
  if (directionSwitchState != previousDirectionSwitchState) {
    // change the value of motorDirection if pressed
    if (directionSwitchState == HIGH) {
      motorDirection = !motorDirection;
    }
  }

  // change the direction the motor spins by talking to the control pins
  // on the H-Bridge
  if (motorDirection == 1) {
    digitalWrite(controlPin1, HIGH);
    digitalWrite(controlPin2, LOW);
  } else {
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, HIGH);
  }

  // if the motor is supposed to be on
  if (motorEnabled == 1) {
    // PWM the enable pin to vary the speed
    analogWrite(enablePin, motorSpeed);
  } else {  // if the motor is not supposed to be on
    //turn the motor off
    analogWrite(enablePin, 0);
  }
  // save the current on/off switch state as the previous
  previousDirectionSwitchState = directionSwitchState;
  // save the current switch state as the previous
  previousOnOffSwitchState = onOffSwitchState;
}