Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HifiBerry or alternative DAC for Dynamic_RDS #23

Open
TomasRa1 opened this issue Nov 19, 2023 · 36 comments · Fixed by #27, #28, #31, #34 or #36
Open

HifiBerry or alternative DAC for Dynamic_RDS #23

TomasRa1 opened this issue Nov 19, 2023 · 36 comments · Fixed by #27, #28, #31, #34 or #36
Assignees
Labels
documentation Improvements or additions to documentation enhancement New feature or request FPP change A change or fix was needed in FPP hardware Relates to physical hardware pending verification Fix is done. Waiting to confirm.

Comments

@TomasRa1
Copy link

On https://www.aliexpress.com/item/1005005393398013.html is possible to buy very cheap but with relatively good audio quality DAC for Rpi with IC PCM5102A.
HifiBerryPCM5102A_DAC It works nicely as good quality audio driver for FM transmitter as I tested.
For Rpi connection it needs these Rpi GPIOs: +5V/pin2, GND/pin6, BCK/pin12, LCK/pin35, Din/pin40
You can see on picture mutual connection and also 4 PCB jumpers, which must be soldered as on this picture:
PCM5102_jumpers
For to use this or similar Rpi HifiBerry DAC or also for to use Rpi built-in PCM DAC we need reconnect Dynamic_RDS PWM output from pin32 (GPIO12) PWM0 to any other free pin, because built-in Rpi audio or external HifiBerry DAC needs this pin PWM0.
For more detailed informations regarding Rpi implementation of this HifiBerry DAC module, please visit eg. https://blog.himbeer.me/2018/12/27/how-to-connect-a-pcm5102-i2s-dac-to-your-raspberry-pi/.
I decided to use RPi pin11 (GPIO17) for PWM output.

It needs to modify "Dynamic_RDS_Engine.py".

  1. Delete (or comment by "#") all regarding PWM0.
  2. Added on the beginning of file to the end of IMPORT loads (from line 17):
~~~~~~
import smbus
import subprocess
import unicodedata
from time import sleep
from datetime import date, datetime, timedelta
from urllib.request import urlopen
from urllib.parse import quote
import RPi.GPIO as GPIO     # RPi GPIO for transmitter output power set
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.OUT)    # Set GPIO17/pin11 as PWM2 OUTPUT
pwm_2 = GPIO.PWM(17, 18000) # PWM2 set to GPIO17/pin11,PWMf=18kHz
pwm_2.start(0)              # PWM2 duty cycle=0 (0V on pin11)

@atexit.register
def cleanup():
  try:
    logging.debug('Cleaning up fifo')
    os.unlink(fifo_path)
  except:
    pass
  logging.info('Exiting')

# ===============
# Basic I2C Class
~~~~~~
  1. Add under "class QN80xx(Transmitter):/def update(self):/# TX gain changes and input impedance" and above "def shutdown(self):"(from line 271):
    # TX output power update
    pwm_2.ChangeDutyCycle(int(config['DynRDSQN8066AmpPower']))
    logging.info('PWM2 duty cycle updated to {}%'.format(config['DynRDSQN8066AmpPower']))
    self.activePWM = True
  1. Modify # With everything stopped, disable PWM (from line 279):
     # With everything stopped, disable PWM
    if self.activePWM:
      logging.debug('Stopping PWM2')
      pwm_2.ChangeDutyCycle(0)
      logging.debug('PWM2 duty cycle = 0')
      GPIO.cleanup()
      logging.debug('GPIO cleanup')
      self.activePWM = False

MODIFY Dynamic_RDS.php:

  1. Delete or comment by "//" PWM0 detection on lines 97-99
  2. Modify line 100 to: PrintSettingGroup("DynRDSPowerSettings", "", "", 1, "Dynamic_RDS", "DynRDSFastUpdate");
  3. Modify end of file lines 116-124:
> <h2>PWM and audio hardware setup</h2>
> <div class="container-fluid settingsTable settingsGroupTable">
> For output power control of 
> Transmitter board: <li>Connect Transmitter board PWM input pin -> to RPi pin11 (GPIO17)</li> <li>Use ferrite bead around cable 
> between RPi and Transmitter board.</li> For HiFiBerry DAC: <li>Add line to /boot/config.txt:</li> <li>dtoverlay=hifiberry-dac</li> 
> <li>HiFiBerry/RPi connection: +5V/pin2, GND/pin6, BCK/pin12, LCK/pin35, Din/pin40</li> </div> </div>                                         
> <div class="container-fluid settingsTable settingsGroupTable">
> </div>
> </div>

MODIFY settings.json from line 115 (to 140):

>         "DynRDSQN8066ChipPower": {
>             "name": "DynRDSQN8066ChipPower",
>             "description": "Chip Power (92-122)",
>             "tip": "Adjust the power output from the transmitter chip",
>             "restart": 0,
>             "reboot": 0,
>             "type": "number",
>             "min": 92,
>             "max": 122,
>             "step": 1,
>             "suffix": "dB&mu;V <i class='fas fa-fw fa-bolt fa-nbsp ui-level-1'></i>",
>             "default": 120
> 	},
>         "DynRDSQN8066AmpPower": {
>             "name": "DynRDSQN8066AmpPower",
>             "description": "Amp Power (0-100)",
>             "tip": "Adjust the power output for the amplifier after the transmitter chip.",
>             "suffix": "% <i class='fas fa-fw fa-bolt fa-nbsp ui-level-1'></i>",
>             "restart": 0,
>             "reboot": 0,
>             "type": "number",
>             "min": 0,
>             "max": 100,
>             "step": 1,
>             "default": 0
> 	},

I am not so proffesional as Mr. Nick Anderson. I think that my code for Dynamic_RDS_Engine.py needs tunning, because I am only amateur. Eg. I was also not sucessful with attempt to not send PWM value repeatedly when not changed. But I tested this my solution in longer transmitter's operation sucessfuly.
I also think that when we will sucessful with improve i2c I/O errors during communication by replace SMBUS with "SOFTWARE I2C" than we can change all values setting on Plugin FPP web page to change for immediately update without need any restart (as I already realized above on PWM and chip power set).
I hope that Nick will be understanding :-)

@ShadowLight8 ShadowLight8 self-assigned this Nov 20, 2023
@ShadowLight8 ShadowLight8 added enhancement New feature or request hardware Relates to physical hardware labels Nov 20, 2023
@ShadowLight8
Copy link
Owner

Ability to switch which PWM is being used will be part of #27, but it is just the framework at the moment

@ShadowLight8 ShadowLight8 added the in progress Actively being worked on, more or less label Dec 26, 2023
@ShadowLight8
Copy link
Owner

I decided to keep #27 to be the basic enable/disable for PWM. I'll start a new pull request to allow changing which pins are being used for PWM and I2C.

@ShadowLight8 ShadowLight8 added the documentation Improvements or additions to documentation label Dec 28, 2023
@ShadowLight8
Copy link
Owner

@TomasRa1 I've had some time to read through all the info you posted. I've ordered, what looks like, the same I2S board so I have a way to test. (https://www.amazon.com/gp/product/B08SLPHY2Z/)

I did find https://forums.raspberrypi.com/viewtopic.php?t=220082 mentioned being able to use i2s and hardware pwm at the same time by moving pwm to Pin 32 / GPIO 12, so I'm going to give that a try first. That would allow the hardware pwm to still be used, just on a different pin.

I saw your use of RPi.GPIO so I looked into it more as an option for software PWM. That which lead me to https://pythonhosted.org/RPIO/. RPIO can do PWM by using DMA, so it's the middle ground between hardware PWM and software PWM. Something I can look into, especially if the hardware pwm pin change doesn't work.

I've started work on being able to change hardware PWM pins. It's up as a draft PR #28

@TomasRa1
Copy link
Author

TomasRa1 commented Dec 29, 2023

Thank you very much Nick!
HiFiBerry DAC needs these Rpi GPIOs: +5V/pin2, GND/pin6, BCK/pin12, LCK/pin35, Din/pin40. There are GPIO pins 18, 19, 21.
I would like to prefer configure any free pin for PWM, because it is universal at all cases.
Pin 11 (Gpio17) is located next to GND pin and it is thanks this position shielded from other i2c pins, which we use for Transmitter module and at the same time pin11 is next to these i2c pins, we can easy use flat 6pin connector for RPi and Transmitter interconnection. I think it is favorable to use pin11 for PWM.

It is also possible to update PWM value dynamically in time, we do not need restart FPPD or any reboot for to change PWM value (the same as power of TX chip 8066). I changed Dynamic_RDS.php and settings.json source files (as I already described here above) for this dynamic set of PWM value. And also tested OK.

@ShadowLight8
Copy link
Owner

I've got the hardware PWM pin selection done in #28
Next, I'll follow your idea and make the PWM value dynamic so restarts are not needed.
After that, I'll start looking into using RPIO so any gpio pin can be PWM.

@ShadowLight8 ShadowLight8 added the FPP change A change or fix was needed in FPP label Dec 30, 2023
@ShadowLight8
Copy link
Owner

@TomasRa1 I've merged #28, but it required an FPP change that has been merged, but only to master/fpp. I've guessing the next release will have it. Until then, the hardware pwm pin change won't work.

I'll start looking into using RPIO next!

@chrkov
Copy link

chrkov commented Jan 1, 2024

I have been looking for a nice DAC that has RCA outputs. I found this (https://www.amazon.com/Decoder-Amplifier-PCM5102-PCM5102A-Headphone/dp/B0C7KQPR7S/ref=sr_1_50?crid=KTYBTOFN5CGZ&keywords=PCM5102&qid=1704083256&s=industrial&sprefix=pcm5102%2Cindustrial%2C104&sr=1-50)
and just wondering if you think this would work also? It seems to have the same connections.

@TomasRa1
Copy link
Author

TomasRa1 commented Jan 1, 2024

Yes, it is the same chip PCM5102A, it must also works.
I hope that connection could be:
AltDAC_PCM5102A
BCK = BCK
DATA = DIN
LRCK = LCK
GND = GND
VCC = VIN

FLT=N = SCK jumper soldered (ICpin12=GND)
FMT=I2S

Please, test it and inform us regarding result if my ideas above are correct. Thank you.

@TomasRa1
Copy link
Author

TomasRa1 commented Jan 1, 2024

@TomasRa1 I've merged #28, but it required an FPP change that has been merged, but only to master/fpp. I've guessing the next release will have it. Until then, the hardware pwm pin change won't work.

I'll start looking into using RPIO next!

It will be nice to implement PWM via RPIO, thank you very much!
https://pythonhosted.org/RPIO/

from RPIO import PWM

# Setup PWM and DMA channel 0
PWM.setup()
PWM.init_channel(0)

# Add some pulses to the subcycle
PWM.add_channel_pulse(0, 17, 0, 50)
PWM.add_channel_pulse(0, 17, 100, 50)

# Stop PWM for specific GPIO on channel 0
PWM.clear_channel_gpio(0, 17)

# Shutdown all PWM and DMA activity
PWM.cleanup()

@ShadowLight8
Copy link
Owner

The merge of #31 makes it so the dynamic changing of the pwm amp power works. I'm continuing work on RPIO

@ShadowLight8
Copy link
Owner

Draft pull request of work in progress is up #34

@ShadowLight8
Copy link
Owner

RPIO is pretty old and no longer maintained, so it doesn't have support already in place for the newer Pi's. I'm looking into options to update it or finding a similar PWM via DMA library. A key part is finding something that is light weight.

@chrkov
Copy link

chrkov commented Jan 11, 2024

I dont know if it helps, but maybe look at WLED and what they are doing? It seems they have the ability to move pins around so they must be using something. Maybe it would work for PI. Again, I am no programmer, just tossing ideas out.

@chrkov
Copy link

chrkov commented Jan 12, 2024

Should the DAC be able to work now without affecting this plugin? Because I have the DAC hooked up and it is working (outputs sound), but now I am seeing issues with this plugin. I believe PWM is not working as I can no longer adjust the power. I have the PWM set to "PIN 32 / GPIO 12". The only reason I am thinking this is because my range is no where near what it was before.

@ShadowLight8
Copy link
Owner

I'll check that pin's output and try to add in my DAC this weekend to test.

@ShadowLight8
Copy link
Owner

@chrkov I've not physically hooked up the DAC yet, but I did setup everything on the PI for it (confirmed that is show up with aplay -l). Using my logic analyzer, I can see PWM output on Pin 32. Something might change when I actually connect the DAC and play audio, so I'll check again once I'm to that point.
PWM-Pin32

@ShadowLight8
Copy link
Owner

PWM via DMA Notes
Seems that no single option would cover everything, but seems like bringing together parts of each might be an option.

https://github.com/jbentham/rpi

https://github.com/besp9510/dma_pwm

https://github.com/metachris/RPIO

  • Multiple files and folders
  • Ok docs - https://pythonhosted.org/RPIO/
  • Test code
  • 9 years old
  • Highest complexity, does more than pwm and would take time to pull out
  • Python interface
  • Very out dated RPi revision code - Based on RPI.GPIO code
  • Pin to GPIO mappings

https://sourceforge.net/projects/raspberry-gpio-python/

  • RPi revision code

@chrkov
Copy link

chrkov commented Jan 14, 2024

Is there any logs or anything I can do to help troubleshoot the issue? I am not sure if there is any feedback given when the change is made to see if its taken. I can see in the logs when I make a change to the power:
03:36:46 INFO Config {'DynRDSEnableRDS': '1', 'DynRDSPSUpdateRate': '2', 'DynRDSPSStyle': 'Merry|Christ-|-mas!', 'DynRDSRTUpdateRate': '6', 'DynRDSRTSize': '32', 'DynRDSRTStyle': 'Christmas on 124th Ave|{T}[ / {A}]|[Track {N} of {C}]|See you for the 2024 Show!', 'DynRDSPty': '22', 'DynRDSPICode': '3DC6', 'DynRDSTransmitter': 'QN8066', 'DynRDSFrequency': '88.9', 'DynRDSPreemphasis': '75us', 'DynRDSQN8066Gain': '0', 'DynRDSQN8066SoftClipping': '1', 'DynRDSQN8066AGC': '0', 'DynRDSQN8066ChipPower': '122', 'DynRDSQN8066PIHardwarePWM': '1', 'DynRDSQN8066AmpPower': '100', 'DynRDSStart': 'FPPDStart', 'DynRDSStop': 'Never', 'DynRDSCallbackLogLevel': 'INFO', 'DynRDSEngineLogLevel': 'INFO', 'DynRDSmpcEnable': '1', 'DynRDSAdvPISoftwareI2C': '1', 'DynRDSAdvPIPWMPin': '12,4', 'DynRDSQN8066DigitalGain': 0, 'DynRDSQN8066InputImpedance': 1, 'DynRDSQN8066BufferGain': 1}

@TomasRa1
Copy link
Author

TomasRa1 commented Jan 14, 2024

Nick, please, try to use RPi.GPIO solution and adapt it, please. I tested it sucessfully. Yes, it is SW emulation, but we do not need extrem speed resp. PWM frequency 18kHz is low and RPi manage it without any problem or any overload.
It is good to block PWM pin on the transmitter board by small ceramic capacitor 22n against GND. This capacitor round the edges of the pulses and remove noise from the PWM wire and capacitive coupling PWM signal to other wires. I also tested sucessfully.

Chrkov: (if I understand correctly) PWM signal is only transmited signal from RPi to transmitter (TX) board. On the TXboard is analog OP which convert digital PWM signal to analog level, which regulate voltage to PA driver. It is simple passive analog solution, not digital. Due to PWM signal cannot be validated by CPU as backward received data for secondary validation. We can only set PWM frequency and duty cycle and regarding duty cycle we can display percentual level of regulated voltage - eg. 100% = 10V and 10% = 1V, etc. We cannot validate how to data were set. We can only display actual set value of duty cycle. But you can connect SWR metter between RF output connector and antenna and you can see forward (and reflected) output power directly.

@chrkov
Copy link

chrkov commented Jan 14, 2024

So two things. 1. Can I put a voltage meter on the PWM pin then and measure the voltage out to verify if its working then? If so, was your example about 1V = 10% and 10V = 100% just an example or what I should really see?

Is there a cheap SWR meter? I would only need it for this, so I dont want to spend a lot on it. Does something like this (https://www.amazon.com/Astatic-PDC1-100-Watt-Meter/dp/B004ULN610) do the trick for basic testing? It says for CB, but I know those frequencies are different than FM.

@ShadowLight8
Copy link
Owner

Is there any logs or anything I can do to help troubleshoot the issue? I am not sure if there is any feedback given when the change is made to see if its taken. I can see in the logs when I make a change to the power:....

@chrkov Can you run grep -i dt /boot/config.txt? That will list the dtparam and dtoverlay lines. It's possible that something got messed up since the code to edit that file is not very fancy.

You can also see what the PWM settings are with
cat /sys/class/pwm/pwmchip0/pwm0/period Should be 18300
cat /sys/class/pwm/pwmchip0/pwm0/duty_cycle Varies with Amp Power setting
cat /sys/class/pwm/pwmchip0/pwm0/enable Should be 1

Also, I just merged #34 which gets the other 2 hardware pwm pins working. You might give that a try.

@ShadowLight8
Copy link
Owner

Nick, please, try to use RPi.GPIO solution and adapt it, please. I tested it sucessfully. Yes, it is SW emulation, but we do not need extrem speed resp. PWM frequency 18kHz is low and RPi manage it without any problem or any overload. It is good to block PWM pin on the transmitter board by small ceramic capacitor 22n against GND. This capacitor round the edges of the pulses and remove noise from the PWM wire and capacitive coupling PWM signal to other wires. I also tested sucessfully.

@TomasRa1 I'll take a look at this route with software PWM as much as I don't like it :) Since you've had success with it, it does give me confidence that it is a reasonable option.

This was linked to pull requests Jan 14, 2024
@chrkov
Copy link

chrkov commented Jan 14, 2024

Here is the outputs of those commands. None of the cat commands found a file? Is there a typo there or is that my problem? If I do a 'ls' under /sys/class/pwm' I dont see any subdirs...

fpp@cmk-od-fpp01:~ $ grep -i dt /boot/config.txt
#framebuffer_width=1280
#sdtv_mode=2
#dtparam=i2c_arm=on
dtoverlay=i2c-gpio,i2c_gpio_sda=2,i2c_gpio_scl=3,i2c_gpio_delay_us=4,bus=1
#dtparam=i2s=on
#dtparam=spi=on
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18
#dtparam=audio=on
#dtoverlay=vc4-kms-v3d
dtparam=spi=on
#dtparam=i2c_arm=on
dtoverlay=i2c-gpio,i2c_gpio_sda=2,i2c_gpio_scl=3,i2c_gpio_delay_us=4,bus=1
#dtparam=audio=on
dtoverlay=pwm
dtparam=i2s=on
dtoverlay=hifiberry-dac
dtparam=i2c_arm=on

fpp@cmk-od-fpp01:~ $ cat /sys/class/pwm/pwmchip0/pwm0/period
cat: /sys/class/pwm/pwmchip0/pwm0/period: No such file or directory
fpp@cmk-od-fpp01:~ $ cat /sys/class/pwm/pwmchip0/pwm0/duty_cycle
cat: /sys/class/pwm/pwmchip0/pwm0/duty_cycle: No such file or directory
fpp@cmk-od-fpp01:~ $ cat /sys/class/pwm/pwmchip0/pwm0/enable
cat: /sys/class/pwm/pwmchip0/pwm0/enable: No such file or directory

@ShadowLight8
Copy link
Owner

ShadowLight8 commented Jan 14, 2024

@chrkov For the cat commands, that tells me the hardware pwm didn't get setup correctly for some reason. A few things in your config.txt that might be part of it:
dtoverlay=pwm
dtparam=i2c_arm=on
While neither are wrong, the plugin updates the pwm line with pin and func (otherwise it defaults to Pin 12 / GPIO 18). The i2c_arm=on is hardware i2c where the i2c-gpio is the software i2c. I'm surprised to see both.

If you haven't already, update the plugin to get the latest.

To see if we can get it out of this state using the plugin, on the Dynamic_RDS config page, change the PI PWM Pin to Pin 12 / GPIO 18, uncheck Enable Pi PWM, uncheck Use PI Software I2C. That should clean up things in the /boot/config.txt. You can check with the grep -i dt /boot/config.txt to see the changes. Next, you can re-enable PWM, re-enable software I2C, and set your PWM pin again. Run the grep command again and you should see lines like:
dtoverlay=i2c-gpio,i2c_gpio_sda=2,i2c_gpio_scl=3,i2c_gpio_delay_us=4,bus=1 without an uncommented dtparm=i2c_arm=on
dtoverlay=pwm,pin=12,func=4
After that reboot and see if that clears things up.


For comparison, here's what the grep -i dt /boot/config.txt looks like for me:

fpp@FPP-DevPi:~/media/plugins/Dynamic_RDS $ grep -i dt /boot/config.txt
#framebuffer_width=1280
#sdtv_mode=2
#dtparam=i2c_arm=on
dtparam=i2s=on
dtoverlay=hifiberry-dac
#dtparam=spi=on
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18
#dtparam=audio=on
dtoverlay=pwm,pin=18,func=2
#dtoverlay=vc4-kms-v3d
dtparam=spi=on
dtparam=i2c_arm=on,i2c_arm_baudrate=400000
#dtparam=audio=on
#dtoverlay=pwm,pin=13,func=4
dtoverlay=pi3-miniuart-bt
dtoverlay=dwc2

@chrkov
Copy link

chrkov commented Jan 14, 2024

So I did the following. Change PWM pin to 12, disabled PWM and disabled Software I2C. Rebooted. Ran check on config.txt with output.

fpp@cmk-od-fpp01:~ $ grep -i dt /boot/config.txt
#framebuffer_width=1280
#sdtv_mode=2
dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18
#dtparam=audio=on
#dtoverlay=vc4-kms-v3d
dtparam=spi=on
dtparam=i2c_arm=on
#dtparam=audio=on
dtparam=i2s=on
dtparam=i2c_arm=on
dtparam=i2s=on
dtparam=i2s=on
dtoverlay=hifiberry-dac
dtparam=i2s=on

Not sure why I see so many dtparam=i2c=on now.

Go back in to config and reenable PWM, Software I2C and set pin to 32. Reboot.

Run check on config.txt and it is now:

fpp@cmk-od-fpp01:~ $ grep -i dt /boot/config.txt
#framebuffer_width=1280
#sdtv_mode=2
#dtparam=i2c_arm=on
dtoverlay=i2c-gpio,i2c_gpio_sda=2,i2c_gpio_scl=3,i2c_gpio_delay_us=4,bus=1
#dtparam=i2s=on
#dtparam=spi=on
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18
#dtparam=audio=on
#dtoverlay=vc4-kms-v3d
dtparam=spi=on
#dtparam=i2c_arm=on
dtoverlay=i2c-gpio,i2c_gpio_sda=2,i2c_gpio_scl=3,i2c_gpio_delay_us=4,bus=1
#dtparam=audio=on
dtparam=i2s=on
#dtparam=i2c_arm=on
dtoverlay=i2c-gpio,i2c_gpio_sda=2,i2c_gpio_scl=3,i2c_gpio_delay_us=4,bus=1
dtparam=i2s=on
dtparam=i2s=on
dtoverlay=hifiberry-dac
dtparam=i2s=on

and the Config page says this:

image

and still nothing under the directory /sys/class/pwm

I also did upgrade to 7.5. and after the upgrade the DAC was gone. I checked before I did anything and the /sys/class/pwm directory was populated and the cat commands all came back as you said. Then I ran the Enable_HiFiBerry.sh script and the /sys/class/pwm directory went blank again. I am starting to thing that script does something to cause me issues. Is that the script you guys are using to enable the DAC also?

@ShadowLight8
Copy link
Owner

@chrkov I'm still not sure what is happening that's causing the issue. The first config.txt output shows me that the i2c setting updated in the config.txt from software to hardware as expected. As expected, the pwm line was removed, but it should have uncommented #dtparam=audio=on as well, but that doesn't appear to be the case.

In the second config.txt output, again, it looks like the i2c settings worked as expected, but no pwm line appears. It should be right after the #dtparam=audio=on lines.

I'm not familiar with the Enable_HiFiBerry.sh script, but I'll take a look. I'm guessing it adds the dtparam=i2s=on and dtverlay=hifiberry-dac lines. I had just followed https://blog.himbeer.me/2018/12/27/how-to-connect-a-pcm5102-i2s-dac-to-your-raspberry-pi/ and manually updated the /boot/config.txt.

You can manually add the following to your /boot/config.txt to setup PWM on Pin 32 / GPIO 12:
dtoverlay=pwm,pin=12,func=4
I'd put it right after one of the #dtparam=audio=on lines

@chrkov
Copy link

chrkov commented Jan 14, 2024

ok. Pretty sure that using the Enable_HiFiBerry.sh script did something bad to my system. I have noticed several oddities since I did that (Like my UserCallbackHook.sh script no long runs either). I grabbed a new SD card and reinstalled a fresh copy of FPP 7.5 and installed everything and its working perfect (like before I added the DAC) but using your directions above for adding the DAC. I think we are all good now.

@ShadowLight8
Copy link
Owner

This morning, after rebooting my Pi, I noticed that pwm wasn't working. Looking into the syslog to see why, I discovered that there is a race condition in startup between the hardware pwm0 on pin 18 and i2s when both are enabled. While I know they both want pin 18, it seems like it is random who gets it. I'm not using the DAC yet, so that's why I still have pin 18 set. It should be easy enough to check for, so I'll add a warning about it.

@ShadowLight8
Copy link
Owner

@TomasRa1 I've got my first version of software PWM in #36 now. Once I split out the PWM functionality to a new class, it went pretty quick to get it added. More testing is needed to make sure it works well.

I've been looking at the software PWM output with my logic analyzer. Here's what I have observed so far - While I set the base frequency to 10kHz, I'm seeing something closer to ~4-6kHz. Trying an Amp Power of 30, which sets a 10% duty cycle, I'm seeing much higher (25-35%) on my analyzer. While I haven't try it on the transmitter yet, I expect it will increase the output power, but the control of it won't be as good as the hardware PWM (which runs at 54.6kHz).

I'll spend some more time to see if I can get this to be better.

@ShadowLight8 ShadowLight8 reopened this Jan 18, 2024
@ShadowLight8 ShadowLight8 added pending verification Fix is done. Waiting to confirm. and removed in progress Actively being worked on, more or less labels Jan 18, 2024
@ShadowLight8
Copy link
Owner

I've merged #36 to the main branch, so you can update the plugin. To use the software PWM, enable PWM, then select a Software pin in the advanced options.

@chrkov
Copy link

chrkov commented Jan 18, 2024

Testing out Pin 11 right now and everything seems to be working well.

I am guessing Duty Cycles are different?

@ShadowLight8
Copy link
Owner

@chrkov The frequency of the software PWM is an order of magnitude slower than hardware PWM (5 kHz vs 50 kHz). The duty cycle with software PWM is not as granular either, so you might find an Amp Power of 1 and an Amp Power of 30 have about the same effect on the transmitter.

I don't have enough electrical engineering knowledge to know how the slower PWM frequency impacts the amplification circuit on the transmitter board, but I'm glad to hear that it seems to do something :)

@TomasRa1
Copy link
Author

Hello Nick, thank you very much for your great work!
Real measured frequency of PWM could be outside of audible frequencies, which is used for FM transmitting, which is up to 15kHz and also outside of all FM subcarrier frequencies: 19kHz-pilot stereo, 38kHz-L/R switching, 56-58kHz-RDS.
I think that optimal real measured output PWM frequency, which cannot interfere in FM radio chain is around 18kHz, because audible frequencies around 19kHz are suppressed in stereocoder on transmitter side and also on FM receiver side. Frequency 5kHz could be audible as whistling. I recommend to set PWM frequency to output frequency around 18kHz eg. 17-18kHz.
Thank you again for all!

@ShadowLight8
Copy link
Owner

@TomasRa1 I'll do some more testing and tweaking to see if I can get a higher frequency out of the software pwm. I might also see about making the software pwm period/frequency a configurable advanced option as well.

@ShadowLight8
Copy link
Owner

ShadowLight8 commented Jan 25, 2024

@TomasRa1 @chrkov I've spent sometime testing different things with Software PWM and the results are disappointing. For reference, this was all tested on a Raspberry Pi 3B+. The short version is that no matter what I've set, the actual PWM output is significantly different than expected and is effectively providing more power to the transmitter than desired. I'm not even factoring in the jitter and other inconsistencies in timing I saw. I tried to get the best, most consistent numbers, while testing.

Set Freq - What I used in the code to initialize RPi.GPIO
Set Amp Power - From config screen
T1 Duty Cycle - Measured the time of the high part of the pwm
T2 Period - Measured from the start of high to the next start of high
Calc Freq - Calculated the frequency from T2
Calc Amp Power - What the equivalent Amp Power setting would be based on the pwm measurements

image
As the pwm frequency goes up, the actual frequency measured gets further from expected. At 2000Hz, it's pretty close, but even 5000Hz is only managing 3000Hz and it continues to get worse from there.
Amp Power basically corresponds to the Duty Cycle, but you can see that at low amp power setting, the measured amp power (derived from the duty cycle) is much higher than it should be. At the higher frequencies, it is much worse, but even at 2000Hz it isn't great.

I'm going to look over the code in RPi.GPIO to see if anything looks odd, especially around the frequency.

@TomasRa1
Copy link
Author

TomasRa1 commented Jan 25, 2024

I tested with set frequency to 18kHz (as I wrote in the code) and not registered inconsistency in power regulation. Maybe it was not perfect, but in real operation the regulation was consistent. When I will have a time I try to measure PWM signal with osciloscope. I understand that set frequency is different (lower with dependency on the frequency) than real transmitted PWM frequency. I used blocking capacitor 22n connected from PWM pin to GND on the transmitter board and check on osciloscope that edges of pulses are rounded. I also check that PWM frequency from original china's CPU controller was around 54kHz. I will inform later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment