Happy Xmas to all forum users!
I need your help to focus and solve my troubles about NRF24, signing and Arduinos (UNO and nanos).
Previously I did start another discussion about this, opening a new one 'cause I did collect other infos and I would restart the discussion from zero.
Preamble > My environment
** Controller + Gateway **
Domoticz as controller on a Raspberry PI2 + Arduino UNO as gateway + NRF24L01+ PA/LNA. Antenna is powered from a socket getting 5V from PI Gpio and converted to 3V3. PI itself is powered with a charger 5V / 2A. UNO has write in EEPROM a fixed software serial from the security personalizer sketch and shares the same AES KEY for all nodes.
Current image of setup:
** Nodes **
I have 4 nodes with SI7021, custom PCBs, battery powered without boosters. NO signing, no security. They works perfectly.
Software: they have a software serial and share the same AES KEY with all other nodes.
3 of them have NRF24 black, I think counterfeit, but with 47uF caps on 3v3 and gnd. 1 of them has another type of NRF24, "red aliexpress version", with 47uF caps like others.
This is the "red" version:
Heater commander relay node
As name says, it's a node with a SI7021 + relay (based on secture actuator) that poweron the heater. It is on a custom PCB.
Software: has a software serial and share the same AES KEY with all other nodes.
You can see DOUBLE caps on it. Cap on the antenna + caps on the PCB (47uF + 0.1uF). Powered from a 5V / 2A Samsung charger (you can see the AMS converting the 5V to 3v3 and TPs, voltage are perfect) it works perfectly with UNO gateway.
That antenna was for testing solder, before mount on the wall. Now it has this kind of antenna:
It has security and whitelisting. Only because I don't want that another familty with mysensors could poweron my heater .
The big troubles
1 - If I swap the Antennas (BLACK LNA on relay node and GREEN on the gateway), security doesn't work. Period. Node relay wait for infinite for the nonce from gateway. I have 2x green and 4x black. I did try ALL antenna in every combination. No possibility to work.
The log is:
19544 Nonce requested from 0. Waiting...
24549 Timeout waiting for nonce!
2 - Sketch for Relay is a bit "fat". Uses 85% of memory. Cannot "put to diet". If I enable DEBUG + DEBUG SIGNING, it wait for infinite for
2134 Waiting for GW to send signing preferences...
The issues goes away when I comment both DEBUG or only the DEBUG_SIGNING. So, for debugging, need to remove the library for SI7021 and it's functions. Not very handly.
3 - Yesterday I did change the UNO with a NANO (on the gateway). Used same antenna and same power shield (5V from PI > 3v3 to antenna). Security signing stop working. After some restart of relay secure node, got the signing working. Of course, I did personalized with same serial software of the UNO and the AES KEY. From an hardware view, I did "swap" an ATMEGA328 with another with same, same, same configuration. No reason to break the environment.
For the moment (12h) all works, with the NANO. I cannot explain reason for relay node to make about 30/40 reset before re-start.
So, now my questions.
- This is the GATEWAY UNO/NANO sketch. Based on the (looooong) preamble, is it right?
TL;DR:
- 1 gateway, software signing + software serial + aes key
- 4 temperature nodes without security
- 1 relay node with security
// Enable debug prints to serial monitor
#define MY_DEBUG
#define MY_DEBUG_VERBOSE_SIGNING //!< Enable signing related debug prints to serial monitor
// Enable and select radio type attached
#define MY_RADIO_NRF24
// Enable serial gateway
#define MY_GATEWAY_SERIAL
#define MY_RF24_CHANNEL 125
#define MY_SIGNING_SOFT
#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
#define MY_SIGNING_REQUEST_SIGNATURES
#include <MySensors.h>
#include <avr/wdt.h>
void setup()
{
// Setup locally attached sensors
wdt_enable(WDTO_2S);
}
void presentation()
{
// Present locally attached sensors
}
void loop()
{
// Send locally attached sensor data here
wdt_reset();
}
2 - This is the RELAY secure sketch, reporting the temp and relay state. It is a bit fat, use 85% of resource and cannot enable DEBUG_SIGNING without removing the SI7021 library. Is it possible to put to diet?
* DEFINE MYSENSORS SECTION
*/
//#define MY_DEBUG // Enable Basic Debug
//#define MY_DEBUG_VERBOSE_SIGNING // Enable Signing Debug
#define MY_RADIO_NRF24
#define MY_RF24_CHANNEL 125
#define MY_TRANSPORT_WAIT_READY_MS (5000)
#define MY_SIGNING_SOFT
#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
#define MY_SIGNING_REQUEST_SIGNATURES
#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x3B,0xF4,0x61,0xDF,0x1E,0x97,0xB1,0x2D,0xEC}}} // corretto!!!
#define MY_NODE_ID 4 // Default ID
#define MY_DEFAULT_LED_BLINK_PERIOD 300
#define MY_WITH_LEDS_BLINKING_INVERSE
#define MY_DEFAULT_ERR_LED_PIN 16
#define MY_DEFAULT_TX_LED_PIN 15
#define MY_DEFAULT_RX_LED_PIN 14
#define MY_BAUD_RATE 57600
/*
* Relay section
*/
#define RELAY_ON 1 // If logic of relay is inverted, invert here
#define RELAY_OFF 0 // If logic of relay is inverted, invert here
/**
* PIN section
*/
#define PIN_RELAY 4
/**
* Include libraries
*/
#include <MySensors.h>
#include "Adafruit_Si7021.h"
#include <avr/wdt.h>
/**
* Define section.
*
* // NAME
*/
#define SKETCH_NAME "Termostato - I2C+Relay"
#define SKETCH_VERSION "2.2"
// CHILD ID
#define CHILD_ID_TEMP 0
#define CHILD_ID_HUM 1
#define CHILD_ID_RELAY 2
// initialize the sensor
Adafruit_Si7021 sensor = Adafruit_Si7021();
bool is_first_start = true;
// offset of temperature
float temperature_offset = -1.5;
// the max temperature, after which automatically shutdown
float max_temperature = 23;
// storing for millis
unsigned long previous_millis = 0; // will store last time loop was executed
// constants won't change:
const long interval = 120000; // interval at which to make the loop (milliseconds)
// finally simply wait
// 1000 millisecondi = 1 sec
// 1000 * 30 sec = 30000 = 30 sec
// 1000 * 60 sec = 60000 = 1 minuto
// 60000 * 2 = 120000 milli = 2 minuti
// 60000 * 5 = 300000 millisecondi = 5 minuti
//wait(120000);
//wait(1000);
#define MAX_RETRY_SEND_BEFORE_DELAY 30 // after this try, it will call delay
/**
* Mysensors message
*/
// Initialize temperature message
MyMessage msg_temperature(CHILD_ID_TEMP , V_TEMP);
// Initialize humidity message
MyMessage msg_humidity(CHILD_ID_HUM , V_HUM);
// Initialize relay message
MyMessage msg_relay(CHILD_ID_RELAY , V_STATUS);
/**
* Presentation.
*
* Presents the child to the controller
*
* @since 1.0
*
*/
void presentation() {
// send sketch name
sendSketchInfo(SKETCH_NAME , SKETCH_VERSION);
// Present all sensors to controller.
// TEMPERATURE
present(CHILD_ID_TEMP, S_TEMP);
// HUMIDITY
present(CHILD_ID_HUM , S_HUM);
// RELAY
present(CHILD_ID_RELAY , S_BINARY);
}
/**
* Our Setup
*
* @since 1.0
*/
void setup() {
// enable Watchdog to 2 seconds
wdt_enable(WDTO_2S);
// send a serial output to advice
Serial.println("================================");
Serial.println("=====>>>> Start sketch <<<<=====");
Serial.println("================================");
// Initialize relay
initializeRelay();
// Initialize sensor
sensor.begin(); // si7021
}
/**
* Relay initialization
*
* @since 1.0
*/
void initializeRelay() {
pinMode(PIN_RELAY , OUTPUT);
digitalWrite(PIN_RELAY , RELAY_OFF);
}
/**
* Our loop
*
* @since 1.0
*
*/
void loop() {
// check to see if it's time to execute the loop; that is, if the difference
// between the current time and last time we executed the loop is bigger than
// the interval at which you want to make the loop.
unsigned long current_millis = millis();
if ( (current_millis - previous_millis >= interval) || ( is_first_start == true ) ) {
Serial.println("Time to do our loop!");
// false the is_first_start;
is_first_start = false;
// update previous millis
previous_millis = current_millis;
// get the temperature from sensor
String type = "temperature";
float temperature = getDataFromSensor(type);
if ( temperature >= max_temperature ) {
digitalWrite(PIN_RELAY , RELAY_OFF);
Serial.println("Temp is over, shutdown the relay");
} else {
Serial.println("Temp is not over");
}
if ( temperature < 100 ) {
sendDataToGateway(type , temperature);
}
// get the humidity from sensor
type = "humidity";
float humidity = getDataFromSensor(type);
// send hum to gateway
if ( humidity < 100 ) {
sendDataToGateway(type , humidity);
}
// send relay data to the gateway
sendRelayToGateway();
}
}
/**
* Get the data from sensor
*
* @param string the type of request for sensor
*
* @return float the temperature
*
* @since 1.0
*/
float getDataFromSensor(String type) {
float data;
if ( type == "temperature") {
data = sensor.readTemperature();
Serial.print("Temp read direct from sensor is ");
Serial.println(data);
data = data+temperature_offset;
Serial.print("Temp after apply offset is ");
Serial.println(data);
} else {
data = sensor.readHumidity();
}
Serial.print("The read of ");
Serial.print(type);
Serial.print(" is ");
Serial.print(data);
Serial.print(", so returning is ");
Serial.println(data);
return data;
}
/**
* Send relay state to the gateway
*
*
* @since 1.0
*/
void sendRelayToGateway() {
bool current_state = digitalRead(PIN_RELAY);
//current_state = !current_state; // delete if NOT inverted
if (current_state == 1) {
current_state = RELAY_ON;
} else {
current_state = RELAY_OFF;
}
//send(msg_relay.set(current_state) , true);
bool transmission_was_ok = false;
int i = 0;
do {
transmission_was_ok = send(msg_relay.set(current_state) , true);
Serial.println("Send RELAY to the gateway.");
Serial.print("Variable i is ");
Serial.println(i);
Serial.print("Variable transmission_was_ok value is ");
Serial.println(transmission_was_ok);
i++;
wait(150);
if ( i > MAX_RETRY_SEND_BEFORE_DELAY ) {
delay(5000); // this delay will call watchdog!
}
} while (transmission_was_ok == false);
}
/**
* Send the data to the gateway
*
* @param string the type of data to send
* @param float the data to send
*
* @since 1.0
*/
void sendDataToGateway(String type , float data) {
bool transmission_was_ok = false;
int i = 0;
do {
if ( type == "temperature" ) {
transmission_was_ok = send(msg_temperature.setSensor(CHILD_ID_TEMP).set(data,1) , true);
} else {
transmission_was_ok = send(msg_humidity.setSensor(CHILD_ID_HUM).set(data,1) , true);
}
Serial.print("Send data to the gateway, the type sending is ");
Serial.println(type);
Serial.print("Variable i is ");
Serial.println(i);
Serial.print("Variable transmission_was_ok value is ");
Serial.println(transmission_was_ok);
i++;
wait(150);
if ( i > MAX_RETRY_SEND_BEFORE_DELAY ) {
delay(5000); // this delay will call watchdog!
}
} while (transmission_was_ok == false);
}
/**
* Receive function from gateway
*
* @since 1.0
*/
void receive(const MyMessage &message) {
/*Serial.println("-------------- DEBUG receive() ---------------");
Serial.print("message.type value is ");
Serial.println(message.type);
Serial.println("------------------------------------------");
Serial.print("message.getCommand() value is ");
Serial.println(message.getCommand());
Serial.println("------------------------------------------");*/
if ( message.isAck() ) {
/*if ( message.type == V_STATUS ) {
Serial.println("Relay state transmitted");
}
if ( message.type == V_TEMP ) {
Serial.println("Temperature transmitted");
}*/
}
if ( !message.isAck() ) {
if ( message.type == V_STATUS) {
if ( message.getCommand() == 1 ) {
bool received_state = message.getBool();
Serial.print("We did receive a new value. Received_state value is ");
Serial.println(received_state);
if ( received_state == 1) {
digitalWrite(PIN_RELAY , RELAY_ON);
} else {
digitalWrite(PIN_RELAY , RELAY_OFF);
}
}
}
}
}
Thank you and again Merry Xmas!