Last active
December 10, 2015 01:38
-
-
Save ati/4360766 to your computer and use it in GitHub Desktop.
Electric imp code for K30 CO2 sensor communication using RS-232 protocol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//K30 CO2 sensor interface | |
// using RS-232 communication | |
/* | |
250 - 350 ppm – background (normal) outdoor air level | |
350- 1,000 ppm - typical level found in occupied spaces with good air exchange. | |
1,000 – 2,000 ppm - level associated with complaints of drowsiness and poor air. | |
2,000 – 5,000 ppm – level associated with headaches, sleepiness, and stagnant, stale, stuffy air. | |
Poor concentration, loss of attention, increased heart rate | |
and slight nausea may also be present. | |
>5,000 ppm – this indicates unusual air conditions where high levels of other gases could also be present. | |
Toxicity or oxygen deprivation could occur. This is the permissible exposure limit | |
for daily workplace exposures. | |
>40,000 ppm - this level is immediately harmful due to oxygen deprivation. | |
source: http://www.dhs.wisconsin.gov/eh/chemfs/fs/carbondioxide.htm | |
*/ | |
local k30_response = []; | |
local co2_value = 0; | |
local output = OutputPort("CO2", "number"); | |
/* | |
We read CO2 value from IR4 using “Read input registers” (function code 04). | |
Hence, Starting address will be 0x0003 (register number-1) and Quantity of registers 0x0001. | |
CRC calculated to 0xC5D5 is sent with low byte first. | |
source: "modbus on co2 engine" pdf | |
*/ | |
const co2_read_request = "\xfe\x04\x00\x03\x00\x01\xd5\xc5"; | |
const co2_response_length = 7; | |
const poll_period = 10.0; // seconds | |
function join(a, sep) | |
{ | |
local res = ""; | |
foreach(i,v in a) | |
{ | |
if (i > 0) { res += sep; } | |
res += v.tostring(); | |
} | |
return res; | |
} | |
function k30_setup() | |
{ | |
hardware.uart12.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS); | |
} | |
// can't pass parameters for imp.wakeup | |
function k30_inner_poll() | |
{ | |
return k30_poll(false); | |
} | |
// main receiver loop. currently receives data in 7-bytes frames (co2 read mode) | |
function k30_poll(do_reset) | |
{ | |
if (do_reset) { k30_response = []; } | |
local byte = hardware.uart12.read(); | |
while (byte >= 0) | |
{ | |
k30_response.push(byte); | |
byte = hardware.uart12.read(); | |
} | |
if (k30_response.len() >= co2_response_length) | |
{ | |
local current_co2 = (k30_response[3]<<8) + k30_response[4] | |
// server.show(join(k30_response, ":")); | |
server.show(current_co2) | |
output.set(current_co2) | |
} | |
else | |
{ | |
imp.wakeup(0.01, k30_inner_poll); | |
} | |
} | |
function k30_ping() | |
{ | |
hardware.uart12.write(co2_read_request); | |
imp.sleep(0.02); | |
k30_poll(true); | |
// server.log(time()); | |
imp.wakeup(poll_period, k30_ping); | |
} | |
imp.configure("K30 sensor RS232 logger", [], [output]); | |
k30_setup(); | |
k30_ping(); | |
// end of code |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment