Skip to content

Instantly share code, notes, and snippets.

@bjnhur
Created November 22, 2018 07:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bjnhur/8eb9c3860c4feaf062a59ad9953c974a to your computer and use it in GitHub Desktop.
Save bjnhur/8eb9c3860c4feaf062a59ad9953c974a to your computer and use it in GitHub Desktop.
A simple example supports remote contorlling and monitoring function with smartphone application.
/*
WIZnet IoT Tool Example
A simple example supports remote contorlling and monitoring function with smartphone application.
To use, download WIZnet IoT Tool from Google play store, Apple Apps Store.
https://play.google.com/store/apps/details?id=kr.co.wiznet.app_tcp
You can see the client's input in the serial monitor as well.
Using an Arduino Wiznet Ethernet shield.
THis version attempts to get an IP address using DHCP
Circuit:
Ethernet shield attached to pins 10, 11, 12, 13
created 20 Nov 2018 by Bongjun Hur(bjnhur@gmail.com)
Based on DhcpChatServer example
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
byte mac[] = {
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
};
IPAddress ip(192, 168, 1, 177);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
unsigned int localPortUDP = 5000;
unsigned int localPortTCP = 5001;
#define BUFFER_SIZE 100
char receivePacket[BUFFER_SIZE];
char sendPacket[BUFFER_SIZE];
char UDPpacketBuffer[BUFFER_SIZE]; //buffer to hold incoming packet,
EthernetUDP Udp;
EthernetServer server(localPortTCP);
// Current version of WizAPP can support 6 unit (byte value) and 1 string unit.
byte ByteUnitVal[6];
char SerialBuf[80];
String strFromSerial; // saving 1 line string
byte rCmd = 0;
byte rID = 0;
byte rVal = 0;
// Use NeoPixel Library & example
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN 6
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 2
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup()
{
// You can use Ethernet.init(pin) to configure the CS pin
//Ethernet.init(10); // Most Arduino shields
Ethernet.init(5); // MKR ETH shield
//Ethernet.init(0); // Teensy 2.0
//Ethernet.init(20); // Teensy++ 2.0
//Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet
//Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet
// Open serial communications and wait for port to open:
Serial.begin(9600);
// while (!Serial) {
// ; // wait for serial port to connect. Needed for native USB port only
// }
// start the Ethernet connection:
Serial.println("Trying to get an IP address using DHCP");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// initialize the Ethernet device not using DHCP:
Ethernet.begin(mac, ip, myDns, gateway, subnet);
}
Ethernet.MACAddress(mac); // fill the MAC buffer
Serial.print("The MAC address is: ");
for (byte octet = 0; octet < 6; octet++) {
Serial.print(mac[octet], HEX);
if (octet < 5) {
Serial.print('-');
}
}
Serial.println();
// print your local IP address:
ip = Ethernet.localIP(); // update the IP address buffer
Serial.print("My IP address: ");
Serial.println(Ethernet.localIP());
Serial.print("My TCP listen port number: ");
Serial.println(localPortTCP);
// start listening for clients
Udp.begin(localPortUDP);
server.begin();
// This initializes the NeoPixel library.
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code
pixels.begin(); // This initializes the NeoPixel library.
}
void loop()
{
Network_search_run();
WizAPP_control_run();
User_application_run();
}
void User_application_run()
{
// application for RGB remote control
RGB_NeoPixel(ByteUnitVal[0], ByteUnitVal[1], ByteUnitVal[2]);
// application for simple text chat
if (readline(Serial.read(), SerialBuf, 80) > 0) {
strFromSerial = String(SerialBuf);
Serial.print("Your message saved >>");
Serial.print(strFromSerial);
Serial.println("");
}
}
void Network_search_run()
{
// if there's data available, read a packet
int packetSizeUDP = Udp.parsePacket();
if (packetSizeUDP) {
Serial.print("UDP Received packet of size : ");
Serial.println(packetSizeUDP);
Serial.print("From ");
IPAddress remote = Udp.remoteIP();
for (int i = 0; i < 4; i++) {
Serial.print(remote[i], DEC);
if (i < 3) {
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(UDPpacketBuffer, BUFFER_SIZE);
switch (UDPpacketBuffer[0]) {
case 'S':
Serial.println("Getting device search message");
Serial.print("Reply...");
sendPacket[0] = 'N';
sendPacket[1] = 0x0C;
for (byte octet = 0; octet < 6; octet++) {
sendPacket[octet + 2] = mac[octet];
}
for (byte octet = 0; octet < 4; octet++) {
sendPacket[octet + 8] = ip[octet];
}
sendPacket[12] = highByte(localPortTCP);
sendPacket[13] = lowByte(localPortTCP);
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(sendPacket, 14);
Udp.endPacket();
Serial.println("Done");
break;
default:
break;
}
}
}
void WizAPP_control_run()
{
int packetSizeTcp = 0;
//int loop_cnt;
// wait for a new client:
EthernetClient client = server.available();
if (client) {
packetSizeTcp = client.available();
if (packetSizeTcp) {
//Serial.print("TCP Received packet of size : ");
//Serial.println(packetSizeTcp);
if (packetSizeTcp < 2) {
// Get the wrong message, clear received data
client.read();
} else {
// min size : 2 bytes (CMD + ID)
rCmd = client.read();
packetSizeTcp--;
rID = client.read();
packetSizeTcp--;
switch (rCmd) {
case 'W': {
if (packetSizeTcp) {
rVal = client.read();
packetSizeTcp--;
WriteDataWizAPP(rID, rVal);
}
break;
}
case 'R': {
sendPacket[0] = 'W'; // Write operation
sendPacket[1] = rID; // id
sendPacket[2] = ReadDataWizAPP(rID); // Value
client.write(sendPacket, 3);
break;
}
case 'G': { // Get string, Simple message sending
if (strFromSerial.length()) { // if any,
// Send PutString message to WIZnet SmartAPP
sendPacket[0] = 'P'; // Put String
sendPacket[1] = (byte)strFromSerial.length(); // len
strFromSerial.toCharArray( &(sendPacket[2]), (sendPacket[1] + 1) ); // because of null, we use (len+1). Otherwise, last character is missing.
//strcpy(&(sendPacket[2]), "No message");
client.write(sendPacket, (sendPacket[1] + 2) );
strFromSerial = ""; // clear saved message
}
else {
// Send empty message to WIZnet IoT Tool
sendPacket[0] = 'P'; // Put String
sendPacket[1] = 0x00; // zero
client.write(sendPacket, 2 );
}
break;
}
case 'P': { // Put string
Serial.print("Message from APP >> ");
// in case of rCMD == 'P', rID is "String Length information"
for (int i = 0; (i < rID && packetSizeTcp); i++) {
Serial.write(client.read());
packetSizeTcp--;
}
Serial.println();
break;
}
default :
// Get the wrong message, clear received data
while (packetSizeTcp) {
client.read();
packetSizeTcp--;
}
break;
}
}
Ethernet.maintain();
}
}
}
void WriteDataWizAPP(byte uid, byte uval)
{
// This example can control RGB value with WIZnet IoT Tool
// So, Red = ByteUnitVal[0], Green = ByteUnitVal[1], Blue = ByteUnitVal[2]
// You can modify this fuction as your application.
if (uid < 6 ) {
ByteUnitVal[uid] = uval;
}
}
byte ReadDataWizAPP(byte uid)
{
// You can modify this fuction as your application.
if (uid < 6 ) {
return ByteUnitVal[uid];
}
return 0;
}
void RGB_NeoPixel(byte red, byte green, byte blue) {
int delayval = 50; // delay for 50ms
// For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
for (int i = 0; i < NUMPIXELS; i++) {
// pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(i, pixels.Color(red, green, blue)); // Moderately bright green color.
pixels.show(); // This sends the updated pixel color to the hardware.
delay(delayval); // Delay for a period of time (in milliseconds).
}
}
// readline function from https://hackingmajenkoblog.wordpress.com/2016/02/01/reading-serial-on-the-arduino/
int readline(int readch, char *buffer, int len) {
static int pos = 0;
int rpos;
if (readch > 0) {
switch (readch) {
case '\r': // Ignore CR
break;
case '\n': // Return on new-line
rpos = pos;
pos = 0; // Reset position index ready for next time
return rpos;
default:
if (pos < len - 1) {
buffer[pos++] = readch;
buffer[pos] = 0;
}
}
}
return 0;
}
@bjnhur
Copy link
Author

bjnhur commented Nov 22, 2018

Message structure between device and smartphone app
app download

msg1
msg2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment