Ecrã Informativo para Raspberry Pi

26 October, 2020

Este ecrã funciona com Raspberry 2/3/4 e Zero que tenham uma entrada JTAG de 40 pinos.

undefinedundefined

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).

undefined

Para utilizar um potenciómetro para definir a intensidade da iluminação do ecrã:

BkLgt -> Potenciómetro

undefined

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:

 

undefined

 

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:

Download

Home