RFM69W (RFM69HW) transceiver + T3

Status
Not open for further replies.
Beware max message len. In RadioHead, there is one called
#define RH_MAX_MESSAGE_LEN 255
which is 255 as the max for any radio type. The above is in the datagram .h file.

But in each radio type there's a max for that radio...
#ifndef RH_RF22_MAX_MESSAGE_LEN
#define RH_RF22_MAX_MESSAGE_LEN 255
//#define RH_RF22_MAX_MESSAGE_LEN 50
#endif

The default is 50, not 255. That includes the preamble bytes.
If you transmit more than 50, there will be an error return which is silent and easily overlooked.

I have a sniffer program for the radios that displays everything it hears.


== On RadioHead, at this point I have it talking to the radio but it blows up on the first interrupt in transmit. Probably a change in the way the ISRs are dispatched. Working on that.
I'm away for the weekend.
 
Hello Everybody,
i think i need your input here. i have been trying to make work the RFM69HW with teensy 3.1 too but it looks like i don't succeed.

i connected like this:
RFM69HW MISO >> teensy3 pin 12
RFM69HW MOSI >> teensy3 pin 11
RFM69HW SCK >> teensy3 pin 13
RFM69HW NSS >> teensy3 pin 10
+ 3v3/ gnd and D0 to D0 on the teensy.

did commented "SPI.setDataMode(SPI_MODE0);"

but nothing, no print in my serial terminal other than when i send command ("r" or "t")

any idea of something i could try ?

thank you!
 
Hello Everybody,
i think i need your input here. i have been trying to make work the RFM69HW with teensy 3.1 too but it looks like i don't succeed.

Freja, Which example are you uploading? Are you using the library from Low Power Labs? How many nodes are running? You will need more than 1 to be able to send and receive.

Your wiring looks correct. Did you put an antenna on the RFM69HW?

Eric
 
I have the RadioHead working now on Teensy 3 for the RFM22. A couple of changes are needed unique to the Teensy 3.
Have tested ReliableDatagram support with two nodes, my own server/client code, and my sniffer (promiscuous mode, display all that's heard).
Now testing 4 nodes.
I would now try the RFM69s but I haven't ordered any yet.

steve
 
The Teensy-specific bugs I've found so far are small in number. A couple of the changes are in the RFM22 driver and the same would need to go into the RFM69.
Do you have 2, or ideally 3, teensy 3's each with an RFM69 or RFM22?

The 1.2 driver at airspayce.com doesn't have my Teensy specific changes yet.

Let's merge this thread with the below so we have one thread on the RadioHead libraries for the RFM22, RFM69 and now with v1.2, Nordic radios.
http://forum.pjrc.com/threads/25587-...6412#post46412
 
Last edited:
Hey Eric!
Sorry, for some reason i haven't been notified about your reply...
i tried the gateway + node example using the lowpowerlab lib. i got one gateway plug to my computer and one other teensy as a node.
i did puted an antenna with the length needed according to the informations i found on the moteino website .

it looks like you got it working on your side! would you mind sharing pictures of your wiring and maybe your modified lib + sketches ?

let me know if you want my email ))

thanks a lot!



Freja, Which example are you uploading? Are you using the library from Low Power Labs? How many nodes are running? You will need more than 1 to be able to send and receive.

Your wiring looks correct. Did you put an antenna on the RFM69HW?

Eric
 
freja,
I'm still having an issue with dropped packets. One more thing, you need to initialize radio as follows

RFM69 radio(10,0);
The first parameters is the CS pin, the default is pin 10. The second one is the interrupt pin. The default is 2, but on the Teensy it should be 0.

This would replace the line which has
RFM69 radio();
in the examples.

Eric
 
I'm still trying to get the RFM69HW to work with the Teensy 3.1.

I have the RFM69HW wired to the Teensy 3.1 as follows.

RFM69HW......Teensy
NSS..........D8
SCK..........D13
MISO.........D12
MOSI.........D11
D0...........D0
GND..........GND..........GND
3.3V......................Regulated 3.3v Supply
ANT.......................Antenna


I downloaded the driver from GitHub, Low Power Labs, https://github.com/LowPowerLab/RFM69

I tested the Node & Gateway example using Moteino's, R4 and verified they work.

I commented out the line,
SPI.setDataMode(SPI_MODE0);
in the library file RFM69.cpp (this line would cause the Teensy 3.1 to hang, Mode 0 is the default anyways)

I removed the SPI Flash from the example, and added conditional compile (#if defined) so that the Teensy 3.1 uses CS pin 8, and Interrupt pin 0 and the Moteino uses the default (CS pin 10, interrupt pin 2).

I tested the modified project with the Moteinos and verified that it still works.

I tested using the Teensy 3.1 with the gateway sketch, and a Moteino using the node sketch. The Teensy initializes without error, but never receives any transmissions. If i type 't', it will report the RFM temperature.

Below is a picture of the Teensy connected to the RFM69HW.

Teensy31_RFM69hw.jpg

Here is the modified version of the Node example

Code:
// Sample RFM69 sender/node sketch, with ACK and optional encryption
// Sends periodic messages of increasing length to gateway (id=1)
// It also looks for an onboard FLASH chip, if present
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Get the RFM69 and SPIFlash library at: https://github.com/LowPowerLab/

#include <RFM69.h>
#include <SPI.h>

#define NODEID        2    //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_868MH
//#define FREQUENCY     RF69_915MHZ
#define ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ACK_TIME      30 // max # of ms to wait for an ack
#define LED           2  // Moteinos have LEDs on D9
#define SERIAL_BAUD   115200

int TRANSMITPERIOD = 300; //transmit a packet to gateway so often (in ms)
char payload[] = "123 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char buff[20];
byte sendSize=0;
boolean requestACK = false;
#if  defined( __MK20DX256__ ) || defined( __MK20DX128__ )
#define TEENSY_CPU 1
RFM69 radio(8,0);
#else
#define TEENSY_CPU 0
RFM69 radio;
#endif

void setup() {
  Serial.begin(SERIAL_BAUD);
  delay(3000);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
  radio.setHighPower(); //uncomment only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  char buff[50];
  if( TEENSY_CPU )
    Serial.print( "\nTeensy" );
  else
    Serial.print( "\nMoteino" );
  sprintf(buff, " transmitting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);

}

long lastPeriod = -1;
void loop() {
  //process any serial input
  if (Serial.available() > 0)
  {
    char input = Serial.read();
    if (input >= 48 && input <= 57) //[0,9]
    {
      TRANSMITPERIOD = 100 * (input-48);
      if (TRANSMITPERIOD == 0) TRANSMITPERIOD = 1000;
      Serial.print("\nChanging delay to ");
      Serial.print(TRANSMITPERIOD);
      Serial.println("ms\n");
    }
    
    if (input == 'r') //d=dump register values
      radio.readAllRegs();
    //if (input == 'E') //E=enable encryption
    //  radio.encrypt(KEY);
    //if (input == 'e') //e=disable encryption
    //  radio.encrypt(null);
    
  }

  //check for any received packets
  if (radio.receiveDone())
  {
    Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
    for (byte i = 0; i < radio.DATALEN; i++)
      Serial.print((char)radio.DATA[i]);
    Serial.print("   [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]");

    if (radio.ACK_REQUESTED)
    {
      radio.sendACK();
      Serial.print(" - ACK sent");
      delay(10);
    }
    Blink(LED,5);
    Serial.println();
  }
  
  int currPeriod = millis()/TRANSMITPERIOD;
  if (currPeriod != lastPeriod)
  {
    lastPeriod=currPeriod;
    Serial.print("Sending[");
    Serial.print(sendSize);
    Serial.print("]: ");
    for(byte i = 0; i < sendSize; i++)
      Serial.print((char)payload[i]);

    if (radio.sendWithRetry(GATEWAYID, payload, sendSize))
     Serial.print(" ok!");
    else Serial.print(" nothing...");

    sendSize = (sendSize + 1) % 31;
    Serial.println();
    Blink(LED,3);
  }
}

void Blink(byte PIN, int DELAY_MS)
{
  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

And this is the modified version of the Gateway example

Code:
// Sample RFM69 receiver/gateway sketch, with ACK and optional encryption
// Passes through any wireless received messages to the serial port & responds to ACKs
// It also looks for an onboard FLASH chip, if present
// Library and code by Felix Rusu - felix@lowpowerlab.com
// Get the RFM69 and SPIFlash library at: https://github.com/LowPowerLab/

#include <RFM69.h>
#include <SPI.h>

#define NODEID        1    //unique for each node on same network
#define NETWORKID     100  //the same on all nodes that talk to each other
//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 ENCRYPTKEY    "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define ACK_TIME      30 // max # of ms to wait for an ack
#define LED           13  // Moteinos have LEDs on D9
#define SERIAL_BAUD   115200

#if  defined( __MK20DX256__ ) || defined( __MK20DX128__ )
#define TEENSY_CPU 1
RFM69 radio(8,0);
#else
#define TEENSY_CPU 0
RFM69 radio;
#endif

bool promiscuousMode = false; //set to 'true' to sniff all packets on the same network

void setup() {
  Serial.begin(SERIAL_BAUD);
  delay(3000);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
  radio.setHighPower(); //uncomment only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  radio.promiscuous(promiscuousMode);
  char buff[50];
  if( TEENSY_CPU )
    Serial.print( "\nTeensy " );
  else
    Serial.print( "\nMoteino " );
    
  sprintf(buff, "Listening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
}

byte ackCount=0;
void loop() {
  //process any serial input
  if (Serial.available() > 0)
  {
    char input = Serial.read();
    if (input == 'r') //d=dump all register values
      radio.readAllRegs();
    if (input == 'E') //E=enable encryption
      radio.encrypt(ENCRYPTKEY);
    if (input == 'e') //e=disable encryption
      radio.encrypt(null);
    if (input == 'p')
    {
      promiscuousMode = !promiscuousMode;
      radio.promiscuous(promiscuousMode);
      Serial.print("Promiscuous mode ");Serial.println(promiscuousMode ? "on" : "off");
    }
    
    if (input == 't')
    {
      byte temperature =  radio.readTemperature(-1); // -1 = user cal factor, adjust for correct ambient
      byte fTemp = 1.8 * temperature + 32; // 9/5=1.8
      Serial.print( "Radio Temp is ");
      Serial.print(temperature);
      Serial.print("C, ");
      Serial.print(fTemp); //converting to F loses some resolution, obvious when C is on edge between 2 values (ie 26C=78F, 27C=80F)
      Serial.println('F');
    }
  }

  if (radio.receiveDone())
  {
    Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
    if (promiscuousMode)
    {
      Serial.print("to [");Serial.print(radio.TARGETID, DEC);Serial.print("] ");
    }
    for (byte i = 0; i < radio.DATALEN; i++)
      Serial.print((char)radio.DATA[i]);
    Serial.print("   [RX_RSSI:");Serial.print(radio.RSSI);Serial.print("]");
    
    if (radio.ACK_REQUESTED)
    {
      byte theNodeID = radio.SENDERID;
      radio.sendACK();
      Serial.print(" - ACK sent.");

      // When a node requests an ACK, respond to the ACK
      // and also send a packet requesting an ACK (every 3rd one only)
      // This way both TX/RX NODE functions are tested on 1 end at the GATEWAY
      if (ackCount++%3==0)
      {
        Serial.print(" Pinging node ");
        Serial.print(theNodeID);
        Serial.print(" - ACK...");
        delay(3); //need this when sending right after reception .. ?
        if (radio.sendWithRetry(theNodeID, "ACK TEST", 8, 0))  // 0 = only 1 attempt, no retries
          Serial.print("ok!");
        else Serial.print("nothing");
      }
      
    }
    Serial.println();
//    Blink(LED,3);
  }
}

void Blink(byte PIN, int DELAY_MS)
{
//  pinMode(PIN, OUTPUT);
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

I also tried adding
radio.send( 2, "Test", 4 );
which would run on the Gateway whenever 't' is pressed, after displaying the temperature. When I press 't' on the Gateway serial terminal, both the gateway and the node would hangup. The node would recover after unplugging the USB cable from the Gateway.

Does anyone have any ideas why this is not working?

Thanks,

Eric
 
Today I received some RF69 modules - I'll soon be trying them out.
add a printout confirming that setup() runs - ensuring the constructors all worked.
And the same for the .init()
All I've done is compile RH, no over the air yet. But it does startup and iterate the loop() where I added an LED blinker.
 
Last edited:
I began testing RH 1.7 with the newly received RFM69 modules here.
Compile & load on Teensy 3.1 OK.
radio init() succeeeds. SPI working OK. I can see messages exchanged on my 'scope on the SPI lines.
At the moment, I'm stuck on this problem:
When I use manager.senttoWait(), I see SPI transactions, then a delay (transmission), then the DIO0 line goes high for an end of transmission interrupt. I think this is the first interrupt used.
I determined that the isr isn't vectored to. This is essentially the same code as is in the RFM22 I have that does work. A pin0 interrupt, though the polarity is true=1 on the RFM69 and true=0 on the RFM22. But the attachInterrupt() call accounts for this. When it hangs after transmitting, pin 0 is high but no isr0 ran.

That's where I am as of now. Will ask Mike for ideas since he ran the code on the Teensy3.
 
Sound similar to what I'm seeing. The initialization succeeds, and the loop continues to run until I try to transmit - then the RFM69 hangs up.
 
Mike says so far, he tested RadioHead for the RF69 only on a platform other than Teensy 3.

I sent him one more change for Teensy (macro to include Teensy as having yield() support) .. discussed on this forum. He'll add.

So re the transmit hangup... I'm troubleshooting why the pin 0 interrupt (HIGH or RISING mode) doesn't "fire" and get the ISR to run.
 
I finally got this working thanks to stevech and others on this thread. I'm using the Low Power Labs library. I will test this with the RadioHead library next.

The following are the things to do when using the RFM69 with the Teensy 3.x with the Low Power Labs RFM69 Library.

  1. The Moteino Schematic provides a example of how to connect an RFM69. There are a couple of small things to change.
    Be sure to connect the Data0 from the RFM69 to D0 rather than D2.
    Also, be sure to provide a regulated 3.3V supply to the RFM69. The Teensy's 3.3V pin can't provide sufficient current.
    If D10 is not available on the Teensy for SS, it can be connected to any other available digital pin. Just be sure to initialize the RFM69 to use the correct SS pin.​
  2. When constructing the RFM69 object specify the interrupt pin. The default interrupt pin the library uses is pin D2. With the Teensy 3.x, interrupt 0 is on pin D0.
    RFM69 radio(10,0);​
  3. Modify the RFM69 library. Comment out the line which initializes the SPI mode. Add a line which sets the pin mode of the interrupt pin to INPUT.
    In the RFM69::initialize() function, in RFM69.cpp, comment out this line:
    //SPI.setDataMode(SPI_MODE0);
    and just below it, add this line
    pinMode( _interruptPin, INPUT );​

I tested the Node and Gateway examples successfully (I removed the SPI Flash code from the examples). I did the testing using the Teensy 3.1 communicating with a Moteino R4.

Here's a picture of the assembled controller (also has a Wiz820io ethernet module).

Teensy3.1_with_RFM69_and_Wiz820io.jpg
Teensy3.1_with_RFM69_and_Wiz820io2.jpg

Eric
 
Last edited:
Congrats.
The RadioHead lib v1.7 is working OK here on a Teensy3 talking to an Anarduino. I use the same code on both, and have a simple ping-pong-messages reliable datagram test program.
Both RF69's with the 13dBm (20mW) RFM69. I'm powering the RFM69 from the Teensy3's 3.3V supply. It might not work at 100mW, so you could set the RFM69 power to 20mW if you like, to use the Teensy's power. I did run the RFM22 radios at 100mW from the Teensy 3 power.

The setDataMode() issue is still a bug in Teensy's SPI driver, avr_emulation.h as noted earlier. But it's not an issue in RH 1.7 because that isn't needed.

I have this code BEFORE the manager.init() call in radio head. It changes the pin settings so that the SPI clock moves to pin 14 to save pin 13 for the LED.
Code:
	//// Add by Adrien van den Bossche <vandenbo@univ-tlse2.fr>
	#if  defined (TEENSYDUINO)
	SPI.setSCK(14); // added this to move SCK to pin 14
	CORE_PIN13_CONFIG = PORT_PCR_MUX(1); //   Alt1 = PTC5.  chip pin PTC5
	//// and then reassign pin 14 to SCK
	//CORE_PIN14_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); // Alt2=SPIO_SCK.  chip pin PTD1
	#endif

and this code must be AFTER the manager.init() call
Code:
// the below is needed a 2nd time due to pin mapping for SPI done by the above .init() call, above
	#if  defined (TEENSYDUINO)
	// First reassign pin 13 to Alt1 so that it is not SCK but the LED still works
	CORE_PIN13_CONFIG = PORT_PCR_MUX(1); //   Alt1 = PTC5.  chip pin PTC5
	SPI.setClockDivider(SPI_CLOCK_DIV2); // 8MHz SPI clock. Do change after SPI init runs else hang in teensyduino.
	#endif
The code above finishes the SPI clock and LED remapping. If done before the manager.init(), the SPI begin code in the SPI library undoes the LED remapping.
Also above, you can see that I change the SPI clock to 8MHz. This is optional.

Both hunks of code above are in my application, not the RadioHead library.

These done (in the application, not the lib), there are no changes needed in the RadioHead 1.7 library for the RF69.

Happy to pass on to you my test program.

I'm testing two RFM69 in the various modulation modes with reliable datagrams. I think I've found some modes that don't work even at close range. The RF22 was not as finnicky. ALso, the RF69 library limits the user data size to 60 bytes, unlike the RF22.

steve
 
Last edited:
One more thing: RadioHead 1.7 allows you to use any pin # for the interrupt from the radio. Prior version required use of pin 0.
Beware SPI port use race condition with Wiznet or other SPI thing. Easiest way is to use software SPI on the radio. Or easy too is disable interrupts from just the radio's pin interrupt, while Wiznet / ethernet lib is using SPI.
 
see also on the RadioHead forum... I posted a list of modulation modes that don't work or hang the radio. Could be typos in the register bits/bytes calculations for each mode.
 
RH_RF69 lib v1.8 - new

Note for RF69 users: default Transmitter power is +13dBm which is the max that the RF69W does. For the RF69HW your app may change to +18 if you need that.
The RF69W, if set above +13, seems to disable the transmitter entirely.

But in v1.8 - no interrupts. It's because v1.8 changed the default pin number from 0 to 2. Affects any MCU that had been wired up for pin 0.
So in your application, code this, or any other pin #
add these in your application
// for RFM69 module variants
#define RF69_1_SLAVE_SELECT_PIN SS // 10
#define RF69_1_INTERRUPT_PIN 2


Then in your app, change the instance of the radio driver class as:
// Singleton instance of the radio driver.
// Override the default pin numbers...
RH_RF69 driver (RF69_1_SLAVE_SELECT_PIN, RF69_1_INTERRUPT_PIN);


I'm testing the new modulation mode constants in v1.8. V1.7 had some values that did not work properly.

steve

EDIT
to correct typo above: { should have been ( in two places

The pin # change was in the release notes but I missed it.
 
Last edited:
Here's a quick note about using Paul's generously shared PCB to simplify adding a HopeRF RFM69W or RFM69HW digital packet transceiver to a Teensy 3.x.
I'll do a video soon on that and how to use with the RadioHead library on AVRs and/or Teensy3. I have an RFM69 on each kind of MCU, exchanging reliable datagrams at good speeds.
Elaborate performance test program I've about finished - runs on both MCUs.
It's running at many of the modulation modes, including 250Kbps/250KHz. There, two-way packet exchanges at 75Kbps sustained are doing great in terms of near 0 error rates/dropped packets. This is a bit extreme though.

More later.
https://groups.google.com/forum/#!topic/radiohead-arduino/4lQ_W7urLLA

steve
PS: Note for Paul: if there's ever a new spin of this PCB, it would be very much easier to build if the PCB allowed for soldering the castellated connectors on the radio module. Surface mount pads instead of pin header holes, and spaced wider for the castellated connections.
 
Last edited:
Great. That's given all the RFM69 RadioHead and other code fits, with hanging, for some time.
Here's the change at line number 933 of avr_emulation.h with a bit more context:
Code:
	inline int operator & (int val) const __attribute__((always_inline)) {
		int ret = 0;
		//serial_print("SPCR & ");
		//serial_phex(val);
		//serial_print("\n");
		[COLOR="#FF0000"]SIM_SCGC6 |= SIM_SCGC6_SPI0; [/COLOR]
		if ((val & (1<<DORD)) && (SPI0_CTAR0 & SPI_CTAR_LSBFE)) ret |= (1<<DORD);

avr_emulation.h is in the installation directory, teensy3 directory. For MS Windows (Linux/MAC would differ of course) and the default installation path would lead to this path
C:\Arduino\hardware\teensy\cores\teensy3
 
I finally got this working...

The following are the things to do when using the RFM69 with the Teensy 3.x with the Low Power Labs RFM69 Library.

  1. Modify the RFM69 library. Comment out the line which initializes the SPI mode. Add a line which sets the pin mode of the interrupt pin to INPUT.
    In the RFM69::initialize() function, in RFM69.cpp, comment out this line:
    //SPI.setDataMode(SPI_MODE0);
    and just below it, add this line
    pinMode( _interruptPin, INPUT );​

Eric

I committed a fix for this bug.

https://github.com/PaulStoffregen/cores/commit/d1b989b883323d08456a60e9d9119cf1bed75318

I realize this is an old thread, but if you still have this project going, please let me know if this solves the problem for you?

Hello,
Sorry for bringing up an old thread - but why was it necessary to comment out the SPI.setDataMode line? And to add the pinMode() line?
 
Status
Not open for further replies.
Back
Top