Go Down

Topic: Interfacing with TWO k30 CO2 sensors (Read 6232 times) previous topic - next topic

Jason_B

#15
Apr 02, 2013, 07:20 pm Last Edit: Apr 02, 2013, 07:28 pm by Jason_B Reason: 1
Once you have set up one of the sensors to have an alternate address, they can share the same Tx and Rx lines. For instance say you have 2 sensors, Sensor_A is at address 0x68, and Sensor_B is at 0x34. you would connect both sensors to the same 2 pins on the arduino (12 and 13 in the example) and when you send a read request with the address 0x68, only Sensor_A will reply, and when you send a request to 0x34 only Sensor_B will reply.

So you only need to initialize one SoftwareSerial.

If you wanted to run it on two separate Softwareserial ports, you could initialize two and use a total of 4 pins. However when using multiple SoftwareSerials you must switch between them manually using the .listen() function. this page explains how to do this: http://arduino.cc/en/Reference/SoftwareSerialListen

Hope this helps.

James_M

I never did manage to get the address change thing to work correctly.  I'm sure I was doing something wrong but I have no clue what.  I did, however, get the two sensors playing nice by using the TwoPortReceive method outlined here http://arduino.cc/en/Tutorial/TwoPortReceive

So far my code checks one sensor, writes it to the LCD then checks the other and displays that on the second LCD line.  Next up, PWM a 24 LED array via a TIP120 based on the CO2 levels.  Code to date is below (I know it's pretty ungainly, I'm figuring this stuff out as I go along).

Code: [Select]
/*
  Software serial multple serial test

Receives from the two software serial ports,
sends to the hardware serial port.

*/

#include <SoftwareSerial.h>
// software serial #1: TX = digital pin 10, RX = digital pin 11
SoftwareSerial portOne(12,13);
#include "Wire.h"
#include "LiquidCrystal.h"

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

// software serial #2: TX = digital pin 8, RX = digital pin 9
// on the Mega, use other pins instead, since 8 and 9 don't work on the Mega
SoftwareSerial portTwo(8,9);

byte readCO2[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25}; //Command packet to read Co2 (see app note)

byte response[] = {0,0,0,0,0,0,0}; //create an array to store the response

//multiplier for value. default is 1. set to 3 for K-30 3% and 10 for K-33 ICB

int valMultiplier = 1;

void setup()
{
// set up the LCD's number of rows and columns:
  lcd.begin(16, 2);
  lcd.print("Hello!");
  delay(5000);
  lcd.setCursor(0, 0);
  lcd.print("CO2-in:");
  lcd.setCursor(0, 1);
  lcd.print("CO2-out:");   
 
// Open serial communications and wait for port to open:
  Serial.begin(9600);


  // Start each software serial port
  portOne.begin(9600);
  portTwo.begin(9600);
}

void loop()
{
  // By default, the last intialized port is listening.
  // when you want to listen on a port, explicitly select it:
  portOne.listen();
  sendRequestA(readCO2);
  unsigned long valCO2A = getValueA(response);
  Serial.print("Co2 A = ");
  Serial.println(valCO2A);
  lcd.setCursor(8, 0);
 
  for (int i = 0; i < 16; ++i)
{
  lcd.write(' ');
}
  lcd.setCursor(8, 0);
  lcd.print(valCO2A); 
  delay(5000);



  // blank line to separate data from the two ports:
  Serial.println();

  // Now listen on the second port
  portTwo.listen();
  sendRequestB(readCO2);
  unsigned long valCO2B = getValueB(response);
  Serial.print("Co2 B = ");
  Serial.println(valCO2B);
  lcd.setCursor(9, 1);
 
  for (int i = 0; i < 16; ++i)
{
  lcd.write(' ');

  lcd.setCursor(9, 1);
  lcd.print(valCO2B);
  delay(5000);


  // blank line to separate data from the two ports:
  Serial.println();
}














//*************************************************************************
void sendRequestA(byte packet[])
{
while(!portOne.available()) //keep sending request until we start to get a response
{
portOne.write(readCO2,7);

delay(50);

}
int timeout=0; //set a timeoute counter
while(portOne.available() < 7 ) //Wait to get a 7 byte response
{
timeout++;
if(timeout > 10) //if it takes to long there was probably an error
{
while(portOne.available()) //flush whatever we have
portOne.read();
break; //exit and try again
}
delay(50);
}
for (int i=0; i < 7; i++)
{
response[i] = portOne.read();
}
}


unsigned long getValueA(byte packet[])
{
int high = packet[3]; //high byte for value is 4th byte in packet in the packet
int low = packet[4]; //low byte for value is 5th byte in the packet
unsigned long val = high*256 + low; //Combine high byte and low byte with this formula to get value
return val* valMultiplier;

}



//*************************************************************************
void sendRequestB(byte packet[])
{
while(!portTwo.available()) //keep sending request until we start to get a response
{
portTwo.write(readCO2,7);

delay(50);

}
int timeout=0; //set a timeoute counter
while(portTwo.available() < 7 ) //Wait to get a 7 byte response
{
timeout++;
if(timeout > 10) //if it takes to long there was probably an error
{
while(portTwo.available()) //flush whatever we have
portTwo.read();
break; //exit and try again
}

delay(50);

}
for (int i=0; i < 7; i++)
{
response[i] = portTwo.read();
}

}


unsigned long getValueB(byte packet[])
{
int high = packet[3]; //high byte for value is 4th byte in packet in the packet
int low = packet[4]; //low byte for value is 5th byte in the packet
unsigned long val = high*256 + low; //Combine high byte and low byte with this formula to get value
return val* valMultiplier;

}

greis006

Jason, i Did a test with one sensor using the same code posted here, i have connected the sensor to the arduino using pins 12 and 13 to the UART conectors on the sensor. Please correct me if I am wrong but the sensor address must be needed only if I use the IC2 connection. The sensor address should not matter for the UART connection. My thinking is correct.

To use the sensor address the connection used must be to the IC2 arduino pins that are not the common digital pins 1 trough 13.

So if I use the UART connection I don't need to change one sensor address.

What is the best option? UART or IC2. I was thinking to use the IC2 connection because I need the arduino Digital Pins for other sensors.

I didn't find (at least yest) a sample using the IC2 connections on co2meter site. Can you point how I do the IC2 connection and programming with arduino?

Regards

Go Up