433Mhz trip wire sensor system: Difference between revisions
From Pessin randon wiki
Created page with "== 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. thumb|Vastaanottimen oled näyttö === Mitä näyttö kertoo? === Näyttö on jaettu kahteen osaan: * Vasemmassa reunassa (suurena): ** '''ID-numero''' (esim. <code>5</code>) ** '''Huutomerkki <code>!</code>''' näkyy, jo..." |
|||
| Line 81: | Line 81: | ||
!Komponentti | !Komponentti | ||
!Määrä | !Määrä | ||
!Hinta | |||
!Linkki | |||
|- | |- | ||
|Arduino Nano v3 | |Arduino Nano v3 | ||
|1 | |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-radiovastaanotin | |433 MHz ASK-radiovastaanotin | ||
|1 | |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] | |||
|- | |- | ||
|OLED-näyttö (128×32, I2C, SSD1306) | |OLED-näyttö (128×32, I2C, SSD1306) | ||
|1 | |1 | ||
|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] | |||
|- | |- | ||
|Momenttikytkin (painonappi) | |Momenttikytkin (painonappi) (EI PAKOLLINEN) | ||
|1 | |1 | ||
| | |||
|[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ä | |||
|4 | |||
|11,5 € | |||
| | |||
|} | |} | ||
Revision as of 15:54, 20 September 2025
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.

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)
- ID-numero (esim.
- Oikeassa reunassa (pienellä tekstillä):
- 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ä
- Toinen rivi (vain jos koodi on passiivinen):
- Aika viimeisestä viestistä minuutteina (esim.
17m)
- Aika viimeisestä viestistä minuutteina (esim.
- Kolmas rivi (vain jos passiivinen):
- Sana
PASSIVE
- Sana
- Alarivi:
- DIP-koodi (esim.
0100)
- DIP-koodi (esim.
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 |
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 |
| 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ä | 4 | 11,5 € |
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
Lähettimen 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();
}