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 : SetPin(GPnn), FIN query
Page 1 of 2 | |||||
Author | Message | ||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Hi there I note that currently Pin(GPnn), FIN returns an integer value. Is this correct or am I missing something? I'm looking to measure a frequency of 50Hz to at least 3 decimal places. Any guidance would be appreciated. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
Chopperp Guru Joined: 03/01/2018 Location: AustraliaPosts: 1057 |
Hi Carl As far as I know, it is the nature of the beast. so to speak. You will only get integers with MMBasic, even if you use a longer gate time (but I could be wrong) From the Manual SETPIN pin, cfg [, option] FIN Frequency input 'option' can be used to specify the gate time (the length of time used to count the input cycles). It can be any number between 10 ms and 100000 ms. Note that the PIN() function will always return the frequency correctly scaled in Hz regardless of the gate time used. If 'option' is omitted the gate time will be 1 second. Brian Edited 2023-08-26 12:19 by Chopperp ChopperP |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6100 |
Measure period and invert for low frequencies. Jim VK7JH MMedit MMBasic Help |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Thanks for the feedback @chopperp and TassyJim. I have tried longer gate periods but the result is always an integer value, even printing str$(pin(GPnn),6,4). I have used PULSIN to measure the period and using that to determined the frequency. It measures period in µs. Sub Freq TimeEnd=Timer Period%=Pulsin(GP22,0,25000,25000) Period2%=Pulsin(GP22,0,25000,25000) Period3%=Pulsin(GP22,0,25000,25000) Period%=(Period3%+Period%+Period2%)/3 DeltaTime=TimeEnd-TimeStart Freq!=(1000000/Period%)/2 ' Measuring PWM 50% duty cycle so two edges Frequency$=Str$(Freq!,6,2) ' used in the JSON string to talk to the graph TimeStart=Timer End Sub This subroutine is called by a 1s Tick. Interestingly the DeltaTime is rarely 1000ms, usually under. Frequency to 2 decimal places. Target frequency for the PWM output I'm measuring is 50.01Hz. Using the Pin(GPNN),FIN would just have been far more elegant:) Edited 2023-08-26 13:47 by carlschneider Cheers Carl Retirement is tough on Hobbies without a day job |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2136 |
As TassyJim says, it's slow but it works. > setpin gp7,fin,10000 > do : ? pin(gp7) : pause 10000 : loop 25 50 60.7 67 69.5 69.5 63.7 50 50 |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9128 |
It returns a floating point number but this is derived as the number of counts in 1000mSec (default) like any other frequency counter. so 50 counts in 1000 mSec gives a frequency of 50. Can't be anything but an integer in this case.If you set the gate time to 2 seconds and there are 101 counts in the period then you will get a frequency of 50.5. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6100 |
If you are serious about high resolution, get a GPS with 1Hz output and measure the change in phase between it and the 50Hz. I did that successfully a few years ago, just for fun. Jim VK7JH MMedit MMBasic Help |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Thanks for the response and guidance phil99, matherp and TassyJim, much appreciated. Peter’s explanation has resonated and I now realize that to achieve 2 decimal precision I would need a gate time of 100s, ie a count of 5001 in 100s will yield the desired 50.01Hz. For my intended usage I will have to stick with period measurement to derive the frequency. The GPS route sounds fascinating Jim. I wonder if an external RTC, DS3231’s 1Hz output would be stable enough as a reference. I assume your implementation did some sort of synchronization and then measured the phase drift. Thanks again for your assistance. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
The most accurate way to measure low frequencies (up to 20kHz) is measuring the period. Using the picomite PIO allows for 44MHz tick (measurement resolution) at 133MHz CPUSPEED. When measuring 50Hz you would get near 1ppm (1:1000000) resolution. This is how it is done: 'PIO frequency counter for PICOMITE MMBasic measuring period time 'this is a PIO program Dim a%(7)=(&h008400C5A029E020,&hE0408000A0CA0042,&h00C9008B004AA04A,&h8000A0C9,0,0,0,0) 'PIO configuration f=133e6 '133MHz PIO execution speed e=Pio(execctrl gp0,0,31) 'use gp0 for PIN...select the input pin 'program pio1 and start PIO program 1,a%() PIO init machine 1,0,f,0,e PIO start 1,0 'pio fifo register for reading information from PIO Dim x%(4) 'read the PIO time counted and convert to frequency Do PIO read 1,0,5,x%() 'read 5 count values, fifo + most recent period = x%(4) + 4 'counts measured + instructions PIO setup time Print f/(3*period);" Hz" 'convert counts to Hz and print Pause 1000 Loop While Inkey$="" end In line 8 (e=Pio(execctrl gp0,0,31)) you can assign any gpio pin of the pico. e=Pio(execctrl gp26,0,31) uses gp26 (pin 31). Success... Volhout P.S. if you use a picomiteVGA, you better set f=126e6 since it runs at 126MHz. Edited 2023-08-27 00:33 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Hi Volhout Thank you for the PIO solution.This is not something I have tried yet. I have captured the PIO programming as you provided in the Pico running at 264MHz. 'Frequency pin test If MM.Info(ip address) = "0.0.0.0" Then Print "Failure to connect to the Internet - Restart" CPU restart EndIf ' ' Print MM.Info(ip address) On ERROR SKIP 5 WEB NTP -6 'Saskatoon If MM.Errno Then WEB NTP -6 If MM.Errno Then WEB NTP -6 If MM.Errno Then Print "Failure to connect to the NTP Server" : CPU RESTART Target=50.01 SetPin GP5, PWM2B PWM 2, Target,, 50 'PIO frequency counter for PICOMITE MMBasic measuring period time 'this is a PIO program Dim a%(7)=(&h008400C5A029E020,&hE0408000A0CA0042,&h00C9008B004AA04A,&h8000A0C9, 0,0,0,0) 'PIO configuration f=264e6 '264MHz PIO execution speed e=Pio(execctrl gp6,0,31) 'use gp0 for PIN...select the input pin 'program pio1 and start PIO program 1,a%() PIO init machine 1,0,f,0,e PIO start 1,0 'pio fifo register for reading information from PIO Dim x%(4) 'read the PIO time counted and convert to frequency Do PIO read 1,0,5,x%() 'read 5 count values, fifo + most recent period = x%(4) + 4 'counts measured + instructions PIO setup time Print f/(3*period);" Hz" 'convert counts to Hz and print Pause 1000 Loop While Inkey$="" End Unfortunately there appears to be an error > RUN 172.16.1.67 ntp address 209.115.181.107 got ntp response: 26/08/2023 08:55:40 [38] PIO program 1,a%() Error : 1 is invalid (valid is 0 to 0) > option list WebMite MMBasic Version 5.07.07 OPTION COLOURCODE ON OPTION CPUSPEED (KHz) 264000 OPTION DISPLAY 41, 140 OPTION WIFI Actiontec1177, ********** OPTION TCP SERVER PORT 80 OPTION TELNET CONSOLE ON I checked in the manual and the example provides PIO program 1, a% So at this stage I'm fumbling around in the dark unfortunately. Thank you for your assistance. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 9128 |
The web version uses PIO 1 to interface the web chip so only PIO 0 is available The VGA version uses PIO 0 to interface to the VGA display so only PIO 1 is available The standard version has both PIO available Just change all references to PIO 0 if running on the WebMite |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Thank you very much Volhout and Peter. It works! Much appreciated indeed. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Simplified and improved, and for PIO 0 on the webmite.. Note that the result accuracy is depending on the accuracy of the crystal on the pico. 'PIO frequency counter for PICOMITE MMBasic 'PIO program 'this PIO program samples the GPx pin for edges in 2 loops 'that are 2 instructions per loop so the resulting count is in 'ticks that are 2/f seconds. Each GPx period is 2 instructions off. Dim a%(7)=(&h0044004100c3a02b,&h8020a0c900c3,0,0,0,0,0,0) 'configure pio1 e=Pio(execctrl gp0,0,6) 'use gp0 for PIN f=133e6 '133MHz @ 2 instr per loop 'program pio0 and start PIO program 0,a%() PIO init machine 0,0,f,0,e PIO start 0,0 'pio fifo register Dim h%(4) 'read counted time, average over 4, and convert to frequency Do PIO read 0,0,5,h%() period=(h%(1)+h%(2)+h%(3)+h%(4))/4 + 2 'skip h%(0) = rubbish 'correct loop delay Print f/(2*period);" Hz" 'convert to the Hz Pause 1000 Loop While Inkey$="" PIO stop 0,0 End Edited 2023-08-27 05:28 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Hi Volhout Some queries, if I may, to gain insight and expand my knowledge. The WebMite manual v3 indicates that the MMBasic must assign the pin to the PIO with SetPin GPnn, PIO. I notice this has not been done in the example and does not appear to affect the operation of the program. In the manual Read GPIO a,b,c,d indicates that c, the number of 32 bit words to read has a range 1..4 and I see you use 5 to include the latest reading. In the normal usage of this method the very first 2 readings need to be discarded apparently. I assume this is due to the cleared FIFO register being filled as the PIO populates the FIFO with readings after the PIO start instruction. My understanding is that there are 4 state machines per PIO and these operate independently; thus one could develop a further 3 state machines to do something else on PIO0? Could you possibly provide the PIO menomics which yield the program contained in the array. I would like to understand what you did to get the period. I have tried to reverse engineer the a%() code but my depth of knowledge is lacking. The last time I did any menomic programming and state machines was in 1982 and rusty doesn't describe the holes in my memory on the subjects. I have run the PIO code on a PicoW and now need to migrate it to the Pico WH and see how it lives with the rest of the code :) I really appreciate your assistance, thanks again. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2136 |
Volhout's PIO introduction |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Thanks for the revised PIO program, much appreciated. I will follow the link provided and see to what level I can confuse myself. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
Hi Carl, At time of writing, the picomite did not have a build in assembler for PIO. It has now. And this is the same program when using the build in assembler. When assembling it immediately writes the program into memory. 'PIO frequency counter for PICOMITE MMBasic 'PIO program 'this PIO program samples the GPx pin for edges in 2 loops 'that are 2 instructions per loop so the resulting count is in 'ticks that are 2/f seconds. Each GPx period is 2 instructions off. PIO assemble 0,".program period" PIO assemble 0,".line 0" pio assemble 0,".wrap target" PIO assemble 0,"mov X,!null" PIO assemble 0,"posloop:" PIO assemble 0,"jmp pin negloop" PIO assemble 0,"jmp x-- posloop" PIO assemble 0,"negloop:" PIO assemble 0,"jmp x-- next" PIO assemble 0,"next:" PIO assemble 0,"jmp pin negloop" PIO assemble 0,"mov isr ,!x" PIO assemble 0,"push noblock" pio assemble 0,".wrap" PIO assemble 0,".end program list" 'configure pio0 e=Pio(execctrl gp0,pio(.wrap target),pio(.wrap)) 'use gp0 for PIN f=133e6 '133MHz @ 2 instr per loop 'program pio0 and start PIO init machine 0,0,f,0,e PIO start 0,0 'pio fifo register Dim h%(4) 'read counted time, average over 4, and convert to frequency Do PIO read 0,0,5,h%() period=(h%(1)+h%(2)+h%(3)+h%(4))/4 + 2 'skip h%(0) = rubbish 'correct loop delay Print f/(2*period);" Hz" 'convert to the Hz Pause 1000 Loop While Inkey$="" End I hope this helps... Volhout Edited 2023-08-27 18:05 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 4247 |
@Carl, You had another question I did not answer. About assigning a pin with SETPIN. When you want PIO to control a pin, then you must inform MMBasic to reserve it for PIO. When you want PIO to only read the pin status (high or low) you do not need to do that. In fact, it can be used to your advantage. The above program reads the pin status of GP0. You can add 2 lines to the program so MMBasic uses the same GP0 pin for PWM SETPIN gp0,PWM PWM 0,5000,50 Now the PWM generates a 5000Hz test tone that PIO measures. The reverse can also be done. Use SETPIN to assign a pin to PIO, make PIO generate a signal, and have MMBasic read the pin status with a=PIN(gpxx). Both above cross-functions are used in the PicoMite VGA LA (logic analyzer) that uses the PIO to sample the analyzer signals, and MMBasic to control and display. Edited 2023-08-27 18:29 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
carlschneider Senior Member Joined: 04/08/2023 Location: South AfricaPosts: 158 |
Thank you Volhout for your continued assistance. I will continue to apply my mind to the information you have so kindly provided as well as the material you have published on TheBackShed per the link provided by phil99. I note that the PIO Assembler writes directly to PIO memory. Using the assembler vs using the hand assembled string seems to take up more coding space. Not being able to read the 32 byte PIO memory makes the development cycle of PIO programs challenging :) In your detailed explanation I now see how multiple state machine codes reside in the 32 byte PIO memory, thanks. Your assistance is appreciated. Cheers Carl Retirement is tough on Hobbies without a day job |
||||
Chopperp Guru Joined: 03/01/2018 Location: AustraliaPosts: 1057 |
Hi Carl & Volhout Thanks for the posts. I was blatantly unaware of the PIO stuff. I have the need to measure low frequency stuff as well & I've got the 2 PIO channels going measuring frequencies OK. @Volhout. The only issue I have (so far) is that if the inputs drop off or become disconnected, the PIO still puts out readings, normally the same frequencies. Is there a way of inhibiting the output (or something else) if there is no signal input? My immediate solution is to monitor the inputs with other input pins set to PIN (or FIN) to check that there is a signal there or not. Again, thanks. Brian ChopperP |
||||
Page 1 of 2 |
Print this page |