Category Archives: 802.15.4

Updated MRF24J40 library code, now easier to use

I’ve just substantially updated my library code for dealing with Microchip’s MRF24J40 modules on AVR microcontrollers, making it much much easier to use. It’s now based on callbacks for handling rx/tx packets, so you don’t need to know anywhere near as much about the module’s internals anymore. The tradeoff is a bit more ram usage.

mrf_reset and mrf_init now take parameters to ports and pins, so you no longer need to mess around with defines in the library headers any more.

#include "lib_mrf24j.h"
    mrf_reset(&PORTB, PINB5);   // reset pin
    mrf_init(&PORTB, PINB0);  // chip select pin

You no longer need to manually work with the interrupts, you just need to set up the ISR for the pin you’ve chosen to connect to the MRF24J40’s INT pin, for example, for my case, using INT0. (Remember to add a EIMSK |= _BV(INT0); somewhere too!)

ISR(INT0_vect) {
    mrf_interrupt_handler();
}

The interrupt handler takes care of reading in received rf data, and keeping it in a local buffer. It always contains the most recent packet. To do something with the received data, call mrf_check_flags() pretty often. It takes two function pointers as parameters, one which will be called for rx, and one for tx. Here’s a snippet from my main().

    // set the pan id to use
    mrf_pan_write(0xcafe);
    // set our address
    mrf_address16_write(0x6001);
    while (1) {
        // Call this pretty often, at least as often as you expect to be receiving packets
        mrf_check_flags(&handle_rx, &handle_tx);
        if (time_to_send()) {
            mrf_send16(0x4202, 4, "abcd");
        }
    }

And here’s some example rx/tx callback handlers.

void handle_rx(mrf_rx_info_t *rxinfo, uint8_t *rx_buffer) {
    printf_P(PSTR("Received a packet: %d bytes long\n"), rxinfo->frame_length);
    printf_P(PSTR("Packet data:\n"));
    for (int i = 0; i <= rxinfo->frame_length; i++) {
        printf("%x", rx_buffer[i]);
    }
    printf_P(PSTR("\nLQI/RSSI=%d/%d\n"), rxinfo->lqi, rxinfo->rssi);
}
 
void handle_tx(mrf_tx_info_t *txinfo) {
    if (txinfo->tx_ok) {
        printf_P(PSTR("TX went ok, got ack\n"));
    } else {
        printf_P(PSTR("TX failed after %d retries\n"), txinfo->retries);
    }
}

The library code is available here, and also on github (lib_mrf24j)

Complete demo code for a module connected to a PJRC Teensy 2.0 board is here and also on github (You’ll probably have to edit paths in the Makefile)

Dresden Elektronik ATmega128RFA1 breakout boards, deRFmega128

I’ll write up more about the parts themselves later, but I finally got boards made for Dresden Elektronik’s deRFmega128 modules, both made, and now assembled and tested. Briefly, these are a module with Atmel’s ATmega128RFA1 (a combined ATmega128 with a 802.15.4 2.4 Ghz transceiver on a single chip) with either a chip antenna, or a connector for your own antenna. These are TINY, and they also manage to pack a 1Mbit EEPROM on the module, for your own use. All for 21€

I’ve only tested a basic blinky thing so far, but it’s good to know that I can finally start doing something with these cool modules.

Here’s one up on a breadboard.

These modules are the same length as PJRC’s Teensy boards, but they have leads on 1.27mm pitch, not 2.54mm pitch. Lots more pins, but you’ll need some parts. For the 1.27mm socket holders, I ordered direct from Samtec. [1] Dresden recommends SLM Series, but I ordered SMS series. It may have been price, or availability, who knows. I ordered SMS-123-02-G-S, and the pins are really way too long on those. SMS-01-G-S would have been a better choice. Also, and I don’t know if the SLM would have been better, but I have a little bit of a hard time getting the modules into these sockets. They seem to “spring” out a little bit, to point that I initially thought I had failed to make my pcbs properly. Some of the pins weren’t making good contact. I have my modules mounted “upside down” with the silver RF can facing down. That’s the way the module leads are longest, and gold, and the only way they fit, when I was testing out the sockets and the modules. (Before the boards got here)

I’ve now found, that they will fit in nicely with the metal can UP and click into place nicely, but that’s not pin compatible with the AVR ISP header, or the power supply I put on the breakout.

So, I have some breakouts that work just fine, if you solder the part in, and probably well enough for development before your own boards, but I’m probably going to respin them :( The modules are cool, and they just came out with a pin compatible module, with an ARM7 core, instead of the ATmega128.

I still have a spare board from this revision though, if you are at all interested, I can send you one :)

Here’s the board itself

Note, it already says rev3. That’s a story for another day :)

And to leave you, a picture of the different RF modules I’ve been working with here recently.

deRFmega128, Teensy v2 + MRF24J40MA, Xbee Series 1 + adafruit board

The current board files are available from https://github.com/karlp/karlnet/tree/master/experiments/dresden

The very basic blinking demo is also at github, should you really want it :)

[1] You can pretty much forget about getting 23pin headers from either digikey or mouser. Samtec were prompt, and had cheap enough shipping, relatively speaking. (I ordered a dozen)