Remote relay control wia Ethernet with WEB access.

   

     It is my first commercial project, which i created from idea to hardware devices and user WEB interface. It is very scalable decision which provide function for control remote circuit based. This devices can switch relay from on to off state, using simple Web interface. In figure below you can see abstract scheme with all needed. So we can connect terminating devices to local area network and control it using, for example, smartphone wia WiFi connection.

   

     The device, which execute command to switching relay state, is consist a microcontroller unit by Microchip - PIC18F67J60. This microcontroller has integrated PHY interface to connect to Ethernet network 802.3 on based 10Mbit/s speed. So it need only create PCB board with some additional chips for electrical compatibility. To create PCB board i use Sprint-Layout 6 application. It good to create simple one side PCB boards. One module contains 6 relay switch, types LEG-5 and can connect power load up to 7 Amp 240 Volts. It relays driving with helper Darlington transistors arrays - ULN2003A.

   

     To make micro code for microcontroller i use ANSI C language. It is very common standard of C language. Programs created with ANSI C can be compiled with different compilers. Part of code is presented below.

#include   "__EthJ60.h"
#define Ethernet_HALFDUPLEX     0
#define Ethernet_FULLDUPLEX     1
/*********** RAM variables *************************/
unsigned char   myMacAddr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x02} ;   // my MAC address
unsigned char   server_ip[4]  = {0, 0, 0, 0 } ;                   // server IP address
unsigned char   myIpAddr[4]  = {0, 0, 0, 0 } ;                   // my IP address
unsigned char   gwIpAddr[4]  = {0, 0, 0, 0 } ;                   // gateway (router) IP address
unsigned char   ipMask[4]    = {0, 0, 0, 0 } ;                   // network mask (for example : 255.255.255.0)
unsigned char   dnsIpAddr[4] = {0, 0, 0, 0 } ;                   // DNS server IP address
unsigned char   obtaine_packet, getRequest[256],dyna[500],toWrite[464],hhex[7];  // HTTP request buffer
/*========================================*/
sbit Relay1_Port at RE1_bit;
sbit Relay2_Port at RE0_bit;
sbit Relay3_Port at RB0_bit;
sbit Relay4_Port at RB1_bit;
sbit Relay5_Port at RB2_bit;
sbit Relay6_Port at RB3_bit;
sbit Conf_pin at RF2_bit;
sbit Test_time at RD2_bit;
sbit Test_relay at RD1_bit;
sbit Chip_Select at RC2_bit;
sbit Chip_Select_Direction at TRISC2_bit;
unsigned short take, menu, res, res1, res2, timer, pos,timer_minut;
int Relay1_time,Relay2_time,Relay3_time,Relay4_time,Relay5_time,Relay6_time;
int temp_int, buffer, i,pack_len, res_find;
unsigned char
dev_name[64],    //  ---
relay1_name[64], //  --
relay2_name[64], //
relay3_name[64], //  --
relay4_name[64], //  --
relay5_name[64], //
relay6_name[64]; //
/*******************************************/
unsigned int Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength, TEthPktFlags *flags)
        {
        unsigned int    len = 0 ;                   // my reply length
        return(len) ;                               // return to the library with the number of bytes to transmit
        }
unsigned int Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned int destPort, unsigned int reqLength, TEthPktFlags *flags)
        {
        unsigned int len=0;                    // my reply length
          // back to the library with the length of the UDP reply
        if(destPort != 50050) {return(0);}
        pack_len=reqLength;
        for (i=0;i<256;i++){getRequest[i] ='\x00';}
        obtaine_packet=1;
        server_ip[0]=remoteHost[0];
        server_ip[1]=remoteHost[1];
        server_ip[2]=remoteHost[2];
        server_ip[3]=remoteHost[3];
        for(i = 0; i<256; i++)
                {
                getRequest[i] = Ethernet_getByte() ;
                }
        return(len) ;
        }
/*
 * main entry
 */
void Update_device(void){
                    for (i = 0; i < 500; i++) {dyna[i]='\x00';}
                    res = strcat(dyna, "key_id=dinka&table=Devices&module_mac=");
                    for (i=0; i<6; i++){bytetoHex(myMacAddr[i],hhex); strcat(dyna, hhex);}
                    strcat(dyna, "&hw_ver=01&module_info=Relay control (6 relay)&module_name=");
                    strcat(dyna, dev_name);
                    strcat(dyna, "&module_ip="); 
                    for (i=0; i<4; i++){bytetostr(myIPAddr[i],hhex); strcat(dyna, hhex);strcat(dyna, ".");}
                    strcat(dyna, "&module_func=Relay");
                    Ethernet_sendUDP(server_ip, 50050, 50051, dyna, strlen(dyna));
}
void Update_relay(void){
//Update table Relay
                    for (i = 0; i < 500; i++) {dyna[i]=0;}
                    strcat(dyna, "key_id=dinka&table=Relay&relay_state=R1+");
                    if (Relay1_port==1){strcat(dyna, "1;R2+");} else {strcat(dyna, "0;R2+");}
                    if (Relay2_port==1){strcat(dyna, "1;R3+");} else {strcat(dyna, "0;R3+");}
                    if (Relay3_port==1){strcat(dyna, "1;R4+");} else {strcat(dyna, "0;R4+");}
                    if (Relay4_port==1){strcat(dyna, "1;R5+");} else {strcat(dyna, "0;R5+");}
                    if (Relay5_port==1){strcat(dyna, "1;R6+");} else {strcat(dyna, "0;R6+");}
                    if (Relay6_port==1){strcat(dyna, "1&");} else {strcat(dyna, "0&");}
                    strcat(dyna, "relay_time=R1+");
                    inttostr(Relay1_time,hhex); strcat(dyna, hhex);
                    strcat(dyna, ";R2+");
                    inttostr(Relay2_time,hhex); strcat(dyna, hhex);
                    strcat(dyna, ";R3+");
                    inttostr(Relay3_time,hhex); strcat(dyna, hhex);
                    strcat(dyna, ";R4+");
                    inttostr(Relay4_time,hhex); strcat(dyna, hhex);
                    strcat(dyna, ";R5+");
                    inttostr(Relay5_time,hhex); strcat(dyna, hhex);
                    strcat(dyna, ";R6+");
                    inttostr(Relay6_time,hhex); strcat(dyna, hhex);
                    strcat(dyna, "&relay_name=R1+");
                    strcat(dyna, relay1_name);
                    strcat(dyna, ";R2+");
                    strcat(dyna, relay2_name);
                    strcat(dyna, ";R3+");
                    strcat(dyna, relay3_name);
                    strcat(dyna, ";R4+");
                    strcat(dyna, relay4_name);
                    strcat(dyna, ";R5+");
                    strcat(dyna, relay5_name);
                    strcat(dyna, ";R6+");
                    strcat(dyna, relay6_name);
                    Ethernet_sendUDP(server_ip, 50050, 50051, dyna, strlen(dyna));
            //Update table Relay
}
void main() {
    timer=0;
    timer_minut=0;
    PORTB=0; PORTD=0; PORTF=0;
    LATB=0; LATF=0; TRISA=0;
    TRISB=0; TRISC=0; TRISD=0;
    TRISF=0x04; TRISE=0;
    CMCON=0x07;
    ADCON1=0x0F;
    Relay1_Port=0;    Relay2_Port=0;    Relay3_Port=0;
    Relay4_Port=0;    Relay5_Port=0;    Relay6_Port=0;
    Relay1_time=0;    Relay2_time=0;    Relay3_time=0;
    Relay4_time=0;    Relay5_time=0;    Relay6_time=0;
    obtaine_packet=0;
    INTCON = 0;            // Îáíóëåíèå ðåãèñòðà óïðàâëåíèÿ ïðåðûâàíèÿìè
    PIE1 = 0;              //
    PIE2 = 0;
//=============== Èíèöèàëèçàöèÿ ìîäóëÿ SPI =====================================
    Chip_Select_Direction = 0;             // Set CS# pin as Output
    Chip_Select = 1;                       // Deselect EEPROM
    //SPI1_Init();                           // Initialize SPI module
    SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
/* ==========Initialize Ethernet controller==========================         */
if (Conf_pin==0){
    for (i = 0; i < 64; i++) {dev_name[i]='\x00';}
    for (i = 0; i < 64; i++) {relay1_name[i]='\x00';}
    for (i = 0; i < 64; i++) {relay2_name[i]='\x00';}
    for (i = 0; i < 64; i++) {relay3_name[i]='\x00';}
    for (i = 0; i < 64; i++) {relay4_name[i]='\x00';}
    for (i = 0; i < 64; i++) {relay5_name[i]='\x00';}
    for (i = 0; i < 64; i++) {relay6_name[i]='\x00';}
                strcat(dev_name,"Device name");
                strcat(relay1_name,"Relay1 name");
                strcat(relay2_name,"Relay2 name");
                strcat(relay3_name,"Relay3 name");
                strcat(relay4_name,"Relay4 name");
                strcat(relay5_name,"Relay5 name");
                strcat(relay6_name,"Relay6 name");
                WriteEEPROM();
                }
        ReadEEPROM();
        Ethernet_Init(myMacAddr, myIpAddr, Ethernet_FULLDUPLEX) ;
        Ethernet_initDHCP(5); // get network configuration from DHCP server, wait 5 sec for the response
        Ethernet_Enable(_Ethernet_BROADCAST); // enable Broadcast traffic
while(1)                        // do forever
        {
if (obtaine_packet==1) {obtaine_packet=0;
//============================================================
        res_find = strstr (getRequest,"update_all_tables");
        if (res_find > 0){Update_device();
                          Update_relay();
                          }

        res_find = strstr (getRequest,"update_Relay");
        if (res_find > 0){Update_relay();
                         }

        res_find = strstr (getRequest,"Relay+R1+ON");
        if (res_find > 0){res_find = strstr (getRequest,"time=-1");
                         if (res_find > 0) {Relay1_port=1;Relay1_time=-1;}
                                       else{
                                            for (i = 0; i < 256; i++) {if (getRequest[i]=='='){res_find=i;i=256;}}
                                            take=0;
                                            for (i = 0; i < 7; i++) {hhex[i]='\x00';}
                                            for (i=res_find+1; i<res_find+4;i++) {hhex[take]=getRequest[i];take++;}
                                            Relay1_time=atoi(hhex); if (Relay1_time>0) {Relay1_port=1;}

                                                           }
                         
                         }
        res_find = strstr (getRequest,"Relay+R1+OFF");
        if (res_find > 0){Relay1_Port=0;Relay1_time=0;
                         }
                res_find = strstr (getRequest,"Relay+R2+ON");
        if (res_find > 0){res_find = strstr (getRequest,"time=-1");
                         if (res_find > 0) {Relay2_port=1;Relay2_time=-1;}
                                       else{
                                            for (i = 0; i < 256; i++) {if (getRequest[i]=='='){res_find=i;i=256;}}
                                            take=0;
                                            for (i = 0; i < 7; i++) {hhex[i]='\x00';}
                                            for (i=res_find+1; i<res_find+4;i++) {hhex[take]=getRequest[i];take++;}
                                            Relay2_time=atoi(hhex);if (Relay2_time>0) {Relay2_port=1;}
                                                           }

                         }
        res_find = strstr (getRequest,"Relay+R2+OFF");
        if (res_find > 0){Relay2_Port=0;Relay2_time=0;
                         }
        
                res_find = strstr (getRequest,"Relay+R3+ON");
        if (res_find > 0){res_find = strstr (getRequest,"time=-1");
                         if (res_find > 0) {Relay3_port=1;Relay3_time=-1;}
                                       else{
                                            for (i = 0; i < 256; i++) {if (getRequest[i]=='='){res_find=i;i=256;}}
                                            take=0;
                                            for (i = 0; i < 7; i++) {hhex[i]='\x00';}
                                            for (i=res_find+1; i<res_find+4;i++) {hhex[take]=getRequest[i];take++;}
                                            Relay3_time=atoi(hhex);if (Relay3_time>0) {Relay3_port=1;}
                                                           }

                         }
        res_find = strstr (getRequest,"Relay+R3+OFF");
        if (res_find > 0){Relay3_Port=0;Relay3_time=0;
                         }
                res_find = strstr (getRequest,"Relay+R4+ON");
        if (res_find > 0){res_find = strstr (getRequest,"time=-1");
                         if (res_find > 0) {Relay4_port=1;Relay4_time=-1;}
                                       else{
                                            for (i = 0; i < 256; i++) {if (getRequest[i]=='='){res_find=i;i=256;}}
                                            take=0;
                                            for (i = 0; i < 7; i++) {hhex[i]='\x00';}
                                            for (i=res_find+1; i<res_find+4;i++) {hhex[take]=getRequest[i];take++;}
                                            Relay4_time=atoi(hhex);if (Relay4_time>0) {Relay4_port=1;}
                                                           }

                         }

 //======================================================
        
        }
        Ethernet_doPacket() ;   // process incoming Ethernet packets
        if(Ethernet_doDHCPLeaseTime())
           Ethernet_renewDHCP(5); // it's time to renew the IP address lease, with 5 secs for a reply
        }
}


     For communicate with MAIN ROUTER microcontroller use UDP protocol and ports 50050, 50051. When relay module is starting it obtain IP address from router wia DHCP protocol. As we can see below in OpenWRT main page both of devices obtain IP 192.168.1.101 and 192.168.1.102 and displayed their "VIP" MAC addresses 00:00:00:00:00:01 and 00:00:00:00:00:02.


     To visualize process of control and switching relay, on main router working HTTP server which uses PHP scripts and database MySQL. Permanently working php script (displayed below) for sending and obtaining a packets. It open a socket wia UDP protocol and when ip packet recieved it writes packet payload to database. 

<?PHP        
#===========Server UDPD configuration ================
            $local_address="0.0.0.0";
            $local_port=50051;
            $remote_port=50050;
#===========Data Base configuration =================
            $db_name="Module";
            $db_address="127.0.0.1";
            $db_login="root";
            $db_pass="admin";
#====================================================                
$key_ok=0;
$table_ok=0;
            $socket=socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
            socket_set_option($socket, SOL_SOCKET, SO_KEEPALIVE, 1);                    
            socket_bind($socket,$local_address,$local_port);
           
           $dbcnx = mysql_connect($db_address,$db_login,$db_pass);
           $select_db = mysql_select_db($db_name);
                                        
while(true){
                                       
            socket_recvfrom($socket,$buf,1000,0,$clientip,$clientport);
if ($clientport == $remote_port){            
            $arra = explode("&", $buf);
            foreach ($arra as $value) {
                                      $dem = explode("=", $value);
                                      if (($dem[0]=="key_id") && ($dem[1]=="dinka")) {$key_ok=1;}
                                      if (($dem[0]=="table") && ($key_ok==1)) {$db_table=$dem[1];
                                                                               $zapros = mysql_query("INSERT INTO $db_table SET obtaine_ip='$clientip'");
                                                                               $table_ok=1;
                                                                              }
                                      if (($key_ok==1)&&($table_ok==1)) {
                                                                        $zapros = mysql_query("UPDATE $db_table SET $dem[0]='$dem[1]' WHERE obtaine_ip='$clientip'"); 
                                                                        }
                                      };
                                      unset($value);
                                      $key_ok=0;
                                      $table_ok=0;

#            file_put_contents("./cs.log","$buf\n",FILE_APPEND);
           
                               }
           }
?>

     Other scripts create a interface for user, such as relay name, time to autodisable, MAC, IP addr and other.

   

   

   






No comments:

Post a Comment