Please select To the mobile version | Continue to access the desktop computer version

OrangePi

 Login            
 Register            
Search
Hot search: orangepi
1234Next
Return to list New
View: 25952|Reply: 31

[Guide] Internet radio + LCD 2x16 + TactSwitch (Ready to use)

[Copy link]

3

Threads

46

Posts

679

Credits

Senior member

Rank: 4

Credits
679
Post time 2016-4-9 16:14:48 | Show all posts |Read mode
Edited by mswiniuch at 2016-4-16 14:51

Hello
In the begining sorry for my english... ;)
I'd like to show you my project - Internet radio on OPI PC controled by three buttons or remote control or Android phone.
It is many simillar projects for Raspberry Pi but no for Orange Pi so I decided to make first (I think).
Finally you don't have to connect any monitor to play internet radio - just power, speakers and ethernet (in this article wired ethernet but it is good idea to configure Wifi or mobile GSM)
Of course radio player will be usable without LCD but will be not so cool
This thread is for Python and Interfacing - so please don't ask how to configure lirc or wifi - for this are many others threads. In there rather write how to improve Python code or how to get beatifull case for hardware
Base system is Jacers Debian Jessie: http://www.orangepi.org/orangepi ... =867&extra=page%3D1
In my opinion the best system for our OPI.

1. Wiring
Wiring is easy. We need LCD 2x16 HD44780, three tact switch and two small potentiometers 10K.

Attached schematic-lcd-switch.jpg

2. Write image to SD card (Debian8_jacer_2.img) - first run

After first run login as root (password: orangepi). In this tread we will login always as root - to be easly do everythink - I know it is not well.
#fs_resize
# systemctl set-default multi-user.target (login to console - to open X - startx)
#passwd (if you want to change root password)
#reboot

3. Upgrade system
#apt-get update
#apt-get upgrade


4. Installing radio packages
#apt-get install mpd mpc ncmpc
Make radio playlist in PLS format (bellow is example file): /var/lib/music/radio.pls
  1. [playlist]
  2. Version=2
  3. numberofentries=5
  4. File1=http://95.141.24.22:80
  5. Title1=RauteMusic ChartHits
  6. File2=http://193.200.42.210:80
  7. Title2=HITPARTY.fm
  8. File3=http://95.141.24.40:80
  9. Title3=RauteMusic Main
  10. File4=http://193.34.51.92:80
  11. Title4=RauteMusic HOUSE(FUNKY)
  12. File5=http://205.164.36.5:80
  13. Title5=CHILLOUT LOUNGE RADIO (1.FM TM)
Copy the Code
If you want to activate analog audio by 3.5mm jack change "card 1" to "card 0" in two places in /etc/asound.conf
  1. pcm.!default {
  2.     type hw
  3.     card 0
  4.     device 0
  5.   }
  6.   ctl.!default {
  7.     type hw
  8.     card 0
  9.   }
Copy the Code
#reboot
After reboot we have to test radio:
#mpc load radio.pls
#mpc play
If you update playlist (radio.pls) do:
#mpc clear
#mpc load radio.pls
#mpc play
To adjust volume use:
#alsamixer
If you hear music it is great - you should - if not google ;)
From now radio is working. You can control it by command line (#mpc next, #mpc prev, etc.), by program #ncmpc, from Android phone (Mupeace, Droid MPD Client - search MPD in Google Play)

5. Remote control - Lirc
It is not required step.
Install lirc:
#apt-get install lirc
To configure lirc it is article on this forum.
Bellow my configuration files:
/etc/lirc/hardware.conf
  1. # /etc/lirc/hardware.conf
  2. LIRCD_ARGS=""
  3. #START_LIRCMD=false
  4. #START_IREXEC=false
  5. LOAD_MODULES=true
  6. MODULES="sunxi-ir-rx"
  7. DRIVER="devinput"
  8. DEVICE="/dev/input/event5"
  9. LIRCD_CONF=""
  10. LIRCMD_CONF=""
Copy the Code
Check wich input number is for you - look where is "sunxi-ir" - change DEVICE in hardware.conf
# cat /proc/bus/input/devices
My remote is small cheap remote from car mp3 player

Configuration for it:
/etc/lirc/lircd.conf
  1. begin remote

  2.   name  CAR_MP3
  3.   bits           56
  4.   flags SPACE_ENC|CONST_LENGTH
  5.   eps            30
  6.   aeps          100

  7.   header       9000  4500
  8.   one           563  1687
  9.   zero          563   562
  10.   ptrail        563
  11.   pre_data_bits   8
  12.   pre_data       0x0
  13.   gap          108000
  14.   toggle_bit_mask 0x0
  15.   frequency    38000
  16.   duty_cycle   33

  17.       begin codes
  18.           KEY_CHANNELDOWN          0x01004500000001
  19.           KEY_CHANNEL              0x01004600000001
  20.           KEY_CHANNELUP            0x01004700000001
  21.           KEY_PREVIOUS             0x01004400000001
  22.           KEY_FORWARD              0x01004000000001
  23.           KEY_PLAYPAUSE            0x01004300000001
  24.           KEY_VOLUMEDOWN           0x01000700000001
  25.           KEY_VOLUMEUP             0x01001500000001
  26.           KEY_HOME                 0x01000900000001
  27.           KEY_RECORD               0x01001600000001
  28.           KEY_BACK                 0x01000C00000001
  29.           KEY_UP                   0x01001800000001
  30.           KEY_INFO                 0x01005E00000001
  31.           KEY_LEFT                 0x01000800000001
  32.           KEY_OK                   0x01001C00000001
  33.           KEY_RIGHT                0x01005A00000001
  34.           KEY_MENU                 0x01004200000001
  35.           KEY_DOWN                 0x01005200000001
  36.           KEY_STOP                 0x01004A00000001
  37.       end codes

  38. end remote
Copy the Code
You can configure any remote by irrecord

To control radio necessery is file - bellow example:
/etc/lirc/lircrc
  1. begin
  2.   prog = irexec
  3.   button = KEY_CHANNELDOWN
  4.   config = mpc prev
  5. end

  6. begin
  7.   prog = irexec
  8.   button = KEY_CHANNELUP
  9.   config = mpc next
  10. end

  11. begin
  12.   prog = irexec
  13.   button = KEY_PLAYPAUSE
  14.   config = mpc toggle
  15. end
Copy the Code
#reboot

6. Installing python library for control GPIO
#apt-get install python-dev
#git clone https://github.com/duxingkei33/orangepi_PC_gpio_pyH3.git
#cd /root/orangepi_PC_gpio_pyH3
#python setup.py install


7. Last step - main code
Copy /root/radio.py from attachement to /root
(Code in next post)

Run this program
#python radio.py
You should see text on LCD - radio informations
Button 'Right" - next radio from playlist,
Button "Left" - previous radio from playlist
Button "Menu" - menu, if you don't touch any button for 4 seconds it return to display radio informations.
In menu click "Left" or "Right" to scroll options and "Menu" to run it.
Just test it

If it works you can run this program during boot:
add in /etc/rc.local  above "exit 0"
######################################
python /root/radio.py &
######################################

This is all
All necessery files are in attachement

PS.
I am nor programist or electronic. I did it for me and share it with you. I know the code is not well but I don't know how to improve it.
If is someone who can improve this code or whole project - please do it and share with us

GOOD LUCK!

This post contains more resources

You have to Login for download or view attachment(s). No Account? Register

x

3

Threads

46

Posts

679

Credits

Senior member

Rank: 4

Credits
679
 Author| Post time 2016-4-9 16:55:45 | Show all posts
Edited by mswiniuch at 2016-4-16 14:49

Main code:
/root/radio.py
  1. #!/usr/bin/env python

  2. import os
  3. import sys
  4. import subprocess
  5. import time
  6. import textwrap

  7. from time       import sleep, strftime
  8. from datetime   import datetime
  9. from subprocess import *
  10. from pyA20.gpio import gpio
  11. from pyA20.gpio import connector
  12. from pyA20.gpio import port

  13. if not os.getegid() == 0:
  14.   sys.exit('Script must be run as root')

  15. #Defina GPIO to buttons mapping
  16. button_menu = port.PA2  #PIN 22
  17. button_prev = port.PA13 #PIN 8
  18. button_next = port.PA14 #PIN 10

  19. # Define GPIO to LCD mapping
  20. LCD_RS = port.PA21 #PIN 26
  21. LCD_E  = port.PC3  #PIN 24
  22. LCD_D4 = port.PA0  #PIN 13
  23. LCD_D5 = port.PA3  #PIN 15
  24. LCD_D6 = port.PC4  #PIN 16
  25. LCD_D7 = port.PC7  #PIN 18

  26. # Define some device constants
  27. LCD_WIDTH = 16    # Maximum characters per line
  28. LCD_CHR = True
  29. LCD_CMD = False

  30. LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
  31. LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line

  32. # Timing constants
  33. E_PULSE = 0.0005
  34. E_DELAY = 0.0005

  35. #Init gpio module
  36. gpio.init()

  37. gpio.setcfg(LCD_E,  gpio.OUTPUT) # E
  38. gpio.setcfg(LCD_RS, gpio.OUTPUT) # RS
  39. gpio.setcfg(LCD_D4, gpio.OUTPUT) # DB4
  40. gpio.setcfg(LCD_D5, gpio.OUTPUT) # DB5
  41. gpio.setcfg(LCD_D6, gpio.OUTPUT) # DB6
  42. gpio.setcfg(LCD_D7, gpio.OUTPUT) # DB7

  43. #Set buttons
  44. gpio.setcfg(button_menu, gpio.INPUT)
  45. gpio.setcfg(button_prev, gpio.INPUT)
  46. gpio.setcfg(button_next, gpio.INPUT)

  47. #Enable pullup resistor
  48. gpio.pullup(button_menu, gpio.PULLUP)
  49. gpio.pullup(button_prev, gpio.PULLUP)
  50. gpio.pullup(button_next, gpio.PULLUP)


  51. def main():

  52.   # Initialise display
  53.   lcd_init()

  54.   counter = 0

  55.   while True:

  56.     # Get current status and playtime
  57.     process = subprocess.Popen('mpc', shell=True, stdout=subprocess.PIPE)
  58.     status = process.communicate()[0]
  59.     if status == "":
  60.       radioName = "    No radio    "
  61.       listN = " or no network  "
  62.       songName = " or no network  "
  63.       if counter == 10:
  64.         run_cmd("service mpd restart")
  65.     else:
  66.       statusLines = status.split('\n')
  67.       # Extract the songName (first line)
  68.       songN = statusLines[0]
  69.       listN = statusLines[1]
  70.       if ":" in songN:
  71.         radioName = statusLines[0].split(':',1)[0].strip()
  72.         songName = statusLines[0].split(':',1)[1].strip()
  73.       if ":" not in songN:
  74.         radioName = statusLines[0]
  75.         songName = "                "
  76.     if radioName == "volume":
  77.       if counter == 10:
  78.         run_cmd("mpc play")
  79.     lcd_string(radioName,LCD_LINE_1)
  80.     if counter < 10:
  81.       lcd_string(listN,LCD_LINE_2)
  82.     else:
  83.       lcd_string(songName,LCD_LINE_2)

  84.     press = read_switches()

  85.     if (press == 3):
  86.       menu()
  87.       counter = 0

  88.     if (press == 2):
  89.       run_cmd("mpc next")
  90.       counter = 0

  91.     if (press == 1):
  92.       run_cmd("mpc prev")
  93.       counter = 0

  94.     sleep(0.1)
  95.     counter = counter + 1
  96.     if counter == 20:
  97.       counter = 0

  98. def read_switches():

  99.   sw_prev = 1
  100.   sw_next = 1
  101.   sw_menu = 1

  102.   # Initialize
  103.   got_prev = False
  104.   got_next = False
  105.   got_menu = False

  106.   # Read switches
  107.   sw_prev = gpio.input(button_prev)
  108.   sw_next = gpio.input(button_next)
  109.   sw_menu = gpio.input(button_menu)

  110.   if sw_prev == 0:
  111.     got_prev = True
  112.   if sw_next == 0:
  113.     got_next = True
  114.   if sw_menu == 0:
  115.     got_menu = True

  116.   if(got_menu):
  117.     return 3
  118.   if(got_next):
  119.     return 2
  120.   if(got_prev):
  121.     return 1
  122.   return 0

  123.   sleep(0.01)


  124. MENU_LIST = [  
  125.   '0. Time & IP    ',
  126.   '1. Play / Pause ',
  127.   '2. Reload Radio ',
  128.   '3. Reboot System',
  129.   '4. Halt System  ',
  130.   '5. Connect 3G   ',
  131.   '6. Exit Menu    ']

  132. def menu ():

  133.   global MENU_LIST
  134.   item = 0
  135.   lcd_string("[  << MENU >>  ]",LCD_LINE_1)
  136.   lcd_string(MENU_LIST[item],LCD_LINE_2)
  137.   counter = 0
  138.   keep_looping = True

  139.   while (keep_looping):

  140.     # Wait for a key press
  141.     press = read_switches()

  142.     # PREV button
  143.     if(press == 1):
  144.       counter = 0
  145.       item -= 1
  146.       if(item < 0):
  147.         item = len(MENU_LIST) - 1
  148.       lcd_string("[  << MENU >>  ]",LCD_LINE_1)
  149.       lcd_string(MENU_LIST[item],LCD_LINE_2)

  150.     # NEXT button
  151.     if(press == 2):
  152.       counter = 0
  153.       item += 1
  154.       if(item >= len(MENU_LIST)):
  155.         item = 0
  156.       lcd_string("[  << MENU >>  ]",LCD_LINE_1)
  157.       lcd_string(MENU_LIST[item],LCD_LINE_2)

  158.     # MENU button
  159.     if(press == 3):

  160.       # Take action
  161.       if(item == 0):
  162.         # display time and IP address
  163.         display_ipaddr()
  164.       if(item == 1):
  165.         # Play/Pause
  166.         output = run_cmd("mpc toggle")
  167.       if(item == 2):
  168.         # reload radio
  169.         lcd_string("      WAIT      ",LCD_LINE_1)
  170.         lcd_string("Restarting radio",LCD_LINE_2)
  171.         output = run_cmd("service mpd restart")
  172.         output = run_cmd("mpc clear")
  173.         output = run_cmd("mpc load radio.pls")
  174.         output = run_cmd("mpc play")
  175.       if(item == 3):
  176.         # output reboot system
  177.         lcd_string("      WAIT      ",LCD_LINE_1)
  178.         lcd_string("Rebooting system",LCD_LINE_2)
  179.         output = run_cmd("sudo service mpd stop && sudo reboot")
  180.       if(item == 4):
  181.         #shutdown the system
  182.         lcd_string("    GOODBYE!    ",LCD_LINE_1)
  183.         lcd_string(" Halting system ",LCD_LINE_2)
  184.         output = run_cmd("sudo service mpd stop && sudo shutdown now -h")
  185.       if(item == 5):
  186.         #connect 3G mobile internet
  187.         lcd_string("      WAIT      ",LCD_LINE_1)
  188.         lcd_string("  connecting 3G ",LCD_LINE_2)
  189.         output = run_cmd("sudo /usr/bin/sakis3g connect --console")
  190.       if(item == 6):
  191.         #exit Menu - return to radio
  192.         keep_looping = False

  193.       keep_looping = False

  194.     counter = counter + 1
  195.     if counter == 40:
  196.       keep_looping = False
  197.     sleep(0.1)

  198. def display_ipaddr():
  199.   show_eth0  = "/sbin/ifconfig eth0|grep inet|head -1|sed 's/\:/ /'|awk '{print $3}'"
  200.   ipaddr = run_cmd(show_eth0)
  201.   lcd_string(ipaddr,LCD_LINE_2)

  202.   i = 0
  203.   keep_looping_1 = True

  204.   while (keep_looping_1):

  205.     # Every second, update the time display
  206.     i = i + 1
  207.     if(i % 10 == 0):
  208.       show_time = datetime.now().strftime('%b %d  %H:%M:%S\n')
  209.       lcd_string(show_time,LCD_LINE_1)
  210.       lcd_string(ipaddr,LCD_LINE_2)

  211.     # Every 100 milliseconds, read the switches
  212.     press = read_switches()
  213.     if(press == 3):
  214.       keep_looping_1 = False
  215.     sleep(0.1)


  216. def run_cmd(cmd):
  217.   p = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
  218.   output = p.communicate()[0]
  219.   return output

  220. def lcd_init():
  221.   # Initialise display
  222.   lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  223.   lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  224.   lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  225.   lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
  226.   lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  227.   lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  228.   time.sleep(E_DELAY)

  229. def lcd_byte(bits, mode):
  230.   # Send byte to data pins
  231.   # bits = data
  232.   # mode = True  for character
  233.   #        False for command

  234.   gpio.output(LCD_RS, mode)

  235.   # High bits
  236.   gpio.output(LCD_D4, False)
  237.   gpio.output(LCD_D5, False)
  238.   gpio.output(LCD_D6, False)
  239.   gpio.output(LCD_D7, False)
  240.   if bits&0x10==0x10:
  241.     gpio.output(LCD_D4, True)
  242.   if bits&0x20==0x20:
  243.     gpio.output(LCD_D5, True)
  244.   if bits&0x40==0x40:
  245.     gpio.output(LCD_D6, True)
  246.   if bits&0x80==0x80:
  247.     gpio.output(LCD_D7, True)

  248.   # Toggle 'Enable' pin
  249.   lcd_toggle_enable()

  250.   # Low bits
  251.   gpio.output(LCD_D4, False)
  252.   gpio.output(LCD_D5, False)
  253.   gpio.output(LCD_D6, False)
  254.   gpio.output(LCD_D7, False)
  255.   if bits&0x01==0x01:
  256.     gpio.output(LCD_D4, True)
  257.   if bits&0x02==0x02:
  258.     gpio.output(LCD_D5, True)
  259.   if bits&0x04==0x04:
  260.     gpio.output(LCD_D6, True)
  261.   if bits&0x08==0x08:
  262.     gpio.output(LCD_D7, True)

  263.   # Toggle 'Enable' pin
  264.   lcd_toggle_enable()

  265. def lcd_toggle_enable():
  266.   # Toggle enable
  267.   time.sleep(E_DELAY)
  268.   gpio.output(LCD_E, True)
  269.   time.sleep(E_PULSE)
  270.   gpio.output(LCD_E, False)
  271.   time.sleep(E_DELAY)

  272. def lcd_string(message,line):
  273.   # Send string to display
  274.   message = message.ljust(LCD_WIDTH," ")
  275.   lcd_byte(line, LCD_CMD)
  276.   for i in range(LCD_WIDTH):
  277.     lcd_byte(ord(message[i]),LCD_CHR)


  278. if __name__ == '__main__':

  279.   try:
  280.     main()
  281.   except KeyboardInterrupt:
  282.     pass
  283.   finally:
  284.     lcd_byte(0x01, LCD_CMD)
  285.     lcd_string("    Goodbye!    ",LCD_LINE_1)
  286.     lcd_string("                ",LCD_LINE_2)
Copy the Code

If you want to have access to playlist and main code by Samba, add this to the end of samba config fie /etc/samba/smb.conf
  1. [MPD-Music]
  2.     guest account = root
  3.     writeable = yes
  4.     delete readonly = yes
  5.     path = /var/lib/mpd/music
  6.     force group = root
  7.     force user = root
  8.     create mode = 777
  9.     public = yes
  10.     directory mode = 777

  11. [root]
  12.     guest account = root
  13.     writeable = yes
  14.     delete readonly = yes
  15.     path = /root
  16.     force group = root
  17.     force user = root
  18.     create mode = 777
  19.     public = yes
  20.     directory mode = 777
Copy the Code

11

Threads

286

Posts

1864

Credits

Moderator

Rank: 7Rank: 7Rank: 7

Credits
1864
Post time 2016-4-20 18:09:47 | Show all posts
very cool,thanks

0

Threads

54

Posts

299

Credits

Intermediate member

Rank: 3Rank: 3

Credits
299
Post time 2016-4-20 19:10:10 | Show all posts
Well done and nice job

2

Threads

45

Posts

789

Credits

Senior member

Rank: 4

Credits
789
Post time 2016-4-30 03:19:07 | Show all posts
NICE, THANKS!!!!

0

Threads

2

Posts

36

Credits

Novice

Rank: 1

Credits
36
Post time 2016-11-20 16:28:29 | Show all posts

Thanks for detailed guide.
Running on Armbian OPi PC plus with small modifications. Case is made of 3mm plywood. 2x40 character LCD added to see full song names.
Great gadged in my workshop.


This post contains more resources

You have to Login for download or view attachment(s). No Account? Register

x

4

Threads

53

Posts

2306

Credits

Gold member

Rank: 6Rank: 6

Credits
2306
Post time 2017-1-3 02:54:46 | Show all posts
Laco replied at 2016-11-20 16:28
Thanks for detailed guide.
Running on Armbian OPi PC plus with small modifications. Case is made of ...

Nice job your too Iaco!Are you using the internal audio card?
what is the boot time of your OS?
Are you using Armian Server?

0

Threads

2

Posts

16

Credits

Novice

Rank: 1

Credits
16
Post time 2017-1-14 10:12:58 | Show all posts
Laco replied at 2016-11-20 16:28
Thanks for detailed guide.
Running on Armbian OPi PC plus with small modifications. Case is made of ...

What is the boot time of your Armbian OS with internet radio?

0

Threads

2

Posts

16

Credits

Novice

Rank: 1

Credits
16
Post time 2017-1-14 10:16:18 | Show all posts
Edited by lino at 2017-1-14 10:18

Dear mswiniuch

What is the boot time of your Debian Jessie OS with internet radio?


3

Threads

46

Posts

679

Credits

Senior member

Rank: 4

Credits
679
 Author| Post time 2017-1-17 01:10:12 | Show all posts
It was fiew mounths ago. Now I use latest Armbian - instalation is simillar. Boot time is maybe 20 seconds. Now I have full system with GUI so I can't measure time for using OPI only for radio.
You have to log in before you can reply Login | Register

Points Rules

Archiver|Mobile edition|Darkroom|OrangePi En ( 粤ICP备14086627号-2

2019-11-22 10:18 GMT+8 , Processed in 0.042052 second(s), 23 queries .

Powered by Discuz! X3.2

© 2014-2015 orangepibbs en.

Quick Reply To Top Return to the list