From: Roman Bazalevskiy Date: Sat, 3 Sep 2016 15:15:05 +0000 (+0300) Subject: Добавлен датчик уровня углекислоты MH-Z14 X-Git-Url: https://git.rvb.name/weathermon.git/commitdiff_plain/357607fbe9159afef9ba89f1dbe86abe7966efc8?ds=inline;hp=e7a2d1b901dbeb947e0ad605a53badc845e23ebc Добавлен датчик уровня углекислоты MH-Z14 --- diff --git a/Weather_Station.ino b/Weather_Station.ino deleted file mode 100644 index 9358d3d..0000000 --- a/Weather_Station.ino +++ /dev/null @@ -1,272 +0,0 @@ -/* SFE_BMP180 library example sketch - -This sketch shows how to use the SFE_BMP180 library to read the -Bosch BMP180 barometric pressure sensor. -https://www.sparkfun.com/products/11824 - -Like most pressure sensors, the BMP180 measures absolute pressure. -This is the actual ambient pressure seen by the device, which will -vary with both altitude and weather. - -Before taking a pressure reading you must take a temparture reading. -This is done with startTemperature() and getTemperature(). -The result is in degrees C. - -Once you have a temperature reading, you can take a pressure reading. -This is done with startPressure() and getPressure(). -The result is in millibar (mb) aka hectopascals (hPa). - -If you'll be monitoring weather patterns, you will probably want to -remove the effects of altitude. This will produce readings that can -be compared to the published pressure readings from other locations. -To do this, use the sealevel() function. You will need to provide -the known altitude at which the pressure was measured. - -If you want to measure altitude, you will need to know the pressure -at a baseline altitude. This can be average sealevel pressure, or -a previous pressure reading at your altitude, in which case -subsequent altitude readings will be + or - the initial baseline. -This is done with the altitude() function. - -Hardware connections: - -- (GND) to GND -+ (VDD) to 3.3V - -(WARNING: do not connect + to 5V or the sensor will be damaged!) - -You will also need to connect the I2C pins (SCL and SDA) to your -Arduino. The pins are different on different Arduinos: - -Any Arduino pins labeled: SDA SCL -Uno, Redboard, Pro: A4 A5 -Mega2560, Due: 20 21 -Leonardo: 2 3 - -Leave the IO (VDDIO) pin unconnected. This pin is for connecting -the BMP180 to systems with lower logic levels such as 1.8V - -Have fun! -Your friends at SparkFun. - -The SFE_BMP180 library uses floating-point equations developed by the -Weather Station Data Logger project: http://wmrx00.sourceforge.net/ - -Our example code uses the "beerware" license. You can do anything -you like with this code. No really, anything. If you find it useful, -buy me a beer someday. - -V10 Mike Grusin, SparkFun Electronics 10/24/2013 -*/ - -// Your sketch must #include this library, and the Wire library. -// (Wire is a standard library included with Arduino.): - -#include -#include -#include "DHT.h" - -// You will need to create an SFE_BMP180 object, here called "pressure": - -SFE_BMP180 pressure; - -// DHT object for humidity sensor -DHT dht; - -#define CO2_PIN A1 -#define DHT_PIN 4 -#define GAS_PIN A0 -#define START_DELAY 20000 -#define DELAY 50000 - -byte HasBaro; - -#define READ_SAMPLE_INTERVAL 50 -#define READ_SAMPLE_TIMES 5 - -#define MQ135_RES 1000 - -float MQRead(int mq_pin) -{ - - int i; - float rs=0; - float rr; - - for (i=0;i +#include +#include "DHT.h" + +// You will need to create an SFE_BMP180 object, here called "pressure": + +SFE_BMP180 pressure; + +// DHT object for humidity sensor +DHT dht; + +#define CO2_PIN A1 +#define DHT_PIN 4 +#define GAS_PIN A0 +#define MHZ14_PIN A2 +#define START_DELAY 20000 +#define DELAY 50000 + +byte HasBaro; + +#define READ_SAMPLE_INTERVAL 50 +#define READ_SAMPLE_TIMES 5 + +float MQRead(int mq_pin) +{ + + int i; + float rs=0; + float rr; + + for (i=0;i +#include +#include + +// DHT11 and BMP085 wired sensors +dht DHT; +BMP085 bmp; + +// Humidity sensor at pin 4 +#define DHT11PIN 5 +int sensorPin = 0; +#define DEBUG + +// LED pins +#define REDPIN 11 +#define GREENPIN 12 + +// Read data from 433MHz receiver on digital pin 3 +#define RF_IN 4 +// For better efficiency, the port is read directly +// the following two lines should be changed appropriately +// if the line above is changed. +#define RF_IN_RAW PIND4 +#define RF_IN_PIN PIND + +// Port that is hooked to LED to indicate a packet has been received + +#define COUNTER_RATE 3200-1 // 16,000,000Hz / 3200 = 5000 interrupts per second, ie. 200us between interrupts +// 1 is indicated by 500uS pulse +// wh2_accept from 2 = 400us to 3 = 600us +#define IS_HI_PULSE(interval) (interval >= 2 && interval <= 3) +// 0 is indicated by ~1500us pulse +// wh2_accept from 7 = 1400us to 8 = 1600us +#define IS_LOW_PULSE(interval) (interval >= 7 && interval <= 8) +// worst case packet length +// 6 bytes x 8 bits x (1.5 + 1) = 120ms; 120ms = 200us x 600 +#define HAS_TIMED_OUT(interval) (interval > 600) +// we expect 1ms of idle time between pulses +// so if our pulse hasn't arrived by 1.2ms, reset the wh2_packet_state machine +// 6 x 200us = 1.2ms +#define IDLE_HAS_TIMED_OUT(interval) (interval > 6) +// our expected pulse should arrive after 1ms +// we'll wh2_accept it if it arrives after +// 4 x 200us = 800us +#define IDLE_PERIOD_DONE(interval) (interval >= 4) +// Shorthand for tests +//#define RF_HI (digitalRead(RF_IN) == HIGH) +//#define RF_LOW (digitalRead(RF_IN) == LOW) +#define RF_HI (bit_is_set(RF_IN_PIN, RF_IN_RAW)) +#define RF_LOW (bit_is_clear(RF_IN_PIN, RF_IN_RAW)) + +// wh2_flags +#define GOT_PULSE 0x01 +#define LOGIC_HI 0x02 +volatile byte wh2_flags = 0; +volatile byte wh2_packet_state = 0; +volatile int wh2_timeout = 0; +byte wh2_packet[5]; +byte wh2_calculated_crc; + + +#ifdef DEBUG +byte printed = 0; +#endif + +ISR(TIMER1_COMPA_vect) +{ + static byte sampling_state = 0; + static byte count; + static boolean was_low = false; + + switch(sampling_state) { + case 0: // waiting + wh2_packet_state = 0; + if (RF_HI) { + if (was_low) { + count = 0; + sampling_state = 1; + was_low = false; + } + } else { + was_low = true; + } + break; + case 1: // acquiring first pulse + count++; + // end of first pulse + if (RF_LOW) { + if (IS_HI_PULSE(count)) { + wh2_flags = GOT_PULSE | LOGIC_HI; + sampling_state = 2; + count = 0; + } else if (IS_LOW_PULSE(count)) { + wh2_flags = GOT_PULSE; // logic low + sampling_state = 2; + count = 0; + } else { + sampling_state = 0; + } + } + break; + case 2: // observe 1ms of idle time + count++; + if (RF_HI) { + if (IDLE_HAS_TIMED_OUT(count)) { + sampling_state = 0; + } else if (IDLE_PERIOD_DONE(count)) { + sampling_state = 1; + count = 0; + } + } + break; + } + + if (wh2_timeout > 0) { + wh2_timeout++; + if (HAS_TIMED_OUT(wh2_timeout)) { + wh2_packet_state = 0; + wh2_timeout = 0; +#ifdef DEBUG + if (printed) { + Serial1.println(); + printed=0; + } +#endif + } + } +} + +void setup() { + + Serial1.begin(115200); // Set the baud. + + // Wait for U-boot to finish startup. Consume all bytes until we are done. + do { + while (Serial1.available() > 0) { + Serial1.read(); + } + + delay(1000); + } while (Serial1.available()>0); + + Serial1.begin(57600); + Serial1.println(); + Serial1.println("STATUS:STARTING"); + + bmp.begin(); + + pinMode(REDPIN,OUTPUT); + pinMode(GREENPIN,OUTPUT); + + pinMode(RF_IN, INPUT); + digitalWrite(RF_IN,HIGH); + + TCCR1A = 0x00; + TCCR1B = 0x09; + TCCR1C = 0x00; + OCR1A = COUNTER_RATE; + TIMSK1 = 0x02; + + // enable interrupts + sei(); +} + +unsigned long previousMillis = 0; +unsigned long indoor_interval = 60000; +unsigned long outdoor_interval = 45000; +unsigned long previousIndoor = 0; +unsigned long previousOutdoor = 0; + +float temperature; +float pressure; + +void loop() { + unsigned long now; + int gas = 0; + byte i; + + now = millis(); + + if (wh2_flags) { + if (wh2_accept()) { + // calculate the CRC + wh2_calculate_crc(); + + if (wh2_valid()) { + + Serial1.println(); + Serial1.print("SENSOR:TYPE=OUTDOOR,"); + + Serial1.print("ID="); + Serial1.print(wh2_sensor_id(), HEX); + + Serial1.print(",HUMIDITY="); + Serial1.print(wh2_humidity(), DEC); + + Serial1.print(",TEMPERATURE="); + Serial1.println(format_temp(wh2_temperature())); + + previousOutdoor = now; + digitalWrite(REDPIN,HIGH); + + } else { + + Serial1.println(); + Serial1.println("ERROR:OUTDOOR"); + previousOutdoor = now; + digitalWrite(REDPIN,LOW); + + } + + } + wh2_flags = 0x00; + } + + if ((unsigned long)(now - previousMillis) >= indoor_interval) { + + previousMillis = now; + + int chk = DHT.read11(DHT11PIN); + + if (chk==0) { + + Serial1.println(); + Serial1.print("SENSOR:TYPE=INDOOR,"); + Serial1.print("HUMIDITY="); + Serial1.print(DHT.humidity); + Serial1.print(",TEMPERATURE="); + Serial1.print(DHT.temperature); + + previousIndoor = now; + digitalWrite(GREENPIN,HIGH); + + + } else { + + Serial1.println(); + Serial1.println("ERROR:INDOOR"); + previousIndoor = now; + digitalWrite(GREENPIN,LOW); + + } + + pressure=bmp.readPressure(); + temperature=bmp.readTemperature(); + Serial1.println(); + Serial1.print("SENSOR:TYPE=BARO,"); + Serial1.print("PRESSURE="); + Serial1.print(pressure); + Serial1.print(",TEMPERATURE="); + Serial1.println(temperature); + + gas = analogRead(sensorPin); // Получаем значения из датчика + Serial1.print("SENSOR:TYPE=GAS,VALUE="); + Serial1.println(gas); // Пишем в серийный порт + + } + + if ((unsigned long)(now - previousIndoor) > indoor_interval*10) { + + Serial1.println(); + Serial1.println("ERROR:INDOOR TIMEOUT"); + previousIndoor = now; + digitalWrite(GREENPIN,LOW); + + } + + if ((unsigned long)(now - previousOutdoor) > outdoor_interval*10) { + + Serial1.println(); + Serial1.println("ERROR:OUTDOOR TIMEOUT"); + previousOutdoor = now; + digitalWrite(REDPIN,LOW); + + } + + +} + + +// processes new pulse +boolean wh2_accept() +{ + static byte packet_no, bit_no, history; + + // reset if in initial wh2_packet_state + if(wh2_packet_state == 0) { + // should history be 0, does it matter? + history = 0xFF; + wh2_packet_state = 1; + // enable wh2_timeout + wh2_timeout = 1; + } // fall thru to wh2_packet_state one + + // acquire preamble + if (wh2_packet_state == 1) { + // shift history right and store new value + history <<= 1; + // store a 1 if required (right shift along will store a 0) + if (wh2_flags & LOGIC_HI) { + history |= 0x01; + } + // check if we have a valid start of frame + // xxxxx110 + if ((history & B00000111) == B00000110) { + // need to clear packet, and counters + packet_no = 0; + // start at 1 becuase only need to acquire 7 bits for first packet byte. + bit_no = 1; + wh2_packet[0] = wh2_packet[1] = wh2_packet[2] = wh2_packet[3] = wh2_packet[4] = 0; + // we've acquired the preamble + wh2_packet_state = 2; + } + return false; + } + // acquire packet + if (wh2_packet_state == 2) { + + wh2_packet[packet_no] <<= 1; + if (wh2_flags & LOGIC_HI) { + wh2_packet[packet_no] |= 0x01; +#ifdef DEBUG + Serial1.print('1'); + printed=1; + } else { + Serial1.print('0'); + printed=1; +#endif + } + + bit_no ++; + if(bit_no > 7) { + bit_no = 0; + packet_no ++; + } + + if (packet_no > 4) { + // start the sampling process from scratch + wh2_packet_state = 0; + // clear wh2_timeout + wh2_timeout = 0; + return true; + } + } + return false; +} + + +void wh2_calculate_crc() +{ + wh2_calculated_crc = crc8(wh2_packet, 4); +} + +bool wh2_valid() +{ + return (wh2_calculated_crc == wh2_packet[4]); +} + +int wh2_sensor_id() +{ + return (wh2_packet[0] << 4) + (wh2_packet[1] >> 4); +} + +byte wh2_humidity() +{ + return wh2_packet[3]; +} + +/* Temperature in deci-degrees. e.g. 251 = 25.1 */ +int wh2_temperature() +{ + int temperature; + temperature = ((wh2_packet[1] & B00000111) << 8) + wh2_packet[2]; + // make negative + if (wh2_packet[1] & B00001000) { + temperature = -temperature; + } + return temperature; +} + +String format_temp(int temperature) +{ + byte whole, partial; + String s; + s = String(); + if (temperature<0) { + temperature = -temperature; + s += String('-'); + } + + whole = temperature / 10; + partial = temperature - (whole*10); + + s += String(whole, DEC); + s += '.'; + s += String(partial, DEC); + + return s; + +} + +uint8_t crc8( uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + // Indicated changes are from reference CRC-8 function in OneWire library + while (len--) { + uint8_t inbyte = *addr++; + for (uint8_t i = 8; i; i--) { + uint8_t mix = (crc ^ inbyte) & 0x80; // changed from & 0x01 + crc <<= 1; // changed from right shift + if (mix) crc ^= 0x31;// changed from 0x8C; + inbyte <<= 1; // changed from right shift + } + } + return crc; +} + + + + + + + + + diff --git a/web/config_local.php b/web/config_local.php new file mode 100644 index 0000000..eef2134 --- /dev/null +++ b/web/config_local.php @@ -0,0 +1,17 @@ +>>>>>> 438eca78d7802bd2758a4969b80bb0be6b9f14f6 + +?> \ No newline at end of file diff --git a/web/config_local.php~ b/web/config_local.php~ new file mode 100644 index 0000000..eef2134 --- /dev/null +++ b/web/config_local.php~ @@ -0,0 +1,17 @@ +>>>>>> 438eca78d7802bd2758a4969b80bb0be6b9f14f6 + +?> \ No newline at end of file