SOLVED: Getting unexpected characters in data from WiFly Bee

Hi

I'm using a WiFly bee mounted in a Bees Shield which is accessed using the SoftwareSerial library. I've had some success with it, but find the comms unreliable as the information read back from the bee is overlaid by what appears to be random noise. I'm hoping this will be familiar to someone here, and you'll be able to point me in the right direction to solving it.

To illustrate, I'll use a sequence of commands on the WiFly which generate no HTTP traffic to display, so this is simply command line stuff which . In terraterm, here's these commands and the responses:

CMD
show connection
8130
<2.31> lites
<2.31> lookup google.com
google.com=74.125.237.128
<2.31> lites
<2.31> exit
EXIT

The initial CMD is in response to $$$ to enter command mode, which isn't echoed. So I created a test script to send these same lines to the WiFly Bee, with a short delay and then echo the contents of the WiFly buffer out to the serial port. Sketch here :

#include <SoftwareSerial.h>

// WiFly bee is using pins 2 & 3 on the Arduino
SoftwareSerial WiFly(2, 3);
const int waitTime = 2000;

void setup(void) {
  // start serial port
  Serial.begin(9600);
  WiFly.begin(9600);                                   // set the data rate for the SoftwareSerial port
  for (int i=0; i<15; i++) delay(1000);                // allow 15 secs to reset WiFly bee manually
 }
 
void doWiFlyCommand(char* commandString) {
  // write string to WiFly bee's serial buffer, 
  // wait a small while, 
  // then read WiFly bee's serial output buffer for results
  for(int idx = 0; commandString[idx] != '\0'; idx++) WiFly.write(commandString[idx]);
  WiFly.println();
  delay(waitTime);
  while(WiFly.available()) Serial.write(WiFly.read());
  Serial.println();
}

void loop(void) { 
  Serial.println("=============================================================================================");
  delay(300);                                          // 250ms delay either side of command mode signal
  WiFly.print("$$");
  delay(300);                                          // 250ms delay in going into command mode in the WiFly
  while (WiFly.available()) Serial.write(WiFly.read());
  Serial.println();
  doWiFlyCommand("show connection");                    // status of WiFly bee
  doWiFlyCommand("lites");                              // on-board disco light show
  doWiFlyCommand("lookup google.com");                  // DNS lookup
  doWiFlyCommand("lites");                              // turn off light-show
  doWiFlyCommand("exit");                              // depart command mode
}

But the result is somewhat different. Note also that the unexpected characters change each loop through, so it's not predictable (or at least a pattern I recognise, but I'm really hoping you do?).

=============================================================================================
CMD

s½ÿeÿo+ÿctikÖL³Ì?
<2.31> 

lÑÿe5ÖLf˳1> 

l½ÿkÁÿ ½ÿÿle.cok¦ügoogle.com=74.125.237.134
<2.31> 

Ñÿes5f?&æl³fÏ 

e¥ÿt
)V
-µa?
=============================================================================================
CMD

shÝÿÿ¹ÿ+ÿctsÿ
S?6ÖL&æl³fÏ 

¥ÿtÍÿ
SÆ&æl³fÏ 

l½ÿkÁÿ ½ÿÿ?ÿÿom
SvÛÛÛ6mÙ?com=74.125.237.134
<2.31> 

¥ÿtÍÿ
SÆ&æl³fÏ 

e¥ÿt5V¬kÒª

=============================================================================================
CMD

s½ÿeÿsÿec{ÿn
8130
<2.31> 

lÑÿe5ÖLfË?1> 

l½ÿkÁÿ ½ÿÿ?ÿ.cok¦ì¶ÛÛ6mÙ?com=74.125.237.134
<2.31> 

lÑÿe5ÖLfË31> 

e¥ÿt5¦¬kÒª

=============================================================================================
CMD

sÝÿÿonneKÿon
8130
<2.31> 

¥ÿtÍÿ
#Æ&æl³fÏ 

½ÿokÁÿ ½ÿÿ?ÿÿµÿ
SvÛÛÛ6mÙ?com=74.125.237.134
<2.31> 

lÑÿe5kLfË?1> 

e¥ÿt5S¬kÒª

=============================================================================================
CMD

s½ÿeÿsÿeKÿon
8130
<2.31> 

lÑÿe5ÖLfË?1> 

l½ÿkÁÿ ½ÿÿ?ÿ.com
SvÛÛÛ6mÙ?com=74.125.237.134
<2.31> 

¥ÿtÍÿ
SÆ&æl³fÏ 

e¥ÿt5¦¬kÒª

I've tested this on two different WiFly Bees, on multiple Arduinos and two Bees Shields to try to eliminate hardware failings. You can also see the legitimate responses are in there, just not always identifiable, and the sequence of commands actually does run as evidenced by the DNS lookup and the LED light show each loop through.

Thanks for reading this far...any ideas?
Geoff

Hi,

Further testing. Added a test for buffer overflow to the function that outputs the commands.

void doWiFlyCommand(char* commandString) {
  // write string to WiFly bee's serial buffer, 
  // wait a small while, 
  // then read WiFly bee's serial output buffer for results
  for(int idx = 0; commandString[idx] != '\0'; idx++) WiFly.write(commandString[idx]);
  WiFly.println();
  delay(waitTime);
  while(WiFly.available()) {
   if (WiFly.overflow()) Serial.println("<<<OVERFLOW!>>>");
   Serial.write(WiFly.read());
  }
  Serial.println();
}

At 115200 the issue is far more pronounced, perhaps, but again teraterm at the same baud rate is flawless.

=============================================================================================
CMD
?
7öÛ÷nû?û[öe÷íû[¬?1?0
?<23?>dá
[ûWö¯¬??æ?ó¦ü
Ûû[ûìû÷ÿeû?ùÛý[X?ض{ce?cm?7fY?³3?6»æ?&Ö¦?2?31? ð
[ûwö·X??æ¶æþ

6÷eûX?¬-­??ø
=============================================================================================
C¦D
?
s´owc??[Û6·í?
?
8?30?
<?.ó¦þ
[ýmX?&s6æ¦ü
Ûû·ÿéû{ÿeû6ùÛû[XLض{c.±om?74?125?237YÙ3f???s6æSþ
-û?ÿk¦Æ?æ6?æSþ
eO¬?¬-­??ø

However at the other extreme, setting things all up at 2400 (on WiFly and in the instantiation of SoftwareSerial in the sketch) does not improve things.

CMD

s´ow ½ÿ¹ÿeÑÿ½ÿn5¦6ÖL&æl³f? 

lÑÿes
<2.31> 

looÕÿpÿoÿ?ÿ.½ÿ5ÖLض·gle.com=74.125.237.130
<2.31> 

£e5ÖLfË31> 

exi5ÖLX4kT

=============================================================================================
CMD

¡ÿoþc¹ÿ?ÿK¹ÿ5¦6ÖL&æl³f? 

lite5ÖLfË31> 

½ÿokÁÿ ½ÿÿl¹þ½ÿm5¦ì¶ÛÛ6mÙ?com=74.125.237.130
<2.31> 

lÑÿes
S?&æl³f? 

exi[a?EXIT

=============================================================================================
CMD

shÝÿ ½ÿ¹ÿeÑÿ½ÿk¦³Ì?0
<2.31> 

li?ÿs
S?&æl³f? 

ÿuþg½ÿg?ÿÿo5ÖLøgoogle.com=74.125.237.131
<2.31> 

£e5ÖLfË31> 

exi5ÖLX4kT

So...still none the wiser.

Geoff

  while (WiFly.available()) Serial.write(WiFly.read());

What does the WiFly.read() function return? ASCII or binary data? If it is ASCII, why are you using Serial.write() to send it to the serial monitor? I think you should be using Serial.print(), AND I think you should be storing the returned value in the appropriate type variable.

There have been lots of issues with "noise" that have been caused by just this sort of processing that have been solved by:

char aChar = WiFly.read();
Serial.print(aChar);

Hi PaulS

Thanks for looking into this. I was under the impression Serial.print() and Serial.write() were essentially the same for character data?

But FWIW that code is lifted directly from the SoftwareSerial example sketch "SoftwareSerialExample"

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

I'll give what you suggest a crack though, at this stage I'm taking any option. Will report back when done.

Cheers ! Geoff

But FWIW that code is lifted directly from the SoftwareSerial example sketch "SoftwareSerialExample"

If you are referring to the SoftwareSerial in 1.0, then the example is flawed. The chances of getting it changed in my lifetime range between slim and fat.

If you are referring to the SoftwareSerial example from 0023 or earlier, well then, you shouldn't even be using that obsolete-before-it-was-delivered library.

It's IDE v1.0 - so if the example is bad then this could be easier to fix than I'd expected :slight_smile:

Hoping to keep the real world at bay for a while later today to get back onto this. Thanks for the advice and fingers X'd it works with that simple mod.

Cheers ! Geoff

Hi again,

Unfortunately this change didn't improve the result so wondering if I'm hitting a limit with SoftwareSerial.

So this leads to a slight change of plan: I'm using a bees shield to run both a bluetooth bee and the WiFly bee. I know others have had success with a Bluetooth bee over SoftwareSerial so will put the BT bee on the slow road and the WiFly on the inbuilt serial rather than the way I was planning to run it. Will report back what I find.

Geoff

Hi again,

Well the result was like night and day. While I can't paste the LCD output, the only non-printable characters in the feed were (of course) LF & CR. Worked first time, and every time. Using the inbuilt UART is the way to go for the WiFly bee. Would be happy to hear if anyone works out how to get one running with SoftwareSerial for flexibility.

The other difference is I didn't need to add any delay after writing to the WiFly for it to respond.

For the record, here's my test code outputting to the I2C 16x2 LCD:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

int waitTime = 2000;

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup(void) {
  // start serial port
  Serial.begin(9600);            // WiFly
  lcd.init();                    // initialize the lcd 
  lcd.backlight();
  lcd.clear();
  lcd.print("Starting in");
  for (int i=0; i<15; i++) {
    lcd.setCursor(0,1);
    lcd.print(15-i, DEC);
    lcd.print("...");
    delay(1000);                // allow 15 secs to reset WiFly bee manually if required
  }
 }
 
void doWiFlyCommand(const char* commandString) {
  // write string to WiFly bee's serial buffer, 
  // then read WiFly bee's serial output buffer for results
  int lcdPos = 1;
  char thisChar;
  
  lcd.clear();  
  for(int idx = 0; commandString[idx] != '\0'; idx++) {
    lcd.print(commandString[idx]);
    Serial.print(commandString[idx]);       // to WiFly
  }
  lcd.print(":");
  lcd.setCursor(0,1);                        // 2nd line
  Serial.println();                          // to WiFly

  while(Serial.available()) {
    thisChar = Serial.read();
    if(byte(thisChar) != 10 && byte(thisChar) != 13) {
      lcd.print(thisChar);
      lcdPos++;
      if(lcdPos > 15) lcdPos = 1;
      if(lcdPos == 1) {                    // display wrap
        lcd.setCursor(15,0); 
        lcd.print("+");                    // + at end of top line indicates lower display line has wrapped
        lcd.setCursor(0,1);                // next char will be output at start of 2nd row again
        delay(waitTime / 2);               // after a short pause so you get to read it
      }
    }
  }
  delay(waitTime);
}

void loop(void) { 
  delay(300);                                          // 250ms delay either side of command mode signal
  Serial.print("$$");                                 // to WiFly
  delay(300);                                          // 250ms delay in going into command mode in the WiFly
  lcd.clear();
  lcd.print("Running...");
  lcd.setCursor(0,1);
  while (Serial.available()) lcd.print(char(Serial.read()));
  doWiFlyCommand("show connection");                    // status of WiFly bee
  doWiFlyCommand("lites");                              // on-board disco light show
  doWiFlyCommand("get everything");
  doWiFlyCommand("lookup google.com");                  // DNS lookup
  doWiFlyCommand("lites");                              // turn off light-show
  doWiFlyCommand("exit");                              // depart command mode
}

Thanks for your suggestions Paul, and to the other lurkers who read all that text.

So now: back to the project at hand :smiley:
Geoff

I've had no problems with software serial (newsoftserial on 0022) with a WiFly RN-VX module. I've used pins 11 and 12 and also 8 and 9 on an Uno. Perhaps you're getting noise from some source on pins 2 and 3 on your board? Did you try different pins?

void loop() // run over and over
{
  if (mySerial.available())
    Serial.write(mySerial.read());
  if (Serial.available())
    mySerial.write(Serial.read());
}

This code looks perfectly fine, and I've run the same without problems. There is no difference between "ASCII" and binary characters. If you look at Print.cpp in the core code you see this:

size_t Print::print(char c)
{
  return write(c);
}

So a Serial.print(c) or SoftSerial.print(c) is exactly the same as a Serial.write(c) or SoftSerial.write(c).

Hi dhunt

I have a feeling I've debugged my own code. A day down the track and I'm happy to use the serial UART on D0 & D1, but I think I've overlooked two very important lines in the setup() routine and feel a bit sick to the stomach for missing it all along...

  pinMode(2,INPUT);                                   // comms pins for Bluetooth bee
  pinMode(3,OUTPUT);

These were in an earlier instance of my test sketch but are now missing, and certainly not present in the version I was presenting here.

My first hint should have been that there's a perfectly functional WiFlySerial library (updated just this week to IDE v1 too) that works using SoftwareSerial so it had to be something I was doing...and there it is.

So solved twofold. What a rookie mistake !
Geoff

What a rookie mistake !

No. If the pins are to be used by the SoftwareSerial library, it sets the pin modes correctly, so you don't need to. In fact, it would be an error to set the pin mode on SoftwareSerial's pins.

Well that's still a mystery to me then. I've got to use the SoftwareSerial connection to run my 2nd bee so I expect I'll be revisiting this thread in the not-too-distant future...