Ελέγχουμε διάφορες ηλεκτρονικές συσκευές από το Android και το Arduino

Android Arduino Infrared Control Devices

Πριν από χρόνια σας είχα δείξει ενδεικτικά ένα μέρος του σπιτιού μου, το οποίο (χάρη στο Arduino) ελέγχω από το Android κινητό μου -ή φυσικά και από οποιονδήποτε υπολογιστή-.

Το συγκεκριμένο άρθρο αφορά την πιο συχνή ερώτηση που δέχομαι -τον έλεγχο από το Android "πιο πολύπλοκων" συσκευών, όπως τηλεοράσεις, κλιματιστικά, ηχοσυστήματα κτλ.- Και εξηγούμαι.

Ο έλεγχος των κεντρικών φώτων στα δωμάτια, ο έλεγχος φωτιστικών δαπέδου/γραφείου, του θερμοσίφωνα, της καφετιέρας μου, της ηλεκτρικής σόμπας κτλ, απαιτεί απλά ένα relay στο κύκλωμα τροφοδοσίας τους για ενεργοποίηση/απενεργοποίηση από το Arduino (και στην συνέχεια από το Android), το οποίο έδειξα για πολλές περιπτώσεις πώς μπορείτε να το αντιμετωπίσετε. Με τις υπόλοιπες συσκευές;

Hint για το πώς μπορείτε να τις ελέγξετε και αυτές είχα δώσει στο άρθρο "ασύρματου" ελέγχου της DSLR μου, μέσω IR LED. Ναι, δεν το είχα δείξει στο Project του Smart Home -αλλά η λογική παραμένει η ίδια-. Απλά αντί το Arduino να στείλει την υπέρυθρη κυματομορφή όταν λάβει στην COM port του κάποιο σήμα, θα την στέλνει όταν λάβει κάποιο συγκεκριμένο GET request στον Server που τρέχει σε αυτό, χάρη στην Ethernet Shield. Επειδή σας κούρασα, πάμε στο βίντεο και συνεχίζουμε:

Στην ουσία μπορούμε να διαβάσουμε την κυματομορφή που παράγει το χειριστήριο υπερύθρων της εκάστοτε συσκευής, και μετά να την αναπαράξουμε από ένα υπέρυρθο LED. Γιάννη δεν έχουμε παλμογράφο σας ακούω να λέτε και έχετε δίκιο. Γι' αυτόν τον λόγο μπορείτε να χρησιμοποιήσετε μία δίοδο υπερύρθων όπως η TSOP34838, ή αντίστοιχες (TSOP38238), με ελάχιστο κόστος.

Αφού συνδέσουμε την IR δίοδο, μπορούμε να χρησιμοποιήσουμε κάποια από τις έτοιμες IR βιβλιοθήκες του Arduino για να διαβάσουμε την κυμματομορφή. Η χρήση κάποιας έτοιμης βιβλιοθήκης γλιτώνει στον μέσο χρήστη πολύ κόπο από την κατανόηση (αλλά και υλοποίηση) διαφόρων πρωτοκόλλων που θα συναντήσει (NEC, Sony, RC5, RC6). Στην συνέχεια συνδέουμε τουλάχιστον ένα υπέρυθρο LED σε κάποιο/κάποια PWM Digital Pin του Arduino. (Προσωπικά για δική μου ευκολία, χρησιμοποίησα διαφορετικό Arduino, ένα για να διαβάσω την κυματομορφή, και ένα άλλο για να την αναπαράξω -με διευκόλυνε να μην χρειάζεται να αλλάζω συνέχεια sketches.) Για να διαβάσετε από το TSOP χρησιμοποιήστε το example IRrecvDumpV2 που περιέχεται στην βιβλιοθήκη, ενώ για να αναπαράξετε την κυματομορφή μπορείτε να δείτε το IRsendDemo (ή για άγνωστες κυματομορφές που δεν ακολουθούν κάποιο γνωστό πρωτόκολλο, το IRsendRawDemo)

Arduino Mega TSOP IR DiodeArduino with Ethernet Shield Infrared Control Devices

Παρακάτω δίνω τον κώδικα του Arduino (με την Ethernet Shield) που περιέχει (προφανώς) τα σήματα των δικών μου συσκευών. Ενδεικτικά ο Server μας τρέχει στο 192.168.10.40 (προφανώς αλλάζετε την IP σε αντίστοιχη για το δικό σας δίκτυο), όπως επίσης προφανώς με port forwarding (και dynDNS) μπορείτε να "ανοίξετε" τον Server προς το Internet (με ό,τι αυτό συνεπάγεται).

Τόσο στην Android εφαρμογή, όσο και στην εφαρμογή στο laptop που δείχνω, κάνω GET Requests στα URLs που περιέχει ο κώδικας του Arduino παρακάτω:

#include <SPI.h>
#include <Ethernet.h>
#include <IRremote.h>

IRsend My_Sender;

byte mac[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90 };
IPAddress ip(192, 168, 10, 40);
//IPAddress gateway(192, 168, 10, 254);
//IPAddress subnet(255, 255, 255, 0);

  int khz = 38; // 38kHz sixnotita ferontos
  
 unsigned int IrSigOn[] = {8750, 4200, 400, 1700, 350, 650, 400, 600, 450, 600, 400, 1650, 400, 600,
 450, 600, 400, 650, 400, 600, 450, 600, 400, 600, 450, 600, 400, 600, 450, 1650, 400, 600, 400, 650, 
 400, 1650, 400, 1650, 400, 1650, 400, 1650, 400, 650, 400, 600, 400, 1700, 400, 600, 450, 600, 400, 
 1700, 400, 600, 450, 1650, 400}; 
  unsigned int IrSigOff[] = {8750,4200,450,1650,400,600,400,650,400,600,400,1650,450,600,400,600,450,
650,400,1650,400,1650,400,650,400,600,450,600,400,600,450,600,450,600,400,650,400,600,400,650,
400,600,400,650,400,1650,400,600,450,1600,450,600,450,550,450,650,400,1650,400}; 

EthernetServer server(80);
String readString;

void setup()
{ 
  pinMode(A0, OUTPUT);  
  //Serial.begin(9600);
  Ethernet.begin(mac, ip);
  //Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  //Serial.print("O Server trexei stin IP: ");
  //Serial.println(Ethernet.localIP());
  //Serial.println("Bootup!");
}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client)

  {
    Serial.println("new client");

    while (client.connected())
    {
      if (client.available())

      {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100)

        {
          readString += c;
          //Serial.print(c);

          Serial.write(c);         
          if (c == '\n') {
            //Serial.println(readString); //gia debugging
            
            client.println("HTTP/1.1 200 OK"); //send new page
            client.println("Content-Type: text/html");
            client.println();
            client.println("<a href=\"/?tvon\">TV On</a>");
            client.println("<a href=\"/?tvoff\">TV Off</a>");
            client.println("<a href=\"/?chplus\">C+</a>");
            client.println("<a href=\"/?chminus\">C-</a>");
            client.println("<a href=\"/?volplus\">V+</a>");
            client.println("<a href=\"/?volminus\">V-</a>");
            client.println("<a href=\"/?airon\">Air On</a>");
            client.println("<a href=\"/?airoff\">Air Off</a>");
            client.println("<a href=\"/?fwson\">Fws On</a>");
            client.println("<a href=\"/?fwsoff\">Fws Off</a>");
            //telika kratisa to html sta apolitws vasika, alliws ta global vars crasharan to arduino
            delay(1);            
            client.stop();

            if (readString.indexOf("?tvon") > 0) //on
            {
              My_Sender.sendRC5(0x84c, 12);
              //Serial.println("TVon");
            }
            else if (readString.indexOf("?tvoff") > 0) //off
            {
              My_Sender.sendRC5(0x84c, 12);
              //Serial.println("TVoff");
            }
            else if (readString.indexOf("?chplus") > 0) //plus
            {
              My_Sender.sendRC5(0x060, 12);              
              //Serial.println("Ch+");
            }
            else if (readString.indexOf("?chminus") > 0) //minus
            {
              My_Sender.sendRC5(0x061, 12);
              //Serial.println("Ch-");
            }
            else if (readString.indexOf("?volplus") > 0) //plus
            {
              My_Sender.sendRC5(0x050, 12);
              //Serial.println("Vol+");
            }
            else if (readString.indexOf("?volminus") > 0) //minus
            {
              My_Sender.sendRC5(0x051, 12);
              //Serial.println("Vol-");
            }
            else if (readString.indexOf("?airon") > 0) //on
            {
              My_Sender.sendRaw(IrSigOn, sizeof(IrSigOn) / sizeof(IrSigOn[0]), khz);
              //Serial.println("AirOn");
            }
            else if (readString.indexOf("?airoff") > 0) //off
            {
              My_Sender.sendRaw(IrSigOff, sizeof(IrSigOff) / sizeof(IrSigOff[0]), khz);
              //Serial.println("AirOff");
            }
            else if (readString.indexOf("?fwson") > 0) //on
              {
                digitalWrite(A0,HIGH);
                //Serial.println("Energopoihsh Relay");
              }
            else if (readString.indexOf("?fwsoff") > 0) //off
              {
                digitalWrite(A0,LOW);
                //Serial.println("Apenergopoihsh Relay");
              }
            //clearing string for next read
            readString = "";

            //ena mikro delay gia ton browser
            delay(1);            
            client.stop();
            //Serial.println("client disonnected");

          }
        }
      }
    }
  }
}



Android Arduino Infrared Control Devices

aByte