Why ESP32 with static IP address can't connect to internet but can ping normally? - httprequest

I have connected ESP32 to WIFI, but this WIFI must fix IP address, Gateway, Subnet mask, DNS and MAC. So, I assign them and test with two codes. The first one is with a ping library and the 2nd one is with http request to Google.
Ping code
#include <WiFi.h>
#include <ESP32Ping.h>
const char* ssid = "test";
const char* password = "test";
IPAddress staticIP(172, 16, 116, 90);
IPAddress gateway(172, 16, 116, 254);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(172, 17, 10, 1);
void setup(){
Serial.begin(115200);
if (WiFi.config(staticIP, gateway, subnet, dns, dns) == false) {
Serial.println("Configuration failed.");
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print("Connecting...\n\n");
}
Serial.print("Local IP: ");
Serial.println(WiFi.localIP());
Serial.print("Subnet Mask: ");
Serial.println(WiFi.subnetMask());
Serial.print("Gateway IP: ");
Serial.println(WiFi.gatewayIP());
Serial.print("DNS 1: ");
Serial.println(WiFi.dnsIP(0));
Serial.print("DNS 2: ");
Serial.println(WiFi.dnsIP(1));
bool success = Ping.ping("www.google.com", 3);
if(!success){
Serial.println("\nPing failed");
return;
}
Serial.println("\nPing successful.");
}
void loop(){}
Http request code
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "test";
const char* password = "test";
IPAddress staticIP(172, 16, 116, 90);
IPAddress gateway(172, 16, 116, 254);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(172, 17, 10, 1);
void setup() {
Serial.begin(115200);
if (WiFi.config(staticIP, gateway, subnet, dns, dns) == false) {
Serial.println("Configuration failed.");
}
delay(4000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
Serial.println("MAC address: ");
Serial.println(WiFi.macAddress());
}
void loop() {
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin("www.google.com"); //Specify the URL
int httpCode = http.GET(); //Make the request
if (httpCode > 0) { //Check for the returning code
String payload = http.getString();
Serial.println(httpCode);
}
else {
Serial.println("Error on HTTP request");
}
http.end(); //Free the resources
} else {
Serial.println("WiFi lost");
}
delay(10000);
}
After I tried, output of the first one is working normally. But the 2nd one seems like it can connect to Wi-Fi only one time but can't make request after that it lost connection. I so confused pls help.
It can't connect via mqtt too.
Output 1st code
Output 2nt code

Related

400 BAD REQUEST while sending an HTTP request using wamp localhsot

I am a student doing an internship as part of my college course, and I'm having a problem with using WAMP during sending an HTTP request.
I'm working on an RFID project with nodemcu8266 using arduino IDE, and I've to scan the tags and send the ID (ID of the card or the tag that the rfid scans) into my website using WAMP localhost server.
But after compiling the code I receive that problem '400 BAD REQUEST AS IT SHOWN BELOW'
here's my code for Arduino IDE:
//*******************************libraries********************************
//RFID-----------------------------
#include <SPI.h>
#include <MFRC522.h>
//NodeMCU--------------------------
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
//************************************************************************
#define SS_PIN D2 //D2
#define RST_PIN D1 //D1
//************************************************************************
`MFRC522 mfrc522(SS_PIN, RST_PIN);` // Create MFRC522 instance.
//************************************************************************
/* Set these to your desired credentials. */
const char *ssid = "..";
const char *password = "Nsssss*";
const char* device_token = "115f2dbcafdb111d ";
//************************************************************************
String URL = "http://192.168.1.105/rfidattendance/getdata.php"; //computer IP or the server domain
String getData, Link;
String OldCardID = "";
unsigned long previousMillis = 0;
//************************************************************************
void setup() {
delay(1000);
Serial.begin(115200);
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
//---------------------------------------------
connectToWiFi();
}
//************************************************************************
void loop() {
//check if there's a connection to Wi-Fi or not
if(!WiFi.isConnected()){
connectToWiFi(); //Retry to connect to Wi-Fi
}
//---------------------------------------------
if (millis() - previousMillis >= 15000) {
previousMillis = millis();
OldCardID="";
}
delay(50);
//---------------------------------------------
//look for new card
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;//got to start of loop if there is no card present
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;//if read card serial(0) returns 1, the uid struct contians the ID of the read card.
}
String CardID ="";
for (byte i = 0; i < mfrc522.uid.size; i++) {
CardID += mfrc522.uid.uidByte[i];
}
//---------------------------------------------
if( CardID == OldCardID ){
return;
}
else{
OldCardID = CardID;
}
//---------------------------------------------
// Serial.println(CardID);
SendCardID(CardID);
delay(1000);
}
//************send the Card UID to the website*************
void SendCardID( String Card_uid ){
Serial.println("Sending the Card ID");
if(WiFi.isConnected()){
HTTPClient http; //Declare object of class HTTPClient
//GET Data
getData = "?card_uid=" + String(Card_uid) + "&device_token=" + String(device_token); // Add the Card ID to the GET array in order to send it
//GET methode
Link = URL + getData;
http.begin(Link); //initiate HTTP request //Specify content-type header
int httpCode = http.GET(); //Send the request
String payload = http.getString(); //Get the response payload
// Serial.println(Link); //Print HTTP return code
Serial.println(httpCode); //Print HTTP return code
Serial.println(Card_uid); //Print Card ID
Serial.println(payload); //Print request response payload
if (httpCode == 200) {
if (payload.substring(0, 5) == "login") {
String user_name = payload.substring(5);
// Serial.println(user_name);
}
else if (payload.substring(0, 6) == "logout") {
String user_name = payload.substring(6);
// Serial.println(user_name);
}
else if (payload == "succesful") {
}
else if (payload == "available") {
}
delay(100);
http.end(); //Close connection
}
}
}
//********************connect to the WiFi******************
void connectToWiFi(){
WiFi.mode(WIFI_OFF); //Prevents reconnection issue (taking too long to connect)
delay(1000);
WiFi.mode(WIFI_STA);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
delay(1000);
}
//=======================================================================
And the OUTPUT is:
16:28:00.789 -> Connecting to ..
16:28:01.398 -> .......
16:28:05.195 -> Connected
16:28:05.195 -> IP address: 192.168.1.103
16:28:08.101 -> Sending the Card ID
16:28:08.101 -> 400
16:28:08.101 -> 511749228
16:28:08.101 -> <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
16:28:08.101 -> <html><head>
16:28:08.101 -> <title>400 Bad Request</title>
16:28:08.101 -> </head><body>
16:28:08.101 -> <h1>Bad Request</h1>
16:28:08.101 -> <p>Your browser sent a request that this server could not understand.<br />
16:28:08.101 -> </p>
16:28:08.148 -> <hr>
16:28:08.148 -> <address>Apache/2.4.51 (Win64) PHP/7.4.26 Server at localhost Port 80</address>
16:28:08.148 -> </body></html>
16:28:08.148 ->

UDP directed broadcast (WinSock2) failure

Let me start by saying this is my first foray into the world of C after 20+ years of assembly programming for PLCs and MicroControllers.
I'm trying to send a UDP datagram to the network broadcast address, in this particular case, 192.168.1.255.
The error I'm getting is a bind failure with error code 10049 (from WSAGetLastError()). As you can see from the attached code, I've created the socket, populated sockaddr_in, and setsockopt() to SO_BROADCAST.
For the life of me I can't figure out what I'm doing wrong and any pointers would be gratefully received.
iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
if (iResult != NO_ERROR)
{
WSAErrorString("WSAStartup for TX failed");
return(-1);
}
XPLMDebugString("UDP Server: WSAStartup TX complete.\n");
if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
WSAErrorString("UDP Server: Could not create BECN socket");
return(-1);
}
// setup the sockaddr_in structure
//
si_beacon.sin_family = AF_INET;
si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");
si_beacon.sin_port = htons(_UDP_TX_PORT);
// setup to broadcast
//
char so_broadcast_enabled = '1';
if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
WSAErrorString("Error in setting Broadcast option");
closesocket(BeaconSocket);
return(-1);
}
// bind our socket
//
if (bind(BeaconSocket, (struct sockaddr *)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
{
char buf[256];
WSAErrorString("Bind to socket for UDP beacon failed");
sprintf(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
XPLMDebugString(buf);
return(-1);
}
// start the UDP beacon
//
udp_becn_thread_id = CreateThread(NULL, 0, BeaconThread, NULL, 0, NULL);
if (!udp_becn_thread_id) {
WSAErrorString("UDP Server: Error starting UDP Beacon");
return (-1);
}
XPLMDebugString("UDP Server: bind complete. beacon ACTIVE.\n");
return(0);
The issue is the IP address itself.
I copied the code to my computer (changed it a bit to get it to compile) and I got the error:
UDP Server: WSAStartup TX complete.
Bind to socket for UDP beacon failed
Port 47977, address 192.168.1.255
I then changed the line:
si_beacon.sin_addr.s_addr = inet_addr("192.168.1.255");
To
si_beacon.sin_addr.s_addr = inet_addr("192.168.0.127");
And when I ran it again, everything worked:
UDP Server: WSAStartup TX complete.
Done successfully
The issue is that the "bind" address needs to be your computers address on the local network. Not the remote client.
Another alternative is to use the address:
si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");
which binds to all network interfaces on the computer at once.
For reference, here's the version of the code that I used:
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <WinSock2.h>
#include <WS2tcpip.h> // For inet_pton
#pragma comment(lib, "ws2_32.lib")
int main()
{
{
WSADATA wsaTxData;
memset(&wsaTxData, 0, sizeof(WSADATA));
const int iResult = WSAStartup(MAKEWORD(2, 2), &wsaTxData);
if (iResult != NO_ERROR)
{
printf("%s", "WSAStartup for TX failed.\n");
return -1;
}
printf("%s", "UDP Server: WSAStartup TX complete.\n");
}
SOCKET BeaconSocket;
memset(&BeaconSocket, 0, sizeof(SOCKET));
if ((BeaconSocket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
printf("%s", "UDP Server: Could not create BECN socket\n");
return -1;
}
// setup the sockaddr_in structure
//
sockaddr_in si_beacon;
memset(&si_beacon, 0, sizeof(sockaddr_in));
si_beacon.sin_family = AF_INET;
si_beacon.sin_addr.s_addr = inet_addr("0.0.0.0");
const unsigned short port_num = 0xbb69;
si_beacon.sin_port = htons(port_num);
// setup to broadcast
//
char so_broadcast_enabled = '1';
if (setsockopt(BeaconSocket, SOL_SOCKET, SO_BROADCAST, &so_broadcast_enabled, sizeof(so_broadcast_enabled)) == SOCKET_ERROR) {
printf("%s", "Error in setting Broadcast option\n");
closesocket(BeaconSocket);
return(-1);
}
// bind our socket
//
if (bind(BeaconSocket, (struct sockaddr*)&si_beacon, sizeof(si_beacon)) == SOCKET_ERROR)
{
char buf[256];
printf("%s", "Bind to socket for UDP beacon failed\n");
sprintf_s(buf, "Port %u, address %s\n", ntohs(si_beacon.sin_port), inet_ntoa(si_beacon.sin_addr));
printf("%s", buf);
return(-1);
}
printf("%s", "Done successfully");
return 0;
}

After each sending data packet, I add Thread.sleep(1), why does the packet loss rate of udp drop?

Udp server
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define PORT 10086
int main() {
int server_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (server_fd < 0) {
perror("create socket");
_exit(2);
}
int ret;
struct sockaddr_in s_addr;
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = htonl(INADDR_ANY);
s_addr.sin_port = htons(PORT);
ret = bind(server_fd, (struct sockaddr *) &s_addr, sizeof(s_addr));
if (ret < 0) {
perror("bind error");
_exit(2);
}
for (;;) {
struct sockaddr_in c_addr;
socklen_t c_addr_len;
char buf[100];
int ret = recvfrom(server_fd, buf, 100, 0, (struct sockaddr *) &c_addr, &c_addr_len);
if (ret < 0) {
perror("accept error");
_exit(2);
} else {
char temp[100];
char *host2 = inet_ntoa(c_addr.sin_addr);
printf("A client connect: %d, %s, %d with msg: %s.\n", c_addr.sin_port, host2, c_addr.sin_family, buf);
}
}
}
Server listen on 10086, recvfrom a udp data packet, print client IP, port and data.
And here is client code:
public static void main(String[] args) throws IOException {
String server = "192.168.1.5";
DatagramSocket ds = new DatagramSocket();
byte[] data = "Hello".getBytes();
DatagramPacket p = new DatagramPacket(data, data.length);
p.setAddress(InetAddress.getByName(server));
p.setPort(10086);
ds.send(p);
data = "world".getBytes();
p = new DatagramPacket(data, data.length);
p.setAddress(InetAddress.getByName(server));
p.setPort(10086);
ds.send(p);
}
After run client, I get server output(tested several times, same output)
A client connect: 38394, 192.168.1.2, 2 with msg: Hello.
After I add Thread.sleep(1); after send "Hello" to server.
public static void main(String[] args) throws IOException, InterruptedException {
DatagramSocket ds = new DatagramSocket();
byte[] data = "Hello".getBytes();
DatagramPacket p = new DatagramPacket(data, data.length);
String server = "192.168.1.5";
p.setAddress(InetAddress.getByName(server));
p.setPort(10086);
ds.send(p);
Thread.sleep(1);
data = "world".getBytes();
p = new DatagramPacket(data, data.length);
p.setAddress(InetAddress.getByName(server));
p.setPort(10086);
ds.send(p);
}
After run client, I get server output(tested several times, same output)
A client connect: 38394, 192.168.1.2, 2 with msg: Hello.
A client connect: 38394, 192.168.1.2, 2 with msg: world.
I checked it with Wireshark and it's OK.
I also checked socket read buffer and it's OK.
So why is there packet loss here? There should be no buffer overflow, and the network environment is not that bad. Is there any other reason for UDP packet loss?
Thanks in advance.

UDP STM32- Error: Destination host unreachable

I am trying to establish UDP communication in the stm32 NUCLEO-F746ZG board. But I'm not able to ping. Getting the message as "Destination host unreachable." The program not going inside udp_echoserver_receive_callback() function.
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_LWIP_Init();
while (1)
{
MX_LWIP_Process();
}
}
void udp_echoserver_init(void)
{
struct udp_pcb *upcb;
err_t err;
upcb = udp_new();
if (upcb)
{
ip_set_option(upcb, SOF_BROADCAST);
err = udp_bind(upcb, IP_ADDR_ANY, 80);
if(err == ERR_OK)
{
udp_recv(upcb, udp_echoserver_receive_callback, NULL);
}
else
{
udp_remove(upcb);
}
}
}
void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
pc = (char*)p->payload;
pbuf_free(p);
}

Trouble with Sending HTTP 1.1 GET request

I am trying to use PubNub to publish a message to a channel but I always get "Connection Failed!".
I know the structure of a publish URL is the following:
http://pubsub.pubnub.com/publish/<PUB-KEY>/<SUB-KEY>/0/<CHANNEL>/0/%22<MESSAGE>%22
I have tested the URL on Google Chrome and it works just fine.
The following is a C flavored code is running on an Arduino UNO + Adafruit HUZZAH CC3000 WIFI Breakout. This is not an Arduino hardware question per se, because I believe there is nothing wrong with my circuit. My issue is with the structure of the HTTP GET request created using Adafruit CC3000 Library.
I am having to go with sending a GET rather than using PubNub Arduino Library because it doesn't seem to support CC3000 WIFI module. They have a JSON WIFI and Ethernet examples but both do not communicate with the CC3000 WIFI module.
char PUBKEY[] = "XXXXXXX";
char SUBKEY[] = "XXXXXXX";
Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
if (client.connected())
{
client.print("GET /publish/");
client.print(PUBKEY);
client.print("/");
client.print(SUBKEY);
client.print("/0/");
client.print("MyPubChannel"); // Channel Name
client.print("/0/%22");
client.print("Hello World from Arduino!"); // Msg to publish
client.print("%22");
client.println(" HTTP/1.1");
client.print("Host: ");
client.println("pubsub.pubnub.com");
client.println();
}
else
{
Serial.println(F("Connection failed"));
}
I have read this page and understood that a correct GET request would be of the form:
GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org
I am pretty sure there is something wrong with my GET request. Can anyone look at this and provide ANY hints as to what could be going wrong?
I am finally able to connect to PubNub using the code below.
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin!
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
#define WLAN_SSID "XXXWifi"
#define WLAN_PASS "XXX"
#define WLAN_SECURITY WLAN_SEC_WPA2
#define IDLE_TIMEOUT_MS 3
uint32_t ip;
// PubNub Setup
#define WEBSITE "pubsub.pubnub.com"
#define WEBPAGE "/publish/"
char PUBKEY[] = "pub-XXXX";
char SUBKEY[] = "sub-XXXX";
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT, SPI_CLOCK_DIVIDER); // you can change this clock speed
Adafruit_CC3000_Client www;
void setup(void)
{
Serial.begin(115200);
/* Initialize the module */
Serial.print(F("\n Initializing WIFI Adapter..."));
if (!cc3000.begin())
{
Serial.println(F("Couldn't begin()! Check your wiring?"));
while(1);
}
Serial.print(F("Ready!\n"));
Serial.print(F("Connecting to [")); Serial.print(WLAN_SSID);
Serial.print(F("]..."));
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while(1);
}
Serial.print(F("Connected!\n"));
//Wait for DHCP to complete
Serial.print(F("Waiting for DHCP..."));
while (!cc3000.checkDHCP())
{
delay(100); // ToDo: Insert a DHCP timeout!
}
Serial.print(F("Done!\n"));
Serial.print(F("Resolving PubNub..."));
ip = 0;
// Try looking up the website's IP address
while (ip == 0) {
if (! cc3000.getHostByName(WEBSITE, &ip)) {
Serial.println(F("Couldn't resolve!"));
}
delay(500);
}
Serial.print(F("Resolved!\n"));
www = cc3000.connectTCP(ip, 80);
for(int i=0;i<=50;i++)
{
char buffer[4];
dtostrf(i, 4, 0, buffer);
Publish("ch2", buffer);
}
/* You need to make sure to clean up after yourself or the CC3000 can freak out */
/* the next time your try to connect ... */
Serial.println(F("\n\nDisconnecting"));
www.close();
cc3000.disconnect();
}
void loop(void)
{
delay(1000);
}
void Publish(char* CH, char* MSG)
{
if (www.connected()) {
www.fastrprint(F("GET "));
www.fastrprint(WEBPAGE);
www.fastrprint(PUBKEY);
www.fastrprint(F("/"));
www.fastrprint(SUBKEY);
www.fastrprint(F("/0/"));
www.fastrprint(CH);
www.fastrprint(F("/0/%22"));
www.fastrprint(MSG);
www.fastrprint(F("%22"));
www.fastrprint(F(" HTTP/1.1\r\n"));
www.fastrprint(F("Host: "));
www.fastrprint(WEBSITE);
www.fastrprint(F("\r\n"));
www.fastrprint(F("\r\n"));
www.println();
} else {
Serial.println(F("Connection failed"));
return;
}
//Read data until either the connection is closed, or the idle timeout is reached.
unsigned long lastRead = millis();
while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
while (www.available()) {
char c = www.read();
//Serial.print(c);
lastRead = millis();
}
}
}
char* clean(char* MSG)
{
return MSG;
}