Server/Client on same device
Posted:
Mon May 11, 2015 12:48 am
by WanaGo
Hello,
I have just recently discovered the ESP8266 and have on order about 20 modules of various sorts to experiment with.
Really loving how the Arduino IDE has a port for this now, as that makes life quite nice for what we are trying to do.
I have been reading some of the posts on this forum, and I found mention of being able to do a Server/Client setup on a single ESP8266 module, and that is exactly what I am trying to do.
For simplicity I will explain what we are trying to achieve.
Around the building we hope to have these ESP8266 modules scattered around, performing various tasks, connected to a central home/business AP Router. I need one of them to be a master (ie a Server) which they can all transmit data to, such as sensor information, and that module can do various things based on the sensor data - turn on relays, display information on an LCD etc. This part I am sure will be no problem.
I however need some of the modules which have sensors on them, to also perform a Server type roll, in the sense the master server can send information to a client and get it to perform some actions, such as turning on a relay. So each device really needs to be a Server/Client in its own right, so they can no only send out information to each other, but receive it too, based on specific situations.
I am just wondering if anyone has attempted this, in any capacity.
I am just starting to look at some code examples, and starting off looking at the WiFiClient and WiFiWebServer examples that ship with the ESP8266 Arduino module in the Arduino IDE. Is it this type of Server I need, and this type of Client?
Whats the difference between the WiFiWebServer example, and the ESP8266 Webserver example?
I will continue to look and try and figure this out. I am very new to using WiFi on microcontrollers, and have never had to think about how it works before.
As I understand it, I would start with the server example and then basically merge in relevant parts of the client, to form the Server/Client module code. I can then have one client talking to another server, then that same one also being a client talking to the master server etc.
Any help on what example does what, and a poke in the right direction would be appreciated. I should be fine to figure out the code once I understand what example is actually doing what function and what the difference is.
Regards
WanaGo
Re: Server/Client on same device
Posted:
Fri May 15, 2015 5:49 am
by juanmol
(sorry WanaGo this is not the answer your are waiting for)
Please, we really need a example with server/client. I think it's needed for home automation systems, with the examples i can do:
1- using a button/switch conmute a led
2- using the server at 8266, turn on/off the led
3- every time the leds changes, send the status via GET or POST to another server (daemon+sql)
i think this example needs to be in the fisrt samples.
Re: Server/Client on same device
Posted:
Fri May 15, 2015 8:22 am
by j0hncc
WanaGo, MQTT protocol is being used widely and effectively for this . Including by me. Very easy. Just google "esp8266 MQTT".
Also node-red.
Cheers,
John
Re: Server/Client on same device
Posted:
Tue May 19, 2015 4:42 pm
by hakha4
I've made a sketch with a client/server solution. Listening on one TCP port and sending on another. Works perfect on a node sending DS1820 data . I use a Raspberry Pi2 as 'gateway for the ESP nodes.
Below is a sketch example, Needs to be tidy up but maybe someone can find it useful as a template. It's far from finished but works. Check code in main loop for recieving and in void Check_Temp() for sending data
Code: Select all
/*
/////////////////////// DS1820 Node //////////////////////////////////////////////
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <WiFiServer.h>
#ifdef __cplusplus
extern "C" {
#endif
char *dtostrf (double val, signed char width, unsigned char prec, char *sout);
#ifdef __cplusplus
}
#endif
void* __dso_handle;
const char* ssid = "xxxxx";
const char* password = "yyyyy";
unsigned long counter;
unsigned long interval = 10000;
boolean timedOut = false;
boolean busy = false;
String InputString;
int numberOfDevices; // Number of temperature devices found
DeviceAddress tempDeviceAddress; // variable to store a found device address (1-Wire)
//------------------ Setup Temp. sensors ---------------------------
// Setup a oneWire (ON PIN 2) instance to communicate with any OneWire devices
#define ONE_WIRE_BUS 2//check what pin to use!!!!!!!!!
#define TEMPERATURE_PRECISION 9
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
//------------------ END 1-wire setup Setup ---------------------------
#define HOST_PORT (32340)
IPAddress Piserver(192,168,1,4);// Pi Gateway
WiFiClient client;
WiFiServer Server(13000);
String StringToSend;
#define BOARD_NO 20
unsigned int BOARD_ID = 11020;
String Node_Id = "11020";
String Node_description = "DS1820 Temperature sensor";
String Node_sketchname = "ESP_generic_1820";
String Node_compiledate = "2015-05-07";
void setup(void)
{
Serial.begin(115200);
delay(1000);
// connecting to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
delay(1000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
// print node data
Serial.println("######################################");
Serial.print("#### ");
Serial.print("Node ID : ");
Serial.print(Node_Id);
Serial.println(" ###");
Serial.println("######################################");
Serial.println(Node_description);
Serial.println(Node_sketchname);
Serial.println(Node_compiledate);
delay(3000);
// Start up Dallas 1-Wire library
sensors.begin();
// Grab a count of devices on the wire
numberOfDevices = sensors.getDeviceCount();
OneWire_report();
Server.begin();
delay (1000);
}
void loop(void)
{
// ********** SERVER *************************
//Server
client = Server.available();
if (client) {
busy = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
//read char by char
if (InputString.length() < 100) {
//store characters to string
InputString += c;
}
//if request has ended
if (c == '\n') {
//EVALUATE INVOMING DATA
//check if it's a command to ALL Nodes - '$'
if(InputString.substring(0,1)=="$"){
Serial.println("for all");
eval_Radiodata (InputString.substring(1));
InputString = "";
busy = false;
}
//check if it's for me
String toEval = InputString.substring(5);
Serial.println(toEval);
int tmpID;
char carray[6];
InputString.substring(0,5).toCharArray(carray, sizeof(carray));
tmpID = atoi(carray);
Serial.println(tmpID);
Serial.println(InputString);
if(tmpID==(11000+BOARD_ID)){
eval_Radiodata(toEval);
InputString = "";
busy = false;
}
//END EVALUATE DATA
Serial.println(InputString);
}
}
}
}
// ********** END SERVER *************************
// ************ DO JOBS EVERY X SECOND ***********
if(!busy){
if ((!timedOut) && ((millis() - counter) > interval)) {
timedOut = true; //
Serial.println("Reading Temperature sensor(s)");
//Check_Temp();
eval_Radiodata ("T");// temperature sensors
timedOut = false;
counter = millis();
}
}
// ***************************************************
}// END VOID LOOP
//----------- EVALUATE RADIO DATA -------------------------------------
void eval_Radiodata(String radioData)
{
String tmpCmd;//A,B,C,D;E etc
String tmpData="";//relaystatus etc
String tmpdata_eval;//data to be sent/evaluated in routines
unsigned int strLen;
//EVALUATE new data and take action !!!!!!!!!
tmpCmd = radioData.substring(0,1);//strip off command id
tmpData = radioData.substring(1,radioData.length());//strip off data part
// just for debug
// Serial.println(F("Incoming DATA : "));
// Serial.println(radioData);
strLen = tmpData.length();
// Serial.println("Incoming DATA : ");
// Serial.println(radioData);
/////////////////////////////////////////////////////////////////////////
/////// Dispatch the command to the correct handler. /////////////
/////////////////////////////////////////////////////////////////////////
//----------------- Check Temp. sensors ---------------------------------------------------
if (tmpCmd.equals("T"))
{
if(numberOfDevices > 0)// check temps if there were sensors detected
{
Serial.println("Reading Temperature sensor(s)");
Check_Temp();
}
else
{
Serial.println("No Temperature sensor(s) connected");
}
}
//----------------- END Check Temp. sensors ---------------------------------------------------
}
void Check_Temp()
{
String StringToSend;
String address;
char tempBuf[6];
sensors.requestTemperatures(); // Send the command to get temperature
for(int i = 0;i<numberOfDevices; i++)
{
Serial.print("Temperature for Device ");
Serial.print(i+1);
Serial.print(" : ");
float DS_temp = (sensors.getTempCByIndex(i));
dtostrf(DS_temp,5,2,tempBuf);
Serial.print(tempBuf);
Serial.println(" C'");
if(sensors.getAddress(tempDeviceAddress, i))
{
address = printAddress(tempDeviceAddress);
Serial.println(address);
Serial.println();
}
StringToSend = StringToSend + tempBuf + "!" + i + "!" + address + "*";
address="";
}
//send to MLServer trough Raspberry Pi gateway
if (client.connect(Piserver, HOST_PORT)) {
Serial.print("TCP connected on Port : ");
Serial.println(HOST_PORT);
/////////////// send data //////////////////////////////////////////////
if(numberOfDevices > 0){
client.print("Scripting|From_WiFi~Eval~" + Node_Id + "~" + String(numberOfDevices) + "~" + StringToSend + "~T" + "\r\n") ;
}
else {
client.print("Scripting|From_WiFi~Eval~" + Node_Id + "~" + "0" + "~" + "Sensor ERROR" + "~T" + "\r\n") ;
}
////////////////////////////////////////////////////////////////////////
Serial.print("Sending : ");
Serial.print(StringToSend);
Serial.println();
}
}
//--------------------END Read DS18b20 sensors and send to MLServer -----------------------------------
void OneWire_report()
{
Serial.println("-------------------------------------------");
Serial.print("Locating 1-wire devices...");
Serial.print("Found ");
Serial.print(numberOfDevices, DEC);
Serial.println(" devices.");
// report parasite power requirements
Serial.print("Parasite power is: ");
if (sensors.isParasitePowerMode()) Serial.println("ON");
else Serial.println("OFF");
Serial.println("-------------------------------------------");
// Loop through each device, print out address
for(int i = 0;i<numberOfDevices; i++)
{
// Search the wire for address
if(sensors.getAddress(tempDeviceAddress, i))
{
//Serial.print("Found device ");
//Serial.print(i, DEC);
//Serial.print(" with address: ");
//printAddress(tempDeviceAddress);
//Serial.println();
//Serial.print("Setting resolution to ");
//Serial.println(TEMPERATURE_PRECISION, DEC);
// set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions)
sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);
// Serial.print("Resolution actually set to: ");
//Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
//Serial.println();
}else{
//Serial.print("Found ghost device at ");
//Serial.print(i, DEC);
//Serial.print(" but could not detect address. Check power and cabling");
}
}
}
//-------------------- END Find DS18b20 sensors on 1-Wire net -----------------------------------
//-------------------- Print DS18b20 sensors temp to console -----------------------------------
// function to print the temperature for a device
String printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
char tempF[6]; // buffer for temp incl. decimal point & possible minus sign
dtostrf(tempC, 6, 2, tempF); // Min. 6 chars wide incl. decimal point, 2 digits right of decimal
return tempF;
//Serial.print("Temp C: ");
Serial.print(tempF);
}
// function to print a device address
String printAddress(DeviceAddress deviceAddress)
{
String tmpadr;
for (uint8_t i = 0; i < 8; i++)
{
if (deviceAddress[i] < 16) tmpadr = tmpadr + ("0");
// Serial.print(deviceAddress[i], HEX);
tmpadr = tmpadr + String(deviceAddress[i], HEX);
}
return tmpadr;
}
//-------------------- END Print DS18b20 senos temp to console -----------------------------------