EcoRenovator  

Go Back   EcoRenovator > Improvements > Conservation
Advanced Search
 


Blog Register 60+ Home Energy Saving Tips Recent Posts Search Today's Posts Mark Forums Read


Reply
 
Thread Tools Display Modes
Old 04-01-14, 08:33 PM   #1
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 58 Times in 54 Posts
Default GE T6603-5 CO2 sensor Arduino sketch

Code:
/*
GE T6603-5 Safe-AirTM Plus CO2 Sensor

This sensor: +5vdc on pin 3, Gnd on pin 4, 
produces an open collector +Pulse output on pin 5  (with 10K pullup resistor to +5)
The duration of this pulse indicates the CO2 in Parts per Million (with manipulation)

This sketch averages 100 samples & prints out PPM  Takes about 1.7 minutes / printout

http://www.sensorexpert.com.cn/Uploa...2843_18796.pdf

http://www.tecnosens.it/media/6970/920-6603.pdf

Arduino - PulseIn

*/

#define sample_cnt 100
int I;
float sample_avg = 0.0;
float sample_accum = 0.0;
float sample = 0.0;
float ppm = 0.0;

int pin = 11;
 
unsigned long duration;


void setup()
{
  Serial.begin(9600); // start serial communication

  pinMode(pin, INPUT);
  
  delay(5000); 
  
  Serial.println("........Hello world!.......");
}

void loop()
{

sample_accum = 0.0;                    //clear accumulator

for (I = 0; I < sample_cnt ; I++)      //loop taking samples
{    
duration = pulseIn(pin, HIGH);        //read the pulse in microseconds

sample = (duration / 1000.0);        //convert to ms

ppm = (1.996 * sample);              //convert to ppm

sample_accum += ppm;                  //accumulate samples
}

sample_avg = (sample_accum / sample_cnt);  //find average


Serial.print("CO2 level = ");      // Write ppm to serial monitor
Serial.print(sample_avg); 
Serial.println(" ppm"); 
Serial.println("..............");

}


Last edited by buffalobillpatrick; 04-02-14 at 02:54 PM..
buffalobillpatrick is offline   Reply With Quote
Old 04-02-14, 01:17 PM   #2
AC_Hacker
Supreme EcoRenovator
 
AC_Hacker's Avatar
 
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,002
Thanks: 303
Thanked 712 Times in 532 Posts
Default

Quote:
Originally Posted by buffalobillpatrick View Post
...GE T6603-5 Safe-AirTM Plus CO2 Sensor...
Perhaps a better way to display your code is to enclose it in a "CODE" box. It makes it easier for others to recognize and to use.

To do that you begin your box with: left-square-bracket, then the capital letters CODE, then right-square-bracket.

Your code goes in between...

Then you end your CODE box with: left-square-bracket, then forward-slash, then the capital letters CODE, then right-square-bracket.

You could even edit your post to put your code in a code box.

Code:
it will look look this.

-AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker...
AC_Hacker is offline   Reply With Quote
The Following User Says Thank You to AC_Hacker For This Useful Post:
buffalobillpatrick (04-02-14)
Old 04-02-14, 03:07 PM   #3
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 58 Times in 54 Posts
Default

Thanks A/C,
My bedroom went from about: 450ppm to about 800ppm, overnight.
back down to about 480ppm @ 2PM

Getting this sensor working was Royal PITA, they can be bought on Ebay about $50
but I couldn't find any code using them. They have I2C on pins 1 & 2 but couldn't find any specifications or examples for use.

I found some code that is suppose to work on Github "T6603" but it won't download as my Imac is too old to run latest Safari. So I copied & pasted the .cpp & .h code still won't compile for me possibly it's Python. I don't understand the source code.

I plan to include this CO2 detector as part of my DIY HRV controls that I'm building from coroplast, thanks to A/C's thread.

Last edited by buffalobillpatrick; 04-02-14 at 03:16 PM..
buffalobillpatrick is offline   Reply With Quote
Old 04-02-14, 03:39 PM   #4
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 58 Times in 54 Posts
Default

My HRV will pull stale air from 3 bathrooms + Greatroom.
Fresh incoming air will dump into mechanical room -> greatroom, then circulated to rear closets in 3 bedrooms.

4x Panasonic FV-11VQ5 110cfm, high Eff. ceiling ventilation fans.
Each has a timer wall switch for on demand needs.
These provide stale air into HRV.

4x PIR (Human IR motion detection sensors) input to Arduino.

If PIR-1 detects someone, Arduino energizes R-1 for 8hrs. (time adjustable)
During this 8hrs a mechanical timer (adjustable) will turn F-1 on intermittently (say 15min on & 45min off)

This is replicated for: PIR-2, R-2, F-2 : PIR-3, R-3, F-3 : PIR-4, R-4, F-4

This elemonates wasting energy to automatically ventilate any section of house where people haven't been lately. I expect that 2 bedrooms/bathrooms will have very little use except when family comes to visit.

I have this code working on Arduino.

BTW, there is only 1 mechanical timer, it energizes a 4-pole relay so that the 4 exhaust fans are independant of each other.

Last edited by buffalobillpatrick; 04-03-14 at 12:32 PM..
buffalobillpatrick is offline   Reply With Quote
Old 04-02-14, 11:27 PM   #5
AC_Hacker
Supreme EcoRenovator
 
AC_Hacker's Avatar
 
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,002
Thanks: 303
Thanked 712 Times in 532 Posts
Default

Quote:
Originally Posted by buffalobillpatrick View Post
...My bedroom went from about: 450ppm to about 800ppm, overnight... back down to about 480ppm @ 2PM.
I don't know if you saw my post, but Germany did some research into CO2 levels, and the effect on people. The upshot was that levels above 1000 ppm can cause a reduction in performance in children at school. ASHRAE is less restrictive, and says that levels of greater than 2000 ppm are problematic. I agree with the Germans.

I have gas appliances in my house and since my infiltration jihad, CO2 levels have become a problem. I wouldn't have known were it not for my CO2 project.

I had a terrible time trying to convince S_Hull that I actually had a problem with CO2 levels. I guess he never lived in a tight house. CO2 can be a problem, as we know.

I actually think that 800 ppm is a bit high for a bedroom. I think that once you get your HRV going, you'll sleep better.


So you couldn't find any libraries for your project?

No I2C libraries?

How did you get it working?

-AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker...

Last edited by AC_Hacker; 04-02-14 at 11:39 PM..
AC_Hacker is offline   Reply With Quote
Old 04-02-14, 11:49 PM   #6
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 58 Times in 54 Posts
Default

It seems to be working with the pulse duration on pin 5, read preface to code above.
buffalobillpatrick is offline   Reply With Quote
Old 04-03-14, 01:28 AM   #7
AC_Hacker
Supreme EcoRenovator
 
AC_Hacker's Avatar
 
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,002
Thanks: 303
Thanked 712 Times in 532 Posts
Default

If you go back to GITHUB you will find an examples link that will give you a working example of Arduino code, T6603Example.ino

Here it is:

Code:
/*
Copyright (c) 2014 Brian Manley

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "SoftwareSerial.h"
#include <T6603.h>

T6603 sensor;

void setup() {
    Serial.begin(19200);
    sensor.begin(10, 11);  
}

void loop() {
    Serial.println(sensor.get_co2());
    delay(2000);
}
This piece of code calls on two libraries to be loaded at compile time:

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


one of them is T6603.h which is also at the GITHUB page, and is shown here:

Code:
/*
Copyright (c) 2014 Brian Manley

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <SoftwareSerial.h>
#include "T6603.h"

T6603::T6603() {

}

T6603::~T6603() {
    
    if ( NULL != _serial ) {
        delete _serial;
        _serial = NULL;
    }
}

void T6603::begin(uint8_t rx, uint8_t tx) {

    _serial = new SoftwareSerial(rx, tx);
    _serial->begin(19200);
}

int T6603::get_co2(void) {

    _serial->overflow();
    _serial->write(FLAG);
    _serial->write(BRDCST);
    _serial->write(0x02);
    _serial->write(CMD_READ); 
    _serial->write(CO2_PPM);
    delay(50);

    for ( int attempts = 0; attempts < MAX_ATTEMPTS; attempts++ ) {

        byte reading[5]; 
        int bytesRead = 0;        
        
        while ( _serial->available() && bytesRead < 6) {
            reading[bytesRead] = _serial->read();
            bytesRead++;
            delay(10);
        }

        if ( reading[0] == 0xFF && reading[1] == 0xFA ) {
            int i = 0;
            i |= reading[3] & 0xFF;
            i <<= 8;
            i |= reading[4] & 0xFF;
            _lastReading = i;
            return (_lastReading); 
        }
    }
    
    return (_lastReading);
}

byte T6603::get_status(void) {

    _serial->overflow();
    _serial->write(FLAG);
    _serial->write(BRDCST);
    _serial->write(0x01);
    _serial->write(CMD_STATUS); 
    delay(50);

    for ( int attempts = 0; attempts < MAX_ATTEMPTS; attempts++ ) {

        byte reading[4]; 
        int bytesRead = 0;        
        
        while ( _serial->available() && bytesRead < 4) {
            reading[bytesRead] = _serial->read();
            bytesRead++;
            delay(10);
        }

        if ( reading[0] == 0xFF && reading[1] == 0xFA ) {
            return ( reading[3] );
        }
    }
    
    return (NULL);
}

void T6603::set_idle(bool onOff) {

    byte cmd = onOff ? 0x01 : 0x02;
    
    _serial->overflow();
    _serial->write(FLAG);
    _serial->write(BRDCST);
    _serial->write(0x02);
    _serial->write(CMD_IDLE); 
    _serial->write(cmd);
    delay(50);

    for ( int attempts = 0; attempts < MAX_ATTEMPTS; attempts++ ) {

        byte reading[3]; 
        int bytesRead = 0;        
        
        while ( _serial->available() && bytesRead < 3) {
            reading[bytesRead] = _serial->read();
            bytesRead++;
            delay(10);
        }

        if ( reading[0] == 0xFF && reading[1] == 0xFA ) {
            return;
        }
    }
        
}
The other library is probably already part of your Arduino IDE. But if it is not, you can find it HERE, and the code is shown below:

Code:
/*
SoftwareSerial.h (formerly NewSoftSerial.h) - 
Multi-instance software serial library for Arduino/Wiring
-- Interrupt-driven receive and other improvements by ladyada
   (http://ladyada.net)
-- Tuning, circular buffer, derivation from class Print/Stream,
   multi-instance support, porting to 8MHz processors,
   various optimizations, PROGMEM delay tables, inverse logic and 
   direct port writing by Mikal Hart (http://www.arduiniana.org)
-- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
-- 20MHz processor support by Garrett Mace (http://www.macetech.com)
-- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

The latest version of this library can always be found at
http://arduiniana.org.
*/

#ifndef SoftwareSerial_h
#define SoftwareSerial_h

#include <inttypes.h>
#include <Stream.h>

/******************************************************************************
* Definitions
******************************************************************************/

#define _SS_MAX_RX_BUFF 64 // RX buffer size
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif

class SoftwareSerial : public Stream
{
private:
  // per object data
  uint8_t _receivePin;
  uint8_t _receiveBitMask;
  volatile uint8_t *_receivePortRegister;
  uint8_t _transmitBitMask;
  volatile uint8_t *_transmitPortRegister;

  uint16_t _rx_delay_centering;
  uint16_t _rx_delay_intrabit;
  uint16_t _rx_delay_stopbit;
  uint16_t _tx_delay;

  uint16_t _buffer_overflow:1;
  uint16_t _inverse_logic:1;

  // static data
  static char _receive_buffer[_SS_MAX_RX_BUFF]; 
  static volatile uint8_t _receive_buffer_tail;
  static volatile uint8_t _receive_buffer_head;
  static SoftwareSerial *active_object;

  // private methods
  void recv();
  uint8_t rx_pin_read();
  void tx_pin_write(uint8_t pin_state);
  void setTX(uint8_t transmitPin);
  void setRX(uint8_t receivePin);

  // private static method for timing
  static inline void tunedDelay(uint16_t delay);

public:
  // public methods
  SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
  ~SoftwareSerial();
  void begin(long speed);
  bool listen();
  void end();
  bool isListening() { return this == active_object; }
  bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
  int peek();

  virtual size_t write(uint8_t byte);
  virtual int read();
  virtual int available();
  virtual void flush();
  
  using Print::write;

  // public only for easy access by interrupt handlers
  static inline void handle_interrupt();
};

// Arduino 0012 workaround
#undef int
#undef char
#undef long
#undef byte
#undef float
#undef abs
#undef round

#endif

The idea is that if you go to your Arduino IDE installation, and drill down, you will find a folder called libraries. You'll probably see a few libraries in there already.

So you make a folder by the exact name of the library being called, and you put the library-code file by it's exact name into that folder.

You need to have all called libraries available when you compile, in this case you are compiling T6603Example.ino.


Is life any easier now?

-AC
__________________
I'm not an HVAC technician. In fact, I'm barely even a hacker...

Last edited by AC_Hacker; 04-03-14 at 01:31 AM..
AC_Hacker is offline   Reply With Quote
Old 04-03-14, 04:05 AM   #8
jeff5may
Supreme EcoRenovator
 
Join Date: Jan 2010
Location: elizabethtown, ky, USA
Posts: 2,394
Thanks: 410
Thanked 604 Times in 506 Posts
Send a message via Yahoo to jeff5may
Default

Quote:
Originally Posted by buffalobillpatrick View Post
Thanks A/C,
Getting this sensor working was Royal PITA, they can be bought on Ebay about $50
but I couldn't find any code using them. They have I2C on pins 1 & 2 but couldn't find any specifications or examples for use.
If getting this to work using python to read analog signals was a pain for you, implementing I2C would be more like torture. It's kind of like ladder logic on a plc, but with 3 wires. The interface works very well once debugged, but each device has its own set of limits and standards. When things go awry, it's difficult to figure out what's going wrong. Not fun at all.
jeff5may is offline   Reply With Quote
Old 04-03-14, 11:34 AM   #9
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 58 Times in 54 Posts
Default

A/C Thanks but that is the same code that I tried to get working for 2 days.

from my post #3 above:

"I found some code that is suppose to work on Github "T6603" but it won't download as my Imac is too old to run latest Safari. So I copied & pasted the .cpp & .h code still won't compile for me possibly it's Python. I don't understand the source code."


sketch_apr03a.cpp.o: In function `__static_initialization_and_destruction_0':
/Users/jamespatrick/Downloads/sketch_apr03a.ino:24: undefined reference to `T6603::T6603()'
/Users/jamespatrick/Downloads/sketch_apr03a.ino:24: undefined reference to `T6603::~T6603()'
sketch_apr03a.cpp.o: In function `loop':
/Users/jamespatrick/Downloads/sketch_apr03a.ino:32: undefined reference to `T6603::get_co2()'
sketch_apr03a.cpp.o: In function `setup':
/Users/jamespatrick/Downloads/sketch_apr03a.ino:28: undefined reference to `T6603::begin(unsigned char, unsigned char)'

Last edited by buffalobillpatrick; 04-03-14 at 11:55 AM..
buffalobillpatrick is offline   Reply With Quote
Old 04-19-14, 08:32 PM   #10
buffalobillpatrick
Master EcoRenovator
 
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 58 Times in 54 Posts
Default

http://ecorenovator.org/forum/attach...1&d=1397957512

A/C did you try to compile that code you linked?


"Is life any easier now?"


Got little LCD working with my CO2 sketch

Attached Thumbnails
Click image for larger version

Name:	IMG_2706.jpg
Views:	2024
Size:	514.9 KB
ID:	4303  

Last edited by buffalobillpatrick; 04-19-14 at 08:36 PM..
buffalobillpatrick is offline   Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -5. The time now is 07:40 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, vBulletin Solutions Inc.
Ad Management by RedTyger
Inactive Reminders By Icora Web Design