trame-crc.ino

Arduino MKR WAN 1300 · File : trame-crc.ino · Language : Arduino · Use case : Fiabiliser les trames avec une somme de contrôle

On radio, any frame can be corrupted or lost: this minimal protocol adds a station id, a sequence number and a CRC-8 to each MKR WAN 1300 LoRa packet. The receiver thus discards invalid frames and spots sequence gaps.

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). Transmitting MKR WAN 1300, any analog sensor on A1 (or a test potentiometer), compatible LoRa receiver.

Wiring

Sensor to A1/GND/3.3 V; check the pinout for your sensor, otherwise a classic potentiometer.

How it works

The 6-byte binary frame separates header (id, seq), 16-bit data and a CRC-8 computed over the preceding bytes. The sequence number counts losses even when the CRC passes.

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

Extend to CRC-16-CCITT for long frames, or add a flags field to multiplex several sensors in one frame.

trame-crc.ino

// Trame LoRa robuste : [id][seq][donnees...][crc8] sur MKR WAN 1300.
#include <MKRWAN.h>

LoRaModem modem;

uint8_t seq = 0;

uint8_t crc8(const uint8_t *d, size_t n) {
  uint8_t crc = 0x31; // CRC-8/MAXIM-like simple polynomial 0x07
  for (size_t i = 0; i < n; i++) {
    crc ^= d[i];
    for (int b = 0; b < 8; b++)
      crc = (crc & 0x80) ? (crc << 1) ^ 0x07 : (crc << 1);
  }
  return crc;
}

void setup() {
  Serial.begin(115200);
  if (!modem.begin(EU868)) while (true);
  modem.setFrequency(868.7);
}

void loop() {
  uint8_t trame[8];
  trame[0] = 0x2A;                 // id station
  trame[1] = seq++;                // numero de serie
  int brut = analogRead(A1);
  trame[2] = brut >> 8;            // grandeur 16 bits
  trame[3] = brut & 0xFF;
  trame[4] = (uint8_t)(millis() >> 24); // minute approximative
  trame[5] = crc8(trame, 5);
  modem.beginPacket();
  modem.write(trame, 6);
  modem.endPacket(false);
  Serial.println(F("trame CRC emise"));
  delay(600000);
}

← Back to the board