Questa è la procedura passo-passo per installare e programmare arduino in modo che possa ricevere comandi da Raspberry per l’apertura del garage o cancello automatico.
Vedendo i singoli passi puoi personalizzarli a tuo piacere.
Se hai fretta ti conviene invece seguire questa procedura che utilizza l’immagine del raspberry già configurata e ti permette di saltare alcuni passi: Aprire il garage da una pagina web.
Prerequisiti
- Avere Arduino Nano
- Avere la scheda relè
- Avere Raspberry con gli accessori
- Aver configurato il Raspberry come descritto in Installare il software per Raspberry
Installare il software Arduino su Raspberry
- Accendere il Raspberry collegandolo ad una TV o alla rete Lan
- Accedere al Raspberry (se via lan attraverso vnc)
- aprire lx-terminal
- per installare il software Arduino, digitare
sudo apt-get install arduino
- aggiungere l’utente corrente (pi) al gruppo tty in modo da poter controllare via seriale (via usb)
sudo usermod -aG tty pi
- collegare arduino ad una porta USB
Creare lo sketch per Arduino
- Installare la libreria per Arduino EgoMiniTimer
- Scompattarla nella cartella libraries di Arduino.



- Aprire il software Arduino

- Nella schermata copiare ed incollare il seguente contenuto:
#include "Timer.h"
#define LUCE_PIN 11
#define ACCENDI_LUCE 0
#define SPEGNI_LUCE 1
//solo promemoria, non utilizzati
#define APRI_BOX_PIN 13
#define CHIUDI_BOX_PIN 12
#define BASE_PIN 2 //digital pin 2
#define N_INPUT 4
#define N_OUTPUT 4
#define BASE_PIN_OUT 10
//da d2 a d5 sono input
//da d10 a d13 sono output
//#########azioni
#define DO_NOTHING 0
Timer timer;
typedef void (*DoActionFunction) (const byte pin);
DoActionFunction doActionFunction;
typedef void (*SimpleFunction) ();
const char* inputDescr0[]={"Box chiuso1", "chiuso2", "chiuso3", "chiuso4"};
const char* inputDescr1[]={"Box aperto1", "aperto2", "aperto3", "aperto4"};
void doNothing(const byte pin){
}
void doPrint0(const byte pin){
Serial.print("status: ");
Serial.println(inputDescr0[pin]);
}
void doPrint1(const byte pin){
Serial.print("status: ");
Serial.println(inputDescr1[pin]);
}
void doSpegniLuce(const byte pin){
digitalWrite(LUCE_PIN,SPEGNI_LUCE);
doPrint0(pin);
}
void doAccendiLuce(const byte pin){
digitalWrite(LUCE_PIN,ACCENDI_LUCE);
doPrint1(pin);
}
byte simulateInputs=0; //setta a 1 i bit degli input da forzare
byte simulateValues=0; //valore per i bit da simulare;
//int simulateDurations[]={-1,-1,-1,-1};
//Timer simulateTimers[4];
int simulateTimerId[N_INPUT];
void noSimulateInput(int inp){
Serial.println("no simulate "+String(inp));
bitClear(simulateInputs,inp);
timer.stop(simulateTimerId[inp]);
}
void outputHigh(int out){
Serial.println("output high to "+String(out));
digitalWrite(BASE_PIN_OUT+out,HIGH);
printOutStatus(out);
}
void outputLow(int out){
Serial.println("output low to "+String(out));
digitalWrite(BASE_PIN_OUT+out,LOW);
printOutStatus(out);
}
DoActionFunction doAction0[]={
doSpegniLuce,
doPrint0,
doPrint0,
doPrint0
};
DoActionFunction doAction1[]={
doAccendiLuce,
doPrint1,
doPrint1,
doPrint1
};
byte prevInputs;
String inputString = "";
void setup() {
//start serial connection
Serial.begin(9600);
//configure pin2 as an input and enable the internal pull-up resistor
byte base=BASE_PIN;
for (byte pin = 0; pin < N_INPUT; pin++) {
pinMode(base+pin, INPUT_PULLUP);
}
base=BASE_PIN_OUT;
for (byte pin = 0; pin < N_OUTPUT; pin++) {
pinMode(base+pin, OUTPUT);
digitalWrite(base+pin,HIGH); //condizione di riposo per i relè
}
// reserve 100 bytes for the inputString:
inputString.reserve(300);
}
void loop() {
byte inputs=0;
byte base=BASE_PIN;
for (byte pin = 0; pin < N_INPUT; pin++) {
byte sensorVal = digitalRead(base+pin);
if(bitRead(simulateInputs,pin)==HIGH){
sensorVal=bitRead(simulateValues,pin);
};
if (sensorVal == HIGH) {
bitSet(inputs,pin);
} else {
bitClear(inputs,pin);
}
}
if(prevInputs!=inputs){
Serial.println(inputs,BIN);
checkInputs(inputs,prevInputs);
prevInputs=inputs;
}
timer.update();
}
void checkInputs(byte in,byte prevIn){
for (byte pin = 0; pin < N_INPUT; pin++) {
if (bitRead(in,pin) == bitRead(prevIn,pin)) {//si attiva sul fronte alto o basso dell'impulso
} else {
if (bitRead(in,pin) == LOW ){
doAction0[pin](pin);
} else{
doAction1[pin](pin);
}
}
}
}
void printInputs(){
byte in=prevInputs;
for (byte pin = 0; pin < N_INPUT; pin++) {
Serial.print("status: ");
if (bitRead(in,pin) == LOW ){
Serial.println(inputDescr0[pin]);
} else{
Serial.println(inputDescr1[pin]);
}
}
}
void printOutStatus(byte pin){
Serial.print("status: out");
Serial.print(pin);
if (digitalRead(pin+BASE_PIN_OUT) == LOW ){
Serial.println(" low");
} else{
Serial.println(" high");
}
}
void printOutputs(){
byte in=prevInputs;
for (byte pin = 0; pin < N_OUTPUT; pin++) {
printOutStatus(pin);
}
}
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
Serial.println(inputString);
if (inputString.startsWith("status")) {
Serial.println("status: reply to "+ inputString.substring(7));
printInputs();
printOutputs();
Serial.println("status: end");
}
//set output :3=1 5 imposta l'uscita 3 a 1 per 5 secondi
if (inputString.startsWith("set output")) {
String resto=tail(inputString,':');
String outs=head(resto,'=');
String vals=tail(resto,'=');
String durs=tail(vals,' ');
durs.trim();
if(durs.length()>0){
vals=head(vals,' ');
}
int out=outs.toInt();
String risposta="Set output "+outs;
int val=vals.toInt();
if(val>0){
outputHigh(out);
risposta+="=1";
if(durs.length()>0){
int dur=durs.toInt();
timer.after(dur*1000,outputLow,out);
risposta+=" for "+String(dur)+" sec";
};
}else{
outputLow(out);
risposta+="=0";
if(durs.length()>0){
int dur=durs.toInt();
timer.after(dur*1000,outputHigh,out);
risposta+=" for "+String(dur)+" sec";
};
};
Serial.println(risposta);
}
inputString="";
}
}
}
String head(String s,char separator){
int sepIndex = s.indexOf(separator);
if(sepIndex<0){
return s;
}
String firstValue = s.substring(0, sepIndex);
return firstValue;
}
String tail(String s,char separator){
int sepIndex = s.indexOf(separator);
if(sepIndex<0){
return "";
}
String value = s.substring(sepIndex+1);
return value;
}
- Ecco il risultato

- Salvare con nome egodomo_garage

- Scegliere Strumenti/Scheda
- Scegliere Arduino Nano w/ATmega328

- Scegliere la seriale (USB)
-

- Scegliere il tipo di programmatore Arduino as ISP

- Scegliere Sketch/Carica.

- Se il carimento è avvenuto senza errori, provare a vedere se si comunica con Arduino.
- Scegliere monitor seriale

- Digitare Status nel monitor seriale, controllando che sia aggiunto un NL a fine riga
-

Se arduino risponde con lo stato del garage allora il tutto funziona.
A questo punto siamo pronti per collegarci la scheda relè e da questa la luce del garage e i pulsanti di apertura e chiusura.
Comandi utili per fissare il nome della seriale arduino
Provare uno dei seguenti comandi, quello che restituisce delle risposte che non siano
device node not found
Questi i comandi:
udevadm info --name=/dev/ttyACM0 --attribute-walk|less udevadm info --name=/dev/ttyACM1 --attribute-walk|less udevadm info --name=/dev/ttyUSB0 --attribute-walk|less udevadm info --name=/dev/ttyUSB1 --attribute-walk|less
Scorrere il risultato e cercare la stringa “ATTRS{idVendor}” che può valere
ATTRS{idVendor}=="2a03"
oppure
ATTRS{idVendor}=="1a86"
premere q per uscire dalla modalità di scorrimento del risultato (less).
Creare il file di regole per udev per assegnare sempre lo stesso nome di device ad arduino, digitando:
sudo nano /etc/udev/rules.d/99-usb-serial.rules
Usare una o l’altra riga a seconda del risultato sopra riscontrato:
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2a03", ATTRS{serial}=="8543833303635150A0C1", SYMLINK+="arduino"
oppure (per Arduino Nano compatibile)
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="arduino"
Premere CTRL+X e premere Y per uscire e salvare.