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:
Sat Apr 25 10:54:55 2020 +0000
Revision:
9:ac5060331882
Parent:
8:48315bba3adc
Child:
11:4cfdb2d79394
Make some variable static to avoid integration conflict

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