Официальный сайт компании Arduino по адресу arduino.cc
переделал код - не работает. Что не так?
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Втр, 24/11/2015 - 00:25
Всем привет. В общем решил переписать код под себя: не использую bmp085, вре11 - все остальное есть. Код юрал здесь http://devicter.blogspot.co.il/2013/01/blog-post.html
Использую дисплей 16x2 не i2c. Код компилируется, но ничего не выводится. ( При нажатаии на кнопку - не мигает светодиод.
#include <LiquidCrystalRus.h> #include <SoftwareSerial.h> #include <Wire.h> #include "RTClib.h" #include <Bounce.h> #include "DHT.h" //#define DISABLE_DEBUG // если нужен вывод в Serial - закомментируйте эту строчку #define LED 13 // LED на D13 #define BUTTON 3 Bounce bouncer = Bounce( BUTTON,5 ); #define DS1307_I2C_ADDRESS 0x68 LiquidCrystalRus lcd(4, 5, 10, 11, 12, 13); char sTemp[16]; int LCD_LED = 8; //подсветка дисплея static char wDay[7][4] = { "Sun","Mon","Tue","Wed","Thu","Fri","Sat" }; static char wMonth[12][4] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" }; // температура float t[4]; // влажность float h[4]; // батарейка byte b[2]; // счетчик (используем для переключения "экранов") byte cDisp = 0; unsigned long dispNow = 0; unsigned long ledNow = 0; // параметры для формирования трендов #define DELTA_TIME 900000 // 15 минут #define DELTA_TEMP 0.1 // превышение этого значения будет означать изменение температуры #define DELTA_HYM 1 // порог для влажности #define DELTA_BAR 1 float PrevTemp[4]; float PrevHym[4]; unsigned long PrevMeasure[3]; char TrendTemp[4]; char TrendHym[4]; #define BMP085_ADDRESS 0x77 // I2C address of BMP085 const unsigned char OSS = 0; // Oversampling Setting // Calibration values int ac1; int ac2; int ac3; unsigned int ac4; unsigned int ac5; unsigned int ac6; int b1; int b2; int mb; int mc; int md; // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...) // so ...Temperature(...) must be called before ...Pressure(...). long b5; #define DHTPIN 4 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); // Oregon V2 decoder added - Dominique Pierre // New code to decode OOK signals from weather sensors, etc. // 2010-04-11 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php // $Id: ookDecoder.pde 5331 2010-04-17 10:45:17Z jcw $ class DecodeOOK { protected: byte total_bits, bits, flip, state, pos, data[25]; virtual char decode (word width) =0; public: enum { UNKNOWN, T0, T1, T2, T3, OK, DONE }; DecodeOOK () { resetDecoder(); } bool nextPulse (word width) { if (state != DONE) switch (decode(width)) { case -1: resetDecoder(); break; case 1: done(); break; } return isDone(); } bool isDone () const { return state == DONE; } const byte* getData (byte& count) const { count = pos; return data; } void resetDecoder () { total_bits = bits = pos = flip = 0; state = UNKNOWN; } // add one bit to the packet data buffer virtual void gotBit (char value) { total_bits++; byte *ptr = data + pos; *ptr = (*ptr >> 1) | (value << 7); if (++bits >= 8) { bits = 0; if (++pos >= sizeof data) { resetDecoder(); return; } } state = OK; } // store a bit using Manchester encoding void manchester (char value) { flip ^= value; // manchester code, long pulse flips the bit gotBit(flip); } // move bits to the front so that all the bits are aligned to the end void alignTail (byte max =0) { // align bits if (bits != 0) { data[pos] >>= 8 - bits; for (byte i = 0; i < pos; ++i) data[i] = (data[i] >> bits) | (data[i+1] << (8 - bits)); bits = 0; } // optionally shift bytes down if there are too many of 'em if (max > 0 && pos > max) { byte n = pos - max; pos = max; for (byte i = 0; i < pos; ++i) data[i] = data[i+n]; } } void reverseBits () { for (byte i = 0; i < pos; ++i) { byte b = data[i]; for (byte j = 0; j < 8; ++j) { data[i] = (data[i] << 1) | (b & 1); b >>= 1; } } } void reverseNibbles () { for (byte i = 0; i < pos; ++i) data[i] = (data[i] << 4) | (data[i] >> 4); } void done () { while (bits) gotBit(0); // padding state = DONE; } }; // 433 MHz decoders //=================================================================== class OregonDecoderV3 : public DecodeOOK { public: OregonDecoderV3() {} // add one bit to the packet data buffer virtual void gotBit (char value) { data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00); total_bits++; pos = total_bits >> 3; if (pos >= sizeof data) { //Serial.println("sizeof data"); resetDecoder(); return; } state = OK; } virtual char decode (word width) { if (200 <= width && width < 1200) { //Serial.println(width); byte w = width >= 700; switch (state) { case UNKNOWN: if (w == 0) { // Long pulse ++flip; } else if (32 <= flip) { flip = 1; manchester(1); } else { // Reset decoder return -1; } break; case OK: if (w == 0) { // Short pulse state = T0; } else { // Long pulse manchester(1); } break; case T0: if (w == 0) { // Second short pulse manchester(0); } else { // Reset decoder return -1; } break; } } else { // Trame intermédiaire 48bits ex: [OSV3 6281 3C 6801 70] return (total_bits <104 && total_bits>=40 ) ? 1: -1; } return (total_bits == 104) ? 1: 0; } }; class OregonDecoderV2 : public DecodeOOK { public: OregonDecoderV2() {} // add one bit to the packet data buffer virtual void gotBit (char value) { if(!(total_bits & 0x01)) { data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00); } total_bits++; pos = total_bits >> 4; if (pos >= sizeof data) { Serial.println("sizeof data"); resetDecoder(); return; } state = OK; } virtual char decode (word width) { if (200 <= width && width < 1200) { //Serial.println(width); byte w = width >= 700; switch (state) { case UNKNOWN: if (w != 0) { // Long pulse ++flip; } else if (w == 0 && 24 <= flip) { // Short pulse, start bit flip = 0; state = T0; } else { // Reset decoder return -1; } break; case OK: if (w == 0) { // Short pulse state = T0; } else { // Long pulse manchester(1); } break; case T0: if (w == 0) { // Second short pulse manchester(0); } else { // Reset decoder return -1; } break; } } else if (width >= 2500 && pos >= 8) { return 1; } else { return -1; } return 0; } }; //=================================================================== OregonDecoderV2 orscV2; OregonDecoderV3 orscV3; volatile word pulse; void ext_int_1(void) { static word last; // determine the pulse length in microseconds, for either polarity pulse = micros() - last; last += pulse; } void reportSerial (const char* s, class DecodeOOK& decoder) { byte pos; const byte* data = decoder.getData(pos); #ifndef DISABLE_DEBUG Serial.print(s); Serial.print(' '); for (byte i = 0; i < pos; ++i) { Serial.print(data[i] >> 4, HEX); Serial.print(data[i] & 0x0F, HEX); } Serial.println(); #endif // Outside/Water Temp : THGN132N,... if(data[0] == 0xEA && data[1] == 0x4C) { #ifndef DISABLE_DEBUG Serial.print("[THGN132N,...] Id:"); Serial.print(data[3], HEX); Serial.print(", Channel:"); Serial.print(channel(data)); Serial.print(", temp:"); Serial.print(temperature(data)); Serial.print(", hum:"); Serial.print(humidity(data)); Serial.print(", bat:"); Serial.print(battery(data)); Serial.println(); #endif // используем только 2 датчика THGN132N на 1 и 2 канале if (channel(data) > 0 && channel(data) < 4){ t[channel(data)-1]=temperature(data); h[channel(data)-1]=humidity(data); b[channel(data)-1]=battery(data); // если время с прошлого измерения больше DELTA_TIME if(millis()-PrevMeasure[channel(data)-1] > DELTA_TIME) { // считаем тренд по двум значениям TrendTemp[channel(data)-1] = getTrend(t[channel(data)-1], PrevTemp[channel(data)-1], DELTA_TEMP); TrendHym[channel(data)-1] = getTrend(h[channel(data)-1], PrevHym[channel(data)-1], DELTA_HYM); // запоминаем "предыдущее" значение PrevTemp[channel(data)-1] = t[channel(data)-1]; PrevHym[channel(data)-1] = h[channel(data)-1]; // и записываем текущее время PrevMeasure[channel(data)-1] = millis(); #ifndef DISABLE_DEBUG Serial.print("TrendTemp["); Serial.print(channel(data)-1, DEC); Serial.print("]:"); Serial.print(TrendTemp[channel(data)-1], DEC); Serial.print(", TrendHym["); Serial.print(channel(data)-1, DEC); Serial.print("]:"); Serial.print(TrendHym[channel(data)-1], DEC); Serial.println(); #endif } } } decoder.resetDecoder(); } //установка времени void setDateDs1307(byte second, // 0-59 byte minute, // 0-59 byte hour, // 1-23 byte dayOfWeek, // 1-7 byte dayOfMonth, // 1-28/29/30/31 byte month, // 1-12 byte year) // 0-99 { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(dayOfWeek)); Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission(); } void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 7); *second = bcdToDec(Wire.read() & 0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read() & 0x3f); *dayOfWeek = bcdToDec(Wire.read()); *dayOfMonth = bcdToDec(Wire.read()); *month = bcdToDec(Wire.read()); *year = bcdToDec(Wire.read()); } byte decToBcd(byte val) { return ( (val/10*16) + (val%10) ); } byte bcdToDec(byte val) { return ( (val/16*10) + (val%16) ); } void setup () { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; Wire.begin(); second = 30; minute = 00; hour = 23; dayOfWeek = 7; dayOfMonth = 17; month = 5; year = 15; // setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); #ifndef DISABLE_DEBUG Serial.begin(9600); Serial.println("\n[WeatherStation]"); #endif lcd.begin(16, 2); pinMode(2, INPUT); // D2 - RF-модуль digitalWrite(2, 1); // включим подтягивающий резистор pinMode(LED, OUTPUT); // LED pinMode(BUTTON,INPUT); Wire.begin(); dht.begin(); bmp085Calibration(); attachInterrupt(0, ext_int_1, CHANGE); } void loop () { // char string[20]; noInterrupts(); word p = pulse; pulse = 0; interrupts(); if (p != 0) { if (orscV2.nextPulse(p)){ reportSerial("OSV2", orscV2); digitalWrite(LED, HIGH); ledNow = millis()+200; } } // Update the debouncer bouncer.update ( ); // Get the update value int value = bouncer.read(); if ((millis() >= dispNow) || ( value == HIGH)) { //lcd.print(string); getMeasure(); printValues(); dispNow=millis()+20000; } if (millis() >= ledNow) { digitalWrite(LED, LOW); } } float temperature(const byte* data) { int sign = (data[6]&0x8) ? -1 : 1; float temp = ((data[5]&0xF0) >> 4)*10 + (data[5]&0xF) + (float)(((data[4]&0xF0) >> 4) / 10.0); return sign * temp; } byte humidity(const byte* data) { return (data[7]&0xF) * 10 + ((data[6]&0xF0) >> 4); } // Ne retourne qu'un apercu de l'etat de la baterie : 10 = faible byte battery(const byte* data) { return (data[4] & 0x4) ? 10 : 90; } byte channel(const byte* data) { byte channel; switch (data[2]) { case 0x10: channel = 1; break; case 0x20: channel = 2; break; case 0x40: channel = 3; break; } return channel; } void printValues(){ char buf[17]; char tbuf[6]; char pbuf[6]; char string[20]; byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); switch (cDisp) { case 0: sprintf(buf, "Время: %02i:%02i:%02i ", hour, minute, dayOfWeek); lcd.setCursor(0, 1); lcd.print(buf); sprintf(buf, " %2d %s %4d ", dayOfMonth, month, year); lcd.setCursor(0, 1); lcd.print(buf); cDisp++; break; case 1: dtostrf(t[3],5,1,tbuf); sprintf(buf, "Inside: %s\xDF""C%c", tbuf, getTrendSign(TrendTemp[3])); lcd.setCursor(0, 0); lcd.print(buf); dtostrf(h[2],5,1,tbuf); dtostrf(h[3],3,0,pbuf); sprintf(buf, "%s%%%c %smm%c", tbuf, getTrendSign(TrendHym[2]), pbuf, getTrendSign(TrendHym[3])); lcd.setCursor(0, 1); lcd.print(buf); cDisp++; break; case 2: for (int i=0; i<2; i++) { dtostrf(t[i],5,1,tbuf); dtostrf(h[i],3,0,pbuf); sprintf(buf, "%s\xDF""C%c %s%%%c %c", tbuf, getTrendSign(TrendTemp[i]), pbuf, getTrendSign(TrendHym[i]), getBattSign(b[i])); lcd.setCursor(0, i); lcd.print(buf); } cDisp++; break; } if (cDisp>2) cDisp=0; } // функция получения тренда char getTrend(float val1, float val2, float delta) { if (val1-val2>delta) { return 1; } else if (val2-val1>delta) { return -1; } else { return 0; } } // функция выбора символа для отображения тренда char getTrendSign(char trend) { switch (trend){ case -1: return '_'; break; case 1: return '^'; break; default: return ' '; break; } } // функция выбора символа для отображения батареи char getBattSign(byte batt) { if (batt > 50){ return char(219); } return char(161); } // измерение void getMeasure() { // барометр t[3] = bmp085GetTemperature(bmp085ReadUT()); h[3] = bmp085GetPressure(bmp085ReadUP()); h[3] = h[3]*0.0075006375541921; //Serial.println(pressure*0.0075006375541921); // DHT22 t[2] = dht.readTemperature(); h[2] = dht.readHumidity(); // тренды if(millis()-PrevMeasure[3] > DELTA_TIME) { // считаем тренд по двум значениям TrendTemp[3] = getTrend(t[3], PrevTemp[3], DELTA_TEMP); TrendHym[3] = getTrend(h[3], PrevHym[3], DELTA_BAR); // давление у нас тут TrendTemp[2] = getTrend(t[2], PrevTemp[2], DELTA_TEMP); TrendHym[2] = getTrend(h[2], PrevHym[2], DELTA_HYM); // а тут влажность, как и должно // запоминаем "предыдущее" значение PrevTemp[3] = t[3]; PrevHym[3] = h[3]; PrevTemp[2] = t[2]; PrevHym[2] = h[2]; // и записываем текущее время PrevMeasure[3] = millis(); // поскольку у нас DHT22 и BMP085 опрашиваются одновременно - фиксируем время только одно } return; } void bmp085Calibration() { //Serial.println("test0"); ac1 = bmp085ReadInt(0xAA); //Serial.println("test1"); ac2 = bmp085ReadInt(0xAC); ac3 = bmp085ReadInt(0xAE); ac4 = bmp085ReadInt(0xB0); ac5 = bmp085ReadInt(0xB2); ac6 = bmp085ReadInt(0xB4); b1 = bmp085ReadInt(0xB6); b2 = bmp085ReadInt(0xB8); mb = bmp085ReadInt(0xBA); mc = bmp085ReadInt(0xBC); md = bmp085ReadInt(0xBE); //Serial.println("test2"); } // Calculate temperature in deg C float bmp085GetTemperature(unsigned int ut){ long x1, x2; x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; x2 = ((long)mc << 11)/(x1 + md); b5 = x1 + x2; float temp = ((b5 + 8)>>4); temp = temp /10; return temp; } // Calculate pressure given up // calibration values must be known // b5 is also required so bmp085GetTemperature(...) must be called first. // Value returned will be pressure in units of Pa. long bmp085GetPressure(unsigned long up){ long x1, x2, x3, b3, b6, pr; unsigned long b4, b7; b6 = b5 - 4000; // Calculate B3 x1 = (b2 * (b6 * b6)>>12)>>11; x2 = (ac2 * b6)>>11; x3 = x1 + x2; b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2; // Calculate B4 x1 = (ac3 * b6)>>13; x2 = (b1 * ((b6 * b6)>>12))>>16; x3 = ((x1 + x2) + 2)>>2; b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; b7 = ((unsigned long)(up - b3) * (50000>>OSS)); if (b7 < 0x80000000) pr = (b7<<1)/b4; else pr = (b7/b4)<<1; x1 = (pr>>8) * (pr>>8); x1 = (x1 * 3038)>>16; x2 = (-7357 * pr)>>16; pr += (x1 + x2 + 3791)>>4; long temp = pr; return temp; } // Read 1 byte from the BMP085 at 'address' char bmp085Read(unsigned char address) { unsigned char data; Wire.beginTransmission(BMP085_ADDRESS); Wire.write(address); Wire.endTransmission(); Wire.requestFrom(BMP085_ADDRESS, 1); while(!Wire.available()) ; return Wire.read(); } // Read 2 bytes from the BMP085 // First byte will be from 'address' // Second byte will be from 'address'+1 int bmp085ReadInt(unsigned char address) { unsigned char msb, lsb; //Serial.println("test3"); Wire.beginTransmission(BMP085_ADDRESS); Wire.write(address); Wire.endTransmission(); //Serial.println("test4"); Wire.requestFrom(BMP085_ADDRESS, 2); while(Wire.available()<2); msb = Wire.read(); lsb = Wire.read(); //Serial.println("test5"); return (int) msb<<8 | lsb; } // Read the uncompensated temperature value unsigned int bmp085ReadUT(){ unsigned int ut; // Write 0x2E into Register 0xF4 // This requests a temperature reading Wire.beginTransmission(BMP085_ADDRESS); Wire.write(0xF4); Wire.write(0x2E); Wire.endTransmission(); // Wait at least 4.5ms delay(5); // Read two bytes from registers 0xF6 and 0xF7 ut = bmp085ReadInt(0xF6); return ut; } // Read the uncompensated pressure value unsigned long bmp085ReadUP(){ unsigned char msb, lsb, xlsb; unsigned long up = 0; // Write 0x34+(OSS<<6) into register 0xF4 // Request a pressure reading w/ oversampling setting Wire.beginTransmission(BMP085_ADDRESS); Wire.write(0xF4); Wire.write(0x34 + (OSS<<6)); Wire.endTransmission(); // Wait for conversion, delay time dependent on OSS delay(2 + (3<<OSS)); // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB) msb = bmp085Read(0xF6); lsb = bmp085Read(0xF7); xlsb = bmp085Read(0xF8); up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS); return up; } void writeRegister(int deviceAddress, byte address, byte val) { Wire.beginTransmission(deviceAddress); // start transmission to device Wire.write(address); // send register address Wire.write(val); // send value to write Wire.endTransmission(); // end transmission } int readRegister(int deviceAddress, byte address){ int v; Wire.beginTransmission(deviceAddress); Wire.write(address); // register to read Wire.endTransmission(); Wire.requestFrom(deviceAddress, 1); // read a byte while(!Wire.available()) { // waiting } v = Wire.read(); return v; }
Данный код полностью работает для датчика DHN132... используется протокол V2
// New code to decode OOK signals from Energy OWL CMR180 sensor // Oregon V3 decoder added - Eric Vandecasteele (onlinux) // // Oregon V2 decoder modfied - Olivier Lebrun // Oregon V2 decoder added - Dominique Pierre // New code to decode OOK signals from weather sensors, etc. // 2010-04-11 <jcw@equi4.com> http://opensource.org/licenses/mit-license.php // $Id: ookDecoder.pde 5331 2010-04-17 10:45:17Z jcw $ //http://nm.omarov.net/ //http://cyber-place.ru/showthread.php?t=1169 //https://github.com/onlinux/OWL-CM180/blob/6d47a1003ffe4d00a5d72f01ffb3477ba8083a4e/arduino/oregon_owl.ino #include <LiquidCrystal.h> LiquidCrystal lcd(4, 5, 10, 11, 12, 13); //#define DISABLE_DEBUG // если нужен вывод в Serial - закомментируйте эту строчку class DecodeOOK { protected: byte total_bits, bits, flip, state, pos, data[31]; virtual char decode (word width) =0; public: enum { UNKNOWN, T0, T1, T2, T3, OK, DONE }; DecodeOOK () { resetDecoder(); } bool nextPulse (word width) { if (state != DONE) switch (decode(width)) { case -1: resetDecoder(); break; case 1: done(); break; } return isDone(); } bool isDone () const { return state == DONE; } const byte* getData (byte& count) const { count = pos; return data; } void resetDecoder () { total_bits = bits = pos = flip = 0; state = UNKNOWN; } // add one bit to the packet data buffer virtual void gotBit (char value) { total_bits++; byte *ptr = data + pos; *ptr = (*ptr >> 1) | (value << 7); if (++bits >= 8) { bits = 0; if (++pos >= sizeof data) { resetDecoder(); return; } } state = OK; } // store a bit using Manchester encoding_rx void manchester (char value) { flip ^= value; // manchester code, long pulse flips the bit gotBit(flip); } // move bits to the front so that all the bits are aligned to the end void alignTail (byte max =0) { // align bits if (bits != 0) { data[pos] >>= 8 - bits; for (byte i = 0; i < pos; ++i) data[i] = (data[i] >> bits) | (data[i+1] << (8 - bits)); bits = 0; } // optionally shift bytes down if there are too many of 'em if (max > 0 && pos > max) { byte n = pos - max; pos = max; for (byte i = 0; i < pos; ++i) data[i] = data[i+n]; } } void reverseBits () { for (byte i = 0; i < pos; ++i) { byte b = data[i]; for (byte j = 0; j < 8; ++j) { data[i] = (data[i] << 1) | (b & 1); b >>= 1; } } } void reverseNibbles () { for (byte i = 0; i < pos; ++i) data[i] = (data[i] << 4) | (data[i] >> 4); } void done () { while (bits) gotBit(0); // padding state = DONE; } }; class OregonDecoderV2 : public DecodeOOK { public: OregonDecoderV2() {} // add one bit to the packet data buffer virtual void gotBit (char value) { if(!(total_bits & 0x01)) { data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00); } total_bits++; pos = total_bits >> 4; if (pos >= sizeof data) { Serial.println("sizeof data"); resetDecoder(); return; } state = OK; } virtual char decode (word width) { if (200 <= width && width < 1200) { //Serial.println(width); byte w = width >= 700; switch (state) { case UNKNOWN: if (w != 0) { // Long pulse ++flip; } else if (w == 0 && 24 <= flip) { // Short pulse, start bit flip = 0; state = T0; } else { // Reset decoder return -1; } break; case OK: if (w == 0) { // Short pulse state = T0; } else { // Long pulse manchester(1); } break; case T0: if (w == 0) { // Second short pulse manchester(0); } else { // Reset decoder return -1; } break; } } else if (width >= 2500 && pos >= 8) { return 1; } else { return -1; } return 0; } }; //=================================================================== class OregonDecoderV3 : public DecodeOOK { public: OregonDecoderV3() {} // add one bit to the packet data buffer virtual void gotBit (char value) { data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00); total_bits++; pos = total_bits >> 3; if (pos >= sizeof data) { //Serial.println("sizeof data"); resetDecoder(); return; } state = OK; } virtual char decode (word width) { if (200 <= width && width < 1200) { //Serial.println(width); byte w = width >= 700; switch (state) { case UNKNOWN: if (w == 0) { // Long pulse ++flip; } else if (32 <= flip) { flip = 1; manchester(1); } else { // Reset decoder return -1; } break; case OK: if (w == 0) { // Short pulse state = T0; } else { // Long pulse manchester(1); } break; case T0: if (w == 0) { // Second short pulse manchester(0); } else { // Reset decoder return -1; } break; } } else { // Trame intermédiaire 48bits ex: [OSV3 6281 3C 6801 70] return (total_bits <104 && total_bits>=40 ) ? 1: -1; } return (total_bits == 104) ? 1: 0; } }; //=================================================================== OregonDecoderV2 orscV2; OregonDecoderV3 orscV3; volatile word pulse; void ext_int_1(void) { static word last; // determine the pulse length in microseconds, for either polarity pulse = micros() - last; last += pulse; } float temperature(const byte* data) { int sign = (data[6]&0x8) ? -1 : 1; float temp = ((data[5]&0xF0) >> 4)*10 + (data[5]&0xF) + (float)(((data[4]&0xF0) >> 4) / 10.0); return sign * temp; } byte humidity(const byte* data) { return (data[7]&0xF) * 10 + ((data[6]&0xF0) >> 4); } // Ne retourne qu'un apercu de l'etat de la batterie : 10 = faible byte battery(const byte* data) { return (data[4] & 0x4) ? 10 : 90; } byte channel(const byte* data) { byte channel; switch (data[2]) { case 0x10: channel = 1; break; case 0x20: channel = 2; break; case 0x40: channel = 3; break; } return channel; } unsigned int power(const byte* d){ unsigned int val = 0; val += d[4] << 8; val += d[3]; return val & 0xFFF0 ; } unsigned long total(const byte* d){ long val = 0; val = (unsigned long)d[8]<<24; // Serial.println(); // Serial.print(" val:"); Serial.print(val,HEX); Serial.print(" "); // Serial.println(d[8], HEX); val += (unsigned long)d[7] << 16; // Serial.print(" val:"); Serial.print(val,HEX); Serial.print(" "); // Serial.println(d[7], HEX); val += d[6] << 8; // Serial.print(" val:"); Serial.print(val,HEX); Serial.print(" "); // Serial.println(d[6], HEX); val += d[5]; // Serial.print(" val:"); Serial.print(val,HEX); Serial.print(" "); // Serial.println(d[5], HEX); return val ; } void reportSerial (const char* s, class DecodeOOK& decoder) { byte pos; const byte* data = decoder.getData(pos); #ifndef DISABLE_DEBUG Serial.print(s); Serial.print(' '); for (byte i = 0; i < pos; ++i) { Serial.print(data[i] >> 4, HEX); Serial.print(data[i] & 0x0F, HEX); } #endif // Energy OWL : CMR180 if(data[2] == 0x3C ) { #ifndef DISABLE_DEBUG Serial.print("[CMR180,...] Id:"); Serial.print(data[0], HEX);Serial.print(data[1], HEX); Serial.print(", size:"); Serial.print(pos); Serial.print(" ,Flags:"); Serial.print(data[3] & 0x0F, HEX); Serial.print(" ,power:"); Serial.print(power(data)); if (pos > 6) { // Display only for main frame // Secondary frame is only 6 Bytes long Serial.print(" ,total:"); Serial.print(total(data)); Serial.print(" ,total kWh:"); Serial.print(total(data)/3600/1000); } Serial.println(); #endif } // Outside/Water Temp : THN132N,... if (data[0] == 0xEA && data[1] == 0x4C) { #ifndef DISABLE_DEBUG Serial.print("[THN132N,...] Id:"); Serial.print(data[3], HEX); Serial.print(" ,Channel:"); Serial.print(channel(data)); Serial.print(" ,temp:"); Serial.print(temperature(data)); Serial.print(" ,bat:"); Serial.print(battery(data)); Serial.println(); #endif lcd.setCursor(0, 0); lcd.print("temp:"); lcd.setCursor(5, 0); lcd.print(temperature(data)); lcd.setCursor(10, 0); lcd.print("\x99"); } // Inside Temp-Hygro : THGR228N,... else if(data[0] == 0x1A && data[1] == 0x2D) { #ifndef DISABLE_DEBUG Serial.print("[THGR228N,...] Id:"); Serial.print(data[3], HEX); Serial.print(" ,Channel:"); Serial.print(channel(data)); Serial.print(" ,temp:"); Serial.print(temperature(data)); Serial.print(" ,hum:"); Serial.print(humidity(data)); Serial.print(" ,bat:"); Serial.print(battery(data)); Serial.println(); #endif } decoder.resetDecoder(); } void setup () { #ifndef DISABLE_DEBUG Serial.begin(115200); Serial.println("\n[ookDecoder]"); #endif lcd.begin(16, 2); attachInterrupt(0, ext_int_1, CHANGE); //DDRE &= ~_BV(PE5); //input with pull-up //PORTE &= ~_BV(PE5); } void loop () { static int i = 0; cli(); word p = pulse; pulse = 0; sei(); if (p != 0) { if (orscV3.nextPulse(p)) reportSerial("OSV3", orscV3); if (orscV2.nextPulse(p)) reportSerial("OSV2", orscV2); } }
Эх.... забыл спрятать под спойлер . Как можно отредактиовать тему?