Проблема в коде - выводится "удвоенное" значение температуры с oregon датчика

maksmkv
Offline
Зарегистрирован: 07.04.2013

Код большой - ссылку привожу https://cloud.mail.ru/public/DC4q/g3Mg223LH

Собственно проблема  вот в этих 2-х строчках:

 

 

 

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 10, 11, 12, 13);

const byte* data;   // первая строка


.....



void reportSerial (const char* s, class DecodeOOK& decoder) {
    byte pos;
    data = decoder.getData(pos);  // вторая строка
 .....  

 

Radjah
Offline
Зарегистрирован: 06.08.2014
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

1. Так в чём проблема-то? Что выводится, где выводится?

2. Если Вы и так знаете, что беда (неясно какая) в двух строках, то чего нас дёргаете?

3. Пост не содержит вопроса. Чего Вы от нас хотите? Чего ждёте?

maksmkv
Offline
Зарегистрирован: 07.04.2013
// 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

//*****УСТАНОВКА ВРЕМЕНИ ЧЕРЕЗ DS1307RTC

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 10, 11, 12, 13);

const byte* data;
//#define DISABLE_DEBUG // если нужен вывод в Serial - закомментируйте эту строчку

byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

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());
}









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;
    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
     
     
     
    }
    // 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 ()
{
  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(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 () {
  printTime();
    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);   
    }
}


void printTime()
{
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    
    
    lcd.setCursor(0, 0);
     lcd.print("t:");
     lcd.setCursor(2, 0);
     lcd.print(temperature(data));
   
     
     
     
    lcd.setCursor(0, 1);   
lcd.print(hour);
lcd.setCursor(2, 1);  
lcd.print(":");  
lcd.setCursor(3, 1); 
lcd.print(minute);
lcd.setCursor(5, 1); 
lcd.print(":");  
lcd.print(second);
lcd.setCursor(8, 0); 
lcd.print(dayOfMonth);
lcd.setCursor(10, 0);
lcd.print("/");
lcd.setCursor(11, 0); 
lcd.print(month);
lcd.setCursor(13, 0); 
lcd.print("/");
lcd.setCursor(14, 0);
lcd.print(year);
    
    
 
  
  
}

Вот весь код как и просили выше. Собственно  на  дисплее 16x2 выводится правильно  время, секунды тикают. Но температура  выводиться не  правильно. Исходник брал ( в ссылках в коде есть на github).  Перенес переменную в глобальные (разговор про 2 строчки), т.к. если  выводить непосредственно вот в этом куске кода  - температура не отображается, а только  время. Надеюсь понятно описал.

 // 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("t:");
     lcd.setCursor(2, 0);
     lcd.print(temperature(data));
      
     
    }

 

Radjah
Offline
Зарегистрирован: 06.08.2014
static word last;
// determine the pulse length in microseconds, for either polarity
pulse = micros() - last;

last сделай уже тоже глобальной и запиши в нее что-нибудь перед использованием.

Сам датчик как данные передаёт? Меня смущает прерывание по CHANGE.

mkvmaks
Offline
Зарегистрирован: 07.07.2013

Если оставить исходник с github - тозначения более менее ровные (с комнатным отличия в 2 градуса). Если вы об этом

mkvmaks
Offline
Зарегистрирован: 07.07.2013

Проще так: как мне вывести значение температуры и времени одновременно используя мои коды? По отдельности все работает. вывод с задержкой не вариант,т.к. сразу фризится время

vladiv
Offline
Зарегистрирован: 18.03.2014

Время действительно надо?

Задержку в секунду сделайте.