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:12:44 2020 +0000
Revision:
7:47fb36f30355
Parent:
6:9861110c120c
Child:
8:48315bba3adc
Increase the numer of sample treted by period following period task change from 50 to 100; Decrease  thread prio to BelowNormal;

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