433Mhz trip wire sensor system: Difference between revisions

From Pessin randon wiki
No edit summary
No edit summary
Line 23: Line 23:
# '''Alarivi:'''
# '''Alarivi:'''
#* DIP-koodi (esim. <code>0100</code>)
#* DIP-koodi (esim. <code>0100</code>)
== ID Dip taulukko ==
{| class="wikitable"
!ID
!DIP-koodi
|-
|1
|0000
|-
|2
|0001
|-
|3
|0010
|-
|4
|0011
|-
|5
|0100
|-
|6
|0101
|-
|7
|0110
|-
|8
|0111
|-
|9
|1000
|-
|10
|1001
|-
|11
|1010
|-
|12
|1011
|-
|13
|1100
|-
|14
|1101
|-
|15
|1110
|-
|16
|1111
|}


=== Vastaanottimen kytkentäkaavio ja tarvittavat osat ===
=== Vastaanottimen kytkentäkaavio ja tarvittavat osat ===
Line 101: Line 47:
|4,5 €
|4,5 €
|[https://www.amazon.de/-/en/MakerHawk-Display-Module-SSD1306-Arduino/dp/B07BDFXFRK?pd_rd_w=qUaQp&content-id=amzn1.sym.4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_p=4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_r=8GH37VYP9KNF34G3GX0V&pd_rd_wg=BU8DK&pd_rd_r=33638fa5-b549-49a6-be2e-478ec83cc529&pd_rd_i=B07BDFXFRK&psc=1&ref_=pd_bap_d_grid_rp_0_2_pr_t MakerHawk I2C OLED Display Module I2C SSD1306 Tiny Screen Module 0.91 Inch, in White 128X32 I2C OLED Driver]
|[https://www.amazon.de/-/en/MakerHawk-Display-Module-SSD1306-Arduino/dp/B07BDFXFRK?pd_rd_w=qUaQp&content-id=amzn1.sym.4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_p=4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_r=8GH37VYP9KNF34G3GX0V&pd_rd_wg=BU8DK&pd_rd_r=33638fa5-b549-49a6-be2e-478ec83cc529&pd_rd_i=B07BDFXFRK&psc=1&ref_=pd_bap_d_grid_rp_0_2_pr_t MakerHawk I2C OLED Display Module I2C SSD1306 Tiny Screen Module 0.91 Inch, in White 128X32 I2C OLED Driver]
|-
|9V patteriliitin
|1
|0,8 €
|[https://www.amazon.de/-/en/dp/B0919H1113?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1 HeyNana 5 x Battery Clip 9 Volt Block Battery I Type Clip Snap with 15 cm Connection Cable for 9 V Blocks Plug Connection Cable]
|-
|9V Paristo
|1
|1,2 €
|[https://www.amazon.de/-/en/dp/B0DD3ZG4K9?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1 GutAlkaLi Batteries 9 V Block Battery, Pack of 6, Longlife Power for Smoke Detectors, Fire & Fire Detectors, Microphone 6lr61 6F22 PP3 MN1604]
|-
|-
|Momenttikytkin (painonappi) (EI PAKOLLINEN)
|Momenttikytkin (painonappi) (EI PAKOLLINEN)
Line 108: Line 64:
|-
|-
|Yhteensä
|Yhteensä
|4
|
|11,5 €
|
|
|
|}
|}
Line 177: Line 133:
* Wire
* Wire


=== Lähettimen lähdekoodi ===
=== Vastaanottimen lähdekoodi ===
<syntaxhighlight lang="c++" line="1">#include <RH_ASK.h>
<syntaxhighlight lang="c++" line="1">#include <RH_ASK.h>
#include <Wire.h>
#include <Wire.h>
Line 438: Line 394:
   display.display();
   display.display();
}</syntaxhighlight>
}</syntaxhighlight>
== Lähetinyksikkö ==
=== Lähettimen käyttö ===
Lähetinyksikön pohjassa on DIP kytkinkaavio, josta valitaan lähetettävä ID. ID tulisi olla jokaisessa lähettimessä oma, jotta hälytykset on identifioitavissa.
Lähettimen pohjayksikkö on irtirepäistävä 360 astetta pyörivä pohja joka irrottuaan aktivoi lähetyksen välittömästi.
Lähetinyksikön voi myös laittaa omalla painollaan pohja edellä jollekkin tasaiselle alustalle ja mikäli se kaatuu alkaa lähetys.
Järjestelmä toimii 9v paristolla.
=== Lähettimen kytkentäkaavio ja tarvittavat osat ===
==== Tarvittavat osat ====
{| class="wikitable"
!Komponentti
!Määrä
!Hinta
!Linkki
|-
|Arduino Nano v3
|1
|4,2 €
|[https://www.amazon.de/-/en/Development-Connector-Microcontroller-Compatible-Arduino/dp/B0CX1B4X7M?pd_rd_w=qUaQp&content-id=amzn1.sym.4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_p=4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_r=8GH37VYP9KNF34G3GX0V&pd_rd_wg=BU8DK&pd_rd_r=33638fa5-b549-49a6-be2e-478ec83cc529&pd_rd_i=B0CX1B4X7M&psc=1&ref_=pd_bap_d_grid_rp_0_1_ec_pd_rhf_ee_s_rp_c_d_sccl_1_3_i Binghe Development Board with Chip CH340 Type-C Connector 5V 16M Microcontroller Compatible with Arduino IDE Pack of 5]
|-
|433 MHz ASK-radiolähetin
|1
|2,8 €
|[https://www.amazon.de/-/en/ALAMSCN-Receiver-Transmission-Antenna-Compatible/dp/B093PHFW64?pd_rd_w=qUaQp&content-id=amzn1.sym.4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_p=4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_r=8GH37VYP9KNF34G3GX0V&pd_rd_wg=BU8DK&pd_rd_r=33638fa5-b549-49a6-be2e-478ec83cc529&pd_rd_i=B093PHFW64&psc=1&ref_=pd_bap_d_grid_rp_0_8_t ALAMSCN Set of 5 433 MHz RF Receiver and Radio Transmission Module + RF 433 MHz Spring Antenna Kit Compatible with Arduino]     
|-
|9V patteriliitin
|1
|0,8 €
|[https://www.amazon.de/-/en/dp/B0919H1113?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1 HeyNana 5 x Battery Clip 9 Volt Block Battery I Type Clip Snap with 15 cm Connection Cable for 9 V Blocks Plug Connection Cable]
|-
|9V Paristo
|1
|1,2 €
|[https://www.amazon.de/-/en/dp/B0DD3ZG4K9?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1 GutAlkaLi Batteries 9 V Block Battery, Pack of 6, Longlife Power for Smoke Detectors, Fire & Fire Detectors, Microphone 6lr61 6F22 PP3 MN1604]
|-
|Momenttikytkin (painonappi)
|1
|0,25 €
|[https://www.amazon.de/-/en/DAOKAI-Switch-Straight-Moment-Arduino/dp/B09WVMRD5V?pd_rd_w=O2Fz4&content-id=amzn1.sym.4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_p=4bc731ae-4eb4-4e98-9a86-3ba652c5b44e&pf_rd_r=ZVS0D9FANNXXFY26W3FV&pd_rd_wg=pSMHX&pd_rd_r=b5040f30-5385-4685-8609-4b1d19d0597b&pd_rd_i=B09WVMRD5V&psc=1&ref_=pd_bap_d_grid_rp_0_1_ec_pr_pd_rhf_ee_s_rp_c_d_sccl_2_5_t DAOKAI Micro Switch NC+NO Hinge Straight Lever Micro Limit Switch 125V 1A PDT Limit Micro Switch Moment Switch for Arduino (Pack of 20)]
|-
|Yhteensä
|
|
|
|}
==== Kytkentäkaavio ====
===== Lähettimen kytkentä =====
{| class="wikitable"
!Vastaanottimen pinni
!Arduino Nano -pinni
!Selitys
|-
|VCC
|5V
|Virransyöttö
|-
|GND
|GND
|Maa
|-
|DATA (OUT)
|D12
|Lähetysdata
|-
|Antenni
| -
|Antennin optimaalinen pituus ~17cm
|}
===== Virtalähteen kytkentä pikarullausnappi =====
{| class="wikitable"
!Nappi
!Arduino Nano
!Selitys
|-
|1
|D2
|Luku (INPUT_PULLUP)
|-
|2
|GND
|Painettaessa yhdistää maahan
|}
=== Vastaanottimen lähdekoodi ===
<syntaxhighlight lang="bash" line="1">
#include <RH_ASK.h>
#include <SPI.h>
RH_ASK driver(1000);
#define TX_PIN 12
#define DIP1 2
#define DIP2 3
#define DIP3 4
#define DIP4 5
byte crc8_dallas(const String &data) {
  byte crc = 0x00;
  for (int i = 0; i < data.length(); i++) {
    crc ^= data[i];
    for (int j = 0; j < 8; j++) {
      crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : (crc << 1);
    }
  }
  return crc;
}
void setup() {
  driver.init();
  pinMode(DIP1, INPUT_PULLUP);
  pinMode(DIP2, INPUT_PULLUP);
  pinMode(DIP3, INPUT_PULLUP);
  pinMode(DIP4, INPUT_PULLUP);
  pinMode(TX_PIN, OUTPUT);
  randomSeed(analogRead(0));
}
String readDipCode() {
  String code = "";
  code += (digitalRead(DIP1) == LOW) ? '1' : '0';
  code += (digitalRead(DIP2) == LOW) ? '1' : '0';
  code += (digitalRead(DIP3) == LOW) ? '1' : '0';
  code += (digitalRead(DIP4) == LOW) ? '1' : '0';
  return code;
}
void loop() {
  String code = readDipCode();
  String core = "S" + code + "E";
  byte crc = crc8_dallas(core);
  String message = core + String(crc, HEX);
  driver.send((uint8_t*)message.c_str(), message.length());
  driver.waitPacketSent();
  delay(random(800, 1800));  // satunnainen lähetysväli
}
</syntaxhighlight>
== ID Dip taulukko ==
{| class="wikitable"
!ID
!DIP-koodi
|-
|1
|0000
|-
|2
|0001
|-
|3
|0010
|-
|4
|0011
|-
|5
|0100
|-
|6
|0101
|-
|7
|0110
|-
|8
|0111
|-
|9
|1000
|-
|10
|1001
|-
|11
|1010
|-
|12
|1011
|-
|13
|1100
|-
|14
|1101
|-
|15
|1110
|-
|16
|1111
|}

Revision as of 16:31, 20 September 2025

Vastaanotinyksikkö

Vastaanottimen käyttö

Tämä laite vastaanottaa 433 MHz -radioviestejä, joissa on kiinteitä DIP-koodeja. Jokaisella DIP-koodilla on pysyvä ID-numero (1–16). Näytöllä näkyy aina yksi koodi kerrallaan.

Vastaanottimen oled näyttö

Mitä näyttö kertoo?

Näyttö on jaettu kahteen osaan:

  • Vasemmassa reunassa (suurena):
    • ID-numero (esim. 5)
    • Huutomerkki ! näkyy, jos koodi on aktiivinen (viesti saatu viimeisen 5 minuutin aikana)
  • Oikeassa reunassa (pienellä tekstillä):
  1. Ylärivi: Esim. 2/(3)/[5]
    • 2 = aktiivisten lähetysten määrä
    • (3) = passiivisten lähetysten määrä (viesti yli 5 min vanha)
    • [5] = kaikkien vastaanotettujen lähetyksien määrä
  2. Toinen rivi (vain jos koodi on passiivinen):
    • Aika viimeisestä viestistä minuutteina (esim. 17m)
  3. Kolmas rivi (vain jos passiivinen):
    • Sana PASSIVE
  4. Alarivi:
    • DIP-koodi (esim. 0100)

Vastaanottimen kytkentäkaavio ja tarvittavat osat

Tarvittavat osat

Komponentti Määrä Hinta Linkki
Arduino Nano v3 1 4,2 € Binghe Development Board with Chip CH340 Type-C Connector 5V 16M Microcontroller Compatible with Arduino IDE Pack of 5
433 MHz ASK-radiovastaanotin 1 2,8 € ALAMSCN Set of 5 433 MHz RF Receiver and Radio Transmission Module + RF 433 MHz Spring Antenna Kit Compatible with Arduino
OLED-näyttö (128×32, I2C, SSD1306) 1 4,5 € MakerHawk I2C OLED Display Module I2C SSD1306 Tiny Screen Module 0.91 Inch, in White 128X32 I2C OLED Driver
9V patteriliitin 1 0,8 € HeyNana 5 x Battery Clip 9 Volt Block Battery I Type Clip Snap with 15 cm Connection Cable for 9 V Blocks Plug Connection Cable
9V Paristo 1 1,2 € GutAlkaLi Batteries 9 V Block Battery, Pack of 6, Longlife Power for Smoke Detectors, Fire & Fire Detectors, Microphone 6lr61 6F22 PP3 MN1604
Momenttikytkin (painonappi) (EI PAKOLLINEN) 1 DAOKAI Micro Switch NC+NO Hinge Straight Lever Micro Limit Switch 125V 1A PDT Limit Micro Switch Moment Switch for Arduino (Pack of 20)
Yhteensä

Näytön kytkentä

OLED-pinni Arduino Nano -pinni Selitys
VCC 5V Virransyöttö
GND GND Maa
SDA A4 I2C-data
SCL A5 I2C-kello

Vastaanottimen kytkentä

Vastaanottimen pinni Arduino Nano -pinni Selitys
VCC 5V Virransyöttö
GND GND Maa
DATA (OUT) D12 Vastaanottodata

Näytön pikarullausnappi

Nappi Arduino Nano Selitys
1 D2 Luku (INPUT_PULLUP)
2 GND Painettaessa yhdistää maahan

Lisää tarvittavat kirjastot

  • RadioHead (RH_ASK)
  • Adafruit SSD1306
  • Adafruit GFX
  • Wire

Vastaanottimen lähdekoodi

#include <RH_ASK.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// Radiovastaanotin
RH_ASK driver(1000, 12, 11, 10); // RX = D12

// Ajastukset
const unsigned long ENTRY_TIMEOUT = 30 * 60 * 1000UL; // 30 min
const unsigned long DISPLAY_DURATION = 2500;         // 2.5 s

// Seuraava ruutu nappi
#define BUTTON_PIN 2

// Kiinteät DIP-koodit (16 kpl)
const char* dipIdMap[16] = {
  "0000", "0001", "0010", "0011",
  "0100", "0101", "0110", "0111",
  "1000", "1001", "1010", "1011",
  "1100", "1101", "1110", "1111"
};

//Vilkku
bool blinkState = false;
unsigned long lastBlink = 0;
const unsigned long BLINK_INTERVAL = 500;


// Tallennetaan viimeisin aikaleima DIP-koodeille
unsigned long dipSeen[16] = {0};

// Painallusmuuttujat
bool buttonPressed = false;
unsigned long lastDisplaySwitch = 0;

// CRC8 Dallas/Maxim
byte crc8_dallas(const char* data, uint8_t len) {
  byte crc = 0x00;
  for (uint8_t i = 0; i < len; i++) {
    crc ^= data[i];
    for (uint8_t j = 0; j < 8; j++) {
      crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : (crc << 1);
    }
  }
  return crc;
}

// Palauttaa ID:n 1–16 tai 0 jos tuntematon
int getDipId(const char* dip) {
  for (int i = 0; i < 16; i++) {
    if (strncmp(dipIdMap[i], dip, 4) == 0) {
      return i + 1;
    }
  }
  return 0;
}

void setup() {
  // Serial.begin(9600);
  // delay(1000);

  pinMode(BUTTON_PIN, INPUT_PULLUP);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    display.clearDisplay();
    display.setTextSize(1);
    display.setCursor(0, 0);
    display.println(F("OLED ei vastaa"));
    display.display();
    while (1); // Pysäyttää ohjelman
  }

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println(F("Odotetaan..."));
  display.display();

  
  if (!driver.init()) {
    display.clearDisplay();
    display.setCursor(0, 0);
    display.println(F("Radio ei vastaa"));
    display.display();
    while (1); // 
  }
  

  pinMode(12, INPUT);
}

void loop() {
  receiveRadio();
  cleanExpiredEntries();
  checkButton();
  updateDisplay();
  delay(10);
}

void checkButton() {
  static bool prevState = HIGH;
  bool state = digitalRead(BUTTON_PIN);

  if (prevState == HIGH && state == LOW) {
    buttonPressed = true;
  }

  prevState = state;
}

void receiveRadio() {
  uint8_t buf[32];
  uint8_t buflen = sizeof(buf);

  if (driver.recv(buf, &buflen)) {
    if (buflen < 8 || buf[0] != 'S' || buf[5] != 'E') return;

    byte expectedCrc = crc8_dallas((char*)buf, 6);
    char crcStr[3] = { (char)buf[6], (char)buf[7], '\0' };
    byte receivedCrc = strtoul(crcStr, NULL, 16);
    if (expectedCrc != receivedCrc) return;

    char dip[5];
    memcpy(dip, &buf[1], 4);
    dip[4] = '\0';

    int dipId = getDipId(dip);
    
    if (dipId <= 0) {
      //Serial.print(F("⚠️ Tuntematon DIP: "));
      //Serial.println(dip);
      return;
    }
    /*
    Serial.print(F("✅ DIP "));
    Serial.print(dip);
    Serial.print(F(" → ID "));
    Serial.println(dipId);
    */

    dipSeen[dipId - 1] = millis(); // Päivitä aikaleima
  }
}

void cleanExpiredEntries() {
  unsigned long now = millis();
  for (int i = 0; i < 16; i++) {
    if (dipSeen[i] != 0 && now - dipSeen[i] > ENTRY_TIMEOUT) {
      dipSeen[i] = 0; // Nollaa aikaleima = ei enää aktiivinen
    }
  }
}

void updateDisplay() {
  static int currentActiveIndex = -1;
  unsigned long now = millis();

  int allSeenIndices[16];
  int seenCount = 0;
  int activeCount = 0;
  int passiveCount = 0;

  // Kerätään vastaanotetut DIP:t ja lasketaan aktiiviset/passiiviset
  for (int i = 0; i < 16; i++) {
    if (dipSeen[i] != 0) {
      allSeenIndices[seenCount++] = i;
      unsigned long ageMin = (now - dipSeen[i]) / 60000UL;
      if (ageMin <= 5) {
        activeCount++;
      } else {
        passiveCount++;
      }
    }
  }

  display.clearDisplay();

  if (seenCount <= 0) {
    // Jos ei ole aktiivisia koodeja
    currentActiveIndex = -1;
    display.setTextSize(1);
    display.setCursor(0, 0);
    display.println(F("Kuunnellaan radiota..."));

    // Vilkku aina näkyviin
    if (now - lastBlink >= BLINK_INTERVAL) {
      blinkState = !blinkState;
      lastBlink = now;
    }
    if (blinkState) {
      display.fillRect(SCREEN_WIDTH - 3, SCREEN_HEIGHT - 3, 2, 2, SSD1306_WHITE);
    }

    display.display();
    return;
  }

  // Päivitä ruutu vain tarvittaessa
  if (now - lastDisplaySwitch >= DISPLAY_DURATION || buttonPressed) {
    currentActiveIndex = (currentActiveIndex + 1) % seenCount;
    lastDisplaySwitch = now;
    buttonPressed = false;
  }

  // Haetaan näytettävä DIP
  int dipIndex = allSeenIndices[currentActiveIndex];
  int id = dipIndex + 1;

  unsigned long ageMin = (now - dipSeen[dipIndex]) / 60000UL;
  bool isPassive = (ageMin > 5);

  // Vasemmalle iso ID-numero
  display.setTextSize(4);
  display.setCursor(0, 0);
  display.print(id);
  if (!isPassive) {
    display.print("!");
  }

  // Oikealle tilastorivi
  display.setTextSize(1);
  int xTextStart = SCREEN_WIDTH - 6 * 10;
  char indexStr[20];
  snprintf(indexStr, sizeof(indexStr), "%d/(%d)/[%d]", activeCount, passiveCount, seenCount);
  display.setCursor(xTextStart, 0);
  display.print(indexStr);

  // PASSIVE-merkinnät jos yli 5 min vanha
  if (isPassive) {
    char timeStr[10];
    snprintf(timeStr, sizeof(timeStr), "%lum", ageMin);
    display.setCursor(xTextStart, 8);
    display.print(timeStr);

    display.setCursor(xTextStart, 16);
    display.print(F("PASSIVE"));
  }

  // DIP-koodi alariville
  display.setCursor(xTextStart, SCREEN_HEIGHT - 8);
  display.print(dipIdMap[dipIndex]);

  // Vilkku (aina näkyvissä)
  if (now - lastBlink >= BLINK_INTERVAL) {
    blinkState = !blinkState;
    lastBlink = now;
  }
  if (blinkState) {
    display.fillRect(SCREEN_WIDTH - 3, SCREEN_HEIGHT - 3, 2, 2, SSD1306_WHITE);
  }

  display.display();
}

Lähetinyksikkö

Lähettimen käyttö

Lähetinyksikön pohjassa on DIP kytkinkaavio, josta valitaan lähetettävä ID. ID tulisi olla jokaisessa lähettimessä oma, jotta hälytykset on identifioitavissa.

Lähettimen pohjayksikkö on irtirepäistävä 360 astetta pyörivä pohja joka irrottuaan aktivoi lähetyksen välittömästi.

Lähetinyksikön voi myös laittaa omalla painollaan pohja edellä jollekkin tasaiselle alustalle ja mikäli se kaatuu alkaa lähetys.

Järjestelmä toimii 9v paristolla.

Lähettimen kytkentäkaavio ja tarvittavat osat

Tarvittavat osat

Komponentti Määrä Hinta Linkki
Arduino Nano v3 1 4,2 € Binghe Development Board with Chip CH340 Type-C Connector 5V 16M Microcontroller Compatible with Arduino IDE Pack of 5
433 MHz ASK-radiolähetin 1 2,8 € ALAMSCN Set of 5 433 MHz RF Receiver and Radio Transmission Module + RF 433 MHz Spring Antenna Kit Compatible with Arduino
9V patteriliitin 1 0,8 € HeyNana 5 x Battery Clip 9 Volt Block Battery I Type Clip Snap with 15 cm Connection Cable for 9 V Blocks Plug Connection Cable
9V Paristo 1 1,2 € GutAlkaLi Batteries 9 V Block Battery, Pack of 6, Longlife Power for Smoke Detectors, Fire & Fire Detectors, Microphone 6lr61 6F22 PP3 MN1604
Momenttikytkin (painonappi) 1 0,25 € DAOKAI Micro Switch NC+NO Hinge Straight Lever Micro Limit Switch 125V 1A PDT Limit Micro Switch Moment Switch for Arduino (Pack of 20)
Yhteensä

Kytkentäkaavio

Lähettimen kytkentä
Vastaanottimen pinni Arduino Nano -pinni Selitys
VCC 5V Virransyöttö
GND GND Maa
DATA (OUT) D12 Lähetysdata
Antenni - Antennin optimaalinen pituus ~17cm
Virtalähteen kytkentä pikarullausnappi
Nappi Arduino Nano Selitys
1 D2 Luku (INPUT_PULLUP)
2 GND Painettaessa yhdistää maahan

Vastaanottimen lähdekoodi

#include <RH_ASK.h>
#include <SPI.h>

RH_ASK driver(1000);
#define TX_PIN 12

#define DIP1 2
#define DIP2 3
#define DIP3 4
#define DIP4 5

byte crc8_dallas(const String &data) {
  byte crc = 0x00;
  for (int i = 0; i < data.length(); i++) {
    crc ^= data[i];
    for (int j = 0; j < 8; j++) {
      crc = (crc & 0x80) ? (crc << 1) ^ 0x31 : (crc << 1);
    }
  }
  return crc;
}

void setup() {
  driver.init();
  pinMode(DIP1, INPUT_PULLUP);
  pinMode(DIP2, INPUT_PULLUP);
  pinMode(DIP3, INPUT_PULLUP);
  pinMode(DIP4, INPUT_PULLUP);
  pinMode(TX_PIN, OUTPUT);
  randomSeed(analogRead(0));
}

String readDipCode() {
  String code = "";
  code += (digitalRead(DIP1) == LOW) ? '1' : '0';
  code += (digitalRead(DIP2) == LOW) ? '1' : '0';
  code += (digitalRead(DIP3) == LOW) ? '1' : '0';
  code += (digitalRead(DIP4) == LOW) ? '1' : '0';
  return code;
}

void loop() {
  String code = readDipCode();
  String core = "S" + code + "E";
  byte crc = crc8_dallas(core);
  String message = core + String(crc, HEX);

  driver.send((uint8_t*)message.c_str(), message.length());
  driver.waitPacketSent();

  delay(random(800, 1800));  // satunnainen lähetysväli
}

ID Dip taulukko

ID DIP-koodi
1 0000
2 0001
3 0010
4 0011
5 0100
6 0101
7 0110
8 0111
9 1000
10 1001
11 1010
12 1011
13 1100
14 1101
15 1110
16 1111