Hier ist ein Demo-code der einern String per UDP sendet.
Auf dem Raspi läuft dann das Python-Script das am Ende in Blockkommentarklammern steht
// I wrote some basic documentation at the end of the file
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <PString.h>
#include <time.h> // time() ctime()
char *ssid = "FRITZ!Box 7490";
char *password = "";
IPAddress remoteIP (192, 168, 178, 160); // receiver-IP
unsigned int remotePort = 4210; // receiver port to listen on must match the portnumber the receiver is listening to
WiFiUDP Udp;
const char* ntpServer = "fritz.box";
const long gmtOffset_sec = 0;
const int daylightOffset_sec = 7200;
#include <time.h> // time() ctime()
time_t now; // this is the epoch
tm myTimeInfo; // the structure tm holds time information in a more convient way
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - expireTime >= TimePeriod )
{
expireTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
const byte OnBoard_LED = 2;
int BlinkTime = 500;
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
unsigned long TestTimer;
unsigned long UDP_SendTimer;
int myCounter = 0;
int HeaderNr = 0;
#define MaxMsgLength 1024
char UDP_Msg_AoC[MaxMsgLength + 1]; // always remember one extra-char for terminating zero
PString UDP_Msg_PS(UDP_Msg_AoC, sizeof(UDP_Msg_AoC));
uint8_t UDP_Msg_uint8_Buffer[MaxMsgLength + 1]; // for some strange reasons on ESP32 the udp.write-function needs an uint8_t-array
#define MaxHeaderLength 64
char Header_AoC[MaxHeaderLength + 1]; // always remember one extra-char for terminating zero
PString Header_PS(Header_AoC, sizeof(Header_AoC));
#define MaxTimeStampLength 32
char TimeStamp_AoC[MaxTimeStampLength + 1]; // always remember one extra-char for terminating zero
PString TimeStamp_PS(TimeStamp_AoC, sizeof(TimeStamp_AoC));
char HeaderDelimiter = '$'; // must match the delimiter defined in the python-code
void PrintFileNameDateTime()
{
Serial.print("Code running comes from file ");
Serial.println(__FILE__);
Serial.print(" compiled ");
Serial.print(__DATE__);
Serial.println(__TIME__);
}
void showTime() {
time(&now); // read the current time
localtime_r(&now, &myTimeInfo); // update the structure tm with the current time
Serial.print("year:");
Serial.print(myTimeInfo.tm_year + 1900); // years since 1900
Serial.print("\tmonth:");
Serial.print(myTimeInfo.tm_mon + 1); // January = 0 (!)
Serial.print("\tday:");
Serial.print(myTimeInfo.tm_mday); // day of month
Serial.print("\thour:");
Serial.print(myTimeInfo.tm_hour); // hours since midnight 0-23
Serial.print("\tmin:");
Serial.print(myTimeInfo.tm_min); // minutes after the hour 0-59
Serial.print("\tsec:");
Serial.print(myTimeInfo.tm_sec); // seconds after the minute 0-61*
Serial.print("\twday");
Serial.print(myTimeInfo.tm_wday); // days since Sunday 0-6
if (myTimeInfo.tm_isdst == 1) // Daylight Saving Time flag
Serial.print("\tDST");
else
Serial.print("\tstandard");
Serial.println();
}
// my personal naming-convention parameter of functions start with prefix "p_"
void StoreTimeStampStr(char* p_PointerToTarget, tm p_myTimeInfo) {
char l_TimeStamp_AoC[MaxTimeStampLength + 1]; // always remember one extra-char for terminating zero
PString l_TimeStamp_PS(l_TimeStamp_AoC, sizeof(l_TimeStamp_AoC));
time(&now); // read the current time
localtime_r(&now, &myTimeInfo);
l_TimeStamp_PS = p_myTimeInfo.tm_year + 1900;
l_TimeStamp_PS += ".";
l_TimeStamp_PS += p_myTimeInfo.tm_mon + 1;
l_TimeStamp_PS += ".";
l_TimeStamp_PS += p_myTimeInfo.tm_mday;
l_TimeStamp_PS += ", ";
l_TimeStamp_PS += p_myTimeInfo.tm_hour;
l_TimeStamp_PS += ":";
l_TimeStamp_PS += p_myTimeInfo.tm_min;
l_TimeStamp_PS += ":";
l_TimeStamp_PS += p_myTimeInfo.tm_sec;
l_TimeStamp_PS += ",";
strlcpy(p_PointerToTarget, l_TimeStamp_AoC,l_TimeStamp_PS.length() + 1);
}
void connectToWifi() {
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
BlinkHeartBeatLED(OnBoard_LED, 333);
delay(332);
Serial.print(".");
}
Serial.print("\n connected.");
Serial.println(WiFi.localIP() );
}
void synchroniseWith_NTP_Time() {
Serial.print("configTime uses ntpServer ");
Serial.println(ntpServer);
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
Serial.print("synchronising time");
while (myTimeInfo.tm_year + 1900 < 2000 ) {
time(&now); // read the current time
localtime_r(&now, &myTimeInfo);
BlinkHeartBeatLED(OnBoard_LED, 100);
delay(100);
Serial.print(".");
}
Serial.print("\n time synchronsized \n");
showTime();
}
void setup() {
Serial.begin(115200);
Serial.println("\n Setup-Start \n");
PrintFileNameDateTime();
connectToWifi();
synchroniseWith_NTP_Time();
Header_PS = "myDemoHeader";
}
void PrintMsg() {
Serial.print("UDP_Msg_PS #");
Serial.print(UDP_Msg_PS);
Serial.println("#");
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, BlinkTime);
if (TimePeriodIsOver(UDP_SendTimer, 2000) ) {
Serial.print("Send Message to #");
Serial.print(remoteIP);
Serial.print(":");
Serial.println(remotePort);
UDP_Msg_PS = Header_PS;
UDP_Msg_PS += HeaderDelimiter;
UDP_Msg_PS += "myUserData, ";
StoreTimeStampStr(TimeStamp_AoC,myTimeInfo);
UDP_Msg_PS += TimeStamp_PS;
UDP_Msg_PS += myCounter++;
Serial.print("Send UDP_Msg #");
Serial.print(UDP_Msg_PS);
Serial.println("#");
memcpy(UDP_Msg_uint8_Buffer,UDP_Msg_PS,UDP_Msg_PS.length()); // for some strange reason the ESP32 UDP-function write needs an uint8_t-array
Udp.beginPacket(remoteIP, remotePort);
Udp.write(UDP_Msg_uint8_Buffer, UDP_Msg_PS.length() );
Udp.endPacket();
}
}
/*
This is a democode that demonstrates how to send TCP/UDP-messages with a timestamp
The time is synchronized using a NTP-server. Most local routers like Fritz!Box can be used as the NTP-timer-server
The message has a userdefinable header which could be used for identifying the sender on the recieverside
There is a user-definable Header-delimiter that can be used to identify which characters of the
UDP-message belong to the header and which to the userdata
The code makes use of the PString-library. PStrings don't cause memory-problems like datatype "Strings"
and are easier to use than arrays of char. Example adding an integer to a PString-variable is as easy as
MyPString = myInteger;
The userdata has commas between each data so you can import the textfile
into table-calculation-software or databases as CSV-file comma separated values
the code has some additional useful functions as there are
- PrintFileNameDateTime() printing the path and filename of sourcecode file this program was generated with
- boolean TimePeriodIsOver a non-blocking timing-function based on millis which is suitable for
timed execution in a regular manner (repeat every n milliseconds)
- BlinkHeartBeatLED() blinks the onboard-LED of ESP32 nodeMCU-boards. Gives visual feedback if the code is running
The lines of code are grouped by functionality into several functions
The functions name says what the function does
I use this code for easy datalogging on a computer with a python-code that acts as the UDP-listener for
incoming messages. Inside your ESP32-code you have to adjust the IP-adress to the receiver
and the portnumber must be the same on sender (ESP32) and receiver-side
In the python-code The header is used to create a file with the header as filename and extension ".txt" or if file
is already existant to append the actual received UDP-message at the end of the file.
here is the python-code that does this. I tested it with python 3.9.2 for windows
#Start of python-code
# very simple and short upd-receiver based on python-code I found here
# https://www.studytonight.com/network-programming-in-python/working-with-udp-sockets#
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # For UDP
udp_host = socket.gethostname() # Host IP
udp_port = 4210 # specified port to connect
sock.bind((udp_host,udp_port))
print ("Waiting for client...")
HeaderDelimitChar = "$"
while True:
data,addr = sock.recvfrom(1024) #receive data from client
print("data #",data,"#")
Msg = data.decode('utf-8')
print ("Received Message: #",Msg,"# from",addr)
EndOfHeader = Msg.find(HeaderDelimitChar)
HeaderBytes = Msg[0:EndOfHeader]
FileName = HeaderBytes + ".txt"
print("Filename #",FileName,"#")
myFile = open(FileName, "a+")
EndOfStr = data.find(0)
MsgToWrite = Msg[EndOfHeader + 1 :1024] + '\r'
myFile.write(MsgToWrite);
myFile.close()
print ("Data #",MsgToWrite,"#")
#End of python-code
For learning more about python just google with keyword "python" "your keyword of interest"
*/
vgs