-
• #2
Personally I haven't, but I'd be very interested if someone did produce a module for them. It doesn't look hard. I'm not sure what they add over the NRF modules though?
Ideally we'd come up with some kind of shared 'low power radio' module that would use either that or the NRF, and would handle syncing transmitters/receivers so that you didn't have to have the receiver on all the time (which draws 11mA).
-
• #3
They operate at a lower radio frequency and you can get quite a bit more distance on them.
I have one of the wireless modules here so maybe I will have a play around. I guess I just need to connect it up to the SPI interface and work from there... -
• #4
Ahh, good point. Yes - that'd make a big difference...
-
• #5
I had a look but if I'm honest I don't know where to start.
Once its connected is there any way I can just test by reading some information on it?
-
• #6
Which one are you trying, the RFM12B?
The info you need will be in the datasheet and the arduino library
You can follow the steps that the library uses to initialise: https://github.com/LowPowerLab/RFM12B/blob/master/RFM12B.cpp#L114
Looks like the XFER function's equivalent in Espruino is just:
function XFER(cmd) { SPI1.send([cmd>>8,cmd], cs_pin); }
so you can start off with:
var C = { RF_SLEEP_MODE : 0x8205, RF_WAKEUP_MODE : 0x8207, RF_TXREG_WRITE : 0xB800 }; function init() { // setup spi // then... XFER(0x0000); // intitial SPI transfer added to avoid power-up problem XFER(C.RF_SLEEP_MODE); // DC (disable clk pin), enable lbd // wait until RFM12B is out of power-up reset, this takes several *seconds* XFER(C.RF_TXREG_WRITE); // in case we're still in OOK mode while (digitalRead(RFM_IRQ) == 0) XFER(0x0000); // ... }
So if the function finishes then at least you've had some success in talking to the chip and getting it to lower the IRQ line.
That last bit is nasty though, and if it works I'd consider re-writing it as:
if (!digitalRead(RFM_IRQ)) { console.log("IRQ shouldn't be low right now!"); return; } var interval = setInterval(function() {XFER(0x0000);}, 10); setWatch(function() { clearInterval(interval); console.log("IRQ lowered"); // do next stuff }, RFM_IRQ, {edge:"falling", repeat:false});
-
• #7
Progress...
function XFER(cmd) { SPI1.send([cmd>>8,cmd], B8); } var C = { RF_SLEEP_MODE : 0x8205, RF_WAKEUP_MODE : 0x8207, RF_TXREG_WRITE : 0xB800 }; function init() { // setup spi SPI1.setup({sck:B3,miso:B4,mosi:B5}); // then... XFER(0x0000); // intitial SPI transfer added to avoid power-up problem XFER(C.RF_SLEEP_MODE); // DC (disable clk pin), enable lbd // wait until RFM12B is out of power-up reset, this takes several *seconds* XFER(C.RF_TXREG_WRITE); // in case we're still in OOK mode while (digitalRead(B9) === 0) XFER(0x0000); // ... }
Okay so good progress.
If I load the above code thendigitalRead(B9)
the interpreter returns0
.
Run funtioninit()
CheckingdigitalRead(B9)
returns1
-
• #8
great! I guess it's just a matter of hacking through and implementing the rest of the initialisation code.
I just realised I got the polarity wrong in my last bit of code :)
-
• #9
I knew it was too good to be true!
On further investigation it appears as soon as I send the first command, in this case when
init()
is called the first command that is sent is0x0000
, the IRQ pin goes high and stays there unless I cycle the power to the module.Anyone got any suggestions?
-
• #10
Can I just check that these connections are correct.
Espruino --> RFM12B
SCK (B3) ----- SCK
MISO (B4) ----- SDI
MOSI (B5) ----- SDO
NSS_PIN (B8) ----- nSEL (active low)
IRQ (B9) ----- nIRQ (active low) -
• #11
It could be the MISO and MOSI are reversed?
-
• #12
That's weird. So I started again from scratch, hence the pulling all the wires out and making sure I had got the physical connections correct.
@TrapperBob, I tried swapping the MISO and MOSI but that is definitely not it. Definitely worth a try though!
I setup a setWatch on the IRQ pin to log to the console when the state changes (rising and falling).
Now when I send multiple commands I am receiving plenty of IRQ level changes on the console. I'm sure this wasn't working before and as far as I can understand this is proof that the Espruino is at least talking to the module and it is responding correctly??Looking at the Arduino libraries for the RFM12B, I think quite a bit of the code is related to some sort of software SPI. We don't have to worry about this on the Espruino :)
-
• #13
@StuntMonkeh it seems like good news if the IRQ line is moving.
Yes, IIRC quite a lot of the top part of the RFM12B file is for bit-bashed SPI - which isn't needed :)
-
• #14
WHAT THE HELL!!!! Its stopped working, I unplugged the board for some reason and then had to plug back in and reload the code and now it doesn't work.
This is what I have. I was simply running
spiInit()
and it was triggering the IRQ up and down.var C = { // maximum transmit / receive buffer: 3 header + data + 2 crc bytes RF_MAX : (RF12_MAXDATA + 5), // RF12 command codes RF_RECV_CONTROL : 0x94A0, RF_RECEIVER_ON : 0x82DD, RF_XMITTER_ON : 0x823D, RF_IDLE_MODE : 0x820D, RF_SLEEP_MODE : 0x8205, RF_WAKEUP_MODE : 0x8207, RF_TXREG_WRITE : 0xB800, RF_RX_FIFO_READ : 0xB000, RF_WAKEUP_TIMER : 0xE000, // RF12 status bits RF_LBD_BIT : 0x0400, RF_RSSI_BIT : 0x0100, // bits in the node id configuration byte NODE_BAND : 0xC0, // frequency band NODE_ID : 0x1F, // id of this node, as A..Z or 1..31 RETRIES : 8, // stop retrying after 8 times RETRY_MS : 1000, // resend packet every second until ack'ed }; var RFM_IRQ = B9; var SPI_CS = B8; var SPI_MOSI = B5; var SPI_MISO = B4; var SPI_SCK = B3; var nodeid; // address of this node var group; // network group var frequency; // Frequency within selected band var rxfill; // number of data bytes in rf12_buf var rxstate; // current transceiver state var ezInterval; // number of seconds between transmits var ezSendBuf = new Array(RF12_MAXDATA); // an empty array of length 100 var ezSendLen; // number of bytes to send var ezPending; // remaining number of retries var ezNextSend = new Array(2); // when was last retry [0] or data [1] sent var rf12_crc; // running crc value var rf12_buf = new Array(RF_MAX); // recv/xmit buf, including hdr & crc bytes var rf12_seq; // seq number of encrypted packet (or -1) var rf12_fixed_pkt_len; // fixed packet length reception var seqNum; // encrypted send sequence number var cryptKey = new Array(4); // encryption key to use //void (*crypter)(uint8_t); // does en-/decryption (null if disabled) function XFER(cmd) { SPI1.send([cmd>>8,cmd], SPI_CS); } function spiInit() { SPI1.setup({sck:B3,miso:B4,mosi:B5}); // setup SPI XFER(0x0000); // intitial SPI transfer added to avoid power-up problem XFER(C.RF_SLEEP_MODE); // DC (disable clk pin), enable lbd // wait until RFM12B is out of power-up reset, this takes several *seconds* XFER(C.RF_TXREG_WRITE); // in case we're still in OOK mode XFER(0x80C7 | (band << 4)); // EL (ena TX), EF (ena RX FIFO), 12.0pF XFER(0xA000 + frequency); // 96-3960 freq range of values within band XFER(0xC606); // approx 49.2 Kbps, i.e. 10000/29/(1+6) Kbps XFER(0x94A2); // VDI,FAST,134kHz,0dBm,-91dBm XFER(0xC2AC); // AL,!ml,DIG,DQD4 if (group !== 0) { XFER(0xCA83); // FIFO8,2-SYNC,!ff,DR XFER(0xCE00 | group); // SYNC=2DXX; } else { XFER(0xCA8B); // FIFO8,1-SYNC,!ff,DR XFER(0xCE2D); // SYNC=2D; } XFER(0xC483); // @PWR,NO RSTRIC,!st,!fi,OE,EN XFER(0x9850); // !mp,90kHz,MAX OUT XFER(0xCC77); // OB1,OB0, LPX,!ddy,DDIT,BW0 XFER(0xE000); // NOT USE XFER(0xC800); // NOT USE XFER(0xC049); // 1.66MHz,3.1V } setWatch(function() { console.log("IRQ State"); // do next stuff }, RFM_IRQ, {edge:"both", repeat:true});
-
• #15
Did you have some code in there that had been save()d already? That could be causing you problems I guess ...
Maybe there is some other pin (a reset pin?) that needs its state changing first...
Also aren't you supposed to wait for it to initialise at some point? You don't appear to be doing that...
The code is looking good though. It'd make a module really easily.
-
• #16
I figured I must have sent the RFM12B module some commands that must have caused it to jump into life.
I have tried sending just the first two commands and then manually sending the rest. No luck. I have had a look at different uses in other projects, all wired the same way. No reset pin.
I had another go tonight, starting from scratch rewiring all over again but I'm back square one with the IRQ line just being triggered high as soon as I send
(0x0000)
.I tried just sending the first two commands
setWatch(function() { console.log("IRQ State"); // do next stuff }, B9, {edge:"both", repeat:true}); function XFER(cmd) { SPI1.send([cmd>>8,cmd], B8); } SPI1.setup({sck:B3,miso:B4,mosi:B5}); // setup SPI function init(){ XFER(0x0000); XFER(0x8205); }
-
• #17
I'm looking at the datasheet, and it looks like the nIRQ pin is active low. Furthermore, in the case of a power-on reset, it sounds like the nIRQ should be reset by simply reading the status:
• POR: both the nIRQ pin and status bit can be cleared by the read status command
As I interpret that, you're getting correct behavior, so far. nIRQ starts out getting pulled low, then you read the status, which clears the interrupt, and IRQ goes high again. It wasn't clear to me that a RFM12B that's just sitting there will generate IRQ activity - especially when all the radio-related functionality was just turned off (with 0x8205)
Why aren't you recording what the RFM12B is sending back? You should certainly be getting data back when you send 0x0000. I think looking for this would be a better way of seeing whether you're communicating with the device.
function XFER(cmd) { console.log(SPI1.send([cmd>>8,cmd], B8)); }
-
• #19
I invested in a cheapo Saleae clone logic analyser so I can see what's going.
It was my understanding that was lacking, its starting to make a little more sense now :)
Has anyone done anything with these on the Espruino platform?
They are used extensively in other projects it would be handy to have a module for them.