mikaelnousiainen / RS41ng

Custom firmware for Vaisala RS41 and Graw DFM-17 radiosondes with support for amateur radio use. Ideal for tracking high-altitude balloons. Supported modes include APRS, Horus 4FSK mode, CATS, morse code (CW) and additional digital modes like WSPR and FT8 via Si5351.
GNU General Public License v2.0
109 stars 28 forks source link

Pulse Counter 'driver' #17

Closed darksidelemm closed 1 year ago

darksidelemm commented 2 years ago

To enable support for things like radiation sensors, it would be handy to have a 'driver' which counts pulses on one of the IO pins available on the 10-way connector.

The example radiation sensor I have on hand is this one: http://www.radiation-watch.org/

Thoughts on this:

This will need the addition of the stm_lib ext interrupt driver: stm32f10x_exti.c/h I've found a copy of this here: https://github.com/NordicPlayground/mbed/tree/master/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_DISCO_F100RB

Some info on using it here: https://scienceprog.com/interrupt-based-button-read-on-stm32f103zet6-board/

mikaelnousiainen commented 1 year ago

@ManoDaSilva You mentioned in #19 that you had already written some code for this purpose. Did you develop it on top of RS41ng code -- and if so, could you share it?

mikaelnousiainen commented 1 year ago

@ManoDaSilva And yes, I'd probably start with the I²C/Serial pins available in the pin header, as those are really the only pins easily available for this purpose and easy connectivity.

ManoDaSilva commented 1 year ago

@ManoDaSilva You mentioned in #19 that you had already written some code for this purpose. Did you develop it on top of RS41ng code -- and if so, could you share it?

So far, it's really bare-bones, and I'm still getting around the whole RS41ng code base - no HW config yet, I was just trying to implement the CPM field in the "Custom" field for HorusV2. I replaced the GPS rate by a "CPM_value", which gets polled from telemetry.c, which itself calls a new driver that only spits out a fixed value. That part works, but it's not something useful for the counting part :)

@ManoDaSilva And yes, I'd probably start with the I²C/Serial pins available in the pin header, as those are really the only pins easily available for this purpose and easy connectivity.

Got it, I'll give it a try-I've got limited experience in the STM32 world, only played with basic timers using CubeMX (coming from Arduino and its pre-configured I/Os), so I hope I'll be able to do something useful...

ManoDaSilva commented 1 year ago

As mentioned in the other issue (#19 ), PB11-pin22 (XDATA_RX) seems like a good candidate as TIM2_CH4 is available there as an alternate.

darksidelemm commented 1 year ago

I believe there are still 2 bytes free at the end of the custom area, i'd just drop an unsigned 16-bit count value there, and not worry about trying to do the count-per-minute calculations on the sonde itself - that can be done on the ground easily.

mikaelnousiainen commented 1 year ago

@ManoDaSilva Just like Mark VK5QI stated above, I'd also prefer to use the end of the custom data area in the Horus 4FSK packet for this purpose (instead of replacing any existing GPS data). Also, it would be simpler just to start with collecting and transmitting the raw counter values from the timer (and let the timer counter wrap as it reaches the maximum value of 65535, it's not an issue).

Once that is working, an improvement as a separate task could be to start calculating "pulses per minute" counts / averages.

You're welcome to open a work-in-progress pull request for your changes here (don't have to have finished code yet) -- I can do early testing of the code here locally too!

ManoDaSilva commented 1 year ago

Got it! Handling wrap around on the ground shouldn't be too much of an issue, as everything is timestamped...

I got some basics done: config.h flag, telemetry implementation, custom drivers and appending the two bytes at the end of the Custom field. Here's my fork, on "testing" branch.

darksidelemm commented 1 year ago

We should be able to make a dashboard on https://grafana.v2.sondehub.org/ which will perform the counts-per-minute calculation. It would be nice to eventually have it on the sonde itself though.

ManoDaSilva commented 1 year ago

I got some basics done: config.h flag, telemetry implementation, custom drivers and appending the two bytes at the end of the Custom field. Here's my fork, on "testing" branch.

Tested and working so far (+correctly transmitted and handled by horus_gui (although it divides it by 10 somewhere, gotta figure out where...). Just opened a pull request :)

mikaelnousiainen commented 1 year ago

:+1: Looking good so far -- I will start testing once you have added the timer init / counter read features.

We can also allow using the pulse count in APRS / CW messages by adding a new "variable" in template.c (https://github.com/mikaelnousiainen/RS41ng/blob/main/src/template.c), e.g. $pc could represent the pulse counter.

ManoDaSilva commented 1 year ago

Ok, added APRS/CW variable in template.c (+ explanation in config.c).

Just a quick though: wouldn't it be more logical to directly use a hardware counter, to offload the CPU, instead of triggering an interrupt whenever a pulse arrives?

mikaelnousiainen commented 1 year ago

@ManoDaSilva Thanks, yes, by all means use a hardware timer counter -- the "polarity" could be made configurable if possible (haven't checked the specs for timers in that much detail).

ManoDaSilva commented 1 year ago

Do you know which hardware timers are used for your code? Sadly, it seems I can't use TIM2_CH4 (or CH3, PB10) for counting purposes as TIM2 doesn't accept CH4 (or CH3) as a valid trigger source... Or I might have missed something with the Input Capure Direct Mode. PA0 - Pin 11 looks like a good candidate (NFC_IN2), but it's finicky to rewire.

Polarity is indeed configurable, for all timers/counters.

We can also fall back to the external interrupt idea, EXTI11 is available on PB11, and count by increasing a variable...

ManoDaSilva commented 1 year ago

Okay, got some stuff done, basic EXTI implementation, but for some reason it doesn't jump into it... Still some more work to do, I'll come back to it tomorrow :)

ManoDaSilva commented 1 year ago

First implementation is working. I've hooked it up to my Geiger counter, and it seems to register the pulses without issues. I made a small mistake with the data pointer for the custom payload, now fixed in the latest commit. I didn't notice any radio errors, or GPS parsing errors, all data points seem to make sense, confirming I'm not using another IRQ/interrupt line needed for other actions. I also noticed a mistake in the custom field list submission I made, sorry again @darksidelemm !

I added a small radioactive check source on the tube to speed up the counting process, and it does wrap around 65535 and start again at zero, no worries there, as per this Habhub log:


64514
64830
65140
65456
178
502
798
1108
1456
1746
darksidelemm commented 1 year ago

If you can figure out how to make it do the counts-per-minute calculation, that would still be handy (one less thing for me to figure out on the dashboard :-) )

mikaelnousiainen commented 1 year ago

This is more or less finished in PR #20 -- please give it a try @darksidelemm @ManoDaSilva