Low frequency Signal generator for CTCSS

RP2040 based microcontroller boards running MicroPython.
Target audience: MicroPython users with an RP2040 boards.
This does not include conventional Linux-based Raspberry Pi boards.
User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Low frequency Signal generator for CTCSS

Post by pythoncoder » Tue Aug 03, 2021 4:35 am

Looks reasonable to me!
Peter Hinch
Index to my micropython libraries.

User avatar
Pip
Posts: 11
Joined: Mon Jul 12, 2021 6:37 pm
Contact:

Re: Low frequency Signal generator for CTCSS

Post by Pip » Wed Aug 04, 2021 12:00 am

Just to close off. I tested this in my code with all the other timers and it is working as predicted. A steady output with an accurate frequency.

One concern I had was rounding errors in the calculations and clock divisions, so I did another experiment by upping the frequency and dividing down by 500 to see if I could see any difference in precision while monitoring the output with a frequency counter. I found that I couldn't really see any difference between 100 x and 500x , so I guess the accuracy must be better +- 0.05%

Good enough for what I need.

Many thanks for everyone's help.

Cheers

hippy
Posts: 130
Joined: Sat Feb 20, 2021 2:46 pm
Location: UK

Re: Low frequency Signal generator for CTCSS

Post by hippy » Wed Aug 11, 2021 3:24 pm

Pip wrote:
Mon Aug 02, 2021 3:25 pm
As I mentioned in micropython on the Pico we can't do fractions of Hz.
But that's simply because the .freq(hz) implementation doesn't accept anything other than an integer argument. Allow it to accept float and integer and it does just fine -- within the limits of rounding errors and hardware limitations.

The current Pico implementation of .freq(hz) is completely wacko, often doesn't generate the frequencies one has asked for, so perhaps support for float values could be added when that gets fixed.

https://www.raspberrypi.org/forums/view ... 1#p1895341

taPIQoLEHUMA
Posts: 15
Joined: Thu Mar 04, 2021 2:59 am

Re: Low frequency Signal generator for CTCSS

Post by taPIQoLEHUMA » Fri Aug 13, 2021 3:43 am

The PWM hardware can do more that what MP limits us to.

From the RP2040 datasheet, section 4.5.2.6, the output frequency is:

Code: Select all

fpwm = 125MHz / (top + 1) / div_int
(ignoring the phase correct flag and fractional divider)

Write a quick program and brute-force search for the output you want.
For the 76.7 tone:

Code: Select all

	div	top	    fpwm
	42	38802	     76.7000
	25	65188	     76.7001
	47	34674	     76.7001
	73	22324	     76.7001
	95	17154	     76.7001
And that's using only the integer divider, ignoring the fractional part.
The major source of error would be the crystal, yes?

taPIQoLEHUMA
Posts: 15
Joined: Thu Mar 04, 2021 2:59 am

Re: Low frequency Signal generator for CTCSS

Post by taPIQoLEHUMA » Sat Aug 14, 2021 1:55 am

Here's a table of divider and top values for each of the tones.

Code: Select all

CTCSS tones 50
div	top	freq	fpwm	diff
101	18471	67.0000	67.0000	-0.0000
46	39211	69.3000	69.3000	-0.0000
89	19533	71.9000	71.9000	-0.0000
31	54196	74.4000	74.4000	0.0000
31	52366	77.0000	77.0000	-0.0000
103	15226	79.7000	79.7000	0.0000
181	8370	82.5000	82.5000	0.0000
25	58547	85.4000	85.4000	0.0000
23	61409	88.5000	88.5000	-0.0000
34	40179	91.5000	91.5000	0.0000
26	50713	94.8000	94.8001	0.0001
59	21751	97.4000	97.4000	-0.0000
20	62499	100.0000	100.0000	0.0000
31	38958	103.5000	103.5000	0.0000
101	11544	107.2000	107.2000	-0.0000
27	41745	110.9000	110.9000	-0.0000
17	64049	114.8000	114.8000	0.0000
47	22386	118.8000	118.7999	-0.0001
17	59779	123.0000	123.0000	0.0000
28	35068	127.3000	127.3001	0.0001
227	4177	131.8000	131.8001	0.0001
185	4949	136.5000	136.5001	0.0001
131	6752	141.3000	141.2999	-0.0001
14	61070	146.2000	146.1999	-0.0001
127	6500	151.4000	151.4001	0.0001
29	27506	156.7000	156.6999	-0.0001
167	4683	159.8000	159.8000	-0.0000
13	59280	162.2000	162.2001	0.0001
13	58098	165.5000	165.5000	0.0000
53	14046	167.9000	167.8999	-0.0001
19	38405	171.3000	171.3000	-0.0000
157	4580	173.8000	173.8001	0.0001
20	35250	177.3000	177.2999	-0.0001
15	46321	179.9000	179.9001	0.0001
14	48656	183.5000	183.5002	0.0002
29	23148	186.2000	186.2000	0.0000
71	9270	189.9000	189.9001	0.0001
10	64833	192.8000	192.8001	0.0001
12	52983	196.6000	196.6002	0.0002
23	27241	199.5000	199.5001	0.0001
19	32328	203.5000	203.4999	-0.0001
173	3498	206.5000	206.5000	-0.0000
10	59325	210.7000	210.7002	0.0002
14	40937	218.1000	218.0998	-0.0002
21	26372	225.7000	225.6998	-0.0002
17	32094	229.1000	229.0993	-0.0007
16	33443	233.6000	233.5994	-0.0006
11	46995	241.8000	241.8001	0.0001
9	55488	250.3000	250.2999	-0.0001
14	35137	254.1000	254.1002	0.0002

taPIQoLEHUMA
Posts: 15
Joined: Thu Mar 04, 2021 2:59 am

Re: Low frequency Signal generator for CTCSS

Post by taPIQoLEHUMA » Sat Aug 14, 2021 2:02 am

A better sine approximation can be done with two PWM outputs. The PWM frequency is 6 times the resulting sine wave frequency, which means the first overtone for the "sine" is 6x the frequency, so it's easier to filter. Use the up/down mode, and set the PWM levels to 1/3 and 2/3. Sum the outputs with equal value resistors to get a stepped approximation. Use machine.mem32 to poke the registers after MP configures it.

You get something like this:

Code: Select all

	pwm A	__--__
	pwm B	_----_
	sum	_-''-_		two low, mid, two high, mid
And here's the table of best dividers and top values for the tone frequencies x 6. Higher frequency so a little more error.

Code: Select all

CTCSS tones 50
6x freq phase-correct
div	top	freq	fpwm	diff
3	51823	402.0000	402.0016	0.0016
83	1810	415.8000	415.7990	-0.0010
23	6298	431.4000	431.4004	0.0004
4	35001	446.4000	446.4031	0.0031
7	19325	462.0000	461.9979	-0.0021
2	65348	478.2000	478.2017	0.0017
31	4072	495.0000	494.9985	-0.0015
5	24394	512.4000	512.4001	0.0001
2	58850	531.0000	531.0020	0.0020
2	56921	549.0000	548.9969	-0.0031
2	54939	568.8000	568.8023	0.0023
3	35648	584.4000	584.4016	0.0016
7	14880	600.0000	599.9981	-0.0019
2	50321	621.0000	621.0008	0.0008
2	48584	643.2000	643.2026	0.0026
2	46963	665.4000	665.4033	0.0033
2	45368	688.8000	688.7963	-0.0037
2	43840	712.8000	712.8031	0.0031
2	42343	738.0000	738.0030	0.0030
2	40913	763.8000	763.7972	-0.0028
2	39516	790.8000	790.7989	-0.0011
17	4488	819.0000	818.9955	-0.0045
2	36859	847.8000	847.8025	0.0025
2	35624	877.2000	877.1930	-0.0070
3	22933	908.4000	908.4038	0.0038
5	13294	940.2000	940.2031	0.0031
1	65185	958.8000	958.7948	-0.0052
3	21406	973.2000	973.2019	0.0019
1	62940	993.0000	992.9934	-0.0066
7	8862	1007.4000	1007.3983	-0.0017
1	60808	1027.8000	1027.8084	0.0084
1	59934	1042.8000	1042.7964	-0.0036
1	58751	1063.8000	1063.7936	-0.0064
1	57902	1079.4000	1079.3914	-0.0086
1	56766	1101.0000	1100.9918	-0.0082
1	55942	1117.2000	1117.2086	0.0086
1	54852	1139.4000	1139.4090	0.0090
1	54027	1156.8000	1156.8076	0.0076
1	52983	1179.6000	1179.6014	0.0014
1	52213	1197.0000	1196.9970	-0.0030
1	51187	1221.0000	1220.9893	-0.0107
1	50443	1239.0000	1238.9977	-0.0023
1	49437	1264.2000	1264.2097	0.0097
7	6822	1308.6000	1308.5991	-0.0009
1	46152	1354.2000	1354.1915	-0.0085
1	45467	1374.6000	1374.5931	-0.0069
1	44591	1401.6000	1401.5967	-0.0033
1	43079	1450.8000	1450.7892	-0.0108
1	41616	1501.8000	1501.7901	-0.0099
1	40993	1524.6000	1524.6134	0.0134

hippy
Posts: 130
Joined: Sat Feb 20, 2021 2:46 pm
Location: UK

Re: Low frequency Signal generator for CTCSS

Post by hippy » Mon Aug 16, 2021 3:21 pm

For accurate musical tones, 2-bit sine wave generation, one would be better off ignoring PWM and implementing a frequency generator using a PIO.

There is an example of that here - https://www.raspberrypi.org/forums/view ... 5#p1902085 - which is part of a thread on improving the pwm.freq() implementation and creating accurate PWM frequencies.

taPIQoLEHUMA
Posts: 15
Joined: Thu Mar 04, 2021 2:59 am

Re: Low frequency Signal generator for CTCSS

Post by taPIQoLEHUMA » Mon Aug 16, 2021 7:38 pm

For accurate musical tones,
Accurate how? Spectra or pitch? You saw the errors - one thousandth of a Hertz difference isn't going to affect the CTCSS tone detection.

And if you really have to go the PIO route, you can drive 4 outputs to get a 5-level sine approximation, with the first overtone at 10x the base frequency. There's articles out there about Johnson walking ring counters to make sine waves. It's also in The Art of Electronics.

Post Reply