Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

RFM12B Wireless module with Netduino Plus


  • Please log in to reply
24 replies to this topic

#21 mHammer

mHammer

    Member

  • Members
  • PipPip
  • 23 posts

Posted 28 May 2013 - 04:36 AM

I'm looking at the same thing with a moteino which is an integrated version of a mini pro.  I have not started yet, still waiting to get the parts.  I was doing a lot of research on more sophisticated radios (xbee, RFM22), but I thought I would start simple with the RFM12.

 

I've got this thread pegged already. :-)



#22 elettrozero

elettrozero

    Advanced Member

  • Members
  • PipPipPip
  • 58 posts

Posted 29 May 2013 - 08:32 AM

RFM12B is quite a good chip. At 433 (with a good antenna) you can pass several walls with a decent data rate at it's a lot cheeper than  xbee.

I just succeeded in sending data from atmega328p (arduino, seeduino, diavolino, moteino, wathever ....).

During these days I'll try to send back data (ack) and implement a compatible crypting system. Since you're getting moteino you won't  have problems on atmega side because they're a fine peace of machinery and the library from the maker are very very good.

 

Write a line when you'll need support on netduino side.



#23 mHammer

mHammer

    Member

  • Members
  • PipPip
  • 23 posts

Posted 14 June 2013 - 04:47 PM

What I'd like to know is with the RFM12b, what parameters in the command registers must match between sender and receiver?

 

On the arduino side, the lowpowerlabs and Jeelabs libraries are complex to me (still pretty new).  The example netduino lib uses some different parameters.

 

elettrozero, would you share some of the changes you made to the lib posted here?  I've started a little on converting the arduino lib to C# to work with the netduino.  I'm still to early in the process to see any results.



#24 elettrozero

elettrozero

    Advanced Member

  • Members
  • PipPipPip
  • 58 posts

Posted 23 July 2013 - 02:22 PM

Hi all, RF12 module is a bit tricky on Netduino+ 1st brood. On NDP2 works like a charm.

 

I'm going to post a class to control the module but bear in mind that NDP1 is a bit too slow to interact with the module as good as Arduino does. For my case is fully functional but if anybody finds any issue, please let me know. In case you need assistance for wiring write down a line.

using System;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware.NetduinoPlus;using System.Threading;namespace RFM12BLib{    public class RFM12B    {        private SPI _spiPort;        private InterruptPort interrupt;        //private OutputPort _led;        private TransceiveStates rxstate;        private byte nodeID;        private byte networkID;        public delegate void BdEventHandler(uint from, uint channel, uint value);        public BdEventHandler OnCommand;        public RFM12B(Cpu.Pin spiSelectPin, byte ID, byte netID)        {            GRP = netID;            SPI.SPI_module spi = SecretLabs.NETMF.Hardware.NetduinoPlus.SPI_Devices.SPI1;            _spiPort = new SPI(new SPI.Configuration(spiSelectPin, false, 0, 0, false, true, 2000, spi));            interrupt = new InterruptPort(Pins.GPIO_PIN_D9, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);                        InitModule(ID, RF12_433MHZ, netID, 0x07, 0x3F, 0x07);            Debug.Print("SETUP");        }        private void InitModule(byte ID, ushort freqBand, byte networkid, ushort txPower, ushort airKbps, ushort lowVoltageThreshold)        {            nodeID = ID;            networkID = networkid;            RFXX_WRT_CMD(0x0000); // intitial SPI transfer added to avoid power-up problem            RFXX_WRT_CMD(RF_SLEEP_MODE); // DC (disable clk pin), enable lbd            // wait until RFM12B is out of power-up reset, this takes several *seconds*            RFXX_WRT_CMD(RF_TXREG_WRITE); // in case we're still in OOK mode            while (!interrupt.Read())                RFXX_WRT_CMD(0x0000);                                    //CONFIGURATION            RFXX_WRT_CMD(0x80D3);//EL,EF,433band,10.0pF             //FREQUENCY SETTINGS            RFXX_WRT_CMD(0xA640); // Frequency is exactly 434/868/915MHz (whatever freqBand is)            //DATA RATE            RFXX_WRT_CMD(0xC647);//0xC647 = 4.8kbps , 8F = 2.4            RFXX_WRT_CMD(0x90A2);             // VDI,FAST,134kHz,0dBm,-91dBm             RFXX_WRT_CMD(0xC2AC);             // AL,!ml,DIG,DQD4             if (networkID != 0)            {                //RFXX_WRT_CMD(0xCA81);           // FIFO8,2-SYNC,!ff,DR                 RFXX_WRT_CMD(0xCA83);           // FIFO8,2-SYNC,!ff,DR                 RFXX_WRT_CMD((ushort)(0xCE00 | networkID)); // SYNC=2DXX;             }            else            {                RFXX_WRT_CMD(0xCA8B); // FIFO8,1-SYNC,!ff,DR                 RFXX_WRT_CMD(0xCE2D); // SYNC=2D;             }            RFXX_WRT_CMD(0xC483); // @PWR,NO RSTRIC,!st,!fi,OE,EN             RFXX_WRT_CMD((ushort)(0x9850 | (txPower > 7 ? 7 : txPower))); // !mp,90kHz,MAX OUT //last byte=power level: 0=highest, 7=lowest            RFXX_WRT_CMD(0xCC77); // OB1,OB0, LPX,!ddy,DDIT,BW0             RFXX_WRT_CMD(0xE000); // NOT USE            RFXX_WRT_CMD(0xC800); // NOT USE            RFXX_WRT_CMD(0xC043); // Clock output (1.66MHz), Low Voltage threshold (2.55V)            interrupt.OnInterrupt += new NativeEventHandler(_interruptPort_OnInterrupt);            interrupt.EnableInterrupt();            SetReceiving();            RFXX_WRT_CMD(0x0000);        }        byte[] data = new byte[20];        public void _interruptPort_OnInterrupt(uint data1, uint data2, DateTime time)        {            RFXX_WRT_CMD(0x0000);            //RECEIVING            if (rxstate == TransceiveStates.TXRECV)            {                GRP = (byte)RF12_RECV();                if (GRP == 0 || GRP == 1)                {                    if (GRP == 0)  // NULL GRP                    {                        while (interrupt.Read()) ;                        RFXX_WRT_CMD(0x0000);                        HDR1 = (byte)RF12_RECV();                    }                    else                    {                        HDR1 = GRP;                    }                    byte destId = (byte)(HDR1 & 0x7F);                    if (destId == 1)                    {                        while (interrupt.Read()) ;                        RFXX_WRT_CMD(0x0000);                        HDR2 = (byte)RF12_RECV();                        while (interrupt.Read()) ;                        RFXX_WRT_CMD(0x0000);                        LEN = (byte)RF12_RECV();                        bool ctl = ((HDR2 >> 5) & 0x04) != 0;                        bool dst = ((HDR2 >> 5) & 0x02) != 0;                        bool ack = (HDR2 & 0x80) != 0;                        for (int b = 0; b < 20; b++)                        {                            if (b < LEN)                            {                                while (interrupt.Read()) ;                                RFXX_WRT_CMD(0x0000);                                data[b] = (byte)RF12_RECV();                            }                            else                            {                                data[b] = 0;                            }                        }                        try                        {                            Debug.Print("INT |" +                                ToHex(new byte[] { GRP })                                + " | " + ToHex(new byte[] { HDR1 })                                + " | " + ToHex(new byte[] { HDR2 })                                + " | " + ToHex(new byte[] { LEN })                                + " | " + (ack ? "ACK" : " NO ACK ")                                + " | " + new string(System.Text.Encoding.UTF8.GetChars(data))                            );                        }                        catch (Exception)                        {                            Debug.Print("Invalid data");                        }                    }                                    }                else                {                    Debug.Print("G: " + ToHex(new byte[] { GRP }));                                    }                                idleMode();                    SetReceiving();                interrupt.ClearInterrupt();                            }        }                private void SendAck() {                        SendTo(SRC_ID, new byte[]{}, false, true);        }        public void SendToNoAck(byte toNodeID, byte[] data)        {            SendTo(toNodeID, data, false, false);        }        public void SendTo(byte toNodeID, byte[] data)        {            SendTo(toNodeID, data, true, false);        }        private void SendTo(byte toNodeID, byte[] data, bool requestACK, bool sendAck)        {            if (rxstate != TransceiveStates.TXIDLE)            {                idleMode();                Thread.Sleep(500);            }            HDR1 = (byte)(toNodeID | (sendAck ? RF12_HDR_ACKCTLMASK : 0));            HDR2 = (byte)(nodeID | (requestACK ? RF12_HDR_ACKCTLMASK : 0));            LEN = (byte)(data.Length + 1);            rxstate = TransceiveStates.TXSEND;            RFXX_WRT_CMD(RF_XMITTER_ON);                                    sendit(requestACK, data);            idleMode();            SetReceiving();        }        private void sendit(bool requestACK, byte[] data)        {            //SENDING            rf12_crc = crc16_update(0xFFFF, networkID);            rf12_crc = crc16_update(rf12_crc, HDR1);            rf12_crc = crc16_update(rf12_crc, HDR2);            foreach (byte b in data)                rf12_crc = crc16_update(rf12_crc, b);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(0xAA);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(0xAA);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(0xAA);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(0x2D);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(networkID);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(HDR1);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(HDR2);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(LEN);            if (LEN > 0)            {                foreach (byte b in data)                {                    while (interrupt.Read()) ;                    RFXX_WRT_CMD(0x0000);                    RF12_SEND(b);                                    }            }            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND((byte)(rf12_crc >> 8));            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND((byte)rf12_crc);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(0xAA);            while (interrupt.Read()) ;            RFXX_WRT_CMD(0x0000);            RF12_SEND(0xAA);                        /*            Debug.Print("SENT "                + ToHex(new byte[] { 0xAA }) + " | "                + ToHex(new byte[] { 0xAA }) + " | "                + ToHex(new byte[] { 0xAA }) + " | "                + ToHex(new byte[] { 0x2D }) + " | "                + ToHex(new byte[] { networkID }) + " | "                + ToHex(new byte[] { HDR1 }) + " | "                                + ToHex(new byte[] { HDR2 }) + " | "                                + ToHex(new byte[] { LEN }) + " | "                 + new string(System.Text.Encoding.UTF8.GetChars(DATA)) + " | "                 + ToHex(new byte[] { (byte)rf12_crc }) + " | "                 + ToHex(new byte[] { (byte)(rf12_crc >> 8) }) + " | "                + ToHex(new byte[] { 0xAA }) + " | "                + ToHex(new byte[] { 0xAA }) + " | ");            */        }        public void idleMode()        {            RFXX_WRT_CMD(RF_IDLE_MODE);            rxstate = TransceiveStates.TXIDLE;                    }        public void SetReceiving()        {                        rf12_crc = 0xFFFF;            if (rxstate != TransceiveStates.TXRECV)            {                                RFXX_WRT_CMD(RF_RECEIVER_ON);                rxstate = TransceiveStates.TXRECV;            }                    }        /*        private void resetFIFO()        {            RFXX_WRT_CMD(0xCA81);            RFXX_WRT_CMD(0xCA83);        }        */        private ushort SPI_WRITE_READ(ushort cmd)        {            ushort[] readBuffer = new ushort[1];            _spiPort.WriteRead(new ushort[] { cmd }, readBuffer);            return readBuffer[0];        }        private void SPI_WIRTE(ushort cmd)        {            _spiPort.Write(new ushort[] { cmd });        }        ushort[] _readBuf = new ushort[1];         ushort[] _writeBuf = new ushort[1];         private ushort RFXX_WRT_CMD(ushort cmd)         {             _writeBuf[0] = cmd;             _spiPort.WriteRead(_writeBuf, _readBuf);             return (_readBuf[0]);         }                private ushort RF12_RECV()        {            ushort FIFO_data;                        //RFXX_WRT_CMD(0x0000);                        FIFO_data = RFXX_WRT_CMD(0xB000);            return (ushort)(FIFO_data & 0x00FF);        }                private void RF12_SEND(byte data)        {            RFXX_WRT_CMD((ushort)(RF_TXREG_WRITE | data));        }                private enum TransceiveStates        {            TXIDLE,            TXRECV,            TXSEND        };        private enum SleepModes        {            SLEEP_MODE_IDLE = 0,            SLEEP_MODE_PWR_DOWN = 1,            SLEEP_MODE_PWR_SAVE = 2,            SLEEP_MODE_ADC = 3,            SLEEP_MODE_STANDBY = 4,            SLEEP_MODE_EXT_STANDBY = 5        }        private byte GRP = 0x01;        private byte HDR1;        private byte HDR2;        private byte LEN;                private byte SRC_ID        {            get { return (byte)(HDR2 & RF12_HDR_IDMASK); }        }        private byte DST_ID        {            get { return (byte)(HDR1 & RF12_HDR_IDMASK); }        }        private ushort crc16_update(ushort crc, byte data)        {            int i;            crc = (ushort)(crc ^ ((ushort)data << 8));            for (i = 0; i < 8; i++)            {                if ((crc & 0x8000) == 0x8000)                    crc = (ushort)((crc << 1) ^ 0x1021);                else                    crc <<= 1;            }            return crc;        }        private bool CRCPass() { return rf12_crc == 0; }        private const ushort RF_SLEEP_MODE = 0x8205;        private const ushort RF_TXREG_WRITE = 0xB800;        private const ushort RF12_433MHZ = 0x01;        private const ushort RF_IDLE_MODE = 0x820D;        private const ushort RF_RX_FIFO_READ = 0xB000;        private const ushort RF_WAKEUP_TIMER = 0xE000;        private const ushort RF_WAKEUP_MODE = 0x8207;        private const ushort RF_RSSI_BIT = 0x0100;        private const ushort RF_RECEIVER_ON = 0x82DD;        private const ushort RF_XMITTER_ON = 0x823D;        private const byte RF12_HDR_ACKCTLMASK = 0x80;        private const byte RF12_HDR_IDMASK = 0x7F;        private ushort rf12_crc;        private string _Alpha = "0123456789ABCDEF";        private string ToHex(byte[] Blob)        {            int Len = Blob.Length;            char[] res = new char[Len * 2];            for (int i = 0; i < Blob.Length; i++)            {                byte r = (byte)(Blob[i] % 16);                byte v = (byte)((byte)(Blob[i] - r) / 16);                res[(i + 1) * 2 - 1] = _Alpha[r];                res[(i + 1) * 2 - 2] = _Alpha[v];            }            return new string(res);        }    }}


#25 CT1

CT1

    Advanced Member

  • Members
  • PipPipPip
  • 36 posts

Posted 10 February 2014 - 03:04 PM

Hi All,

I've just started researching the RFM12/22/69 and of course I'm confused by all the JeeNodes, Motieno etc that can use this chip.

Do I need something more than the chip?

 

Can't you just use the code posted by Elettrozero and wire it up to the Netduino Plus v1?

Can anyone post a picture of how the chip gets wired to the Netduino?

 

I'm looking to use the RFM12 to receive data from a Lacrosse temperature sensor TX29.  I have found several post where the data translation has been decoded. 

 

Looking for advice on how to get started with the hardware.

Thanks






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.