Adafruit Feather M0 RFM69HCW with MySensors?
-
Hi guys,
I do have a working node now. And I think sleep is working as well. I am using Adafruit_SleepyDog for now.
Powerconsumption has to be tested yet. To see if the node is still active I made it flash the LED everytime it wakes up for sending data. If you leave out that part it will behave a little odd, because the LED will light up for a whole cycle and go down in the next one. But I guess that's just cosmetics.So far it sends battery level and the temperature from one wire sensors.
For anybody interested I will post the code. I hope it helps someone.
/** * 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. * ******************************* * * DESCRIPTION * * Example sketch showing how to send in DS1820B OneWire temperature readings back to the controller * http://www.mysensors.org/build/temp */ #define MY_DEBUG // used by MySensor (Print debug messages via serial) #define MY_RADIO_RFM69 // Select Radio-Module RFM69 #define MY_RFM69_FREQUENCY RF69_433MHZ // Define our Frequency of 433 MHz #define MY_IS_RFM69HW // Module is high power (HW/HCW) //#define MY_RFM69_NETWORKID 100 // leave out for gateway selection #define MY_RF69_SPI_CS 8 // SPI CS PIN #define MY_RF69_IRQ_PIN 3 // IRQ PIN #define MY_RF69_IRQ_NUM 3 // IRQ PIN NUM (for M0 it is the same as IRQ PIN. Will be obsolete in upcoming MySensors.h) #define MY_NODE_ID 162 // Node ID #define MY_DEFAULT_TX_LED_PIN 13 // LED Pin for "Blink while sending" #define CHILD_ID_BATTERY 1 // Battery ID (standard 1) #include <SPI.h> // include SPI for communication with radio #include <MySensors.h> // include MySensors (it has to be done after the defines) #include <DallasTemperature.h> // Lib for Dallas Temperature OneWires #include <OneWire.h> // Lib for OneWires #include <Adafruit_SleepyDog.h> #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No #define ONE_WIRE_BUS 12 // Pin where dallase sensor is connected #define MAX_ATTACHED_DS18B20 16 // maximum number of sensors int VBATPIN = A7; // select the input pin for the battery sense point int batteryPcnt; // battery value in percent int SleepCycles = 1; // Number of sleep cycles (each 17 seconds) int n = 0; // Sleepcounter OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. float lastTemperature[MAX_ATTACHED_DS18B20]; // lastTemp variabels for every possible Sensor (0 - MAX_ATTACHED_DS18B20) int numSensors=0; // Number of Sensors (automatically defined later) bool receivedConfig = false; bool metric = true; MyMessage msg(0,V_TEMP); // initialize temperature message MyMessage msgBatt(CHILD_ID_BATTERY,V_VOLTAGE); // initialize battery reading /* ********************* Before *********************** */ void before() { sensors.begin(); // Startup up the OneWire library } /* ******************** Setup ************************ */ void setup() { sensors.setWaitForConversion(false); // requestTemperatures() will not block current thread pinMode(LED_BUILTIN, OUTPUT); } /* ********************** Presentation ********************** */ void presentation() { sendSketchInfo("Temperature Sensor", "1.1"); // Send the sketch version information to the gateway and Controller numSensors = sensors.getDeviceCount(); // Fetch the number of attached temperature sensors for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(i, S_TEMP); // Present all sensors to controller } present(CHILD_ID_BATTERY, S_MULTIMETER); // Present battery to controller } /* ********************** Loop ********************** */ void loop() { n = 0; // reset sleep count if (n == 0) // Only send Data when sleep cycles completed { /* ***************** Get the battery Voltage ***************** */ // To make this easy we stuck a double-100K resistor divider on the BAT pin, and connected it to D9 (a.k.a analog #7 A7). You can read this pin's voltage, then double it, to get the battery voltage. float sensorValue = analogRead(VBATPIN); #ifdef MY_DEBUG Serial.println(sensorValue); // Debug msg #endif sensorValue *= 2; // we divided by 2, so multiply back (because of double-100K resistor) sensorValue *= 3.3; // Multiply by 3.3V, our reference voltage sensorValue /= 1024; // convert to voltage float batteryV = sensorValue; int batteryPcnt = ((batteryV-2.7)/3.3)*100; // for 6V batterypack (don't use 6V directly. It will fry your radio. 3.3 -5 V is OK) #ifdef MY_DEBUG // Battery Debug Serial.print("Battery Voltage: "); Serial.print(batteryV); Serial.println(" V"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif sendBatteryLevel(batteryPcnt); send(msgBatt.set(batteryV,2)); /* ***************** Send Sensor Data ***************** */ sensors.requestTemperatures(); // Fetch temperatures from Dallas sensors for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { // Read temperatures and send them to controller float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; //Fetch and round temperature to one decimal (v2.1.1 "getControllerConfig" instead of "getConfig") #if COMPARE_TEMP == 1 // Only send data if temperature has changed and no error if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) { #else if (temperature != -127.00 && temperature != 85.00) { // Only send Data if not -127 or 85 °C (indicates reading-error) #endif send(msg.setSensor(i).set(temperature,1)); // Send the new temperature lastTemperature[i]=temperature; // Save new temperatures for next compare } } digitalWrite(LED_BUILTIN, HIGH); // turn the LED on to indicate transmission delay(500); // wait for a 500 ms digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW } // end of "only send data if sleep cycles completed"-if /* ***************** Sleep ***************** */ while (n <= SleepCycles) { Watchdog.sleep(17000); // Deepsleep with Watchdog interrupt !!Watchdog can't handle long sleep times, hence the cycles!! (n=1 -> 17 sec * 2 = 34 sec sleep) n++; } } // end of loop@Sweeman
I'm very interested to hear your power consumption measurements. I only just recently acquired an Adafruit Feather M0 RFM69HCW, and it's probably my #1 question, because if it's not good, then I'm going to shelve it until it is good. Ultra low current consumption is simpy a MUST. -
My gear is a bit quick and dirty, because I am in a cheapo lab and would need to get a better suited resistor for my measurement to be absolutely certain. But what I get is aprox. 150mA while sending and 2mA during sleep (with 10 Ohms as measurement resistor).
There is some room for improvement I guess. But it is already better than the old setup.
I hope that helps a little and maybe you find a way to have even less power consumption.
I will think a little about this and decide wheather I will get some better gear for that later. :) -
My gear is a bit quick and dirty, because I am in a cheapo lab and would need to get a better suited resistor for my measurement to be absolutely certain. But what I get is aprox. 150mA while sending and 2mA during sleep (with 10 Ohms as measurement resistor).
There is some room for improvement I guess. But it is already better than the old setup.
I hope that helps a little and maybe you find a way to have even less power consumption.
I will think a little about this and decide wheather I will get some better gear for that later. :)@Sweeman
That sounds rather high. Was it the sketch above that you were running for the sleep cycle? I could try measuring with a uCurrent Gold. It's the sleep current that matters most. I'm around 1ua during sleep with an atmega328p and an RFM69. -
from datasheet, atsamd is approx 2.8uA in deepest sleep mode without rtc, 4uA with rtc 1khz. wdt should consumes some uA too. it's not comparable with 328p, it's different, not same features, still low power vs features though.
-
@Sweeman
That sounds rather high. Was it the sketch above that you were running for the sleep cycle? I could try measuring with a uCurrent Gold. It's the sleep current that matters most. I'm around 1ua during sleep with an atmega328p and an RFM69.@NeverDie
Yes it was essentially the same sketch. I guess the 3.3 V regulator is consuming some power as well?
I would love to see it consuming even less power. But as long as it holds for about 3 months on 4500 mAh it is kind of OK for my purposes.
It would be great if you could measure it with your gear and maybe you have an idea how to get it even lower, since I also have to work on some peripheral stuff first. I am looking forward to hear from your tests.@scalz
To be honest I am a little lost with all these abbreviations since I just started on working with MCUs, but I guess it is to make a point of "features need power"? But I will use these as hints as where to look for more saving potential. :) -
@NeverDie
Yes it was essentially the same sketch. I guess the 3.3 V regulator is consuming some power as well?
I would love to see it consuming even less power. But as long as it holds for about 3 months on 4500 mAh it is kind of OK for my purposes.
It would be great if you could measure it with your gear and maybe you have an idea how to get it even lower, since I also have to work on some peripheral stuff first. I am looking forward to hear from your tests.@scalz
To be honest I am a little lost with all these abbreviations since I just started on working with MCUs, but I guess it is to make a point of "features need power"? But I will use these as hints as where to look for more saving potential. :)@Sweeman said in Adafruit Feather M0 RFM69HCW with MySensors?:
I guess the 3.3 V regulator is consuming some power as well?
It's a SPX3819 and the datasheet says "Low Quiescent Current: 90μA". Out of spec for any decent battery powered sensor IMHO :P
-
from datasheet, atsamd is approx 2.8uA in deepest sleep mode without rtc, 4uA with rtc 1khz. wdt should consumes some uA too. it's not comparable with 328p, it's different, not same features, still low power vs features though.
@scalz said in Adafruit Feather M0 RFM69HCW with MySensors?:
from datasheet, atsamd is approx 2.8uA in deepest sleep mode without rtc, 4uA with rtc 1khz.
Thanks for posting this. I think that alone may kill it for me. For some reason I thought it was lower.
-
Hey guys aside from these power-consumption issues, I am now running the Feather as gateway and node.
And I get a strange problem.
The gateway is attached to a raspberry pi via usb (by-id), which runs fhem. And everything works great for about an hour to 1 1/2. Then somehow the gateway stops receiving/communicating. I already tried an active USB-Hub incase the power consumption was too high for too long. But that didn't help. I have to reset the gateway and node to make it work again.
Did anybody else ever experience similar behaviour?