analog Sensor -> Arduino -> Xbee -> Raspberry connection speed problem

Hi there. I am working on a sensor network, which reads different analog sensors on a Arduino, then sends the data via Xbees to a RaspberryPi dataserver, who is connected to an PC with LabView via Ethernet.
(I am a mechanical engineer doing my first steps programming outside of Matlab and i am totally new to microcontrollers, networks and so on. But it's fun to learn all this for my Master Thesis.)

My problem is the transmitting speed. Right now i get around 100 Hz maximum. Because i want to measure unsteady flow, 1000 Hz or higher would be nice. I tried my best to find the bottleneck in my network, but i am still not sure. So i want to show you the steps and write down my thoughts on it, so you could maybe help me.

1. Arduino (Uno at the moment, later i want to use the Micro)

void setup() {
 Serial.begin(115200);

}
char Buffer[38];

void loop() {

int sensor0 = analogRead(0);
int sensor1 = analogRead(0);
int sensor2 = analogRead(0);
int sensor3 = analogRead(0);
int sensor4 = analogRead(0);
int sensor5 = analogRead(0);
unsigned long zeit = millis(); //zeit is the german word for time ;)

sprintf(Buffer,"%04i%04i%04i%04i%04i%04i%08i",sensor0,sensor1,sensor2,sensor3,sensor4,sensor5,zeit);

Serial.print ("s");
Serial.print (buffer);

delay (8);
}

What i do here is to read the analog sensors, which transforms them to digital signals. (Should be fast enough for 100 Hz as far as i read) Then i want to have all sensor data at the same length, so i fill it up to 4 characters with sprintf(). Then the buffer of sprintf() is send with Serial.print.

Why strings? I know this produces unnecessary data, but Serial.print uses strings anyway. And it seemd the easiest way to produce a dataset of a constant lenght. I could use Serial.write to send bytes, but then i would need a whole new idea to read the data back in.

Maybe sprintf() is slow. This was my first thought, so i replaced the function by various "if" and "else if", but this doesn't help. Do you want to see it? Just aks, it is a bit longer so i decided not to show it.

When i want to get faster and use a shorter delay, i sometimes don't get the whole buffer. it just starts new before all 32 characters are send. This gets worse the less delay i use. The first sensor signal is oft not harmed, but the last characters, which represent the time often get lost.

2. Xbees

Series 2, Pro version
115 200 bps
AT Mode

The router is connected to the Arduino. I know, that the arduino provides 50 mA and the XBee Pro needs 150 mA, but i worked fine before i read this (...ooops). Could this be a problem? The coordinator is attached to a USB dongle and connected to the RaspberryPi. The Xbees worked fine with different baudrates, so i got up to 115 200 bps. At the moment they are 20 cm away of each other on my desk, so there should be no connection problems.

3. Python script on RaspberryPi

Wrong forum, i know, but it might help you to undestand.

...
while 1:
aktuellerwert = ser.read(1)

if aktuellerwert == "s": #wait for startsign to avoid overlap

sensor0 = ser.read(4) #read the first 4 characters after "s"
sensor1 = ser.read(4)
.
.
sensor5 = ser.read(4)

stringtosend = str(sensor0 + " " + sensor1 + " " + ... + sensor5)

data = conn.recv(BUFFER_SIZE)
try:
conn.send(stringtosend)
...

It reads one character until it gets "s", then it reads the sensor data and the time, which are always the same length. If i try to go faster, the last characters are somtimes just "0", or the first characters of the next sample including the "s".

Then it sends the data via ethernet to a PC (or Internet in the future), where a LabView Script displays the data and saves it. The whole ethernet connection and LabView loop should be fast enought for far more than 1000 Hz samplerate.

Do you need any more information to help me?, or want to know more about what i am doing? Just ask for it.

Thank you very much for taking time for my problem.

delay (8);

It just boggles the mind when people complain about slow, and do this crap.

How are the XBees configured?

Why are you storing 6 values read from the same pin, and sending one packet containing 6 values? It would be faster the send the data one value at a time, using the minimum number of digits and some character to act as a delimiter between values.

How are the XBees configured?

And finally, and most importantly, how are the XBees configured?

Hi Paul,

of course the delay slows it down. But 8 miliseconds is the shortest delay, that doesn't produce wrong output. With these 8 miliseconds i get a bit more than 100 Hz (around 110) which is not too far away of the 125 Hz, that a loop time of 8 ms would produce. So the main code doesn't take much time right now. Because of that i think it should be possible to get faster with that code. My goal would be no delay at all, or just a bit to keep it stable.

At the moment i read the same pin (Temp sensor) 6 times, because i don't want to have the mess of 6 sensors on my desk. This should simulate the same processing time as reading 6 different sensors.

XBee configuration: Sorry, i don't have them here right now. I can tell the details on monday. But as far as i remember:

latest AT Router and AT Coordinator firmware
115 200 bps
one stop bit
no sleep
...
ahhh, i don't remember much. I will do this on monday.

My XBee settings:

Serial Interfacing

Baud Rate: 115 200
Parity: No Parity (default setting)
Stop Bits: One stop bit (default setting)
Packetization Timeout: 3xcharacter Time (don't really know what that means, just left it as it was)
DIO7 Configuration: CTS flow control (default setting)
DIO6 Configuration: Disable (default setting)

AT Command Options (all default settings)

AT Command Mode Timeout: 64 x 100ms
GT Guard Times: 3E8 x 1ms
Command Sequence Character: 2B

anything else needed?

anything else needed?

Much more. What kind of XBees are they? Are they series 1 - point to point? Or, are they series 2 - mech network?

What are the source addresses of the XBees? What are the destination addresses of the XBees?

I suspect that you have the XBees in broadcast mode (talk to everybody) instead of talking to a specific XBee. Broadcast communication is lower priority than direct communication, and waits for there to be no direct communication going on. Obviously, that means that it is slower.

Ah, ok

I do have series 2 XBees (XBP24), but i want them to be set up as a point-to-point network, because i only need to send the data from 3 sensor Arduinos to one coordinator at the Raspberry. For testing i only use one arduino. Is there a broadcast on/off or is this dialed with destination adress (what i have done)? Edit: found that i don't use braodcast when i have a destination address.

full settings:

ID: 3332
SC: 7FFF
SD 3
ZS: 0
NJ: FF
OP: 3332
OI: 8E12
CH: B
NC: A

SH,SL,DH,DL: destination address is the serial number of the opposit XBee
NI:
NH: 1E
BH: 0
AR: FF
DD: 30000
NT: 3C
NO: 0
NP: 54
CR: 3

SE: E8
DE: E8
CI: 11

PL: highest
PM: boost mode enabled
PP: A

Security: all turned off

BD: 115200
NB: no parity
SB: one stop bit
RO: 3
D7: CTS flow control
D6: disable

CT: 64
GT: 3E8
CC: 2B

SP: 20
SN: 1

XBee In/Out: not used

VR: 20A7
HV: 1E46
AI: 0
DB: 5
%V: AD5
TP: 1E

SH,SL,DH,DL: destination address is the serial number of the opposit XBee

Prove it. Show the SH, SL, DH, and DL values for each XBee.

Define which is the coordinator and which is the router/end device.

i only need to send the data from 3 sensor Arduinos

How are the 3 Arduinos supposed to talk to 1 XBee?

Edit: found that i don't use braodcast when i have a destination address.

Correct.

Hi Paul,

thanks for your patience to try to help me. The last days i had to work a bit on my projects hardware, because of that i haven't been here for a few days.

PaulS:
How are the 3 Arduinos supposed to talk to 1 XBee?

They all have the same coordinator as destination address. The messages begin with a letter so i know from which Arduino the message came from. This works fine with two sending Arduinos. I think 3 or 4 would be no problem (beside slowing the datarate down of course). But my goal is to get the maximum datarate of two communicating Xbees first.

Because i am not sure if the XBees or the Arduino sketch is the limitating part, i asked the DIGI Tech Support for help to get the maximum out of the Xbees. I will post the reply here, when i get it.
Theoretically i should get 250 kbit/s through the Xbees. right now i get less than a quarter of it (32 char/message * 16 bit/char = 512 bit/message; 100 messages/s = 51 kbit/s).

The XBee addressing is attached.

Addressing_Coordinator.PNG

Addressing_Router.PNG

Theoretically i should get 250 kbit/s through the Xbees

How did you arrive at that number? Is that the baud rate you set the XBees to?

Are you using the same baud rate to communicate with the XBees as they are using to communicate with each other?

I have the 250 kbit/s from the XBee datasheet. You can see it here:

The baudrate is set to 115 200 bps. So this should be limiting first but you can not set the XBees to a higher Baudrate with the XCTU software.

PaulS:
Are you using the same baud rate to communicate with the XBees as they are using to communicate with each other?

Yep, every part of my sensor network is set to 115200 bps. Otherwise it would not be able to communicate.

Here is the answer i got from Digi Tech Support:

Hi Tillmann

Data rate of 250kbps includes all overheads of transmission along with payload user data. A throughput of 51 kbps is in line with XBee S2B module’s capabilities. See pg. 68 of product manual for details:

But i guess that is the datarate for API mode, not AT.

I choosed AT mode right from the start to get as less overhead as possible.