How can I turn on or turn off a switch using Android and a Wi-Fi connection?
I have used SparkFuns IOIO to control relays. But how do I do it wirelessly?
How can I turn on or turn off a switch using Android and a Wi-Fi connection?
I have used SparkFuns IOIO to control relays. But how do I do it wirelessly?
You could use an Arduino with an Ethernet Shield - or possibly a Netduino. Basically, any device with wireless internet capabilities, since that is the only wireless protocol Android uses - besides Bluetooth (or NFC). When the user presses a button, you could open a Socket
or a BluetoothSocket
to communicate to the second device that it needs to open the switch. Fairly simple - if you have a wireless home network, then your device could be plugged in to your router with a physical wire - as long as your Android device and your microprocessor are on the same network. There might be other wireless options you could use - these are just the simplest I could thing of. Hope this helps!
That's why how I did it with my iPhone (should be the same on Android):
I have a project just like this. Mine is sending position data for a steering system, but the idea is the same. I'll finish uploading it to Google Code soon. You can check it out at PowerWheelino.
The basic structure is this:
Keep in mind that the Arduino automatically resets when receiving data over serial (outside of the IDE Serial interface). See my post here on this topic and ways to get around it. Knowing this previously would have saved me a lot of troubleshooting.
Disclaimer:
This code requires some minor modification to accomplish what was requested by the OP. Since you've already made a working Android program with IOIO and an Arduino sketch, I assume this is within your abilities.
Here's the Android UDP client code:
Execute UdpClient::sendData()
on touch event or button press.
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import android.util.Log;
public class UdpClient {
String messageStr;
DatagramSocket s;;
int server_port;
InetAddress local;
int msg_length;
byte[] message;
public UdpClient (String ipAddress, int port){
server_port = port;
try {
local = InetAddress.getByName(ipAddress);
s = new DatagramSocket();
}
catch (Exception e) {
e.printStackTrace();
Log.d("Powerwheelino",e.getStackTrace() + "error");
}
}
public boolean sendData(byte drive, byte steering){
byte drvByte = (byte) (drive & 0xFF);
byte steerByte = (byte) (steering & 0xFF);
message = new byte[2];
message[0] = drvByte;
message[1] = steerByte;
msg_length = message.length;
//message = messageStr.getBytes();
try {
DatagramPacket p = new DatagramPacket(message, msg_length,local,server_port);
s.send(p);
}
catch (Exception e) {
// TODO Auto-generated catch block
Log.d("Powerwheelino", e.getStackTrace() +"ERROR ");
e.printStackTrace();
return false;
}
return true;
}
}
Here's the listening UDP server (C++) code
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <SerialStream.h>
using namespace std;
class udp_server {
int sock;
int bytes_read;
socklen_t addr_len;
struct sockaddr_in server_addr , client_addr;
public:
udp_server(int portNum)
{
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portNum);
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr.sin_zero),8);
if (bind(sock,(struct sockaddr *)&server_addr,
sizeof(struct sockaddr)) == -1)
{
perror("Bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);
printf("\nUDPServer Waiting for client on port %d", portNum);
fflush(stdout);
}
int listen(char recv_data[]) {
while (1)
{
bytes_read = recvfrom(
sock,
recv_data,
1024,
0,
(struct sockaddr *)&client_addr,
&addr_len
);
recv_data[bytes_read] = '\0';
printf("\n(%s , %d) said : ",inet_ntoa(client_addr.sin_addr),
ntohs(client_addr.sin_port));
printf("%s", recv_data);
string drive;
string direction;
int speed, angle;
if ((recv_data[0] & 128) > 0) {
drive = "Fwd";
}
else {
drive = "Rev";
}
if ((recv_data[1] & 128) > 0) {
direction = "Left";
}
else {
direction = "Right";
}
speed = recv_data[0] & 127;
angle = recv_data[1] & 127;
printf("\t %s @ %d and %s @ %d",
drive.c_str(),
speed,
direction.c_str(),
angle);
fflush(stdout);
}
return 0;
}
};
Here's a snippet of the serial communication to the Arduino using LibSerial:
LibSerial::SerialStream myss;
SerialComm(int argc, char** argv) {
myss = new LibSerial::SerialStream("/dev/ttyS0", ios_base::out);
myss.SetBaudRate(LibSerial::SerialStreamBuf::BAUD_57600);
myss.SetCharSize(LibSerial::SerialStreamBuf::CHAR_SIZE_8);
myss.SetFlowControl(LibSerial::SerialStreamBuf::FLOW_CONTROL_NONE);
myss.SetParity(LibSerial::SerialStreamBuf::PARITY_NONE);
myss.SetNumOfStopBits(1);
const int Dsize = 2;
char buffer[1];
buffer[0] = 125; //0b00000001;
buffer[1] = '\0';
bitset(buffer[0]);
//myss << buffer;
myss.write(buffer,1);
//myss.Close();
}
You can also use a Rugged Circuits Yellowjacket. It has a Wifi on board and can serve simple web pages and control inputs/outputs.