Oregegon scientific decoder V2.1 and V3

Dependents:   Oregon_Decoder_V2_V3

Oregon decoding Library.

It manages protocoles V2.1 and V3.

To be used with RTOS OS2 or MBED V5

OregonBit.cpp

Committer:
sev2000
Date:
2020-04-26
Revision:
11:4cfdb2d79394
Parent:
9:ac5060331882
Child:
12:6d3638a225dd

File content as of revision 11:4cfdb2d79394:

#include "rtos.h" 
#include "Regul.h"

#define Level 1 

int processData(measure_t*, int version);

typedef struct {
    int v;
    bool pin;
}pulse_t;

int onShortLo = 200;
int onShortHi = 700;
int offShortLo = 200;
int offShortHi = 700;
int onLongLo = 700;
int onLongHi = 1200;
int offLongLo = 700;
int offLongHi = 1200;
/*
int onShortLo = 201;
int onShortHi = 615;
int offShortLo = 400;
int offShortHi = 850;
int onLongLo = 615;
int onLongHi = 1100;
int offLongLo = 850;
int offLongHi = 1400;
*/
static long startedAt;
static long endedAt;

static bool dataBits[145]={0}; // 18 Nibbles +1

//Thread O_thread(osPriorityBelowNormal);
Thread O_thread(osPriorityNormal);
static Timer xTime; 

InterruptIn dataPin(PB_8);
DigitalOut  StbyPin(PB_9, 1);

static CircularBuffer<pulse_t, BUF_SIZE> PulseWidth;

measure_t Sensor[NB_CHAN] ={0};
static pulse_t timeDiff;

static void getPulseF(void)
{
        endedAt = xTime.read_us(); // set timer end for last pin
        timeDiff.v = endedAt - startedAt;
        timeDiff.pin = 1;
        PulseWidth.push(timeDiff);
        startedAt= endedAt; //  set timer start for this pin
}

static void getPulseR(void)
{
        endedAt = xTime.read_us(); // set timer end for last pin
        timeDiff.v = endedAt - startedAt;
        timeDiff.pin = 0;
        PulseWidth.push(timeDiff);
        startedAt= endedAt; //  set timer start for this pin
}

 

void getData()
{
pulse_t pulse;
// get next 128 data bits, we determined bit 0 in SYNC
int i= 0; 
int l= 0; // long pulse;
int s= 0; // short pulse
int bit_ptr= 1; //first bit[0] was derived in Preamble;
char state=0;
 
while(true)
    {
    i=0;
    if(PulseWidth.empty()) //If no pulse received since 100 ms, we are no more in the frame
        state=0;
    while(!PulseWidth.empty() && i<200)
        {
        PulseWidth.pop(pulse);
        //pc.printf("%d,", pulse.v);
        if (pulse.pin == 0) //Pin was OFF
            {
            if ((pulse.v > offShortLo) && (pulse.v < offShortHi))
                { // short off detected
                    s++;
                    l=0;
                }
            else if ((pulse.v > offLongLo) && (pulse.v < offLongHi))
                { // long off detected
                    l++;
                    s=0;
                }
            else
                {
                    l=0;
                    s=0;
                }
            }
        else // Pin was ON
            {
            if ((pulse.v > onShortLo) && (pulse.v < onShortHi)) // half-time
                { // short on detetcted
                s++;
                l=0;
                }
            else if ((pulse.v > onLongLo) && (pulse.v < onLongHi)) // full-time
                { // long on detected
                l++;
                s=0;
                }
            else
                {
                    l=0;
                    s=0;
                }
            }

        switch(state)
            {
            case 0:     // Detect preamble 
                        if(l >= 24) // out of 32
                            state=1;
                        if(s >= 40) // out of 48
                            state=11;
                        //pc.printf("%d ", l);
                        break;
            case 1:     // wait start bit (first short in V2.1)
                        //pc.printf("OK2");
                        l=0;
                        if (s==1)
                            state = 2;
                        break;
            case 11:     // wait start bit (first long in V3)
                        //pc.printf("OK3");
                        s=0;
                        if (l==1)
                            {
                            state = 21;
                            dataBits[1]=0; // l => opposite of previous (1)
                            bit_ptr=2;
                            l=0;
                            }
                        break;
            case 2: 
                        //pc.printf(" %d", pulse.v);
                        if(s==0 && l==0)
                            {
                            ERR(" %s : %d\t", (pulse.pin ? "on" : "off"), pulse.v);
                            if (0 == bit_ptr%2)
                                l=1; // V2.1 2nd bit is !(bit n-1)
                            else 
                                if (pulse.v > 736)
                                    l=1;
                                else
                                    s=1;
                            }
                        if (0 == bit_ptr%2 && !l)
                            {
                            ERR("%d V2.1 : 2nd pulse should be long",bit_ptr);
                            s=0;
                            l=1;
                            }
            
                        if (s == 2)
                            { // 2 short pulses this bit equals previous bit (we know 1st bit from sync)
                            dataBits[bit_ptr] = dataBits[bit_ptr-1];
              /*                  if(dataBits[bit_ptr] != !pulse.pin)
                                    pc.printf("Error : V2.1 : pin level don't match"); */
                            bit_ptr++;
                            s=0;
                            l=0;
                            }
                        if (l == 1 && s==0)
                            { // 1 long pulse this bit is inverse of previous bit (we know 1st bit from sync)
                            dataBits[bit_ptr] = !dataBits[bit_ptr-1];
                            l=0;
                            s=0;
                            bit_ptr++;
                            }
                        if(bit_ptr>144)
                            {
                            processData(Sensor,2);
                            state=0;
                            bit_ptr=1;
                            WARN(" Waiting...");
                            }
                        break;
            case 21: 
                        //pc.printf(" %d", pulse.v);
                        if(s==0 && l==0)
                            {
                            ERR(" %s : %d\t", (pulse.pin ? "on" : "off"), pulse.v);

                            if (pulse.v > 736)
                                l=1;
                            else
                                s=1;
                            }
            
                        if(s==1 && l==1)
                            ERR(" %s : %d\t", (pulse.pin ? "on" : "off"), pulse.v);
                        
                        if (s == 2)
                            { // 2 short pulses this bit equals previous bit (we know 1st bit from sync)
                            dataBits[bit_ptr] = dataBits[bit_ptr-1];
                            //pc.printf(",[%d]%d",bit_ptr, dataBits[bit_ptr]);
                            bit_ptr++;
                            s=0;
                            l=0;
                            }
                        if (l == 1)
                            { // 1 long pulse this bit is inverse of previous bit (we know 1st bit from sync)
                            dataBits[bit_ptr] = !dataBits[bit_ptr-1];
                            l=0;
                            s=0;
                            //pc.printf(",[%d]%d",bit_ptr, dataBits[bit_ptr]);
                            bit_ptr++;
                            }
                        if(bit_ptr>72)
                            {
                            processData(Sensor,3);
                            state=0;
                            bit_ptr=1;
                            WARN(" Waiting...");
                            }
                        break;
            }
        i++;
        }
    Thread::wait(100);
    }
 //   return 0;
}
 
int processData(measure_t *data, int version)
{
int x;
int i = 0;
int j=  0;
char nibble[18]={0}, chksum=0;
int tmp;
char channel;

    x= (version==2) ? 2 : 1;
    for (i=0;i<18;i++)
        {
        for (j=0;j<4;j++)
            {
            if ( dataBits[x])
                nibble[i] |= 1<<j;
            x+= (version==2) ? 2 : 1;
            }
        }
                
    for (x=1;x<73;x++)
    {
//        pc.printf("%d", dataBits[x]);
        dataBits[x]=0;
    }

#ifdef __DEBUG__
    for (i=0;i<18;i++)
        pc.printf("%X ",nibble[i]);
    pc.printf("\r\n");
#endif
    
//Decoding for THGR122NX(1D20) and THGR810(F8B4)
    if( 0x0A == nibble[0])
        {
        //Compute Checksum
        for (i=1;i<16;i++)
            chksum += nibble[i]; //no overflow if computed on 15 Nibbles
    
        if (chksum == (nibble[17]<<4 | nibble[16]))
            {
            channel =  nibble[5];
            data[channel].deviceID = channel;
            DBG("Channel: %d", channel);
        
            tmp= (nibble[8] & 0x4) ? 10 : 90;
            DBG("Batterie: %d", tmp);
        
            int sign = (nibble[12]>0x0) ? -1 : 1;
            float temp = nibble[11]*10 + nibble[10] + (float)(nibble[9] / 10.0);
            temp= sign * temp;
            data[channel].temp1= temp;
            DBG("Temperature: %0.1f", temp);
        
            tmp= nibble[14] * 10 + nibble[13];
            data[channel].hum1= (float)tmp;
            DBG("Humidity: %d", tmp);
            
            data[channel].timestamp=time(NULL);
            }
        else
            ERR("Checksum error %X", chksum);
        }
    else
        ERR("Sync error");
    return 0;
}
void RF_Active()
{
    DBG("RF Active");
    xTime.reset();
    startedAt= 0;
    dataPin.enable_irq();
    StbyPin = 1;
}

void RF_StdBy()
{
    DBG("RF Standby");
    StbyPin = 0;
    dataPin.disable_irq();
    PulseWidth.reset(); //clear Circular Buffer
}


void Init_Oregon()
{
    dataPin.fall(&getPulseF);
    dataPin.rise(&getPulseR);
    RF_Active();

    xTime.start();
    xTime.reset();
    dataBits[0] = 1;
    O_thread.start(getData);
}