FS20 / OOK Senden mit dem RFM69(HW)

FS20 / OOK Senden mit dem RFM69(HW)

Beitragvon Rocktagon » Mi 16. Nov 2016, 10:37

Die Vorgänger des RFM69 chips wurden zum senden von OOK Signalen (wie zb beim FS20 System) einfach ein und aus geschaltet.
Der RFM69 bietet jedoch einen extra Modus dafür. Hier ein kleiner Sketch um FS20/FHT Signale zu senden (nicht empfangen):
Dazu muss noch der DI02 Pin des RFM69 an einen Ausgang des Arduinos geschaltet werden.

Infos zu dem FHT Protocoll: // http://fhz4linux.info/tiki-index.php?pa ... 20protocol

Code: Alles auswählen
#include <RFM69.h>
#include <RFM69registers.h>
#include <util/parity.h>

//*** FS20/FHT
#define FS20_OFF 0
#define FS20_ON 17
#define FS20_TOGGLE 18
#define FHT_VENT_OFFEN 1
#define FHT_VENT_ZU 2
#define FHT_VENT_PROZENT 6
#define FHT_VENT_OFFSET 8
#define FHT_ENTKALK 10
#define FHT_SYNC 12
#define FHT_BEEP 14
#define FHT_PAIR 15


#define rfhw true //RF96HW?
#define rfinternr 0 //Interruptnr von rfpin
#define rfcs 10 //CS Pin für RF69
#define rfpin 2 //Data Ready für RF69 (auf DIO0) - interrupt 0

unsigned long FREQUENCY = 868350000; //Genaue Frequenz des FS20/FHT Systems
word fhtAddr;
unsigned long fhtIntervall;

// CS, Interrupt pin, RFM69HW, Interruptnummer
RFM69 HM(rfcs, rfpin, rfhw, rfinternr); //8572/631-> 362 flash, 7 ram mehr

void initOOK() {
  detachInterrupt(rfinternr); //Interrupt pin for normal mode
  const byte CONFIG[][2] =
  {
    /* 0x01 */ { REG_OPMODE, RF_OPMODE_SEQUENCER_OFF | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY },
    /* 0x02 */ { REG_DATAMODUL, RF_DATAMODUL_DATAMODE_CONTINUOUSNOBSYNC | RF_DATAMODUL_MODULATIONTYPE_OOK | RF_DATAMODUL_MODULATIONSHAPING_01 }, // no shaping
    /* 0x03 */ { REG_BITRATEMSB, 0x03}, //Bitrate: 32768 Hz
    /* 0x04 */ { REG_BITRATELSB, 0xD1},
    /* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_5}, // BW: 5.2 kHz
    /* 0x1B */ { REG_OOKPEAK, RF_OOKPEAK_THRESHTYPE_PEAK | RF_OOKPEAK_PEAKTHRESHSTEP_000 | RF_OOKPEAK_PEAKTHRESHDEC_000 },
  };

  for (byte i = 0; i < 6; i++)
    HM.writeReg(CONFIG[i][0], CONFIG[i][1]);
  HM.setFrequency(FREQUENCY); //Exakter wert der FHT's/FS20
  HM.setPowerLevel(31); //31 max
  HM.writeReg(REG_OPMODE, (HM.readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_TRANSMITTER); //Set in TX Mode
}



void fs20_send_bit(uint8_t bit)
{
  byte width = bit ? 6 : 4;
  digitalWrite(rfookpin, true);
  delayMicroseconds(width * 100);
  digitalWrite(rfookpin, false);
  delayMicroseconds(width * 100);
}

void fs20_send_byte(uint8_t byte)
{
  uint8_t i = 7;
  do {
    fs20_send_bit(byte & _BV(i));
  } while (i-- > 0);
  fs20_send_bit(parity_even_bit(byte));
}

void fs20_send(uint16_t housecode, uint8_t address, uint8_t command, byte data = 0, bool FHT = false) //Angaben Dezimal
{
  // Serial.println("send fs");
  if (data > 0) FHT = true;
  byte loops = FHT ? 2 : 3;
  byte sum = FHT ? 12 : 6;
  sum += (housecode >> 8) + (housecode & 0xFF) + address + command + data;
  initOOK();
  for (uint8_t i = 0; i < loops; i++) {
    for (uint8_t j = 0; j < 12; j++) //Einpegeln
      fs20_send_bit(0);
    fs20_send_bit(1);
    fs20_send_byte(housecode >> 8);
    fs20_send_byte(housecode);
    fs20_send_byte(address);
    fs20_send_byte(command);
    if ((data > 0) || (FHT))
      fs20_send_byte(data);
    fs20_send_byte(sum); //CRC Wert
    fs20_send_bit(0);
    delay(10);
  }
  initHM(); //Zurück zum normalen Empfang
}


void runFhtFunc(word hc, byte cmd, byte data = 0, byte nr = 0) {
  if (cmd == FHT_SYNC) {
    // Serial.println("Sync");
    for (int i = 243; i > 0; i = i - 2)
    {
      while (millis() % 1000 > 0) {}; // Immer bis zur nächsten Sekunden warten, egal wie lange senden dauerte
      fs20_send(hc, 0, FHT_SYNC, i, true);
      //   Serial.println(i);
    }
    startTimer(); //Alive Ticks starten
    delay(2000); //muss sein
    //Sync Ende, Beepen
    cmd = FHT_BEEP;
  }
  fs20_send(hc, nr, cmd , data, true);
}

void setFht(byte hc1, byte hc2) {
  fhtIntervall = (long)(hc2 & 7) + 230 ; //Intervall in 500 Ms Schritten, die 10 Ms werden ignoriert
  fhtAddr = (word(hc1) << 8) + hc2;
  runFhtFunc(fhtAddr, FHT_PAIR); //Pairing senden
}


void loop() {
//Fs20/Fht Hauscode/Adresse in Dezimal
   if (millis() % 2000 == 0) fs20_send(20548, 4, FS20_TOGGLE); //FS20 Funksteckdose togglen.
}

Non mihi non tibi sed nobis
nightlight ÄT gmx PUNKT de
Benutzeravatar
Rocktagon
Administrator
 
Beiträge: 142
Registriert: So 28. Okt 2012, 10:15
Wohnort: NRW

Zurück zu Arduino

Wer ist online?

Mitglieder in diesem Forum: NewBot und 1 Gast

Fatal: Not able to open ./cache/data_global.php