Domotica pulsanti

Salve,

Sto testando ormai da due giorni un piccolo impianto domotico con dei relè controllabili da seriale e con dei pulsanti. Tutto sembra funzionare, l'unica cosa è che a volte mi trovo le luci che si accendono da sole. Il codice dovrebbe essere corretto, quindi ora non ho proprio idea di cosa può essere. I cavi utilizzati per i pulsanti sono schermati e per ogni pulsante ho collegato una resistenza da 10Kohm sul GND. Se avete bisogno di qualche altra informazione chiedete pure. Spero in un vostro aiuto!

Nel 90% dei casi è un problema di disturbi di linea, e/o i relè stessi che sono causa di disturbi sul circuito digitale.

Rivedi l'alimentazione dell'apparato, evitando alimentatorini da "telefonino".

Perché io l'arduino lo alimento da usb dal raspberry. Quindi dovrei alimentare separatamente i relè con un altro alimentatore?

Beh, direi proprio di si. I relè, di solito, sono abbastanza esosi come corrente necessaria al loro corretto funzionamento. Poi bisogna anche vedere che relè hai messo.

Tipo questi:

O questi! :smiley:

Ho utilizzato una scheda di quattro relè, se si può posso postare il link di ebay dei relè?

Già 4 relè mi apiono tanti..

Cmq in prima istanza prova ad alimentare separatamente la scheda Arduino+ relè, o almeno quella relè. Ovviamente con un alimentatore serio.

A casa ora ne ho uno di quelli con la tensione regolabile, può andare bene? Poi ne andrò a comprare uno nel negozio di elettronica se risolvo. Ma se attacco solo la scheda relè il GND va messo in comune con quello di arduino o no?

L'Alimentatore regolabile va bene, a patto che la tensione sia corretta e che abbia corrente sufficiente.

Ovviamente si! devi mettere in comune i GND di Arduino e scheda relè, altrimenti non c'è riferimento per l'accensione delle bobine.

Okey benissimo, provo testo e dopo vi dico se ho risolto!

Ho comprato un alimentatore regolabile stabilizzato 5 volt 3000 mA è ci ho collegato solo la scheda dei relè, ma il problema persiste, rientrando a casa stamattina mi sono ritrovato tutte le luci accese :frowning:

Comincia a postare lo schetch, anche se dubito sia un pronblema software.

Lo sketch l'ho trovato su internet, io l'ho modificato per poter usare anche dei pulsanti per accendere la luce, oltre all'interfaccia web

Prima parte:

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
byte i=0;                        // generic counter
byte numPin=0;                   // PIN number
boolean dpin[14];                // array containing logical status of digital outputs
char action;       // char containing the last char of the command
 
//RELE' 1 ---------------
#define RELE1 12
#define BUTTONREL1 51
int valrel1 = 0;                  // si userà val per conservare lo stato del pin di input  
int vecchio_valrel1 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente  
int statorel1 = 0;
//RELE' 2 ---------------
#define RELE2 11
#define BUTTONREL2 50
int valrel2 = 0;                  // si userà val per conservare lo stato del pin di input  
int vecchio_valrel2 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente  
int statorel2 = 0; 
//RELE' 3 ---------------
#define RELE3 10
#define BUTTONREL3 49
int valrel3 = 0;                  // si userà val per conservare lo stato del pin di input  
int vecchio_valrel3 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente  
int statorel3 = 0; 
//RELE' 4 ---------------
#define RELE4 9
//#define BUTTONREL4 48
int valrel4 = 0;                  // si userà val per conservare lo stato del pin di input  
int vecchio_valrel4 = 0;          // si userà vecchio_val per conservare lo stato del pin di input al passo precedente  
int statorel4 = 0; 

void setup() {
  // initialize serial:
  Serial.begin(38400);
  initializePins();
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

void loop() {

  if (stringComplete) {
    // verify that this is a command (8 chars beginning with "*CMD")
    if ((inputString.length()==8) && (inputString.startsWith("*CMD"))) {   
      numPin=getPin();
      // verifiy that the PIN specified in the command is valid
      if (numPin!=99) {
        action=inputString.charAt(6);
        // verifiy last char of command and do the associated functions
        if (action=='V') {          
          Serial.println(readStatus(numPin));
        } else
        if ((numPin<=8) && (numPin>=2)) switch (action) {
          case 'S':      
            Serial.println(readStatus(numPin));
            break;            
          case 'H':
            writeStatus(numPin,HIGH);
            break;
          case 'L':
            writeStatus(numPin,LOW);
            break;
          case 'T':      
            writeStatus(numPin,!readStatus(numPin));
            break;
         }
         //-------------------
         //----  RELE' 1  ----
         if(numPin==12) switch(action) {
            case 'S':      
            Serial.println(readStatus(numPin));
            break;            
          case 'H':
            statorel1=1;
            break;
          case 'L':
            statorel1=0;
            break;
          case 'T':      
            writeStatus(numPin,!readStatus(numPin));
            break;
         }
         //-------------------
         //----  RELE' 2  ----
         if(numPin==11) switch(action) {
            case 'S':      
            Serial.println(readStatus(numPin));
            break;            
          case 'H':
            statorel2=1;
            break;
          case 'L':
            statorel2=0;
            break;
          case 'T':      
            writeStatus(numPin,!readStatus(numPin));
            break;
         }
         //-------------------
         //----  RELE' 3  ----
         if(numPin==10) switch(action) {
            case 'S':      
            Serial.println(readStatus(numPin));
            break;            
          case 'H':
            statorel3=1;
            break;
          case 'L':
            statorel3=0;
            break;
          case 'T':      
            writeStatus(numPin,!readStatus(numPin));
            break;
         }
         //-------------------
         //----  RELE' 4  ----
         if(numPin==9) switch(action) {
            case 'S':      
            Serial.println(readStatus(numPin));
            break;            
          case 'H':
            statorel4=1;
            break;
          case 'L':
            statorel4=0;
            break;
          case 'T':      
            writeStatus(numPin,!readStatus(numPin));
            break;
         }
         //-------------------
        // Serial.println(inputString);        
        // Serial.println(getPin()); // Debug
        // Serial.println(cmd);
      }
    }
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
  //-----------------
  // PULSANTE RELE' 1
  valrel1 = digitalRead(BUTTONREL1);  
  
 
  if ((valrel1 == HIGH) && (vecchio_valrel1 == LOW)){  
    statorel1 = 1 - statorel1;  
    delay(40);                 
  }   
  
  vecchio_valrel1 = valrel1;           
  
    if (statorel1 == 1) {  
    writeStatus(RELE1, HIGH);   
  }   
  else {  
    writeStatus(RELE1, LOW);    
  }  
  
   //-----------------
  // PULSANTE RELE' 2
  valrel2 = digitalRead(BUTTONREL2);  
  
  if ((valrel2 == HIGH) && (vecchio_valrel2 == LOW)){  
    statorel2 = 1 - statorel2;  
    delay(40);                
  }   
  
  vecchio_valrel2 = valrel2;          
  
    if (statorel2 == 1) {  
    writeStatus(RELE2, HIGH);   
  }   
  else {  
    writeStatus(RELE2, LOW);    
  } 
  
   //-----------------
  // PULSANTE RELE' 3
  valrel3 = digitalRead(BUTTONREL3); 
  

  if ((valrel3 == HIGH) && (vecchio_valrel3 == LOW)){  
    statorel3 = 1 - statorel3;  
    delay(40);                 
  }   
  
  vecchio_valrel3 = valrel3;              
  
    if (statorel3 == 1) {  
    writeStatus(RELE3, HIGH);   
  else {  
    writeStatus(RELE3, LOW);     
  }
  
  //-----------------
  // PULSANTE RELE' 4
//  valrel4 = digitalRead(BUTTONREL4);  
   
//  if ((valrel4 == HIGH) && (vecchio_valrel4 == LOW)){  
//    statorel4 = 1 - statorel4;  
//    delay(40);                
//  }   
  
//  vecchio_valrel4 = valrel4;              
  
    if (statorel4 == 1) {  
    writeStatus(RELE4, HIGH);   // accende il led  
  }   
  else {  
    writeStatus(RELE4, LOW);    //spegne il led  
  }  
}

Seconda parte:

// inizialize digital pins as OUTPUT with "LOW" value
void initializePins () {
  dpin[0]=dpin[1]=false;
  for (i=2; i<=13; i++) {
    pinMode(i,OUTPUT);
    digitalWrite(i,LOW);
    // Serial.println(i); // Debug
    dpin[i]=false;
  }  
}

// write "HIGH" or "LOW" on specified pin and save status in array dpin[]
boolean writeStatus(int pin, boolean value) {
  digitalWrite(pin, value);
  dpin[pin]=value;
  return value;
}

// read status of pins (digital and analog)
int readStatus(int pin) {
  if (pin<=13) return dpin[pin]; else return analogRead(pin);
}

// verify if a char is a number
boolean isNumber(char character) {
  if ((character>=48) && (character<=57)) return true; else return false;
}

// return pin number specified by serial command
// remember the command is in this format: *CMDA2S/ so this function
// takes the 5th and the 6th char and does many checks with ASCII table
// in order to convert values from 02 to A6 to an integer from 2 to 19
// being sure that every single char is a number or the 5th is a "A" 
// followed by a number for analog inputs
byte getPin() {
  if (inputString.charAt(4)==65) { 
    if ((inputString.charAt(5)>=48) && (inputString.charAt(5)<=53)) return (inputString.charAt(5)-34); else return 99;
  } else {
      if ((isNumber(inputString.charAt(4))) && (isNumber(inputString.charAt(5)))) {
        char strtemp[2]={inputString.charAt(4),inputString.charAt(5)};
        if ( (atoi(strtemp))<=19 && (atoi(strtemp))>=2 ) return (atoi(strtemp)); else return 99;
      } else return 99;
    }
}    

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
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 "/", set a flag
    // so the main loop can do something about it:
    if (inChar == '/') {
      stringComplete = true;
    } 
  }
}

Dovrebbe essere okey

Ciao akaGiulio
usi raspberry per comandarli da web?

esattamente

Nessuno sa aiutarmi?

Mi spiegheresti più in dettaglio come funziona?
Tu hai una interfaccia web e comandi i relè da li.
Poi? arduino collegato via ethernet e da arduino hai collegato la scheda relè. E' così?
Ma i pulsanti? (fai riferimento al cavo schermato...)

L'arduino è collegato tramite usb al raspberry che fa da server e comunicano tramite seriale.

I pulsanti sono collegati in questo modo:

Se però sono più di un pulsante che controlla la stessa luce (es. uno in cima alle scale e uno alla fine), i pulsanti li ho collegati allo stesso pin

Ho capito.
Anziché utilizzare la scheda relè già bella pronta e fatta saresti prova ad utilizzare dei singoli relè opportunamente collegati alle uscite di arduino.
Io ad esempio ho utilizzato dei relè da 12V collegati ad arduino tramite gli uln2803 e non ho alcun problema.
La gestione delle prese nello studio (dove ci sono collegati pc, monitor, audio ecc.) avviene proprio con questo sistema. Sono in totale 12 relè che funzionano alla perfezione.
Ho portato un cavo comune con i +12V e poi un cavo di controllo collegato all'uln (che ovviamente è collegato a sua volta ad arduino). Attivando l'uscita di arduino l'uln mette la relativa uscita a gnd chiudendo il circuito del relè ed eccitandolo.
Ripeto, saranno almeno 6-8 mesi che il sistema funziona senza alcun problema.

Mi puoi disegnare uno schema?

http://www.pighixxx.com/abc-arduino-basic-connections/

Sulla scheda 3 vedi come collegare un relè ad arduino mediante transistor.

Qua vedi come collegare tramite uln:

Sulle uscite non servono le resistenze. Gli ingressi li colleghi alle uscite di arduino. Al posto dei led ci metti i relè.
Dove vedi il "+" ci metti l'alimentazione adeguata ai relè (5V o 12V o 24V... insomma quelli che trovi).
Prova collegando inizialmente un solo relè...