Programmet är långt ifrån färdigt, nuvarande version använder jag för att ta reda på dels vilka pulslängder som sensorerna faktiskt använder (eller mottagaren känner av) och för att försöka få stabila avläsningar. Jag får ibland signaler som har korrekt format men inte hör till mina sensorer, jag gissar att det är någon av grannarnas sensorer (minst 100 m bort) som inte använder riktigt samma format som de sensorer jag har. Programmet kör jag för ögonblicket på en Arduino Mega, med den syntax som dessa kort har. Jag har ändrat de pulslängder programmet skall acceptera utan att ändra kommentarerna i början, utveckling pågår som sagt.
Kod: Markera allt
/*
  Receiver for temperature probes for wireless thermometers "TFA" brand
  Long high signal measured as 1385 to 1445 µs stands for logic 0
  Short high signal measured as 595 to 635 µs stands for logic 1
  Signal train preceded by about 32 ms low (radio silence)
  Between high signals the low part is measured as 970 to 1050 µs
  
  See also http://thomaspfeifer.net/funk_temperatur_sensor_protokoll.htm for some details on the protocol
*/
#include "string.h"
//#define sigShort 615
//#define sigShortTolerance  150
//#define sigShortLow (sigShort - sigShortTolerance)
//#define sigShortHigh (sigShort + sigShortTolerance)
#define sigShortLow 350
#define sigShortHigh 850
//#define sigLong 1415
//#define sigLongTolerance 150
//#define sigLongLow (sigLong - sigLongTolerance)
//#define sigLongHigh (sigLong + sigLongTolerance)
#define sigLongLow 1150
#define sigLongHigh 1800
#define output Serial
#define rxPin 8
struct structTempSens {  // Struct with information regarding each sensor
  uint16_t id;           // Unit ID (random at each reset/battery change of sensor unit)
  uint8_t tA, tB, tC;    // Transmitted temperature values, temperature = (A-5)*10 + B + C/10
  char tempStr[6];       // Temperature as ASCII string
  char name[16];         // Human comprehensible name
  unsigned long values;  // Received packages from this sensor
} tempSens[8];
uint8_t numberSensors = 0;  // Number of sensors detected
uint8_t lastUnit;
byte data[44];  // Raw data from sensor via radio
unsigned long now;
uint16_t min0, max0, min1, max1;
unsigned long avg0, avg1;
uint8_t sensorNumber(uint16_t unitId) {  // Find position in array of struct of this unitId, or create new
  uint8_t i = 0, thisUnit;
  
  while(i < numberSensors) {
    if(tempSens[i].id == unitId) return(i);  // Found a matching unit ID, return its number in the array
    else i++;
  }
  thisUnit = numberSensors;
  numberSensors++;
  tempSens[thisUnit].id = unitId;  // Store ID
  switch (unitId) {  // Store human comprehensible name, if available
    case 0x0a06:
      strcpy(tempSens[thisUnit].name, "inomhus");
      break;
    case 0x0a01:
      strcpy(tempSens[thisUnit].name, "husvagg");
      break;
    case 0x0a08:
      strcpy(tempSens[thisUnit].name, "garaget");
      break;
    default:
      strcpy(tempSens[thisUnit].name, "unknown");
      break;
  }
  tempSens[thisUnit].values = 0;
  return(thisUnit);  // Return the new number given to this unit ID
}
void process(void) {
  uint16_t unitId = 0;
  uint8_t unitA = 0, unitB = 0, unitC = 0;
  uint8_t currentSensor;
  uint8_t i;
  
  for(uint8_t i=0; i<16; i++) {
    unitId += data[i] << (15 - i);
  }
  for(uint8_t i=0; i<4; i++) {
    unitA += data[i + 20] << (3 - i);
    unitB += data[i + 24] << (3 - i);
    unitC += data[i + 28] << (3 - i);
  }
  
  currentSensor = sensorNumber(unitId);
  tempSens[currentSensor].tA = unitA;
  tempSens[currentSensor].tB = unitB;
  tempSens[currentSensor].tC = unitC;
  
  i = 0;
  if(unitA < 5) {
    tempSens[currentSensor].tempStr[i++] = '-';
    tempSens[currentSensor].tempStr[i++] = '0' + 5 - unitA;
  } else if (unitA > 5) {
    tempSens[currentSensor].tempStr[i++] = '0' + unitA - 5;
  }
  tempSens[currentSensor].tempStr[i++] = '0' + (unitB % 10);
  tempSens[currentSensor].tempStr[i++] = '.';
  tempSens[currentSensor].tempStr[i++] = '0' + unitC;
  tempSens[currentSensor].tempStr[i++] = 0;
  
  tempSens[currentSensor].values++;
  lastUnit = currentSensor;
}
void reportBinData(void) {
  for(uint8_t i=0; i<44; i++) {
    output.print(data[i], DEC);
    if((i >= 15) && (i+1) % 4 == 0) output.print(" ");
  }
}
  
void reportTime(unsigned long now) {
  char nowH, nowM, nowS;
  
  now /= 1000UL;
  nowS = now % 60UL;
  now /= 60UL;
  nowM = now % 60UL;
  nowH = now / 60UL;
  
  if(nowH < 10) output.print("0");
  output.print(nowH, DEC);
  output.print(":");
  if(nowM < 10) output.print("0");
  output.print(nowM, DEC);
  output.print(":");
  if(nowS < 10) output.print("0");
  output.print(nowS, DEC);
}
void reportUnitId(uint16_t unitId) {
  output.print("\"");
  if(unitId < 0x1000) output.print("0");
  if(unitId < 0x100) output.print("0");
  if(unitId < 0x10) output.print("0");
  output.print(unitId, HEX);
  output.print("\"");
}
void reportUnit(uint8_t unitNumber) {
  output.print("\"");
  output.print(tempSens[unitNumber].name);
  output.print("\";");
  output.print(tempSens[unitNumber].tempStr);
  output.print(";");
  output.print(tempSens[unitNumber].values, DEC);
}
void report() {
  reportTime(now);
  output.print(";");
  output.print(min0);
  output.print(";");
  output.print(avg0);
  output.print(";");
  output.print(max0);
  output.print(";");
  output.print(min1);
  output.print(";");
  output.print(avg1);
  output.print(";");
  output.print(max1);
  for(uint8_t i=0; i<numberSensors; i++) {
    output.print(";");
    reportUnit(i);
  }
  output.println();
  if(strcmp(tempSens[lastUnit].name, "unknown") == 0) {
    reportBinData();
    output.println();
    output.print(tempSens[lastUnit].tA, DEC);
    output.print(";");
    output.print(tempSens[lastUnit].tB, DEC);
    output.print(";");
    output.print(tempSens[lastUnit].tC, DEC);
    output.println();
  }
}
void setup() {
  pinMode(rxPin, INPUT);
  output.begin(57600);
}
void loop() {
  uint8_t i = 0, count0 = 0, count1 = 0, j;
  uint16_t sample0[44], sample1[44];
  unsigned long t;
  boolean sigCheck = true;
  
  while (i < 44) {
    t = pulseIn(rxPin, HIGH, sigLongHigh);
    if (sigShortLow < t && t < sigShortHigh) {
      data[i++] = 1;
      sample1[count1++] = int(t);
    } else if(sigLongLow < t && t < sigLongHigh) {
      data[i++] = 0;
      sample0[count0++] = int(t);
    } else {
      i = 0;
      count0 = 0;
      count1 = 0;
      continue;
    }
  }
  
  j = 0;
  while(sigCheck && j<4) {
    sigCheck = sigCheck && (data[j+20] == data[j+32]);
    sigCheck = sigCheck && (data[j+24] == data[j+36]);
    j++;
  }
  
  if(sigCheck) {
    avg0 = 0;
    min0 = max0 = sample0[0];
    for(j=0; j<count0; j++) {
      avg0 += sample0[j];
      min0 = min(min0, sample0[j]);
      max0 = max(max0, sample0[j]);
    }
    avg0 /= count0;
    
    avg1 = 0;
    min1 = max1 = sample1[0];
    for(j=0; j<count1; j++) {
      avg1 += sample1[j];
      min1 = min(min1, sample1[j]);
      max1 = max(max1, sample1[j]);
    }
    avg1 /= count1;
    now = millis();
    process();
    report();
  }
} 
				

