C:ifying continues..

This commit is contained in:
Henrik Ekblad
2015-09-13 11:59:09 +02:00
parent 6a42e2d555
commit f8ee376230
28 changed files with 1541 additions and 1797 deletions
+69 -23
View File
@@ -22,33 +22,53 @@
#define MyConfig_h #define MyConfig_h
#include <stdint.h> #include <stdint.h>
// Enable debug flag for debug prints. This will add a lot to the size of the final sketch but good // Enables this in sketch to show debug prints. This option will add a lot to the size of the
// to see what is actually is happening when developing // final sketch but is helpful to see what is actually is happening during development
//#define MY_DEBUG //#define MY_DEBUG
// Enable this line, If you are using TX(1), RX(0) as normal I/O pin // Enable this in sketch if you want to use TX(1), RX(0) as normal I/O pin
// #define MY_DISABLED_SERIAL //#define MY_DISABLED_SERIAL
// Turn off debug if serial pins is used for other stuff
#ifdef MY_DISABLED_SERIAL
#undef MY_DEBUG
#endif
// Serial output baud rate (for debug prints and serial gateway) // Serial output baud rate (for debug prints and serial gateway)
#ifndef MY_BAUD_RATE #ifndef MY_BAUD_RATE
#define MY_BAUD_RATE 115200 #define MY_BAUD_RATE 115200
#endif #endif
// Node id defaults to AUTO (tries to fetch id from controller)
#ifndef MY_NODE_ID
#define MY_NODE_ID AUTO
#endif
// Node parent defaults to AUTO (tries to find a parent automatically)
#ifndef MY_PARENT_NODE_ID
#define MY_PARENT_NODE_ID AUTO
#endif
// Enables repeater functionality (relays messages from other nodes)
// #define MY_REPEATER_FEATURE
/********************************** /**********************************
* Over the air firmware updates * Over the air firmware updates
***********************************/ ***********************************/
// The following define enables the safe over-the-air firmware update feature // Enable MY_OTA_FIRMWARE_FEATURE in sketch to allow safe over-the-air firmware updates.
// which requires external flash and the DualOptiBoot bootloader. // This feature requires external flash and the DualOptiBoot bootloader.
// Note: You can still have OTA FW updates without external flash but it // Note: You can still have OTA FW updates without external flash but it
// requires the MYSBootloader and disabled MY_OTA_FIRMWARE_FEATURE // requires the MYSBootloader and disabled MY_OTA_FIRMWARE_FEATURE
//#define MY_OTA_FIRMWARE_FEATURE //#define MY_OTA_FIRMWARE_FEATURE
// Slave select pin for external flash // Slave select pin for external flash
#ifdef MY_OTA_FLASH_SS #ifndef MY_OTA_FLASH_SS
#define MY_OTA_FLASH_SS 8 #define MY_OTA_FLASH_SS 8
#endif #endif
// Flash jdecid // Flash jdecid
#ifdef MY_OTA_FLASH_JDECID #ifndef MY_OTA_FLASH_JDECID
#define MY_OTA_FLASH_JDECID 0x1F65 #define MY_OTA_FLASH_JDECID 0x1F65
#endif #endif
@@ -112,8 +132,10 @@
/********************************** /**********************************
* Message Signing Settings * Message Signing Settings
***********************************/ ***********************************/
// Disable to completely disable signing functionality in library
//#define MY_SIGNING_FEATURE // Enable one of these in sketch to use signing functionality
//#define MY_SIGNING_ATSHA204
//#define MY_SIGNING_SOFT
// Define a suitable timeout for a signature verification session // Define a suitable timeout for a signature verification session
// Consider the turn-around from a nonce being generated to a signed message being received // Consider the turn-around from a nonce being generated to a signed message being received
@@ -151,18 +173,30 @@
/********************************** /**********************************
* NRF24L01 Driver Defaults * NRF24L01 Driver Defaults
***********************************/ ***********************************/
#define RF24_CE_PIN 9 #ifndef MY_RF24_CE_PIN
#define RF24_CS_PIN 10 #define MY_RF24_CE_PIN 9
#define RF24_PA_LEVEL RF24_PA_MAX #endif
#define RF24_PA_LEVEL_GW RF24_PA_LOW #ifndef MY_RF24_CS_PIN
// RF channel for the sensor net, 0-127 #define MY_RF24_CS_PIN 10
#define RF24_CHANNEL 76 #endif
//RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
#define RF24_DATARATE RF24_250KBPS
// This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network.
#define RF24_BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL)
// Enable SOFTSPI for NRF24L01 when using the W5100 Ethernet module #ifndef MY_RF24_PA_LEVEL
#define MY_RF24_PA_LEVEL RF24_PA_MAX
#endif
// RF channel for the sensor net, 0-127
#ifndef MY_RF24_CHANNEL
#define MY_RF24_CHANNEL 76
#endif
//RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
#ifndef MY_RF24_DATARATE
#define MY_RF24_DATARATE RF24_250KBPS
#endif
// This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network.
#ifndef MY_RF24_BASE_RADIO_ID
#define MY_RF24_BASE_RADIO_ID ((uint64_t)0xA8A8E1FC00LL)
#endif
// Enable SOFTSPI for NRF24L01, useful for the W5100 Ethernet module
//#define MY_SOFTSPI //#define MY_SOFTSPI
#ifndef MY_SOFT_SPI_SCK_PIN #ifndef MY_SOFT_SPI_SCK_PIN
@@ -186,6 +220,11 @@
//#define MY_RFM69_FREQUENCY RF69_915MHZ //#define MY_RFM69_FREQUENCY RF69_915MHZ
#endif #endif
// Enable this if you're running the RFM69HW model
#ifndef MY_IS_RFM69HW
#define MY_IS_RFM69HW false
#endif
// Default network id. Use the same for all nodes that will talk to each other // Default network id. Use the same for all nodes that will talk to each other
#ifndef MY_RFM69_NETWORKID #ifndef MY_RFM69_NETWORKID
#define MY_RFM69_NETWORKID 100 #define MY_RFM69_NETWORKID 100
@@ -210,9 +249,16 @@
* Gateway Transport Ethernet Defaults * Gateway Transport Ethernet Defaults
***************************************/ ***************************************/
// Enable to use DHCP for getting IP address. If not defined, static IP is expected // Enable to use DHCP for getting IP address. If not defined, static IP is expected
//#define IP_ADDRESS_DHCP //#define MY_IP_ADDRESS_VIA_DHCP
#ifndef MY_IP_RENEWAL_INTERVAL
#define MY_IP_RENEWAL_INTERVAL 60000
#endif
#ifndef MY_MAC_ADDRESS
#define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
#endif
// Enable to use UDP instead of plain Ethernet // Enable to use UDP instead of plain Ethernet
#define MY_USE_UDP //#define MY_USE_UDP
#endif #endif
+141 -27
View File
@@ -16,50 +16,164 @@
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation. * version 2 as published by the Free Software Foundation.
*/ */
#ifndef MySensor_h #ifndef MySensor_h
#define MySensor_h #define MySensor_h
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
// #pragma message(VAR_NAME_VALUE(MY_GATEWAY_FEATURE))
#include "MyConfig.h" #include "MyConfig.h"
// Include drivers #if defined(MY_GATEWAY_SERIAL) || defined(MY_GATEWAY_W5100_CLIENT) || defined(MY_GATEWAY_W5100_SERVER)
#define MY_GATEWAY_FEATURE
#define MY_NODE_TYPE "gateway"
#elif defined(MY_REPEATER_FEATURE)
#define MY_NODE_TYPE "repeater"
#else
#define MY_NODE_TYPE "sensor"
#endif
// CORE
#include "drivers/SPI/SPI.cpp" #include "drivers/SPI/SPI.cpp"
#include "drivers/RF24/RF24.cpp"
#include "drivers/RFM69/RFM69.cpp" // HARDWARE
#if defined(ARDUINO_ARCH_ESP8266)
#include "core/MyHwESP8266.cpp"
#elif defined(ARDUINO_ARCH_AVR)
#include "core/MyHwATMega328.cpp"
#endif
#include "drivers/ATSHA204/ATSHA204.cpp" // SIGNING
#include "drivers/ATSHA204/sha256.cpp" #if defined(MY_SIGNING_ATSHA204) || defined(MY_SIGNING_SOFT)
#include "MySigning.cpp"
#define MY_SIGNING_FEATURE
#if defined(MY_SIGNING_ATSHA204)
#include "MySigningAtsha204.cpp"
#include "drivers/ATSHA204/ATSHA204.cpp"
MySigningAtsha204 signer;
#elif defined(MY_SIGNING_SOFT)
#include "MySigningAtsha204Soft.cpp"
#include "drivers/ATSHA204/sha256.cpp"
MySigningAtsha204Soft signer;
#endif
#endif
#include "drivers/SPIFlash/SPIFlash.cpp" // RADIO
#if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69)
#define MY_RADIO_FEATURE
// SOFTSPI
#ifdef MY_SOFTSPI
#include "drivers/DigitalIO/SoftI2cMaster.cpp"
#include "drivers/DigitalIO/PinIO.cpp"
#endif
#include "drivers/Ethernet_W5100/utility/socket.cpp" // FLASH
#include "drivers/Ethernet_W5100/utility/w5100.cpp" #ifdef MY_OTA_FIRMWARE_FEATURE
#include "drivers/Ethernet_W5100/DNS.cpp" SPIFlash flash(MY_OTA_FLASH_SS, MY_OTA_FLASH_JDECID);
#include "drivers/Ethernet_W5100/Ethernet.cpp" #include "drivers/SPIFlash/SPIFlash.cpp"
#include "drivers/Ethernet_W5100/EthernetUdp.cpp" #endif
#include "drivers/Ethernet_W5100/IPAddress.cpp"
#include "core/MyTransport.cpp"
#if defined(MY_RADIO_NRF24)
#include "drivers/RF24/RF24.cpp"
#include "core/MyTransportNRF24.cpp"
MyTransportNRF24 transport;
#elif defined(MY_RADIO_RFM69)
#include "drivers/RFM69/RFM69.cpp"
#include "core/MyTransportRFM69.cpp"
MyTransportRFM69 transport;
#endif
#endif
// GATEWAY - TRANSPORT
#if defined(MY_GATEWAY_FEATURE)
// GATEWAY - PROTOCOL
#include "core/MyProtocol.cpp"
#if defined(MY_GATEWAY_PROTOCOL_DEFAULT)
#include "core/MyProtocolDefault.cpp"
MyProtocolDefault _protocol;
#else
#error No gateway protocol specified!
#endif
#if defined(MY_RADIO_FEATURE)
// We assume that a gateway having a radio also should act as repeater
#define MY_REPEATER_FEATURE
#endif
#if defined(MY_GATEWAY_W5100_CLIENT) || defined(MY_GATEWAY_W5100_SERVER)
#include "drivers/Ethernet_W5100/utility/socket.cpp"
#include "drivers/Ethernet_W5100/utility/w5100.cpp"
#include "drivers/Ethernet_W5100/DNS.cpp"
#include "drivers/Ethernet_W5100/Ethernet.cpp"
#include "drivers/Ethernet_W5100/EthernetUdp.cpp"
#include "drivers/Ethernet_W5100/IPAddress.cpp"
#if !defined(MY_PORT)
#error You must define MY_PORT
#endif
#if !defined(USE_UDP)
#include "drivers/Ethernet_W5100/EthernetServer.cpp"
#endif
#if defined(MY_GATEWAY_W5100_CLIENT) && !defined(MY_CONTROLLER_IP_ADDRESS)
#error You must define MY_CONTROLLER_IP_ADDRESS when acting as client
#endif
#if defined(MY_GATEWAY_W5100_CLIENT)
#include "drivers/Ethernet_W5100/EthernetClient.cpp"
#include "core/MyGatewayTransportEthernet.cpp"
#endif
#elif defined(MY_GATEWAY_SERIAL)
#include "core/MyGatewayTransportSerial.cpp"
MyGatewayTransportSerial gwTransport(protocol);
#endif
#else
#undef MY_GATEWAY_FEATURE
#endif
// Make sure to disable child features when parent feature is disabled
#if !defined(MY_RADIO_FEATURE)
#undef MY_OTA_FIRMWARE_FEATURE
#undef MY_REPEATER_FEATURE
#undef MY_SECURE_NODE_WHITELISTING
#undef MY_SIGNING_FEATURE
#endif
#if !defined(MY_GATEWAY_FEATURE)
#undef MY_INCLUSION_MODE_FEATURE
#undef MY_INCLUSION_BUTTON_FEATURE
#endif
// Defines used in code for if-statements
#if defined(MY_REPEATER_FEATURE)
#define MY_IS_REPEATER true
#else
#define MY_IS_REPEATER false
#endif
#if defined(MY_GATEWAY_FEATURE)
#define MY_IS_GATEWAY true
#else
#define MY_IS_GATEWAY false
#endif
// Include core classes
#include "core/MyHw.cpp"
#include "core/MyHwATMega328.cpp"
#include "core/MyTransport.cpp"
#include "core/MyTransportNRF24.cpp"
//#include "core/MyTransportRFM69.cpp"
#include "core/MyGatewayTransport.cpp"
#include "core/MyGatewayTransportSerial.cpp"
#include "core/MyMessage.cpp" #include "core/MyMessage.cpp"
#include "core/MySensorCore.cpp" #include "core/MySensorCore.cpp"
extern void setup();
extern void loop();
// Initialize library // Initialize library and call sketch functions
//MyTransportRFM69 transport; int main() {
MySensor gw; begin();
setup();
while(1) {
// We handle incoming message processing here
process();
loop();
}
}
#endif #endif
@@ -1,25 +0,0 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#include "MyGatewayTransport.h"
MyGatewayTransport::MyGatewayTransport(MyProtocol &_protocol) : protocol(_protocol) {
}
@@ -1,47 +0,0 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#ifndef MyGatewayTransport_h
#define MyGatewayTransport_h
#include "MyMessage.h"
#include "MyProtocol.h"
#include "MyProtocolDefault.h"
class MyGatewayTransport
{
public:
// MyProtocol constructor
MyGatewayTransport(MyProtocol &protocol = *new MyProtocolDefault());
// initialize the transport driver
virtual bool begin() = 0;
// Send message to controller
virtual bool send(MyMessage &message) = 0;
// Check if a new message is available from controller
virtual bool available() = 0;
// Pick up last message received from controller
virtual MyMessage& receive() = 0;
protected:
MyProtocol& protocol;
};
#endif
@@ -19,39 +19,28 @@
#include "MyGatewayTransportEthernet.h" #include "MyGatewayTransportEthernet.h"
MyGatewayTransportEthernet::MyGatewayTransportEthernet( IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
MyProtocol &protocol, IPAddress _ethernetGatewayIP(MY_IP_ADDRESS);
uint8_t *gw_mac byte _ethernetGatewayMAC[] = { MY_MAC_ADDRESS };
#ifndef IP_ADDRESS_DHCP uint16_t _ethernetGatewayPort = MY_PORT;
, IPAddress gw_ip char _ethernetInputBuffer[MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface
#endif /* not IP_ADDRESS_DHCP */ MyMessage _ethernetMsg;
, uint16_t gw_port
#ifdef IP_ADDRESS_DHCP
, unsigned long ip_renew_interval
#endif /* IP_ADDRESS_DHCP */
, IPAddress controller_IP
, uint16_t controller_port) :
MyGatewayTransport(protocol),
gatewayMAC(gw_mac),
#ifndef IP_ADDRESS_DHCP
gatewayIP(gw_ip),
#endif /* not IP_ADDRESS_DHCP */
gatewayPort(gw_port),
#ifdef IP_ADDRESS_DHCP
ip_renewal_period(ip_renew_interval),
#endif /* IP_ADDRESS_DHCP */
controllerIP(controller_IP),
controllerPort(controller_port)
{
;
}
bool MyGatewayTransportEthernet::begin() { #ifdef MY_USE_UDP
#ifdef IP_ADDRESS_DHCP EthernetUDP _ethernetServer;
// Get IP address from DHCP
Ethernet.begin(gatewayMAC);
#else #else
Ethernet.begin(gatewayMAC, gatewayIP); // we have to use pointers due to the constructor of EthernetServer
EthernetServer _ethernetServer(_ethernetGatewayPort);
uint8_t _ethernetInputPos;
#endif /* USE_UDP */
bool gatewayTransportBegin() {
#ifdef MY_IP_ADDRESS
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP);
#else
// Get IP address from DHCP
Ethernet.begin(_ethernetGatewayMAC);
#endif /* IP_ADDRESS_DHCP */ #endif /* IP_ADDRESS_DHCP */
// give the Ethernet interface a second to initialize // give the Ethernet interface a second to initialize
@@ -59,34 +48,32 @@ bool MyGatewayTransportEthernet::begin() {
delay(1000); delay(1000);
#ifdef MY_USE_UDP #ifdef MY_USE_UDP
server = new EthernetUDP(); _ethernetServer.begin(_ethernetGatewayPort);
server->begin(gatewayPort);
#else #else
// we have to use pointers due to the constructor of EthernetServer // we have to use pointers due to the constructor of EthernetServer
server = new EthernetServer(gatewayPort); _ethernetServer.begin();
server->begin();
#endif /* USE_UDP */ #endif /* USE_UDP */
} }
bool MyGatewayTransportEthernet::send(MyMessage &message) bool gatewayTransportSend(MyMessage &message)
{ {
char *msg = NULL; char *_ethernetMsg = NULL;
if (controllerIP == INADDR_NONE) { if (_ethernetControllerIP == INADDR_NONE) {
// no controller IP address set! // no controller IP address set!
return false; return false;
} }
else { else {
msg = protocol.format(message); _ethernetMsg = _protocol.format(message);
#ifdef MY_USE_UDP #ifdef MY_USE_UDP
server->beginPacket(controllerIP, controllerPort); _ethernetServer.beginPacket(_ethernetControllerIP, MY_CONTROLLER_PORT);
server->write(msg, strlen(msg)); _ethernetServer.write(_ethernetMsg, strlen(_ethernetMsg));
// returns 1 if the packet was sent successfully // returns 1 if the packet was sent successfully
return server->endPacket(); return _ethernetServer.endPacket();
#else #else
EthernetClient client; EthernetClient client;
if (client.connect(controllerIP, controllerPort)) { if (client.connect(_ethernetControllerIP, MY_CONTROLLER_PORT)) {
client.write(msg, strlen(msg)); client.write(_ethernetMsg, strlen(_ethernetMsg));
client.stop(); client.stop();
return true; return true;
} }
@@ -98,71 +85,64 @@ bool MyGatewayTransportEthernet::send(MyMessage &message)
} }
} }
bool MyGatewayTransportEthernet::available() bool gatewayTransportAvailable()
{ {
bool available = false; bool available = false;
#ifdef IP_ADDRESS_DHCP #ifndef MY_IP_ADDRESS
// renew IP address using DHCP // renew IP address using DHCP
renewIP(); gatewayTransportRenewIP();
#endif #endif
#ifdef MY_USE_UDP #ifdef MY_USE_UDP
int packet_size = server->parsePacket(); int packet_size = _ethernetServer.parsePacket();
if (server->available()) { if (_ethernetServer.available()) {
server->read(inputBuffer, MAX_RECEIVE_LENGTH); _ethernetServer.read(_ethernetInputBuffer, MAX_RECEIVE_LENGTH);
available = true; available = true;
} }
#else #else
// if an incoming client connects, there will be // if an incoming client connects, there will be
// bytes available to read via the client object // bytes available to read via the client object
EthernetClient client = server->available(); EthernetClient client = _ethernetServer.available();
if (client) { if (client) {
while (client.available()) { while (client.available()) {
// read the bytes incoming from the client // read the bytes incoming from the client
char inChar = client.read(); char inChar = client.read();
if (inputPos < MAX_RECEIVE_LENGTH - 1) { if (_ethernetInputPos < MAX_RECEIVE_LENGTH - 1) {
// if newline then command is complete // if newline then command is complete
if (inChar == '\n') { if (inChar == '\n') {
inputBuffer[inputPos] = 0; _ethernetInputBuffer[_ethernetInputPos] = 0;
available = true; available = true;
} else { } else {
inputBuffer[inputPos] = inChar; _ethernetInputBuffer[_ethernetInputPos] = inChar;
inputPos++; _ethernetInputPos++;
} }
} }
} }
} }
inputPos = 0; _ethernetInputPos = 0;
#endif #endif
if (available) { if (available) {
// Parse message and return parse result // Parse message and return parse result
available = protocol.parse(msg, inputBuffer); available = _protocol.parse(_ethernetMsg, _ethernetInputBuffer);
} }
return available; return available;
} }
MyMessage& MyGatewayTransportEthernet::receive() MyMessage& gatewayTransportReceive()
{ {
// Return the last parsed message // Return the last parsed message
return msg; return _ethernetMsg;
} }
void MyGatewayTransportEthernet::setControllerIPPort(const IPAddress& addr, const uint16_t port) {
controllerIP = addr;
/* set the port if some legal value passed */ #ifndef MY_IP_ADDRES
if (port > 0) void gatewayTransportRenewIP()
controllerPort = port;
}
#ifdef IP_ADDRESS_DHCP
void MyGatewayTransportEthernet::renewIP()
{ {
/* renew/rebind IP address /* renew/rebind IP address
0 - nothing happened 0 - nothing happened
@@ -172,7 +152,7 @@ void MyGatewayTransportEthernet::renewIP()
4 - rebind success 4 - rebind success
*/ */
// TODO: Use millis from MyHw ?? // TODO: Use millis from MyHw ??
static unsigned long next_time = millis() + ip_renewal_period; static unsigned long next_time = millis() + MY_IP_RENEWAL_INTERVAL;
unsigned long now = millis(); unsigned long now = millis();
// http://playground.arduino.cc/Code/TimingRollover // http://playground.arduino.cc/Code/TimingRollover
@@ -184,6 +164,6 @@ void MyGatewayTransportEthernet::renewIP()
return; return;
} }
next_time = now + ip_renewal_period; next_time = now + MY_IP_RENEWAL_INTERVAL;
} }
#endif /* IP_ADDRESS_DHCP */ #endif /* IP_ADDRESS_DHCP */
@@ -23,7 +23,6 @@
#include "MyConfig.h" #include "MyConfig.h"
#include "MyMessage.h" #include "MyMessage.h"
#include "MyProtocol.h" #include "MyProtocol.h"
#include "MyGatewayTransport.h"
#include "MyProtocolDefault.h" #include "MyProtocolDefault.h"
#include "drivers/Ethernet_W5100/IPAddress.h" #include "drivers/Ethernet_W5100/IPAddress.h"
@@ -43,58 +42,20 @@
#define MAX_RECEIVE_LENGTH 100 // Maximum message length for messages coming from controller #define MAX_RECEIVE_LENGTH 100 // Maximum message length for messages coming from controller
class MyGatewayTransportEthernet : public MyGatewayTransport // initialize the driver
{ bool gatewayTransportBegin();
public:
MyGatewayTransportEthernet(MyProtocol &protocol,
uint8_t *gw_mac
#ifndef IP_ADDRESS_DHCP
, IPAddress gw_ip
#endif /* not IP_ADDRESS_DHCP */
, uint16_t gw_port
#ifdef IP_ADDRESS_DHCP
, unsigned long ip_renew_interval
#endif /* IP_ADDRESS_DHCP */
, IPAddress controller_IP
, uint16_t controller_port
);
// initialize the driver // Send message to controller
bool begin(); bool gatewayTransportSend(MyMessage &message);
// Send message to controller // Check if a new message is available from controller
bool send(MyMessage &message); bool gatewayTransportAvailable();
// Check if a new message is available from controller // Pick up last message received from controller
bool available(); MyMessage& gatewayTransportReceive();
// Pick up last message received from controller #ifndef MY_IP_ADDRESS
MyMessage& receive(); void gatewayTransportRenewIP();
// Set the controller IP and Port
void setControllerIPPort(const IPAddress& addr, const uint16_t port);
protected:
IPAddress controllerIP;
uint16_t controllerPort;
#ifdef IP_ADDRESS_DHCP
void renewIP();
unsigned long ip_renewal_period;
#endif /* IP_ADDRESS_DHCP */
uint8_t *gatewayMAC;
IPAddress gatewayIP;
uint16_t gatewayPort;
#ifdef MY_USE_UDP
EthernetUDP *server;
#else
EthernetServer *server;
uint8_t inputPos;
#endif #endif
char inputBuffer[MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface
MyMessage msg;
};
#endif /* MyGatewayTransportEthernet_h */ #endif /* MyGatewayTransportEthernet_h */
@@ -22,7 +22,6 @@
#include "MyMessage.h" #include "MyMessage.h"
#include "MyProtocol.h" #include "MyProtocol.h"
#include "MyGatewayTransport.h"
#include "MyProtocolDefault.h" #include "MyProtocolDefault.h"
#define MAX_RECEIVE_LENGTH 100 // Maximum message length for messages coming from controller #define MAX_RECEIVE_LENGTH 100 // Maximum message length for messages coming from controller
-23
View File
@@ -1,23 +0,0 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#include "MyHw.h"
MyHw::MyHw() {
}
-54
View File
@@ -1,54 +0,0 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#ifndef MyHw_h
#define MyHw_h
#include <stdint.h>
#include <stddef.h>
#include "MyConfig.h"
/**
* The Hw contains all hardware specific details of the platform
*/
class MyHw
{
public:
// MyHw constructor
MyHw();
/* // The following is defined as macros to save space
virtual void init() = 0;
virtual void watchdogReset() = 0;
virtual void reboot() = 0;
virtual unsigned long millisec() = 0;
virtual uint8_t readConfig(uint8_t pos) = 0;
virtual void writeConfig(uint8_t pos, uint8_t value) = 0;
virtual void readConfigBlock(void* buf, void * pos, size_t length) = 0;
virtual void writeConfigBlock(void* pos, void* buf, uint16_t length) = 0; */
virtual void sleep(unsigned long ms) = 0;
virtual bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) = 0;
virtual uint8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms) = 0;
#ifdef MY_DEBUG
virtual void debugPrint(bool isGW, const char *fmt, ... ) = 0;
#endif
};
#endif
+26 -68
View File
@@ -19,7 +19,6 @@
#ifdef ARDUINO_ARCH_AVR #ifdef ARDUINO_ARCH_AVR
#include "MyHw.h"
#include "MyHwATMega328.h" #include "MyHwATMega328.h"
int8_t pinIntTrigger = 0; int8_t pinIntTrigger = 0;
@@ -40,51 +39,10 @@ ISR (WDT_vect)
wdt_disable(); wdt_disable();
} }
MyHwATMega328::MyHwATMega328() : MyHw()
{
}
/*
// The following was redifined as macros to save space void hwPowerDown(period_t period) {
inline uint8_t MyHwATMega328::readConfig(uint8_t pos) {
return eeprom_read_byte((uint8_t*)pos);
}
inline void MyHwATMega328::writeConfig(uint8_t pos, uint8_t value) {
eeprom_update_byte((uint8_t*)pos, value);
}
inline void MyHwATMega328::readConfigBlock(void* buf, void * pos, size_t length) {
eeprom_read_block(buf, (void*)pos, length);
}
inline void MyHwATMega328::writeConfigBlock(void* pos, void* buf, size_t length) {
eeprom_write_block((void*)pos, (void*)buf, length);
}
inline void MyHwATMega328::init() {
Serial.begin(BAUD_RATE);
}
inline void MyHwATMega328::watchdogReset() {
wdt_reset();
}
inline void MyHwATMega328::reboot() {
wdt_enable(WDTO_15MS); for (;;);
}
inline unsigned long MyHwATMega328::millis() {
return ::millis();
}
*/
void powerDown(period_t period) {
ADCSRA &= ~(1 << ADEN); ADCSRA &= ~(1 << ADEN);
@@ -119,35 +77,35 @@ void powerDown(period_t period) {
ADCSRA |= (1 << ADEN); ADCSRA |= (1 << ADEN);
} }
void MyHwATMega328::internalSleep(unsigned long ms) { void hwInternalSleep(unsigned long ms) {
// Let serial prints finish (debug, log etc) // Let serial prints finish (debug, log etc)
#ifndef MY_DISABLED_SERIAL #ifndef MY_DISABLED_SERIAL
Serial.flush(); Serial.flush();
#endif #endif
pinIntTrigger = 0; pinIntTrigger = 0;
while (!pinIntTrigger && ms >= 8000) { powerDown(SLEEP_8S); ms -= 8000; } while (!pinIntTrigger && ms >= 8000) { hwPowerDown(SLEEP_8S); ms -= 8000; }
if (!pinIntTrigger && ms >= 4000) { powerDown(SLEEP_4S); ms -= 4000; } if (!pinIntTrigger && ms >= 4000) { hwPowerDown(SLEEP_4S); ms -= 4000; }
if (!pinIntTrigger && ms >= 2000) { powerDown(SLEEP_2S); ms -= 2000; } if (!pinIntTrigger && ms >= 2000) { hwPowerDown(SLEEP_2S); ms -= 2000; }
if (!pinIntTrigger && ms >= 1000) { powerDown(SLEEP_1S); ms -= 1000; } if (!pinIntTrigger && ms >= 1000) { hwPowerDown(SLEEP_1S); ms -= 1000; }
if (!pinIntTrigger && ms >= 500) { powerDown(SLEEP_500MS); ms -= 500; } if (!pinIntTrigger && ms >= 500) { hwPowerDown(SLEEP_500MS); ms -= 500; }
if (!pinIntTrigger && ms >= 250) { powerDown(SLEEP_250MS); ms -= 250; } if (!pinIntTrigger && ms >= 250) { hwPowerDown(SLEEP_250MS); ms -= 250; }
if (!pinIntTrigger && ms >= 125) { powerDown(SLEEP_120MS); ms -= 120; } if (!pinIntTrigger && ms >= 125) { hwPowerDown(SLEEP_120MS); ms -= 120; }
if (!pinIntTrigger && ms >= 64) { powerDown(SLEEP_60MS); ms -= 60; } if (!pinIntTrigger && ms >= 64) { hwPowerDown(SLEEP_60MS); ms -= 60; }
if (!pinIntTrigger && ms >= 32) { powerDown(SLEEP_30MS); ms -= 30; } if (!pinIntTrigger && ms >= 32) { hwPowerDown(SLEEP_30MS); ms -= 30; }
if (!pinIntTrigger && ms >= 16) { powerDown(SLEEP_15Ms); ms -= 15; } if (!pinIntTrigger && ms >= 16) { hwPowerDown(SLEEP_15Ms); ms -= 15; }
} }
void MyHwATMega328::sleep(unsigned long ms) { void hwSleep(unsigned long ms) {
internalSleep(ms); hwInternalSleep(ms);
} }
bool MyHwATMega328::sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) { bool hwSleep(uint8_t interrupt, uint8_t mode, unsigned long ms) {
// Let serial prints finish (debug, log etc) // Let serial prints finish (debug, log etc)
bool pinTriggeredWakeup = true; bool pinTriggeredWakeup = true;
attachInterrupt(interrupt, wakeUp, mode); attachInterrupt(interrupt, wakeUp, mode);
if (ms>0) { if (ms>0) {
pinIntTrigger = 0; pinIntTrigger = 0;
internalSleep(ms); hwInternalSleep(ms);
if (0 == pinIntTrigger) { if (0 == pinIntTrigger) {
pinTriggeredWakeup = false; pinTriggeredWakeup = false;
} }
@@ -155,19 +113,19 @@ bool MyHwATMega328::sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) {
#ifndef MY_DISABLED_SERIAL #ifndef MY_DISABLED_SERIAL
Serial.flush(); Serial.flush();
#endif #endif
powerDown(SLEEP_FOREVER); hwPowerDown(SLEEP_FOREVER);
} }
detachInterrupt(interrupt); detachInterrupt(interrupt);
return pinTriggeredWakeup; return pinTriggeredWakeup;
} }
inline uint8_t MyHwATMega328::sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms) { uint8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms) {
int8_t retVal = 1; int8_t retVal = 1;
attachInterrupt(interrupt1, wakeUp, mode1); attachInterrupt(interrupt1, wakeUp, mode1);
attachInterrupt(interrupt2, wakeUp2, mode2); attachInterrupt(interrupt2, wakeUp2, mode2);
if (ms>0) { if (ms>0) {
pinIntTrigger = 0; pinIntTrigger = 0;
internalSleep(ms); hwInternalSleep(ms);
if (0 == pinIntTrigger) { if (0 == pinIntTrigger) {
retVal = -1; retVal = -1;
} }
@@ -175,7 +133,7 @@ inline uint8_t MyHwATMega328::sleep(uint8_t interrupt1, uint8_t mode1, uint8_t i
#ifndef MY_DISABLED_SERIAL #ifndef MY_DISABLED_SERIAL
Serial.flush(); Serial.flush();
#endif #endif
powerDown(SLEEP_FOREVER); hwPowerDown(SLEEP_FOREVER);
} }
detachInterrupt(interrupt1); detachInterrupt(interrupt1);
detachInterrupt(interrupt2); detachInterrupt(interrupt2);
@@ -191,24 +149,24 @@ inline uint8_t MyHwATMega328::sleep(uint8_t interrupt1, uint8_t mode1, uint8_t i
#ifdef MY_DEBUG #ifdef MY_DEBUG
void MyHwATMega328::debugPrint(bool isGW, const char *fmt, ... ) { void hwDebugPrint(const char *fmt, ... ) {
char fmtBuffer[300]; char fmtBuffer[300];
if (isGW) { #ifdef MY_GATEWAY_FEATURE
// prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE) // prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
snprintf_P(fmtBuffer, 299, PSTR("0;0;%d;0;%d;"), C_INTERNAL, I_LOG_MESSAGE); snprintf_P(fmtBuffer, 299, PSTR("0;0;%d;0;%d;"), C_INTERNAL, I_LOG_MESSAGE);
Serial.print(fmtBuffer); Serial.print(fmtBuffer);
} #endif
va_list args; va_list args;
va_start (args, fmt ); va_start (args, fmt );
va_end (args); va_end (args);
if (isGW) { #ifdef MY_GATEWAY_FEATURE
// Truncate message if this is gateway node // Truncate message if this is gateway node
vsnprintf_P(fmtBuffer, 60, fmt, args); vsnprintf_P(fmtBuffer, 60, fmt, args);
fmtBuffer[59] = '\n'; fmtBuffer[59] = '\n';
fmtBuffer[60] = '\0'; fmtBuffer[60] = '\0';
} else { #else
vsnprintf_P(fmtBuffer, 299, fmt, args); vsnprintf_P(fmtBuffer, 299, fmt, args);
} #endif
va_end (args); va_end (args);
Serial.print(fmtBuffer); Serial.print(fmtBuffer);
Serial.flush(); Serial.flush();
+18 -33
View File
@@ -22,7 +22,6 @@
#ifdef ARDUINO_ARCH_AVR #ifdef ARDUINO_ARCH_AVR
#include "MyHw.h"
#include "MyConfig.h" #include "MyConfig.h"
#include "MyMessage.h" #include "MyMessage.h"
#include <avr/eeprom.h> #include <avr/eeprom.h>
@@ -42,7 +41,7 @@
#ifndef sleep_bod_disable #ifndef sleep_bod_disable
#define sleep_bod_disable() \ #define sleep_bod_disable() \
do { \ do { \
unsigned char tempreg; \ unsigned char tempreg; \
__asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \ __asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \
"ori %[tempreg], %[bods_bodse]" "\n\t" \ "ori %[tempreg], %[bods_bodse]" "\n\t" \
"out %[mcucr], %[tempreg]" "\n\t" \ "out %[mcucr], %[tempreg]" "\n\t" \
@@ -59,22 +58,22 @@ do { \
// Define these as macros to save valuable space // Define these as macros to save valuable space
#define hw_digitalWrite(__pin, __value) (digitalWrite(__pin, __value)) #define hwDigitalWrite(__pin, __value) (digitalWrite(__pin, __value))
#define hw_init() Serial.begin(MY_BAUD_RATE) #define hwInit() Serial.begin(MY_BAUD_RATE)
#define hw_watchdogReset() wdt_reset() #define hwWatchdogReset() wdt_reset()
#define hw_reboot() wdt_enable(WDTO_15MS); while (1) #define hwReboot() wdt_enable(WDTO_15MS); while (1)
#define hw_millis() millis() #define hwMillis() millis()
#define hw_readConfig(__pos) (eeprom_read_byte((uint8_t*)(__pos))) #define hwReadConfig(__pos) (eeprom_read_byte((uint8_t*)(__pos)))
#ifndef eeprom_update_byte #ifndef eeprom_update_byte
#define hw_writeConfig(loc, val) if((uint8_t)(val) != eeprom_read_byte((uint8_t*)(loc))) { eeprom_write_byte((uint8_t*)(loc), (val)); } #define hwWriteConfig(loc, val) if((uint8_t)(val) != eeprom_read_byte((uint8_t*)(loc))) { eeprom_write_byte((uint8_t*)(loc), (val)); }
#else #else
#define hw_writeConfig(__pos, __value) (eeprom_update_byte((uint8_t*)(__pos), (__value))) #define hwWriteConfig(__pos, __value) (eeprom_update_byte((uint8_t*)(__pos), (__value)))
#endif #endif
// //
#define hw_readConfigBlock(__buf, __pos, __length) (eeprom_read_block((__buf), (void*)(__pos), (__length))) #define hwReadConfigBlock(__buf, __pos, __length) (eeprom_read_block((__buf), (void*)(__pos), (__length)))
#define hw_writeConfigBlock(__pos, __buf, __length) (eeprom_write_block((void*)(__pos), (void*)__buf, (__length))) #define hwWriteConfigBlock(__pos, __buf, __length) (eeprom_write_block((void*)(__pos), (void*)__buf, (__length)))
@@ -93,28 +92,14 @@ enum period_t
SLEEP_FOREVER SLEEP_FOREVER
}; };
class MyHwATMega328 : public MyHw
{
public:
MyHwATMega328();
/* void init(); void hwSleep(unsigned long ms);
void watchdogReset(); bool hwSleep(uint8_t interrupt, uint8_t mode, unsigned long ms);
void reboot(); uint8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms);
unsigned long millis();
uint8_t readConfig(uint8_t pos);
void writeConfig(uint8_t pos, uint8_t value);
void readConfigBlock(void* buf, void * pos, size_t length);
void writeConfigBlock(void* pos, void* buf, size_t length); */
void sleep(unsigned long ms);
bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms);
uint8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms);
#ifdef MY_DEBUG #ifdef MY_DEBUG
void debugPrint(bool isGW, const char *fmt, ... ); void hwDebugPrint(const char *fmt, ... );
#endif
private:
void internalSleep(unsigned long ms);
};
#endif #endif
void hwInternalSleep(unsigned long ms);
#endif // #ifdef ARDUINO_ARCH_AVR #endif // #ifdef ARDUINO_ARCH_AVR
#endif
+14 -60
View File
@@ -19,7 +19,6 @@
#ifdef ARDUINO_ARCH_ESP8266 #ifdef ARDUINO_ARCH_ESP8266
#include "MyHw.h"
#include "MyHwESP8266.h" #include "MyHwESP8266.h"
#include <EEPROM.h> #include <EEPROM.h>
@@ -43,7 +42,7 @@ ISR (WDT_vect)
} }
*/ */
static void hw_initConfigBlock( size_t length = 1024 /*ATMega328 has 1024 bytes*/ ) static void hwInitConfigBlock( size_t length = 1024 /*ATMega328 has 1024 bytes*/ )
{ {
static bool initDone = false; static bool initDone = false;
if (!initDone) if (!initDone)
@@ -53,7 +52,7 @@ static void hw_initConfigBlock( size_t length = 1024 /*ATMega328 has 1024 bytes*
} }
} }
void hw_readConfigBlock(void* buf, void* adr, size_t length) void hwReadConfigBlock(void* buf, void* adr, size_t length)
{ {
hw_initConfigBlock(); hw_initConfigBlock();
uint8_t* dst = static_cast<uint8_t*>(buf); uint8_t* dst = static_cast<uint8_t*>(buf);
@@ -64,7 +63,7 @@ void hw_readConfigBlock(void* buf, void* adr, size_t length)
} }
} }
void hw_writeConfigBlock(void* buf, void* adr, size_t length) void hwWriteConfigBlock(void* buf, void* adr, size_t length)
{ {
hw_initConfigBlock(); hw_initConfigBlock();
uint8_t* src = static_cast<uint8_t*>(buf); uint8_t* src = static_cast<uint8_t*>(buf);
@@ -76,14 +75,14 @@ void hw_writeConfigBlock(void* buf, void* adr, size_t length)
EEPROM.commit(); EEPROM.commit();
} }
uint8_t hw_readConfig(int adr) uint8_t hwReadConfig(int adr)
{ {
uint8_t value; uint8_t value;
hw_readConfigBlock(&value, reinterpret_cast<void*>(adr), 1); hw_readConfigBlock(&value, reinterpret_cast<void*>(adr), 1);
return value; return value;
} }
void hw_writeConfig(int adr, uint8_t value) void hwWriteConfig(int adr, uint8_t value)
{ {
uint8_t curr = hw_readConfig(adr); uint8_t curr = hw_readConfig(adr);
if (curr != value) if (curr != value)
@@ -94,85 +93,40 @@ void hw_writeConfig(int adr, uint8_t value)
MyHwESP8266::MyHwESP8266() : MyHw()
{
}
void hwSleep(unsigned long ms) {
/*
// The following was redifined as macros to save space
inline uint8_t MyHwATMega328::readConfig(uint8_t pos) {
return eeprom_read_byte((uint8_t*)pos);
}
inline void MyHwATMega328::writeConfig(uint8_t pos, uint8_t value) {
eeprom_update_byte((uint8_t*)pos, value);
}
inline void MyHwATMega328::readConfigBlock(void* buf, void * pos, size_t length) {
eeprom_read_block(buf, (void*)pos, length);
}
inline void MyHwATMega328::writeConfigBlock(void* pos, void* buf, size_t length) {
eeprom_write_block((void*)pos, (void*)buf, length);
}
inline void MyHwATMega328::init() {
Serial.begin(BAUD_RATE);
}
inline void MyHwATMega328::watchdogReset() {
wdt_reset();
}
inline void MyHwATMega328::reboot() {
wdt_enable(WDTO_15MS); for (;;);
}
inline unsigned long MyHwATMega328::millis() {
return ::millis();
}
*/
void MyHwESP8266::sleep(unsigned long ms) {
// TODO: Not supported! // TODO: Not supported!
} }
bool MyHwESP8266::sleep(uint8_t interrupt, uint8_t mode, unsigned long ms) { bool hwSleep(uint8_t interrupt, uint8_t mode, unsigned long ms) {
// TODO: Not supported! // TODO: Not supported!
return false; return false;
} }
inline uint8_t MyHwESP8266::sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms) { uint8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms) {
// TODO: Not supported! // TODO: Not supported!
return 0; return 0;
} }
#ifdef MY_DEBUG #ifdef MY_DEBUG
void MyHwESP8266::debugPrint(bool isGW, const char *fmt, ... ) { void hwDebugPrint(bool isGW, const char *fmt, ... ) {
char fmtBuffer[300]; char fmtBuffer[300];
if (isGW) { #ifdef MY_GATEWAY_FEATURE
// prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE) // prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
snprintf_P(fmtBuffer, 299, PSTR("0;0;%d;0;%d;"), C_INTERNAL, I_LOG_MESSAGE); snprintf_P(fmtBuffer, 299, PSTR("0;0;%d;0;%d;"), C_INTERNAL, I_LOG_MESSAGE);
Serial.print(fmtBuffer); Serial.print(fmtBuffer);
} #endif
va_list args; va_list args;
va_start (args, fmt ); va_start (args, fmt );
va_end (args); va_end (args);
if (isGW) { #ifdef MY_GATEWAY_FEATURE
// Truncate message if this is gateway node // Truncate message if this is gateway node
vsnprintf_P(fmtBuffer, 60, fmt, args); vsnprintf_P(fmtBuffer, 60, fmt, args);
fmtBuffer[59] = '\n'; fmtBuffer[59] = '\n';
fmtBuffer[60] = '\0'; fmtBuffer[60] = '\0';
} else { #else
vsnprintf_P(fmtBuffer, 299, fmt, args); vsnprintf_P(fmtBuffer, 299, fmt, args);
} #endif
va_end (args); va_end (args);
Serial.print(fmtBuffer); Serial.print(fmtBuffer);
Serial.flush(); Serial.flush();
+13 -28
View File
@@ -22,7 +22,6 @@
#ifndef MyHwESP8266_h #ifndef MyHwESP8266_h
#define MyHwESP8266_h #define MyHwESP8266_h
#include "MyHw.h"
#include "MyConfig.h" #include "MyConfig.h"
#include "MyMessage.h" #include "MyMessage.h"
@@ -34,16 +33,16 @@
// Define these as macros to save valuable space // Define these as macros to save valuable space
#define hw_digitalWrite(__pin, __value) (digitalWrite(__pin, __value)) #define hwDigitalWrite(__pin, __value) (digitalWrite(__pin, __value))
#define hw_init() Serial.begin(BAUD_RATE) #define hwInit() Serial.begin(BAUD_RATE)
#define hw_watchdogReset() wdt_reset() #define hwWatchdogReset() wdt_reset()
#define hw_reboot() wdt_enable(WDTO_15MS); while (1) #define hwReboot() wdt_enable(WDTO_15MS); while (1)
#define hw_millis() millis() #define hwMillis() millis()
void hw_readConfigBlock(void* buf, void* adr, size_t length); void hwReadConfigBlock(void* buf, void* adr, size_t length);
void hw_writeConfigBlock(void* buf, void* adr, size_t length); void hwWriteConfigBlock(void* buf, void* adr, size_t length);
void hw_writeConfig(int adr, uint8_t value); void hwWriteConfig(int adr, uint8_t value);
uint8_t hw_readConfig(int adr); uint8_t hwReadConfig(int adr);
enum period_t enum period_t
{ {
@@ -60,27 +59,13 @@ enum period_t
SLEEP_FOREVER SLEEP_FOREVER
}; };
class MyHwESP8266 : public MyHw
{
public:
MyHwESP8266();
/* void init();
void watchdogReset();
void reboot();
unsigned long millis();
uint8_t readConfig(uint8_t pos);
void writeConfig(uint8_t pos, uint8_t value);
void readConfigBlock(void* buf, void * pos, size_t length);
void writeConfigBlock(void* pos, void* buf, size_t length); */
void sleep(unsigned long ms); void hwSleep(unsigned long ms);
bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms); bool hwSleep(uint8_t interrupt, uint8_t mode, unsigned long ms);
uint8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms); uint8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms);
#ifdef MY_DEBUG #ifdef MY_DEBUG
void debugPrint(bool isGW, const char *fmt, ... ); void hwDebugPrint(const char *fmt, ... );
#endif
};
#endif #endif
#endif // #ifdef ARDUINO_ARCH_ESP8266 #endif // #ifdef ARDUINO_ARCH_ESP8266
File diff suppressed because it is too large Load Diff
+155 -272
View File
@@ -23,9 +23,7 @@
#include "Version.h" // Auto generated by bot #include "Version.h" // Auto generated by bot
#include "MyConfig.h" #include "MyConfig.h"
#include "MyHw.h"
#include "MyTransport.h" #include "MyTransport.h"
#include "MyTransportNRF24.h"
#ifdef MY_SIGNING_FEATURE #ifdef MY_SIGNING_FEATURE
#include "MySigning.h" #include "MySigning.h"
#include "MySigningNone.h" #include "MySigningNone.h"
@@ -35,25 +33,14 @@
#include "drivers/SPIFlash/SPIFlash.h" #include "drivers/SPIFlash/SPIFlash.h"
#endif #endif
#include "MyGatewayTransport.h"
#include "MyGatewayTransportSerial.h"
#include <stddef.h> #include <stddef.h>
#include <stdarg.h> #include <stdarg.h>
// Set the hardware driver to use (initialized by MySensor-class)
#if defined(ARDUINO_ARCH_ESP8266)
#include "MyHwESP8266.h"
typedef MyHwESP8266 MyHwDriver;
#elif defined(ARDUINO_ARCH_AVR)
#include "MyHwATMega328.h"
typedef MyHwATMega328 MyHwDriver;
#endif
#ifdef MY_DEBUG #ifdef MY_DEBUG
#define debug(x,...) hw.debugPrint(isGateway, x, ##__VA_ARGS__) #define debug(x,...) hwDebugPrint(x, ##__VA_ARGS__)
#else #else
#define debug(x,...) #define debug(x,...)
#endif #endif
@@ -146,179 +133,165 @@ typedef struct {
} __attribute__((packed)) ReplyFWBlock; } __attribute__((packed)) ReplyFWBlock;
#ifdef __cplusplus
class MySensor
{
public:
/**
* Constructor
*
* Creates a new instance of Sensor class.
*
*/
MySensor(MyTransport &radio =*new MyTransportNRF24(), MyHw &hw=*new MyHwDriver()
#ifdef MY_SIGNING_FEATURE
, MySigning &signer=*new MySigningNone()
#endif
);
/** /**
* Begin operation of the MySensors library * Begin operation of the MySensors library
* *
* Call this in setup(), before calling any other sensor net library methods. * Call this in setup(), before calling any other sensor net library methods.
* @param incomingMessageCallback Callback function for incoming messages from other nodes or controller and request responses. Default is NULL. * @param incomingMessageCallback Callback function for incoming messages from other nodes or controller and request responses. Default is NULL.
* @param nodeId The unique id (1-254) for this sensor. Default is AUTO(255) which means sensor tries to fetch an id from controller. */
* @param repeaterMode Activate repeater mode. This node will forward messages to other nodes in the radio network. Make sure to call process() regularly. Default in false
* @param parentNodeId Use this to force node to always communicate with a certain parent node. Default is AUTO which means node automatically tries to find a parent.
*/
void begin(void (* msgCallback)(const MyMessage &)=NULL, uint8_t nodeId=AUTO, boolean repeaterMode=false, uint8_t parentNodeId=AUTO);
/**
* Return the nodes nodeId.
*/
uint8_t getNodeId();
/**
* Each node must present all attached sensors before any values can be handled correctly by the controller.
* It is usually good to present all attached sensors after power-up in setup().
*
* @param sensorId Select a unique sensor id for this sensor. Choose a number between 0-254.
* @param sensorType The sensor type. See sensor typedef in MyMessage.h.
* @param description A textual description of the sensor.
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @param description A textual description of the sensor.
*/
void present(uint8_t sensorId, uint8_t sensorType, const char *description="", bool ack=false);
/**
* Sends sketch meta information to the gateway. Not mandatory but a nice thing to do.
* @param name String containing a short Sketch name or NULL if not applicable
* @param version String containing a short Sketch version or NULL if not applicable
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
*
*/
void sendSketchInfo(const char *name, const char *version, bool ack=false);
/**
* Sends a message to gateway or one of the other nodes in the radio network
*
* @param msg Message to send
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool send(MyMessage &msg, bool ack=false);
/** void dataCallback(void (* msgCallback)(const MyMessage &)=NULL);
* Send this nodes battery level to gateway.
* @param level Level between 0-100(%)
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
*
*/
void sendBatteryLevel(uint8_t level, bool ack=false);
/** /**
* Send a heartbeat message (I'm alive!) to the gateway/controller. * Return the nodes nodeId.
* The payload will be an incremental 16 bit integer value starting at 1 when sensor is powered on. */
*/ uint8_t getNodeId();
void sendHeartbeat(void);
/** /**
* Requests a value from gateway or some other sensor in the radio network. * Each node must present all attached sensors before any values can be handled correctly by the controller.
* Make sure to add callback-method in begin-method to handle request responses. * It is usually good to present all attached sensors after power-up in setup().
* *
* @param childSensorId The unique child id for the different sensors connected to this Arduino. 0-254. * @param sensorId Select a unique sensor id for this sensor. Choose a number between 0-254.
* @param variableType The variableType to fetch * @param sensorType The sensor type. See sensor typedef in MyMessage.h.
* @param destination The nodeId of other node in radio network. Default is gateway * @param description A textual description of the sensor.
*/ * @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
void request(uint8_t childSensorId, uint8_t variableType, uint8_t destination=GATEWAY_ADDRESS); * @param description A textual description of the sensor.
*/
void present(uint8_t sensorId, uint8_t sensorType, const char *description="", bool ack=false);
/** /**
* Requests time from controller. Answer will be delivered to callback. * Sends sketch meta information to the gateway. Not mandatory but a nice thing to do.
* * @param name String containing a short Sketch name or NULL if not applicable
* @param callback for time request. Incoming argument is seconds since 1970. * @param version String containing a short Sketch version or NULL if not applicable
*/ * @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
void requestTime(void (* timeCallback)(unsigned long)); *
*/
void sendSketchInfo(const char *name, const char *version, bool ack=false);
/**
* Sends a message to gateway or one of the other nodes in the radio network
*
* @param msg Message to send
* @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
* @return true Returns true if message reached the first stop on its way to destination.
*/
bool send(MyMessage &msg, bool ack=false);
/** /**
* Processes incoming messages to this node. If this is a relaying node it will * Send this nodes battery level to gateway.
* Returns true if there is a message addressed for this node just was received. * @param level Level between 0-100(%)
* Use callback to handle incoming messages. * @param ack Set this to true if you want destination node to send ack back to this node. Default is not to request any ack.
*/ *
boolean process(); */
void sendBatteryLevel(uint8_t level, bool ack=false);
/** /**
* Returns the most recent node configuration received from controller * Send a heartbeat message (I'm alive!) to the gateway/controller.
*/ * The payload will be an incremental 16 bit integer value starting at 1 when sensor is powered on.
ControllerConfig getConfig(); */
void sendHeartbeat(void);
/** /**
* Save a state (in local EEPROM). Good for actuators to "remember" state between * Requests a value from gateway or some other sensor in the radio network.
* power cycles. * Make sure to add callback-method in begin-method to handle request responses.
* *
* You have 256 bytes to play with. Note that there is a limitation on the number * @param childSensorId The unique child id for the different sensors connected to this Arduino. 0-254.
* of writes the EEPROM can handle (~100 000 cycles on ATMega328). * @param variableType The variableType to fetch
* * @param destination The nodeId of other node in radio network. Default is gateway
* @param pos The position to store value in (0-255) */
* @param Value to store in position void request(uint8_t childSensorId, uint8_t variableType, uint8_t destination=GATEWAY_ADDRESS);
*/
void saveState(uint8_t pos, uint8_t value);
/** /**
* Load a state (from local EEPROM). * Requests time from controller. Answer will be delivered to callback.
* *
* @param pos The position to fetch value from (0-255) * @param callback for time request. Incoming argument is seconds since 1970.
* @return Value to store in position */
*/ void requestTime(void (* timeCallback)(unsigned long));
uint8_t loadState(uint8_t pos);
/**
* Returns the last received message
*/
MyMessage& getLastMessage(void);
/** /**
* Wait for a specified amount of time to pass. Keeps process()ing. * Returns the most recent node configuration received from controller
* This does not power-down the radio nor the Arduino. */
* Because this calls process() in a loop, it is a good way to wait ControllerConfig getConfig();
* in your loop() on a repeater node or sensor that listens to messages.
* @param ms Number of milliseconds to sleep.
*/
void wait(unsigned long ms);
/** /**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer. * Save a state (in local EEPROM). Good for actuators to "remember" state between
* @param ms Number of milliseconds to sleep. * power cycles.
*/ *
void sleep(unsigned long ms); * You have 256 bytes to play with. Note that there is a limitation on the number
* of writes the EEPROM can handle (~100 000 cycles on ATMega328).
*
* @param pos The position to store value in (0-255)
* @param Value to store in position
*/
void saveState(uint8_t pos, uint8_t value);
/** /**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer or pin change. * Load a state (from local EEPROM).
* See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin *
* is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3 * @param pos The position to fetch value from (0-255)
* @param interrupt Interrupt that should trigger the wakeup * @return Value to store in position
* @param mode RISING, FALLING, CHANGE */
* @param ms Number of milliseconds to sleep or 0 to sleep forever uint8_t loadState(uint8_t pos);
* @return true if wake up was triggered by pin change and false means timer woke it up.
*/
bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms=0);
/** /**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer or pin change for two separate interrupts. * Returns the last received message
* See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin */
* is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3 MyMessage& getLastMessage(void);
* @param interrupt1 First interrupt that should trigger the wakeup
* @param mode1 Mode for first interrupt (RISING, FALLING, CHANGE)
* @param interrupt2 Second interrupt that should trigger the wakeup
* @param mode2 Mode for second interrupt (RISING, FALLING, CHANGE) /**
* @param ms Number of milliseconds to sleep or 0 to sleep forever * Wait for a specified amount of time to pass. Keeps process()ing.
* @return Interrupt number wake up was triggered by pin change and negative if timer woke it up. * This does not power-down the radio nor the Arduino.
*/ * Because this calls process() in a loop, it is a good way to wait
int8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms=0); * in your loop() on a repeater node or sensor that listens to messages.
* @param ms Number of milliseconds to sleep.
*/
void wait(unsigned long ms);
/**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer.
* @param ms Number of milliseconds to sleep.
*/
void sleep(unsigned long ms);
/**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer or pin change.
* See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin
* is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3
* @param interrupt Interrupt that should trigger the wakeup
* @param mode RISING, FALLING, CHANGE
* @param ms Number of milliseconds to sleep or 0 to sleep forever
* @return true if wake up was triggered by pin change and false means timer woke it up.
*/
bool sleep(uint8_t interrupt, uint8_t mode, unsigned long ms=0);
/**
* Sleep (PowerDownMode) the MCU and radio. Wake up on timer or pin change for two separate interrupts.
* See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin
* is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3
* @param interrupt1 First interrupt that should trigger the wakeup
* @param mode1 Mode for first interrupt (RISING, FALLING, CHANGE)
* @param interrupt2 Second interrupt that should trigger the wakeup
* @param mode2 Mode for second interrupt (RISING, FALLING, CHANGE)
* @param ms Number of milliseconds to sleep or 0 to sleep forever
* @return Interrupt number wake up was triggered by pin change and negative if timer woke it up.
*/
int8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms=0);
/****** PRIVATE ********/
void begin();
void process(void);
void processInternalMessages();
#ifdef MY_LEDS_BLINKING_FEATURE #ifdef MY_LEDS_BLINKING_FEATURE
/** /**
@@ -328,121 +301,31 @@ class MySensor
void rxBlink(uint8_t cnt); void rxBlink(uint8_t cnt);
void txBlink(uint8_t cnt); void txBlink(uint8_t cnt);
void errBlink(uint8_t cnt); void errBlink(uint8_t cnt);
#endif
boolean sendRoute(MyMessage &message);
protected:
NodeConfig nc; // Essential settings for node to work
ControllerConfig cc; // Configuration coming from controller
#ifdef MY_OTA_FIRMWARE_FEATURE
NodeFirmwareConfig fc;
bool fwUpdateOngoing;
unsigned long fwLastRequestTime;
uint16_t fwBlock;
uint8_t fwRetry;
SPIFlash flash;
#endif
bool repeaterMode;
bool autoFindParent;
bool isGateway;
MyMessage msg; // Buffer for incoming messages.
MyMessage tmpMsg ; // Buffer for temporary messages (acks and nonces among others).
#ifdef MY_LEDS_BLINKING_FEATURE
// these variables don't need to be volatile, since we are not using interrupts
uint8_t countRx;
uint8_t countTx;
uint8_t countErr;
void handleLedsBlinking(); // do the actual blinking void handleLedsBlinking(); // do the actual blinking
unsigned long blink_next_time;
#endif #endif
MyTransport& radio;
#ifdef MY_SIGNING_FEATURE
uint16_t doSign[16]; // Bitfield indicating which sensors require signed communication
MyMessage msgSign; // Buffer for message to sign.
MySigning& signer;
#endif
MyHw& hw;
boolean sendWrite(uint8_t dest, MyMessage &message);
void processInternalMessages(MyMessage &msg);
#ifdef MY_DEBUG
char convBuf[MAX_PAYLOAD*2+1];
#endif
uint8_t failedTransmissions;
uint16_t heartbeat;
void (*timeCallback)(unsigned long); // Callback for requested time messages
void (*msgCallback)(const MyMessage &); // Callback for incoming messages from other nodes and gateway.
#ifdef MY_OTA_FIRMWARE_FEATURE #ifdef MY_OTA_FIRMWARE_FEATURE
// do a crc16 on the whole received firmware // do a crc16 on the whole received firmware
bool isValidFirmware(); bool isValidFirmware();
#endif #endif
private:
void requestNodeId();
void setupNode();
void findParentNode();
uint8_t crc8Message(MyMessage &message);
};
#endif
class MyGateway : public MySensor
{
public:
// MyProtocolSerial constructor
MyGateway(MyGatewayTransport &transport=*new MyGatewayTransportSerial(), MyTransport &radio =*new MyTransportNRF24(), MyHw &hw=*new MyHwDriver()
#ifdef MY_SIGNING_FEATURE
, MySigning &signer=*new MySigningNone()
#endif
);
/**
* Begin operation of the MySensors library
*
* Call this in setup(), before calling any other sensor net library methods.
* @param incomingMessageCallback Callback function for incoming messages from other nodes or controller and request responses. Default is NULL.
* @param inclusionModeDuration Number of milliseconds inclusion mode should be enabled
* @param inclusionModeButtonPin Button pin used for enabling inclusion mode
*/
void begin(void (* msgCallback)(const MyMessage &)=NULL);
/**
* See MySensor.h
*
* Overloaded to handle local sensor data sent to controller.
*/
boolean sendRoute(MyMessage &message);
/**
* Processes incoming messages to this node.
* Returns true if there is a message addressed for this node was received.
* Preferred way of handling incoming messages is to use the callback defined in begin().
*/
boolean process();
private:
MyGatewayTransport& transport;
#ifdef MY_INCLUSION_MODE_FEATURE #ifdef MY_INCLUSION_MODE_FEATURE
void setInclusionMode(bool newMode); void setInclusionMode(bool newMode);
void checkInclusionMode(); void checkInclusionMode();
unsigned long inclusionStartTime; unsigned long inclusionStartTime;
bool inclusionMode; bool inclusionMode;
#endif #endif
};
boolean sendRoute(MyMessage &message);
#if defined(MY_RADIO_FEATURE)
boolean sendWrite(uint8_t dest, MyMessage &message);
void requestNodeId();
void setupNode();
void findParentNode();
#endif
#endif #endif
@@ -20,11 +20,10 @@
#include "MyTransport.h" #include "MyTransport.h"
#include "MyTransportNRF24.h" #include "MyTransportNRF24.h"
MyTransportNRF24::MyTransportNRF24(uint8_t ce, uint8_t cs, uint8_t paLevel) MyTransportNRF24::MyTransportNRF24()
: :
MyTransport(), MyTransport(),
rf24(ce, cs), rf24(MY_RF24_CE_PIN, MY_RF24_CS_PIN)
_paLevel(paLevel)
{ {
} }
@@ -38,9 +37,9 @@ bool MyTransportNRF24::init() {
rf24.setAutoAck(1); rf24.setAutoAck(1);
rf24.setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast rf24.setAutoAck(BROADCAST_PIPE,false); // Turn off auto ack for broadcast
rf24.enableAckPayload(); rf24.enableAckPayload();
rf24.setChannel(RF24_CHANNEL); rf24.setChannel(MY_RF24_CHANNEL);
rf24.setPALevel(_paLevel); rf24.setPALevel(_paLevel);
rf24.setDataRate(RF24_DATARATE); rf24.setDataRate(MY_RF24_DATARATE);
rf24.setRetries(5,15); rf24.setRetries(5,15);
rf24.setCRCLength(RF24_CRC_16); rf24.setCRCLength(RF24_CRC_16);
rf24.enableDynamicPayloads(); rf24.enableDynamicPayloads();
+2 -2
View File
@@ -26,7 +26,7 @@
#include "drivers/RF24/RF24.h" #include "drivers/RF24/RF24.h"
#include "drivers/RF24/RF24_config.h" #include "drivers/RF24/RF24_config.h"
#define TO_ADDR(x) (RF24_BASE_RADIO_ID + x) #define TO_ADDR(x) (MY_RF24_BASE_RADIO_ID + x)
#define WRITE_PIPE ((uint8_t)0) #define WRITE_PIPE ((uint8_t)0)
#define CURRENT_NODE_PIPE ((uint8_t)1) #define CURRENT_NODE_PIPE ((uint8_t)1)
@@ -35,7 +35,7 @@
class MyTransportNRF24 : public MyTransport class MyTransportNRF24 : public MyTransport
{ {
public: public:
MyTransportNRF24(uint8_t ce=RF24_CE_PIN, uint8_t cs=RF24_CS_PIN, uint8_t paLevel=RF24_PA_LEVEL); MyTransportNRF24();
bool init(); bool init();
void setAddress(uint8_t address); void setAddress(uint8_t address);
uint8_t getAddress(); uint8_t getAddress();
@@ -20,18 +20,16 @@
#include "MyTransport.h" #include "MyTransport.h"
#include "MyTransportRFM69.h" #include "MyTransportRFM69.h"
MyTransportRFM69::MyTransportRFM69(uint8_t freqBand, uint8_t networkId, uint8_t slaveSelectPin, uint8_t interruptPin, bool isRFM69HW, uint8_t interruptNum) MyTransportRFM69::MyTransportRFM69()
: :
MyTransport(), MyTransport(),
radio(slaveSelectPin, interruptPin, isRFM69HW, interruptNum), radio(MY_RF69_SPI_CS, MY_RF69_IRQ_PIN, MY_IS_RFM69HW, MY_RF69_IRQ_NUM)
_freqBand(freqBand),
_networkId(networkId)
{ {
} }
bool MyTransportRFM69::init() { bool MyTransportRFM69::init() {
// Start up the radio library (_address will be set later by the MySensors library) // Start up the radio library (_address will be set later by the MySensors library)
radio.initialize(_freqBand, _address, _networkId); radio.initialize(MY_RFM69_FREQUENCY, _address, MY_RFM69_NETWORKID);
#ifdef MY_RFM69_ENABLE_ENCRYPTION #ifdef MY_RFM69_ENABLE_ENCRYPTION
radio.encrypt(RFM69_ENCRYPTKEY); radio.encrypt(RFM69_ENCRYPTKEY);
#endif #endif
+1 -3
View File
@@ -30,7 +30,7 @@
class MyTransportRFM69 : public MyTransport class MyTransportRFM69 : public MyTransport
{ {
public: public:
MyTransportRFM69(uint8_t freqBand=MY_RFM69_FREQUENCY, uint8_t networkId=MY_RFM69_NETWORKID, uint8_t slaveSelectPin=MY_RF69_SPI_CS, uint8_t interruptPin=MY_RF69_IRQ_PIN, bool isRFM69HW=false, uint8_t interruptNum=MY_RF69_IRQ_NUM); MyTransportRFM69();
bool init(); bool init();
void setAddress(uint8_t address); void setAddress(uint8_t address);
uint8_t getAddress(); uint8_t getAddress();
@@ -41,8 +41,6 @@ public:
private: private:
RFM69 radio; RFM69 radio;
uint8_t _address; uint8_t _address;
uint8_t _freqBand;
uint8_t _networkId;
}; };
#endif #endif
@@ -28,9 +28,9 @@
/** DigitalPin version YYYYMMDD */ /** DigitalPin version YYYYMMDD */
#define DIGITAL_IO_VERSION 20140217 #define DIGITAL_IO_VERSION 20140217
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#include <DigitalPin.h> #include "DigitalPin.h"
#include <I2cConstants.h> #include "I2cConstants.h"
#include <PinIO.h> #include "PinIO.h"
#include <SoftI2cMaster.h> #include "SoftI2cMaster.h"
#include <SoftSPI.h> #include "SoftSPI.h"
#endif // DigitalIO_h #endif // DigitalIO_h
@@ -25,7 +25,7 @@
* @details Two Wire Interface library. * @details Two Wire Interface library.
* @{ * @{
*/ */
#include <PinIO.h> #include "PinIO.h"
#include <util/atomic.h> #include <util/atomic.h>
#include <Arduino.h> #include <Arduino.h>
//============================================================================== //==============================================================================
@@ -25,7 +25,7 @@
* @details Software Two Wire Interface library. * @details Software Two Wire Interface library.
* @{ * @{
*/ */
#include <SoftI2cMaster.h> #include "SoftI2cMaster.h"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** /**
* Start an I2C transfer with possible continuation. * Start an I2C transfer with possible continuation.
@@ -33,8 +33,8 @@
#include <Arduino.h> #include <Arduino.h>
#endif // ARDUINO #endif // ARDUINO
#include <util/delay_basic.h> #include <util/delay_basic.h>
#include <DigitalPin.h> #include "DigitalPin.h"
#include <I2cConstants.h> #include "I2cConstants.h"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// State codes. // State codes.
@@ -28,7 +28,7 @@
#ifndef SoftSPI_h #ifndef SoftSPI_h
#define SoftSPI_h #define SoftSPI_h
#include <DigitalPin.h> #include "DigitalPin.h"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/** Nop for timing. */ /** Nop for timing. */
#define nop asm volatile ("nop\n\t") #define nop asm volatile ("nop\n\t")
+1 -1
View File
@@ -19,7 +19,7 @@ void RF24::csn(bool mode)
// divider of 4 is the minimum we want. // divider of 4 is the minimum we want.
// CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz // CLK:BUS 8Mhz:2Mhz, 16Mhz:4Mhz, or 20Mhz:5Mhz
#ifdef ARDUINO #ifdef ARDUINO
#if ( !defined(RF24_TINY) && !defined (__arm__) && !defined (SOFTSPI)) || defined (CORE_TEENSY) #if ( !defined(RF24_TINY) && !defined (__arm__) && !defined (MY_SOFTSPI)) || defined (CORE_TEENSY)
_SPI.setBitOrder(MSBFIRST); _SPI.setBitOrder(MSBFIRST);
_SPI.setDataMode(SPI_MODE0); _SPI.setDataMode(SPI_MODE0);
_SPI.setClockDivider(SPI_CLOCK_DIV2); _SPI.setClockDivider(SPI_CLOCK_DIV2);
@@ -26,7 +26,7 @@
//#define SERIAL_DEBUG //#define SERIAL_DEBUG
#define MINIMAL #define MINIMAL
//#define SPI_UART // Requires library from https://github.com/TMRh20/Sketches/tree/master/SPI_UART //#define SPI_UART // Requires library from https://github.com/TMRh20/Sketches/tree/master/SPI_UART
//#define SOFTSPI // Requires library from https://github.com/greiman/DigitalIO //#define MY_SOFTSPI // Requires library from https://github.com/greiman/DigitalIO
/**********************/ /**********************/
// Define _BV for non-Arduino platforms and for Arduino DUE // Define _BV for non-Arduino platforms and for Arduino DUE
@@ -56,15 +56,61 @@
* *
*/ */
// Enable debug prints to console
#define MY_DEBUG
// This node has a NR24L01+ radio attached
#define MY_RADIO_NRF24
// W5100 Ethernet in client mode (node opens conmection to controller)
#define MY_GATEWAY_W5100_CLIENT
// W5100 Ethernet in client mode (controller opens conmection to node)
//#define MY_GATEWAY_W5100_SERVER
// Set default gateway protocol (http://www.mysensors.org/download/serial_api_15)
#define MY_GATEWAY_PROTOCOL_DEFAULT
// Enable Soft SPI for radio (note different radio wiring required)
// Useful for W5100 which sometimes have hard time co-operate with radio on the same spi bus.
//#define MY_SOFTSPI
//#define MY_SOFT_SPI_SCK_PIN 14
//#define MY_SOFT_SPI_MISO_PIN 16
//#define MY_SOFT_SPI_MOSI_PIN 15
// Enable to use UDP
#define MY_USE_UDP
#define MY_IP_ADDRESS 192,168,178,66 // If this is disabled, DHCP is used to retrieve address
// Renewal period if using DHCP
//#define MY_IP_RENEWAL_INTERVAL 60000
// The port to keep open on node server mode / or port to contact in client mode
#define MY_PORT 5003
// Controller ip address (client mode)
#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 254
// The port you want to contact on controller (client mode)
#define MY_CONTROLLER_PORT 5003
// The MAC address can be anything you want but should be unique on your network.
// Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
// Note that most of the Ardunio examples use "DEAD BEEF FEED" for the MAC address.
#define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
// Flash leds on rx/tx/err
#define MY_WITH_LEDS_BLINKING #define MY_WITH_LEDS_BLINKING
#define MY_INCLUSION_MODE_FEATURE // Set blinking period
#define MY_INCLUSION_BUTTON_FEATURE
#define MY_DEFAULT_LED_BLINK_PERIOD 300 #define MY_DEFAULT_LED_BLINK_PERIOD 300
#define MY_INCLUSION_MODE_DURATION 60 // Number of minutes inclusion mode is enabled // Enable inclusion mode
#define MY_INCLUSION_MODE_BUTTON_PIN 3 // Digital pin used for inclusion mode button #define MY_INCLUSION_MODE_FEATURE
// Enable Inclusion mode button on gateway
#define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN 3
#define MY_DEFAULT_ERR_LED_PIN 7 // Error led pin #define MY_DEFAULT_ERR_LED_PIN 7 // Error led pin
#define MY_DEFAULT_RX_LED_PIN 8 // Receive led pin #define MY_DEFAULT_RX_LED_PIN 8 // Receive led pin
@@ -76,53 +122,11 @@
#include <MySensor.h> #include <MySensor.h>
#define MY_IP_PORT 5003 // The port you want to open
#ifndef MY_IP_ADDRESS_DHCP
// Gateway IP address if not using DHCP
IPAddress myIp (192, 168, 178, 66); // Configure your static ip-address here COMPILE ERROR HERE? Use Arduino IDE 1.5.7 or later!
#endif /* IP_ADDRESS_DHCP */
// NRFRF24L01 radio driver (set low transmit power by default)
MyTransportNRF24 transport(RADIO_CE_PIN, RADIO_SPI_SS_PIN, RF24_PA_LEVEL_GW);
//MyTransportRFM69 transport;
// Message signing driver (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
//MySigningNone signer;
//MySigningAtsha204Soft signer;
//MySigningAtsha204 signer;
// Hardware profile
MyHwATMega328 hw;
// Use default controller protocol
MyProtocolDefault protocol;
// The MAC address can be anything you want but should be unique on your network.
// Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
// Note that most of the Ardunio examples use "DEAD BEEF FEED" for the MAC address.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // DEAD BEEF FEED
// Controller IP
IPAddress controllerIP = IPAddress(192, 168, 178, 254);
// Gateway transport driver
#ifdef IP_ADDRESS_DHCP
MyGatewayTransportEthernet ctrlTransport(protocol, mac, /* gw port */ CONTROLLER_PORT, IP_RENEWAL_INTERVAL, controllerIP, CONTROLLER_PORT);
#else
MyGatewayTransportEthernet ctrlTransport(protocol, mac, myIp, /* gw port */ CONTROLLER_PORT, controllerIP, CONTROLLER_PORT);
#endif
// Construct MyGateway library (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
// To use LEDs blinking, uncomment MY_LEDS_BLINKING_FEATURE in MyConfig.h
MyGateway gw(ctrlTransport, transport, hw /*, signer*/);
void setup() void setup()
{ {
gw.begin(NULL); dataCallback();
} }
void loop() { void loop() {
gw.process();
} }
@@ -28,8 +28,14 @@
*/ */
//#define MY_DEBUG //#define MY_DEBUG
//#define MY_SOFTSPI
//#define MY_OTA_FIRMWARE_FEATURE
#define MY_RADIO_NRF24 // MY_RADIO_RFM69
#include <MySensor.h>
#include "MySensor.h"
unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds) unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!)
@@ -43,14 +49,14 @@ MyMessage msg(CHILD_ID, V_TRIPPED);
void setup() void setup()
{ {
gw.begin(); dataDallback();
// Send the sketch version information to the gateway and Controller // Send the sketch version information to the gateway and Controller
gw.sendSketchInfo("Motion Sensor", "1.0"); sendSketchInfo("Motion Sensor", "1.0");
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
// Register all sensors to gw (they will be created as child devices) // Register all sensors to gw (they will be created as child devices)
gw.present(CHILD_ID, S_MOTION); present(CHILD_ID, S_MOTION);
} }
@@ -60,10 +66,10 @@ void loop()
boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
Serial.println(tripped); Serial.println(tripped);
gw.send(msg.set(tripped?"1":"0")); // Send tripped value to gw send(msg.set(tripped?"1":"0")); // Send tripped value to gw
// Sleep until interrupt comes in on motion sensor. Send update every two minute. // Sleep until interrupt comes in on motion sensor. Send update every two minute.
gw.sleep(INTERRUPT,CHANGE, SLEEP_TIME); sleep(INTERRUPT,CHANGE, SLEEP_TIME);
} }