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 Apr 26 06:37:46 2020 +0000
Revision:
11:4cfdb2d79394
Parent:
9:ac5060331882
Child:
12:6d3638a225dd
Set thread prio to Normal; some cleanup on databits variables

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