Ecrã Informativo para Raspberry Pi
Este ecrã funciona com Raspberry 2/3/4 e Zero que tenham uma entrada JTAG de 40 pinos.
Material Necessário:
1 x Raspberry Pi com JTAG de 40 pinos.
1 x PDC8544, ecrã Nokia 5110
Para apenas acender a iluminação do ecrã:
1 x Resistência 470 ohms
Para acender a iluminação do ecrã com regulação de intensidade:
1 x Resistência variável de 5K
Para activar uma ventoínha de acordo com a temperatura do CPU:
1 x Transistor 2N2519
1 x Resistência de 100 ohms
Requisitos de Software:
Executar o raspi-config e activar o interface SPI
Adafruit Circuit Python lib, Adafruit PCD8544 lib, Python Pillow, psutil e netifaces
$ sudo pip3 install adafruit-circuitpython-lis3d adafruit-circuitpython-pcd8544 Pillow psutil netiface
Esquemáticos:
Para ligação da iluminação através do próprio RBPi sem controlo de intensidade:
RST -> GPIO22 (Pin 15)
CE (ou CS) -> GPIO5 (Pin 29)
DC -> GPIO6 (Pin 31)
Din -> MOSI (Pin 19)
CLK -> SCLK (Pin 23)
VCC -> Qualquer pino 3V3 (Pins 1 ou 17)
BkLgt -> Resistência de 470R -> GPIO13 (Pin 33)
GND -> Qualquer GND disponível no Raspberry (Pins 6, 9, 14, 20, 25, 30, 34 ou 39).
Para utilizar um potenciómetro para definir a intensidade da iluminação do ecrã:
BkLgt -> Potenciómetro
Com ventoínha:
GPIO17 (Pin 11) -> Resistência de 100 ohms -> Base do transistor 2N2519
É possível tirar os +5V do RBPi, mas para uma ventoínha de baixo consumo, <1W a 5V, ou usar uma fonte externa para alimentar a ventoínha, neste caso o Ground dessa fonte tem que estar ligado a um pin GND do Raspberry:
Código:
import time
import board
import busio
import digitalio
import os
import psutil
import adafruit_pcd8544
from datetime import datetime
import netifaces as ni
from PIL import Image, ImageDraw, ImageFont
##CONFIGURAÇÕES
tempoPorSlide = 5 #Segundos a mostrar cada slide
hddExtra = False #Se existe algum disco externo ligado
hddMountPoint = "" #Se existir onde está montado
usarVentoinha = False #Se se usa ou não uma ventoínha externa
ventoinhaPin = digitalio.DigitalInOut(board.D17) #Pino no qual se encontra a ventoínha, se existir
tempOff = 30 #Temperatura em ºC a desligar a ventoínha
tempOn = 45 #Temperatura em ºC a ligar a ventoínha
thermalKey = "cpu_thermal" #No RBPi 4 é cpu_thermal, no Zero é cpu-thermal...
backLight = False #Usar o GPIO 13 para ligar o LED
# Initialize SPI bus and control pins
spi = busio.SPI(board.SCK, MOSI=board.MOSI)
dc = digitalio.DigitalInOut(board.D6) # data/command
cs = digitalio.DigitalInOut(board.D5) # Chip select
reset = digitalio.DigitalInOut(board.D22) # reset
display = adafruit_pcd8544.PCD8544(spi, dc, cs, reset)
if backLigth:
##LED com PWM
backlight = digitalio.DigitalInOut(board.D13)
backlight.switch_to_output()
#Ligar o LED, é activeLow, portanto False liga, True desliga
backlight.value = False
display.bias = 10
display.contrast = 80
display.fill(0)
display.show()
#Carregar os tipos de letra
font = ImageFont.truetype("6px-Normal.ttf",8)
tfont = ImageFont.truetype("PressStart2P-Regular.ttf",10)
ifaces = ni.interfaces()
nrifaces = len(ifaces)
def ifaceup(iface):
addr = ni.ifaddresses(iface)
return ni.AF_INET in addr
def checkIfaces():
ifups = list()
ups = 0
for i in range(0,nrifaces):
if ifaces[i] == "lo":
continue
if ifaceup(ifaces[i]):
ifups.append(ifaces[i])
ups+=1
return ups,ifups
def sz_to_txt(sz):
if sz > 1073741824:
return '{:.2f}'.format(sz/1073741824) + " Gb"
if sz > 1048576:
return '{:.2f}'.format(sz/1048576) + " Mb"
if sz > 1024:
return '{:.2f}'.format(sz/1024) + " kb"
return sz + " b"
def clock():
data = Image.new("1",(display.width,display.height))
draw = ImageDraw.Draw(data)
now = datetime.now()
dt = now.strftime("%d/%m/%Y")
hr = now.strftime("%H:%M:%S")
(font_w, font_h) = font.getsize(dt)
draw.text((0, 0),dt,font=font,fill=255)
(hr_sz, hr_h) = font.getsize(hr)
draw.text((display.width - hr_sz,0),hr,font=font,fill=255)
return (data,draw,hr_h)
def slideLabel(label,y,draw):
t = label
(f_w,f_h) = tfont.getsize(t)
draw.text((display.width // 2 - f_w // 2,y+2),t,font=tfont,fill=255)
return y+2+f_h
def infoLine(label,content,y,draw):
draw.text((0,y+2),label,font=font,fill=255)
(f_w,f_h)=font.getsize(content)
draw.text((display.width - f_w,y+2),content,font=font,fill=255)
y+=2+f_h
return y
def infoChart(whole,chunk,y,draw):
val = round((chunk * 360)/whole)
draw.pieslice([(24,y+2),(58,48)],start=20, end=val+20,fill=255)
def barChart(whole,chunk,y,draw):
val = round((chunk * 80)/whole)
y=y+5
draw.rectangle((0, y, display.width, y+20), outline=255, fill=255)
draw.rectangle((2,y+2,val,y+18), outline=0, fill=0)
def slideOne(start=0):
display.fill(0)
data,draw,y = clock()
y = slideLabel("Rede",y,draw)
ifs, iface = checkIfaces()
net_count = 0
all_nets = True
for x in range(start,ifs):
net_count+=1
if len(iface[x]) > 5:
iname = iface[x][0:5]
else:
iname = iface[x]
ifname = iname + ":"
ip = ni.ifaddresses(iface[x])[ni.AF_INET][0]['addr']
y = infoLine(ifname,ip,y,draw)
if x < ifs - 1 and net_count == 3:
all_nets = False
break
display.image(data)
display.show()
if not all_nets:
time.sleep(5)
slideOne(x+1)
def slideTwo():
display.fill(0)
data,draw,y = clock()
y = slideLabel("SD",y,draw)
stat= os.statvfs("/")
sz = stat.f_blocks*stat.f_bsize
free = stat.f_bfree*stat.f_bsize
used = sz - free
y = infoLine("Usado:",sz_to_txt(used),y,draw)
y = infoLine("Livre:",sz_to_txt(free),y,draw)
y = infoLine("Total:",sz_to_txt(sz),y,draw)
display.image(data)
display.show()
def slideThree():
display.fill(0)
data,draw,y = clock()
y = slideLabel("SD",y,draw)
stat= os.statvfs("/")
sz = stat.f_blocks*stat.f_bsize
free = stat.f_bfree*stat.f_bsize
infoChart(sz,free,y,draw)
display.image(data)
display.show()
def slideFour():
display.fill(0)
data,draw,y = clock()
y = slideLabel("HDD",y,draw)
stat= os.statvfs(hddMountPoint)
sz = stat.f_blocks*stat.f_bsize
free = stat.f_bfree*stat.f_bsize
used = sz - free
y = infoLine("Usado:",sz_to_txt(used),y,draw)
y = infoLine("Livre:",sz_to_txt(free),y,draw)
y = infoLine("Total:",sz_to_txt(sz),y,draw)
display.image(data)
display.show()
def slideFive():
display.fill(0)
data,draw,y = clock()
y = slideLabel("HDD",y,draw)
stat= os.statvfs(hddMountPoint)
sz = stat.f_blocks*stat.f_bsize
free = stat.f_bfree*stat.f_bsize
infoChart(sz,free,y,draw)
display.image(data)
display.show()
def slideSix():
display.fill(0)
data,draw,y = clock()
y = slideLabel("RAM",y,draw)
mem= psutil.virtual_memory()
sz = mem.total
free = mem.free
used = sz-free
y = infoLine("Usado:",sz_to_txt(used),y,draw)
y = infoLine("Livre:",sz_to_txt(free),y,draw)
y = infoLine("Total:",sz_to_txt(sz),y,draw)
display.image(data)
display.show()
def slideSeven():
display.fill(0)
data,draw,y = clock()
y = slideLabel("RAM",y,draw)
mem= psutil.virtual_memory()
sz = mem.total
free = mem.free
barChart(sz,free,y,draw)
display.image(data)
display.show()
def slideEight():
display.fill(0)
data,draw,y = clock()
y = slideLabel("Temp.",y,draw)
tr = psutil.sensors_temperatures()
tx = tr[thermalKey][0].current
if usarVentoinha:
if tx > tempOn and fan.value == False:
fan.value = True
elif tx < tempOff and fan.value == True:
fan.value = False
stemp = '{:.1f}'.format(tx)+" ºC"
y = slideLabel(stemp,y,draw)
display.image(data)
display.show()
while 1:
slideOne()
time.sleep(tempoPorSlide)
slideTwo()
time.sleep(tempoPorSlide)
slideThree()
time.sleep(tempoPorSlide)
if hddExtra:
slideFour()
time.sleep(tempoPorSlide)
slideFive()
time.sleep(tempoPorSlide)
slideSix()
time.sleep(tempoPorSlide)
slideSeven()
time.sleep(tempoPorSlide)
slideEight()
time.sleep(tempoPorSlide)
Tipos de Letra: