RFM69W (RFM69HW) transceiver + T3

Status
Not open for further replies.

virtualdave

Well-known member
Hi all,
I was curious if anyone had tried the HopeRF's RFM69W radios with the T3? Seems like a promising upgrade to their older radios (more output power, Tx/Rx buffer, etc. and still cheap). Plus it helps satisfy my desire to get out of the uber-crowded 2.4gz band for a little T3 peer-to-peer network. Here's a little blog post about the radio:

http://lowpowerlab.com/blog/2013/06/20/rfm69-library/

I just ordered a couple to try out this morning, but thought I'd post the question while I wait to their arrival. There's an arduino library available, found here:

https://github.com/LowPowerLab/RFM69

It compiles for the T3, but no idea if it actually works yet. Just curious if anyone had any experience with these before I dive in in a couple days.

Cheers,
David
 
I've used the RFM12 but haven't seen the version you're talking about.
Also, the RFM22 is popular.
 
Hi Steve,
I have several of both and was getting ready to try out the RFM22 with the T3 and got sidetracked with the specs on this newer radio. What library did you use for the RFM12?
Thanks,
David
 
Well finally got time to sit down and look at these radios. And unfortunately all I can do is look :( I've downloaded the library linked above and am trying out the 2 sample sketches (node & gateway). Problem is that it doesn't seem to get beyond the initialization of the radio. Here's my connection set-up:

RFM69HW GND*2, NC (pin 16 on radio) >> connected to ground (pin 16 per radio documentation)
RFM69HW 3v3 >> regulated 3V3 supply
RFM69HW MISO >> teensy3 pin 12
RFM69HW MOSI >> teensy3 pin 11
RFM69HW SCK >> teensy3 pin 13
RFM69HW NSS >> teensy3 pin 10

same set-up for second RFM69HW + teensy3 combo

all share common ground.

I modified the gateway & node sketches since both are set to work with the extra hardware on the developer's "moduino" set-up. Here's my modified gateway.ino sketch:

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           2 
#define SERIAL_BAUD   115200

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

void setup() {
  
  Serial.begin(SERIAL_BAUD);
  delay(10);

  
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  // next 2 lines added to see if we every get past this step, and we don't
  Serial.println("hello?");
  Blink(LED,20);
  
#ifdef IS_RFM69HW
  radio.setHighPower(); //uncomment only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  radio.promiscuous(promiscuousMode);
  char buff[50];
  sprintf(buff, "\nListening at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
  Serial.println(buff);
}

byte ackCount=0;
void loop() {
  Serial.println("bob");
  Blink(LED,3);
  //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);
}

And here's my modified node.ino sketch (but haven't really done much since I haven't been able to get the gateway.ino sketch to work):

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_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           2
#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;
RFM69 radio;

void setup() {
  Serial.begin(SERIAL_BAUD);
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
#ifdef IS_RFM69HW
  radio.setHighPower(); //uncomment only for RFM69HW!
#endif
  radio.encrypt(ENCRYPTKEY);
  char buff[50];
  sprintf(buff, "\nTransmitting 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);
}


Any thoughts what might be going on? My very uneducated guess is that the radio and t3 aren't taking at the same speeds via SPI, but how to look that up, let alone address it, is beyond me at the moment (although poking around now to see what I can break).

Any advice would be greatly appreciated! These radios seem like a lovely upgrade to the older RFM12/22 radios.

Thanks,
David
 
guess is that the radio and t3 aren't taking at the same speeds via SPI

That's extremely unlikely. SPI is a synchronous protocol. The SCK signal (pin 13 on Teensy3) controls the speed.

I looked briefly at this library code. It uses the SPI library and digitalWrite for the chip select, which is very compatible with Teensy3 and nearly all Arduino compatible boards. Teensy3's SPI library faithfully duplicates the AVR timings when using that library (even though Teensy runs much faster and its SPI is capable of much higher speeds), so it's very compatible when using the library in this standard way.


However, one issue I did see in the code is this (at line 79):

Code:
  attachInterrupt(0, RFM69::isr0, RISING);

Obviously this library is expecting a 5th signal for an interrupt to be connected to pin 0 on Teensy3. I didn't see any info on either page about connection info for this RF module. If you have any documentation on the RFM69 pinout that clearly identifies one pin as an interrupt output, connect it to pin 0 on Teensy. (on an Arduino Uno, pin 2 is actually interrupt 0... on Teensy3 the interrupt numbers and pin numbers are the same)

You could also ask Felix about this interrupt pin.

Felix, if you're reading this, recent versions of Arduino have added a digitalPinToInterrupt(pin) macro in pins_arduino.h, meant for library authors to allow their libraries to accept a digital pin number in a begin() or similar function. The idea is to let the user specify which pin (as a digital pin number, which they understand better because it's the number actually printed on the circuit board and most documentation). You can use digitalPinToInterrupt(pin) to turn it into the number to pass into attachInterrupt(). If the pin doesn't have interrupt capability, digitalPinToInterrupt() resolves to -1.

It's also a preprocessor macro, so you can check the version of Arduino the user has supports it, like this:

Code:
#ifdef digitalPinToInterrupt
  int i = digitalPinToInterrupt(pin);
  if (i >= 0) attachInterrupt(i, myfunction);
#else
  // guess which interrupt the user really wanted, or fall back to a constant, or...??
#endif

Making the pins parameters in a begin() function or the object's constructor (when the user has to declare instances of the object) is a nice convention many other libraries use, including most of the ones that come with Arduino. It makes the hardware connection more flexible for people using several libraries together, and it also tends to document the required connections and make them more apparent to users. I hope you'll consider using this convention in future libraries?
 
Last edited:
Thanks, Paul. I'll ping Felix directly about the interrupt pin and report back. In my many hours trying to figure this out last night I noticed it was hanging at:
Code:
radio.initialize(FREQUENCY,NODEID,NETWORKID);

many print messages later this ended up being the culprit:
Code:
SPI.setDataMode(SPI_MODE0);
which doesn't make any sense (to my limited knowledge in this area!) since it seems to a very standard SPI setting for arduino.

now it hangs at sending data (radio.send, radio, radio.sendWithRetry), so I'll investigate the interrupt pin.

Thanks for your help! I'll report back as I learn more.

David
 
OK, so I'm close. Lots of print statements to figure this out :)

For those of you playing along, pin DIO0 on the radio is the IRQ pin. It was still hanging till I finally realized the pinMode was never declared for the interrupt pin (i.e. an INPUT pin).

So here's that I've found so far:
in RFM69.h, this line:
Code:
#define RF69_IRQ_PIN
needs to be set the actual pin you are using on the T3 (pin 2 for me)

Then in RFM69.c, this line:
Code:
attachInterrupt(0, RFM69::isr0, RISING);

should be changed to help minimize the number of places the interrupt pin needs to be set:
Code:
attachInterrupt(_interruptPin, RFM69::isr0, RISING);


Then added this line to RFM69::initialize
Code:
pinMode(_interruptPin, INPUT);

It's at least not locking up now. Now to set up the receiver and see what damage I've really done :)

David
 
Hi virtualdave, did you get it working? I am getting my RFM69HW with Arduino reset when sendWithReply is called.

You say that AttachInterrupt(0, ...) should be changed to AttachInterrupt(_interruptPin, ...), but according to the doc:

http://arduino.cc/es/Reference/AttachInterrupt

the first parameter to AttachInterrupt is not the PIN number, but the interrupt number, which is 0 for PIN 2 in most Arduinos. So I think this was correct. Did you get it working?

What I might try when I get back home is adding the missing the call to pinMode(...).

Please let me know if you got it working

Thanks!

OK, so I'm close. Lots of print statements to figure this out :)

For those of you playing along, pin DIO0 on the radio is the IRQ pin. It was still hanging till I finally realized the pinMode was never declared for the interrupt pin (i.e. an INPUT pin).

So here's that I've found so far:
in RFM69.h, this line:
Code:
#define RF69_IRQ_PIN
needs to be set the actual pin you are using on the T3 (pin 2 for me)

Then in RFM69.c, this line:
Code:
attachInterrupt(0, RFM69::isr0, RISING);

should be changed to help minimize the number of places the interrupt pin needs to be set:
Code:
attachInterrupt(_interruptPin, RFM69::isr0, RISING);


Then added this line to RFM69::initialize
Code:
pinMode(_interruptPin, INPUT);

It's at least not locking up now. Now to set up the receiver and see what damage I've really done :)

David
 
Ok, sorry, I noticed attachInterrupt(0, ...) is right for Teensy (not for Arduino), so my only hope is the missing pinMode.

Anyways, please tell us if you finally got it working, thanks!

Hi virtualdave, did you get it working? I am getting my RFM69HW with Arduino reset when sendWithReply is called.

You say that AttachInterrupt(0, ...) should be changed to AttachInterrupt(_interruptPin, ...), but according to the doc:

http://arduino.cc/es/Reference/AttachInterrupt

the first parameter to AttachInterrupt is not the PIN number, but the interrupt number, which is 0 for PIN 2 in most Arduinos. So I think this was correct. Did you get it working?

What I might try when I get back home is adding the missing the call to pinMode(...).

Please let me know if you got it working

Thanks!
 
On the t3 any pin could be an interrupt. In the RF69 library it was hardcoded to interrupt 0, which in t3-land is pin 0, which I was using for serial1 communications. So I changed it to 2. And to make it easier for future edits, just changed any other calls using pin 0 to refer to RF69_IRQ_PIN.

I got it to work, but was losing packets right and left and haven't had a chance to see what I might have doing wrong.

David
 
...so my only hope is the missing pinMode.

Anyways, please tell us if you finally got it working, thanks!

After making the changes above, yes I got it working using the gateway & node sketches that came with the library. Not sure what you mean by "my only hope is the missing pinMode". If you make the changes I suggest above you should be able to get 2 radios talking. But as I said...I was having some issues with dropped packets and haven't had a chance to investigate it further.

David
 
I'm working with the RFM22 device and library. Working OK. After I RTFM'd to find that I must ground the SDN pin!
I too plan to change the library code for establishing the interrupt pin number; the library code is as you say, hard coded to pin 0, 1 or 2, for up to 3 radio modules on one CPU.

I have this wired up with a 2mm socket soldered to the RFM22s, 0.1 in. sockets on the Teensy 3, and plug-jumpers between the two. I want a teensy (!) breakout board for the RFM22. The best one I've found so far isn't as small as I like...
http://modtronicsaustralia.com/shop/rfm22b-breakout-board-bare-pcb-v2-wireless-transciver/
Ordered but status is backordered.

Sparkfun has one but it's overpriced and kind of large. My goal is to use sub-GHz radios for range, and ensure they are a lot less expensive in total, than the XBee Series 1 2.4GHz. It's a challenge, since many apps can be done with the XBee alone and its built-in firmware for analog/digital I/O and transmission. But the XBee 802.15.4 with a 2MHz bandwidth channel per 802.15.4 is an overkill at the radio level, for simple apps. The XBee S1 mesh network protocol (DigiMesh) is an alternative if need be, to offset the shorter range of 2.4GHz @ 2MHz channel bandwidth.
Well, anyway, just fooling with RFM22's for things like wireless gardening battery powered water valve and so on.
 
Last edited:
Hi all,
I was curious if anyone had tried the HopeRF's RFM69W radios with the T3? Seems like a promising upgrade to their older radios (more output power, Tx/Rx buffer, etc. and still cheap). Plus it helps satisfy my desire to get out of the uber-crowded 2.4gz band for a little T3 peer-to-peer network. Here's a little blog post about the radio:

http://lowpowerlab.com/blog/2013/06/20/rfm69-library/

I just ordered a couple to try out this morning, but thought I'd post the question while I wait to their arrival. There's an arduino library available, found here:

https://github.com/LowPowerLab/RFM69

It compiles for the T3, but no idea if it actually works yet. Just curious if anyone had any experience with these before I dive in in a couple days.

Cheers,
David

at lowpowerlab.com
http://lowpowerlab.com/blog/2013/06/20/rfm69-library/
The table comparing the RFM12 to the RFM69 has some minor errors, e.g., the RFM12B's spec sheet says TX power in the 433MHz band is 3-5dBm (0dBm = 1mW, 3dBm = 2mW, etc) whereas tej website table at lowpowerlab.com says 0dBm. With even a modest antenna, 2mW in this RF band, combined with a choice of 60KHz bandwidth for low volume data, yields very good range - at least 100m for indoor-to-outdoor (walls in the path).

To be sure, the high power RFM69HW has good use cases too. But if battery powered, the transmitter % on-time (duty cycle) has to be very, very low (can't use polling) with small batteries.
 
Finally got it working

With "missing pinMode" I meant I was going to try to add the missing pinMode(2, INPUT) line, but it looks like in Arduino pins are set as input by default, so finally it made no difference.

But I accidentally found what the problem was. I mistankenly left the interrupt pin floating, and suddenly it started mostly working. It looks like the 3.3V DIO0 output from RFM69HW were not enough to fire the interrupt, so I made a 3.3V to 5V level shifter as suggested here: http://electronics.stackexchange.com/questions/81580/step-up-3-3v-to-5v-for-digital-i-o

Now it works like a charm.

Also, I was using a 1K/2K voltage divider for the SPI bus (5V from Arduino to 3.3V on the RFM69), and I think the SPI bus is running at 8Mhz by default (the Arduino clock is 16Mhz and rfm69 library sets the SPI divider to 2). I found it but more stable by setting the divider to 8, so I guess SPI clock is running at 2Mhz. Probably 8Mhz is too high frequency for this resistive voltage divider, might not be compying with the rise and fall times.

Hope is helps someone.

Thanks for your help!

After making the changes above, yes I got it working using the gateway & node sketches that came with the library. Not sure what you mean by "my only hope is the missing pinMode". If you make the changes I suggest above you should be able to get 2 radios talking. But as I said...I was having some issues with dropped packets and haven't had a chance to investigate it further.

David
 
For the RFM22 (and other HopeRF modules that use this Si Labs RF chip), the wiring crib notes omitted that the SDN pin must be grounded.
The SPI worked fine for me as in the RFM22 library.
The example test program has, in the loop() function, calls to all the various test functions.
This program of course has to work with each radio, except for the receive test, which depends on another radio actually transmitting, using the same test program.
My tests are with the Teensy 3 so I don't have 5V level shifting issues. I ran the radio on 3.3V.
 
With "missing pinMode" I meant I was going to try to add the missing pinMode(2, INPUT) line, but it looks like in Arduino pins are set as input by default, so finally it made no difference.

But I accidentally found what the problem was. I mistankenly left the interrupt pin floating, and suddenly it started mostly working. It looks like the 3.3V DIO0 output from RFM69HW were not enough to fire the interrupt, so I made a 3.3V to 5V level shifter as suggested here: http://electronics.stackexchange.com/questions/81580/step-up-3-3v-to-5v-for-digital-i-o

Now it works like a charm.

Also, I was using a 1K/2K voltage divider for the SPI bus (5V from Arduino to 3.3V on the RFM69), and I think the SPI bus is running at 8Mhz by default (the Arduino clock is 16Mhz and rfm69 library sets the SPI divider to 2). I found it but more stable by setting the divider to 8, so I guess SPI clock is running at 2Mhz. Probably 8Mhz is too high frequency for this resistive voltage divider, might not be compying with the rise and fall times.

Hope is helps someone.

Thanks for your help!

Ahh...you aren't using a teensy 3 at all (which is why most of the notes in this thread don't apply to your application). Probably should have mentioned that up front (since the title of the thread was focused on this radio with the teensy 3 (T3).
Glad you got it to work.
David
 
David,

Did you get the RFM69 to work reliably yet? I'm looking at using this with a Teensy 3.

If I understand what you explained, the library from LowPowerLabs should work with the Teensy 3 as-is if pin 0 is used for the interrupt. Is this correct? I plan to use this along with WizNet Ethernet and SD FLASH adaptor.

Thanks,

Eric

EDIT: See post #67 for instructions on how to get this to work.
 
Last edited:
The author of the RF22 library for Arduino (and works with one change for Teensy3) - is creating a new library to be called RadioHead (not the website). He says he has added RFM69 support.
The RF22 library allows for a message size max of 255 bytes, and the lib takes care of fragmenting this though the FIFO is smaller than 255.
The new lib, Mike said, will continue to have reliable datagrams (ACKs and retransmit), router, and mesh network options.

I did a recent test with four radios.. RF22 lib, two sending many messages/sec w/ACKs to one node. Ran one million messages with no hangups. This was at 20dBm (100mW).

One gotcha with all these radio chips, which all use SiLabs 44xx family chips, e.g., Si4432, HopeRF, Dorji via Tindie) --
Don't read the RSSI or do any other SPI transaction in your code while the library code as either receive or transmit active - as there will be a conflict in the interrupt service in concurrent access to the SPI. Going to idle mode - you can access SPI registers since there will be no interrupts. Or you could disable interrupts in the app level while doing the SPI transaction.
 
Last edited:
Yes, the RF22 library. In the RF69 writeup, he says "Coming soon: classes for datagrams, reliable datagrams, routers and meshes". This would be the same stack he has now for the RF22.
The RF22 library has all the protocols - reliable datagram, mesh networking (which a switch mote would need - much as the Insteon, Z-wave and ZIgbee stuff in home automation uses).
I assume that the intent is to make the RFM69 be a swap-out in the library stack, for the RFM22, and all the higher protocols would work the same.
I use the RF22 because it produced 20dBm transmit with 85mA and the Teensy 3's Vout is limited to 100mA.
Truly, at 433MHz, the range with far less than 20dBm is adequate and battery conserving in some apps where a poll is done each wakeup.
I see the value in the mesh network capability of the library. And in a mesh, you probably don't want link layer encryption - you want encryption at the application layer so that the message can hop among the nodes and only the destination node needs-to/can decrypt. The intermediate nodes in the mesh shouldn't be able to decrypt as they are not the recipient. This is true for the case here, and also true in other mesh networks.

The gotcha I spoke of means the use of the SPI port has to be mutually exclusive among the non-ISR applications for all SPI devices (radio, Wiznet) and the ISRs. I've done a lot with Wiznet modules.
The AVR code floating around for these things tends to be really myopic and sloppy. Myopic in that any one app, like a Wiznet driver, assumes it owns the SPI port.
The Teensy version of the radio library (and I assume, the AVR version too), uses an interrupt for the radio. The Wiznet drivers - some do use interrupts, some don't and instead loop and poll.

Teensy3 makes all this easier because it is not so RAM constrained that shortcuts and kludges are done, as they have to be for the AVRs.
see also http://forum.pjrc.com/threads/25578...ssages-(reliable-datagrams)?highlight=million
 
Last edited:
The Ethernet library makes use of the SPI port from non-interrupt context, so it's very likely to conflict with this library.

Perhaps Teensy3, as a platform, should recommend an interrupt priority level for SPI-usage-from-interrupts? Then non-interrupt software, like the Ethernet and SD libraries, could use priority masking to disable those relatively low priority interrupts without having to disable higher priority interrupts that really need rapid service.

Of course, this system would be totally voluntary. The real challenge is persuading library authors to use it, which means adding some #ifdef stuff specific to Teensy3. But that effort can't even really start until I come up with an official recommendation....

Does anyone have any opinions on this?
 
Coordination of hardware assets like SPI, I2C, SD card, etc., is difficult without an operating system - Teensy/Arduino being bare-metal.

What would be ground-breaking is a coordinated/universal mechanism for mutual exclusion. Voluntary but standardized. This is what's needed to make shareware on bare metal really work correctly.
It would be difficult for Arduino's visionaries to see the merit in this. But Teensy could rise above.
Arduinoians have already learned some of this and I wonder how many more pizzas were sold to students stuck in the midnight-oil of not knowing these things.

EDIT: I think step one should just be mutual exclusion PLUS all newbies need to know when to disable interrupts for a few instructions and an SPI call.
 
Last edited:
Yes, seems like it would be useful to have a multi-tasking support in the arduino library. I searched for Arduino RTOS and found this: https://code.google.com/p/rtoslibs/ Would something like this help address the issues at hand?

On the project I'm working on now, the Teensy would initiation the communication using an EthernetClient every 10 seconds, and sensor nodes will be sending data to the Teensy gateway once every minute using an RFM69 transceiver. It would not be good if the conflict caused the gateway to hangup. Would it run more reliably if I put the RFM69 radio to sleep while sending/receiving messages over Ethernet?
 
I started a new thread, specifically to discuss this mutex issue.

http://forum.pjrc.com/threads/25582-SPI-sharing-between-interrupts-and-main-program

Let's continue this conversation about a future mutex mechanism over there, and leave this thread about the specifics of using these radio modules on Teensyduino as it exists today.

EDIT: when I someday implement this in Teensyduino, I'm only going to read that new thread in the Suggestions forum. I've put this issue on my TODO list, but only that new thread is on my written list. Please comment there if you have any input I should see and consider when this moves from "pipe dream" to "beta test".
 
Last edited:
Yes, seems like it would be useful to have a multi-tasking support in the arduino library. I searched for Arduino RTOS and found this: https://code.google.com/p/rtoslibs/ Would something like this help address the issues at hand?

On the project I'm working on now, the Teensy would initiation the communication using an EthernetClient every 10 seconds, and sensor nodes will be sending data to the Teensy gateway once every minute using an RFM69 transceiver. It would not be good if the conflict caused the gateway to hangup. Would it run more reliably if I put the RFM69 radio to sleep while sending/receiving messages over Ethernet?
I've used FreeRTOS a lot on other projects. And I've used the FreeRTOS port that is downloadable here, for Teensy 3 and teensyduino libraries. Since I know it well, I elected to set the config. for non-preemptive task scheduling. This hugely simplifies dealing with all the non-reentrant library code.

But for the initial RFMxx radios and Wiznet and maybe SD card - I'd suggest getting it all going with a big polling loop - because structuring things for an RTOS is quite a bit of work - far less without preemption.
There are two or so other RTOSes ready to go for Teensy. And a couple of cooperative (run to completion) schedulers.
 
Status
Not open for further replies.
Back
Top