| Menu | JAQForum Ver 19.10.27 |
Forum Index : Microcontroller and PC projects : WiFI and ADC sampling at the
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 |
||||||
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 |
||||||
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. |
||||||
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 |
||||||
QTH locator JN45RQ, which indicates the approximate geographical position within the ‘Garden City’ of Varese, Italy (Lombardy). ![]() |
||||||
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 |
||||||
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 |
||||||
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 |
||||||
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. |
||||||
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 |
||||||
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 |
||||||
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? |
||||||
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 |
||||||
Multiple PicoMites is also my preferred method because I like DCS (distributed control systems) 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. |
||||||
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 |
||||||
Hi PoenixRaising, already got the Picos, waiting for them. Pico was a safer choice because the initial take was made with them(initial midnightsolution ccw transceiver in the works, MMBASIC source available), and I need something easy to communicate at the same time with all the other nodes. I don't like the USB micro, this one has the USBC connector, another plus, 5V tolerant I/O (A04 stepping). Broadcast can be received also natively from a laptop, ESP-NOW it is not. I already have a bunch of NodeMCU Amica V2 ESP8266 ESP-12F, and they are nice and cheap, even tough pretty limited in the available interfaces(low i/o count, only one adc pic). Let's see how it goes with the pico plus 2w, if I will be succesful then I will reconsider something to lower the parts count too, nice to have 6 MCUs for a project but one is better. Giuseppe Marullo IW2JWW - JN45RQ |
||||||
Oh I wasn't suggesting switching to ESP32 for the project but they are so inexpensive, they can be simply handling comms and linked to the PicoMite UART. Even with WiFi, they can be an AP. ESP-NOW and WiFi can run concurrently on the ESP32 ![]() Edited 2026-06-30 17:32 by PhenixRising |
||||||
| The Back Shed's forum code is written, and hosted, in Australia. |