Skip to content

Instantly share code, notes, and snippets.

@spacelatte
Created July 2, 2020 20:05
Show Gist options
  • Save spacelatte/fd735995434f4b2c11252e19eaa9875d to your computer and use it in GitHub Desktop.
Save spacelatte/fd735995434f4b2c11252e19eaa9875d to your computer and use it in GitHub Desktop.
arduino stm32 lora master slave sensor device and gateway
#include <LoRa.h>
#include <Wire.h>
#include <I2CSoilMoistureSensor.h>
#define MAGIC 0x74736574 // "test"
#define BUTTON 1
static volatile bool ready = false;
static I2CSoilMoistureSensor sensor;
enum Mode {
NONE,
SLAVE,
MASTER,
} static volatile mode;
struct Data {
long magic;
long identifier; // device id
long cap; // 4-byte = 32-bit
long temp; // 4-byte = 32-bit
long reserved[4];
} __attribute__((packed)) static volatile datapkg = {
.magic = MAGIC,
};
struct Config {
long magic;
long identifier;
long freq;
long sleep_wait;
long wake_interval;
long reserved[4];
} __attribute__((packed)) static volatile configpkg = {
.magic = MAGIC,
};
void onReceive(int packetSize) {
if(!packetSize) return; // invalid packet 0-length
int rssi = LoRa.packetRssi();
float snr = LoRa.packetSnr();
long freqErr = LoRa.packetFrequencyError();
switch(packetSize) {
case sizeof(datapkg):
LoRa.readBytes((uint8_t*) &datapkg, sizeof(datapkg));
ready = (MAGIC == datapkg.magic);
break;
case sizeof(configpkg):
LoRa.readBytes((uint8_t*) &configpkg, sizeof(configpkg));
ready = (MAGIC == configpkg.magic);
break;
default:
// invalid packet
break;
}
return;
}
void setup() {
while(!digitalRead(BUTTON) && millis() < 2222);
mode = digitalRead(BUTTON) ? MASTER : SLAVE;
// put your setup code here, to run once:
Wire.begin();
LoRa.begin(433E6);
sensor.begin(true); // reset sensor and wait
sensor.getCapacitance();
sensor.getTemperature();
LoRa.onReceive(onReceive);
LoRa.receive();
return;
}
void op_master(void) {
if(!ready) return;
/*
printf("Data: from:%08lx temp:%ld cap:%ld \n",
datapkg.identifier,
datapkg.temp,
datapkg.cap
);
*/
configpkg.freq = 433e6;
configpkg.identifier = datapkg.identifier;
configpkg.sleep_wait = 1000;
configpkg.wake_interval = 60000;
LoRa.beginPacket();
LoRa.write((uint8_t*) &configpkg, sizeof(configpkg));
LoRa.endPacket();
LoRa.receive();
return;
}
void op_slave(void) {
while(sensor.isBusy()) delay(9);
datapkg.identifier = HAL_GetUIDw0() ^ HAL_GetUIDw1() ^ HAL_GetUIDw2();
datapkg.cap = (long) sensor.getCapacitance();
datapkg.temp = (long) (sensor.getTemperature() * 10.0);
LoRa.beginPacket();
LoRa.write((uint8_t*) &datapkg, sizeof(datapkg));
LoRa.endPacket();
LoRa.receive();
delay(configpkg.sleep_wait);
return;
}
void loop() {
switch(mode) {
case MASTER:
op_master();
break;
case SLAVE:
op_slave();
break;
default:
// invalid mode
break;
}
return;
}
// https://github.com/Apollon77/I2CSoilMoistureSensor/blob/master/I2CSoilMoistureSensor.cpp#L60
// https://www.empastore.com/stm32-nucleo-32-islemci-kiti-nucleo-l031k6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment