Unable to transfer data between two ESP8266 - sockets

I am trying to connect two esp 8266 (Wi-fi) module with each other one as hotspot (server) using Wifi of ESP12 E module 8266 and other is (client).I am Using Arduino IDE for programming
my server starts properly and client is connected to server but when I send data from client to server I got nothing. I google about data transfer between client and server, but nothing is there for client data transfer using Arduino coding.
Here is My code in Arduino
server side code
#include <ESP8266WiFi.h>
WiFiServer server(80); //Initialize the server on Port 80
void setup()
{
WiFi.mode(WIFI_AP); // ESP8266-12E is an AccessPoint
WiFi.softAP("11111111", "12345678"); // Provide the (SSID, password)
server.begin(); // Start the Server
Serial.begin(115200); //Start communication between the ESP8266-12E and the monitor window
IPAddress HTTPS_ServerIP= WiFi.softAPIP(); // Obtain the IP of the Server
Serial.print("Server IP is: "); // Print the IP to the monitor window
Serial.println(HTTPS_ServerIP);
}
void loop()
{
WiFiClient client = server.available();
if (!client)
{
return;
}
//Looking under the hood
Serial.println("Somebody has connected :)");
}
client side code
#include <ESP8266WiFi.h>
const char *ssid = "11111111";
const char *password = "12345678";
const char *host = "192.168.4.2";
const int httpPort = 80;
void setup()
{
Serial.begin(115200);
delay(10);
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
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());
}
void loop()
{
delay(8000);
Serial.print("connecting to ");
Serial.println(host);
WiFiClient client;
client.connect(host,httpPort);
if (!client.connect(host,httpPort))
{
Serial.println("connection failed");
return;
}
else
client.print("connected");
}
can any one suggest me how to transfer data from client to server

The Arduino ESP8266 class WiFiClient inherits from Stream, so, all stream functions are available to you. You can find documentation for that class here.
You could use readBytes, readString, or just plain read to do what you want.
Additionally, if you do plan to use HTTP, you may be interested in using the libraries ESP8266WebServer and ESP8266HTTPClient which come with your ESP8266 Arduino environment and implement a lot of this low level code you are attempting to write. You can find examples for the server here, and the client here

Related

Failure to send data from client to server in ESP-01 WiFi

Using the ESP8266WiFi library, I have two ESP-01's/ESP8266's connected over WiFi. It works perfectly when the client sends a request (all non HTML!) to the server (using port 5000 - to prevent any confusion with HTTP, FTP etc.). But I cannot get the client to receive an answer back from the server. Now, in the ESP8266WiFi library (3.0.2) there is a note that server.write() is not implemented, and that I should use server.accept() instead of server.available(); though I did not see any applicable examples using server.accept(), but I see many examples using client.print() so I try to follow those - to no avail, yet. What I am doing is the following: 1. establish connectivity to the WiFi; 2. have the client connect to the server and send two bytes to the server. 3. Do a digital write to a pin of the server-ESP8266.(this toggles a relay, which works fine) 4. write back from server to client that the digital write has been done. On the client side, after writing to the server, I run in a loop for some 10 seconds trying to receive something from the server, which never comes. Then I cycle back to the beginning, and the client asks to toggle the relay again - this runs nicely for hours.
Any insights here on what I should do differently are highly appreciated. I really want to be able to get some acknowledgement back to the client once the server has toggled the relay. Or if someone has a working example with server.accept() - I would try that too.
Client side code:
int pin_value;
uint8_t ip[4];
void setup()
{
Serial.begin(115200);
ip[0]=10;
ip[1]=0;
ip[2]=0;
ip[3]=6;
//We connect to the WiFi network
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
//Wait until connected
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.print("Client - ");
Serial.println("WiFi connected");
}
void loop(){
//Variable that we will use to connect to the server
WiFiClient client;
//if not able to connect, return.
if (!client.connect(ip, SERVER_PORT)){ return; }
// We create a buffer to put the send data
uint8_t buffer[Protocol::BUFFER_SIZE];
//We put the pin number in the buffer
// whose state we want to send
buffer[Protocol::PIN] = RELAY;
//put the current state of the pin in the send buffer
buffer[Protocol::VALUE] = pin_value;
//We send the data to the server
client.write(buffer, Protocol::BUFFER_SIZE);
// try to read the answer from the server for about 10 seconds
int nr_of_tries = 10000;
while (client.connected() && nr_of_tries > 0)
{if (client.available())
{ String line = client.readStringUntil('\n');
nr_of_tries = 0;
Serial.print("line= ");
Serial.println(line);
}
else
{delay(1);
nr_of_tries=nr_of_tries-1;
}
}
Serial.print("nr of tries= ");
Serial.println(nr_of_tries);
Serial.print("connected: ");
Serial.println(client.connected());
client.flush();
client.stop();
Serial.println(" change sent");
if (pin_value == 0)
{pin_value =1;
Serial.println("Pin_value set to 1");
}
else
{pin_value=0;
Serial.println("Pin_value set to 0");}
delay(10000);
}
Server side code:
WiFiServer server(SERVER_PORT);
void setup()
{
Serial.begin(115200); // must have the same baud rate as the serial monitor
pinMode(RELAY,OUTPUT);
digitalWrite(RELAY, LOW);
// Connect to the WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println("Server - ");
Serial.println("WiFi connected");
// Set this ESP to behave as a WiFi Access Point
// WiFi.mode(WIFI_AP);
// set SSID and Password to connect to this ESP
// WiFi.softAP(SSID, PASSWORD);
// Start the server
server.begin();
Serial.println("Server started");
// Output of the IP address
Serial.print("Use this IP to connect: ");
Serial.println(WiFi.localIP());
}
void loop()
{
// Check if there is any client connecting
WiFiClient client = server.available();
if (client)
{
//Serial.println("Client detected");
//If the client has data he wants to send us
//check for a second or so as transmission can take time
int nr_of_tries = 1000;
while(!client.available() && nr_of_tries > 0)
{ nr_of_tries=nr_of_tries-1;
delay(1);
}
if (client.available())
{
// Serial.println(" Client data");
// create a buffer to put the data to be received
uint8_t buffer[Protocol::BUFFER_SIZE];
// We put the data sent by the client in the buffer
// but do not read more than the buffer length.
int len = client.read(buffer, Protocol::BUFFER_SIZE);
// retrieve which pin number the client sent
int pinNumber = buffer[Protocol::PIN];
Serial.print("Pin Number: ");
Serial.println(pinNumber);
// retrieve the value of this pin
int value = buffer[Protocol::VALUE];
Serial.print("Value: ");
Serial.println(value);
// Set the pin indicated by the received pin number in output mode
// but only if the pin is the GPIO0 pin!
if (pinNumber == RELAY)
{ pinMode(pinNumber, OUTPUT);
// Set the pin indicated by the received pin number to the passed value
digitalWrite(pinNumber, value);
}
// tell the client that the relay has been set or reset.
size_t i;
if (value == 0) {
i=server.println("Set");
Serial.print("i= ");
Serial.println(i);
}
else {
i=server.println("Reset");
Serial.print("i= ");
Serial.println(i);
}
}
}
//Close the connection with the client
//client.stop();
}
Common definitions:
#include <ESP8266WiFi.h>
const char* ssid = "blablabla";
const char* password = "blublublu";
#define SERVER_PORT 5000
#define RELAY 0
//Protocol that the Server and Client will use to communicate
enum Protocol{
PIN, // Pin whose state you want to change
VALUE, // State to which the pin should go (HIGH = 1 or LOW = 0)
BUFFER_SIZE // The size of our protocol. IMPORTANT: always leave it as the last item of the enum
};
Solved! By changing server.println("Set"); into client.println("Set") and doing the same for the transmission of "Reset" a few lines lower in the server side code it works!

Unity TCP client: connection to a server

I have a hardware that streams data to a windows server, and I have IP and port of this server. Now I want to connect unity app as a TCP client to this server. I have tried many solutions, but still have hard time to figure out best way to do this. Any help is highly appreciated. One issue that I have with current tutorials is that most of them define a unity server and try to connect another unity app as client and mostly based on localhost. However, I just want to connect a unity app as a TCP client to a server which I have IP and port.
Warm regards,
enter image description here
First of all, at the top of your script:
using System;
using System.Net.Sockets;
Then, create an instance of TcpClient and begin the connection:
socket = new TcpClient
{
// dataBufferSize is in bytes
ReceiveBufferSize = dataBufferSize,
SendBufferSize = dataBufferSize
};
socket.BeginConnect(ip, port, ConnectCallback, socket);
In ConnectCallback():
private void ConnectCallback(IAsyncResult asyncResult)
{
socket.EndConnect(asyncResult);
if (!socket.Connected) return;
// stream is a NetworkStream you should declare somewhere
stream = socket.GetStream();
// receiveBuffer is a byte[] you should declare somewhere
receiveBuffer = new byte[dataBufferSize];
stream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveCallback, null);
}
In ReceiveCallback():
private void ReceiveCallback(IAsyncResult asyncResult)
{
try
{
int byteLength = stream.EndRead(asyncResult);
if (byteLength <= 0)
{
// Disconnect client
return;
}
// Transfer data from receiveBuffer to data variable for handling
byte[] data = new byte[byteLength];
Array.Copy(receiveBuffer, data, byteLength);
// Handle data in any way you want to
// BeginRead again so you can keep receiving data
stream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveCallback, null);
}
catch (Exception e)
{
Console.WriteLine($"Error receiving TCP data: {e.Message}");
}
}
I got this information from this tutorial.

UDP not being recieved in mono on a Raspberry pi 3

The code fragment below works happily under windows and using mono under ubuntu, but for a raspberry pi the ReceiveHandler is called for TCP but not for UDP which are broadcast messages. Any clues would be useful. I have confirmed there is no firewall and the addresses are correct, including network masks.
public void StartAsynchronousReceive()
{
m_waitFrom = DateTime.UtcNow;
if (RemoteEndPoint == null)
{
Console.WriteLine("Starting tcp async receive on " + BaseSocket.LocalEndPoint.Serialize());
// BeginReceive is used for connection orientated sockets (TCP)
BaseSocket.BeginReceive(
Buffer,
BufferOffset,
Buffer.Length - BufferOffset,
SocketFlags.None,
ReceiveHandler,
this);
}
else
{
Console.WriteLine("Starting udp async receive on " + BaseSocket.LocalEndPoint.Serialize());
// BeginReceiveFrom is used for connectionless sockets (UDP)
BaseSocket.BeginReceiveFrom(
Buffer,
BufferOffset,
Buffer.Length - BufferOffset,
SocketFlags.None,
ref RemoteEndPoint,
ReceiveHandler,
this);
}
}
private void ReceiveHandler(IAsyncResult pResult)
{
Console.WriteLine("Async ReceiveHandler called");
}

Arduino mkr1000 does not Serial print upon GET using aRest library

I'm trying to create a REST server on an arduino mkr1000. upon searching google i came upon the aRest library which handles most of the stuff i need.
aRest library documentation
So i created a sample sketch based on the guides. Here is the code:
#include < SPI.h >
#include < WiFi101.h >
#include < aREST.h >
aREST rest = aREST();
int status = WL_IDLE_STATUS;
WiFiServer restServer(80);
char ssid[] = "user"; // not actual username
char pass[] = "pass"; // not actual password
int clapMode(String data){
Serial.println("Request Recieved: " + data);
}
void setup() {
Serial.begin(115200);
rest.set_id("000");
rest.set_name("MKR1000");
rest.function("test",clapMode);
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP
network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.println();
// you're connected now, so print out the status:
printWifiStatus();
// Start server
restServer.begin();
Serial.println(F("Listening for connections..."));
}
void loop() {
WiFiClient client = restServer.available();
if (!client) {
return;
}
while(!client.available()){
delay(1);
}
rest.handle(client);
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
IPAddress subnet = WiFi.subnetMask();
Serial.print("Netmask: ");
Serial.println(subnet);
IPAddress gateway = WiFi.gatewayIP();
Serial.print("Gateway: ");
Serial.println(gateway);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
The code works mostly. Upon using POSTMAN to perform a GET the arduino is able to give the appropriate response.
Now for the part that is not working is the endpoint i just have created using this code
rest.function("test",clapMode);
upon performing a GET in postman, the arduino is able to give a response, but it should perform this code
int clapMode(String data){
Serial.println("Request Recieved: " + data);
}
but on my serial Monitor i am not getting anything.
Also i could not find on how to tailor the response of the arduino from the request. How do i it ?
Thank you very much
You have to send the request to <host>/test?params=0, not <host>/clapMode.
Furthermore, you can modify the ID and name with
rest.set_id("device ID");
rest.set_name("device name");
and add variables with
rest.variable("variable name", &variable);
The response is hard-coded into the library, therefore if you want to add/remove other stuff, you have to edit the library by yourself.

How to get the MAC adress of an access point when esp8266 is in client (station) mode?

I would like my esp8266 to retrieve the mac address of the AP it`s connected to as a client (station), following this discussion on How to get Access Point MAC adress.
Here is my code:
#include <ESP8266WiFi.h>
const char* ssid = "somrmthing";
const char* password = "somrmthing"; //
const char* host = "aubs.gear.host"; //create webserver & correct address
uint8_t MAC_array[6];
char MAC_char[18];
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(100);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
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());
int value = 0;
void loop() {
// put your main code here, to run repeatedly:
/*
* http://stackoverflow.com/questions/34078497/esp8266-wificlient-simple-http-get
*/
delay(30000);
++value;
/*
* https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino
*/
Serial.print("connecting to ");
Serial.println(host);
// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
// getting the mac address http://bbs.espressif.com/viewtopic.php?f=15&t=3102&p=10569&hilit=Access+Point+MAC+adress&sid=a68dcff311ea05ece032126d6f93902f#p10569
void wifi_handle_event_cb(System_Event_t *evt)
{
os_printf("event %x\n", evt->event);
switch (evt->event){
case EVENT_STAMODE_CONNECTED:
os_printf("connect to ssid %s, channel %d\n", evt->event_info.connected.ssid, evt->event_info.connected.channel);
os_printf("AP MAC address is %s\n", evt->event_info.connected.bssid);
break;
case ....
....
}
}
//old wrong MAC ADDRESS
// getting the mac address //Serial.println(MAC_char); - See more at: http://www.esp8266.com/viewtopic.php?f=29&t=3587#sthash.bwWPqcc6.dpuf
WiFi.macAddress(MAC_array);
for (int i = 0; i < sizeof(MAC_array); ++i){
sprintf(MAC_char,"%s%02x:",MAC_char,MAC_array[i]);
}
// We now create a URI for the request
String url = "/store.php"; // String url = "/input/";
url += "?dev_id=";
url += "BikeShare9";
url += "&hoster=";
url += MAC_char;
url += "&ip_add=";
url += WiFi.localIP();
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
// Read all the lines of the reply from server and print them to Serial
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line);
}
Serial.println();
Serial.println("closing connection");
}
For void wifi_handle_event_cb(System_Event_t *evt) I get the following error:
C:\Users\Tinotenda\Desktop\ver1.0\ver1.0.ino: In function 'void setup()':
ver1.0:48: error: a function-definition is not allowed here before '{' token
void loop() {
^
ver1.0:129: error: expected '}' at end of input
}
^
exit status 1
a function-definition is not allowed here before '{' token
How can I fix that?
Your setup()-function doesn't have it's closing bracket.
You should also place all the global variables at the top, or make them static inside the function that uses them. (ref: int value = 0 ,although I don't know what you're using the variable for)
Furthermore, avoid the user of very long delays. delay(30000)causes the ESP8266 IP-stack to behave strangely. You should better use the millis-structure:
static unsigned long lastMillis = 0;
if (millis() - lastMillis < 30 * 1000UL) {
lastMillis = millis();
//do your stuff
}
This answer should help other beginners:
Copy and pasting code without understanding the basics is never a good idea.
Basic structure of an Arduino program (=sketch)
Definitions, global vars
int value = 0;
should be placed there
SETUP
void setup(){
All one time functions, initalization routines, etc
}
LOOP
void loop(){
recuring tasks call functions from here in the above example
Call the example function like this
wifi_handle_event_cb(SomeParamToHandOver);
NEVER use delay - it stops processing for the given time
Not a good idea in server client scenarios ->
look for blink without delay in the Arduino examples for more
Never use while in here it may lead to dead locks
}
functions/modules you call from the setup or loop
void wifi_handle_event_cb(System_Event_t *evt) {
Exmple from the question
}
plus all remarks in the answer above
All beginners should start with https://www.arduino.cc/en/Tutorial/BuiltInExamples