Rodemfr / MicronetToNMEA

A NMEA 0183 converter for Raymarine's wireless instruments ... and much more !
GNU General Public License v3.0
20 stars 7 forks source link

Deviation #8

Closed davidwkerr closed 2 years ago

davidwkerr commented 2 years ago

I am creating this issue simply to track some information about deviation. Comments in the code says that Micronet uses an approximately 38kHz deviation. That fits well with a 76.8kbaud rate (+-38kHz).

MICRONET_RF_DEVIATION_KHZ is set to 34kHz in the code because this apparently gives about the correct actual deviation.

Smart RF-Studio gives a required register value of 0x44 for Register 0x15 "DEVIATN" register.

The ELECHOUSE driver sets this register to 0x47, but then gives the opportunity to overwrite it via RfDriver::SetDeviation(float freq_KHz) which is passed the 34.0kHz value from above. The ELECHOUSE driver has a fairly obtuse little chunk of (uncommented) code which generates a value of 0xA4 when called with 34.0. It generates 0xB8 if called with 38.0! These are very, very strange and I believe incorrect.

What I have done, is change the default value of DEVIATN (register 0x15) from 0x47 to 0x44 and commented out the call to RFDriver (which then calls the ELECHOUSE driver) which passes the 34kHz value. Everything works fine! Subjectively, my range (which was very good) is even better now. But I shall attempt to measure the deviation and report back. Given the deviation is fixed for this particular project, I do not see any problem with there being a hard coded constant. The 0x44 is the same for 916MHz and also 868MHz. Probably the proper way to do this (so ELECHOUSE changes do not overwrite the DEVATN reg) is to replace the call to RfDriver&34kHz by a SPI write of the DEVIATN register with 0x44.

Deviation result. Micronet instruments give 77kHz approx (+-38.5) and the CC1101 is giving almost the same- to within a couple of kHz. CC1101 is 37.5kHz. The CC1101 has a few more out of band artefacts than the Micronets but, after all, it is a $2 board and I have not matched the antenna.

I see that tty (with the ESP32 implementation) on the YBW forum is using 0x42 which gives a deviation of about +-32kHz which seems a little low. I did test with 0x42. It worked but range reduced by 2 metres from using 0x44,

Thoughts, observations, comments, suggestions welcomed.....

dwarning commented 2 years ago

My observations are different: Using the debug tool from github LSatan cc1101_debug_service my elechouse lib reporting DEVIATN values 0x43 for 34kHz and 0x44 for values 35 ... 38kHz. Important for accurate center frequency using this lib and all the different cheap CC1101 modules is to overwrite the default calibration with e.g. cc1101Driver.setClb(3, 17, 19); Use the attached script and your sdr stick (ppm calibrated) to find out your values for setClb.

I agree that changing the deviation parameter shows no (or only minimal) impact to deviation of the spectrum. This is to investigated.

Rodemfr commented 2 years ago

38KHz is the value I measured with my RTL-SDR. 34KHz is what I had to give to elechouse driver to get the actual 38kHz deviation. This confirms the conclusions from the baud rate problem : we have to rewrite this driver. I will make it simpler with more hardcoded values, as you suggest. Only two parameters need to be made dynamically configurable : center freq and bandwidth (for the CF search algorithm). Coupled to two separated constant tables for 868 & 915Mhz this should be a manageable work.

davidwkerr commented 2 years ago

Hi dwarning:

  1. I did not test what the DEVIATN register was actually being set to. However my calculations using the ELECHOUSE driver code gave strange values (0xA4 and 0xB8). Referring to the CC1101 data sheet, the top bit is not used, so these become 0x24 and 0x38. It is possible they do actually work (I have not done the maths). It just does not seem sensible to me to have a default in the driver which might be okay as a generic starting point then to have to override it with an unduly complicated algorithm which seems to give the wrong answer and require passing 34.0 to get 38.0 result. Though this is necessary for a generic driver being used in a whole range of different applications. I think we are all saying the same thing, that 0x44 is what we want. Let's make setting it straightforward. Incidentally, the DEVIATN setting DOES make a difference as measured by RSSI and range. It's just not super critical. Changing to 32kHz dropped RSSI about 4dB and reduced range a couple of metres.
  2. Re: "Use the attached script and your sdr stick (ppm calibrated) to find out your values for setClb". I cannot see anything attached. But I am interested in following up on this.
  3. Thanks for pointing out the calibration registers.
  4. While you are there, and a little off topic. Could we have a menu item to set a plus/minus offset for the compass? I am making a backbone PCB and small box to house Teensy 4.0, magnetometer, switching reg, uBlox, UDP WiFi plus switchable balanced GPS input/output. Others are doing similar things. However, getting the magnetometer, box and axis of the boat lined up by mechanical means is challenging and being able to change the offset once everything is calibrated and installed would be very useful. Thanks, David Here is the algorithm which I think the ELECHOUSE driver is trying to emulate. Without modifying the driver, we can simply cut it out of the equation and program DEVIATN with 0x44: deviatn
davidwkerr commented 2 years ago

I've now done a bit of snooping around clb[..] and the FSCAL registers. This seems to be another area where RF Studio has fixed recommendations for the 4 FSCAL registers and they are the same for 916 and 868. The driver is providing calculations for a much wider range of frequencies and the code just about does my head in. I have just done some checks on my system as is (with Rodemfr's latest code) and the ELECHOUSE FSCALx code. My actual CF is 7kHz different from my Micronet devices and my total deviation is 77kHz versus 76kHz (Micronet). Inconsequential differences.

I am reminded of a situation a few years ago when I was developing AIS equipment. The particular chip was at least as complicated as the CC1101 and default drivers just were not specific or good enough for a relatively fixed situation with well defined frequencies, baud rates, deviations, bandwidth, filtering, freq corrections etc. In that case, I needed to use high accuracy crystals and make use of the embedded chip temperature sensor to compensate for crystal temperature drift. Of course, that was a more demanding application than this one, but I quickly learned that the best way was using tables of register constants so it was much easier to see what was going on and remove a lot of code and complexity.

So, in summary, I think that using drivers such as the ELECHOUSE driver is great to get things off the ground but a final solution which is more table driven with just a few variables (such as 916 vs 868 && 26MHz vs 27MHz) is the way to go. However, I am happy with the current state of affairs. The main unknown which I have (for myself) is whether or not Micronet devices use a 27 or a 26MHz xtal in the 916MHz systems because 27 would explain the loss of sync for large packets. But Rodenfr's changes to restrict packet size to 38bytes are working very well for me and hopefully for others. So I'm very happy.

dwarning commented 2 years ago

Hi dwarning:

1. I did not test what the DEVIATN register was actually being set to. However my calculations using the ELECHOUSE driver code gave strange values (0xA4 and 0xB8). Referring to the CC1101 data sheet, the top bit is not used, so these become 0x24 and 0x38. It is possible they do actually 

4. While you are there, and a little off topic. Could we have a menu item to set a plus/minus offset for the compass? I am making a backbone PCB and small box to house Teensy 4.0, 

Sorry - something gone wrong. Here are the modified scripts, both are arduino files .ino:

  1. for determine the clb coefficients with sdr stick cc1101_Calibrate_frequency.txt
  2. test case to see the ELECHOUSE parametrization: cc1101_Transmitt_Hello_World.txt Default value for DEVIATN in ELECHOUSE lib is set to 0x47 - see line 1045.

Did not understood what you meant with "gave strange values (0xA4 and 0xB8)". With the script you can see that the values in the lib are set correct. May be I misunderstood.

I can live with 0x43 (35 kB) and 0x44 (38kB). My measurements are between.

to 4.: I believe a more simpler offset compensation for compass is not possible. You must compensate by offsets in all 3 directions. And this is done in Ronan's program with key 7. I use it too, the coefficients are saved in flash's eeprom emulation.

davidwkerr commented 2 years ago

Hi dwarning, I'm not sure you understand what I was saying. I am talking about the result of calling this:

void ELECHOUSE_CC1101::setDeviation(float d){ float f = 1.586914; float v = 0.19836425; int c = 0; if (d > 380.859375){d = 380.859375;} if (d < 1.586914){d = 1.586914;} for (int i = 0; i<255; i++){ f+=v; if (c==7){v*=2;c=-1;i+=8;} if (f>=d){c=i;i=255;} c++; } SpiWriteReg(21,c); }

Regarding the compass, maybe I was not clear. I am talking about the heading generated after all the corrections are applied. Being able to add or subtract a value to allow for physical mounting in the boat. I shall do it on my private copy of the code if you do not want to add it. For instance, if I find that my heading is 12deg off when I mount the hardware, it would be good if this was subtracted before sending the heading to the instruments (and other places). It is physically very difficult to accurately mount the board to be exactly lined up with the axis of a yacht. Easiest if this was in a menu item.

dwarning commented 2 years ago

I made a printout after SpiWriteReg and got reasonable values: 40k gave 0x45, 38k 0x44 and 34k 0x43. Only thing I am missing is adequate variation of the spectrum, but luckily we are between 36k and 38k which is near same as transmitted from display. In my display mn 100-2 I can setup an offset for compass too. I think it would be an good place to do that.

davidwkerr commented 2 years ago

Re: "In my display mn 100-2 I can setup an offset for compass too. I think it would be an good place to do that." Okay, that is a reasonable suggestion. I am new to Micronet and had not discovered that setting.

Not sure why I got different values from that code, but I checked it in isolation in a debugger not in the MicronetToNMEA code which you did, so I accept it is probably correct code (though unnecessary, in my opinion, in a fixed application).

Thanks for the calibration sketch. It is very broad modulation but I did derive the clb values which were 4,77,79 for 915MHz. I added:

<<cc1101Driver.setClb(4, 77, 79); //Set the clb values derived from calibration script>>

Because I could not find that clb values were currently being set anywhere in the code. The registers are being correctly set to the RfStudio values at initiation and then later I set clb and therefore new FSCAL register values. This seems to be what the datasheet says to do. Is this correct?

For now, in my copy of the code, I am directly writing the DEVIATN register with 0x44 rather than setting 34kHz to get 38kHz.

Regards, David

Rodemfr commented 2 years ago

Regarding the compass, maybe I was not clear. I am talking about the heading generated after all the corrections are applied. Being able to add or subtract a value to allow for physical mounting in the boat. I shall do it on my private copy of the code if you do not want to add it. For instance, if I find that my heading is 12deg off when I mount the hardware, it would be good if this was subtracted before sending the heading to the instruments (and other places). It is physically very difficult to accurately mount the board to be exactly lined up with the axis of a yacht. Easiest if this was in a menu item.

I agree with dwarning answer : you have a menu in your display configuration menu which allow to apply an offset to the compass. This a more user friendly place to configure it.

dwarning commented 2 years ago

@davidwkerr: setClb() you can found around line 597 in the ELECHOUSE_CC1101_SRC_DRV.cpp file. Using the ELECHOUSE lib setClb() has to be placed after Init() and before setMHZ(). Last is important because here the clb coefficients are applied. The clb approach is not only for different frequency usage - it is also for compensate weaknesses of the cheap cc1101 boards. You didn't still trust the setDeviation() function and writing direct to register?

davidwkerr commented 2 years ago

Thank you dwarning. I have now moved the setClb() as you advised. Now I have a new record (for me) of 25 asterisks (*) when I do Rodemfr's tuning loop. Great! Range is excellent.

Maybe I do not trust the deviation code. I just write it directly. I do not like the idea of having to feed it 34 to get 38!

Best Regards, David

davidwkerr commented 2 years ago

This has been a useful thread- thank you for the input. So I am closing it now but I am opening a new one for a suggestion relating to Rodemfr rewriting the Elechouse driver specifically for this project.