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

Committer:
sev2000
Date:
Sun Dec 15 17:46:08 2019 +0000
Revision:
1:37ddcdfee022
Parent:
0:4875d3d646de
Child:
5:23cbd3014844
Modified to integrate with X2D

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sev2000 1:37ddcdfee022 1 #include "rtos.h"
sev2000 0:4875d3d646de 2 #include "Regul.h"
sev2000 0:4875d3d646de 3
sev2000 0:4875d3d646de 4 int processData(measure_t*, int version);
sev2000 0:4875d3d646de 5
sev2000 0:4875d3d646de 6 typedef struct {
sev2000 0:4875d3d646de 7 int v;
sev2000 0:4875d3d646de 8 bool pin;
sev2000 0:4875d3d646de 9 }pulse_t;
sev2000 0:4875d3d646de 10
sev2000 0:4875d3d646de 11 int onShortLo = 201;
sev2000 0:4875d3d646de 12 int onShortHi = 615;
sev2000 0:4875d3d646de 13 int offShortLo = 400;
sev2000 0:4875d3d646de 14 int offShortHi = 850;
sev2000 0:4875d3d646de 15 int onLongLo = 615;
sev2000 0:4875d3d646de 16 int onLongHi = 1100;
sev2000 0:4875d3d646de 17 int offLongLo = 850;
sev2000 0:4875d3d646de 18 int offLongHi = 1400;
sev2000 1:37ddcdfee022 19 long O_startedAt;
sev2000 1:37ddcdfee022 20 long O_endedAt;
sev2000 0:4875d3d646de 21
sev2000 1:37ddcdfee022 22 bool O_dataBits[145]={0}; // 18 Nibbles +1
sev2000 0:4875d3d646de 23
sev2000 1:37ddcdfee022 24 Thread O_thread;
sev2000 1:37ddcdfee022 25 Timer O_xTime;
sev2000 0:4875d3d646de 26
sev2000 0:4875d3d646de 27 InterruptIn dataPin(PB_8, PullUp);
sev2000 1:37ddcdfee022 28 DigitalOut StbyPin(PB_9, 1);
sev2000 0:4875d3d646de 29
sev2000 1:37ddcdfee022 30 CircularBuffer<pulse_t, BUF_SIZE> O_PulseWidth;
sev2000 0:4875d3d646de 31
sev2000 0:4875d3d646de 32 measure_t Sensor[NB_CHAN] ={0};
sev2000 1:37ddcdfee022 33 pulse_t O_timeDiff;
sev2000 0:4875d3d646de 34
sev2000 1:37ddcdfee022 35 void O_getPulseF(void)
sev2000 0:4875d3d646de 36 {
sev2000 1:37ddcdfee022 37 O_endedAt = O_xTime.read_us(); // set timer end for last pin
sev2000 1:37ddcdfee022 38 O_timeDiff.v = O_endedAt - O_startedAt;
sev2000 1:37ddcdfee022 39 O_timeDiff.pin = 1;
sev2000 1:37ddcdfee022 40 O_PulseWidth.push(O_timeDiff);
sev2000 1:37ddcdfee022 41 O_startedAt= O_endedAt; // set timer start for this pin
sev2000 0:4875d3d646de 42 }
sev2000 0:4875d3d646de 43
sev2000 1:37ddcdfee022 44 void O_getPulseR(void)
sev2000 0:4875d3d646de 45 {
sev2000 1:37ddcdfee022 46 O_endedAt = O_xTime.read_us(); // set timer end for last pin
sev2000 1:37ddcdfee022 47 O_timeDiff.v = O_endedAt - O_startedAt;
sev2000 1:37ddcdfee022 48 O_timeDiff.pin = 0;
sev2000 1:37ddcdfee022 49 O_PulseWidth.push(O_timeDiff);
sev2000 1:37ddcdfee022 50 O_startedAt= O_endedAt; // set timer start for this pin
sev2000 0:4875d3d646de 51 }
sev2000 0:4875d3d646de 52
sev2000 0:4875d3d646de 53
sev2000 0:4875d3d646de 54
sev2000 0:4875d3d646de 55 void getData()
sev2000 0:4875d3d646de 56 {
sev2000 0:4875d3d646de 57 pulse_t pulse;
sev2000 0:4875d3d646de 58 // get next 128 data bits, we determined bit 0 in SYNC
sev2000 0:4875d3d646de 59 int i= 0;
sev2000 0:4875d3d646de 60 int l= 0; // long pulse;
sev2000 0:4875d3d646de 61 int s= 0; // short pulse
sev2000 0:4875d3d646de 62 int bit_ptr= 1; //first bit[0] was derived in Preamble;
sev2000 0:4875d3d646de 63 char state=0;
sev2000 0:4875d3d646de 64
sev2000 0:4875d3d646de 65 while(true)
sev2000 0:4875d3d646de 66 {
sev2000 0:4875d3d646de 67 i=0;
sev2000 1:37ddcdfee022 68 while(!O_PulseWidth.empty() && i<100)
sev2000 0:4875d3d646de 69 {
sev2000 1:37ddcdfee022 70 O_PulseWidth.pop(pulse);
sev2000 0:4875d3d646de 71 //pc.printf("%d,", pulse.v);
sev2000 0:4875d3d646de 72 if (pulse.pin == 0) //Pin was OFF
sev2000 0:4875d3d646de 73 {
sev2000 0:4875d3d646de 74 if ((pulse.v > offShortLo) && (pulse.v < offShortHi))
sev2000 0:4875d3d646de 75 { // short off detected
sev2000 0:4875d3d646de 76 s++;
sev2000 0:4875d3d646de 77 l=0;
sev2000 0:4875d3d646de 78 }
sev2000 0:4875d3d646de 79 else if ((pulse.v > offLongLo) && (pulse.v < offLongHi))
sev2000 0:4875d3d646de 80 { // long off detected
sev2000 0:4875d3d646de 81 l++;
sev2000 0:4875d3d646de 82 s=0;
sev2000 0:4875d3d646de 83 }
sev2000 0:4875d3d646de 84 else
sev2000 0:4875d3d646de 85 {
sev2000 0:4875d3d646de 86 l=0;
sev2000 0:4875d3d646de 87 s=0;
sev2000 0:4875d3d646de 88 }
sev2000 0:4875d3d646de 89 }
sev2000 0:4875d3d646de 90 else // Pin was ON
sev2000 0:4875d3d646de 91 {
sev2000 0:4875d3d646de 92 if ((pulse.v > onShortLo) && (pulse.v < onShortHi)) // half-time
sev2000 0:4875d3d646de 93 { // short on detetcted
sev2000 0:4875d3d646de 94 s++;
sev2000 0:4875d3d646de 95 l=0;
sev2000 0:4875d3d646de 96 }
sev2000 0:4875d3d646de 97 else if ((pulse.v > onLongLo) && (pulse.v < onLongHi)) // full-time
sev2000 0:4875d3d646de 98 { // long on detected
sev2000 0:4875d3d646de 99 l++;
sev2000 0:4875d3d646de 100 s=0;
sev2000 0:4875d3d646de 101 }
sev2000 0:4875d3d646de 102 else
sev2000 0:4875d3d646de 103 {
sev2000 0:4875d3d646de 104 l=0;
sev2000 0:4875d3d646de 105 s=0;
sev2000 0:4875d3d646de 106 }
sev2000 0:4875d3d646de 107 }
sev2000 0:4875d3d646de 108
sev2000 0:4875d3d646de 109 switch(state)
sev2000 0:4875d3d646de 110 {
sev2000 0:4875d3d646de 111 case 0: // Detect preamble
sev2000 0:4875d3d646de 112 if(l >= 24) // out of 32
sev2000 0:4875d3d646de 113 state=1;
sev2000 0:4875d3d646de 114 if(s >= 40) // out of 48
sev2000 0:4875d3d646de 115 state=11;
sev2000 0:4875d3d646de 116 //pc.printf("%d ", l);
sev2000 0:4875d3d646de 117 break;
sev2000 0:4875d3d646de 118 case 1: // wait start bit (first short in V2.1)
sev2000 0:4875d3d646de 119 //pc.printf("OK2");
sev2000 0:4875d3d646de 120 l=0;
sev2000 0:4875d3d646de 121 if (s==1)
sev2000 0:4875d3d646de 122 state = 2;
sev2000 0:4875d3d646de 123 break;
sev2000 0:4875d3d646de 124 case 11: // wait start bit (first long in V3)
sev2000 0:4875d3d646de 125 //pc.printf("OK3");
sev2000 0:4875d3d646de 126 s=0;
sev2000 0:4875d3d646de 127 if (l==1)
sev2000 0:4875d3d646de 128 {
sev2000 0:4875d3d646de 129 state = 21;
sev2000 1:37ddcdfee022 130 O_dataBits[1]=0; // l => opposite of previous (1)
sev2000 0:4875d3d646de 131 bit_ptr=2;
sev2000 0:4875d3d646de 132 l=0;
sev2000 0:4875d3d646de 133 }
sev2000 0:4875d3d646de 134 break;
sev2000 0:4875d3d646de 135 case 2:
sev2000 0:4875d3d646de 136 //pc.printf(" %d", pulse.v);
sev2000 0:4875d3d646de 137 if(s==0 && l==0)
sev2000 0:4875d3d646de 138 {
sev2000 1:37ddcdfee022 139 O_ERR(" %s : %d\t", (pulse.pin ? "on" : "off"), pulse.v);
sev2000 0:4875d3d646de 140 if (0 == bit_ptr%2)
sev2000 0:4875d3d646de 141 l=1; // V2.1 2nd bit is !(bit n-1)
sev2000 0:4875d3d646de 142 else
sev2000 0:4875d3d646de 143 if (pulse.v > 736)
sev2000 0:4875d3d646de 144 l=1;
sev2000 0:4875d3d646de 145 else
sev2000 0:4875d3d646de 146 s=1;
sev2000 0:4875d3d646de 147 }
sev2000 0:4875d3d646de 148 if (0 == bit_ptr%2 && !l)
sev2000 0:4875d3d646de 149 {
sev2000 1:37ddcdfee022 150 O_ERR("%d V2.1 : 2nd pulse should be long",bit_ptr);
sev2000 0:4875d3d646de 151 s=0;
sev2000 0:4875d3d646de 152 l=1;
sev2000 0:4875d3d646de 153 }
sev2000 0:4875d3d646de 154
sev2000 0:4875d3d646de 155 if (s == 2)
sev2000 0:4875d3d646de 156 { // 2 short pulses this bit equals previous bit (we know 1st bit from sync)
sev2000 1:37ddcdfee022 157 O_dataBits[bit_ptr] = O_dataBits[bit_ptr-1];
sev2000 0:4875d3d646de 158 /* if(dataBits[bit_ptr] != !pulse.pin)
sev2000 0:4875d3d646de 159 pc.printf("Error : V2.1 : pin level don't match"); */
sev2000 0:4875d3d646de 160 bit_ptr++;
sev2000 0:4875d3d646de 161 s=0;
sev2000 0:4875d3d646de 162 l=0;
sev2000 0:4875d3d646de 163 }
sev2000 0:4875d3d646de 164 if (l == 1 && s==0)
sev2000 0:4875d3d646de 165 { // 1 long pulse this bit is inverse of previous bit (we know 1st bit from sync)
sev2000 1:37ddcdfee022 166 O_dataBits[bit_ptr] = !O_dataBits[bit_ptr-1];
sev2000 0:4875d3d646de 167 l=0;
sev2000 0:4875d3d646de 168 s=0;
sev2000 0:4875d3d646de 169 bit_ptr++;
sev2000 0:4875d3d646de 170 }
sev2000 0:4875d3d646de 171 if(bit_ptr>144)
sev2000 0:4875d3d646de 172 {
sev2000 0:4875d3d646de 173 processData(Sensor,2);
sev2000 0:4875d3d646de 174 state=0;
sev2000 0:4875d3d646de 175 bit_ptr=1;
sev2000 1:37ddcdfee022 176 O_WARN(" Waiting...");
sev2000 0:4875d3d646de 177 }
sev2000 0:4875d3d646de 178 break;
sev2000 0:4875d3d646de 179 case 21:
sev2000 0:4875d3d646de 180 //pc.printf(" %d", pulse.v);
sev2000 0:4875d3d646de 181 if(s==0 && l==0)
sev2000 0:4875d3d646de 182 {
sev2000 1:37ddcdfee022 183 O_ERR(" %s : %d\t", (pulse.pin ? "on" : "off"), pulse.v);
sev2000 0:4875d3d646de 184
sev2000 0:4875d3d646de 185 if (pulse.v > 736)
sev2000 0:4875d3d646de 186 l=1;
sev2000 0:4875d3d646de 187 else
sev2000 0:4875d3d646de 188 s=1;
sev2000 0:4875d3d646de 189 }
sev2000 0:4875d3d646de 190
sev2000 0:4875d3d646de 191 if(s==1 && l==1)
sev2000 1:37ddcdfee022 192 O_ERR(" %s : %d\t", (pulse.pin ? "on" : "off"), pulse.v);
sev2000 0:4875d3d646de 193
sev2000 0:4875d3d646de 194 if (s == 2)
sev2000 0:4875d3d646de 195 { // 2 short pulses this bit equals previous bit (we know 1st bit from sync)
sev2000 1:37ddcdfee022 196 O_dataBits[bit_ptr] = O_dataBits[bit_ptr-1];
sev2000 0:4875d3d646de 197 //pc.printf(",[%d]%d",bit_ptr, dataBits[bit_ptr]);
sev2000 0:4875d3d646de 198 bit_ptr++;
sev2000 0:4875d3d646de 199 s=0;
sev2000 0:4875d3d646de 200 l=0;
sev2000 0:4875d3d646de 201 }
sev2000 0:4875d3d646de 202 if (l == 1)
sev2000 0:4875d3d646de 203 { // 1 long pulse this bit is inverse of previous bit (we know 1st bit from sync)
sev2000 1:37ddcdfee022 204 O_dataBits[bit_ptr] = !O_dataBits[bit_ptr-1];
sev2000 0:4875d3d646de 205 l=0;
sev2000 0:4875d3d646de 206 s=0;
sev2000 0:4875d3d646de 207 //pc.printf(",[%d]%d",bit_ptr, dataBits[bit_ptr]);
sev2000 0:4875d3d646de 208 bit_ptr++;
sev2000 0:4875d3d646de 209 }
sev2000 0:4875d3d646de 210 if(bit_ptr>72)
sev2000 0:4875d3d646de 211 {
sev2000 0:4875d3d646de 212 processData(Sensor,3);
sev2000 0:4875d3d646de 213 state=0;
sev2000 0:4875d3d646de 214 bit_ptr=1;
sev2000 1:37ddcdfee022 215 O_WARN(" Waiting...");
sev2000 0:4875d3d646de 216 }
sev2000 0:4875d3d646de 217 break;
sev2000 0:4875d3d646de 218 }
sev2000 0:4875d3d646de 219 i++;
sev2000 0:4875d3d646de 220 }
sev2000 1:37ddcdfee022 221 Thread::wait(50);
sev2000 0:4875d3d646de 222 }
sev2000 0:4875d3d646de 223 // return 0;
sev2000 0:4875d3d646de 224 }
sev2000 0:4875d3d646de 225
sev2000 0:4875d3d646de 226 int processData(measure_t *data, int version)
sev2000 0:4875d3d646de 227 {
sev2000 0:4875d3d646de 228 int x;
sev2000 0:4875d3d646de 229 int i = 0;
sev2000 0:4875d3d646de 230 int j= 0;
sev2000 0:4875d3d646de 231 char nibble[18]={0}, chksum=0;
sev2000 0:4875d3d646de 232 int tmp;
sev2000 0:4875d3d646de 233 char channel;
sev2000 0:4875d3d646de 234
sev2000 0:4875d3d646de 235 x= (version==2) ? 2 : 1;
sev2000 0:4875d3d646de 236 for (i=0;i<18;i++)
sev2000 0:4875d3d646de 237 {
sev2000 0:4875d3d646de 238 for (j=0;j<4;j++)
sev2000 0:4875d3d646de 239 {
sev2000 1:37ddcdfee022 240 if ( O_dataBits[x])
sev2000 0:4875d3d646de 241 nibble[i] |= 1<<j;
sev2000 0:4875d3d646de 242 x+= (version==2) ? 2 : 1;
sev2000 0:4875d3d646de 243 }
sev2000 0:4875d3d646de 244 }
sev2000 0:4875d3d646de 245
sev2000 0:4875d3d646de 246 for (x=1;x<73;x++)
sev2000 0:4875d3d646de 247 {
sev2000 1:37ddcdfee022 248 // pc.printf("%d", O_dataBits[x]);
sev2000 1:37ddcdfee022 249 O_dataBits[x]=0;
sev2000 0:4875d3d646de 250 }
sev2000 0:4875d3d646de 251
sev2000 0:4875d3d646de 252 #ifdef __DEBUG__
sev2000 0:4875d3d646de 253 for (i=0;i<18;i++)
sev2000 0:4875d3d646de 254 pc.printf("%X ",nibble[i]);
sev2000 0:4875d3d646de 255 pc.printf("\r\n");
sev2000 0:4875d3d646de 256 #endif
sev2000 0:4875d3d646de 257
sev2000 0:4875d3d646de 258 //Decoding for THGR122NX(1D20) and THGR810(F8B4)
sev2000 0:4875d3d646de 259 if( 0x0A == nibble[0])
sev2000 0:4875d3d646de 260 {
sev2000 0:4875d3d646de 261 //Compute Checksum
sev2000 0:4875d3d646de 262 for (i=1;i<16;i++)
sev2000 0:4875d3d646de 263 chksum += nibble[i]; //no overflow if computed on 15 Nibbles
sev2000 0:4875d3d646de 264
sev2000 0:4875d3d646de 265 if (chksum == (nibble[17]<<4 | nibble[16]))
sev2000 0:4875d3d646de 266 {
sev2000 0:4875d3d646de 267 channel = nibble[5];
sev2000 0:4875d3d646de 268 data[channel].deviceID = channel;
sev2000 1:37ddcdfee022 269 O_DBG("Channel: %d", channel);
sev2000 0:4875d3d646de 270
sev2000 0:4875d3d646de 271 tmp= (nibble[8] & 0x4) ? 10 : 90;
sev2000 1:37ddcdfee022 272 O_DBG("Batterie: %d", tmp);
sev2000 0:4875d3d646de 273
sev2000 0:4875d3d646de 274 int sign = (nibble[12]>0x0) ? -1 : 1;
sev2000 0:4875d3d646de 275 float temp = nibble[11]*10 + nibble[10] + (float)(nibble[9] / 10.0);
sev2000 0:4875d3d646de 276 temp= sign * temp;
sev2000 0:4875d3d646de 277 data[channel].temp1= temp;
sev2000 1:37ddcdfee022 278 O_DBG("Temperature: %0.1f", temp);
sev2000 0:4875d3d646de 279
sev2000 0:4875d3d646de 280 tmp= nibble[14] * 10 + nibble[13];
sev2000 0:4875d3d646de 281 data[channel].hum1= (float)tmp;
sev2000 1:37ddcdfee022 282 O_DBG("Humidity: %d", tmp);
sev2000 0:4875d3d646de 283
sev2000 0:4875d3d646de 284 data[channel].timestamp=time(NULL);
sev2000 0:4875d3d646de 285 }
sev2000 0:4875d3d646de 286 else
sev2000 1:37ddcdfee022 287 O_ERR("Checksum error %X", chksum);
sev2000 0:4875d3d646de 288 }
sev2000 0:4875d3d646de 289 else
sev2000 1:37ddcdfee022 290 O_ERR("Sync error");
sev2000 0:4875d3d646de 291 return 0;
sev2000 0:4875d3d646de 292 }
sev2000 1:37ddcdfee022 293 void RF_Active()
sev2000 1:37ddcdfee022 294 {
sev2000 1:37ddcdfee022 295 O_xTime.reset();
sev2000 1:37ddcdfee022 296 O_startedAt= 0;
sev2000 1:37ddcdfee022 297 dataPin.enable_irq();
sev2000 1:37ddcdfee022 298 StbyPin = 1;
sev2000 1:37ddcdfee022 299 }
sev2000 1:37ddcdfee022 300
sev2000 1:37ddcdfee022 301 void RF_StdBy()
sev2000 1:37ddcdfee022 302 {
sev2000 1:37ddcdfee022 303 StbyPin = 0;
sev2000 1:37ddcdfee022 304 dataPin.disable_irq();
sev2000 1:37ddcdfee022 305 O_PulseWidth.reset(); //clear Circular Buffer
sev2000 1:37ddcdfee022 306 }
sev2000 1:37ddcdfee022 307
sev2000 0:4875d3d646de 308
sev2000 0:4875d3d646de 309 void Init_Oregon()
sev2000 0:4875d3d646de 310 {
sev2000 1:37ddcdfee022 311 dataPin.fall(&O_getPulseF);
sev2000 1:37ddcdfee022 312 dataPin.rise(&O_getPulseR);
sev2000 1:37ddcdfee022 313 RF_Active();
sev2000 0:4875d3d646de 314
sev2000 1:37ddcdfee022 315 O_xTime.start();
sev2000 1:37ddcdfee022 316 O_xTime.reset();
sev2000 1:37ddcdfee022 317 O_dataBits[0] = 1;
sev2000 1:37ddcdfee022 318 O_thread.start(getData);
sev2000 0:4875d3d646de 319 }