Installare Arduino per aprire il garage

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

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

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.

 

Leave a Reply

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *