My "Ultimate" 3A+ Build - With Temp-Controlled Fan
Posted: Wed Jul 03, 2019 1:59 pm
This one was in the works for a long time, but I think I'm finally "done" (or as done as reasonably possible). i've had it in working condition before, but I was never totally happy with it, and now I think I am (mostly, anyway).
Highlights:
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.
I also opted for digital controls, so that I could use this Nav Toggle as a hotkey for the battery monitor and shutdown. I had to tweak the volume script that I wrote for my GBCZ build a little to get it working with USB audio...
For some reason, I could not get the on-board audio to work on the Tinkerboy board, which was very frustrating. Luckily there was still a free USB port on there to use, so I hooked in this tiny audio adapter and an audio amp for the speaker, which I got working pretty quickly, but I'm still bummed about having to stick those extra components in there, not to mention the extra power draw from them... but, oh well, "working" is better than not.
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.
ok, more pics...
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.
Temp-controlled fan InstructionsShow
First, create the file:
You should have a blank text file. Paste the content in - Settings for the control Pin and temperature to trigger the fan are near the top:
finally, you need to set it up to run the script at boot time:
Add a line above "exit 0" with this text:
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 &
Digital Volume InstructionsShow
First, create the file:
You should have a blank text file. Paste the content in - Settings for the control Pins, Volume speed (increment and timing) are near the top:
that will also create a file to store the current volume setting (to persist when you reboot) named volume.txt in the pi root.
finally, you need to set it up to run the script at boot time:
Add a line above "exit 0" with this text:
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.
config.txt settings for SPI screenShow
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