Highlights:
- Pi 3 A+
- Temperature-controlled rear fan
- LED backlit buttons, with H/W switch
- Dual analog controllers
- "Wide Angle" SPI Screen (Looks amazing!
)
- Digital Volume and Hotkey
- HDMI Connectivity
So, next I reworked a 3d model and made use of four tactile buttons on the sides in the rear, since the pi and the BW Screen variant I had in there took up most of the main area... but I wasn't very happy with the buttons, and that screen seemed to be a huge power drain for whatever reason, so I pulled that out and put a Gearbest in, and that was.. ok... a little better life, but it would get really hot, and I couldn't fit a fan in there with the control board for the screen and all.
And so, I thought an SPI screen would be ideal. Low power, (almost) no control board, good picture quality, and pretty cheap... but since I had no experience with doing SPI, I first opted to build some GBZs to get my feet wet. That went well, so I was able to come back to this one, pull out the GB screen, and start figuring out how to get the fan back in there.
I designed a holder that could fit in the rear, if you cut out the two spots where stickers normally went.. the models are here which fit really well above a Pocket Adventures rear bracket prototype that I had (I designed some buttons and wells for a four button layout). That worked ok but the buttons are pretty close together and not the most comfortable to use.
Using this guide as a starting point, and ab NPN transistor, I was able to control the fan turning on and off with software, based on the CPU temp.
Code: Select all
sudo nano fan.py
Code: Select all
from os import popen
from time import sleep
import RPi.GPIO as GPIO
debug = False
GPIO_pin = 4
trigger_temp = 42
def setupGPIO():
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_pin, GPIO.OUT)
GPIO.setwarnings(False)
return()
def getCPUTemp():
cmd = popen('vcgencmd measure_temp').readline()
temp = (cmd.replace("temp=","").replace("'C\n",""))
if debug:
print("CPU temp: {0}".format(temp))
return temp
def checkTemp():
CPU_temp = float(getCPUTemp())
if CPU_temp>trigger_temp:
enableFan(True)
if debug:
print("Fan is enabled")
else:
enableFan(False)
if debug:
print("Fan is disabled")
return()
def enableFan(isActive):
GPIO.output(GPIO_pin, isActive)
return()
# do it
setupGPIO()
while True:
checkTemp()
sleep(5)
Code: Select all
sudo nano /etc/rc.local
Code: Select all
sudo python /home/pi/fan.py &
Code: Select all
sudo nano volume.py
Code: Select all
from os import system
from gpiozero import Button
from signal import pause
from time import sleep
# Location of perisitant state file
statePath = "/home/pi/volume.txt"
# Initial volume setting
vState = 80
# Minimum/maximum volume and how much each press adjusts
sType = "Speaker" # PCM or Speaker (USB audio)
vStep = 10
vMin = 0
vMax = 100
vSpeed = 0.5
# GPIO pin configuration
volumeUpBtn = Button(23)
volumeDownBtn = Button(22)
# Functions
def volumeDown():
global vState
vState = max(vMin, vState - vStep)
system("amixer sset -q '" + sType + "' " + str(vState) + "%")
def volumeUp():
global vState
vState = min(vMax, vState + vStep)
system("amixer sset -q '" + sType + "' " + str(vState) + "%")
def readData(filepath):
with open(filepath, 'rb') as file:
return file.read()
def writeData(filepath):
with open(filepath, 'wb') as file:
file.write(str(vState))
def doVolume():
while True:
if volumeUpBtn.is_pressed:
volumeUp()
writeData(statePath)
sleep(vSpeed)
elif volumeDownBtn.is_pressed:
volumeDown()
writeData(statePath)
sleep(vSpeed)
# Initial File Setup
try:
vState = int(readData(statePath))
system("amixer sset -q '" + sType + "' " + str(vState) + "%")
except:
writeData(statePath)
system("amixer sset -q '" + sType + "' " + str(vState) + "%")
# Doin its thing
volumeUpBtn.when_pressed = doVolume
volumeDownBtn.when_pressed = doVolume
pause()
finally, you need to set it up to run the script at boot time:
Code: Select all
sudo nano /etc/rc.local
Code: Select all
sudo python /home/pi/volume.py &
For the screen, I am using the JUJ ILI9341 Driver and I am also using Sixteenbit's fork of HoolyHoo's MintyBatteryMonitor but it took a little tweaking to get those two things to work together. Essentially, in MintyBatteryMonitor.py, "changeicon" method, I had to change the X/Y coordinates in the PngView call to be x=570, y=10.
Code: Select all
framebuffer_width=320
framebuffer_height=240
## No Overscan needed
disable_overscan=1
overscan_scale=1
overscan_left=0
overscan_right=0
overscan_top=0
overscan_bottom=0
### Set custom view mode
## 320x240 60hz 4:3, no margins, progressive
hdmi_cvt=320 240 60 1
hdmi_mode=1
hdmi_group=1
### Just assume hdmi is on (for spi display)
hdmi_force_hotplug=1
### disable edid check
hdmi_ignore_edid=0xa5000080