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 Oct 20 13:21:52 2019 +0000
Revision:
0:4875d3d646de
Child:
1:37ddcdfee022
Oregon Library created

Who changed what in which revision?

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