/* Test der Decodierung der Oregon-Daten auf einem Teensy 3.2 */
// Decodierung Oregon-Daten:
#include <Arduino.h>
#include <stdio.h>
#include <math.h>
#include "OregonDecodeV3_2.h"
#include "digitalWriteFast.h"
#include <util/atomic.h>
// Decodierung Oregon-Daten:
#define SYNCPIN 5 // zum Triggern Oszi
#define MARKSENT A1 // zeigt 1/2 Sek. lang an LED an, dass Datenblock gesendet wurde
//#define HOT // HOT fuer WDFA
//#define MEAN_SPEED // gemittelte Windgeschw. anstatt aktueller
OOK_OregonDecodeV3_2 orscV3;
boolean SerMonitor;
uint8_t fstat;
elapsedMicros blinkPrint=0;
uint16_t looping=0;
byte isr_disen =0;
// Decodierung Oregon-Daten:
bool tglbit=false;
unsigned long tm; // Zeit für einen loop-Durchlauf
// Winddata:
word wv;
byte wdir, lowbatt;
// for temperature data:
int temp_act;
byte rh_act;
// Parameter in loop():
byte n, dtyp;
static word Scount=0;
static short int v16;
static byte v8;
static char outstr[12];
static byte newdata=0;
unsigned long tm_wd; // Zeit zwischen WGR800-Winddaten
byte norecdat; // Luecke zwischen Winddaten in 14sec-Einheiten
char ic='n';
byte respos_cpy, respos_cold;
// Parameter, die von der Komparator-Interrupt-Routine veraendert werden koennen:
volatile byte res_valid[N_DATASETS];
volatile byte res_pos=0, dbcount;
volatile byte dtmin=255, dtmax=0;
volatile word pulse, tot_p;
//volatile byte Wdone=1;
void waitSM(const char* msg) {
Serial.println(msg);
while (Serial.available()>0) Serial.read();
while (Serial.available()==0);
while (Serial.available()>0) Serial.read();
}
// Interrupt Routine
void ext_int_2(void) { // ohne Comparator
static unsigned long last, pw, t00; // mit static muss Speicher für die Parameter
// nur einmal reserviert werden
static byte dt;
// determine the pulse length in microseconds, for either polarity
t00 = micros(); // nur zum Testen
pw = micros() - last;
last += pw;
if (pw < 65536) pulse=(word)pw;
else pulse=65535;
// OregonDecoder
if ( (orscV3.total_bits > 0) || (pulse > PW1) ) {
if (orscV3.nextPulse(pulse)==1) {
dbcount = orscV3.pos; // pos retten, ehe es zu 0 wird
orscV3.resetDecoder ();
res_valid[res_pos]=1; // valid Flag
res_pos++;
if (res_pos > (N_DATASETS-1)) res_pos = 0;
orscV3.setdb(res_pos); // für nächsten Datensatz
tot_p = orscV3.anz_p; // Wert retten
}
}
dt=micros()-t00;
if (dt<dtmin) dtmin=dt;
if (dt>dtmax) dtmax=dt;
}
byte readRFData(byte r_pos, short int* val16, byte* val8, byte* lowBatt, boolean mean_speed) {
// liest Daten des Empfaengers aus dem Datensatz r_pos und liefert sie in val16 und val8 zurück;
// mean_speed==true: gemittelte Windgeschwindigkeit
// mean_speed==false: aktuelle Windgeschwindigkeit
// WGR800 THGN TFA
// val16 Geschw.*10 Temperatur*10 Geschw.*10 simuliert
// val8 Richtung Luftfeuchte Richtung simuliert
// return 1 0 2
//
volatile const byte* data = orscV3.getData(r_pos);
static int wv=36, tmp; // für Geschw., Temp.
byte wd, rh; // für Richtung, rel. Luftfeuchte
byte retv=0;
//Serial.print("von Datensatz ");Serial.print(r_pos);Serial.print(" ");
if ( (data[0] == 26) & (data[1] == 137) ) { // WGR800: 1A89
if (mean_speed)
wv = (data[8] >> 4)*100 + (data[8] & 0x0F)*10 + (data[7] >> 4);
else
wv = (data[7] & 0x0F)*100 + (data[6] >> 4)*10 + (data[6] & 0x0F);
Serial.print(": ");Serial.print(wv);Serial.print("m/s*10 ");
// wv = word(round(wv * 3.6)); // kmh*10
wd = (data[4] >> 4);
*val16 = wv;
*val8 = wd;
if (data[4] & 0x04)
*lowBatt = 4; // battery low Windsensor
else
*lowBatt = 0;
retv = 1;
}
else if ( (data[0] == 250) && (data[1] == 40) ) { // THGR810: FA28
tmp = (data[5] >> 4)*100 + (data[5] & 0x0F)*10 + (data[4] >> 4);
if (data[6] & 0x0F) tmp = -tmp;
rh = (data[7] & 0x0F)*10 + (data[6] >> 4);
*val16 = tmp;
*val8 = rh;
if (data[4] & 0x04)
*lowBatt = 5; // battery low Temperatursensor
else
*lowBatt = 0;
retv = 0;
}
else { // unbekannte Daten
retv = 2;
}
return(retv);
}
void mark_dataReceived() {
digitalWrite(MARKSENT,HIGH);
delay(500);
digitalWrite(MARKSENT,LOW);
delay(200);
}
void setup() { // -------------------------------------------------------------
uint32_t read_time;
int16_t anz_errors;
analogWriteResolution(8);
pinMode(A14, OUTPUT);
Serial.begin(38400);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println(F("<<< Sprache + Oregon-Decodierung >>>"));
SerMonitor=true;
// Vorbelegungen ohne cli() ok, weil erst
// anschließend die Interrupt-Routine scharf wird
for (byte nn=0; nn<N_DATASETS; nn++)
res_valid[nn]=0; // Flags der Datenbaenke
res_pos=0;
respos_cpy=respos_cold=0;
orscV3.setdb(0);
// Empfaenger-Interrupt aktivieren, Pin 23
attachInterrupt(digitalPinToInterrupt(23), ext_int_2, CHANGE);
Serial.println("es ist ein Teensy");
#ifdef WGR800
Serial.println("Pulssequenzen wie WGR800");
#else
Serial.println("Pulssequenzen wie TFA-Sensor");
#endif
tm_wd=millis();
tm=tm_wd;
}
void loop() { // ---------------------------------------------------------
// to read a variable which the interrupt code writes, we
// must temporarily disable interrupts, to be sure it will
// not change while we are reading. To minimize the time
// with interrupts off, just quickly make a copy, and then
// use the copy while allowing the interrupt to keep working
boolean dvalid;
byte dtmin_c, dtmax_c;
if (Serial.available()) {
ic=Serial.read();
while (Serial.available()) Serial.read();
}
// --------------------------------------
// Trigger-Sync:
digitalWrite(SYNCPIN,HIGH);
digitalWrite(SYNCPIN,LOW);
delay(200);
for (n=0; n<N_DATASETS; n++) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
dvalid = res_valid[n] == 1;
}
if (dvalid) { // Daten sind verfuegbar
#ifdef MEAN_SPEED
dtyp = readRFData(n, &v16, &v8, &lowbatt, true);
#else
dtyp = readRFData(n, &v16, &v8, &lowbatt, false);
#endif
switch (dtyp) {
case 0: // Temperaturdaten
sprintf(outstr,"n=%d dbcnt=%d T%04dH%02dB%d",n,dbcount,v16,v8,lowbatt);
Serial.print(outstr);
mark_dataReceived();
break;
case 1: // Winddaten WGR800
#ifndef HOT
Serial.print(millis()-tm_wd);Serial.print(": ");
tm_wd=millis();
sprintf(outstr,"n=%d dbcnt=%d W%03dR%02dB%d",n,dbcount,v16,v8,lowbatt);
Serial.print(outstr);
#ifdef MEAN_SPEED
Serial.print(F(" mean="));
Serial.print(v16);
#endif
#else
sprintf(outstr,"n=%d W%03dR%02dB%d",n,v16,v8,lowbatt);
Serial.println(outstr);
#endif
mark_dataReceived();
break;
case 2: // unbekanntes Signal
Serial.print(F("unbekanntes Signal: n="));Serial.print(n);
Serial.print(F(", dbcnt="));Serial.print(dbcount);
} // switch
Serial.print(F(" Interrupt-Dauer von "));
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
dtmin_c = dtmin;
dtmax_c = dtmax;
dtmin=255;
dtmax=0;
}
Serial.print(dtmin_c);
Serial.print(" bis ");Serial.println(dtmax_c);
res_valid[n] = 0; // wenn es 1 war, dann wurde in der Interrupt-Routine
// bestimmt nicht daran gearbeitet
} // if (res_valid..)
Scount++;
tm=millis();
} // for n
// }
}