React-Native application – Raspberry Pi Radio

Recently I have got my Raspberry Pi Radio up and running again. In the past I created simple internet radio player by installing Music Player Daemon on my Raspberry Pi device. The radio looks like this:
IMG_20200324_172631
In order to play/stop playing the hardcoded radio stream on need to press the yellow button on the top of the cover. This solution has a serious drawback: to change the radio one need to connect by ssh to the device and modify by hand the perl script which controls the button. This solution is far from being handy.
So I have decided to play around with Android application and I have created the mobile application – the remote controller. The prototype was created in pure Kotlin however I have decided to build the final version in React-Native. The application has the following screens:
radio-pi
It allows to play different streams which the user can add and remove. The application lets user to control the volume of the sound and restart or even shutdown the device as well.
The communication between the Music Player Daemon and mobile application is handled by the REST service I have created on Raspberry Pi with Express web application framework and mpc-js client library.
The entire code can be found on this repo.

Raspberry Pi: radio with play/stop button

I have decided to extend my pi radio and create a prototype of a button with which I could play defined url and stop it as well. I reused my code of mpd client and my button’s experiment to create a handle of single button. As long as the button is pressed the LED diode is on. When the button press is short (i.e. less than 1s) then radio starts playing hardcoded url. When the button press is longer than 1s then radio stops:

#!/usr/bin/env python

import mpd_client
import RPi.GPIO as gpio
import time
import commands

def main_loop():
  gpio.setmode(gpio.BCM)
  gpio.setup(14, gpio.IN)
  gpio.setup(15, gpio.OUT)
  
  try:
    button_down = 0  
    while True:
      button = gpio.input(14)
      if not button:
        gpio.output(15, gpio.HIGH)
        if not button_down:
          button_down = time.time()
      else:
        gpio.output(15, gpio.LOW)
        now = time.time()
        if button_down:
          diff = now - button_down
          if diff  1.0 and diff  3.0 and diff  5.0:
            restart()
        button_down = 0
      time.sleep(100.0/1000.0) 

  except KeyboardInterrupt, e:
    gpio.cleanup()

def play():
  url = 'http://stream4.nadaje.com:8002/muzo'
  ip = '127.0.0.1'
  port = 6600
  print 'Connecting to mpd server:',ip,':',port
  print 'Playing: ', url
  mpd_client.play(ip, port, url)

def stop():
  ip = '127.0.0.1'
  port = 6600
  print 'Connecting to mpd server:',ip,':',port
  print 'Stoping: '
  mpd_client.stop(ip, port)
    
def network_restart():
  cmd = 'service networking restart'
  print 'network restart', cmd
  (status, output) = commands.getstatusoutput(cmd)
  if status:
    sys.stderr.write(output)
    sys.exit(status)
  print output

def restart():
  cmd = 'shutdown -r 0'
  print 'restart', cmd
  (status, output) = commands.getstatusoutput(cmd)
  if status:
    sys.stderr.write(output)
    sys.exit(status)
  print output

main_loop()

The code above contains also some “service” features. When the button will be pressed longer than 3s the network will be restarted, and when it will be pressed longer than 5s the full device will restart.

Moreover with a help of this great tutorial I installed my script as a systemd service which starts automatically with Raspberry pi.

The prototype looks like this:
20180208_151834

For the real implementation I decided to modify a circuit. I removed all the elements and stay only with tact switch. I connected directly first pin of the button to the gpio pin 21 and second one to the gpio ground. There was also a need to modify slightly a setup code:

gpio.setup(21, gpio.IN, pull_up_down=gpio.PUD_UP)

the rest was not changed. With this line I turn on the raspberry’s pull up resistor so it can be safely eliminated from the circuit.

The script can be found on github.

The version with the single button which I placed on the top of the cover20180209_120141:

Raspberry pi GPIO: first steps – testing input

I extended the circuit I made with LED and this time I added the tact switch. The LED is connected through 470Ohm resistor to pin 15. The button’s first pin is connected to the GND and second one to the pin 14 and through 10kOhm resistor to 3.3V output. When the button is pressed it closes the circuit so the current flows from 3.3V through the resistor to the ground and this is why the pin 14 returns false in input.
In my example when the button is pressed it turns on the LED for 1 second:

#!/usr/bin/env python
import RPi.GPIO as gpio
import time
gpio.setmode(gpio.BCM)
gpio.setup(14, gpio.IN)
gpio.setup(15, gpio.OUT)
while True:
  button = gpio.input(14)
  if not button:
    gpio.output(15, gpio.HIGH)
    time.sleep(1)
    gpio.output(15, gpio.LOW)
    while not button:
      button = gpio.input(14)

The tact switch:
20180206_204205

Raspberry pi GPIO: first steps – testing output

Recently I have decided to play around with GPIO of my Raspberry Pi. My goal is to find some useful application of LED diodes and tact switches and probably I will implement some additional features to pi radio.
But initially I just want to only turn on the LED diode to understand how it really works. So I created simple circuit with LED and resistor to protect this diode. The output pin gives me 3.3V and my diode allows only 2.2V and 20mA. So the resistor should have 55Ohms, however I used a bit greater resistance 470Ohm (it was the lowest I could find).

Here is the numbering of GPIO pins: GPIO

I wrote the python script which uses pin 14 and 15 to turn on alternately
the diodes green and red every 1 second:

#!/usr/bin/env python

import RPi.GPIO as gpio
import time

gpio.setmode(gpio.BCM)
gpio.setup(14, gpio.OUT)
gpio.setup(15, gpio.OUT)

while True: 
  gpio.output(14, gpio.HIGH) 
  gpio.output(15, gpio.LOW) 
  time.sleep(1) 
  gpio.output(14, gpio.LOW) 
  gpio.output(15, gpio.HIGH) 
  time.sleep(1)

And here is the presentation:
test.gif