My digital countryside

EN Emuārs par darbiem, nedarbiem u.c. lietām, kuras gribas publiski pierakstīt.
en lv

How to set GPIO high on RasPi when sound is played

Aleady some time - a year ago I bought couple of simple Easy Digi devices from KF5INZ. Accidentaly I got one extra - there was some mistake. I offered to send it back, but as shipping was costly, than seller kindly left it as bonus.

At that time I hoped, that it can help me to pair my old Kenwood TS-50S with PC and do some digital modes, but it was not so easy as that radio has pretty old and there was not so much info on PC interfacing on net. So these Easy Digi Boxes has almoust forgoten until I finaly decided to buy and tinker around RasPi. The idea was similar - to do some interfacing with a radio. But in this case at first to try to make some simple tasks, like simple parrot repeater, auto transmission recorder or pair with some voice recognition AI software.

I had some success with Mycroft AI on my big linux box, when I used it with Easy Digi and some handheld with VOX option activated. I could ask questions and got anwers by using another handheld radio. Those was Che-Chi PoC radios like UV-5R or similar and I was not satisfied about VOX stability. So I was thinking how to fire PTT line on sound output.

I got near solution when started to tinker around RasPi. Here also some note on Easy Digi - it is actualy as very simple device with two sound transformers for RF isolation and also simple orthocoupler circuit for shorting PTT lines. It can be used with some serial port programming or for RasPi case gpio programing.

I was not very succesful for diging some samples for serial port programming on linux, but for RasPi there was plenty info regarding gpoi programing and samples. So my joyrney was suucessfull.

So bellow is my notes how to achieve this task - set gpio high on RasPi when sound is played. Then we can use gpio voltage level to switch on some device or “push PTT” on the transceiver.

Requirements: Some knowledge about RasPi and linux command line. Rasbery Pi with USB sound card. Configured and installed necesary sound drivers and utilities. Unfortunately I did not documented it, but mainly it is just the same “apt-get install …” method

By digging net I found that it is possible to check sound output by checkin some status “directory”. But first I had to setup my USB sound card as RasPi has just sound outputs, but for my case I need also input i.e. microphone input. We can also live by just plugging in an USB sound card and use default set up. But it means that attached USB sound card will be some secondary etc. after RasPi onboard sound outputs, that are not just one (remember, that HDMI also has sound out). So as my plans was use RasPi in headless mode I also whanted that my USB sound card was primary or sound card 0.

First I checked what is sound cards order:

$ cat /proc/asound/modules
 0 snd_bcm2835
 1 snd_usb_audio

To reorder soundcards I used file: /etc/modprobe.d/usb-sound.conf The file name could be any thing as far it have .conf extension. The contents of /etc/modprobe.d/usb-sound.conf

# Set the index value of the cards.
options snd_usb_audio index=0
options snd_bcm2835 index=1

# Reorder sound cards
options snd slots=snd_usb_audio,snd_bcm2835

Now reboot RasPi and check:

By attaching some microphone or sound input to USB card testing for sound input:

$ arecord test.wav

And similar way for output:

aplay test.wav

The sound should came in and out through attached USB sound card.

To check is the sound output active we can specific dir or rather some virtual file that is created each time when a sound card is activated:

/proc/asound/card0/pcm0p/sub0/status

You can check whichever is yours, but as I ordered my sound card as card with index=0, than is now card0.

We also need to know which GPIO we should and/or want to use. I choosed to used GPIO 27, because it has righ behind them groud GPIO. So it is ieasier to find them and also possible to use paired GPIO connectors.

Create main script file, that checks for sound card status file and accordingly set GPIO voltage level high or low:

sudo nano /usr/local/bin/sound2gpio.sh

Paste script content in nano editor and exit from nano text editor and save the file:

#!/bin/bash

#Sound card statuss "file"
DIR='/proc/asound/card0/pcm0p/sub0/status'

#GPIO number
OUTPIO=27

#Here probably should be the check are this GPIO are not in use already
#but as we will use it as service started upon boot and not planning to use other scripts
#than it can be left out
echo $OUTPIO > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio$OUTPIO/direction

# When script is stopped release GPIO 
function cleanup()
{
    echo $OUTPIO > /sys/class/gpio/unexport
    exit 0
}

trap cleanup SIGINT

status1='closed'
while true
do

    if grep -q 'state: RUNNING' $DIR ; then
	status2='open'
    elif grep -q 'closed' $DIR ; then
	status2='closed'
    fi

    if [[ $status1 != $status2 ]] ; then
	if grep -q 'state: RUNNING' $DIR ; then
		echo "1" > /sys/class/gpio/gpio$OUTPIO/value
        	echo "Sound Detected!"
        	status1='open'
    	elif grep -q 'closed' $DIR ; then
		echo "0" > /sys/class/gpio/gpio$OUTPIO/value
        	echo "Sound Stopped!"
        	status1='closed'
	fi
    fi
done

Make file executable:

sudo chmod +x /usr/local/bin/sound2gpio.sh

Now we can check how it works by running the script and playing some sound and using some multimeter to check does the voltage between GPIO 27 and Ground GPIO changes.

If it is going well and voltage changes accordingly when sound is played than we can go furtherand automate RasPi to run the sound catcher script on boot and in background as service.

To do so we have to create service for that:

sudo nano /etc/systemd/system/sound2gpio.service

Paste there service file content in nano editor and exit from nano text editor and save the file:

[Unit]
Description=Sets GPIO hight when sound is outputing on sound card
After=network.target

[Service]
Type=simple
Restart=on-failure
ExecStart=/usr/local/bin/sound2gpio.sh

[Install]
WantedBy=multi-user.target

Now run:

sudo systemctl daemon-reload
sudo systemctl start sound2gpio.service
# Check for errors
journalctl -xe
# Set the service to start at each boot
sudo systemctl enable sound2gpio.service

Then last check by rebooting your RasPi and testing voltage levels on GPIO 27 when sound is playing.

Now we can attach Easy Digi and start receive and send some transmissions. But before we will need last step - somehow to control volumes on sound input and output. While we can control radio sound volume it is sometimes worth to switch of mikrophone auto gain control or in some situations we can have some specific radio, that has no volume control or it is limited, like some old military radios. Also we have to tune sound output lever from RasPi USB soun card, because not all radios has feature to set it’s microphone gain.

To tune sound card we can use amixer Following command will output sound card parameters:

$ amixer --card 0 contents
numid=10,iface=CARD,name='Keep Interface'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=3,iface=MIXER,name='Mic Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=4,iface=MIXER,name='Mic Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=31,step=0
  : values=16
  | dBminmaxmute-min=-23.00dB,max=8.00dB
numid=7,iface=MIXER,name='Mic Capture Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=8,iface=MIXER,name='Mic Capture Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=35,step=0
  : values=16
  | dBminmax-min=-12.00dB,max=23.00dB
numid=9,iface=MIXER,name='Auto Gain Control'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=5,iface=MIXER,name='Speaker Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=6,iface=MIXER,name='Speaker Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=37,step=0
  : values=4,4
  | dBminmaxmute-min=-37.00dB,max=0.00dB
numid=2,iface=PCM,name='Capture Channel Map'
  ; type=INTEGER,access=r----R--,values=1,min=0,max=36,step=0
  : values=0
  | container
    | chmap-fixed=MONO

numid=1,iface=PCM,name='Playback Channel Map'
  ; type=INTEGER,access=r----R--,values=2,min=0,max=36,step=0
  : values=0,0
  | container
    | chmap-fixed=FL,FR

To set the Auto Gain Control off:

$ amixer -c 0 cset numid=9,iface=MIXER,name='Auto Gain Control' 0
numid=9,iface=MIXER,name='Auto Gain Control'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off

To set the recording volume to 25:

$ amixer -c 0 cset numid=8,iface=MIXER,name='Mic Capture Volume' 25
numid=8,iface=MIXER,name='Mic Capture Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=35,step=0
  : values=25
  | dBminmax-min=-12.00dB,max=23.00dB

When we are tuned our sound card acordingly to our transceiver we can start to make some automation regarding receiving and sending, add some voice recognition or AI, or just simple parrot repeater. It just depends on our imagination and knowledge. But let it be another blog record… ;-)

VirtualBox and USB to Serial on Linux Ubuntu 18.04

Sometimes we need to get to use some old rig and for that we need quite old software. Somotimes also recent chine radio config software is quite exotic and better runs on older windoze, like WinXP.

It seems for me useles to keep dedicated PC for that - it takes some place and care. It could be solved with dual boot approach to keep them on the same Linux Ubuntu hardware, but then it is not possible to work at the same time in both systems. Then there is Wine (windowz environment emulator) - that works but there is enough cases when not. And I have failed yet to pair Wine with USB to serial converter.

So the virtual machine seems for me the best solution and that also works with USB to Serial converters.

In my case I am using Linux Ubuntu 18.04 with VirtualBox virtual machine.

But there is some tips & tricks to get it work:

Continue reading