Hi,
I am using the Wifly Shield with Arduino Uno (Wifly library alpha 2 from git).
I want to use the Arduino/Wifly to read a six degree of freedom force/torque sensor and stream the data as fast as possible to a wireless node (Netgear router). A labview compact Rio is connected on the ethernet port of the router and is used to collect the data.
I am sending the data as blocks of:
- 6 force values (integer)= 6x 2 bytes
For a total of 16 bytes per data block.
To be more precise, I would like to get in the 300-500 blocks/s ball part … or 38400-64000 baud (16bytes/block x 8bits/bytes x 300blocks/s = 38400).
Since I read about people getting the communication to work at over 115200 baud I thought the Arduino/Wifly to be able to do so (maybe someone will tell me otherwise).
As you can guess, it doesn’t work. Trying to debug, I found interesting things about SpiSerial.write delay.
Here’s the code:
#include <SPI.h>
#include <WiFly.h>
//#include <SoftwareSerial.h>
// Change the prescale to 16 for faster analogRead()
#define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
// Wifi parameters
char passphrase[] = "passphrase";
char ssid[] = "ssid";
// Data Variables
const int NBFORCES=6;
int intForces[NBFORCES];
// Other Variables
String inputString="";
unsigned long t1;
unsigned long t2;
unsigned long t3;
unsigned long told=0;
//////////////////////////////////////////////////////////////////
void setup() {
#if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
#endif
Serial.begin(9600);
//SpiSerial.begin(115200);
Serial.println("");
Serial.println("");
Serial.println("----------------------------------------------");
Serial.println("WiFly: Communication with cRio");
Serial.println("----------------------------------------------");
Serial.println("");
// reserve 20 bytes for the state buffer
inputString.reserve(20);
WiFly.begin();
if(!WiFly.join(ssid, passphrase)) {
Serial.println("Association failed");
while(1) {
// Hang on failure
}
}
Serial.println("Associated!");
Serial.print("IP: ");
Serial.println(WiFly.ip());
//establishContact(); // Wait for connection to be established ... commented for debuging
//ONLY FOR DEBUGING ... to be removed
while(!Serial.available()) {
// Wait for a character
}
}
/////////////////////////////////////////////////////////////////
...
/////////////////////////////////////////////////////////////////
void loop() {
//Because the time when the port is read is important
//we read every port, then send the value
t1=micros();
readAnalogPorts();
t2=micros();
writeToCRio(t1);
t3=micros();
//Debug print
Serial.print("timestamp:");
Serial.println(t1);
Serial.print("Read:");
Serial.println(t2-t1);
Serial.print("Write:");
Serial.println(t3-t2);
Serial.print("Period:");
Serial.println(t1-told);
Serial.println("");
told=t1;
}
/////////////////////////////////////////////////////////////////
// Reads NBFORCES analog ports
void readAnalogPorts() {
for (int i=0; i<NBFORCES; i++)
{
intForces[i]=analogRead(i);
}
}
/////////////////////////////////////////////////////////////////
// Write every byte once at the time
// Starting with the most significative
void writeToCRio(unsigned long t) {
//Write time as 4 bytes
SpiSerial.write((t>>24));
SpiSerial.write((t>>16));
SpiSerial.write((t>>8));
SpiSerial.write(t);
//Write each forces as 2 bytes
for (int i=0; i<NBFORCES; i++)
{
SpiSerial.write((intForces[i]>>8));
SpiSerial.write(intForces[i]);
}
}
/////////////////////////////////////////////////////////////////
I am already using a ADC prescale divider of 16 for a faster analogRead()
So when using Serial.begin(9600) and default value for SpiSerial (9600) here is the typical output I get:
timestamp:22270288
Read:108
Write:624
Period:59280
timestamp:22329568
Read:108
Write:616
Period:59280
When I use Serial.begin(115200) and SpiSerial.begin(115200) here is what I get:
timestamp:9036048
Read:108
Write:15008
Period:16636
timestamp:9052704
Read:108
Write:14984
Period:16656
I get that there is a lot of overhead in the while loop with all those print and micros instructions. I also get that this overhead gets lower as the baudrate goes up. The thing I don’t understand is why does my write function sudently takes more time as the baudrate goes up?? (though the first few readings gets me a 650us delay as well)
If I keep 9600 baud, remove all the overhead and I read the timestamps on the receiver side, I still get a period of about 16000us (which is too slow).
It looks like I am hitting the communication saturation speed… and I don’t see why.
Thanks for the help