While running the UDP example on my node mcu v3.0 I encountered the following strange problem.
If I connect both my computer and the node mcu to a WIFI-hotspot hosted by my phone everything runs perfectly (I can send udp packets from my computer via netcat to the node mcu and get an answer).
However if I switch to the WiFi-network provided by the student residence where Im living (we have to connect to the next router with corresponding ssid and password like for any other normal wifi network) the node mcu doesn't receive any packets at all (it still prints out an IP address so I guess it could connect to the network). I also tried sending udp packets from my computer to my laptop via netcat, which stills works normally.
What's going on here?
Here's the code:
/*
UDPSendReceive.pde:
This sketch receives UDP message strings, prints them to the serial port
and sends an "acknowledge" string back to the sender
A Processing sketch is included at the end of file that can be used to send
and received messages for testing with a computer.
created 21 Aug 2010
by Michael Margolis
This code is in the public domain.
adapted from Ethernet library examples
*/
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#ifndef STASSID
#define STASSID ".."
#define STAPSK ".."
#endif
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged\r\n"; // a string to send back
WiFiUDP Udp;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
Serial.printf("UDP server on port %d\n", localPort);
Udp.begin(localPort);
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.printf("Received packet of size %d from %s:%d\n (to %s:%d, free heap = %d B)\n",
packetSize,
Udp.remoteIP().toString().c_str(), Udp.remotePort(),
Udp.destinationIP().toString().c_str(), Udp.localPort(),
ESP.getFreeHeap());
// read the packet into packetBufffer
int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
packetBuffer[n] = 0;
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
}
/*
test (shell/netcat):
--------------------
nc -u 192.168.esp.address 8888
*/
EDIT: Calling a website (like google) from the node mcu works fine
Most likely you will have to add IO firewall rules.
Check This link.
Or by using PowerShell:
PS C:\> New-NetFirewallRule -DisplayName "Allow UDP 8888 over Teredo" -Direction Inbound -Action Allow -EdgeTraversalPolicy Allow -Protocol UDP -LocalPort 8888 -Program "C:\Program Files (x86)\TestIPv6App.exe"
Related
I'm trying to run the WebServer example below from the Arduino IDE using an Ethernet shield (Wiznet W5100) that is stacked on top of an Arduino Uno R3. The Ethernet shield is connected using an RJ45 cable to an Internet router. After uploading the code to the board, I see that the requested IP address (192.168.1.177) is printed to the console. The strange behavior that I'm facing here is that when I ping the IP address, I get a response indicating that the IP is reachable from my laptop. Also, I see the Tx, Rx LED lights blinking thereby indicating that the board is receiving the ping msgs and replying to them. This means that the board successfully received an IP address and is now connected to the LAN. However, when I try to access the same IP from the browser to receive the HTML page, no response is returned and the browser takes around 30 seconds displaying loading before returning site not reachable message. I tried different browsers from both the laptop and an iPhone connected to the same LAN with no luck in receiving the web page. Any hint as to what the problem could be is highly appreciated.
See below the code and a picture for the Ethernet shield during the experiment.
/*
Web Server
A simple web server that shows the value of the analog input pins.
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
* Analog inputs attached to pins A0 through A5 (optional)
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
modified 02 Sept 2015
by Arturo Guadalupi
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print("analog input ");
client.print(analogChannel);
client.print(" is ");
client.print(sensorReading);
client.println("<br />");
}
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disconnected");
}
}
To those who come later here for the same problem, it appeared that there was an issue with the DHCP of the Internet router. It seems like my router's DHCP was not stable when providing IP addresses for devices connected through the Ethernet ports. I replaced the router and the problem went away.
I am connecting 4 nodemcu (esp8266). 1 esp8266 is used as access point and others are connected to it.
When I send UDP packets as a broadcast message to all the esp8266 via with esp8266 as access point it is not recieved by the others however when I use a home router or even by mobile hotspot as access point, the broadcast messages are received by the other esp8266.
Also, I have posted here a part of my code that is used for UDP so there may be some variables that you will see as undeclared but they are originally declared and the code is working when I connect it with Access Point that is not esp8266
Code For Access Point:
#include
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print("Setting soft-AP ... ");
boolean result = WiFi.softAP("ssid", "password123456");
if(result == true)
{
Serial.println("Ready");
}
else
{
Serial.println("Failed!");
}
}
void loop()
{
Serial.printf("Stations connected = %d\n",
WiFi.softAPgetStationNum());
delay(3000);
}
Code for sending UPD packet as broadcast:
unsigned int localPort = 2000;
IPAddress SendIP(192,168,43,255);
setup()
{
udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(udp.localPort());
}
loop()
{
udp.beginPacket(SendIP, 2000);
udp.write("p");
udp.endPacket();
}
Code for Recieving UDP packets:
void loop()
{
int packetSize = udp.parsePacket();
if(packetSize)
{
udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
p = packetBuffer[0];
Serial.println(p);
function();
}
Please tell me whats the problem with using esp8266 as access point to send UDP packets.
And if esp8266 can not be used please tell me any other chip that can do the work, I want to make a portable system so I cannot use the router.
The default IP address of ESP8266 router in AP mode is 192.168.244.1.
Try to change sending address to 192.168.244.255.
Context
Hello everybody. I'm working on a project where I need to send about 60 TCP sockets per second to my ESP8266 in order to change a light bulb intensity "in real time". The sockets are really small, like 5 bytes.
Hardware
Server device: NodeMCU 1.0 (ESP-12E Module)
Client device: Linux 16.04 PC sending data with Node.js
-The NodeMCU board is running the last Arduino firmware: https://github.com/esp8266/Arduino
The problem
When I send a lot of TCP packets every second, the ESP8266 wifi eventually stops working. The cpu keeps working but it won't reply any ping or TCP request.
I created a really small program just to test this bug, and here it is the wireshark output.
(192.168.1.11) -> ESP8266
(192.168.1.101) -> Linux PC
As you can see, there is a moment where the ESP8266 stops sending ACKs. Sometimes it will recover after a few seconds, sometimes it doesn't.
Here is the code I use in the ESP8266:
#include <ESP8266WiFi.h>
#define TCP_PORT 17717
#define PIN_LED 2
#define MAX_INTENSITY 255
#define MAX_PWM_FREQ 1023
WiFiServer server(TCP_PORT);
WiFiClient socket;
const char * ssid = "MyWifi";
const char * password = "MyPass";
void setLed(byte intensity) {
analogWrite(PIN_LED, (int)(intensity/(float)MAX_INTENSITY * MAX_PWM_FREQ));
}
void setup() {
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
setLed(0);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.print("Ready! IP = ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
if (server.hasClient()) {
socket = server.available();
while (socket.connected()) {
if (socket.available()) {
setLed(socket.read());
}
}
}
}
Any idea of what is going on here?
It's probably because the MAX_SOCK_NUM is 4 defined in the Ethernet.h file. So we cannot connect more than 4 TCP connections which is restricted by the small memory size of the TCP/IP stack in ESP8266 and if we exceed the fixed number the board crashes.
I am using UDP to connect two nodemcu modules. One nodemcu is wireless acces point and another nodemcu connects to access point as client.
This code sends client's IP adress to AP when client connects:
Udp.beginPacket("192.168.4.1", UDPPort);//send ip to server
char ipBuffer[20];
WiFi.localIP().toString().toCharArray(ipBuffer, 20);
Udp.write(ipBuffer);
Udp.endPacket();
Serial.println("Sent ip adress to server");
But on the server side I don't recieve this packet.
Client:
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
unsigned int UDPPort = 2390; // local port to listen on
char packetBuffer[255]; //buffer to hold incoming packet
char replyBuffer[] = "acknowledged"; // a string to send back
WiFiUDP Udp;
void setup() {
Serial.begin(115200);
WiFi.begin("Wi-Fi");
Serial.println();
Serial.print("Wait for WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: " + WiFi.localIP().toString());
Udp.begin(UDPPort);
Udp.beginPacket("192.168.4.1", UDPPort);//send ip to server
char ipBuffer[255];
WiFi.localIP().toString().toCharArray(ipBuffer, 255);
Udp.write(ipBuffer);
Udp.endPacket();
Serial.println("Sent ip adress to server");
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remoteIp = Udp.remoteIP();
Serial.print(remoteIp);
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
int len = Udp.read(packetBuffer, 255);
if (len > 0) {
packetBuffer[len] = 0;
}
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(replyBuffer);
Udp.endPacket();
}
}
Server:
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
unsigned int UDPPort = 2390; // local port to listen on
char packetBuffer[255]; //buffer to hold incoming packet
char ReplyBuffer[] = "acknowledged"; // a string to send back
WiFiUDP Udp;
void setup() {
Serial.begin(115200);
WiFi.softAP("Wi-Fi");
Udp.begin(UDPPort);
Serial.println();
Serial.println("Started ap. Local ip: " + WiFi.localIP().toString());
}
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.print("Received packet of size ");
Serial.println(packetSize);
Serial.print("From ");
IPAddress remoteIp = Udp.remoteIP();
Serial.print(remoteIp);
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
int len = Udp.read(packetBuffer, 255);
if (len > 0) {
packetBuffer[len] = 0;
}
Serial.println("Contents:");
Serial.println(packetBuffer);
// send a reply, to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();
}
}
Another thing doesn't work: If I send a packet from another device connected to AP nodemcu to client nodemcu(also connected to AP), packet is recieved, but I get no acknowledgement reply back to device.
Everything else works - If i send a packet from another device to AP nodemcu, packet is recieved and i get acknowledgement.
Also, if I connect to my home wi-fi router with client nodemcu and listen for packet from my pc, i get client's ip adress when it connects.
I got exactly the same problem. I've just solve it. Your code is almost the same as mine.
All ESP- modules can be AP and station.
That means, a ESP module has local network for itself.
In my case, client module(ESP) is station mode and server module(ESP) is SoftAP mode.
The ip of the server module is 192.168.4.9 and I set the ip of gateway is 192.168.4.1.
When client module connected to the AP of server module, the ip of client was 192.168.4.103, and then i tried to send udp packets from the client module to the AP. Nothing happened but when i send the same packet from other device such as pc it worked.
I tried to access the AP of server module on my laptop. I found a wired SSID the name was 'EPS_4510DB'. It was actually the client module's one. The gateway ip of ESP_4510DB was 192.168.4.1.
Suddenly I realised the network of client module's AP and of server module's AP is the same, and the client module(for station)'s network linked its own AP network.
In other word, the client module sent udp packets to AP's network of itself instead of one of the server module.
So i changed the ip and i was able to send udp packets to server module.
And as #Barry Bea mentioned, I think you can also disable the AP of client module by using WiFi.mode(WIFI_STA) in client module, not server module.
I hope it helps someone~
I had to change port numbers for each conected esp8266. If IP of esp was 192.168.4.2, I set port to 2302, for 192.168.4.3, I set it to 2303...
I have painstakingly been trying to trouble shoot a similar problem...
I too could not get any packages sent by my ESP8266's
I changed your line;
WiFi.softAP("Wi-Fi");
to ....
WiFi.mode(WIFI_STA);
works EVERY TIME now....with no package loss..
I'm trying to send information from the arduino board to my computer through the Wi-Fi network.
for my project's purposes it has to be a UDP connection
I use the "Send and Receive UDP String" example (http://arduino.cc/en/Tutorial/WiFiSendReceiveUDPString)
with a few changes:
#include <SPI.h>
#include <WiFi.h>
#include <WiFiUdp.h>
int status = WL_IDLE_STATUS;
char ssid[] = "itay_net"; // your network SSID (name)
char pass[] = "0527414540"; // your network password (use for WPA, or use as key for WEP)
unsigned int localPort = 50505; // local port to listen on
IPAddress remote_ip(192, 168, 1, 100);
unsigned int remote_port = 50505;
char ReplyBuffer[] = "acknowledged"; // a string to send back
WiFiUDP Udp;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while(true);
}
// attempt to connect to Wifi network:
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
// you're connected now, so print out the data:
Serial.print("You're connected to the network");
delay(10000);
printWifiStatus();
Serial.println("\nStarting connection to server...");
// if you get a connection, report back via serial:
Udp.begin(localPort);
}
void loop() {
int bite_send;
Udp.beginPacket(remote_ip, remote_port);
bite_send = Udp.write("hello");
Udp.endPacket();
Serial.println("the packet was sent");
Serial.println(bite_send);
delay(1000);
}
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);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
It compiles and connects to the network just fine.
the only problem is that I can't tell if the packet was sent because I see no trace of it on Wireshark.
I also wrote a socket on java that listens to the port (50505) and should display the message from the packet, but it didn't work either.
(I can copy the java code here but i can assure you that it is not the problem 'cause I tested it with a different java server and it worked, so the problem should be on the Arduino side)
a few details to narrow it down:
I believe the "remote ip" is correct but even if it isn't - I still should have seen it in the Wireshark, so it can't be the problem.
I should mention that the Wi-Fi shield works, I successfully sent pings and ran other examples (such as SimpleWebServerWifi).
I'm using an original Arduino Uno R3 board and an original Wi-Fi shield.
The arduino IDE is the newest version.
I updated the Wi-Fi shield with the newest update I found on GitHub.
I also ran the same "Send and Receive UDP String" code (with the necessary changes) on my Ethernet shield and it did work.
I don't know what else to try - please help.
any help will be appreciated.
Itay
I dont think you have a reply buffer packet. google arduino wifisendrecieve and you will see the example they have that has a reply packet labeled as 'acknowledged'. Hope this helps