General

X-Board v2 and Pachube data on LCD

userHead synekvl 2012-04-21 16:09:34 7395 Views4 Replies
The described project reads feed data on Pachube and shows them on LCD. The project is quite simple. I've used following HW:

- DFRobot X-Board v2 (DFR0162)
- DFRobot FTDI Basic Breakout (DFR0065) for uploading the sketch code to X-Board
- LCD2004 display
- i2c / SPI character LCD backpack by Adafruit (www.adafruit.com/products/292)
- DFRobot USB Power adapter (FIT0107)
- USB cable for power, Ethernet cable to connect it to router/internet


The connection between X-Board and LCD is serial using four wires only. Of course, you may use also the parallel connection without Adafruit (or other) adapter but it uses much more X-Board pins. Information on wiring you may find here: http://www.ladyada.net/products/i2cspilcdbackpack/

So we have the hardware, now it is time for software. To compile your code you need:

- Arduino IDE, the latest version is 0023 now
- Pachube library ERxPachube available here: http://code.google.com/p/pachubelibrary/ (note: please download and install library version compatible with your IDE, i.e. for IDE 0023 is the latest version ERxPachube-I-2.5.zip)
- LCD LiquidTWI library by FalconFour can be found on http://hostfile.org/LiquidTWI.rar, the forum topic http://forums.adafruit.com/viewtopic.ph ... 6&p=113177

The sketch code:
Code: Select all
/*
 Demonstration sketch for X-Board by DFRobot ( http://www.dfrobot.com/index.php?route=product/product&filter_name=dfr0162&product_id=564 ) and Adafruit i2c/SPI LCD backpack
 using MCP23008 I2C expander( http://www.ladyada.net/products/i2cspilcdbackpack/index.html )

  The circuit:
 *  5V to X-Board 5V pin
 * GND to X-Board GND pin
 * CLK to X-Board #5
 * DAT to X-Board #4
*/

// include the library code:
#include <ERxPachube.h>
#include <Ethernet.h>
#include <LiquidTWI.h>
#include <SPI.h>
#include <Wire.h>

#define PACHUBE_API_KEY         ".............." // fill in your API key PACHUBE_API_KEY
#define PACHUBE_FEED_ID         .....            // fill in your PACHUBE_FEED_ID


unsigned long lastConnectionTime = 0;                // last time you connected to the server, in milliseconds
const int postingInterval = 29500;                   // delay in [ms] between updates from Pachube.com

String data[5];                 // My sketch is for 5 streams. Enter YOUR number of datastreams you will be recovering from Pachube.
                       // Standard ERxPachube library is set for 4 streams only. If you need more go to the file ERxPachube.h
                                                     // and change #define MAX_DATASTREAM_NUM x to meet your requirements

byte mac[] = { 0xCC, 0xAC, 0xBE, 0xEF, 0xFE, 0x91 }; // make sure this is unique on your network
byte ip[] = { 192, 168, 2, 9 };                      // set your own IP address

ERxPachubeDataIn datain( PACHUBE_API_KEY, PACHUBE_FEED_ID );

LiquidTWI lcd( 0 );                    // Connect via i2c, default address #0 (A0-A2 not jumpered)


void setup(){
  // set up the LCD's number of rows and columns: 
  lcd.begin( 20, 4 );                  // depends on your LCD type, I use 2004 LCD
  Ethernet.begin( mac, ip );
  delay( 100 );
  lastConnectionTime = postingInterval;
}


void loop(){
  
  if( millis()-lastConnectionTime > postingInterval ){
  
    int status = datain.syncPachube();
    String stat = char(status);
    GetDataStream( datain );    

    lcd.clear();
    
    if( status != 200 ){
      lcd.setCursor( 20 - stat.length(), 0 );      // if connection to Pachube is NOT OK then status "number" is shown in upper right corner
      lcd.print(status);
    }
    else {
      lcd.setCursor( 19, 0 );
      lcd.print(".");                  // if connection to Pachube is OK (status code=200) then "." is shown in upper right corner
    }

    // set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor( 0, 0 );                        // FIRST row - Outer temperature
    lcd.print("Outer:");
    lcd.setCursor( 13 - data[3].length(), 0 );
    lcd.print(data[3]);
    lcd.setCursor( 13, 0 );lcd.print(char(223));lcd.print("C");

    lcd.setCursor( 0, 1 );                        // SECOND row - Inner temperature
    lcd.print("Inner:");
    lcd.setCursor( 8, 1 ) ;
    lcd.print(data[0]);
    lcd.setCursor( 13, 1 );lcd.print(char(223));lcd.print("C");
  
    lcd.setCursor( 0, 2 );                        // THIRD row - Names of another three values
    lcd.print("Press");
    lcd.setCursor( 9, 2 );
    lcd.print("Trend");
    lcd.setCursor( 16, 2 );
    lcd.print("Accu");
        
    lcd.setCursor( 0, 3 ) ;                        // FOURTH row - atm.pressure, trend and accu voltage values
    lcd.print(data[1]);      
    lcd.setCursor( 11 - data[2].length()/2, 3 ) ;
    lcd.print(data[2]);
    lcd.setCursor( 17, 3 ) ;
    lcd.print(data[4]);

    lastConnectionTime = millis();
  }
  if( millis()-lastConnectionTime > postingInterval/2 ){      // in the half of posting period the Units are shown in THIRD row instead on value's names
    lcd.setCursor( 0, 2 );
    lcd.print(" hPa     Pa/Hr    mV");
  }
}

void GetDataStream( const ERxPachube& pachube ){

    unsigned int count = pachube.countDatastreams();

    for( unsigned int i = 0; i < count; i++ ){
      data[i] = ( pachube.getValueByIndex(i) );
    }      
}
I recover all 5 values from Pachube: Outer and inner temperature, atmospheric pressure and trend of its changes, and LiPO accumulator voltage. My Pachube feed is 25574, so you may check it on Pachube's site.

The sketch is very simple. The ways how to display the values on LCD is endless so take my layout as an idea only. If you have any questions don't hesitate to contact me either here or on synekvl AT gmail DOT com

Have a nice day
Vladimir
2012-04-25 10:38:17 Vladimir,


Thanks again for the great contribution. I must apologize for the confusion caused by the sample code posted in the community. There is a problem with the code highlight provided with wordpress. It keeps changing the "<" and ">" symbols.


I think I finally fixed the problem.  I have updated the code as well.


Cheers!
userHeadPic Hector
2012-04-24 23:47:12 I'm here again,

I went through IDE 1.0, I had to search little bit on the internet, but finally I got compiliable code. Can you replace the last one in community blog, please ??
Code: Select all
/*
Modified code for Arduino IDE ver. 1.0

  The circuit:
 * 5V to Arduino 5V pin
 * GND to Arduino GND pin
 * CLK to Analog #5
 * DAT to Analog #4
*/

// include the library code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ERxPachube.h>
#include <Ethernet.h>
#include <SPI.h>

#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args)  write(args);
#else
#define printByte(args)  print(args,BYTE);
#endif

#define PACHUBE_API_KEY				"................" // fill in your API key PACHUBE_API_KEY
#define PACHUBE_FEED_ID				.....

String data[5];

byte mac[] = { 0xCC, 0xAC, 0xBE, 0xEF, 0xFE, 0x91 }; // make sure this is unique on your network
byte ip[] = { 192, 168, 2, 9 };                      // no DHCP so we set our own IP address

unsigned long lastConnectionTime = 0;               // last time you connected to the server, in milliseconds
const int postingInterval = 30000;                  // delay in [ms] between updates from Pachube.com

ERxPachubeDataIn datain(PACHUBE_API_KEY, PACHUBE_FEED_ID);

//void PrintDataStream(const ERxPachube& pachube);

// Connect via i2c, default address #0 (A0-A2 not jumpered)
LiquidCrystal lcd(0);


void setup() {
  // set up the LCD's number of rows and columns: 
  lcd.begin(20, 4);
  Ethernet.begin(mac, ip);
  delay(100);
  lastConnectionTime = postingInterval;
}


void loop() {
  
  if( millis()-lastConnectionTime > postingInterval ){
  
    lastConnectionTime = millis();
    int status = datain.syncPachube();
    GetDataStream(datain);    

    // set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
    lcd.clear();
    
    if( status != 200 ){
      lcd.setCursor( 20 - sizeof(status)+1, 0 );
      lcd.print(status);
    }
    else {
      lcd.setCursor( 19, 0 );
      lcd.print(".");
    }

    lcd.setCursor( 0, 0 );
    lcd.print("Outer:");
    lcd.setCursor( 12 - data[3].length(), 0 );
    lcd.print( data[3] );
    lcd.setCursor( 13, 0 );lcd.print(char(223));lcd.print("C");

    lcd.setCursor( 0, 1 );
    lcd.print("Inner:");
    lcd.setCursor( 8, 1 ) ;
    lcd.print(data[0]);
    lcd.setCursor( 13, 1 );lcd.print(char(223));lcd.print("C");
  
    lcd.setCursor( 0, 2 );
    lcd.print("Press");
    lcd.setCursor( 9, 2 );
    lcd.print("Trend");
    lcd.setCursor( 16, 2 );
    lcd.print("Accu");
        
    lcd.setCursor( 0, 3 ) ;
    lcd.print( data[1] );      
    lcd.setCursor( 11 - data[2].length()/2, 3 ) ;
    lcd.print( data[2] );
    lcd.setCursor( 17, 3 ) ;
    lcd.print( data[4] );
  }

  if( millis()-lastConnectionTime > postingInterval/2 ){    // THIRD row shows Units instead of values
    lcd.setCursor( 0, 2 );
    lcd.print(" hPa     Pa/Hr    mV");
  }

  char buf[ data[4].length()+1 ];
  data[4].toCharArray( buf, data[4].length()+1 );
  int volt = atoi( buf );
  
  if( volt < 340 && millis()%2000 < 1000 ){              // voltage value blinks every 1sec when less than 340
    lcd.setCursor( 17, 3 );
    lcd.print( "   " );
  }
  else {
    lcd.setCursor( 17, 3 );
    lcd.print(volt);
  }
}

void GetDataStream( const ERxPachube& pachube ){
  
  unsigned int count = pachube.countDatastreams();

  for(unsigned int i = 0; i < count; i++){
    data[i] = pachube.getValueByIndex(i);
  }      
}
There is a small additional code at the end causing the accu voltage starts to blink when the value is less than 3.40 V.

That's all from my side.

Cheers
Vladimir
userHeadPic synekvl
2012-04-24 14:51:09 Hi Hector,

I have nothing against the modification of my contribution. Thanks to your modification I finally got a courage and I installed IDE version1.0. But here the problems start - I installed IDE 1.0, all libraries as you changed, I took your modified code and:

1. there are missing libraries in all #include statements
2. there are characters as "&&" instead "==" and ">" instead of ">" (the last is not only in arduino version statement but also further in the code ...)
3. did you try to compile the code in IDE 1.0 ?? I can't compile it as IDE 1.0 takes in different way than previous ver.0023 string conversions in two places of the code. I can't do that without change of the code.

Please check / change above items as I would like to avoid any misunderstandings in future if someone will be willing to use this project ....  ;) and let me know whether you can compile it in IDE 1.0 (maybe I have something wrong here).
userHeadPic synekvl
2012-04-23 13:47:32 Hi Vladimir,


We have slightly modified your post and turned it into a blog post, I hope thats ok with you.  You have been given credit for it. Thanks for the contribution!




You can see the blog post: here
userHeadPic Hector