Posts tonen met het label scripts. Alle posts tonen
Posts tonen met het label scripts. Alle posts tonen

zaterdag 16 januari 2016

Raspberry PI(2) MP3 player based on mpdclient, controlled with analog joystick and PCF8544 and a Nokia LCD display the PCD8544

I'm fiddling with electronics for many years, besides that I'm very new in at the Raspberry PI thing, I love it. I'm publishing this because many posts in forums and on blogs didn't gave what I needed.

What I made
A really simple MP3 player on a Raspberry PI that displays the song and artists and also displays play/pause/next/previous. It is all controlled with an analog joystick.

You can see how it works: https://youtu.be/rmaHO2rLwvg

Why?
Why I used these components? It is what I had without going to the store. This display was included in a kit. The analog joystick was because I didn't have enough buttons. I know the Rapsberry PI is totally useless for audio playback.

What is used? 
The Raspberry PI(2)

PCD8544:
This was included in a kit, with the connector can it be placed directly on the RPi but in a project it doesn't really make sense.










Analog joystick:
Mine was with a red PCB.











The AD converter PCF8591
Be sure you remove the jumpers.











The hook it up
Connect the PCF8591 board with the VCC to the 3.3V from the RPi. GND to the GND of the RPi.
Connect the PCF8591 board with SCL to the SCL from the RPi
Connect the PCF8591 board with SDA to the SDA from the RPi
Connect the PCF8591 board AIN2 and AIN3 to GND

Connect the joystick board with the + to the 3.3V from the RPi. GND to the GND of the RPi.
Connect the joystick board B (button) to pin 25 on the RPi
Connect the joystick board X to the AIN0 on the PCF8591 board
Connect the joystick board Y to the AIN1 on the PCF8591 board

Now comes the hard part, connecting the PCD to the Rapsberry.  This picture was very helpful.

The first column is counted from the top left as seen on the picture so:
1-2
3-4
5-6
ans so on.

Pin 1 is 3.3V
Pin 25 is GND

The code:
 #!/usr/bin/env python  
   
   
 #basic needs  
 from smbus import SMBus  
 from time import sleep  
 from socket import error as SocketError  
   
 #Needed for the PMD8544/NokiaLCD   
 import Adafruit_Nokia_LCD as LCD  
 from PIL import Image  
 from PIL import ImageFont  
 from PIL import ImageDraw  
   
 #This is needed for the PCF85  
 from smbus import SMBus  
   
 #Needed for reading the button  
 import RPi.GPIO as GPIO  
   
 #Needed for the MPDClient  
 from mpd import (MPDClient, CommandError)  
   
 ## SETTINGS  
 ##  
 HOST = 'localhost'  
 PORT = '6600'  
 PASSWORD = False  
 ###  
   
   
 #Set some basic values  
 bus = SMBus(1) #This is for the PCF8591   
 last_reading_1 = -1  
 last_reading_2 = -1  
 volume = 70   
 status = "stop"  
   
 # This is for the button of the analog joystick.  
 GPIO.setmode(GPIO.BCM)  
 GPIO.setup(25, GPIO.IN)  
   
 # Raspberry Pi software SPI config:  
 SCLK = 17  
 DIN = 18  
 DC = 27  
 RST = 23  
 CS = 22  
 client = MPDClient()  
   
   
 #This function displays the icons  
 def display(action):  
     #clean display first  
      draw.rectangle((0,0,LCD.LCDWIDTH,LCD.LCDHEIGHT), outline=255, fill=255)  
     disp.image(image)  
     disp.display()  
      #Set the right icon to show:   
      if (action == "volumeplus"):   
          draw.rectangle((25,24,61,28), outline=0, fill=0)  
         draw.rectangle((40,12,46,40), outline=0, fill=0)  
     elif (action == "volumeminus"):  
           draw.rectangle((25,24,61,28), outline=0, fill=0)  
      elif (action == "play_pause"):  
           if (status == "play"):  
             draw.rectangle((33,12,40,34), outline=0, fill=0)  
             draw.rectangle((43,12,50,34), outline=0, fill=0)  
         else:  
             draw.polygon([(31,10), (51,22), (31,34)], outline=0, fill=0)  
      elif (action == "next"):   
           draw.polygon([(21,10), (41,22), (21,34)], outline=0, fill=0)  
         draw.polygon([(41,10), (61,22), (41,34)], outline=0, fill=0)  
      elif (action == "previous"):   
           draw.polygon([(21,22), (41,10), (41,34)], outline=0, fill=0)  
         draw.polygon([(41,22), (61,10), (61,34)], outline=0, fill=0)            
      disp.image(image)  
     disp.display()  
      sleep(0.5) # the time the icon is showed   
      #below the icon is cleared from the screen again.  
      draw.rectangle((0,0,LCD.LCDWIDTH,LCD.LCDHEIGHT), outline=255, fill=255)  
      disp.image(image)  
     disp.display()  
   
   
 #This function is to compensate for the non-linear volume controll of the   
 #Raspberry PI   
 def logvolume(action, volume):  
      if (volume <=50):  
           if (action == "volumeplus"):  
                volume = volume + 20  
           else:   
                volume = volume - 20  
      elif (volume >= 50 and volume <= 70):  
           if (action == "volumeplus"):  
             volume = volume + 10  
         else:   
             volume = volume - 10   
      elif (volume >=70 and volume <= 79):  
           if (action == "volumeplus"):  
             volume = volume + 5  
         else:   
             volume = volume - 5   
     elif (volume >=80 and volume <= 89):  
         if (action == "volumeplus"):  
             volume = volume + 2  
         else:  
             volume = volume - 2  
      elif (volume >=90):   
           if (action == "volumeplus"):  
             volume = volume + 1  
         else:   
             volume = volume - 1  
      elif (volume == 100):   
           volume = 100  
      return(volume)  
   
   
   
   
 #In this function the core functionality is called.   
 #     - It calls the logaritmic volume controll   
 #      - It calls the screen action   
   
 def action(action, volume):   
      if (action == "volumeplus"):  
           volume = logvolume(action, volume)   
           client.setvol(volume)  
      if (action == "volumeminus"):  
           volume = logvolume(action, volume)  
         client.setvol(volume)  
      if (action == "play_pause"):  
           if (status == "play"):  
             client.pause()  
         else:  
             client.play()  
      if (action == "next"):   
         client.next()  
      if (action == "previous"):   
         client.previous()  
      display(action)   
      return(volume)  
   
   
 #This connects the MCP client to the deamon  
 try:  
     client.connect(host=HOST, port=PORT)  
     print "connect"  
 except SocketError:  
     print "socketerror"  
     exit(1)  
   
   
   
 # Software SPI usage (defaults to bit-bang SPI interface):  
 disp = LCD.PCD8544(DC, RST, SCLK, DIN, CS)  
   
 # Initialize library.  
 disp.begin(contrast=60)  
   
 # Clear display.  
 disp.clear()  
 disp.display()  
   
 # Create image buffer.  
 # Make sure to create image with mode '1' for 1-bit color.  
 image = Image.new('1', (LCD.LCDWIDTH, LCD.LCDHEIGHT))  
   
 # Get drawing object to draw on image.  
 draw = ImageDraw.Draw(image)  
   
 # Draw a white filled box to clear the image.  
 draw.rectangle((0,0,LCD.LCDWIDTH,LCD.LCDHEIGHT), outline=255, fill=255)  
   
 # Load default font.  
 #font = ImageFont.load_default()  
   
 # Alternatively load a TTF font.  
 # Some nice fonts to try: http://www.dafont.com/bitmap.php  
 font = ImageFont.truetype('visitor1.ttf', 9)  
 font1 = ImageFont.truetype('visitor1.ttf', 12)  
   
 #Set basic volume to 60%  
 client.setvol(volume)  
   
 while True:  
      bus.write_byte(0x48, 0x40) #This writes to the channel that needs to be read      
      reading = bus.read_byte(0x48) #This reads the value from the channel   
      #Make sure that it is only read if it is different than before   
     if(abs(last_reading_1 - reading) > 2):   
           if (reading >= 230):          #This about 90% of the joystick change of value        
                #Calls the action function and returns the volume   
             volume = action("volumeminus", volume)   
           elif (reading <= 30): #This is also 80% the other way around   
                volume = action("volumeplus", volume)  
           last_reading_1 = reading  
     #Now the other axis needs to be read so it writes to the other channel   
     bus.write_byte(0x48, 0x41)   
     reading = bus.read_byte(0x48)  
     if(abs(last_reading_2 - reading) > 2):  
         if (reading >= 230):                
                action("next", volume)  
         elif (reading <= 30):  
                action("previous", volume)   
         last_reading_2 = reading  
      if (GPIO.input(25)== True):  
           action("play_pause", volume)   
      sleep(0.3)  
      running  = client.status() #Checks the state of the player   
     status = running['state'] #Puts the running state in status   
        
      #This shows the current song on the display   
      if (status == "play"):  
         curSongInfo = client.currentsong()  
         draw.text((1,1), curSongInfo['albumartist'], font=font)  
         draw.text((1,8), curSongInfo['title'], font=font)  
      disp.image(image)  
     disp.display()  
   
 client.disconnect()  

You might bump into some issues so need to do some stuff:
sudo pip install smbus
sudo apt-get install alsa-utils mpd python-mpd python-imaging

alter the music directory in /etc/mpd.conf
And restart it: sudo service mpd restart

install the adafruit GPIO library: https://github.com/adafruit/Adafruit_Python_GPIO

Enable the audio jack output on the RPi:
amixer cset numid=3 1

Load the drivers for the I2C bus:
modprobe i2c_bcm2708
modprobe i2c_dev
And maybe add them to load them at boot: /etc/modules




maandag 16 februari 2015

Use the build in TFTP server in OSX

Use the build in TFTP server in OSX

To start the TFTP server: 
sudo launchctl load -F /System/Library/LaunchDaemons/tftp.plist

To stop the TFTP Server: 
sudo launchctl unload -F /System/Library/LaunchDaemons/tftp.plist

You can put your files in the folder: 
/private/tftpboot

You can change this folder in: 
/System/Library/LaunchDaemons/tftp.plist

To test the TFTP setup

Create a file named test.txt in:
/private/tftpboot

Change into your home folder: 
cd ~

Enter the following command: 
tftp 127.0.0.1 

You will get a prompt: 
tftp>

To get the test file: 
get test.txt 

You will get a response like: 
Received 8 bytes in 0.0 seconds

zondag 5 januari 2014

Organize or clean your downloads folder

My downloads folder is always a mess and I got fed up with it, I have wrote in a script that will clean up my downloads folder.

First I created a few folders in the downloads folder:

  • DL-Compressed 
  • DL-Firmware 
  • DL-Programs 
  • DL-Android
  • DL-Documents
  • DL-media
After this I created a bash script:


# Move Wetransfer files to tje picure folder 
mv ~/Downloads/wetransfer*  ~/Pictures/Wetransfer

# Move all Airdroid Files to the DL-Airdroid folder
mv ~/Downloads/Files_downloaded_by_AirDroid*  ~/Downloads/DL-Airdroid/

# Move all porn to DL-Media
mv ~/Downloads/*.jpg ~/Downloads/DL-media/
mv ~/Downloads/*.JPG ~/Downloads/DL-media/
mv ~/Downloads/*.png ~/Downloads/DL-media/
mv ~/Downloads/*.PNG ~/Downloads/DL-media/
mv ~/Downloads/*.mov ~/Downloads/DL-media/    
mv ~/Downloads/*.MOV ~/Downloads/DL-media/
mv ~/Downloads/*.bmp ~/Downloads/DL-media/
mv ~/Downloads/*.BMP ~/Downloads/DL-media/
mv ~/Downloads/*.jpeg ~/Downloads/DL-media/
mv ~/Downloads/*.JPEG ~/Downloads/DL-media/
mv ~/Downloads/*.gif ~/Downloads/DL-media/
mv ~/Downloads/*.GIF ~/Downloads/DL-media/
mv ~/Downloads/*.tif ~/Downloads/DL-media/
mv ~/Downloads/*.TIF ~/Downloads/DL-media/

# move al compressed files to DL-Compressed folder
mv ~/Downloads/*.zip ~/Downloads/DL-Compressed/
mv ~/Downloads/*.ZIP ~/Downloads/DL-Compressed/
mv ~/Downloads/*.rar ~/Downloads/DL-Compressed/
mv ~/Downloads/*.RAR ~/Downloads/DL-Compressed/
mv ~/Downloads/*.jar ~/Downloads/DL-Compressed/
mv ~/Downloads/*.JAR ~/Downloads/DL-Compressed/
mv ~/Downloads/*.7z ~/Downloads/DL-Compressed/
mv ~/Downloads/*.7Z ~/Downloads/DL-Compressed/
mv ~/Downloads/*.tgz ~/Downloads/DL-Compressed/
mv ~/Downloads/*.TGZ ~/Downloads/DL-Compressed/

# Move all installers to DL-Programs 
mv ~/Downloads/*.dmg ~/Downloads/DL-Programs/
mv ~/Downloads/*.DMG ~/Downloads/DL-Programs/
mv ~/Downloads/*.pkg ~/Downloads/DL-Programs/
mv ~/Downloads/*.pkg ~/Downloads/DL-Programs/
mv ~/Downloads/*.prefPane ~/Downloads/DL-Programs/

# Split up all the documents
mv ~/Downloads/*.pdf  ~/Downloads/DL-Documenten/DL-PDF/
mv ~/Downloads/*.PDF  ~/Downloads/DL-Documenten/DL-PDF/
mv ~/Downloads/*.txt  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.TXT  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.csv  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.CSV  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.htm  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.html  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.HTM  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.HTML  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.cfg  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.CFG  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.tpl  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.TPL  ~/Downloads/DL-Documenten/DL-TXT/
mv ~/Downloads/*.doc  ~/Downloads/DL-Documenten/DL-Docs/
mv ~/Downloads/*.docx  ~/Downloads/DL-Documenten/DL-Docs/
mv ~/Downloads/*.DOC  ~/Downloads/DL-Documenten/DL-Docs/
mv ~/Downloads/*.DOCX  ~/Downloads/DL-Documenten/Docs/

# Remove windows stuff
rm ~/Downloads/*.exe 
rm ~/Downloads/*.EXE

# Verwijderen van overbodige folders (alle niet DL- folders) 
find ~/Downloads/. -type d -not -name 'DL-*' -print0 | xargs -0  rm -R

# Remove files from Compressed after 30 days. 
find ~/Downloads/DL-Compressed/* -mtime +30 -exec rm {} \;

Now i added the file to the crontab
Create a file called crontab.txt 
fill it up with: 
15  * * * * ~/scripts/download.sh  &> /dev/null

Now put it in the crontab:
crontab crontab.txt 

Check your crontabs with:
crontab -l 

Clear your crontabs with:
crontab -r