Go Down

Topic: Serial read from sensor (Read 4 times) previous topic - next topic

point5

Hi Andy,

Your right - at this stage I just want to 'see' the output, eventually printing to an LCD and finally data logging.

The sensor is pre-production so not too much info available to share - it does output to both I2C & UART.

Thanks for the serial expalination - I'm clear now - would also expalin why I couldn't upload with the sensor connected!

point5

Hi Groove,

OKAY - that would explain a lot - it looks like I am back to headscratching (well scrathced already) with I2C then or buying a MEGA?

Groove

Well, I'd go with the Mega, but then it isn't my money  ;D

You could persist with I2C - did you remember the pull-up resistors
(and the fact that I2C is on the analogue port)?
Per Arduino ad Astra

point5

#18
Oct 28, 2009, 11:06 pm Last Edit: Oct 28, 2009, 11:18 pm by point5 Reason: 1
Ideally I would get I2C working :-)  I am using 4K7 pullups to 5V and analog pins 4 & 5.  The code below (written by another helpful soul)returns a result but the bytes returned are all 8's with a PPM: 2056 !!!

IE:
CO PPM: 2056
Data received:8,8,8,8,8,8,8,


Code: [Select]
#include <Wire.h>
//wire library

#define address 0x31
//address of the sensor

#define delayC 5000
//delay count in ms

#define baudrate 9600
//baudrate for communication

void setup()
{
 Wire.begin();
 Serial.begin(baudrate);
}

void loop()
{
 //Serial.print("CO PPM: ");
 
 int co=0;

 Wire.beginTransmission(address);
 // start the transmission
 
 Wire.send('R');
   
 Wire.endTransmission();
 //end the transmission
 
/// Wire.requestFrom(address, 7);
 
 // format
 // 1) Configuration 0x08
 // 2) CO (high byte?)
 // 3) CO (low byte?)
 // 4) reserved
 // 5) reserved
 // 6) reserved
 // 7) reserved
 
 Serial.print ("Data received:");
 for (int i=0;i<7;i++)
 {
   byte c;
   c = getI2Cchar();
   Serial.print(c,HEX);
   Serial.print(',');
   if (i==1) co = c;
   if (i==2) co = (co << 8) | c;
 }
 Serial.println("");
 Serial.print("CO PPM: ");
 Serial.println(co);

 delay(delayC);
}

byte getI2Cchar()
{
 delay(2); // delay 2mS
 Wire.requestFrom(address, 1);
 return (Wire.receive());
}

AWOL

#19
Oct 29, 2009, 11:57 am Last Edit: Oct 29, 2009, 12:11 pm by AWOL Reason: 1
Code: [Select]
Serial.print ("Data received:");
 for (int i=0;i<7;i++)
 {
   byte c;
   c = getI2Cchar();
   Serial.print(c,HEX);
   Serial.print(',');
   if (i==1) co = c;
   if (i==2) co = (co << 8) | c;
 }


I'm not sure this approach will work - I think you're repeating the configuration byte.

It looks to me like you're trying to get one byte at a time from I2C, printing it and then trying to get another.

You'd be better off requesting and buffering all the data from the sensor, then printing it to Serial from the buffer.

Code: [Select]
void getI2Cdata()
{
 delay(2); // delay 2mS
 Wire.requestFrom(address, databytes);
 while (!Wire.available ())
   ;
 for (int i = 0; i < databytes; ++i) {
   data_buffer [i] = Wire.receive();
 }  
}
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

point5

Hi Awol,

Thanks for the advice - I substituted your code into the script but I'm getting errors beyond my ability.  It will be my lack of syntax/knowledge !!  Would you be up for patching it into the original code?

AWOL

I left the definition of the missing elements "as an exercise for the reader"
(mainly because I don't have an IDE available at the moment to check it)

Uncompiled, therefore untested; I tried to leave as much of the original code as I could.

Code: [Select]
#include <Wire.h>
//wire library

#define address 0x31
//address of the sensor

#define delayC 5000
//delay count in ms

#define baudrate 9600
//baudrate for communication

const int databytes = 7;
byte data_buffer [data_bytes];

void setup()
{
 Wire.begin();
 Serial.begin(baudrate);
}

void loop()
{
 //Serial.print("CO PPM: ");
 
 int co=0;

 Wire.beginTransmission(address);
 // start the transmission
 
 Wire.send('R');
   
 Wire.endTransmission();
 //end the transmission
 
/// Wire.requestFrom(address, 7);
 
 // format
 // 1) Configuration 0x08
 // 2) CO (high byte?)
 // 3) CO (low byte?)
 // 4) reserved
 // 5) reserved
 // 6) reserved
 // 7) reserved

 getI2Cdata();

 Serial.print ("Data received:");
 for (int i=0;i<7;i++)
 {
   byte c = data_buffer [i];
   Serial.print(c,HEX);
   Serial.print(',');
   if (i==1) co = c;
   if (i==2) co = (co << 8) | c;
 }
 Serial.println("");
 Serial.print("CO PPM: ");
 Serial.println(co);

 delay(delayC);
}

void getI2Cdata()
{
 delay(2); // delay 2mS
 Wire.requestFrom(address, databytes);
 while (!Wire.available ())
   ;
 for (int i = 0; i < databytes; ++i) {
   data_buffer [i] = Wire.receive();
 }
}


(the clue was "  // 1) Configuration 0x08" and 2056 =0x0808)
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

point5

Well, GOD MEMBER is about right - you have fixed it - very, very much appreciated.

Thanks for your input on this and sorry for my lack of skill - I now know a little more :-)

Cheers

AWOL

Since you were getting some non-zero or non-255 data, there was a good chance that it was partly working.
The problem was your "getI2Cdata" was restarting the bus transaction each time it was called, so you always got the first byte of a new packet.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

point5

ahhh... new problem !!!  It's all working very nicely printing out to an LCD but..... after a few short minutes it seems to crash - ie it all looks the same but the value remains the same (even when I know it should be changing)  Any ideas what could be going on?

The code used is:

Code: [Select]
#include <LCD4Bit_mod.h>
LCD4Bit_mod lcd = LCD4Bit_mod(2);

#include <Wire.h>

#define address 0x31

#define delayC 2000

#define baudrate 9600

char co_str[10];

int co;

const int data_bytes = 7;
byte data_buffer [data_bytes];

void setup()
{
 Wire.begin();
 Serial.begin(baudrate);
 lcd.init();
 lcd.clear();
 lcd.printIn("Value");
}

void loop()
{
 Wire.beginTransmission(address);
 Wire.send('R');
 Wire.endTransmission();
 
 getI2Cdata();

 for (int i=0;i<7;i++)
 {
   byte c = data_buffer [i];
   if (i==1) co = c;
   if (i==2) co = (co << 8) | c;
 }
 lcd.cursorTo(2, 0);
 lcd.printIn(itoa((long)co,co_str,10));
 lcd.printIn(" ppm  ");
 delay(delayC);
}

void getI2Cdata()
{
 delay(2);
 Wire.requestFrom(address, data_bytes);
 while (!Wire.available ());
 for (int i = 0; i < data_bytes; ++i) {
 data_buffer [i] = Wire.receive();
 }
}
 

AWOL

#25
Oct 30, 2009, 11:38 am Last Edit: Oct 30, 2009, 11:42 am by AWOL Reason: 1
OK, try to isolate the problem.
Write a sketch that doesn't have the I2C stuff, and just writes an incrementing count to the LCD every second, and see if that runs on.
Without your exact setup, it is difficult to diagnose.

[edit]Then do the opposite - cut out the LCD, and just write I2C results to the Serial.[/edit]
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

point5

Thanks AWOL - will give it a try.

point5

Hmmm - this routine has been running happily for an hour or so - that's with the sensor connected.  Not sure what to do next?

Code: [Select]
#include <LCD4Bit_mod.h>
LCD4Bit_mod lcd = LCD4Bit_mod(2);

#define address 0x31

#define delayC 1000

char co_str[10];

void setup()
{
 
 lcd.init();
 lcd.clear();
 lcd.printIn("test");
}

void loop()
{
 
 for (int co=0; co >= 0; co++){
 
 lcd.cursorTo(2, 0);
 lcd.printIn(itoa((long)co,co_str,10));
 lcd.printIn(" number  ");
 delay(delayC);
 }
}

AWOL

It doesn't really matter if the sensor is or isn't connected - it's an I2C slave, so unless you talk to it, it won't do a great deal.

Did you try same, but writing the real sensor results to Serial, i.e re-enabling I2C?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

point5

Printing to the serial window rather than the LCD also produces a crash - first try after 35 samples, second time after 49 samples.  The sensor is still blinking away though.

Go Up