Pages: 1 [2]   Go Down
Author Topic: Interfacing with TWO k30 CO2 sensors  (Read 3968 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: April 02, 2013, 12:28:38 pm by Jason_B » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*
  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;

}
Logged

Pages: 1 [2]   Go Up
Jump to: