relais-radio.ino
Remote 12 V relay control: the receiving MKR WAN 1300 reads ON/OFF commands arriving over radio, drives pin 6 through a transistor, and sends an acknowledgement back. One simple gesture — pressing the transmitter button — commands equipment kilometres away.
Hardware
An Arduino MKR WAN 1300 (SAMD21 microcontroller, Semtech SX1272 LoRa modem for point-to-point links, no built-in LoRaWAN stack, 868/915 MHz antenna). Receiving MKR WAN 1300, 5 V relay module or SSR, NPN transistor + 1 kΩ resistor for a classic relay, separate relay supply.
Wiring
PIN 6 → 1 kΩ resistor → NPN base; relay between 5 V and collector, flyback diode across the coil; the load goes on its own supply.
How it works
The loop polls the radio FIFO; each frame is normalised then compared to ON/OFF. The action is idempotent (re-setting the same pin is safe) and the ACK confirms execution to the transmitter.
Running it
Install Arduino SAMD Boards and the MKRWAN library, select the board, upload. You need TWO LoRa boards (two MKR WAN 1300s, or a 1300 and a 1310) to see exchanges; set the same frequency plan in the code.
Variants
Add a station code in the frame to avoid cross commands between neighbours, or a safety timeout that drops the relay without news.
relais-radio.ino
// Commande radio d'un relais : recepteur MKR WAN 1300 -> broche 6.
// Trames attendues : "ON" ou "OFF" (emetteur = bouton sur autre carte).
#include <MKRWAN.h>
LoRaModem modem;
const int RELAIS = 6;
bool etat = false;
void setup() {
Serial.begin(115200);
pinMode(RELAIS, OUTPUT);
digitalWrite(RELAIS, LOW);
if (!modem.begin(EU868)) while (true);
modem.setFrequency(868.7); // meme canal que l'emetteur
Serial.println(F("Attente de consigne ON/OFF..."));
}
void loop() {
int n = modem.available();
if (n > 0) {
String cmd = "";
while (modem.available()) cmd += (char)modem.read();
cmd.trim(); cmd.toUpperCase();
if (cmd == "ON" || cmd == "OFF") {
etat = (cmd == "ON");
digitalWrite(RELAIS, etat ? HIGH : LOW);
Serial.println(etat ? F("RELAIS ACTIVE") : F("RELAIS COUPE"));
// Accuse de reception vers l'emetteur (half-duplex)
modem.beginPacket();
modem.print("ACK "); modem.print(cmd);
modem.endPacket(false);
} else {
Serial.println(F("consigne ignoree : ") + cmd);
}
}
}