Why my client does not receive data from server that is sent from interrupt function? - arduino-ide

I have to send data to the client in the interrupt function. But apparently, the client cannot receive the data. The server did get the data sent from the client but the client cannot reply back.
When I try the communication in void loop it is a success. But once I put it in the interrupt, I cannot get the data back. The data that the server has to send is simply a number which will then trigger the led at the client side. It is really helpful if someone can help me figure it out.
This is part of the server code.
void ICACHE_FLASH_ATTR detectsMovement() {
LightValue = LightSensor.GetLightIntensity();
Serial.print("Light: ");
Serial.println(LightValue);
if (LightValue < threshold )
{
Serial.println("MOTION DETECTED!!!");
analogWrite(led, 1023);
startTimer = true;
lastTrigger = millis();
WiFiClient client = server.available();
if (client) {
if (client.connected())
{
digitalWrite(ledPin, LOW); // to show the communication only
(inverted logic)
Serial.println("");
String request = client.readStringUntil('\r'); // receives the
message from the client
Serial.print("From client: "); Serial.println(request);
client.flush();
client.println("1\r"); // sends the answer to the client
digitalWrite(ledPin, HIGH);
}
client.stop(); // terminates the connection with the client
}
}
}
void setup() {
Serial.begin(115200); // only for debug
WiFi.config(ip, gateway, subnet); // forces to use the fix IP
WiFi.begin(ssid, pass); // connects to the WiFi router
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
pinMode(motionSensor, INPUT_PULLUP);
// Set motionSensor pin as interrupt, assign interrupt function and set RISING mode
attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, RISING);
server.begin(); // starts the server
pinMode(light, INPUT);
LightSensor.begin();
Serial.println("Running...");
pinMode(ledPin, OUTPUT);
pinMode(led, OUTPUT);
}
And the client code
void loop () {
client.connect(server, 80); // Connection to the server
digitalWrite(ledPin, LOW); // to show the communication only (inverted logic)
Serial.println(".");
client.println("Hello server! Are you sleeping?\r"); // sends the message to the server
String answer = client.readStringUntil('\r'); // receives the answer from the server
Serial.println("from server: " + answer);
if (answer == "1")
{
Serial.println("Success!");
analogWrite(D0, 512);
}
client.flush();4
digitalWrite(ledPin, HIGH);
delay(2000); // client will trigger the communication after two seconds
}
The client supposed to get the value '1'. I don't know what to do.

Related

Wrong format of JSON data (Arduino) to .net Azure App service, getting code 415

I would like to ask about sending data from arduino/esp to .net App service running on Azure.
I am sending JSON to API with "list" of measurements (simple JSON, Id and Value).
Over PostMan I don't have any issue, but over Arduino I am facing issue that I receive result code 415.
Data are sent in JSON.
Arduino Code:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
const char* ssid = "*******";
const char* password = "*******";
//Your Domain name with URL path or IP address with path
const char* serverName = "https://********.azurewebsites.net/api/Measurements/";
unsigned long lastTime = 0;
// Set timer to 5 seconds (5000)
unsigned long timerDelay = 5000;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());
Serial.println("Timer set to 5 seconds (timerDelay variable), it will take 5 seconds before publishing the first reading.");
}
void loop() {
//Send an HTTP POST request every 10 minutes
if ((millis() - lastTime) > timerDelay) {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED)
{
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
client->setInsecure();
HTTPClient https;
https.addHeader("Content-Type", "application/json"); // tried even "text/json"
//https.addHeader("Content-Length", "32");
https.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
https.addHeader("Host","******.azurewebsites.net");
https.addHeader("Cache-Control","no-cache");
String httpRequestData = "[{\"SensorId\": 1, \"Value\": 77.7}]";
if (https.begin(*client, serverName))
{
Serial.print("[HTTPS] POST...\n");
int httpCode = https.POST(httpRequestData);
if (httpCode > 0)
{
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] POST... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY)
{
String payload = https.getString();
Serial.println(payload);
}
else
{
Serial.printf("[HTTPS] POST... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
}
else
{
Serial.printf("[HTTPS] POST... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
https.end();
}
else
{
Serial.printf("[HTTPS] Unable to connect\n");
}
}
lastTime = millis();
}
}
Not receiving any error, just response code 415.
The HTTP 415 Unsupported Media Type client error response code indicates that the server refuses to accept the request because the payload
JSON text:
[{"SensorId": 1, "Value": 77.7}]
AppInsight:
PostMan successful request:
body of request in Postman:
And report from AppInsight:
App service:
Over PostMan I am able to reach azure and send data, but over Arduino I am not able to send data (I am able to get data, but not post)
Probably some beginner mistake.
Can someone give me hint?
Do I have wrong format of JSON?

Parsing a JSON document in an HTTP response-Arduino (Unexpected response: HTTP/1.1 301 moved permanently error)

I'm using Arduino's ethernet shield with Arduino mega to parse a JSON document in a HTTP response to read some values in the JSON file.
The JSON address is: https://api.coinbase.com/v2/prices/BTC-USD/spot.
I'm getting this error message:
Connecting...
Connected!
Unexpected response: HTTP/1.1 301 Moved Permanently
Is is that the the Arduino library doesn't have SSL capability, so it can't connect to a secure server? If it is, then I would need your help to resolve this issue.
Or perhaps I need to use another port that's related to https?
Here is my code:
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>
void setup() {
// Initialize Serial port
Serial.begin(9600);
while (!Serial) continue;
// Initialize Ethernet library
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
if (!Ethernet.begin(mac)) {
Serial.println(F("Failed to configure Ethernet"));
return;
}
delay(1000);
Serial.println(F("Connecting..."));
// Connect to HTTP server
EthernetClient client;
client.setTimeout(10000);
if (!client.connect("api.coinbase.com", 80)) {
Serial.println(F("Connection failed"));
return;
}
Serial.println(F("Connected!"));
// Send HTTP request
client.println(F("GET /v2/prices/BTC-USD/spot/response.json HTTP/1.0"));
client.println(F("Host: api.coinbase.com"));
client.println(F("Connection: close"));
if (client.println() == 0) {
Serial.println(F("Failed to send request"));
return;
}
// Check HTTP status
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
// It should be "HTTP/1.0 200 OK" or "HTTP/1.1 200 OK"
if (strcmp(status + 9, "200 OK") != 0) {
Serial.print(F("Unexpected response: "));
Serial.println(status);
return;
}
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
if (!client.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
return;
// the rest of the code related to parsing that I didn't paste for the sake the argument.
Thanks everybody.

Sending UDP packet with ESP32

I'm trying to send a UDP packet to my Milights (wifi LED bulbs via bridge) to controll them. The packets do not show up in Wireshark though.
When I change the destination ip of the UDP packet to the one of my PC then it works. I can find the packet in Wireshark then.
/*
* This sketch sends random data over UDP on a ESP32 device
*
*/
#include <WiFi.h>
#include <WiFiUdp.h>
// WiFi network name and password:
const char * networkName = "********";
const char * networkPswd = "********";
//IP address to send UDP data to:
// either use the ip address of the server or
// a network broadcast address
const char * udpAddress = "********";
const int udpPort = ********;
//Are we currently connected?
boolean connected = false;
//The udp library class
WiFiUDP udp;
byte command[27] = {0x20, 0x00, 0x00, 0x00, 0x16, 0x02, 0x62, 0x3A, 0xD5, 0xED, 0xA3, 0x01, 0xAE, 0x08, 0x2D, 0x46, 0x61, 0x41, 0xA7, 0xF6, 0xDC, 0xAF, 0xD3, 0xE6, 0x00, 0x00, 0x1E};
void setup(){
// Initilize hardware serial:
Serial.begin(115200);
//Connect to the WiFi network
connectToWiFi(networkName, networkPswd);
}
void loop(){
//only send data when connected
if(connected){
//Send a packet
udp.beginPacket(udpAddress,udpPort);
udp.write(command, 27);
udp.endPacket();
}
//Wait for 1 second
delay(1000);
}
void connectToWiFi(const char * ssid, const char * pwd){
Serial.println("Connecting to WiFi network: " + String(ssid));
// delete old config
WiFi.disconnect(true);
//register event handler
WiFi.onEvent(WiFiEvent);
//Initiate connection
WiFi.begin(ssid, pwd);
Serial.println("Waiting for WIFI connection...");
}
//wifi event handler
void WiFiEvent(WiFiEvent_t event){
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
//When connected set
Serial.print("WiFi connected! IP address: ");
Serial.println(WiFi.localIP());
//initializes the UDP state
//This initializes the transfer buffer
udp.begin(WiFi.localIP(),udpPort);
connected = true;
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
connected = false;
break;
}
}
Can somebody explain to me why I CAN send messages UDP packets to my PC and not to my Wifi bridge?

Server-Sent Event is not working- Browsers can not listen any events of Server-Sent Event

I am implementing of server-sent event(HTML5) in my project without using node.js, It is just simple webpage(another JSP page) call and i get response from it. But when i get response from it but none of method/function(onopen,onmessage or onerror) is execute...
Client Code:
if (!!window.EventSource) {
var source=new EventSource("kitAvailCall.jsp");
source.onopen = function(){
alert("Kit is not available");
source.close();
};
source.onmessage=function(event){
console.log(event.data);
alert("Kit is not available");
}
source.onerror =function(){
console.log("EventSOurce: Getting error call");
alert("Kit is not available");
}
}
Server-side code:
try{
while(true) {
Thread.sleep(15000);
String IpAddress = (String) session.getAttribute("IPName");
boolean bool;
if(IpAddress != null && ((new Date()).getTime() - session.getLastAccessedTime())/1000 > 28){
bool = sample.pingToKit((String) session.getAttribute("IPName"));
System.out.println("Long polling request: "+bool);
//if bool is false then i want to quit loop and back to browser
if(bool == false){
response.setHeader("Content-Type","text/event-stream");
response.setHeader("Cache-Control", "no-cache");
out.print("data: " + bool);
out.flush();
break;
}
}
}
}catch(Exception e){
System.out.println("Going bad CONN:"+ e);
}
I don't know much of java, but i could conjecture that you might be listening to the same controller/jsp servlet(whatever routes data in java) which you made to send as streaming.
Listen on a page other than kitavailcall.jsp. This script is meant only for streaming, use another view/html page other than kitavailcall.jsp
The thing you have to understand is, SSE is a concurrent process, you create another page and run on that page with the javascript(client code) included in that page. And your server should support multi-threading as well.

What is the equivalent of BeginRead method in Netframework v4 socket

In the netframework v2, the socket use the Invoke (BeginRead) method to call a method (example ReceiveMsg) as below:
client = new TcpClient();
client.Connect(SERVERIP, PORTNO);
data = new byte[client.ReceiveBufferSize];
SendMessage("hello\n");
client.GetStream().BeginRead(data, 0, System.Convert.ToInt32(client.ReceiveBufferSize), ReceiveMsg, null);
Will this method ReceiveMsg of socket always be in "Auto Mode" such that it will standby to receive the message broadcast by SocketServer?
or It is using System.Threading.Thread.Sleep() to make ReceiveMsg method always active so that it will be in ready mode to respond to when SocketServer broadcast message?
How to do this in Netframework v4 or 4.5 socket for this ReceiveMsg method as BeginRead() is no longer required.
Thanks.
Below is the code for socket in netframework v4 :http://msdn.microsoft.com/en-us/library/hh202858(v=vs.92).aspx (for WP mango/ Wp8)
Client.Connect();
Client.Send();
Client.Receive();
public string Receive()
{
//-- receive the reply from server
string response = "Receiving Operation Timeout";
// We are receiving over an established socket connection
if (_socket != null)
{
// Create SocketAsyncEventArgs context object
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
// Setup the buffer to receive the data
socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
// Inline event handler for the Completed event.
// Note: This even handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler(delegate(object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
// Retrieve the data from the buffer
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
}
else
{
response = e.SocketError.ToString();
}
_clientDone.Set();
});
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Receive request over the socket
_socket.ReceiveAsync(socketEventArg);
// Block the UI thread for a maximum of TIMEOUT_MILLISECONDS seconds.
// If no response comes back within this time then proceed
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
}
return response;
}