Blog Archive

Wednesday 19 December 2012

Remote sockets with opto-isolator


Update to my remote switch I once used to run with the USB Bit Whacker. Now it uses Arduino.


I used Bootstrap to make a webpage which would look OK on an iPhone. I wanted nice big buttons. (Always use a VPN when connected to unsecured WiFi kids!)


 Here is the Arduino code:
 int on1 = 2;   
 int on1gnd = 3;  
 int off1 = 4;  
 int off1gnd = 5;  
 //int on2 = 10;  
 //int off2 = 11;  
 String input;  
 char inData[20]; // Allocate some space for the string  
 char inChar; // Where to store the character read  
 byte index = 0; // Index into array; where to store the character  
 // the setup routine runs once when you press reset:  
 void setup() {    
 Serial.begin(9600);  
  Serial.write("Power On");   
  pinMode(on1, OUTPUT);  
  pinMode(on1gnd, OUTPUT);  
  pinMode(off1, OUTPUT);  
  pinMode(off1gnd, OUTPUT);  
  //pinMode(on1, OUTPUT);  
  //pinMode(off1, OUTPUT);  
  //pinMode(on2, OUTPUT);  
  //pinMode(off2, OUTPUT);  
  digitalWrite(on1, LOW);  
  digitalWrite(off1, LOW);   
  //digitalWrite(on2, LOW);  
  //digitalWrite(off2, LOW);   
  digitalWrite(on1gnd, LOW);  
  digitalWrite(off1gnd, LOW);   
  //digitalWrite(on2gnd, LOW);  
  //digitalWrite(off2gnd, LOW);   
 }  
 // the loop routine runs over and over again forever:  
 void loop() {  
 delay (50);  
 //Serial.println("start");  
  /*  
 switchoff();  
 delay(2000);  
 switchon();  
 delay(2000);  
 */  
 while(Serial.available() > 0) // Don't read unless  
                          // there you know there is data  
   {  
     if(index < 8) // One less than the size of the array  
     {  
       inChar = Serial.read(); // Read a character  
       inData[index] = inChar; // Store it  
       index++; // Increment where to write next  
       inData[index] = '\0'; // Null terminate the string  
     }  
   }  
   input = inData;  
   index=0;  
   // Now do something with the string (but not using ==)  
  //Serial.println(input);  
  if(strcmp(inData,"rs1on") == 0)  
   {   
   switch1on();   
   memset(inData, 0, sizeof(inData));  
   }  
  if(strcmp(inData,"rs1off") == 0)  
   {   
   switch1off();   
   memset(inData, 0, sizeof(inData));  
   }  
  /*if(strcmp(inData,"rs2on") == 0)  
   {   
   switch2on();   
   memset(inData, 0, sizeof(inData));  
   }  
  if(strcmp(inData,"rs2off") == 0)  
   {   
   switch2off();   
   memset(inData, 0, sizeof(inData));  
   }  
  */  
  //Serial.println("end");  
 }  
 //-----------------------------------------------  
 void switch1on(){  
  digitalWrite(on1, HIGH);  // turn the LED on (HIGH is the voltage level)  
  delay(500);        // wait for a second  
  digitalWrite(on1, LOW);  // turn the LED off by making the voltage LOW  
 }  
 void switch1off(){  
  digitalWrite(off1, HIGH);  // turn the LED on (HIGH is the voltage level)  
  delay(500);        // wait for a second  
  digitalWrite(off1, LOW);  // turn the LED off by making the voltage LOW  
 }  
 /*  
 void switch2on(){  
  digitalWrite(on2, HIGH);  // turn the LED on (HIGH is the voltage level)  
  delay(500);        // wait for a second  
  digitalWrite(on2, LOW);  // turn the LED off by making the voltage LOW  
 }  
 void switch2off(){  
  digitalWrite(off2, HIGH);  // turn the LED on (HIGH is the voltage level)  
  delay(500);        // wait for a second  
  digitalWrite(off2, LOW);  // turn the LED off by making the voltage LOW  
 }  
 */  

And here is the C code (which is run by the PHP code):
 #include <termios.h>  
 #include <fcntl.h>  
 #include <stdio.h>  
 #include <string.h>  
 //-----------------  
 int DC(serial_port_fd) {  
      int n;  
      usleep(2000000);  
      printf(" -- sending rs1on to output --\n");  
      n = write(serial_port_fd, "rs1on\n", 5);   
      usleep(1000000);  
      return 0;  
 }  
 //-----------------  
 int CLOSE(serial_port_fd){  
      struct termios termios_save;  
      tcsetattr(serial_port_fd, TCSANOW, &termios_save);  
      tcflush(serial_port_fd, TCOFLUSH);  
      tcflush(serial_port_fd, TCIFLUSH);  
      close(serial_port_fd);  
      return 0;  
 }  
 //------------------------------------------------------------------------------------------  
 int main(int  argc, char *argv[])  
 {  
      int serial_port_fd; // = -1;  
      char port[64] = "/dev/ttyUSB0";  
      //struct termios termios_p;  
      serial_port_fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);   
      if(serial_port_fd < 0) {  
           printf("could not open port %s\n error: %d\n", port, serial_port_fd);  
           return 1;  
      }  
      struct termios port_settings;   // structure to store the port settings in  
      cfsetispeed(&port_settings, B9600);  // set baud rates  
      cfsetospeed(&port_settings, B9600);  
      port_settings.c_cflag &= ~PARENB;  // set no parity, stop bits, data bits  
      port_settings.c_cflag &= ~CSTOPB;  
      port_settings.c_cflag &= ~CSIZE;  
      port_settings.c_cflag |= CS8;  
      tcsetattr(serial_port_fd, TCSANOW, &port_settings);  // apply the settings to the port  
      //open the serial port  
      DC(serial_port_fd); // send data to port  
      CLOSE(serial_port_fd); // close the port  
      return 0;  
 }  



Here is the code for the page:
 <?php  
 header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1  
 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past  
 ?>  
 <!DOCTYPE html>  
 <html lang="en">  
  <head>  
   <meta charset="utf-8">  
   <title>RemoteSockets</title>  
     <meta content="yes" name="apple-mobile-web-app-capable" />  
     <meta name="viewport" content="width=device-width" />  
     <meta name="apple-mobile-web-app-status-bar-style" content="black">  
   <meta name="description" content="">  
   <meta name="author" content="">  
   <link href="css/bootstrap.css" rel="stylesheet" >  
 <style type="text/css">  
 .rlmbtnred {  
   -moz-box-shadow:inset 0px 1px 0px 0px #ffffff;  
   -webkit-box-shadow:inset 0px 1px 0px 0px #ffffff;  
   box-shadow:inset 0px 1px 0px 0px #ffffff;  
   background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #ff0000), color-stop(1, #ab0000) );  
   background:-moz-linear-gradient( center top, #ff0000 5%, #ab0000 100% );  
   filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ab0000');  
   background-color:#ff0000;  
   -moz-border-radius:6px;  
   -webkit-border-radius:6px;  
   border-radius:6px;  
   border:0px solid #a3a3a3;  
   display:inline-block;  
   color:#ffffff;  
   font-family:arial;  
   font-size:15px;  
   font-weight:bold;  
   padding:32px 32px;  
   text-decoration:none;  
   text-shadow:1px 1px 0px #9e9e9e;  
 }.rlmbtnred:hover {  
   background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #ab0000), color-stop(1, #ff0000) );  
   background:-moz-linear-gradient( center top, #ab0000 5%, #ff0000 100% );  
   filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ab0000', endColorstr='#ff0000');  
   background-color:#ab0000;  
 }.rlmbtnred:active {  
   position:relative;  
   top:1px;  
 }  
 /* This imageless css button was generated by CSSButtonGenerator.com */  
 </style>  
 <style type="text/css">  
 .rlmbtngreen{  
   -moz-box-shadow:inset 0px 1px 0px 0px #ffffff;  
   -webkit-box-shadow:inset 0px 1px 0px 0px #ffffff;  
   box-shadow:inset 0px 1px 0px 0px #ffffff;  
   background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #00ff5e), color-stop(1, #06ad00) );  
   background:-moz-linear-gradient( center top, #00ff5e 5%, #06ad00 100% );  
   filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff5e', endColorstr='#06ad00');  
   background-color:#00ff5e;  
   -moz-border-radius:6px;  
   -webkit-border-radius:6px;  
   border-radius:6px;  
   border:0px solid #a3a3a3;  
   display:inline-block;  
   color:#ffffff;  
   font-family:arial;  
   font-size:15px;  
   font-weight:bold;  
   padding:32px 32px;  
   text-decoration:none;  
   text-shadow:1px 1px 0px #9e9e9e;  
 }.rlmbtngreen:hover {  
   background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #06ad00), color-stop(1, #00ff5e) );  
   background:-moz-linear-gradient( center top, #06ad00 5%, #00ff5e 100% );  
   filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#06ad00', endColorstr='#00ff5e');  
   background-color:#06ad00;  
 }.rlmbtngreen:active {  
   position:relative;  
   top:1px;  
 }  
 /* This imageless css button was generated by CSSButtonGenerator.com */  
 </style>  
   <style>  
    body { background:black;  
     color:white;  
     padding-top: 30px; /* to make the container go all the way to the bottom of the topbar */ }  
       button.btn { width:100%; height:100%; }  
       button.btn-large { width:100%; height:100%; }  
   </style>  
   <link href="css/bootstrap-responsive.css" rel="stylesheet">  
   <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->  
   <!--[if lt IE 9]>  
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>  
   <![endif]-->  
   <!-- Fav and touch icons -->  
   <link rel="apple-touch-icon-precomposed" sizes="144x144" href="ico/remotecontrol144x144.png">  
   <link rel="apple-touch-icon-precomposed" sizes="114x114" href="ico/remotecontrol114x114.png">  
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="ico/remotecontrol72x72.png">  
           <link rel="apple-touch-icon-precomposed" href="ico/remotecontrol57x57.png">  
                   <link rel="shortcut icon" href="ico/remotecontrol144x144.png">  
     <!-- Scripts (jQuery) -->  
     <script src="js/jquery-1.8.3.js"></script>  
     <script type="text/javascript">  
       $(document).ready(function(){  
       var phpScript='controller.php?871624';  
       var keyPressed='';  
       $("button").click(function(){  
         keyPressed=$(this).val(); // get value of key pressed  
         $.post(phpScript,{data:keyPressed},function(response){  
           $('#execout').text(response);  
         });  
      });  
   });  
     </script>  
   </head>  
  <body>  
     <center>  
   <div class="container-fluid">  
       <table><tr><td>This is the socket at long location 1</td></tr></table>  
       <table>  
         <tr ><td><h2>1</h2></td><td width=400><center>  
         <button value=button1on type="submit" class="rlmbtngreen btn-large btn-success" data-toggle="button"><i class="icon-white icon-play"></i>on</button> </td>  
         <td width=400><center>  
         <button value=button1off type="submit" class="rlmbtnred btn-large btn-danger" data-toggle="button"><i class="icon-white icon-stop"></i>off</button> </td>  
         </td></tr>  
       </table>  
       <table><tr><td><br></td></tr></table>  
       <table><tr><td>This is the socket at long location 2</td></tr></table>  
       <table>  
         <tr><td><h2>2</h2></td><td width=400><center>  
         <button value=button2on type="submit" class="rlmbtngreen btn-large btn-success" data-toggle="button"><i class="icon-white icon-play"></i>on</button> </td>  
         <td width=400><center>  
         <button value=button2off type="submit" class="rlmbtnred btn-large btn-danger" data-toggle="button"><i class="icon-white icon-stop"></i>off</button> </td>  
         </td></tr>  
       </table>  
       <table>  
         <tr><td></td> <td><br><center> <span id="execout"> </span> </td> </tr>  
       </table>  
   </div> <!-- /container -->  
  </body>  
 </html>  



This is how I butchered the remote control for the remote sockets. I removed the battery compartment and powered the remote from the Arduino.

This next photo should be self-explanatory: