Go Down

Topic: Interfacing with TWO k30 CO2 sensors (Read 5207 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;

}

Go Up