Go Down

Topic: Serial communication issues? Wifly + Wireless SD Shield + Uno (Read 700 times) previous topic - next topic

Lamplighter

Hi Folks,

I'm having a bit of trouble with a setup using Uno + Arduino Wireless SD Shield + Wifly RN-XV and a temperature sensor, and would be very grateful for some guidance on this.

My goal here was to have the Uno read a DS18B20 One Wire Temperature sensor, and PUT that data to a COSM/Patchube datastream every 30 seconds. My current setup does work, and will reliably send temperature readings accepted by COSM. But only 2 - 12 hours at a time, then it starts behaving oddly.

After about two hours of PUTing data to COSM, Uno ceases to send data to COSM. The COSM API debugger shows no put requests. Troubleshooting has not been easy, since the way the Arduino behaves after it stops sending the data tends to vary.

When the unit is outside (and it's fairly cold outside, about 10-20F at night), and stops sending the sensor data to COSM, the green light on the RN-XV continues to slow blink. My wireless router shows it connecting to the internet. But the lack of LED activity for RX and TX seem to indicate there's no serial communication going on between the RN-XV and the UNO. The last temp that the sensor reports is usually around 25F, but it usually takes only a couple of hours at most for it to stop working. Pressing the reset button yielded a second-long solid orange light, as if some serial communication was going on, and then the green light started flashing again as if it were in CMD mode.

But just here today, when the unit was inside and near a radiator (registering between 75-80F), it worked for approximately 12 hours before it quit. This time when it stopped working, not only did it seem that communication stopped between the RN-XV and the UNO, but RN-XV was blinking its green LED as if it was bumped into command mode. Unlike when it was outside, pressing the reset button here does return the Arduino to operating normally.

Some info about my current setup:
1) Pins RX0 and TX1 are bent back on the (official) Arduino wireless shield so as to not give contact with the Uno.
2) Switch on wireless shield is always in "USB" mode, not "MICRO" mode.
3) Pin 8 on the shield is jumped to pin RX0 on the shield, and pin 9 on the shield is jumped to pin TX1 on the shield for serial communication with the RN-XV.
4) Center pin on the temp sensor is jumped to pin 2 on the shield. Sensor has 10k ohm pull-up resistor, is fed 5v from wireless shield.
5) RN-XV firmware was upgraded about 24 hours ago to most recent version.
6) Using WiflyHQ library.
7) Wifly RN-XV is authenticated to the home Wifi router with no issues, did not need to designate a static IP for this application. Therefore the sketch does not call for signing into and out of the network for each PUT.
8.) Power is supplied via external 9v wall wart.

Here's my code, which is the boilerplate COSM sketch which I've made just a little more simple (got rid of a loop triggered by a calculation using mills() to trigger sending the data, which I suspected might be causing the problem, but no avail) with added functionality from WiflyHQ library and Bildr's one wire temp sensor library:

Code: [Select]

#include <WiFlyHQ.h>
#include <SoftwareSerial.h>
#include <OneWire.h>

SoftwareSerial wifiSerial(9,8);

WiFly wifly;

#define APIKEY         "API KEY" // your cosm api key
#define FEEDID         FEEDID // your feed ID
#define USERAGENT      "USERAGENT" // user agent is the project name

const char server[] = "api.cosm.com";
boolean lastConnected = false;                 // state of the connection last time through the main loop
const unsigned long postingInterval = 30*1000; //delay between updates to Cosm.com
int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2

void terminal();
OneWire ds(DS18S20_Pin);  // on digital pin 2

void setup() {
  Serial.begin(9600);
  wifiSerial.begin(9600);
  // next line is new, don't know what it does.
  wifly.begin(&wifiSerial);
}

void loop() {
  float temperature = getTemp();
  temperature = ((temperature*9)/5) + 32;
  int sensorReading = temperature;
  delay(postingInterval);
  sendData(sensorReading);
}

// this method makes a HTTP connection to the server:
void sendData(int thisData) {
  // if there's a successful connection:
    wifly.open(server, 80);
    wifly.print("PUT /v2/feeds/");
    wifly.print(FEEDID);
    wifly.println(".csv HTTP/1.1");
    wifly.println("Host: api.cosm.com");
    wifly.print("X-ApiKey: ");
    wifly.println(APIKEY);
    wifly.print("User-Agent: ");
    wifly.println(USERAGENT);
    wifly.print("Content-Length: ");

    // calculate the length of the sensor reading in bytes:
    // 8 bytes for "sensor1," + number of digits of the data:
    int thisLength = 12 + getLength(thisData);
    wifly.println(thisLength);

    // last pieces of the HTTP PUT request:
    wifly.println("Content-Type: text/csv");
    wifly.println("Connection: close");
    wifly.println();

    // here's the actual content of the PUT request:
    wifly.print("temperature,");
    wifly.println(thisData);
}


// This method calculates the number of digits in the
// sensor reading.  Since each digit of the ASCII decimal
// representation is a byte, the number of digits equals
// the number of bytes:

int getLength(int someValue) {
  // there's at least one byte:
  int digits = 1;
  // continually divide the value by ten,
  // adding one to the digit count for each
  // time you divide, until you're at 0:
  int dividend = someValue /10;
  while (dividend > 0) {
    dividend = dividend /10;
    digits++;
  }
  // return the number of digits:
  return digits;
}

/* Connect the WiFly serial to the serial monitor. */
void terminal()
{
    while (1) {
if (wifly.available() > 0) {
    Serial.write(wifly.read());
}


if (Serial.available() > 0) {
    wifly.write(Serial.read());
}
    }
}

//returns the temperature from one DS18S20 in DEG Celsius
float getTemp(){
  byte data[12];
  byte addr[8];
  if ( !ds.search(addr)) {
      //no more sensors on chain, reset search
      ds.reset_search();
      return -1000;
  }
  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return -1000;
  }
  if ( addr[0] != 0x10 && addr[0] != 0x28) {
      Serial.print("Device is not recognized");
      return -1000;
  }
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end
  byte present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE); // Read Scratchpad
  for (int i = 0; i < 9; i++) { // we need 9 bytes
    data[i] = ds.read();
  }
  ds.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float tempRead = ((MSB << 8) | LSB); //using two's compliment
  float TemperatureSum = tempRead / 16;
  return TemperatureSum;
}


Sorry if this seems like a novel, but I'm trying to be as thorough as possible with this. My hunch is that something on the Arduino itself (not the WiFly), perhaps the WiflyHQ library, is tripping up over an extended period of time. Still don't know why any such hiccup could send a "$$$" command to the WiFly module, which would explain it being in command mode. Issue with the resonator causing the baud rate to go out of whack in serial communication? I honestly have no idea, but I'd really like to get to the bottom of this. Very frustrating.

Thanks for your help! It's really appreciated.


Go Up