Archivi categoria: arduino

Errori comuni nell’uso di Arduino – chiamata di funzione senza parentesi

Tra gli errori comuni segnalo quello che viene commesso quando si richiama una funzione senza l’uso delle parentesi, l’errore è più frequente quanto la funzione non accetta parametri. Le parentesi vanno sempre inserite.

Versione non corretta

int LED = 8;

void setup()
{
  pinMode(LED, OUTPUT);
}

void lampeggia()
{
  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
  delay(500);
}

void loop()
{
  lampeggia; // errore nessuna parentesi
}

Versione corretta

int LED = 8;

void setup()
{
  pinMode(LED, OUTPUT);
}

void lampeggia()
{
  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
  delay(500);
}

void loop()
{
  lampeggia(); // la chiamata di funzione vuole le parentesi
}

Le parentesi devono quindi essere presenti anche se la funzione non ha parametri.

Buon lavoro 🙂

Cover IOT2020/2040 per Arduino Motor Shield V3

L’inserimento di shield Arduino all’interno del Siemens SIMATIC IOT2040 necessita in alcuni casi dell’asportazione della copertura sinistra del contenitore per consentire un’agevole passaggio dei cavi, a tal fine ho realizzato un coperchio che si adatta alla scheda Arduino Motor Shield V3 che può essere stampato in 3D. Condivido i file grafici per la stampa in modo che sia possibile, per chi lo desidera, riprodurlo, modificarlo o migliorarlo.
Spero che questo lavoro sia utile anche ad altri.

Buon Making a tutti 🙂

Errori comuni nell’uso di Arduino – fare più azioni nell’if senza l’uso delle parentesi graffe

Continua la segnalazione degli errori che spesso vengono commessi durante le prime attività di programmazione con Arduino.
La sequenza di istruzioni da eseguire se risulta vera la condizione dell’istruzione if  (il corpo della if) deve essere racchiusa tra parentesi graffe. L’errore è immaginare che l’indentazione sia sufficiente per indicarne l’appartenenza al corpo della if, modalità valida in altri linguaggi di programmazione come in Python, ma non in C:

Uso non corretto

if (temperatura > 25)
  digitalWrite (normaleTemp, LOW);
  digitalWrite (allarmeTemp, HIGH);

Uso corretto

if (temperatura > 25)
{
  digitalWrite (normaleTemp, LOW);
  digitalWrite (allarmeTemp, HIGH);
} // fine del controllo temperatura > 25

Buon lavoro 🙂

Errori comuni nell’uso di Arduino – uso non corretto della digitalWrite

Errore: considerare la “,” come separatore di istruzioni e non come separatore di valori. In C una scrittura del tipo: (a, b, c) è una sequenza di espressioni separate da virgola che valuta l’ultima espressione c, mentre {a; b; c;} è una sequenza di istruzioni che non valuta nulla.
La virgola si inserisce solamente tra due espressioni a differenza del punto e virgola che si inserisce alla fine di un’istruzione (ma non di un’istruzione di blocco come: if, for, while, do while).

Esempio non corretto

digitalWrite ((5, 6, 7), HIGH);

Esempio corretto

digitalWrite (5, HIGH);
digitalWrite (6, HIGH);
digitalWrite (7, HIGH);

O ancora meglio usando un ciclo for:

for (byte i = 5; i<= 7; i++)
  digitalWrite(i, HIGH);

Domanda che in genere faccio ai ragazzi:
“perché ho dichiarato i come byte e non come int?”

La risposta la trovate in: Appunti di programmazione su Arduino: tipi di dati in cui viene evidenziato che la dimensione del tipo byte è di 8 bit (1 byte) e rappresenta interi (senza decimali) ed hanno un range da 0 a 255, mentre gli int sono dei tipi di dato usati per memorizzare numeri senza decimali e memorizzano valori a 16 bit (2 byte) nel range da 32.767 a -32.768, quindi usando il tipo byte occupiamo meno spazio in memoria.

Buon Coding a tutti 🙂

Disegnare caratteri personalizzati con Arduino per un LCD 16×2

Durante le attività di sperimentazione capita spesso la necessità di utilizzare caratteri speciali o icone che non fanno parte del set di caratteri ASCII standard (https://www.asciitable.com) visualizzatili su un display 16×2. Ovviamente un display LCD 16×2 non permette risoluzioni elevate, ma la qualità che si riesce ad ottenere è più che accettabile.

Tutti i display LCD basati sul controller Hitachi HD44780 hanno due tipi di memorie in cui vengono memorizzati i caratteri: CGROM e CGRAM (Character Generator ROM & RAM). La memoria CGROM non è volatile e non può essere modificata mentre la memoria CGRAM è volatile e può essere modificata in qualsiasi momento.

CGROM è usato per memorizzare tutti i caratteri permanenti che possono essere visualizzati usando il loro codice ASCII. Ad esempio, se scriviamo 0x4D, sul display viene visualizzato il carattere “M”. CGRAM è un’altra memoria che può essere utilizzata per la memorizzazione di caratteri definiti dall’utente.

Questa RAM è limitata a 64 byte, cioè implica che per LCD a 5 × 8 pixel come LCD 16×2 Hitachi HD44780, nel CGRAM possono essere memorizzati fino a 8 caratteri definiti dall’utente.

Un carattere sul display viene realizzato utilizzando una matrice di pixel 5 × 8, quindi per definire un nostro carattere dovremo lavorare in quest’area.

La definizione del carattere personale avviene utilizzando la funzione createChar() della libreria LiquidCrystal.

Prima di utilizzare la libreria createChar() è necessario impostare un array di 8 byte ed ognuno di essi definisce una riga della matrice costituita dalla lettera b che definisce il tipo del dato (byte) e la serie di 1 e 0 definiscono i pixel attivi o disattivi: nell’array i bit a 1 indicano i pixel attivi, mentre gli 0 indicano i pixel disattivi.

Nell’esempio che segue viene utilizzato un display 16×2 i2c

Per quanto riguarda la libreria LiquidCrystal_I2C vi rimando alla lezione:
Utilizzo dell’LCD 16×2 Hitachi HD44780 1602 con modulo I2C PCF8574T

Nel caso abbiate necessità di sviluppare in modo più semplice ed agevole i vostri caratteri personalizzati potete utilizzare una soluzione grafica che immediatamente vi permettessi impostare l’array di byte, fate riferimento a questi due link:

da cui ho realizzato velocemente le icone, il codice corrispondenti è poi stato inserito all’interno dello sketch come si può evincere dallo sketch che segue:

/* 
 *  Prof. Michele Maffucci
 *  Crezione di caratteri personali
 *  Utilizzo di un display LCD 16×2 Hitachi HD44780 1602
 *  con modulo i2C PCF8574T
 *  Data: 17.01.2020 - v01
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// inizializzazione della libreria in cui è descritta la modalità di utilizzo dei pin
LiquidCrystal_I2C lcd(0x27, 16, 2); // impostazione dell'indirizzo dell'LCD 0x27 di 16 caratteri e 2 linee

// caratteri personalizzati

byte lucchettoChiuso[8] = {
  0b01110,
  0b10001,
  0b10001,
  0b10001,
  0b11111,
  0b11011,
  0b11011,
  0b11111
};

byte lucchettoAperto[8] = {
  0b01110,
  0b10000,
  0b10000,
  0b10000,
  0b11111,
  0b11011,
  0b11011,
  0b11111
};

byte Altoparlante[8] = {
  0b00001,
  0b00011,
  0b01111,
  0b01111,
  0b01111,
  0b00011,
  0b00001,
  0b00000
};

byte batteriaMezza[8] = {
  0b01110,
  0b11011,
  0b10001,
  0b10001,
  0b10001,
  0b11111,
  0b11111,
  0b11111
};

byte alieno[8] = {
  0b10001,
  0b01010,
  0b11111,
  0b10101,
  0b11111,
  0b11111,
  0b01010,
  0b11011
};


byte pacmanBoccaChiusa[8] = {
  0b01110,
  0b11101,
  0b11111,
  0b11111,
  0b11000,
  0b11111,
  0b11111,
  0b01110
};

byte pacmanBoccaAperta[8] = {
  0b01110,
  0b11101,
  0b11111,
  0b11100,
  0b11000,
  0b11000,
  0b11111,
  0b01110
};

byte fantasmino[8] = {
  0b01110,
  0b11111,
  0b10101,
  0b11111,
  0b11111,
  0b11111,
  0b11111,
  0b10101
};

void setup()
{
  lcd.begin();      // inizializzazione dell'LCD
  lcd.backlight();  // attivazione della retroilluminazione

  // creazione nuovi caratteri
  lcd.createChar(0, lucchettoChiuso);
  lcd.createChar(1, lucchettoAperto);
  lcd.createChar(2, Altoparlante);
  lcd.createChar(3, batteriaMezza);
  lcd.createChar(4, alieno);
  lcd.createChar(5, pacmanBoccaChiusa);
  lcd.createChar(6, pacmanBoccaAperta);
  lcd.createChar(7, fantasmino);
  
  // Cancella il display
  lcd.clear();

  // Stampa la stringa
  lcd.print("maffucci.it");

}

void loop()
{
  lcd.setCursor(0, 1);
  lcd.write(byte(0));

  lcd.setCursor(2, 1);
  lcd.write(byte(1));

  lcd.setCursor(4, 1);
  lcd.write(byte(2));

  lcd.setCursor(6, 1);
  lcd.write(byte(3));

  lcd.setCursor(8, 1);
  lcd.write(byte(4));

  lcd.setCursor(10, 1);
  lcd.write(byte(5));

  lcd.setCursor(12, 1);
  lcd.write(byte(6));

  lcd.setCursor(14, 1);
  lcd.write(byte(7));
  
}

Dopo aver incluso la libreria, è necessario inizializzare l’array che definisce il carattere personalizzato definito da 8 byte.

...
byte alieno[8] = {
  0b10001,
  0b01010,
  0b11111,
  0b10101,
  0b11111,
  0b11111,
  0b01010,
  0b11011
};
...

Nel setup() bisogna inizializzare il carattere personalizzato mediante la funzione createChar(), che accetta due parametri, il primo, compreso tra  0 e 7 è utilizzato come indirizzo ad uno degli 8 caratteri creati personalizzati, il secondo parametro definisce il nome dell’array di byte che definisce il carattere personalizzato.

  // creazione nuovi caratteri
  lcd.createChar(0, lucchettoChiuso);
  lcd.createChar(1, lucchettoAperto);
  lcd.createChar(2, Altoparlante);
  lcd.createChar(3, batteriaMezza);
  lcd.createChar(4, alieno);
  lcd.createChar(5, pacmanBoccaChiusa);
  lcd.createChar(6, pacmanBoccaAperta);
  lcd.createChar(7, fantasmino);

Successivamente nel loop, per la visualizzazione del carattere personalizzato viene utilizzata la funzione write() che ha come parametro il numero (l’indirizzo) assegnato al carattere.

...
void loop()
{
  lcd.setCursor(0, 1);
  lcd.write(byte(0));

  lcd.setCursor(2, 1);
  lcd.write(byte(1));

  lcd.setCursor(4, 1);
  lcd.write(byte(2));

  lcd.setCursor(6, 1);
  lcd.write(byte(3));

  lcd.setCursor(8, 1);
  lcd.write(byte(4));

  lcd.setCursor(10, 1);
  lcd.write(byte(5));

  lcd.setCursor(12, 1);
  lcd.write(byte(6));

  lcd.setCursor(14, 1);
  lcd.write(byte(7));
}
...

Esercizi per i miei studenti

Esercizio 1

Realizzare uno sketch che mostra un omino che cammina da sinistra verso destra e ritorno, in modo continuo. Il movimento deve essere accompagnato dall’emissione di due note che mettono in evidenza il passo.

Esercizio 2

Realizzare un Pac Man che partendo dalla riga 0 colonna 0 mangi una serie di puntini , scende alla riga 1 colonna 0 e prosegue fino alla riga 1 colonna 15 dove si trova un fantasma che deve essere mangiato. Predisporre un buzzer che emette due tipi di suoni, uno che identifica quando Pac Man mangia un puntino ed uno quando Pac Man mangia il fantasma. Quando il fantasma viene mangiato il display fa un 3 blink e l’azione comincia nuovamente con il Pac Man che si posizione in riga 0 colonna 0.

Esercizio 3

Realizzare un sistema che rilevi il livello di carica di batterie da 1,5V.
Utilizzare 7 icone che definiscono livelli diversi di carica della batteria e a fianco di ogni icona deve anche apparire in modo numerico il valore di tensione misurato.

Esercizio 4

Realizzare uno sketch che valuta in percentuale la quantità di luce in una stanza e la mostra su display mediante numero in percentuale e una barra di livello realizzata con caratteri personalizzati che può aumentare o diminuire in funzione della quantità di luce che colpisce l’LDR.
Mediante la pressione di un pulsante viene attivata la calibrazione del sistema, questa fase dura 5 secondi in cui viene misurate il valore minimo di luce (comprendo con mano il sensore) e valore massimo della luce (togliendo la mano dal sensore). La fase di calibrazione deve essere evidenziato dalla scrittura su display del messaggio: “calibrazione” e icone animate che dovete inventare.