I. Introduction

In real life, we usually have devices placed at different areas (e.g, like light bulbs in different rooms). The traditional way to control those devices is via locally installed buttons/switches.
Nowadays you can even take control via smart phone application, web browsers, etc, but that's a different story.

In this project, I just want to show you how to make a simple centralized control panel. That means, you can sit in one room, with all the buttons/switches on the table, and use them to control anything from anywhere.

In fact, this type of applications can be called "Internet Switches", whereas the input information is forwarded through TCP/IP network, and then on the other side over the Internet, the output control signal is made based on those input information.
Enough talking, now I am going to show you how I made an Internet switches. It allows me to use switches to remotely control devices (toggle a lamp ON/OFF) via the Internet.




II. How it works

Hardware components

+) Arduino UNO × 1

+) Arduino Mega 2560 × 1

+) PHPoC Shield for Arduino × 2

+) PHPoC 4-port Relay Board × 1

+) PHPoC 4-Port Digital Input Board × 1

+) Switch × 1

+) Lamp × 1




Things are quite straightforward. I made a simple demonstration project with two Arduino boards, one work as a controller and another work as an actuator.

- Controller board: One Arduino is used at the control side. It receives the input signal from the switches, then transfers those input signal via the Internet with the help of PHPoC Shield. This controller board is a combination of one Arduino + one PHPoC Shield (for network function) + one PHPoC Smart 4-Port Input Board (for reading input signal), stacked together. The input board is connected with a switch. The board detects the input state from the switch and forward any input changes to the actuator board.
input.jpg

Controller board



- Actuator board: I make another Arduino board to receive the input signal and then output that signal to control the lamb. This board consists of one Arduino, one PHPoC Shield, and one PHPoC Smart Relay Board.

The control board communicates with the actuator board via TCP connection, one works as a TCP client and the other as a TCP server. That means we can put the controller and actuators at long-distance places and they will still work, because they can connect to each other via the Internet.
relay.jpg

Actuator board



Well, I made this project with the hardware I have T_T, so only one input port (connected with the switch) and one relay output port (connected with the lamb) are used. Actually this can be extended much more than that with more hardware equipment.

Two-way control can be made. With additional effort, we can make the controller board work as an actuator board also, and vice versa.
Other actuators can be added, that means one controller can be used to control many actuator boards.

Demonstration




Source code

input.ino - Source code for Arduino input board. This board works as a TCP client and gets the input state

Code:
  
#include <Phpoc.h>
#include <PhpocExpansion.h>

#define TCP_PEER_ADDR "192.168.0.101"    // enter your tcp server addr here
#define TCP_PEER_PORT 1470                // enter your tcp server port here
#define EXPANSION_ID 2

char peer_addr[] = TCP_PEER_ADDR;
int peer_port = TCP_PEER_PORT;
byte expansionId = EXPANSION_ID;

PhpocClient client;

ExpansionPhotoInput inputs[4] = {
  ExpansionPhotoInput(expansionId, 0),
  ExpansionPhotoInput(expansionId, 1),
  ExpansionPhotoInput(expansionId, 2),
  ExpansionPhotoInput(expansionId, 3)
};

int last_state[4] = { 0, 0, 0, 0 };

void setup() {
  Serial.begin(9600);
  while(!Serial)
    ;

  // initialize PHPoC [WiFi] Shield
  Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
  //Phpoc.begin();

  if(client.connect(peer_addr, peer_port))
  {
    // if connected
    Serial.println("Connected to server");
  }
  else // if not connected
    Serial.println("connection failed");

  // initialize expansion board
  Expansion.begin();

  // get name and print it to serial
  Serial.println(inputs[0].getName());
}

void loop() {
  bool event = false;
  byte input_state = 0;

  for (int i = 0; i < 4; i++) {
    int state;
    String state_str;

    // Get the state of each input port
    if (inputs[i].isOn())
    {
      state = 1;
      state_str = "ON";
    }
    else
    {
      state = 0;
      state_str = "OFF";
    }

    // Accumulate the input state
    input_state = input_state | (state << i);

    // Update if any input state is changed
    if(state != last_state[i])
    {
      event = true;
      last_state[i] = state;
      String input_str = "";
      input_str = input_str + "Input port " + i + " is " + state_str;
      Serial.println(input_str);
      Serial.println();
    }
  }


  if (event) // Transfer the control state to relay board
  {
    client.write(input_state);
    client.flush();
  }

  delay(500);
}



output.ino - Source code for Arduino relay board. This board works as a TCP server and controls the output state

Code:
  
#include <Phpoc.h>
#include <PhpocExpansion.h>

#define TCP_LOCAL_PORT 1470    // enter your tcp server listening port here
#define EXPANSION_ID 1

byte expansionId = 1;
PhpocServer server(TCP_LOCAL_PORT);

ExpansionRelayOutput relays[4] = {
  ExpansionRelayOutput(expansionId, 0),
  ExpansionRelayOutput(expansionId, 1),
  ExpansionRelayOutput(expansionId, 2),
  ExpansionRelayOutput(expansionId, 3)
};

void relayOutputState(byte relay_state) {
  for (int i = 0; i < 4; i++) {
    int state = (relay_state >> i) & 0x01;
    if (state)
      relays[i].on();
    else
      relays[i].off();
  }
}

void relayPrintState(void) {
  for (int i = 0; i < 4; i++) {
    String state_str;
    String output_str = "";

    state_str = (relays[i].isOn()) ? "ON" : "OFF";
    output_str = output_str + "Relay port " + i + " is " + state_str;

    Serial.println(output_str);
  }
  Serial.println();
}

void setup() {
  Serial.begin(9600);
  while(!Serial)
    ;

  // initialize PHPoC [WiFi] Shield
  Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
  //Phpoc.begin();


  // initialize expansion board
  Expansion.begin();

  // get name and print it to serial
  Serial.println(relays[0].getName());

}

void loop() {
  PhpocClient client = server.available();
  if (client) {
    if (client.available() > 0) {
      // read a byte incoming from the client
      byte relay_state = client.read();

      // set relay output based on the received control state
      relayOutputState(relay_state);

      // get current relay state and print to serial
      relayPrintState();
      delay(500);
    }
  }

}