Go Down

Topic: Temp, Humidity CO2 sensor and library. (Read 139761 times) previous topic - next topic

Simas32

Hey everyone.  First time poster here. 

Currently running the Github library and sample sketch posted by DirtGambit (thanks much).  The COZIR is functioning when I run a sketch shell on my Mega 2560 and hook up the COZIR TX and RX to the hardware serial on the Mega.  The humidity, temp, and CO2 readings all display on the output.  However, when I run the sample sketch, the output is as follows:

Fahrenheit : 32.00
Humidity : 0.00
CO2 : 0
Digital Filter : 0

When I adjust the Digital Filter value, all values change directly with the digital filter value.  I'm stumped.  Please help.

kslstn

@Dew321, I'm not entirely sure if I understand entirely what you want, but I created a sketch for logging to SD card where from 15 measurements only the highest and lowest are saved and an average is calculated for every added measurement, until the measurements for that array are saved. If I'm correct, you want to see the velocity at which change happens, so you only have to divide by time after that. The snippet:

Code: [Select]
  float currentCO2 = (float)czr.CO2();
  if ((currentCO2 < CO2[0]) || (pollsInLog == 1)){// save CO2 if it's the lowest value in this interval.
    CO2[0] = currentCO2;
  }
  CO2[1] = (CO2[1] * (pollsInLog - 1)/pollsInLog) + (currentCO2 / pollsInLog);// calculate and save average
  if (currentCO2 > CO2[2]){// save CO2 if it's the highest value in this interval.
    CO2[2] = currentCO2;
  }


The complete sketch is over here on GitHub.


If others are looking for inspiration for logging measurements to an SD card: check it out :-)

kslstn

#137
Feb 26, 2015, 09:46 am Last Edit: Feb 26, 2015, 11:09 am by kslstn
@Simas, I had that issue too. After setting the sensor to poll mode and starting the calibration manually, everything worked fine with Rob's library.

You can find the sketches to do that here on the forum and in my repo (the SetToPolling and Calibrate sketches).

Edit: Also make sure the sensor is connected to pin 2 and 3. If, after trying the above, you still get the 0 readings, try switching the wires, there was some confusing about Tx and Rx. And give it a bit of time. After it's connected to power, the sensor needs about 5 seconds before it measures correctly.

nitrojet

Simas, how did you get it working with the Mega 2560?

I don't seem to be able to get too far with hardware serial, considering writing from scratch but if you have been able to, please let me know.

Regards

robtillaart

@nitrojet

took a while before I had some time to dive into it. Find attached a version of the library with a slightly modified interface that works for both Software and HardwareSerial; The examples compile on a MEGA

Please give it a try

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

kslstn

Because I wanted to get rid of the delay() in the library (my project has fading LEDs), I created a rather different version. It's a bit harder to use and doesn't have all the settings and calibration functions. In return it's a bit lighter and as mentioned, doesn't slow your loop down.

Instead of a single call, two functions have to be called from within the loop. The first send the request to the sensor, the second is repeated until the sensor returns data 200 ms later. There's an example sketch that demonstrates it. Maybe it's of use to anyone!

jmnijsse

#141
Apr 08, 2015, 01:39 pm Last Edit: Apr 08, 2015, 01:46 pm by jmnijsse
Hello,

I have a Cozir ambient sensor +RH/T.
Until last week it was oke.
And now, without any changes (as far as i know) it stops Serial.printing the values.
It stops whit any serial.printing, such as a testing text Serial.println("setup");

I used this code:
Code: [Select]

#include <SoftwareSerial.h>
#include "cozir.h"

SoftwareSerial nss(3,2);
COZIR czr(nss);

void setup()
{
  Serial.begin(9600);
  delay(3000);
  czr.SetOperatingMode(CZR_POLLING);
  //czr.SetOperatingMode(CZR_STREAMING);
  //czr.CalibrateFreshAir();
  //czr.SetDigiFilter(64);
}

void loop()
{
  Serial.println("loop");
  float t = czr.Celsius();
  float f = czr.Fahrenheit();
  float h = czr.Humidity();
  int c = czr.CO2();
  int digi = czr.GetDigiFilter();
 
  Serial.print("Celcius : ");Serial.println(t);
  Serial.print("Fahrenheit : ");Serial.println(f);
  Serial.print("Humidity : ");Serial.println(h);
  Serial.print("CO2 : ");Serial.println(c);
  Serial.print("Digital Filter : ");Serial.println(digi);   
}


And when I, at DirtGambit's earlier post, uncomment the 'czr.SetOperatingMode(CZR_POLLING);' line, Arduino comes with an error:

F:\Software\USB-stick\arduino-1.0.5-r2\libraries\cozir103/cozir.h: In function 'void setup()':
F:\Software\USB-stick\arduino-1.0.5-r2\libraries\cozir103/cozir.h:97: error: 'void COZIR::SetOperatingMode(uint8_t)' is private
Cozir_CO2:12: error: within this context

Calibrate and filter options are allowed. Only at Polling and Streaming uncommenting he gives an error.

What happened?
What means 'is private' in this case?

Thanks,

Johan


robtillaart

Apparently the 1.0.3 and up version declares    

Code: [Select]
void SetOperatingMode(uint8_t mode);

as private.

That means that a user (you) of the class are not allowed to use that function, only public functions are callable as user of the class.

The example code seems to be copied from the 1.0.2 version and is not compatible with 1.0.3 and up.


disclaimer: I do not have a Cozir sensor to verify

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

jmnijsse

Ah, thats the problem.
I had play with different libraries. And with a clean up stored only the newest. Combined with an older sketch.
Thanks, it works again...

J.

jmnijsse

Another question (perhaps it belongs to another subforum...).

I used v-usb to put the values in Excel. https://www.hackster.io/rayburne/arduino-to-excel-using-v-usb
For many sensors it works fine.

BUt with the Cozir, it fills 20 rows, or 50 and it stops.

The cozir is a low-power sensor, so it couldn't make a voltage-ripple in the v-usb protocol?
Maybe the SoftwareSerial library uses extra power? I don't think so, but you never know...

This is the total code:
Code: [Select]
/*
This sketch is used for measuring CO2 with a COZIR Ambient sensor.
 With the V-USB protocol the values are dropped in Excel or any spreadsheet whatsoever
 */

#include "UsbKeyboard.h"
//#include <avr/pgmspace.h>
#include <SoftwareSerial.h>
#include "cozir.h"

// #define BUTTON_PIN 10
#define WIP 1
int sch = 3;

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)
int delaytime = 400;
int delaytimes = (delaytime/1000);

unsigned long time;
long oldtime;
long newtime;

String sOut;


SoftwareSerial nss(6,13);
COZIR czr(nss);

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

void delayMs(unsigned int ms) {    // Safe delay helper function
  for (int i = 0; i < ms; i++) {
    delayMicroseconds(1000);
  }
}


void setup() {
  //setup the COZIR sensor

  Serial.begin(9600);
  delay(3000);
  //czr.SetOperatingMode(CZR_POLLING);
  //czr.SetOperatingMode(CZR_STREAMING);
  //czr.CalibrateFreshAir();
  //czr.SetDigiFilter(64);


  //setup the V-usb protocol
  // Disable timer0 since it can mess with the USB timing. Note that
  // this means some functions such as delay() will no longer work.
  TIMSK0&=!(1<<TOIE0);
  // Clear interrupts while performing time-critical operations
  cli();
  // Force re-enumeration so the host will detect us
  usbDeviceDisconnect();
  delayMs(250);
  usbDeviceConnect();

  // Set interrupts again
  sei();
  pinMode(11, INPUT);
  pinMode(sch, INPUT);

  for (int i = 0; i < 250; i++){            // 10 second delay in lieu of using Button press on pin 10
    digitalWrite(13, !digitalRead(13));
    // while (digitalRead(BUTTON_PIN) != 0)
    UsbKeyboard.update();
    delayMs(20);

  }
  //setup the headers in the first row of Excel
  set_header();

}

void loop() {

  //initialize the state of the button which gives an enter after filling first row  
  int sch_state = digitalRead(sch);

  //potmeter to set the frequency of sampling
  int fr_pot = analogRead(A2);
  long frequency = map(fr_pot, 0, 1023, 500, 10000);

  //get the CO2-value
  int c = czr.CO2();

  //set the timestamp
  newtime = oldtime + frequency;
  oldtime = newtime;


  // Put it all in al string
  UsbKeyboard.update();
  sOut = "";
  sOut = (String(newtime));
  KeyStrokeAlpNum(sOut);
  UsbKeyboard.sendKeyStroke(43);
  sOut = (String(c));
  KeyStrokeAlpNum(sOut);
  UsbKeyboard.sendKeyStroke(0x50);

  //looks for buttonstate: HIGH makes a table, LOW overwrite the measurement
  if (sch_state == HIGH){
    for (int x = 0; x < 1; x++){
      UsbKeyboard.sendKeyStroke(KEY_ENTER);
    }
  }

  //delay between samples
  delayMs(frequency);  
}

void set_header(){

  String first_sensor;
  String second_sensor;
  String delaytijd;

  delaytijd = "TIJD MILLIS";
  first_sensor = "SENSOR 1";            // Using capitals is neccessary
  second_sensor = "SENSOR 2";
  KeyStrokeAlpNum(delaytijd);
  UsbKeyboard.sendKeyStroke(43);  
  KeyStrokeAlpNum(first_sensor);
  UsbKeyboard.sendKeyStroke(43);    
  KeyStrokeAlpNum(second_sensor);
  UsbKeyboard.sendKeyStroke(KEY_ENTER);
  UsbKeyboard.sendKeyStroke(0x50);
  UsbKeyboard.sendKeyStroke(0x50);
}


void KeyStrokeAlpNum(String Sc){
  int sPoint = Sc.length();          // Pointer to end-of-String (inc. null)
  for (int x = 0; x < sPoint; x++){
    int y = x + 1;
    if (Sc.substring(x, y) == "H"){  // substring single character: y = x+1
      UsbKeyboard.sendKeyStroke(KEY_H, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "L"){
      UsbKeyboard.sendKeyStroke(KEY_L, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == " "){
      UsbKeyboard.sendKeyStroke(KEY_SPACE);
    }
    else if (Sc.substring(x, y) == "1"){
      UsbKeyboard.sendKeyStroke(KEY_1);
    }
    else if (Sc.substring(x, y) == "2"){
      UsbKeyboard.sendKeyStroke(KEY_2);
    }
    else if (Sc.substring(x, y) == "3"){
      UsbKeyboard.sendKeyStroke(KEY_3);
    }
    else if (Sc.substring(x, y) == "4"){
      UsbKeyboard.sendKeyStroke(KEY_4);
    }
    else if (Sc.substring(x, y) == "5"){
      UsbKeyboard.sendKeyStroke(KEY_5);
    }
    else if (Sc.substring(x, y) == "6"){
      UsbKeyboard.sendKeyStroke(KEY_6);
    }
    else if (Sc.substring(x, y) == "7"){
      UsbKeyboard.sendKeyStroke(KEY_7);
    }
    else if (Sc.substring(x, y) == "8"){
      UsbKeyboard.sendKeyStroke(KEY_8);
    }
    else if (Sc.substring(x, y) == "9"){
      UsbKeyboard.sendKeyStroke(KEY_9);
    }
    else if (Sc.substring(x, y) == "0"){
      UsbKeyboard.sendKeyStroke(KEY_0);
    }
    else if (Sc.substring(x, y) == "."){
      UsbKeyboard.sendKeyStroke(55);
    }
    else if (Sc.substring(x, y) == "-"){
      UsbKeyboard.sendKeyStroke(45);
    }
    else if (Sc.substring(x, y) == "A"){
      UsbKeyboard.sendKeyStroke(KEY_A, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "B"){
      UsbKeyboard.sendKeyStroke(KEY_B, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "C"){
      UsbKeyboard.sendKeyStroke(KEY_C, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "D"){
      UsbKeyboard.sendKeyStroke(KEY_D, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "E"){
      UsbKeyboard.sendKeyStroke(KEY_E, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "F"){
      UsbKeyboard.sendKeyStroke(KEY_F, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "G"){
      UsbKeyboard.sendKeyStroke(KEY_G, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "I"){
      UsbKeyboard.sendKeyStroke(KEY_I, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "J"){
      UsbKeyboard.sendKeyStroke(KEY_J, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "K"){
      UsbKeyboard.sendKeyStroke(KEY_K, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "M"){
      UsbKeyboard.sendKeyStroke(KEY_M, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "N"){
      UsbKeyboard.sendKeyStroke(KEY_N, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "O"){
      UsbKeyboard.sendKeyStroke(KEY_O, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "P"){
      UsbKeyboard.sendKeyStroke(KEY_P, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "Q"){
      UsbKeyboard.sendKeyStroke(KEY_Q, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "R"){
      UsbKeyboard.sendKeyStroke(KEY_R, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "S"){
      UsbKeyboard.sendKeyStroke(KEY_S, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "T"){
      UsbKeyboard.sendKeyStroke(KEY_T, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "U"){
      UsbKeyboard.sendKeyStroke(KEY_U, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "V"){
      UsbKeyboard.sendKeyStroke(KEY_V, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "W"){
      UsbKeyboard.sendKeyStroke(KEY_W, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "X"){
      UsbKeyboard.sendKeyStroke(KEY_X, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "Y"){
      UsbKeyboard.sendKeyStroke(KEY_Y, MOD_SHIFT_LEFT);
    }
    else if (Sc.substring(x, y) == "Z"){
      UsbKeyboard.sendKeyStroke(KEY_Z, MOD_SHIFT_LEFT);
    }

  }
  // Return
}

/*  Additional translations
 
 45 -
 46 =
 47 [
 48 ]
 49 \
 50 \
 51 ;
 52 '
 53 `
 54 ,
 55 .
 56 /
 
 84 /
 85 *
 86 -
 87 +
 */


kslstn

jmnijsse, if the sensor's signal output voltage would be too low, you wouldn't get any values from it. Moreover, it's powered by the Arduino, so don't worry about that.

Your issue has nothing to do with the sensor. I've had a issue with similar symptoms though. In my case, it happens only when a sketch is big and after multiple logs. Therefore, I'm pretty sure it's a memory issue. As I don't have all your libraries installed, I can't verify the size of the compiled program, so it may be something else.

jmnijsse

Ok, thanks.
The size is 12.366 bites (of 32.256)

I'll looking further in this way...


J.

robtillaart

Your application uses strings quite intensively and as the String class uses dynamic memory it gets possibly (big chance) fragmented. You could do a test the amount of freeRAM with this function

Code: [Select]

int freeRam ()
{
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
};

Calling at a fixed location in loop() should always give the same result. If it changes you have a memory leak.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

toledofjose

Hey everyone.  First time poster here. 

Currently running the Github library and sample sketch posted by DirtGambit (thanks much).  The COZIR is functioning when I run a sketch shell on my Mega 2560 and hook up the COZIR TX and RX to the hardware serial on the Mega.  The humidity, temp, and CO2 readings all display on the output.  However, when I run the sample sketch, the output is as follows:

Fahrenheit : 32.00
Humidity : 0.00
CO2 : 0
Digital Filter : 0

When I adjust the Digital Filter value, all values change directly with the digital filter value.  I'm stumped.  Please help.
@Simas, I had that issue too. After setting the sensor to poll mode and starting the calibration manually, everything worked fine with Rob's library.

You can find the sketches to do that here on the forum and in my repo (the SetToPolling and Calibrate sketches).

Edit: Also make sure the sensor is connected to pin 2 and 3. If, after trying the above, you still get the 0 readings, try switching the wires, there was some confusing about Tx and Rx. And give it a bit of time. After it's connected to power, the sensor needs about 5 seconds before it measures correctly.
i have the same problem as simas but i cant fixed it with the solution provided by kslstn .
After calibrate manually ,set the polling mode and digitalfilter
the values in my console are the same as simas.

By now , i have no idea how to fix that problem . I read the user´s guide , the datasheet and tried few codes  included the manufacturer´s .

kalllelll

Hi,

I've got the Cozir Wide Range Co2 Sensor and as I hope an easy-to-solve problem :-) It's about the delay(2000) in the "loop" . Without this everything works quite well and I see z ##### z ##### in my seriell monitor every second a new line with new values. With the delay(2000) (2000ms just for testing purpose) my seriell monitor delays the appearance of every singe sign. Is there an easy way to fix this or do I have to get it to work with the cozir.h library? At the end I've to log the Co2 values of an experiment for 7 days and store it on a SD Card (which already works). But one value every 5 or 10 minutes is more than enough.

Code: [Select]
#include <SoftwareSerial.h>

SoftwareSerial nss(11,10);

void setup()
{
  Serial.begin(9600);
  nss.begin(9600);
  delay(3000);
}

void getStuff()
{
  if (nss.available())
  {
    Serial.write(nss.read());
  }
}
void loop()
{
  getStuff();
  delay(2000);
}



I would appreciate your help


Go Up