/*
RFM69 Pinout:
MOSI = 11
MISO = 12 <<<<
SCK = 13
SS = 8
*/
/*
Ethernet Pinout:
MOSI = 11
MISO = 12
SCK = 13
SS = 10
DI00 to Pin 2 (interrupt)
*/
//general --------------------------------
#define SERIAL_BAUD 115200
#if 0
#define DEBUG1(expression) Serial.print(expression)
#define DEBUG2(expression, arg) Serial.print(expression, arg)
#define DEBUGLN1(expression) Serial.println(expression)
#else
#define DEBUG1(expression)
#define DEBUG2(expression, arg)
#define DEBUGLN1(expression)
#endif
//RFM69 ----------------------------------
#include <RFM69.h>
#include <SPI.h>
#define NODEID 1 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
//#define FREQUENCY RF69_433MHZ
//#define FREQUENCY RF69_868MHZ
#define FREQUENCY RF69_915MHZ
#define ENCRYPTKEY "MysampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ACK_TIME 30 // max # of ms to wait for an ack
#define RFM69_SS 8
RFM69 radio(RFM69_SS);
bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network
#include <Ethernet.h>
bool conn_ok;
bool mydebug = true;
//Ethernet
byte mac[] = {
0x90, 0xA2, 0xDA, 0x0D, 0x11, 0x11
};
byte server[] = {192, 168, 0, 134 }; //Linux server address
IPAddress ip(192, 168, 0, 4); //address of gateway device
EthernetClient ethClient;
#define DHCP_RETRY 500
// Mosquitto---------------
#include <PubSubClient.h>
PubSubClient client(server, 1883, callback, ethClient);
#define MQTT_CLIENT_ID "arduinoClient"
#define MQTT_RETRY 500
int sendMQTT = 0;
unsigned long MQTT_reconnect = 0;
void MQTTSendInt(PubSubClient* _client, int node, int sensor, int var, int val);
void MQTTSendULong(PubSubClient* _client, int node, int sensor, int var, unsigned long val);
void MQTTSendFloat(PubSubClient* _client, int node, int sensor, int var, float val);
//use LED for indicating MQTT connection status.
int led = 13;
typedef struct {
int nodeID;
int sensorID;
unsigned long var1_usl;
float var2_float;
float var3_float;
}
Payload;
Payload theData;
volatile struct
{
int nodeID;
int sensorID;
unsigned long var1_usl;
float var2_float;
float var3_float; //
int var4_int;
}
SensorNode;
void setup()
{
Serial.begin(SERIAL_BAUD);
Serial.println("Rebooting Ethernet_RFM_Gateways_Combinedv1.1");
//Ethernet -------------------------
//Ethernet.begin(mac, ip);
// //wait for IP address
while (Ethernet.begin(mac) != 1) {
Serial.println("Error getting IP address via DHCP, trying again...");
delay(DHCP_RETRY);
}
Serial.println("ethernet OK");
// print your local IP address:
Serial.println("My IP address: ");
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(".");
}
Serial.println();
Serial.println("Connecting to MQTT via ethernet: ");
// Mosquitto ------------------------------
while (client.connect(MQTT_CLIENT_ID) != 1) {
DEBUGLN1("Error connecting to MQTT");
delay(MQTT_RETRY);
}
Serial.println("Connected... ");
//RFM69 ---------------------------
Serial.println("Initializing radio");
radio.initialize(FREQUENCY, NODEID, NETWORKID);
#ifdef IS_RFM69HW
radio.setHighPower(); //uncomment only for RFM69HW!
Serial.println("setHighPower ok ");
#endif
radio.encrypt(ENCRYPTKEY);
radio.promiscuous(promiscuousMode);
Serial.println("Radio initialized");
char buff[50];
sprintf(buff, "\nListening at %d Mhz...", FREQUENCY == RF69_433MHZ ? 433 : FREQUENCY == RF69_868MHZ ? 868 : 915);
Serial.println(buff);
Serial.println("setup complete");
} // end of setup
byte ackCount = 0;
long watchdogInterval = 2000;
long watchdog = 0;
void loop() {
// calling client.loop too often block the system at some point quite early (~up to 5 loop)
// Here is a temporized call to it on a regular interval
// This need to be as fast as the fastest sensor received
// if (millis() > watchdog) {
// Serial.print("loop ");
// Serial.println(millis());
// watchdog += watchdogInterval;
// //client.loop needs to run every iteration. Previous version did not. Big opps.
// client.loop();
// }
//Serial.println("Other loop");
if (radio.receiveDone()) {
if (mydebug) Serial.print('[');
if (mydebug) Serial.print(radio.SENDERID, DEC);
if (mydebug) Serial.print("] ");
if (promiscuousMode) {
if (mydebug) Serial.print("to [");
if (mydebug) Serial.print(radio.TARGETID, DEC);
if (mydebug) Serial.print("] ");
}
if (mydebug) Serial.println();
if (mydebug) Serial.println("before checking payload");
if (radio.DATALEN != sizeof(Payload))
Serial.println(F("Invalid payload received, not matching Payload struct!"));
else {
theData = *(Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else
if (mydebug) Serial.println("payload is valid");
//save it for i2c:
SensorNode.nodeID = theData.nodeID;
SensorNode.sensorID = theData.sensorID;
SensorNode.var1_usl = theData.var1_usl;
SensorNode.var2_float = theData.var2_float;
SensorNode.var3_float = theData.var3_float;
SensorNode.var4_int = radio.RSSI;
sendMQTT = 1;
}
if (radio.ACK_REQUESTED)
{
if (mydebug) Serial.println("ACK Requested");
byte theNodeID = radio.SENDERID;
radio.sendACK();
// When a node requests an ACK, respond to the ACK
// and also send a packet requesting an ACK (every 3rd one only)
// This way both TX/RX NODE functions are tested on 1 end at the GATEWAY
if (ackCount++ % 3 == 0)
{
//Serial.print(" Pinging node ");
//Serial.print(theNodeID);
//Serial.print(" - ACK...");
//delay(3); //need this when sending right after reception .. ?
//if (radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0)) // 0 = only 1 attempt, no retries
// Serial.print("ok!");
//else Serial.print("nothing");
}
}//end if radio.ACK_REQESTED
} //end if radio.receive
if (sendMQTT == 1)
{
if (mydebug) Serial.println("starting MQTT send");
conn_ok = client.connected();
if (conn_ok == 1)
{
digitalWrite(led, HIGH);
if (mydebug) Serial.println("MQTT connected OK from MQTT Send");
}
else
{
digitalWrite(led, LOW);
if (mydebug) Serial.println("MQTT NOT connected OK from MQTT Send");
}
//no connection, reconnect
if (conn_ok == 0)
{
client.disconnect();
delay(5000);
while (client.connect("arduinoClient") != 1)
{
digitalWrite(led, LOW);
Serial.println("Error connecting to MQTT");
delay(4000);
digitalWrite(led, HIGH);
}
digitalWrite(led, HIGH);
Serial.println("reconnected to MQTT");
MQTT_reconnect = millis();
}
int varnum;
char buff_topic[6];
char buff_message[12];
Serial.println("******************************");
//send var1_usl
varnum = 1;
buff_topic[6];
buff_message[12];
//sprintf creates buff_topic by combining SensorNode.nodeID, SensorNode.sensorID, varnum
sprintf(buff_topic, "%02d%01d%01d", SensorNode.nodeID, SensorNode.sensorID, varnum);
dtostrf (SensorNode.var1_usl, 10, 1, buff_message);
client.publish(buff_topic, buff_message);
Serial.println("Publishing");
decodeBuffTopic(buff_topic);
Serial.print("buff_topic: ");
Serial.print(buff_topic);
Serial.print(" varnum 1: ");
Serial.println(buff_message);
//%02d means format the integer with 2 digits, left padding with zeros
//send var2_float
varnum = 2;
buff_topic[6];
buff_message[7];
sprintf(buff_topic, "%02d%01d%01d", SensorNode.nodeID, SensorNode.sensorID, varnum);
dtostrf (SensorNode.var2_float, 2, 1, buff_message);
client.publish(buff_topic, buff_message);
decodeBuffTopic(buff_topic);
Serial.print("buff_topic: ");
Serial.print(buff_topic);
Serial.print(" varnum 2: ");
Serial.println(buff_message);
delay(200);
//send var3_float
varnum = 3;
sprintf(buff_topic, "%02d%01d%01d", SensorNode.nodeID, SensorNode.sensorID, varnum);
dtostrf (SensorNode.var3_float, 2, 2, buff_message);
client.publish(buff_topic, buff_message);
decodeBuffTopic(buff_topic);
Serial.print("buff_topic: ");
Serial.print(buff_topic);
Serial.print(" varnum 3: ");
Serial.println(buff_message);
delay(200);
//send var4_int, RSSI
varnum = 4;
sprintf(buff_topic, "%02d%01d%01d", SensorNode.nodeID, SensorNode.sensorID, varnum);
sprintf(buff_message, "%04d%", SensorNode.var4_int);
client.publish(buff_topic, buff_message);
decodeBuffTopic(buff_topic);
Serial.print("buff_topic: ");
Serial.print(buff_topic);
Serial.print(" varnum 4: ");
Serial.println(buff_message);
Serial.println("******************************");
sendMQTT = 0;
// Serial.println("finished MQTT send");
}//end if sendMQTT
}//end loop
void MQTTSendInt(PubSubClient* _client, int node, int sensor, int var, int val) {
char buff_topic[6];
char buff_message[7];
sprintf(buff_topic, "%02d%01d%01d", node, sensor, var);
sprintf(buff_message, "%04d%", val);
_client->publish(buff_topic, buff_message);
}
void MQTTSendULong(PubSubClient* _client, int node, int sensor, int var, unsigned long val) {
char buff_topic[6];
char buff_message[12];
sprintf(buff_topic, "%02d%01d%01d", node, sensor, var);
sprintf(buff_message, "%u", val);
_client->publish(buff_topic, buff_message);
}
void MQTTSendFloat(PubSubClient* _client, int node, int sensor, int var, float val) {
char buff_topic[6];
char buff_message[12];
sprintf(buff_topic, "%02d%01d%01d", node, sensor, var);
dtostrf (val, 2, 1, buff_message);
_client->publish(buff_topic, buff_message);
}
// Handing of Mosquitto messages
void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
Serial.println(F("Mosquitto Callback"));
}
void decodeBuffTopic (char mybufftopic[6])
{
//print the OpenHAB Items value
int myInt;
myInt = atoi(mybufftopic);
if (myInt == 4032)
{
Serial.print("Garage Distance: ");
}
else if (myInt == 4122)
{
Serial.print("Mailbox count: ");
}
else if (myInt == 4124)
{
Serial.print("Mailbox RSSI: ");
}
else if (myInt == 4123)
{
Serial.print("Mailbox battery: ");
}
else if (myInt == 4022)
{
Serial.print("Garage light: ");
}
else if (myInt == 4042)
{
Serial.print("Garage temp: ");
}
else if (myInt == 4043)
{
Serial.print("Garage humidity: ");
}
else if (myInt == 3042)
{
Serial.print("Dryer: ");
}
else if (myInt == 3052)
{
Serial.print("Washer: ");
}
else if (myInt == 3032)
{
Serial.print("Water leak: ");
}
else if (myInt == 3062)
{
Serial.print("Laundry light: ");
}
else
Serial.print("unknown: ");
}
Comments