I am doing a project involving UDP from teensy 4.1 to PC. After some experiments and help from forums I managed to acquire data on teensy and send to the PC via regular Cat5e twisted pair cable. The problem is that the data I am receiving on the PC is far from what I am actually sending. I already verified that hardware is tested and working properly.
2 pictures down below of arduino serial monitor (two numbers separated by space converted into 12 position char array, nice and clean, thats what I am after...) and text file on PC (there are some fragments of the data I want but its really messy and unpredictable).
What is more, the text file should be written almost instantly, but after running the python code for 5-10 seconds, I only get sometimes only several hundred lines beginning and ending with random numbers (it should always be 0-4095)
I guess there is no problem with the teensy code. But I am not sure about python. I wrote and improvised an algorithm to synchronize teensy and PC (teensy is constatnly spitting stream of data, the PC only has to write data lines that contain 0-4095 first number values.)
I am aware that UDP can lose some packets etc. But I am giving a really generous 50 us delay after each send operation on teensy, I feel like this problem is not about UDP limits, any observations about python code? Thank you in advance
P.S. I am adding teensy code, but its really bulky and I believe its ok...
Teensy:
#include <QNEthernet.h>
//#include "TeensyTimerTool.h"
using namespace qindesign::network;
//using namespace TeensyTimerTool;
IPAddress staticIP{10, 10, 16, 111};
IPAddress subnetMask{255, 255, 255, 0};
IPAddress gateway{10, 10, 16, 1};
constexpr uint16_t kPort = 5190;
EthernetUDP udp;
static void printPrompt();
static void receivePacket();
static void sendLine();
int Chanel[4096];
int Chanel_value[4096] = {0};
int Analog_value = 0;
void setup() {
Serial.begin(115200);
while (!Serial && millis() < 4000) {
}
printf("Starting...\r\n");
uint8_t mac[6];
Ethernet.macAddress(mac);
printf("MAC = %02x:%02x:%02x:%02x:%02x:%02x\r\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
Ethernet.onLinkState([](bool state) {
printf("[Ethernet] Link %s\r\n", state ? "ON" : "OFF");
});
printf("Starting Ethernet with static IP...\r\n");
if (!Ethernet.begin(staticIP, subnetMask, gateway)) {
printf("Failed to start Ethernet\r\n");
}
udp.begin(kPort);
printPrompt();
for (int i = 0; i<4096; i++){
Chanel[i]=i;
}
analogReadResolution(12);
}
//*******************************************************************************************************************
void loop() {
Analog_value = analogRead(A9);
for (int i = 0; i<4096; i++){
if(Analog_value==Chanel[i]){
Chanel_value[i]++;
}
}
delay(1000);
sendLine();
//Serial.end();
}
//*******************************************************************************************************************
static const String kCtrlNames[] {
"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
};
static void receivePacket() {
int size = udp.parsePacket();
if (size < 0) {
return;
}
const uint8_t *data = udp.data();
IPAddress ip = udp.remoteIP();
printf("[%u.%u.%u.%u][%d] ", ip[0], ip[1], ip[2], ip[3], size);
for (int i = 0; i < size; i++) {
uint8_t b = data[i];
if (b < 0x20) {
printf("<%s>", kCtrlNames[b].c_str());
} else if (b < 0x7f) {
putchar(data[i]);
} else {
printf("<%02xh>", data[i]);
}
}
printf("\r\n");
}
static bool readLine(String &line) {
static bool inCR = false;
while (Serial.available() > 0) {
int c;
switch (c = Serial.read()) {
case '\r':
inCR = true;
return true;
case '\n':
if (inCR) {
inCR = false;
break;
}
return true;
default:
if (c < 0) {
return false;
}
inCR = false;
line.append(static_cast<char>(c));
}
}
return false;
}
static void printPrompt() {
printf("chat> ");
fflush(stdout);
}
static void sendLine() {
char line[12]={'\0'};
for (int i = 0; i<4096; i++){
line[0]=((Chanel[i]/1000)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[0],sizeof(char));
Serial.print(line[0]);
delayMicroseconds(50);
line[1]=((Chanel[i]/100)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[1],sizeof(char));
Serial.print(line[1]);
delayMicroseconds(50);
line[2]=((Chanel[i]/10)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[2],sizeof(char));
Serial.print(line[2]);
delayMicroseconds(50);
line[3]=(Chanel[i]%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[3],sizeof(char));
Serial.print(line[3]);
delayMicroseconds(50);
line[4]=' ';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[4],sizeof(char));
Serial.print(line[4]);
delayMicroseconds(50);
line[5]=((Chanel_value[i]/1000000)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[5],sizeof(char));
Serial.print(line[5]);
delayMicroseconds(50);
line[6]=((Chanel_value[i]/100000)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[6],sizeof(char));
Serial.print(line[6]);
delayMicroseconds(50);
line[7]=((Chanel_value[i]/10000)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[7],sizeof(char));
Serial.print(line[7]);
delayMicroseconds(50);
line[8]=((Chanel_value[i]/1000)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[8],sizeof(char));
Serial.print(line[8]);
delayMicroseconds(50);
line[9]=((Chanel_value[i]/100)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[9],sizeof(char));
Serial.print(line[9]);
delayMicroseconds(50);
line[10]=((Chanel_value[i]/10)%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[10],sizeof(char));
Serial.print(line[10]);
delayMicroseconds(50);
line[11]=(Chanel_value[i]%10)+'0';
udp.send({10, 10, 16, 110}, kPort,(const uint8_t*)&line[11],sizeof(char));
Serial.print(line[11]);
Serial.print('\n');
delayMicroseconds(50);
printPrompt();
delayMicroseconds(50);
}
}
Python:
import socket
from datetime import datetime
import os
import time
localIP = "10.10.16.110"
localPort = 5190
bufferSize = 1024
counter = 0
flag = 0
msgFromServer = "Hello UDP Client\n"
bytesToSend = str.encode(msgFromServer)
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDPServerSocket.bind((localIP, localPort))
print("UDP server up listening")
while(True):
bytesAddressPair = UDPServerSocket.recvfrom(bufferSize)
message = bytesAddressPair[0]
address = bytesAddressPair[1]
clientMsg = "Message from client:{}".format(message.decode())
clientIP = "Client IP Address:{}".format(address)
file = open ('Results.txt', 'w')
now = datetime.now()
if counter%12==0:
dt_string = now.strftime("%Y/%m/%d, %H:%M:%S")
else:
dt_string = ''
if flag == 1:
if counter < 4096:
if counter%12==0:
with open(os.path.join('D:\VSC_projektai\Python_ETH','Results.txt'), 'a') as f1:
f1.write("\n")
f1.write("{} {}".format(dt_string,message.decode()))
else:
with open(os.path.join('D:\VSC_projektai\Python_ETH','Results.txt'), 'a') as f1:
f1.write("{}".format(message.decode()))
counter=counter+1
else:
counter=counter+1
if counter==4095:
flag=1
counter=0
print(clientMsg)
print(clientIP)
UDPServerSocket.sendto(bytesToSend, address)

