2

I am working through this tutorial on using the RF69HW. The RF69HW datasheet can be found here. I am using an Eegoo Uno R3 and yes I am aware that the Arduino is a 5v and the RF69HW is a 3.3v board. I am using some voltage dividers to get the voltage to 3.3v via the circuit shown below, at end of question.

I would use a level shifter but I only realized this mistake today and I am trying to get this working ASAP. The radio does not appear to be working. In fact the program seems to get caught on it. I introduced:

radio.sendACK();
Serial.print(" - ACK sent");

After the button has been pressed. This is the output I get:

Listening at 915 Mhz...
Button pressed!

So it gets to the line before it where the button is pressed but then gets stuck attempting to sendACK. I don't know what to make of this. Any help getting these two to communicate is appreciated. Code and pictures below.

Here is the code I am using as the sender:

#include <SPIFlash.h>
#include <SPI.h>
#include <LowPower.h>
#include <RFM69.h>
#include <RFM69_ATC.h>
#include <RFM69_OTA.h>
#include <RFM69registers.h>

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************
//This part of the code simply sets up the parameters we want the chip to use
// these parameters allow you to have multiple networks, channels, and encryption keys
#define NETWORKID     100  //the same on all nodes that talk to each other
#define RECEIVER      1    //unique ID of the gateway/receiver
#define SENDER        2    // you could for example, have multiple senders
#define NODEID        SENDER  //change to "SENDER" if this is the sender node (the one with the button)
//Select your frequency by uncommenting
#define FREQUENCY     RF69_915MHZ
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW    //uncomment only for RFM69HW! Remove/comment if you have RFM69W!
//*********************************************************************************************
#define SERIAL_BAUD   9600

//This part defines the LED pin and button pin
#define LED             9 //LED on D9
#define BUTTON_INT      1 //user button on interrupt 1 (D3)
#define BUTTON_PIN      3 //user button on interrupt 1 (D3)
#define RX_TOGGLE_PIN   7 //GPIO to toggle on the RECEIVER

RFM69 radio;

// the setup contains the start-up procedure and some useful serial data
void setup() {
  Serial.begin(SERIAL_BAUD);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
  radio.setHighPower(); //only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
  Serial.flush();
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  attachInterrupt(BUTTON_INT, handleButton, FALLING);
  pinMode(RX_TOGGLE_PIN, OUTPUT);
}

//******** THIS IS INTERRUPT BASED DEBOUNCING FOR BUTTON ATTACHED TO D3 (INTERRUPT 1)
#define FLAG_INTERRUPT 0x01
volatile int mainEventFlags = 0;
boolean buttonPressed = false;
void handleButton() {
  mainEventFlags |= FLAG_INTERRUPT;
}

byte LEDSTATE=LOW; //LOW=0

void loop() {
  //******** THIS IS INTERRUPT BASED DEBOUNCING FOR BUTTON ATTACHED TO D3 (INTERRUPT 1)
  if (mainEventFlags & FLAG_INTERRUPT) {
    LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_ON);
    mainEventFlags &= ~FLAG_INTERRUPT;
    if (!digitalRead(BUTTON_PIN)) {
      buttonPressed=true;
    }
  }
  if (buttonPressed) {
    Serial.println("Button pressed!");
    buttonPressed = false;
    radio.sendACK();
    Serial.print(" - ACK sent");
    if (radio.sendWithRetry(RECEIVER, "All About Circuits", 18)) //target node Id, message as string or byte array, message length
      delay(100);
  }
  //check if something was received (could be an interrupt from the radio)
  if (radio.receiveDone()) {
    //print message received to serial
    Serial.print('[');Serial.print(radio.SENDERID);Serial.print("] ");
    Serial.print((char*)radio.DATA);
    Serial.print("   [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]");
    Serial.println();
    if(LEDSTATE==LOW) LEDSTATE=HIGH;
    else LEDSTATE=LOW;
    digitalWrite(LED, LEDSTATE);
    digitalWrite(RX_TOGGLE_PIN, LEDSTATE);
    //check if sender wanted an ACK
    if (radio.ACKRequested()) {
      radio.sendACK();
      Serial.print(" - ACK sent");
    }
  }
  radio.receiveDone(); //put radio in RX mode
  Serial.flush(); //make sure all serial data is clocked out before sleeping the MCU
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_ON); //sleep Arduino in low power mode (to save battery)
}

And the receiver:

#include <SPIFlash.h>
#include <SPI.h>
#include <LowPower.h>
#include <RFM69.h>
#include <RFM69_ATC.h>
#include <RFM69_OTA.h>
#include <RFM69registers.h>

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/CONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************
//This part of the code simply sets up the parameters we want the chip to use
// these parameters allow you to have multiple networks, channels, and encryption keys
#define NETWORKID     100  //the same on all nodes that talk to each other
#define RECEIVER      1    //unique ID of the gateway/receiver
#define SENDER        2    // you could for example, have multiple senders
#define NODEID        SENDER  //change to "SENDER" if this is the sender node (the one with the button)
//Select your frequency by uncommenting
#define FREQUENCY     RF69_915MHZ
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW    //uncomment only for RFM69HW! Remove/comment if you have RFM69W!
//*********************************************************************************************
#define SERIAL_BAUD   9600

//This part defines the LED pin and button pin
#define LED             9 //LED on D9
#define BUTTON_INT      1 //user button on interrupt 1 (D3)
#define BUTTON_PIN      3 //user button on interrupt 1 (D3)
#define RX_TOGGLE_PIN   7 //GPIO to toggle on the RECEIVER

RFM69 radio;

// the setup contains the start-up procedure and some useful serial data
void setup() {
  Serial.begin(SERIAL_BAUD);
  radio.initialize(FREQUENCY, NODEID, NETWORKID);
#ifdef IS_RFM69HW
  radio.setHighPower(); //only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY == RF69_433MHZ ? 433 : FREQUENCY == RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
  Serial.flush();
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  attachInterrupt(BUTTON_INT, handleButton, FALLING);
  pinMode(RX_TOGGLE_PIN, OUTPUT);
}

//******** THIS IS INTERRUPT BASED DEBOUNCING FOR BUTTON ATTACHED TO D3 (INTERRUPT 1)
#define FLAG_INTERRUPT 0x01
volatile int mainEventFlags = 0;
boolean buttonPressed = false;

void handleButton() {
  mainEventFlags |= FLAG_INTERRUPT;
}

byte LEDSTATE = LOW; //LOW=0

void loop() {
  //******** THIS IS INTERRUPT BASED DEBOUNCING FOR BUTTON ATTACHED TO D3 (INTERRUPT 1)
  if (mainEventFlags & FLAG_INTERRUPT) {
    LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_ON);
    mainEventFlags &= ~FLAG_INTERRUPT;
    if (!digitalRead(BUTTON_PIN)) {
      buttonPressed = true;
    }
  }
  if (buttonPressed) {
    Serial.println("Button pressed!");
    buttonPressed = false;
    radio.sendACK();
    Serial.print(" - ACK sent");
    if (radio.sendWithRetry(RECEIVER, "All About Circuits", 18)) //target node Id, message as string or byte array, message length
      delay(100);
  }
  //check if something was received (could be an interrupt from the radio)
  if (radio.receiveDone()) {
    //print message received to serial
    Serial.print('['); Serial.print(radio.SENDERID); Serial.print("] ");
    Serial.print((char*)radio.DATA);
    Serial.print("   [RX_RSSI:"); Serial.print(radio.RSSI); Serial.print("]");
    Serial.println();
    if (LEDSTATE == LOW) LEDSTATE = HIGH;
    else LEDSTATE = LOW;
    digitalWrite(LED, LEDSTATE);
    digitalWrite(RX_TOGGLE_PIN, LEDSTATE);
    //check if sender wanted an ACK
    if (radio.ACKRequested()) {
      radio.sendACK();
      Serial.print(" - ACK sent");
    }
  }
  radio.receiveDone(); //put radio in RX mode
  Serial.flush(); //make sure all serial data is clocked out before sleeping the MCU
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_ON); //sleep Arduino in low power mode (to save battery)
}

Here is a link to project pictures: imgur.com/a/sFW88

Here is my circuit diagram: circuit diagram

2
  • Please edit your question and add circuit diagrams. Did you implement both 3.3-to-5V and 5V-to-3.3V interfaces, or just the latter? Feb 26, 2017 at 2:44
  • @jwpat7 Here is a circuit diagram. I apologize, I know its not great. First attempt doing this online. I only implemented the latter with 1k and 2k resistors.
    – onyex
    Feb 26, 2017 at 23:08

1 Answer 1

1

The circuit diagram shows several resistive voltage divider circuits, each made up of a 1KΩ in series with 2KΩ.

When 5 V goes into the top of such a divider, about 3.3 V appears at the resistor junction. (And 0 V in gives 0 V out.) This is suitable for a 5 V output pin connected to a 3.3 V input pin.

For connecting RF69HW 3.3 outputs (eg MISO) to 5 V Uno inputs, ideally one would step up 3.3 V to 5 V. Instead, MISO goes to the resistor junction of what resembles a resistive voltage divider but in fact is not.

Consider a low output on MISO; then the 1K-2K junction goes to zero; so the Uno reads 0 on D12, as it should.

Now consider a high output on MISO. The 1K-2K junction goes to 3.3 V, driving about 1.65 mA to ground through the 2KΩ resistor. Presumably the SPI library uses pin 12, MISO, as an input, so current through the 1KΩ resistor is specified to be at most 10 μA (per Table 29-14 in ATmega328 datasheet) and is quite likely to be at most a few nanoAmps. In any case, the voltage at pin 12 will be quite close to 3.3 V, which will register as a high input. (Figure 31-72 in ATmega328 datasheet shows a 2.6 V threshold when Vcc is 5 V.)

This is more of a long comment than an answer, because although the MISO circuitry is problematic, it appears that it should work anyway.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.