Author Topic: RFM69HW hangs every time [solved - bad multimeter]  (Read 2755 times)

bruster999

  • NewMember
  • *
  • Posts: 16
RFM69HW hangs every time [solved - bad multimeter]
« on: February 01, 2016, 09:57:49 PM »
Hi all,
I am trying to get a version of the mailbox sender sketch to work but have been having trouble for quite some time. Any suggestions would be appreciated.

The configuration is simple, a Moteino with an RFM69HW and a contact switch. When the contact switch is closed, the radio transmits the word "MOTION" to the gateway. That's it really. Below is the code that I am using. It either hangs every time it reaches line "if (radio.sendWithRetry(GATEWAYID, sendBuf, sendLen))" on line 91 or the unit reboots and starts over.

Can anyone suggest why the radio is hanging and what I can do to resolve this? Thanks in advance.
Bruster
Code: [Select]
#include <RFM69.h>    //get it here: https://github.com/LowPowerLab/RFM69
#include <SPI.h>      //get it here: https://github.com/LowPowerLab/SPIFlash
#include <LowPower.h> //get library from: https://github.com/LowPowerLab/LowPower
//writeup here: http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NODEID        55    //unique for each node on same network
#define NETWORKID     100  //the same on all nodes that talk to each other
#define GATEWAYID     1
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY     RF69_433MHZ
//#define FREQUENCY     RF69_868MHZ
#define FREQUENCY     RF69_915MHZ
#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define SENDEVERYXLOOPS   60 //each loop sleeps 8 seconds, so send status message every this many loops (default "4" = 32 seconds)
//*********************************************************************************************

#define MOTIONPIN     1  //hardware interrupt 1 (D3)
#define BATTERYSENSE  A7 //through 1Meg+470Kohm and 0.1uF cap from battery VCC - this ratio divides the voltage to bring it below 3.3V where it is scaled to a readable range
#define LED           9  // Moteinos have LEDs on D9
#define BLINK_EN         //uncomment to make LED flash when messages are sent, leave out if you want low power

#define SERIAL_BAUD   115200
#define SERIAL_EN      //uncomment this line to enable serial IO debug messages, leave out if you want low power
#ifdef SERIAL_EN
#define DEBUG(input)   {Serial.print(input); delay(1);}
#define DEBUGln(input) {Serial.println(input); delay(1);}
#else
#define DEBUG(input);
#define DEBUGln(input);
#endif

RFM69 radio;
volatile boolean motionDetected = false;

void setup() {
#ifdef SERIAL_EN
  Serial.begin(SERIAL_BAUD);
#endif
  Serial.println("**************starting MailboxNotifier4_v1.2*************");
  Serial.println("starting radio");
  radio.initialize(FREQUENCY, NODEID, NETWORKID);
  Serial.println("radio started");
#ifdef IS_RFM69HW
  radio.setHighPower(); //uncomment only for RFM69HW!
#endif
  Serial.println("radio encryption");
  delay(50);
  radio.encrypt(ENCRYPTKEY);
  pinMode(MOTIONPIN, INPUT);
  attachInterrupt(MOTIONPIN, motionIRQ, RISING);
  char buff[50];
  sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY == RF69_433MHZ ? 433 : FREQUENCY == RF69_868MHZ ? 868 : 915);
  DEBUGln(buff);
  radio.sleep();
}

void motionIRQ()
{
  motionDetected = true;
  //DEBUGln("I");
}

char sendBuf[32];
byte sendLen;
byte sendLoops = 0;
unsigned long MLO = 0; //MailLastOpen (ago, in ms)
unsigned long now = 0, time = 0, lastSend = 0, temp = 0;
char* BATstr = "BAT:5.00v";

void loop() {
  now = millis();

  if (motionDetected ) //avoid duplicates in 20second intervals
  {
    DEBUGln("Motion detected");
    delay(50);
    MLO = time; //save timestamp of event
    sprintf(sendBuf, "MOTION");
    sendLen = strlen(sendBuf);
    DEBUG("sendBuf: ");
    DEBUG(sendBuf);
    DEBUG(" ,GATEWAYID: ");
    DEBUG(GATEWAYID);
    DEBUG(" ,sendLen: ");
    DEBUGln(sendLen);
    delay(25);
    if (radio.sendWithRetry(GATEWAYID, sendBuf, sendLen))
    {
      DEBUGln(" ok!");
    }
    else DEBUGln(" no response from receiver");
    delay(50);
    motionDetected = false;
  }

  radio.sleep();
  DEBUGln("going to sleep");
  delay(25);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  DEBUGln("waking up");
}
« Last Edit: February 03, 2016, 02:57:53 PM by Felix »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6866
  • Country: us
    • LowPowerLab
Re: RFM69HW hangs every time
« Reply #1 on: February 01, 2016, 10:13:18 PM »
You could remove this:
Code: [Select]
    sprintf(sendBuf, "MOTION");
    sendLen = strlen(sendBuf);

And just do:
Code: [Select]
radio.sendWithRetry(GATEWAYID, "MOTION", 6)

How do you power the whole thing?
What is your contact switch circuit looking like, or schematic? And what does it do when it is closed?
How do you know the code is hanging at sendWithRetry?

bruster999

  • NewMember
  • *
  • Posts: 16
Re: RFM69HW hangs every time
« Reply #2 on: February 02, 2016, 02:39:33 PM »
Hi Felix,
Thanks for the suggestion. Unfortunately that didn't resolve the issue.

I am powering the Moteino from a powered USB hub.
I have attached a diagram of the circuit.
I know it's failing at the sendWithRetry because there are debug statements after the command that never get printed. Also, I have to power cycle the Moteino each time before it will accept code again.
Also, I tried it on a different Moteino. Same result.

Here is the serial o/p. I am tripping the switch during the first sleep cycle.
**************starting MailboxNotifier4_v1.2*************
starting radio
radio started
radio encryption

Transmitting at 915 Mhz...
going to sleep
waking up
Motion detected <<<<<--switch tripped
Before sendWithRetry

I updated the code a little with your suggestions and a little more debugging.

#include <RFM69.h>    //get it here: https://github.com/LowPowerLab/RFM69
#include <SPI.h>      //get it here: https://github.com/LowPowerLab/SPIFlash
#include <LowPower.h> //get library from: https://github.com/LowPowerLab/LowPower
//writeup here: http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NODEID        55    //unique for each node on same network
#define NETWORKID     100  //the same on all nodes that talk to each other
#define GATEWAYID     1
//Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define FREQUENCY     RF69_433MHZ
//#define FREQUENCY     RF69_868MHZ
#define FREQUENCY     RF69_915MHZ
#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define SENDEVERYXLOOPS   60 //each loop sleeps 8 seconds, so send status message every this many loops (default "4" = 32 seconds)
//*********************************************************************************************

#define MOTIONPIN     1  //hardware interrupt 1 (D3)
#define BATTERYSENSE  A7 //through 1Meg+470Kohm and 0.1uF cap from battery VCC - this ratio divides the voltage to bring it below 3.3V where it is scaled to a readable range
#define LED           9  // Moteinos have LEDs on D9
#define BLINK_EN         //uncomment to make LED flash when messages are sent, leave out if you want low power

#define SERIAL_BAUD   115200
#define SERIAL_EN      //uncomment this line to enable serial IO debug messages, leave out if you want low power
#ifdef SERIAL_EN
#define DEBUG(input)   {Serial.print(input); delay(1);}
#define DEBUGln(input) {Serial.println(input); delay(1);}
#else
#define DEBUG(input);
#define DEBUGln(input);
#endif

RFM69 radio;
volatile boolean motionDetected = false;

void setup() {
#ifdef SERIAL_EN
  Serial.begin(SERIAL_BAUD);
#endif
  Serial.println("**************starting MailboxNotifier4_v1.2*************");
  Serial.println("starting radio");
  radio.initialize(FREQUENCY, NODEID, NETWORKID);
  Serial.println("radio started");
#ifdef IS_RFM69HW
  radio.setHighPower(); //uncomment only for RFM69HW!
#endif
  Serial.println("radio encryption");
  delay(50);
  radio.encrypt(ENCRYPTKEY);
  pinMode(MOTIONPIN, INPUT);
  attachInterrupt(MOTIONPIN, motionIRQ, RISING);
  char buff[50];
  sprintf(buff, "\nTransmitting at %d Mhz...", FREQUENCY == RF69_433MHZ ? 433 : FREQUENCY == RF69_868MHZ ? 868 : 915);
  DEBUGln(buff);
  radio.sleep();
}

void motionIRQ()
{
  motionDetected = true;
  //DEBUGln("I");
}

char sendBuf[32];
byte sendLen;
byte sendLoops = 0;
unsigned long MLO = 0; //MailLastOpen (ago, in ms)
unsigned long now = 0, time = 0, lastSend = 0, temp = 0;
char* BATstr = "BAT:5.00v";

void loop() {
  now = millis();

  if (motionDetected ) //avoid duplicates in 20second intervals
  {
    DEBUGln("Motion detected");
    delay(50);
    MLO = time; //save timestamp of event
    DEBUGln("Before sendWithRetry");
    delay(25); 
    if (radio.sendWithRetry(GATEWAYID, "MOTION", 6))
    {
      DEBUGln(" ok!");
    }
    else DEBUGln(" no response from receiver");
    delay(50);
    motionDetected = false;
    DEBUGln("After sendWithRetry");
 }
 
  radio.sleep();
  DEBUGln("going to sleep");
  delay(25);
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
  DEBUGln("waking up");
}

bruster999

  • NewMember
  • *
  • Posts: 16
Re: RFM69HW hangs every time
« Reply #3 on: February 02, 2016, 03:30:59 PM »
Found the problem. One thing I didn't mention about my circuit was that I was trying to take current readings with my multi-meter. I had the meter in series with the +V line coming from my powered hub(i had it down to 1.3ua). Once I removed this it worked ok so apparently the meter was limiting the current to the device.

What's a better way to measure current than how I was doing it?

Bruster.

luisr320

  • Sr. Member
  • ****
  • Posts: 255
  • Country: pt
Re: RFM69HW hangs every time
« Reply #4 on: February 03, 2016, 07:17:51 AM »

bruster999

  • NewMember
  • *
  • Posts: 16
Re: RFM69HW hangs every time
« Reply #5 on: February 03, 2016, 09:25:49 AM »
Thanks. I will check it out.
Bruster

emjay

  • Full Member
  • ***
  • Posts: 119
  • Country: nl
Re: RFM69HW hangs every time
« Reply #6 on: February 03, 2016, 01:11:44 PM »
@bruster,

Or save the dollars and shipping time with a 'poor man's uA meter.  Your multimeter is probably fine for volts measurement, it is just that on the lowest current range, the burden resistor it inserts in series creates too much voltage drop for the downstream load.

* Find the best quality capacitor (non-electrolytic) you have, say 1uF for explanation.
* Charge it up to a voltage towards the top of the range allowed by your board.
* Observe and time the V with no load - if the cap and/or meter loading is good, the V will show a *slow* decline. That is your baseline.
* Connect up the board, note the starting V and jump through whichever hoops you need, keeping track of elapsed time.
* Check V at the end

Your test has taken additional charge from the capacitor, hence the voltage droop
delta Q = C x (Vstart - Vend)   (Remember that C is in FARADS. Correct with the baseline leakage if you want better accuracy)
But current is simply Charge / time, so the average current drawn is delta Q / time  (time in seconds)

If you keep the voltage droop relatively small (you can fiddle with the size of the cap to do this), then the second order effects of the current draw depending on the Vdd don't matter much - usually you are looking for a comparison, not an absolute uA number.

This will work with or without an LDO regulator (provided you keep the LDO input within range), but if you are searching for the lowest consumption, if possible - throw the regulator out, it is a relatively hungry beast. Just make sure the direct supply is within the board limits.

« Last Edit: February 03, 2016, 01:25:30 PM by emjay »