Send get request with arduino to ASP.NET webservice - asp.net

I created a webservices in ASP .NET, that i published on azure, with this function
public string GetObject(int id)
{
return ("it is a test !");
}
when i enter the right URL, it works.
But when i try to send the request with arduino (based on ethernetclient example), it does not work.
the arduino code :
#include "Arduino.h"
#include <SPI.h>
#include <WiFlyHQ.h>
#include <Ethernet.h>
#include <SoftwareSerial.h>
WiFly wifly;
char ssid[] = "myssid";
char password[] = "mypass";
void setup() {
Serial.begin(9600);
wifly.begin(&Serial, NULL);
if (!(wifly.setSSID(ssid))) {
Serial.println("Fail to set ssid");
}
/* if (!(wifly.setKey(password))) {
Serial.println("Fail to set passPhrase");
} */
if (!(wifly.setPassphrase(password))) {
Serial.println("Fail to set passPhrase");
}
wifly.enableDHCP();
if (wifly.join()) {
Serial.println("Joined wifi network");
} else {
Serial.println("Failed to join wifi network");
}
if (wifly.open(myurl.azurewebsites.net)) {
wifly.println("GET /api/object/123 HTTP/1.0");
wifly.println("");
}
else
Serial.println("Connection failed");
}
void loop() {
if (client.available()) {
char c = client.read();
Serial.print(c);
}
}
The connection to the ssid works. But it blocks on wifly.open(). But, if I put wifly.open("search.yahoo.com") and then wifly.write("GET /search?p=50+km+in+miles HTTP/1.0"), ALL WORKS !
Do you know why ?
Thanks for your help.

How does EthernetClient get connected with WiFly? I don't see any calls that connect them. I have done some playing with a WiFly module but I don't see how you use EthernetClient with it.
The WiFly module is the network connection and is accessed via serial. Wouldn't you need to make the request though it, handle the responses with serial processing?

Related

ESP32: Send a simple TCP Message and receive the response

I want to do the same request as with the netcat "nc" command on my computer with an ESP32:
Computer:
$ nc tcpbin.com 4242
Test
Test
What I've tried so far:
Create a wifi client and listen to an answer:
Connect to a tcp server
write a message
wait and read the answer
#include <Arduino.h>
#include <WiFi.h>
WiFiClient localClient;
const char* ssid = "...";
const char* password = "...";
const uint port = 4242;
const char* ip = "45.79.112.203"; // tcpbin.com's ip
void setup() {
Serial.begin(115200);
Serial.println("Connect Wlan");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(WiFi.localIP());
}
void loop() {
sendRequest();
delay(200);
}
void sendRequest() {
if(!localClient.connected()) {
if (localClient.connect(ip, port)) {
Serial.println("localClient connected");
localClient.write('A'); //Single char
Serial.println("msg sent");
}
}
if(localClient.connected()) {
Serial.println("Start reading");
if (localClient.available() > 0) {
char c = localClient.read();
Serial.print(c);
}
Serial.println("Stop reading");
}
}
I'm pretty sure that I misunderstood something of the tcp concept during the implementation. However, after various approaches and trying other code snippets, I can't come up with a solution.
thank you in advance
regards
Leon
There are several issues with your code.
If you test nc, you will notice that the server will not acknowledge back until your press 'return'. You are sending a single byte without termination in your code, so the server is waiting for subsequent data. To terminate the data, you need to send a '\n', or instead of using client.write('A'), use client.println('A').
A network response take time, your current code expecting immediate response without waiting with if (localClient.available() > 0).
Here is the code that will work:
void sendRequest() {
if (localClient.connect(ip, port)) { // Establish a connection
if (localClient.connected()) {
localClient.println('A'); // send data
Serial.println("[Tx] A");
}
while (!localClient.available()); // wait for response
String str = localClient.readStringUntil('\n'); // read entire response
Serial.print("[Rx] ");
Serial.println(str);
}
}

Can't connect ESP32 to MQTT

I have been trying to connect my ESP32 with HiveMQ MQTT broker url. It connects when I use free public MQTT broker like broker.hivemq.com, but when I use my url which I got after registering in HiveMQ, it doesn't connect. It returns error with code 2.
I have used this MQTT broker url with windows MQTT client app and it works fine but it doesn't work with ESP32.
#include <WiFi.h>
#include <PubSubClient.h>
// WiFi
const char *ssid = "********"; // Enter your WiFi name
const char *password = "********"; // Enter WiFi password
// MQTT Broker
const char *mqtt_broker = "591c2cacc87d4e248d106212ae6e0d4f.s2.eu.hivemq.cloud";
const char *topic = "esp32/test";
const char *mqtt_username = "*******";
const char *mqtt_password = "*******";
const int mqtt_port = 8883;
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
// Set software serial baud to 115200;
Serial.begin(115200);
// connecting to a WiFi network
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
//connecting to a mqtt broker
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
while (!client.connected()) {
String client_id = "esp32-client-";
client_id += String(WiFi.macAddress());
Serial.printf("The client %s connects to the public mqtt broker\n", client_id.c_str());
if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
Serial.println("Public emqx mqtt broker connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
// publish and subscribe
client.publish(topic, "Hi EMQ X I'm ESP32 ^^");
client.subscribe(topic);
}
void callback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char) payload[i]);
}
Serial.println();
Serial.println("-----------------------");
}
void loop() {
client.loop();
}
In the comments, #hcheung said:
When you use MQTT over TLS (port 8883), you need to use WiFiClientSecure.h and add the root CA of broker.hivemq.com to your sketch. Refer to WiFiClientSecure on how to do it.
You can get the root CA of your HiveMQ broker with the following OpenSSL method:
openssl s_client -connect hivemq-broker-host:8883 -showcerts
Change hivemq-broker-host with your MQTT host.
Using a combination of Farhan's example and a few other examples I found elsewhere, I was able to get this to work.
First, open a terminal run the command from Johnny Boy's answer (This assumes you have openssl installed. If not, install it.
openssl s_client -connect YOUR_URL.hivemq.cloud:8883 -showcerts
You'll get three certificates. They look like this
-----BEGIN CERTIFICATE----- MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
...Lots more characters that I'll omit for brevity...
-----END CERTIFICATE-----
The third certificate is the one you want. Copy this certificate out of your terminal (including the BEGIN and END CERTIFICATE parts). Paste the cert into your ESP32 code as a const char variable, such as:
const char *ROOT_CERT = "-----BEGIN CERTIFICATE-----\n"
"MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/\n"
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n"
... etc..
Using the WiFiClientSecure library mentioned in the comments, use the setCACert function to utilize your certificate. The rest of the code looks pretty close to what Farhan had. In my example, a few of the variables, including the ROOT_CERT variable from above, were defined in another file (WifiCredentials.h):
#include <PubSubClient.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include "WifiCredentials.h"
#include <WiFiClientSecure.h>
*********/
Helpful References:
* https://randomnerdtutorials.com/esp32-web-server-arduino-ide/
*
*********/
WiFiClientSecure wifiClient;
PubSubClient mqttClient(wifiClient);
char *mqttServer = "YOUR_URL.hivemq.cloud";
int mqttPort = 8883;
const char *mqtt_password = "password_I_setup_at_hivemq";
const char *mqtt_username = "username_I-setup_at_hivemq";
void setup() {
Serial.begin(9600);
// Connect to Wi-Fi network
Serial.print("Connecting to ");
Serial.println(WifiSSID);
WiFi.begin(WifiSSID, WifiPassword);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("...Still Connecting");
}
Serial.println("");
Serial.println("WiFi connected.");
wifiClient.setCACert(ROOT_CERT);
}
void loop(){
if (!mqttClient.connected()) {
mqttClient.setServer(mqttServer, mqttPort);
// set the callback function
mqttClient.setCallback(callback);
Serial.println("Connecting to MQTT Broker...");
while (!mqttClient.connected()) {
Serial.println("Reconnecting to MQTT Broker..");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (mqttClient.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
Serial.println("Connected to MQTT BRoker!.");
// subscribe to topic
mqttClient.subscribe("/transactions/device1");
mqttClient.publish("/transactions/device1", "testing hello");
} else {
Serial.print("failed with state ");
Serial.print(mqttClient.state());
delay(2000);
}
}
}
mqttClient.loop();
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Callback - ");
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
}
Connect a tool like MQTT Dash to your HiveMQ instance, open a serial monitor, and test your code.

Connect to a public server using pubsubclient

I am using PubSubClient library to subscribe to a server using a nodemcu. I tested the code using cloudMQTT and MQTTlens and it worked fine. In addition to that, I used MQTTlens to check mqtt connection with my pc. In there, I did not specify username and password (I kept blank) and it worked just fine. When I want to connect for a public server (ex: "tcp://11.111.111.111"), does not connect.
code for nodemcu
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "*****";
const char* password = "****";
const char* mqttServer = "****";
const int mqttPort = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected()) {
Serial.println("Connecting to MQTT...");
if (client.connect("ESP8266Client")) {
Serial.println("connected");
} else {
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
client.publish("topic1", "Hello from ESP8266_tester1");
client.subscribe("topic1");
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println("-----------------------");
}
void loop() {
client.loop();
}
the result from the serial monitor
Any suggestion is welcome
If you genuinely don't require a username and password then don't use the connect function that expects them:
...
if (client.connect("ESP8266Client")) {
...
I see you are using a fairly generic client id - ESP8266Client. Remember that all clients connecting to a broker must have a unique client id. If you depoyed this sketch to two different devices they would not both be able to connect at the same time.
The problem was with the ip I have provided. IP does not require "tcp://" part. After removing that, the code worked well.

NodeMCU 1.0 (ESP-12E Module) as a TCP server

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
const char *ssid = "ESPap";
const char *password = "thereisnospoon";
WiFiServer server(8080);
void setup() {
delay(1000);
Serial.begin(115200);
Serial.println();
Serial.print("Configuring access point...");
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
}
void loop() {
WiFiClient clie = server.available();
if(clie) {
while(clie.connected()) {
if(clie.available()) {
Serial.println(clie.read());
}
}
clie.stop();
}
}
I'm new to IoT. My goal is to start a TCP server using NodeMCU 1.0 to listen to the string sent by an Android app. The Android app is already implemented and 100% working. (Tested using AT commands with an ESP8266-01 module).
But when I upload this code to the NodeMCU it doesn't print out the strings in the Serial Monitor.
What is wrong? There is no errors showing up either.
Did you try using clie.readString() or clie.readStringUntil() instead of clie.read().

How to send a packet from tcp server to client use nodemcu(ESP8266) in arduino IDE?

In this code I wrote that the server send again what it received from client:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
WiFiServer server(8080);
WiFiClient client;
void setup()
{
initHardware();
setupWiFi();
server.begin();
}
void loop()
{
if (!client.connected()) {
// try to connect to a new client
client = server.available();
} else {
// read data from the connected client
if (client.available() > 0) {
char inChar= client.read();
String in=(String) inChar;
Serial.print(in);
server.write(inChar);
}
}
}
void setupWiFi()
{
WiFi.mode(WIFI_AP_STA);
WiFi.softAP("esp", "123456789");
// WiFi.softAP("RControl", WiFiAPPSK);
}
void initHardware()
{
Serial.begin(115200);
}
Now it receive what I send from my PC, but it doesn't send anything to me.
Why? What is wrong here?

Resources