SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By Zorink
#75480
I want to interface sparkfun's usb weather board http://www.sparkfun.com/commerce/produc ... ts_id=8311 with the Arduino, but I can't get the serial communication working

I tried using the software serial library, but am new to this so I could get the lights blinking on the weather board indicating communication, but my serial.print would not show anything.

I found the following code, but the "string" type won't compile:
Code: Select all
#include <SoftwareSerial.h>

//Created August 15 2006
//Heather Dewey-Hagborg
//http://www.arduino.cc

#include <ctype.h>

#define bit9600Delay 84  
#define halfBit9600Delay 42
#define bit4800Delay 188 
#define halfBit4800Delay 94 

byte rx = 6;
byte tx = 7;
byte SWval;
String buffer = String(" ");  // buffer to read data from the weather board 
int ready = 0;  // used to mark when we have a complete string to process 
int val;  // use to read a byte from the serial 
unsigned long humidity=0, fahrenheit=0, celcius=0, SCPfahrenheit=0, presure=0; 


void setup() {
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  digitalWrite(tx,HIGH);
  digitalWrite(13,HIGH); //turn on debugging LED
  SWprint('h');  //debugging hello
  SWprint('i');
  SWprint(10); //carriage return
  Serial1.begin(9600);  // starts the second hardware serial port at 9600 to communicate with the weather board 
  Serial.begin(9600);  // starts the serial at 9600 
  pinMode(48, OUTPUT);  // turn ON the board LED for diagnostics 
  digitalWrite(48, HIGH); 

}

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit9600Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}

int SWread()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
     delayMicroseconds(bit9600Delay);
     val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

void loop()
{
    SWval = SWread(); 
    SWprint(toupper(SWval));
    while(Serial1.available() > 0) {  // if data vailable from the weather board 
    val = Serial1.read();  // read it 
    if((val != '\n')) {  // if no end of line 
      buffer.append(char(val));  // add it to the buffer 
    } 
    else {  // if end of line reached, readu to parse the buffer 
      ready = 1; 
      break; 
    }  
  } 
  if(ready == 1) {  // parse the buffer 
    if(buffer.contains("#")) {  // verify if it is aggod reading 
      // Serial.println(buffer);  // just to see what we got 
      processReading(buffer.toCharArray());  // parse the buffer extracting the data 
    } 
    buffer = String("");  // clean up the buffer for next reading 
    ready = 0; 
  } 
} 
 
// parse the buffer received extracting the data 
void processReading(char packet[]) { 
  byte i; 
  char* endptr; 
 
  // start parsing 
  i = 0; 
  i++; 
  humidity = strtod(&packet[i], &endptr);       // next field: humidity 
 
  while(packet[i++] != ',');			// next field: fahrenheit	 
  fahrenheit = strtod(&packet[i], &endptr); 
 
  while(packet[i++] != ',');			// next field: celcius 
  celcius = strtod(&packet[i], &endptr);	 
 
  while(packet[i++] != ',');			// next field: SCPfahrenheit 
  SCPfahrenheit = strtod(&packet[i], &endptr);	 
 
  while(packet[i++] != ',');			// next field: presure 
  presure = strtod(&packet[i], &endptr);	 
 
  while(packet[i++] != ',');			// next field: counter 
 
  while(packet[i++] != '$');			// next field: checksum 
 
  Serial.print("humidity: "); 
  Serial.print(humidity, DEC); 
  Serial.print(" fahrenheit: "); 
  Serial.print(fahrenheit, DEC); 
  Serial.print(" celcius: "); 
  Serial.print(celcius, DEC); 
  Serial.print(" SCPfahrenheit: "); 
  Serial.print(SCPfahrenheit, DEC); 
  Serial.print(" presure: "); 
  Serial.println(presure, DEC); 

}
If someone could help me with the code I would be very grateful.
By stevech
#75495
String would be in some .h that you aren't including. It's unique to Arduino,.
By trialex
#75502
No if you just cut'n'paste the code above; you'll also need to grab the file ctype.h that it references.

The ctype.h is not a standard arduino library, which is why it won't compile without it. Probably the author of the code will be happy to share the library - just ask if you can't find it on their website.
By Zorink
#75552
Thanks so much! I saw the software serial library, but I missed that. I'll let you know if I can get it to work.
By trialex
#75555
Note that Software Serial is built into arduino IDE - and has been superceded by NewSoftSerial.

I'm pretty sure ctype.h is not standard - grab that.
By Zorink
#75563
I looked up ctype.h and found this:
First we include the file ctype.h in our application. This gives us access to the toupper() function from the Character Operations C library which we will use later in our main loop. This library is part of the Arduino install, so you don't need to do anything other than type the #include line in order to use it
from:
http://www.arduino.cc/en/Tutorial/SoftwareSerial

I also tried this (I think this is what the first code I posted was based on), but I can't get the serial.print to output it to my computer.
By trialex
#75574
Hmmm... looks like you are right - my apologies. I hadn't come across it before - I should have been more thorough in my search!
By Zorink
#77589
I tried getting it to work again today after not touching it for a few weeks (vacation!) and I realized I had wired it incorrectly. I had the 5v and gnd going to the pwr and gnd pins next to the serial pins instead of the ones on the other side of the board.

Correct way to wire:
Image

Now using this code I get a string of two digit numbers off the serial monitor
Code: Select all
//Created August 15 2006
//Heather Dewey-Hagborg
//http://www.arduino.cc

#include <ctype.h>

#define bit9600Delay 84  
#define halfBit9600Delay 42
#define bit4800Delay 188 
#define halfBit4800Delay 94 

byte rx = 6;
byte tx = 7;
byte SWval;

void setup() {
  pinMode(rx,INPUT);
  pinMode(tx,OUTPUT);
  digitalWrite(tx,HIGH);
  digitalWrite(13,HIGH); //turn on debugging LED
  Serial.begin(9600);          //  setup serial
  SWprint('h');  //debugging hello
  SWprint('i');
  SWprint(10); //carriage return
}

void SWprint(int data)
{
  byte mask;
  //startbit
  digitalWrite(tx,LOW);
  delayMicroseconds(bit9600Delay);
  for (mask = 0x01; mask>0; mask <<= 1) {
    if (data & mask){ // choose bit
     digitalWrite(tx,HIGH); // send 1
    }
    else{
     digitalWrite(tx,LOW); // send 0
    }
    delayMicroseconds(bit9600Delay);
  }
  //stop bit
  digitalWrite(tx, HIGH);
  delayMicroseconds(bit9600Delay);
}

int SWread()
{
  byte val = 0;
  while (digitalRead(rx));
  //wait for start bit
  if (digitalRead(rx) == LOW) {
    delayMicroseconds(halfBit9600Delay);
    for (int offset = 0; offset < 8; offset++) {
     delayMicroseconds(bit9600Delay);
     val |= digitalRead(rx) << offset;
    }
    //wait for stop bit + extra
    delayMicroseconds(bit9600Delay); 
    delayMicroseconds(bit9600Delay);
    return val;
  }
}

void loop()
{
    SWval = SWread(); 
    SWprint(toupper(SWval));
    Serial.println(toupper(SWval));    //debug print
}
here is some of the text from my serial monior:
96

80

67

66

80

96

79

96

79

81

65

66

65

96

81
I think these numbers are the data I need, but I'm not sure how to find which is which and label the output as such.

I think this part of the Wiring example code does it, but I'm not sure how to implement it into arduino if I can't get the 'string' var to work
Code: Select all
// parse the buffer received extracting the data 
void processReading(char packet[]) { 
  byte i; 
  char* endptr; 
 
  // start parsing 
  i = 0; 
  i++; 
  humidity = strtod(&packet[i], &endptr);       // next field: humidity 
 
  while(packet[i++] != ',');			// next field: fahrenheit	 
  fahrenheit = strtod(&packet[i], &endptr); 
 
  while(packet[i++] != ',');			// next field: celcius 
  celcius = strtod(&packet[i], &endptr);	 
 
  while(packet[i++] != ',');			// next field: SCPfahrenheit 
  SCPfahrenheit = strtod(&packet[i], &endptr);	 
 
  while(packet[i++] != ',');			// next field: presure 
  presure = strtod(&packet[i], &endptr);	 
 
  while(packet[i++] != ',');			// next field: counter 
 
  while(packet[i++] != '$');			// next field: checksum 
 
  Serial.print("humidity: "); 
  Serial.print(humidity, DEC); 
  Serial.print(" fahrenheit: "); 
  Serial.print(fahrenheit, DEC); 
  Serial.print(" celcius: "); 
  Serial.print(celcius, DEC); 
  Serial.print(" SCPfahrenheit: "); 
  Serial.print(SCPfahrenheit, DEC); 
  Serial.print(" presure: "); 
  Serial.println(presure, DEC); 
By cgdnorth
#114224
Zorink, Did you ever get this working with labels for the values? I am working on a project where I will post weather data to a website via the Ethernet Shield.

Thanks

Chris