/*********
IR_Bee_GP_OLED_Remote_BME280_4IR_HONEY.ino
Get temp,humidity,pressure,1,2,3,4
(four bee counters at end)
sudo
/home/pi/lora/WIFI_GPT_lora/send_command_wifi_arg.py HONEY,t
*********/
// Libraries for LoRa
#include <SPI.h>
#include <LoRa.h>
// Libraries for OLED Display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Libraries for BME280
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
// =====================
// Node identity / protocol
// =====================
const String NODE_ID = "HONEY";
// If true: respond to plain "t" as well as "HONEY,t" etc.
// If false: ONLY respond when message contains NODE_ID + t
#define ALLOW_PLAIN_T false
// BME280 definition
#define SDA 21
#define SCL 13
// LoRa transceiver pins
#define SCK 18
#define MISO 19
#define MOSI 23
#define SS 5
#define RST 14
#define DIO0 2
#define BAND 868E6
// OLED pins
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// IR Sensor pulse counting
volatile unsigned long beeCount1 =
0;
volatile unsigned long beeCount2 = 0;
volatile unsigned long beeCount3 = 0;
volatile unsigned long beeCount4 = 0;
TwoWire I2Cone = TwoWire(1);
Adafruit_BME280 bme;
float temperature = 0;
float humidity = 0;
float pressure = 0;
String LoRaData;
String LoRaMessage = "";
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
&Wire, OLED_RST);
void IRAM_ATTR countBee1() { beeCount1++; }
void IRAM_ATTR countBee2() { beeCount2++; }
void IRAM_ATTR countBee3() { beeCount3++; }
void IRAM_ATTR countBee4() { beeCount4++; }
void startOLED() {
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
delay(20);
digitalWrite(OLED_RST, HIGH);
Wire.begin(OLED_SDA, OLED_SCL);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false,
false)) {
Serial.println(F("SSD1306 allocation
failed"));
while (1);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.print("LORA REMOTE");
display.display();
}
void startBME() {
I2Cone.begin(SDA, SCL, 100000);
bool status1 = bme.begin(0x76, &I2Cone);
if (!status1) {
Serial.println("Could not find a valid
BME280 sensor, check wiring!");
while (1);
}
}
void startLoRA() {
SPI.begin(SCK, MISO, MOSI, SS);
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(BAND)) {
Serial.println("LoRa init failed!");
while (true) { delay(1000); }
}
LoRa.setSpreadingFactor(9);
LoRa.setSignalBandwidth(125E3);
LoRa.setCodingRate4(5);
LoRa.setTxPower(17);
LoRa.setPreambleLength(8);
LoRa.setSyncWord(0x34);
LoRa.disableCrc();
LoRa.disableInvertIQ();
}
void getReadings() {
temperature = bme.readTemperature();
humidity = bme.readHumidity();
pressure = bme.readPressure() / 100.0F;
}
// Returns true if this packet is asking THIS node for 't'
bool isRequestForThisNode(const String& msg) {
String s = msg;
s.trim();
// Normalize common separators to commas, and remove
spaces
s.replace(" ", "");
s.replace(":", ",");
s.replace(";", ",");
s.replace("|", ",");
// Accept:
// 1) "HONEY,t" or "HONEY,t,..."
// 2) optionally plain "t"
if (s.length() == 0) return false;
// plain "t"
if (ALLOW_PLAIN_T && (s == "t" ||
s.startsWith("t,"))) {
return true;
}
// Must start with "HONEY,"
String prefix = NODE_ID + ",";
if (!s.startsWith(prefix)) return false;
// After "HONEY," must be 't' (or "t,")
int idx = prefix.length();
if (idx >= s.length()) return false;
char c = s.charAt(idx);
if (c == 't') return true;
return false;
}
void setup() {
Serial.begin(115200);
startOLED();
startBME();
Serial.println("LoRa Receiver Test");
startLoRA();
pinMode(34, INPUT);
pinMode(35, INPUT);
pinMode(32, INPUT);
pinMode(33, INPUT);
attachInterrupt(digitalPinToInterrupt(34), countBee1,
RISING);
attachInterrupt(digitalPinToInterrupt(35), countBee2,
RISING);
attachInterrupt(digitalPinToInterrupt(32), countBee3,
RISING);
attachInterrupt(digitalPinToInterrupt(33), countBee4,
RISING);
}
void loop() {
int packetSize = LoRa.parsePacket();
if (!packetSize) return;
Serial.print("Received packet___");
while (LoRa.available()) {
LoRaData = LoRa.readString();
}
LoRaData.trim();
Serial.println(LoRaData);
if (!isRequestForThisNode(LoRaData)) {
Serial.println("Not for me (or not 't') -
no data sent out");
int rssi = LoRa.packetRssi();
Serial.print(" with RSSI ");
Serial.println(rssi);
return;
}
Serial.println("Request matched (HONEY + t)");
getReadings();
// Safely read and reset pulse count
noInterrupts();
unsigned long beepulses1 = beeCount1;
unsigned long beepulses2 = beeCount2;
unsigned long beepulses3 = beeCount3;
unsigned long beepulses4 = beeCount4;
beeCount1 = 0;
beeCount2 = 0;
beeCount3 = 0;
beeCount4 = 0;
interrupts();
// Create data payload (same as before)
String dataPayload =
String(temperature) + "," +
String(humidity) + "," + String(pressure) + "," +
String(beepulses1) + "," +
String(beepulses2) + "," +
String(beepulses3) + "," +
String(beepulses4);
// Now prepend the node ID for the master
LoRaMessage = NODE_ID + "," + dataPayload;
Serial.print("LoRaMessage = ");
Serial.println(LoRaMessage);
delay(10);
LoRa.beginPacket();
LoRa.print(LoRaMessage);
LoRa.endPacket();
Serial.println("data packet sent to master TX");
// Display information on OLED
display.clearDisplay();
display.setCursor(0, 0);
display.print("ID: ");
display.print(NODE_ID);
display.setCursor(0, 10);
display.print("Rx: ");
display.print(LoRaData);
display.setCursor(0, 20);
display.print("Tx: ");
display.print(LoRaMessage); // may wrap; OLED is small
display.setCursor(0, 50);
display.print(beepulses1); display.print(" ");
display.print(beepulses2); display.print(" ");
display.print(beepulses3); display.print(" ");
display.print(beepulses4);
display.display();
int rssi = LoRa.packetRssi();
Serial.print(" with RSSI ");
Serial.println(rssi);
}