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-25
- Revision:
- 8:48315bba3adc
- Parent:
- 7:47fb36f30355
- Child:
- 9:ac5060331882
File content as of revision 8:48315bba3adc:
#include "rtos.h" #include "Regul.h" 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; long O_startedAt; long O_endedAt; bool O_dataBits[145]={0}; // 18 Nibbles +1 Thread O_thread(osPriorityBelowNormal); Timer O_xTime; InterruptIn dataPin(PB_8); DigitalOut StbyPin(PB_9, 1); CircularBuffer<pulse_t, BUF_SIZE> O_PulseWidth; measure_t Sensor[NB_CHAN] ={0}; pulse_t O_timeDiff; void O_getPulseF(void) { O_endedAt = O_xTime.read_us(); // set timer end for last pin O_timeDiff.v = O_endedAt - O_startedAt; O_timeDiff.pin = 1; O_PulseWidth.push(O_timeDiff); O_startedAt= O_endedAt; // set timer start for this pin } void O_getPulseR(void) { O_endedAt = O_xTime.read_us(); // set timer end for last pin O_timeDiff.v = O_endedAt - O_startedAt; O_timeDiff.pin = 0; O_PulseWidth.push(O_timeDiff); O_startedAt= O_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(O_PulseWidth.empty()) //If no pulse received since 100 ms, we are no more in the frame state=0; while(!O_PulseWidth.empty() && i<200) { O_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; O_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) { O_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) { O_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) O_dataBits[bit_ptr] = O_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) O_dataBits[bit_ptr] = !O_dataBits[bit_ptr-1]; l=0; s=0; bit_ptr++; } if(bit_ptr>144) { processData(Sensor,2); state=0; bit_ptr=1; O_WARN(" Waiting..."); } break; case 21: //pc.printf(" %d", pulse.v); if(s==0 && l==0) { O_ERR(" %s : %d\t", (pulse.pin ? "on" : "off"), pulse.v); if (pulse.v > 736) l=1; else s=1; } if(s==1 && l==1) O_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) O_dataBits[bit_ptr] = O_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) O_dataBits[bit_ptr] = !O_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; O_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 ( O_dataBits[x]) nibble[i] |= 1<<j; x+= (version==2) ? 2 : 1; } } for (x=1;x<73;x++) { // pc.printf("%d", O_dataBits[x]); O_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; O_DBG("Channel: %d", channel); tmp= (nibble[8] & 0x4) ? 10 : 90; O_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; O_DBG("Temperature: %0.1f", temp); tmp= nibble[14] * 10 + nibble[13]; data[channel].hum1= (float)tmp; O_DBG("Humidity: %d", tmp); data[channel].timestamp=time(NULL); } else O_ERR("Checksum error %X", chksum); } else O_ERR("Sync error"); return 0; } void RF_Active() { O_DBG("RF Active"); O_xTime.reset(); O_startedAt= 0; dataPin.enable_irq(); StbyPin = 1; } void RF_StdBy() { O_DBG("RF Standby"); StbyPin = 0; dataPin.disable_irq(); O_PulseWidth.reset(); //clear Circular Buffer } void Init_Oregon() { dataPin.fall(&O_getPulseF); dataPin.rise(&O_getPulseR); RF_Active(); O_xTime.start(); O_xTime.reset(); O_dataBits[0] = 1; O_thread.start(getData); }