Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:37 30 Jun 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : WiFI and ADC sampling at the

Author Message
xardomain
Newbie

Joined: 28/06/2026
Location: Italy
Posts: 6
Posted: 06:52am 28 Jun 2026
Copy link to clipboard 
Print this post

Hi all,
new member here, I hope it is not OT since it is about Pico Plus 2W (something like 5 of them) and MMBASIC.
I would need to process exactly every 100ms an audio stream, I need to capture samples at 4KHz, process the audio send and receive results to all the other MCUs and take a decision based on the results.
The 100ms frame is synced to GPS at tx and rx stations but propagation introduces a delay that can vary between a minimum of 4-8ms to over 65-80ms.

The goal is to detect a 700Hz morse signal buried into the noise.

The different MCUs will process the audio independently and in parallel but each one will start processing at a slightly different delta, so they will end the processing of the 100ms at different times.

My questions:
1) Would it be possible to sample the ADC @ 4KHz and at the same time store/collect broadcast messages from other Pi Pico Plus 2W?
I am asking this because several MCUs will listen to the same audio but will start at different offset every 100ms and only at the end each one will send the broadcast to announce their results, so most of them will receive the broadcasts while sampling.
I understand that the Wi-Fi handling happens in hardware but the buffer is limited to just one packet.

AFAIK, the reception of more than one packet without storing it will result in the packet being lost, so I should at least store them as soon as I receive it, and it will happen while sampling.
After the sampling and the processing of the audio, I will recover all the broadcast packets collected and process them as well.

I understand that ADC sampling has a specific instruction to start the whole sampling, wondering what it would be the effect of a interrupt driven routine triggered while the ADC sampling is happening.

I am also considering the Teensy 4.1 with Ethernet, but it is significantly more expensive than the Pico Plus 2W. For this project, I need the lightest possible way for the MCUs to communicate with each other, and I would prefer not to implement I2C multimaster, CAN bus, or similar wired solutions. In this context, wireless communication is hard to beat, it requires no additional components, avoids bus contention (let’s assume it is negligible), and keeps the overall design simpler.
Keep in mind that the 100ms window is fixed, and I need to sample most of it, even a blazing fast processor could not speed up this phase. On a Pi Pico, you cant’t sample for more than 65ms else the rest is for processing (FFT) and decision making will.
Using a Pi Pico 2W, I could sample a little more (about 80ms) and compress the FFT and decision making in the last 20ms (I hope at least).
<audio sampling>
<audio analysis>
<comparison with the results of others MCUs>
<announcement of my results to the other MCU>

2) I would like to know how useful it could be the debugging interface while using MMBASIC, is it worth it?
Thanks in advance.

Giuseppe Marullo
IW2JWW - JN45RQ

PS: why is it so? I *try* to overcome limitations on syncing reception of coherent morse (CCW). I cannot detect the transmission buried in noise unless I know the delay introduced by ionospheric propagation, so I am trying to “fish” the delay sampling at different delta at the same time, hopefully one MCU will be enough close to capture the transmission. Only after capturing and processing the audio will I know if the delay is centered, thus the need for each MCU to know how well the others performed and eventually move the respective deltas close r to the most tuned on the delay. Propagation also changes within few minutes, so the ideal algorithm will move delays back and forth during reception.
Edited 2026-06-28 16:57 by xardomain
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6541
Posted: 07:41am 28 Jun 2026
Copy link to clipboard 
Print this post

Welcome to the group.

With the pico, you can use two arrays for the captured waveform.
Start recording one array and when complete start recording into the second array.
You then process the first array while the second is being recorded in the background.
Then back to recording the first while processing the second array.

You should be able to start the process using an interrupt to get the timing but I am not sure how precise it will be.

A sample rate of 4k is easily achieved.

I haven't tried this on the Webmite, only standard picomites so not sure how much the web processes get in the way.

Jim

Edit: I have never played with CCW.
Are there any HF frequencies where it can be found?
Edited 2026-06-28 17:54 by TassyJim
VK7JH
MMedit
 
ville56
Guru

Joined: 08/06/2022
Location: Austria
Posts: 537
Posted: 08:03am 28 Jun 2026
Copy link to clipboard 
Print this post

xardomain,

you may have some timing jitter on the ADC sampling as the TCP/UDP interrupts will steal some CPU cycles for processing. So you should consider how accurate your ADC timing has to be. So IMHO, even if the 4 kHz interval is accurate to the limits of the CPU clock, the exact sampling point may have some jitter.
                                                                 
73 de OE1HGA, Gerald
 
xardomain
Newbie

Joined: 28/06/2026
Location: Italy
Posts: 6
Posted: 09:41am 28 Jun 2026
Copy link to clipboard 
Print this post

Hi Jim and Gerald,

@Jim
>With the pico, you can use two arrays for the captured waveform.
I don't need to capture two arrays, each Pico will sequentially:
- ADC capture
- analyze
- take action
BUT this will happen in each MCU interleaved, each one starting at 100ms interval+a different delta. Each one will finish at a different time, and send a broadcast. My problem is how feasible is to handle the incoming broadcas packets (from the other n-1 Picos) while performing the ADC capture. If I wait until the end of the ADC capture to check networking data presence, probably I will only detect the last broadcast received.
I need to look at all the broadcasts received, thus I need to somewhat monitor the incoming wifi data and at least save it.

>Are there any HF frequencies where it can be found?
Not that I am aware of. In old documentation I saw some frequencies, one for all 14.049MHz but really I don't think actual regular transmissions occur anywere.

The problem is that when it was first described having a super accurate frequency was a achievement in itself, now that we have everything (and cheap) still there is no public demonstration taking into account the propagation delays (the remaining but big problem in my opinion).
AFAIK this is the only available video on the internet of a CCW transmission(bottom of the page):
https://midnightdesignsolutions.com/ccw-xcvr/index.html

George N2APB is doing a great job using a teensy(he started with a Pi pico in MMBASIC!), still ironing out the sync process.
George may have ccw beacons, that could be a good starting point but nothing 24/7 AFAIK.

Because even if the rx knows when the rx started by the GPS assisted 100ms slot, it does not know when the actual trasmission will arrive.
From NVIS to very long range, the delay can be from 4ms to over 65ms.

spreading the MCUs on several delays is my idea to try to find the transmission, you will know you detected it if your analysis value is greater than the others. I would like everybody to announce their score, and the highest bidder will be used as the winning detector. From here you could try to follow that leader and concentrate the other MCUs near the best delay, or use other algorhytms.

@Gerald
you got it, wondering how jitter it will introduce, I expect ideally 4 packets max and I just need to store them into an array while performing the ADC acquisition. The easiest should be UDP broadcasts, so I will also optimize the trasmission.
The packet should contain the current delay, the score of the signal after the FFT and few other information.

So it seems I could buy some Pico Pi Plus 2W then...of course actually is classified as an impossible projects but the journey is more important than the destination.


What about the debugger? Worth it or not with MMBASIC/Webmite?

Thanks for your help.

Giuseppe Marullo
IW2JWW - JN45RQ
 
Martin H.

Guru

Joined: 04/06/2022
Location: Germany
Posts: 1462
Posted: 11:11am 28 Jun 2026
Copy link to clipboard 
Print this post

QTH locator JN45RQ, which indicates the approximate geographical position within the ‘Garden City’ of Varese, Italy (Lombardy).
'no comment
 
ville56
Guru

Joined: 08/06/2022
Location: Austria
Posts: 537
Posted: 11:50am 28 Jun 2026
Copy link to clipboard 
Print this post

Guiseppe,

ADC RUN with 2 buffers, for me, seems to be the method of choice. From reading the manual I expect the ADC conversion timing to be relatively independent from the Basic environment. With double buffering you can copy the ADC data into your local buffer for further processing regardless of the progress of the conversions into the other buffer. All can be done within an ISR (interrupt service routine) without disturbing the actual ADC conversions. UDP packet retrival can also be performed on ISR level. Danger of losing a UDP packet is not given as the ISR level of UDP is higer than ADC. Also no data loss if ADC conversion completes while processing UDP as ADC is used double buffered. All depends of the final processing of the data that you want to do( FFT, result assessment, UDP send, ...). As long as this is completed within the conversion time for one ADC buffer it should be ok.

So IMHO ADC jitter, if any, is only introduced internally but this can probably best be answered by Peter. The polling of the interrupt states before each Basic statement may be such a source but could probably be negligible for your application.

Gerald
                                                                 
73 de OE1HGA, Gerald
 
xardomain
Newbie

Joined: 28/06/2026
Location: Italy
Posts: 6
Posted: 12:05pm 28 Jun 2026
Copy link to clipboard 
Print this post

Nah:
https://www.karhukoti.com/maidenhead-grid-square-locator/?grid=jn45rq

QTH is Paderno d'Adda:
https://www.google.com/search?sca_esv=6a07eaa0fa2bcf7e&sxsrf=APpeQntlpZChOPnwe5qTouQwqrfxDF4fFg:1782645327614&udm=2&fbs=ABfTbFWgwlc2MNw7uknLQP9cFo05YtUSpNgn2klEDQSYENClc3814hVGLKLmTTvfFZWpNyhh6s43y_qew9F2PpV6cRk5MBsIJ25mqyuvopjy2omiQ3R3j14-BjjqQP6o0e3ptrlzDRkUrqANAAnUdF5KZiLrQRlFUKeFcyHNfEGQbgsk4ouE3biXxdr86fgIJqnj2lFW_9Wt&q=paderno+d%27adda&sa=X&ved=2ahUKEwj21Iys56mVAxV45gIHHZPlBtwQtKgLegQIFBAB&biw=1272&bih=588&dpr=1.5

Varese is North West of Milan, Paderno is North East of Milan.

Giuseppe Marullo
IW2JWW - JN45RQ
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5957
Posted: 10:18am 29 Jun 2026
Copy link to clipboard 
Print this post

Hi Guiseppe,

This is not related to Webmite, or directly applicable to your project.
I tried to use FFT to detect morse. I used MMBasic, and ADC and 2 buffers (one being processed while the other being filled).

In my case I sample at 3.2kHz, and take 32 samples. This results in a 10ms "tick" in which I FFT process the data.

The program also generates its own test signals (audio outputs with noise and 400Hz sine wave) to test the ADC/FFT performance. But no actual decoding yet. Next is retrieving the time information, and do statistical analysis on that.

Just for reference, the listing. This runs on the VGA picomite (it shows FFT on screen), but you can use the ADC section from it (starting line 132 with SUB INT_RDY).

 'test program for audio tone detection on ADC
 'uses PLAY SOUND ot generate test signal and noise
 'technology can be used for morse decoder
 'fft(32) takes 3ms, so 10ms time resolution can be possible
 
 Option base 1
 Option default float
 
 'for graphs and statistical data enable debug
 debug=1                   '0=no debug, 1=tone detector, 2=text decoder
 
 's/n threshold
 snt=0.25
 
 'process defines
 n=32                      'samples
 Dim a(n),b(n),c(n),w(n)   'data arrays for FFT and samples and window(=w())
 m=n/2                     'size for n/2 samples (half FFT)
 Dim d(m),scd(m),x(m),ad(m)'data arrays analysis,screen plot,average fft
 dim nb(m)                 'histogram base for frequency bins
 ready=0                   'new ADC data available
 pingpong=0                'fill samples in array a() or b()
 whte=RGB(white)           'frame color
 pkb%=6                    'carrier average default value
 cntl%=0                   'loop counter 10ms tick, 64bits
 
 
 'decoder filter paramters
 flt = 4                   'circular filter depth
 Dim ra(flt)               'circular filter for frequency bin
 
 'create a Hann window array w()
 For i=1 To n:w(i)=(Sin(i*Pi/n))^2:Next
 
 'graph x-axis and frame
 For i=1 To m:x(i)=4*i:Next      'x axis graph increments with 4
 CLS:print @(0,72)"Ti "
 if debug=1 then
   box 0,104,640,36:box 0,158,640,36:box 0,210,640,36
   print @(0,198)"Decode":print @(0,252)"bin"
   print @(0,92)"SD ":print @(0,146)"s/n"
 end if
 
 'hardware parameters
 freq = 3200                     'ADC sampling frequency
 testtone = 400                  'connect audio to adc gp26
 
 'test signal for ADC from PWM audio picomite
 'play tone testtone,testtone:play volume 100,100         'noise free max
 Play sound 1,b,s,testtone,15                            'signal
 Play sound 2,b,n,100,25                                 'noise added
 
 'open the ADC on gp26 and start first conversion
 ADC open freq,1,INT_RDY
 pingpong = 0
 ADC start a()
 
 'the main loop decodes the pre-processed fft sample arrays
 Do
   timer=0
   Do :Loop While ready=0              'wait until new samples available
   print @(24,72)str$(timer,2,3)       'time idle (waiting) in 10ms loop, debug
   
   'average spectrums 2x for better s/n (not more, delays will kill you)
   inc cntl%                           'time reference for decoding                          
   math C_ADD ad(),d(),ad()
   math scale ad(),0.5,ad()            'average 1/2
   
   'low pass filter on highets peak in the spectrum
   pk=Math(MAX ad(),f%)
   Inc i,1:If i>flt Then i=1           'pointer in history array
   ra(i)=f%                            'array with bins
   sdv=Math(sd ra())             'standard deviation bin array (0=homegeneous)
   
   'signal to noise for actual measurement
   sn=pk/((MATH(SUM ad()))-pk)       's/n value
   'sna=(sna*127+sn)/128             'rolling average 128 of sn
   
   'build spectrum histogram to determine morse carrier (bin# and weight)
   if sdv=0 then
     inc cnt,1:inc nb(f%),sn*cnt     'add weight to bin
   else
     cnt=0:pkv=math(max nb(),pkb%)   'find heaviest bin = carrier
     if debug=1 then print @(24,252)str$(pkb%,2,0)+" wght "+str$(pkv,6,0)
   end if
   
   
   if debug=1 then
     
     'diagnosis
     print @(24,92)str$(sdv,2,3)     'standard deviation x bins, 0=perfect
     print @(24,146)str$(sn,2,3)     'signal to noise 1=perfect, 0.12=bad
     
     'trend graphs
     Inc xi,1:If xi>638 Then
       xi=0
       box 0,104,640,36,1,whte,0
       box 0,158,640,36,1,whte,0
       box 0,210,640,36,1,whte,0
     end if
     ysdv=16*min(sdv,1.9)+106:pixel xi,ysdv      'standard deviation graph
     ysn=192-32*sn:pixel xi,ysn                  's/n graph
     
     'try decoding dit-dah when good s/n, correct + stable carrier
     pixel xi,242-30*(sn>snt)*(sdv=0)*(f%=pkb%)  'decoded carrier detect graph
   end if
   
   
   'here comes the actual decoding based on (sn>snt)*(sdv=0)*(f%=pkb%) and cntl%
   if debug=2 then
     
   end if
   
   'scale fft data to graph window
   'Math window d(),60,10,scd()                                 'window y
   Math scale ad(),-min(60/pk,99),scd():Math add scd(),65,scd() 'fixed y
   Box 0,0,70,70,1,whte,0:Line graph x(),scd()                  'show graph
   
   ready=0
   
   select case ASC(inkey$)
       case 32:  math set 1,nb()
       case 128: snt=min(1.1*snt,0.5)
       case 129: snt=max(0.9*snt,0.2)
       case 27: exit do
   end select
   
 Loop
End
 
 'interrupt routine switches between buffers and does pre-processing
Sub INT_RDY
 
 'toggle buffer
 pingpong = 1 - pingpong
 
 'offset removed from input data to avoid FFT element 0 to be dominant
 If pingpong Then
   ADC START b()
   Math add a(),-Math(mean a()),a()  'offset gone
   Math c_mult a(),w(),a()           'window data
   Math fft magnitude a(),c()        'perform fft
 Else
   ADC START a()
   Math add b(),-Math(mean b()),b()  'offset gone
   Math c_mult b(),w(),b()           'window data
   Math fft magnitude b(),c()        'perform fft
 EndIf
 
 'copy lower half of FFT in c() to d()
 Memory copy float Peek(varaddr c()),Peek(varaddr d()),m
 
 ready=1
 
End Sub


Volhout
PicomiteVGA PETSCII ROBOTS
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1971
Posted: 01:11pm 29 Jun 2026
Copy link to clipboard 
Print this post

Smart Pins and eight identical CPUs

Can be programmed in BASIC, C, SPIN, PASM or a mixture.

No jitter
No latency

The 64 Smartpins require zero CPU overhead.
 
xardomain
Newbie

Joined: 28/06/2026
Location: Italy
Posts: 6
Posted: 02:12pm 29 Jun 2026
Copy link to clipboard 
Print this post

Thanks Volhout,
I still don't get why I would need two ADC buffers and alternate captures for my use case and in general.

After the start, I will capture for a big portion of the tick time (100ms) an analog signal.
The only thing I would like to do in parallel is to store the UDP broadcast packets the other MCUs will send, so I am expecting that an interrupt routine storing UDP packets would suffice while performing the ADC sampling.

After sampling, I will process the ADC array performing FFT or even better other more optimized stuff like Goertzel algorithm plus some other conditioning operations.
Once I will have a value that would represent the morse detection level, I will broadcast my results to the other MCUs to compare them with mine.
The winner will be used to send out the synthetized morse signal (and its delay).
The total time should not exceed 100ms, so the sampling will be reduced accordingly to avoid that the total will not take more than 100ms.

Just to give you an idea, something that will resemble this for the sampling+processing(early code from George N2APB):

...
WaitFrame
     ADC start val_y!()
     Math FFT MAGNITUDE val_y!(), val_l!()
     For i =1 To 60: val_c(i) = Int(30 * Log( 1 + val_l(I+1)*5 )-5)-3: Next

     If val_c(50) >50 Then               ' Inspect the 800 Hz "sweet spot" cell for tone/no tone
        Pin(GP15)=1                      ' We got a tone! Indicate with LED #4
        Play TONE 850,850                ' Turn on tone in headphone
     Else
        Pin(GP15)=0                      ' Turn off LED #4 indicator
        Play STOP                        ' and stop the tone.
     EndIf
...
https://github.com/n2apb/pmk/blob/main/PMK%20v2.0%20(24-Mar-2023).txt

It is based on a simple pico with 800Hz signal. I will use a faster MCU to buy additional time for the sampling. with the pico, it is 65ms for the sampling out of 95ms total.
I hope to extend the sampling at 80ms, and still close before 100ms.
This is a very simple example that assume no propagation delay and so it is using a single MCU starting at the beginning of the 100ms slot.

In real world scenario, it will never happen, it will have a 4-8ms minimum(NVIS) and the worst case will be over 65ms (other side of the world).
The whole idea for the "interleaved" MCU is to land where the transmission has mostly the same delay of the MCU involved. The more MCsU, the greatest chance one will have the same delay of the transmission.



Thanks PhenixRising,
but already ordered 6 Pimoroni Pico Plus 2W, 5 for parallel sampling and one for orchestrating the results. Waiting them to come from UK to Italy.

Never had the chance to use a Parallax processor beside the mithycal Stamp 2 driving my yelloy LynxMotion Arm, eons ago.

For sure their Propeller were great back then and seems even more today.
At the time I decided to use an IsoPod, based on the Motorola DSP56F805 in Forth, it was able to tame my 50k samples/rev HP encoders without a glitch and up to 26 servos in hardware.
My idol:
Sadly, the Metrowerks Codewarrior development environment was “a little” out of my budget. Still IsoMax was like using a multitasking Forth, very interesting concept.

When I had way much more free time...

Let's see what I will achieve, wifi is my hope to simplify stuff, and at the same time receive all the relevant comms on the pc where I will have to develop a proper monitoring tool.

Giuseppe Marullo
IW2JWW - JN45RQ
 
xardomain
Newbie

Joined: 28/06/2026
Location: Italy
Posts: 6
Posted: 02:15pm 29 Jun 2026
Copy link to clipboard 
Print this post

Sorry fat fingers:
My idol:
https://en.wikipedia.org/wiki/Johann_Borenstein

Look at his Clapper Robot or UMB Mark paper.
Amazing.

Giuseppe Marullo
IW2JWW - JN45RQ
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11557
Posted: 02:47pm 29 Jun 2026
Copy link to clipboard 
Print this post

I may be misunderstanding what you are trying to do but you are aware MMbasic can only use the wifi as a station and not an access point?
 
xardomain
Newbie

Joined: 28/06/2026
Location: Italy
Posts: 6
Posted: 03:18pm 29 Jun 2026
Copy link to clipboard 
Print this post

Hi Matherp,
thanks for letting me know but not so important, I will use a wifi AP or will create one from a PC/PI.
Sure, if a Pico Plus 2W could have this feature it would be better.

Giuseppe Marullo
IW2JWW - JN45RQ
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1971
Posted: 04:52pm 29 Jun 2026
Copy link to clipboard 
Print this post

  xardomain said  

Thanks PhenixRising,
but already ordered 6 Pimoroni Pico Plus 2W, 5 for parallel sampling and one for orchestrating the results. Waiting them to come from UK to Italy.


Multiple PicoMites is also my preferred method because I like DCS (distributed control systems)

  Quote  
Never had the chance to use a Parallax processor beside the mithycal Stamp 2 driving my yelloy LynxMotion Arm, eons ago.

For sure their Propeller were great back then and seems even more today.
At the time I decided to use an IsoPod, based on the Motorola DSP56F805 in Forth, it was able to tame my 50k samples/rev HP encoders without a glitch and up to 26 servos in hardware.


I forgot to mention that FORTH is resident on the Parallax P2...I never understood it  

Are you a motion control guy?
This is where the P2 blows everything away. The Smartpins can be configured as quadrature counters (with optional filtering...which was my idea, BTW ).

Assuming using the typical 56 free pins, 28 quadrature counters can be handled at sysclock/2 with zero CPU involvement. Furthermore, the motor command can be PWM or real analogue with 16bit resolution (DAC dither).

Incredible product and just like MMBasic, plug-in and start programming. Compile and run happens in the blink of an eye.
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1971
Posted: 08:01pm 29 Jun 2026
Copy link to clipboard 
Print this post

  xardomain said  Hi Matherp,
thanks for letting me know but not so important, I will use a wifi AP or will create one from a PC/PI.
Sure, if a Pico Plus 2W could have this feature it would be better.

Giuseppe Marullo
IW2JWW - JN45RQ


Not trying to sway you BUT; I use Bluetooth and traditionally, the HC-05 module. Then I looked at the ESP32 which has Bluetooth, WiFi and ESP-NOW.
I'm not an Arduino lover but I downloaded ready-made code for the ESP32 and it was easy to redirect the Bluetooth to UART. So here is a device that can provide multiple types of communication to the PicoMite.

I recommend that you look at ESP-NOW because it sounds perfect for your needs.

Great Scott ESP-NOW video

Ah, limited length packets, though  
Edited 2026-06-30 06:04 by PhenixRising
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026