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