Arduino: UDP sending yields extra characters - udp

At the moment I have an Arduino board with an Ethernet Shield connected to a router. My computer connects to this router via Wi-Fi. My board and my computer send UDP messages back and forth to each other. My computer is a client, and the board is a server. However I noticed, that when I send a longer UDP message from my computer, and then a shorter UDP message, the Arduino accepts the shorter message, then followed by remaining bits from the longer message.
For instance: if I send "Hello World" from my computer, followed with "Test"; the Arduino will not read the second message as "Test", but rather: "Testo World".
I thought perhaps in was a problem from the Arduino end first. The Arduino stores the messages temporarily in an array called packetBuffer. I tried clearing this buffer before I receive a new message each time. The buffer would clear, but then I would receive the faulty message again.
So I assume the culprit is the computer, the client. On the computer end I have a processing sketch that sends the UDP messages. The example below is not the sketch itself; however it is by far a simpler example that still provides the exact symptoms as I described with my original sketch.
import hypermedia.net.*;
UDP udp; // define the UDP object
void setup() {
udp = new UDP( this, 6000 ); // Create a new datagram connection on port 6000
//udp.log( true ); // <-- printout the connection activity
udp.listen( true ); // and wait for incoming message
}
void keyPressed() {
String IPaddress = "192.168.1.177"; // The remote IP address
int port = 8888; // The destination port
if (keyCode == UP)
{
udp.send("Test", IPaddress, port );
}
else
if (keyCode == DOWN)
{
udp.send("Hello World", IPaddress, port );
}
}
void receive( byte[] data ) { // <-- default handler
//void receive( byte[] data, String IPaddress, int port ) { // <-- extended handler
for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}
How could I get the sketch to send the right messages?
Of course I am more than willing to provide more information.

There wasn't a direct solution to this problem; so I ended up resorting to a work around. The work around involves dynamically adding zeros to all strings sent to the Arduino so there is always 10 characters sent.
For instance:
If I am to send "Hello Bot", the actual string sent is "Hello Bot0". If I sent an additional message like "Test" after that, the string sent to the Arduino would be "Test000000". The additional zeros would cover up the overlapping characters. One problem with this work around is that I had to prepare the Arduino to accept the zeros also. This work around is also kind of messy for the code. It does work though.
Here's a snippet of code from the computer (client) side. The Arduino code obviously just had to be adjusted to account for the zeros.
public void Send() { //bang button named "Send" activates function
String txtSend = comField.getText(); //Grab text from a textbox to be sent
int txtSendLength = txtSend.length();
for(int i = 0; i < 10-txtSendLength; i++){ //Add zeros until it has 10 char
txtSend = txtSend + "0";
}
udp.send(txtSend, ip, port);
comField.clear(); //Clear the textbox
}
Behold, the very simple and crude solution!

I believe your issue is with properly clearing the buffer. I found a line of code that goes through and clears each character, since it is a character array. There is theoretically no buffer to clear once it is read.
Use:
for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;
Once you read the data, and that will clear the array. I also found out that when trying to do logic on the data that was received, in order to control some output, I needed to first convert the packetBuffer to a string. After that, all seemed to work correctly.
Hope that help.

Related

communication between board and the GPS module

I'm currently having trouble with talking between the dev board (STM32L476RG) and the GPS module (GP-207U). What my code does now is that, it can print out the very first packet received from GPS to PuTTY and will keep printing the same packet, even if I unplug the Tx wire from the dev board, PuTTY will still keep printing. I suspect that either the buffer that stores the received value is not getting updated(fulshed) or the HAL_UART_Receive() function only run once. (The receive function is in While(1) in main, so I'm confused)
enter image description here
(I unpluged the GPS, Putty still prints, so the receive function isn't doing anything after it received the very first packet from GPS)
/*retrive data from GPS*/
char UARTRxBuffer[1024] = "";
char RxBuffer[1024] = "";
void GetGPS(void) {
HAL_UART_Receive(&huart3, (uint8_t *)UARTRxBuffer, 1024, 1000);
HAL_Delay(100);
sprintf(RxBuffer,"%s\r\n\r\n", UARTRxBuffer);
HAL_UART_Transmit(&huart2, (uint8_t *)RxBuffer, strlen(RxBuffer), 5000);
HAL_Delay(100);
}
GetGPS() is put into while(1) in main().
I tried everything based on my guesses, but none worked.
Thanks ahead for any sort of help!
I suspect the call to HAL_UART_Receive is timing out (1000 ms in your code) during the second/subsequent attempts to read the GPS. if so, the buffer contents wouldn't get cleared or overwritten resulting the same data being printed over and over. It might help to read the GPS datasheet/manual to find out the maximum polling speed (here it appears to be ~200ms, considering the 2x 100 ms delays) and adjust the delay if the GPS device cannot keep up.
try this to confirm
HAL_StatusTypeDef status = HAL_UART_Receive(/*same as above*/);
if(status == HAL_OK){
// got valid data
sprintf(RxBuffer,"%s\r\n\r\n", UARTRxBuffer);
HAL_UART_Transmit(&huart2, (uint8_t *)RxBuffer, strlen(RxBuffer), 5000);
}
else{
sprintf(RxBuffer,"read timeout.\r\n\r\n");
HAL_UART_Transmit(&huart2, (uint8_t *)RxBuffer, strlen(RxBuffer), 5000);
}
API reference docs here page 1037/2232

How do I send strings between my osx app and arduino continuously?

I made a cocoa application that generates a list of instructions for an arduino uno to execute. Because the list is too large to fit at one time within the arduino's memory, I am trying to send the arduino an individual instruction at a time.
Arduino:
void setup(){
Serial.begin(9600);
}
void loop(){
if(Serial.available() > 0){
String in = Serial.readString();
delay(10);
Serial.print(in);
}
Serial.print("A");
}
Cocoa App
(Code after the serial port is open and working)
- (void)incomingTextUpdateThread: (NSThread *) parentThread {
// mark that the thread is running
readThreadRunning = TRUE;
const int BUFFER_SIZE = 1;
char byte_buffer[BUFFER_SIZE]; // buffer for holding incoming data
long numBytes=0; // number of bytes read during read
// assign a high priority to this thread
[NSThread setThreadPriority:1.0];
// this will loop unitl the serial port closes
while(TRUE) {
// read() blocks until some data is available or the port is closed
numBytes = read(serialFileDescriptor, byte_buffer, BUFFER_SIZE); // read up to the size of the buffer
if(numBytes>0) {
if(byte_buffer[0] == 'A'){
Coordinate *c = [coordinates objectAtIndex:coordinateIndex];
[self writeString:[self formateCoordinateString:c]];
coordinateIndex++;
}
}
if(coordinateIndex == coordinates.count){
close(serialFileDescriptor);
break;
}
}
readThreadRunning = FALSE;
}
I run the arduino code first and it prints a bunch of 'A's in the serial console. However once I start the cocoa app, it stops printing 'A's and doesn't do anything.
When I set a breakpoint within the while loop, the arduino starts printing the 'A's again. I continue to step within the while loop, and the "instruction" string is sent correctly to the arduino.
My issue is that this only works when I set this break point. Otherwise both my cocoa app and arduino app go into a stand-still.
Thanks for any and all advice! Please feel free to ask for clarification.

Connecting Arduino Ethernet Shield and reading data issue PROCESSING

i am new to this forum and the whole thing with Processing.
I have a specific question to ask and thanks a lot for your time and thoughts!
How can i connect my Arduino with Ethernet Shield, getting temperature values from a sensor so they can be seen to a processing script?
In a straight Arduino script, one gets the value, connects from the ethernet shield to a server and does what one likes. I have accomplished that.
In my case i want Arduino to just run the script of reading an analog input value from the sensor.
Is it possible?
I have made the serial connection work and read the values alright through the usb, but with ethernet shield? How can i get the value that arduino reads WITHOUT USB/Serial connection?
ps. i am using WAMP server etc, Windows 7
I am trying the UDP connection script example for both arduino and processing from http://arduino.cc/en/Tutorial/UDPSendReceiveString, but
1)i ain't sure if that's what i need,
2)i have excluded from firewall ports 6000, 8888 for my tests and have put the IP address of my Arduino at the Arduino script and "localhost" at the Processing script
THE CODE COPIED FOR BETTER USE HERE
/*
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.
*/
#include <SPI.h> // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <EthernetUdp.h> // UDP library from: bjoern#cs.stanford.edu 12/30/2008
// 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);
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged"; // a string to send back
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
void setup() {
// start the Ethernet and UDP:
Ethernet.begin(mac,ip);
Udp.begin(localPort);
Serial.begin(9600);
}
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 remote = Udp.remoteIP();
for (int i =0; i < 4; i++)
{
Serial.print(remote[i], DEC);
if (i < 3)
{
Serial.print(".");
}
}
Serial.print(", port ");
Serial.println(Udp.remotePort());
// read the packet into packetBufffer
Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
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();
}
delay(10);
}
/*
Processing sketch to run with this example
=====================================================
// Processing UDP example to send and receive string data from Arduino
// press any key to send the "Hello Arduino" message
*/
import hypermedia.net.*;
UDP udp; // define the UDP object
void setup() {
udp = new UDP( this, 6000 ); // create a new datagram connection on port 6000
//udp.log( true ); // <-- printout the connection activity
udp.listen( true ); // and wait for incoming message
}
void draw()
{
}
void keyPressed() {
String ip = "192.168.1.177"; // the remote IP address
int port = 8888; // the destination port
udp.send("Hello World", ip, port ); // the message to send
}
void receive( byte[] data ) { // <-- default handler
//void receive( byte[] data, String ip, int port ) { // <-- extended handler
for(int i=0; i < data.length; i++)
print(char(data[i]));
println();
}
Read those values into a file and use that file to send data to processing. http://py.processing.org/reference/createReader.html
Great scheme. Only one problem. It works perfectly on my system. I loaded my Arudino Uno R3 with your Arduino sketch and loaded the Processing sketch as well. Worked like a charm, first try. Didn't change anything on my Arduino, Windows system, Processing (2.0.3), network, etc.
Could be you have a Arduino board problem (unlikely) or an Ethernet shield problem (sadly, more likely). You could have a network problem (even more likely).
Try Wireshark. You will really just be guessing until you take a look at the Wireshark output. Note that Wireshark has filters. You will need them. Filter out all of the non-UDP traffic.

programming processing, can't bind to udp port in network

I have a processing program working on a local machine. It reads data from a local udp port and uses this data to draw circles on my screen. It works, so that great.
But in production the program has to run on an other computer. And I cant get it to work. Processing is presenting me this error message:
opening socket failed!
> address:192.168.1.118, port:6666 [group:null]
> Cannot assign requested address: Cannot bind
Of cource I checked the IP adress and these are OK as it works fine on the local machine. Here is my code for the UDP part:
// import UDP library
import hypermedia.net.*;
String HOST_IP = "192.168.1.118";
UDP udp; // define the UDP object
// get an array ready
int num = 20;
int[] xx = new int[num];
int[] yy = new int[num];
void setup() {
size(1024, 768);
smooth();
//noStroke();
// create a new datagram connection on port 6666
udp = new UDP(this, 6666, HOST_IP);
udp.listen( true );
}
//process events
void draw() {;}
/**
* To perform any action on datagram reception, you need to implement this
* handler in your code. This method will be automatically called by the UDP
* object each time he receive a nonnull message.
* By default, this method have just one argument (the received message as
* byte[] array), but in addition, two arguments (representing in order the
* sender IP address and his port) can be set like below.
*/
// void receive( byte[] data ) { // <-- default handler
void receive( byte[] data ) {
background(255);
// get the "real" message =
// forget the ";\n" at the end <-- !!! only for a communication with Pd !!!
data = subset(data, 0, data.length-2);
String message = new String( data );
// print the result
println(message );
On both machines I use Windows XP And they are connected via a switch and udp cables.
I don't know where to start troubleshooting and how. Any ideas?

sprintf() and WriteFile() affecting string Buffer

I have a very weird problem which I cannot seem to figure out. Unfortunately, I'm not even sure how to describe it without describing my entire application. What I am trying to do is:
1) read a byte from the serial port
2) store each char into tagBuffer as they are read
3) run a query using tagBuffer to see what type of tag it is (book or shelf tag)
4) depending on the type of tag, output a series of bytes corresponding to the type of tag
Most of my code is implemented and I can get the right tag code sent back out the serial port. But there are two lines that I've added as debug statements which when I tried to remove them, they cause my program to stop working.
The lines are the two lines at the very bottom:
sprintf(buf,"%s!\n", tagBuffer);
WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);
If I try to remove them, "tagBuffer" will only store the last character as oppose being a buffer. Same thing with the next line, WriteFile().
I thought sprintf and WriteFile are I/O functions and would have no effect on variables.
I'm stuck and I need help to fix this.
//keep polling as long as stop character '-' is not read
while(szRxChar != '-')
{
// Check if a read is outstanding
if (HasOverlappedIoCompleted(&ovRead))
{
// Issue a serial port read
if (!ReadFile(hSerial,&szRxChar,1,
&dwBytesRead,&ovRead))
{
DWORD dwErr = GetLastError();
if (dwErr!=ERROR_IO_PENDING)
return dwErr;
}
}
// resets tagBuffer in case tagBuffer is out of sync
time_t t_time = time(0);
char buf[50];
if (HasOverlappedIoCompleted(&ovWrite))
{
i=0;
}
// Wait 5 seconds for serial input
if (!(HasOverlappedIoCompleted(&ovRead)))
{
WaitForSingleObject(hReadEvent,RESET_TIME);
}
// Check if serial input has arrived
if (GetOverlappedResult(hSerial,&ovRead,
&dwBytesRead,FALSE))
{
// Wait for the write
GetOverlappedResult(hSerial,&ovWrite,
&dwBytesWritten,TRUE);
if( strlen(tagBuffer) >= PACKET_LENGTH )
{
i = 0;
}
//load tagBuffer with byte stream
tagBuffer[i] = szRxChar;
i++;
tagBuffer[i] = 0; //char arrays are \0 terminated
//run query with tagBuffer
sprintf(query,"select type from rfid where rfidnum=\"");
strcat(query, tagBuffer);
strcat(query, "\"");
mysql_real_query(&mysql,query,(unsigned int)strlen(query));
//process result and send back to handheld
res = mysql_use_result(&mysql);
while(row = mysql_fetch_row(res))
{
printf("result of query is %s\n",row[0]);
string str = "";
str = string(row[0]);
if( str == "book" )
{
WriteFile(hSerial,BOOK_INDICATOR,strlen(BOOK_INDICATOR),
&dwBytesWritten,&ovWrite);
}
else if ( str == "shelf" )
{
WriteFile(hSerial,SHELF_INDICATOR,strlen(SHELF_INDICATOR),
&dwBytesWritten,&ovWrite);
}
else //this else doesn't work
{
WriteFile(hSerial,NOK,strlen(NOK),
&dwBytesWritten,&ovWrite);
}
}
mysql_free_result(res);
// Display a response to input
//printf("query is %s!\n", query);
//printf("strlen(tagBuffer) is %d!\n", strlen(tagBuffer));
//without these, tagBuffer only holds the last character
sprintf(buf,"%s!\n", tagBuffer);
WriteFile(hSerial,buf,strlen(buf), &dwBytesWritten,&ovWrite);
}
}
With those two lines, my output looks like this:
s sh she shel shelf shelf0 shelf00 BOOKCODE shelf0001
Without them, I figured out that tagBuffer and buf only stores the most recent character at any one time.
Any help at all will be greatly appreciated. Thanks.
Where are you allocating tagbuffer, how large is it?
It's possible that you are overwriting 'buf' because you are writing past the end of tagbuffer.
It seems unlikely that those two lines would have that effect on a correct program - maybe you haven't allocated sufficient space in buf for the whole length of the string in tagBuffer? This might cause a buffer overrun that is disguising the real problem?
The first thing I'd say is a piece of general advice: bugs aren't always where you think they are. If you've got something going on that doesn't seem to make sense, it often means that your assumptions somewhere else are wrong.
Here, it does seem very unlikely that an sprintf() and a WriteFile() will change the state of the "buf" array variable. However, those two lines of test code do write to "hSerial", while your main loop also reads from "hSerial". That sounds like a recipie for changing the behaviour of your program.
Suggestion: Change your lines of debugging output to store the output somewhere else: to a dialog box, or to a log file, or similar. Debugging output should generally not go to files used in the core logic, as that's too likely to change how the core logic behaves.
In my opinion, the real problem here is that you're trying to read and write the serial port from a single thread, and this is making the code more complex than it needs to be. I suggest that you read the following articles and reconsider your design:
Serial Port I/O from Joseph Newcomer's website.
Serial Communications in Win32 from MSDN.
In a multithreaded implementation, whenever the reader thread reads a message from the serial port you would then post it to your application's main thread. The main thread would then parse the message and query the database, and then queue an appropriate response to the writer thread.
This may sound more complex than your current design, but really it isn't, as Newcomer explains.
I hope this helps!