I'm looking for a working I2C code example for the Sunrise S11 CO2 sensor from Senseair. I'm able to run an UART sample code, but I want to use I2C.
Not working example (for me):
Code: Select all
#include <Wire.h>
char FIND_ADDRESS = 'F';
char READ_CO2 = 'R';
byte address = 0x68;
//byte address = 104; //slave address
void setup() {
// put your setup code here, to run once:
Wire.begin();
Wire.setClock(10000);
Serial.begin(115200);
Serial.println("Type F to find all devices on I2C bus and type R to read CO2 from S-11");
}
void sendDataAndReadToAddress(byte reg, byte address, int bufferSize, int readCount) {
Wire.beginTransmission(address);
for (int k = 0; k < bufferSize; k++) {
Wire.write(reg);
}
Wire.endTransmission(false);
delay(24);
Wire.requestFrom(address, readCount);
delay(12);
int nBytes = Wire.available();
byte buff[nBytes];
int i = 0;
while (Wire.peek() != -1) {
buff[i] = Wire.read();
Serial.print(buff[i],HEX);
Serial.print(" ");
i++;
}
//Serial.write(buff, nBytes);
Serial.print('\n');
int co2 = (buff[0] << 8) | buff[1];
Serial.print("CO2 Concentration: ");
Serial.print(co2);
Serial.print("\n");
}
void getAllAddress() {
//Serial.println("Looking for addresses");
byte error, address;
for (address = 1; address < 128; address++) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
delay(5);
if (error == 0) {
Serial.print(address, HEX);
Serial.print(" ");
}
}
}
void loop() {
// put your main code here, to run repeatedly:
while (Serial.available() == 0) { }
//Delay 10ms to ensure we get the whole message
delay(15);
int serialBufferSize = Serial.available();
byte buff[serialBufferSize];
int i = 0;
while (Serial.peek() != -1 && i < serialBufferSize) {
buff[i] = (byte)Serial.read();
i++;
}
char command = (char)buff[0];
if (command == FIND_ADDRESS) {
getAllAddress();
} else if (command == READ_CO2) {
//The LSB nibble of the second byte contains the number of data bytes being read
//Add 2 for the Command byte and Checksum
int bufferSize = 1;
int readCount = 2;
sendDataAndReadToAddress(0x06, address, bufferSize, readCount);
} else {
Serial.println("Invalid Command... Type F to find all devices on I2C bus and type R to read CO2 from S-11");
}
}
Code: Select all
#include <Wire.h>
const int SUNRISE_EN = 8; //serial EN pin
const uint8_t SUNRISE_ADDR = 0x68; // communication address
const int ATTEMPTS = 5; // Amount of wakeup attempts before time-out
/* Delays in milliseconds*/
const int STABILIZATION_MS = 35;
//¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
void reInitI2C() { // Initialize I2C
Wire.begin();
Wire.setClock(100000); // Setup I2C clock to 100kHz
}
//¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
bool _wakeup(uint8_t target) // Wakes up the sensor by initializing a write operation with no data.
{
int attemps = ATTEMPTS;
int error;
do {
Wire.beginTransmission(target);
error = Wire.endTransmission(true);
Serial.print("Error ");
Serial.println(error);
} while (((error != 0 /*success */) && (error != 2 /*Received NACK on transmit of address*/)) && (--attemps > 0));
if (error == 4) {
reInitI2C();
return false;
}
return (attemps > 0);
}
//¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
void setup()
{
pinMode(SUNRISE_EN, OUTPUT);
digitalWrite(SUNRISE_EN, HIGH);
delay(STABILIZATION_MS); // Wait for sensor start-up and stabilization
reInitI2C(); // Initialize I2C
Serial.begin(115200);
_wakeup(SUNRISE_ADDR);
}
//¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
void loop() {
}
Code: Select all
//Limitations
//
//The library has the following known limitations:
//
// If using multiple software serial ports, only one can receive data at a time.
// Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).
// Not all pins on the Leonardo and Micro support change interrupts, so only the following can be used for RX: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
// On Arduino or Genuino 101 the current maximum RX speed is 57600bps
// On Arduino or Genuino 101 RX doesn't work on Pin 13
#include <SoftwareSerial.h>
#define S11_TX A2 // 12
#define S11_RX A3 // 11
SoftwareSerial s11(S11_TX, S11_RX);
void setup() {
// put your setup code here, to run once:
s11.begin(9600);
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
byte co2Read[] = { 0xfe, 0x04, 0x00, 0x03, 0x00, 0x01, 0xd5, 0xc5 };
s11.write(co2Read, 8);
int millisec = 0;
while(s11.available() <= 0) {
delay(1);
millisec++;
if (millisec > 1500) break;
}
delay(50);
if (s11.available() <= 0) {
Serial.println("no data available");
return;
}
int s11ResponseSize = s11.available();
byte s11Response[s11ResponseSize];
int count = 0;
while (count < s11ResponseSize) {
s11Response[count] = s11.read();
count++;
}
int co2 = (s11Response[3] << 8) | s11Response[4];
Serial.print("CO2 Concentration: ");
Serial.print(co2);
Serial.print("\n");
delay(2000);
}