04-01-14, 08:33 PM | #1 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
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.. |
04-02-14, 01:17 PM | #2 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
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... |
The Following User Says Thank You to AC_Hacker For This Useful Post: | buffalobillpatrick (04-02-14) |
04-02-14, 03:07 PM | #3 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
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.. |
04-02-14, 03:39 PM | #4 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
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.. |
04-02-14, 11:27 PM | #5 | |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
Quote:
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.. |
|
04-02-14, 11:49 PM | #6 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
It seems to be working with the pulse duration on pin 5, read preface to code above.
|
04-03-14, 01:28 AM | #7 |
Supreme EcoRenovator
Join Date: Mar 2009
Location: Portland, OR
Posts: 4,004
Thanks: 303
Thanked 724 Times in 534 Posts
|
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); } #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; } } } 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.. |
04-03-14, 04:05 AM | #8 |
Supreme EcoRenovator
|
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.
|
04-03-14, 11:34 AM | #9 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
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.. |
04-19-14, 08:32 PM | #10 |
Master EcoRenovator
Join Date: Mar 2014
Location: Florissant, Colorado
Posts: 599
Thanks: 814
Thanked 59 Times in 55 Posts
|
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 Last edited by buffalobillpatrick; 04-19-14 at 08:36 PM.. |
|
|