Informatica

Programmazione, CoderDojo, configurazioni ecc

Elettronica

Arduino, Raspberry, stampanti 3D ecc

Fisica

Fisiclab, esperimenti, laboratori

Astronomia

Planetario, museo del cielo e della terra

Cucina

Ricette, esperimenti culinari, paciughi

Una macchina programmabile - prime prove

Eccoci al quarto post relativo al mio progetto con Arduino: una macchina programmabile.
Questi sono i link del primo, secondo e terzo post

Il telaio è pronto, la pulsantiera anche. Tutti i componenti sono montati.
Questo è il risultato finale:

Macchina programmabile finita Simone Bacciglieri
Si può vedere anche il dettaglio della posizione della batteria da 9V.
In questa foto invece si vede come il led si incastri perfettamente all'interno del buco del Lego.
Led Lego Brick

Ho fatto anche uno schema con Fritzing per far capire meglio come ho collegato il tutto. A questo però bisogna aggiungere lo schema della pulsantiera che ho inserito nel terzo post.

schema macchina programmabile Simone Bacciglieri

Questo è il programma che ho scritto:

/* Software per la macchina programmabile */
/* Simone Bacciglieri */

#include <Servo.h>

Servo servoleft;
Servo servoright;

//Array contenente tutte le istruzioni da eseguire.
//Nessuna istruzione = 0
//AVANTI = 1
//INDIETRO = 2
//DESTRA = 3
//SINISTRA = 4
int instructions[100];

int sLeft = 9;
int sRight = 8;

//Front left led
int flLed = 10;
//Front right led
int frLed = 11;
//Rear left led
int rlLed = 12;
//Rear right led
int rrLed = 13;

//Push button panel led
int bPanelLed = 7;

//Flag per sapere se sono in modalità inserimento comandi
int insertMode = 0;
//Posizione dell'ultima istruzione nell'array
int currentPosition = 0;

void setup() {
  Serial.begin(9600);

  pinMode(sLeft, OUTPUT);
  pinMode(sRight, OUTPUT);

  // Nei servo normali l'argomento del metodo write è la posizione angolare.
  // In quelli a rotazione continua invece
  // 0 vuol dire ruota avanti alla massima velocità
  // 180 vuol dire ruota indietro alla massima velocità
  // 90 vuol dire fermo
  servoleft.attach(sLeft);
  servoleft.write(90);
  servoright.attach(sRight);
  servoright.write(90);
 
  pinMode(flLed, OUTPUT);
  pinMode(frLed, OUTPUT);
  pinMode(rlLed, OUTPUT);
  pinMode(rrLed, OUTPUT);

  pinMode(bPanelLed, OUTPUT);

  //Abilito la resistenza interna di pullup sul pin A0
  pinMode(A0, INPUT_PULLUP);
  //Tutti i led spenti
  digitalWrite(flLed, LOW);
  digitalWrite(frLed, LOW);
  digitalWrite(rlLed, LOW); 
  digitalWrite(rrLed, LOW);

  digitalWrite(bPanelLed, LOW);
 
  Serial.println("Inizio");
}

void loop() {
  // Leggo il valore che mi arriva dalla pulsantiera
  int buttonsPanel = analogRead(A0);
  // Un po' di debug
  Serial.println(buttonsPanel);
  // Se il flag insertMode è a 0 eseguo immediatamente l'istruzione relativa al tasto premuto
  // Altrimenti la inserisco nell'array delle istruzioni
  switch (buttonsPanel) {
    case 15 ... 30:
      Serial.println("Bottone AVANTI premuto");
      delay(500);
      insertMode ? carSet(1) : fw();
      break;

    case 122 ... 142:
      Serial.println("Bottone INDIETRO spremuto");
      delay(500);
      insertMode ? carSet(2) : back();
      break;

    case 166 ... 175:
      Serial.println("Bottone SX spremuto");
      delay(500);
      insertMode ? carSet(4) : left();
      break;

    case 72 ... 82:
      Serial.println("Bottone DX spremuto");
      delay(500);
      insertMode ? carSet(3) : right();
      break;

    case 277 ... 284:
      Serial.println("Bottone STOP spremuto");
      delay(500);
      carStop();
      insertMode = 0;
      break;

    case 243 ... 251:
      //Hanno premuto SET quindi devo iniziare ad immagazzinare le istruzioni
      Serial.println("Bottone SET spremuto");
      delay(500);
      //Azzero l'array
      for (int i = 0; i < 100; i++) {
        instructions[i] = 0;
      }
      insertMode = 1;
      currentPosition = 0;
      break;

    case 207 ... 214:
      //Hanno premuto GO quindi devo eseguire tutte le istruzioni dell'array
      Serial.println("Bottone GO spremuto");
      delay(500);
      carGo();
      insertMode = 0;
      break;

    default:
      Serial.println("Nessun tasto spremuto");
      break;
  }
}

void ledBlink() {
  digitalWrite(bPanelLed,HIGH);
  delay(150);
  digitalWrite(bPanelLed,LOW);
  delay(150);
}

void fw() {
  Serial.println("Avanti");
  //Accendo i led anteriori e spengo quelli posteriori
  digitalWrite(flLed, HIGH);
  digitalWrite(frLed, HIGH);
  digitalWrite(rlLed, LOW);
  digitalWrite(rrLed, LOW);
  //I servo devono girare  in direzioni opposte per andare nello stesso verso
  //Sono montati in direzioni opposte
  servoleft.write(0);
  servoright.write(116);

  for(int i=0;i<8;i++) {

    ledBlink();
  }
  carStop();
}

void back() {
  Serial.println("Indietro");
 
  digitalWrite(flLed, LOW);
  digitalWrite(frLed, LOW);
  digitalWrite(rlLed, HIGH);
  digitalWrite(rrLed, HIGH);

  servoleft.write(180);
  servoright.write(60);

  for(int i=0;i<8;i++) {
    ledBlink();
  }
  carStop();
}

void left() {
  Serial.println("Sinistra");
 
  digitalWrite(flLed, HIGH);
  digitalWrite(frLed, LOW);
  digitalWrite(rlLed, HIGH);
  digitalWrite(rrLed, LOW);
  // Il servo sinistro è fermo mentre quello destro gira
  servoleft.write(90);
  servoright.write(180);

  for(int i=0;i<3;i++) {
    ledBlink();
  }
  carStop();
}

void right() {
  Serial.println("Destra");
  // Il servo sinistro gira mentre quello destro è fermo
  digitalWrite(flLed, LOW);
  digitalWrite(frLed, HIGH);
  digitalWrite(rlLed, LOW);
  digitalWrite(rrLed, HIGH);

  servoleft.write(0);
  servoright.write(90);

  for(int i=0;i<3;i++) {
    ledBlink();
  }
  carStop();
}

void carStop() {
  //Fermo la macchina e spengo tutto
  Serial.println("Ferma");
 
  digitalWrite(flLed, LOW);
  digitalWrite(frLed, LOW);
  digitalWrite(rlLed, LOW);
  digitalWrite(rrLed, LOW);

  servoleft.write(90);
  servoright.write(90);
}

void carGo() {
  Serial.println("Via");
  //Quando incontro il valore 0 vuol dire che sono finite le istruzioni
  for (int i = 0; i < 100; i++) {
   
    switch (instructions[i]) {
      case 0:
        //Fine istruzioni
        carStop();   
        break;
      case 1:
        //Avanti
        fw();
        break;
      case 2:
        //Indietro
        back();
        break;
      case 3:
        //Destra
        right();
        break;
      case 4:
        //Sinistra
        left();
        break;
    }
  }
}

void carSet(int instruction) {
  Serial.println("Set");
  // Inserisco nell'array l'istruzione relativa al pulsante premuto.
  // Se arrivo all'ultima istruzione segnalo facendo blinkare il led.
  if (currentPosition > 98) {
    Serial.println("Raggiunto il limite massimo di istruzioni");
    for(int i=0;i<14;i++) {
      ledBlink();
    }
  }
  instructions[currentPosition] = instruction;
  currentPosition++;
}



Ho iniziato a fare un po' di prove e ho notato subito un problema: i due servo motori non vanno alla stessa velocità. Ho provato a variare il parametro che passo alla funzione write ma, anche se la situazione è migliorata, non sono riuscito a farla andare perfettamente dritta.
Una volta risolto questo problema posso dire di aver raggiunto l'obiettivo che mi sono dato nel primo post e posso iniziare ad estendere il progetto: per prima cosa voglio mettere il sensore ad ultrasuoni perchè ho visto che i miei figli quando la usano la fanno sbattere da tutte le parti, quindi è bene che sappia fermarsi in tempo da sola. :)

Una macchina programmabile - la pulsantiera

Questo è il terzo post che dedico al mio progettino: costruire una macchina programmabile utilizzando Arduino e Lego.
Nel primo post ho spiegato a grandi linee cosa volevo fare, mentre nel secondo ho iniziato ad elencare i componenti e ho descritto come voglio realizzare il telaio.

Adesso è ora di parlare della pulsantiera, forse la parte più difficile di questo progetto.
Come dicevo deve avere 7 pulsanti e un led e deve utilizzare meno pin possibile.

Cercando un po' in rete ho visto che si puo' utilizzare un solo pin analogico  dell'Arduino in modalità pull-up, collegando pulsanti e resistenze in modo che diventi un partitore resistivo.

Per maggiore chiarezza ho fatto lo schema con Fritzing, un programma open source per creare schemi elettronici.
Schema pulsanti partitore resistivo progetto macchina programmabile di Simone Bacciglieri

Le resistenze sono collegate tra loro in serie e dopo ogni resitenza c'è il piedino di un pulsante: l'ultima resitenza è collegata a massa.
L'altro piedino di ogni pulsante è collegato al pin analog0 dell'Arduino configurato, come detto prima, in modalità pull-up. In questa configurazione il pin è connesso ai 5V dell'Arduino tramite una resistenza interna detta di pull-up.

Quando nessun pulsante è premuto il circuito è aperto e il pin analog0 segna i 5V a cui è attaccato; quando invece premiamo un pulsante il circuito si chiude ma prima di arrivare alla massa deve passare attraverso le resistenze successive al tasto premuto.
In questo modo abbiamo creato un partitore resistivo tra la resistenza di pull-up e tutte le altre in serie.

I pin analogici in realtà non sono analogici, ma restituiscono un valore tra 0 e 1024 a seconda della tensione in ingresso.

Quando abbiamo controllato i valori con Arduino ci siamo resi conto che non erano stabili quindi per ogni tasto abbiamo dovuto identificare un range di ingresso.
Questo è il codice utilizzato:

  int buttonsPanel = analogRead(A0);
  Serial.println(buttonsPanel);

  switch (buttonsPanel) {
    case 15 ... 30:
      Serial.println("Bottone AVANTI premuto");
      delay(500);

      break;

    case 122 ... 142:
      Serial.println("Bottone INDIETRO premuto");
      delay(500);
      break;

    case 166 ... 175:
      Serial.println("Bottone SX premuto");
      delay(500);
      break;

    case 72 ... 82:
      Serial.println("Bottone DX premuto");
      delay(500);
      break;

    case 277 ... 284:
      Serial.println("Bottone STOP premuto");
      delay(500);
      break;

    case 243 ... 251:
      Serial.println("Bottone SET premuto");
      delay(500);

      break;

    case 207 ... 214:
      Serial.println("Bottone GO premuto");
      delay(500);

      break;


Questo è il lavoro finito:

Pulsantiera partitore resistivo di Simone Bacciglieri

Il led al centro condivide solo la massa con il resto del circuito. L'altro piedino va direttamente ad un altro pin dell' Arduino e viene usato come di consueto.

Il telaio ha subito una modifica: non ha più due ruote davanti ma una sola girevole.

Macchina programmabile di Simone Bacciglieri


Per oggi è tutto, vediamo se riuscirò a farla funzionare :)

Progetto per bambini con Arduino

Sono parecchi mesi che non scrivo più nulla su questo blog, soprattutto non scrivo più nulla sulle lezioni di programmazione per bambini. Questo perchè alcune cose sono cambiate e io e Serena stiamo cercando di capire come dare seguito a questa attività.

Durante questo periodo di "pausa", se così lo possiamo chiamare, mi sto cimentando in un progetto con Arduino.
arduino uno

Nulla di nuovo, ho visto in rete che varie persone hanno già fatto la stessa cosa, però volevo provare lo stesso.



Sto facendo una macchinina
programmabile, cioè una macchinina che prende in input una sequenza di comandi e poi li esegue una volta dato il via.
Il gioco da fare con i bambini a questo punto è creare un percorso e programmare la macchinina in modo che riesca a seguirlo tutto da sola.
A loro sembra un gioco ma in realtà questo serve per dargli le prime informazioni su come creare un programma, cos'è un'istruzione e cosa succede se si eseguono istruzioni sbagliate.
Inoltre imparano a pianificare le azioni che la macchina dovrà eseguire e prevederne gli errori.

Se viene bene può essere una bella idea utilizzarla anche durante le lezioni di programmazione.

Finita la premessa passiamo ai requisiti che mi sono dato:
  • Deve essere il più possibile autocostruita. Non voglio comprare uno di quei kit completi che si trovano nei siti di elettronica.
  • Deve essere indipendente (cioè deve andare a batterie, non voglio cavi di collegamento al pc)
  • Non deve essere telecomandata: tutto risiede nella macchina e quando si avvia non deve esserci possibilità di cambiare i comandi
  • Deve andare nelle quattro direzioni: avanti, indietro, destra e sinistra
  • Deve accettare input sulle direzioni attraverso una pulsantiera
  • Deve essere espandibile. Visto che sicuramente  mi verrà voglia di aggiungerci di tutto dovrò usare i pin dell' Arduino e la breadboard con parsimonia.
  • Deve essere bella!
In questi post cercherò di documentare tutto quello che sto facendo, in modo da condividere con tutti la mia esperienza ma anche di dare la possibilità a chi ne sa più di me di dirmi cosa ho sbagliato o cosa posso migliorare.
Spero che questi ultimi commentino le mie pagine così anche gli altri potranno leggere quali sono stati i miei errori e non replicarli :)

Una macchina programmabile


Una macchina programmabile

Come dicevo in questo post ho iniziato a costruire una macchina programmabile con Arduino.
I componenti che mi servono per realizzarla sono:
  • un Arduino uno
  • due led ad alta luminosità rossi
  • due led ad alta luminosità blu
  • un led verde
  • cinque resistenze da 220 Ohm
  • sei resistenze da 2200 Ohm
  • due servomotori a rotazione continua
  • una batteria da 9V
  • una breadboard
  • sette pulsanti
  • cavi di collegamento per la breadboard
Il telaio ho pensato di costruirlo con i Lego Technics, visto che ne ho già in abbondanza.
Nella foto si può vedere la prima prova. I due servomotori sono già posizionati e hanno già le ruote fissate; sulla parte blu voglio metterci l'Arduino, sopra i servomotori metterò la breadboard e sulla parte anteriore metterò la pulsantiera.

telaio macchina programmabile creato con lego technics


I quattro led ad alta luminosità mi servono per i fari mentre quello verde mi serve per la pulsantiera. Darà un minimo di feedback durante l'immissione dei comandi.
I led dei fari si illumineranno a seconda della direzione.

La pulsantiera merita un discorso a parte: devo prevedere 4 pulsanti direzione più il pulsante per iniziare l'immissione dati (set), quello per far partire la macchina e il pulsante stop. Vorrei creare qualcosa di definitivo in modo da poterla riutilizzare anche in futuro senza ricominciare sempre tutto da capo.
In più vorrei che utilizzasse meno pin possibile, visto che voglio sette pulsanti non vorrei dover occupare sette pin dell'Arduino.

Se riesco a fare tutto vorrei aggiungere un sensore di prossimità ad ultrasuoni in modo che si fermi da sola se arriva troppo vicino ad un ostacolo.