etrombly/RFM69

Set frequency

Closed this issue · 6 comments

ygoe commented

First, there's a typo in the method name setFreqeuncy, it should be named setFrequency.

Then, I have no idea how to use that. What's the FRF parameter? Is it the actual tx/rx frequency in MHz or kHz or Hz? The RFM69 datasheet (registers description) is unclear about the meaning of these registers, too. So I see that this method writes a 24-bit number into three registers as-is but I still don't know what to do.

Other randomly found code suggests that some arithmetic conversion of a frequency in kHz is required before writing its result to the registers (search for "frequency", it appears a few times in that file). The conversion might depend on something Chinese being 30 or 32 MHz. This isn't computable yet.

Does anybody know how to set the frequency of this radio? I mean, that's the most basic function of a radio, setting the frequency, isn't it? I've just assembled a single of these modules now and would like to verify it sending with my ham radio handset around 433 MHz. I need a frequency for that. (Don't have a fancy SDR yet which could quickly tell me where the signal is.)

The frequency is set during init directly without using setFrequency, that's why I never noticed the typo. It's defined by the freqBand parameter to init. The two relevant sections in init are:

frfMSB = {RF69_315MHZ: RF_FRFMSB_315, RF69_433MHZ: RF_FRFMSB_433,
                  RF69_868MHZ: RF_FRFMSB_868, RF69_915MHZ: RF_FRFMSB_915}
        frfMID = {RF69_315MHZ: RF_FRFMID_315, RF69_433MHZ: RF_FRFMID_433,
                  RF69_868MHZ: RF_FRFMID_868, RF69_915MHZ: RF_FRFMID_915}
        frfLSB = {RF69_315MHZ: RF_FRFLSB_315, RF69_433MHZ: RF_FRFLSB_433,
                  RF69_868MHZ: RF_FRFLSB_868, RF69_915MHZ: RF_FRFLSB_915}

and:

0x07: [REG_FRFMSB, frfMSB[freqBand]],
0x08: [REG_FRFMID, frfMID[freqBand]],
0x09: [REG_FRFLSB, frfLSB[freqBand]],

so if you wanted to set the freq to 433mhz you'd pass in RF69_433MHZ to init for freqBand.

ygoe commented

I was thinking about a frequency like 433.750 MHz. Or 434.125 MHz (434 125 kHz). Can I do that? It's a number, measured in Hertz, not a symbol that's defined with some obscure unitless values.

I'm not sure why you're being so confrontational about this. It's a volunteer project that I'm trying to assist you with in my spare time. The formula is 61.03507913Hz per step stored in a 3 byte word. So take your desired freq and divide by that, then convert it to hex. So you get 7,112,712 which converted to hex is 0x6C 0x88 0x08. I believe you should be fine calling setFrequency with the decimal value, but I haven't tested it. If that doesn't work you can do something like this:

test = RFM69.RFM69(RF69_433MHZ, node_id, network_id, is_rfm_69HW)
test.writeReg(REG_FRFMSB, 0x6C)
test.writeReg(REG_FRFMID, 0x88)
test.writeReg(REG_FRFLSB, 0x08)

two additional notes:
The antenna is tuned for whatever frequency you bought it at (either 433, 868, or 915) if you operate it outside of that frequency it won't be optimal.

The crystal it comes with isn't very accurate. So tuning to a specific freq like this will not necessarily get the results you want unless you have equipment to measure it. There's a good post here that discusses it https://ukhas.net/wiki/ideas:rfm69_frequency_trimming

ygoe commented

Thank you. I looked a little further and found this in the upstream C code: https://github.com/LowPowerLab/RFM69/blob/master/RFM69.cpp#L163

The setFrequency method there has two important differences:

  • The parameter name makes clear that a frequency in Hz is expected. There's also a comment for that.
  • The provided frequency is divided by that RF69_FSTEP constant to convert it to the value expected by the hardware. The caller doesn't have to know about that magic.

I've done the same here and it works well. Setting the frequency (or the stepped down value) in the constructor is not working, it leads to an error because the lookup table doesn't support that.

I'm asking these question because I have reason to believe that your knowledge about radio frequencies is limited. Actually so much that it leads to nonfunctional or illegal solutions. For example, 433.000 MHz is not within the nearest ISM band so sending there is not allowed. The band goes from 433.05 to 434.79 MHz, at least in Europe. Other regions don't have that band at all. Using the constant RF69_433MHZ is thus illegal unless you have an amateur radio licence (which I do).

This frequency conversion thing also leads me to another question: Is this Python code a one-time port of some older version of the C code or is it somehow kept up to date to include possible improvements or bugfixes?

I think this article may be helpful for you to get better results in future interactions https://tweakyourbiz.com/management/personal-development-plan/master-communication-skills

I haven't had the hardware setup for this for several years, so it's not being actively developed. I'm open to PR's though. Now that you know how it works feel free to submit one.