• Benvenuti su RaspberryItaly!
Benvenuto ospite! Login Login con Facebook Registrati


Valutazione discussione:
  • 0 voto(i) - 0 media
  • 1
  • 2
  • 3
  • 4
  • 5

[-]
Tags
utilizzo nokia 5110 lcd display

[Problema] Utilizzo Nokia 5110 Lcd Display
#1
Come già segnalato nella mia precedente discussione (http://forum.raspberryitaly.com/showthread.php?tid=1219), ho ricevuto un mini-diplay lcd Nokia 5110 (solitamente utilizzato su Arduino).
La versione in mio possesso, che ho acquistato su Ebay per una cifra ridicola, è GIA' DOTATA DI SLOT GPIO a 26 pin (vedi immagine).
Dopo una prima verifica (svolta con esito positivo) sulla compatibilità con Raspberry PI2 (il fornitore mi aveva detto che forse non avrebbe funzionato), mi stò 'avventurando' nella creazione di un semplice script in Pyton che dovrebbe MONITORARE/VISUALIZZARE LO STATO DI SALUTE DEL SISTEMA (sono un assoluto incompetente/principiante dunque le mie conoscente sono decisamente ridotte).
In particolare vorrei visualizzare (in tempo reale) sul display:
1) Carico complessivo Cpu indicato in percentuale (valore anche approssimativo)
2) Temperatura Cpu
3) Carico Ram ovvero quanta memoria  è impegnata dalle applicazioni e dai processi in esecuzione (vorrei leggere un unico valore, anche approssimativo, indicato in percentuale)
4) Spazio impegnato su micro-Sd in percentuale (valore anche approssimativo)

Leggendo vari articoli in giro per la rete e un manuale in Pdf per l'utilizzo specifico del display (vedi allegato), ho scoperto che, utilizzando il linguaggio C, esiste già una specifica applicazione che mi permette di ottenere (più o meno) ciò che voglio.
Ho tentato (invano) di compilare l'applicazione ma, visto la mia totale inesperienza, NON sono riuscito nell'intento.
Ho dunque provato ad 'aggirare' il problema utilizzando Pyton e le librerie fornite da Adafruit ed ho realizzato questo script che è il frutto di un copia-incolla (un orribile e probabilmente sbagliato incrocio) tra vari script reperiti in rete.

Codice:
#!/usr/bin/env python
import os
import sys
import time
from datetime import datetime
import psutil
import Adafruit_Nokia_LCD as LCD
import Adafruit_GPIO.SPI as SPI
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# Raspberry Pi software SPI config
SCLK = 17
DIN = 18
DC = 27
RST = 23
CS = 22

# Software SPI usage (defaults to bit-bang SPI interface)
disp = LCD.PCD8544(DC, RST, SCLK, DIN, CS)

# Initialize display library
disp.begin(contrast=45)

# Load default font
font = ImageFont.load_default()

# Create blank image for drawing.
image = Image.new('1', (LCD.LCDWIDTH, LCD.LCDHEIGHT))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Initialize system healt variables

def bytes2human(n):
   # better readability
   """
   >>> bytes2human(10000)
   '9K'
   >>> bytes2human(100001221)
   '95M'
   """
   symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
   prefix = {}
   for i, s in enumerate(symbols):
       prefix[s] = 1 << (i+1)*10
   for s in reversed(symbols):
       if n >= prefix[s]:
           value = int(float(n) / prefix[s])
           return '%s%s' % (value, s)
   return "%sB" % n

def system_up():
   # read system uptime
   uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
   return "UP: %s" \
           % (str(uptime).split('.')[0])

def cpu_usage():
   # read cpu load
   av1, av2, av3 = os.getloadavg()
   return "CPU:%.1f %.1f %.1f" \
           % (av1, av2, av3)

def mem_usage():
   # read memory usage
   usage = psutil.virtual_memory()
   return "MEM: %s %.0f%%" \
           % (bytes2human(usage.used), 100 - usage.percent)

def disk_usage(dir):
   # read sd usage
   usage = psutil.disk_usage(dir)
   return "SD: %s %.0f%%" \
           % (bytes2human(usage.used), usage.percent)

# show system data in loop

while True:

       # Clear display.
       disp.clear()
       disp.display()

       # Draw a white filled box to clear the image.
       draw.rectangle((0,0,LCD.LCDWIDTH,LCD.LCDHEIGHT), outline=255, fill=255)

       # Write some text.
       draw.text((0,0),"System monitor",font=font)
       draw.text((0,9),(system_up()),font=font)
       draw.text((0,18),(cpu_usage()),font=font)
       draw.text((0,27),(mem_usage()),font=font)
       draw.text((0,36),(disk_usage('/')),font=font)

       # Display image.
       disp.image(image)
       disp.display()

       time.sleep(10.0)

print 'Press Ctrl-C to quit'

Tutto sommato il risultato non è male (vedi immagine) ma purtroppo il CARICO CPU vene visualizzato in modo a me incomprensibile e NON riesco neppure a inserire il valore relativo alla TEMPERATURA CPU.
A questo punto non sò come risolvere il problema (non vorrei mettere il dislpay in un cassetto...) e chiedo a voi qualche indicazione in merito, in particolare:
1) Come modificare la riga che rileva il carico CPU per rendere il risultato 'chiaramente leggibile' con un valore espresso in percentuale.
2) Come inserire la rilevazione della TEMPERATURA CPU

La mia configurazione di sistema è:
Raspberry PI2
Ubuntu-Mate 16.04 LTS
Micro-SD 32 Gb
Disco SSD 120 Gb

Come ulteriore indicazione riporto uno script Pyton (l'ho messo insieme io) che stò utilizzando sul Rapberry in abbinamento a un mini-circuito autocostruito (avvia automaticamente una ventolina di raffreddamento, vedi immagine).

Codice:
#!/usr/bin/python

import subprocess, RPi.GPIO as GPIO
import os
import psutil
import time
#from time import sleep

# Disabilita messaggi di avviso
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)

# Massa su pin 39
GPIO.setup(31, GPIO.OUT)                # Trigger ventola
GPIO.setup(36, GPIO.OUT)                # Led rosso carico Cpu
GPIO.setup(37, GPIO.OUT)                # Led verde carico Cpu
GPIO.setup(33, GPIO.OUT)                # Led rosso temperatura Cpu
GPIO.setup(35, GPIO.OUT)                # Led verde temperatura Cpu
GPIO.setup(38, GPIO.OUT)                # Led verde carico ram
GPIO.setup(40, GPIO.OUT)                # Led rosso carico ram

def LedOff():
   GPIO.output(31, False)              # Spenge ventola
   GPIO.output(36, False)              # Spenge tutti i led
   GPIO.output(38, False)
   GPIO.output(40, False)
   GPIO.output(33, False)
   GPIO.output(35, False)
   GPIO.output(37, False)

def LedTest():
   GPIO.output(33, True)               # Led rosso temperatura Cpu acceso
   GPIO.output(36, True)               # Led rosso carico Cpu acceso
   GPIO.output(40, True)               # Led rosso carico Ram acceso
   time.sleep(.300)
   GPIO.output(33, False)              # Led rosso temperatura Cpu spento
   GPIO.output(36, False)              # Led rosso carico Cpu spento
   GPIO.output(40, False)              # Led rosso carico Ram spento
   time.sleep(.300)
   GPIO.output(35, True)               # Led verde temperatura Cpu acceso
   GPIO.output(37, True)               # Led verde carico Cpu acceso
   GPIO.output(38, True)               # Led verde carico Ram acceso
   time.sleep(.300)
   GPIO.output(35, False)              # Led verde temperatura Cpu spento
   GPIO.output(37, False)              # Led verde carico Cpu spento
   GPIO.output(38, False)              # Led verde carico Ram spento
   time.sleep(.300)

LedTest()

try:

   while True:

       # Rileva temperatura Cpu
       temperatura = int( subprocess.check_output(["/opt/vc/bin/vcgencmd","measure_temp"])[5:7])

       if temperatura <=49:
            GPIO.output(31, False)     # Ventola spenta
            GPIO.output(33, False)
            GPIO.output(35, True)      # Led verde acceso

       if temperatura >49:
            GPIO.output(31, True)      # Ventola accesa
            GPIO.output(33, True)      # Led rosso acceso
            GPIO.output(35, False)

       # Rileva carico Cpu
       carico = psutil.cpu_percent(interval=4)

       if carico <=49:
            GPIO.output(36, False)
            GPIO.output(37, True)      # Led verde acceso

       if carico >49:
            GPIO.output(36, True)      # Led rosso acceso
            GPIO.output(37, False)

       # Rileva carico Ram
       mem = psutil.virtual_memory()
       limite = 500 * 1024 * 1024      # 500 Mb

       if mem.available >limite:
            GPIO.output(40, False)
            GPIO.output(38, True)      # Led verde acceso

   time.sleep(3)

except KeyboardInterrupt:
       # CTRL+C uscita, spenge i led
       print 'Processo terminato'
       LedOff()
       LedTest()

Potrei utilizzare alcuni parametri di questo script per pilotare il display ? Se sì come devo fare ?
Vi ringrazio anticipatamente per la PAZIENZA e vi saluto cordialmente.


Allegati Anteprime
               

.pdf   PCD8544.pdf (Dimensione: 402.32 KB / Download: 2)
 
Risposta
#2
Ci sono quasi...
Dopo aver navigato molto per cercare qualche soluzione, sono riuscito a mettere insieme una specie di script alquanto raccapricciante (assomiglia a Frankenstei) che, nonostante la mia assoluta ignoranza, sembra funzionare correttamente (vedi immagini).

Codice:
#!/usr/bin/env python

# Importa librerie necessarie per esecuzione
import os
import time
from datetime import datetime
import psutil
import Adafruit_Nokia_LCD as LCD
import Adafruit_GPIO.SPI as SPI
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# Configura SPI via software
SCLK = 17
DIN = 18
DC = 27
RST = 23
CS = 22

# Inizializza display per SPI software
disp = LCD.PCD8544(DC, RST, SCLK, DIN, CS)

# Regola contrasto (sembra non avere effetto)
disp.begin(contrast=45)

# Carica carattere scrittura display
#font = ImageFont.load_default()
font = ImageFont.truetype('Minecraftia-Regular.ttf', 8)

# Crea immagine vuota per cancellazione display
image = Image.new('1', (LCD.LCDWIDTH, LCD.LCDHEIGHT))
draw = ImageDraw.Draw(image)

# Migliora leggibilita' dati sistema
def bytes2human(n):
   """
   >>> bytes2human(10000)
   '9K'
   >>> bytes2human(100001221)
   '95M'
   """
   symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
   prefix = {}
   for i, s in enumerate(symbols):
       prefix[s] = 1 << (i+1)*10
   for s in reversed(symbols):
       if n >= prefix[s]:
           value = int(float(n) / prefix[s])
           return '%s%s' % (value, s)
   return "%sB" % n

# Definisce variabili per lettuta dati sistema

# Legge tempo trascorso dall'accensione
def system_up():
   uptime = datetime.now() - datetime.fromtimestamp(psutil.boot_time())
   return "Uptime:  %s" \
           % (str(uptime).split('.')[0])

# Legge carico % Cpu
def getCPUuse():
   res = psutil.cpu_percent()
   return "Cpu:  %s%%" \
           % (res)

# Legge temperatura Celsius Cpu
def getCPUtemperature():
   res = os.popen('vcgencmd measure_temp').readline()
   return "Cpu:  %s C." \
           % (res.replace("temp=","").replace("'C\n",""))

# Legge carico Mb Ram
def mem_usage():
   usage = psutil.virtual_memory()
   return "Ram:  %s  %.0f%%" \
           % (bytes2human(usage.used), 100 - usage.percent)
#    usage = psutil.virtual_memory()
#    return "Ram used  %s" \
#            % (bytes2human(usage.used))

# Legge carico Mb Sd
def disk_usage(dir):
   usage = psutil.disk_usage(dir)
   return "Disk:  %s  %.0f%%" \
           % (bytes2human(usage.used), usage.percent)
#    usage = psutil.disk_usage(dir)
#    return "Disk used  %s" \
#            % (bytes2human(usage.used))

# Avvia loop infinito per visualizzazione dati
try:
       while True:

               # Assegna variabile per lettura temperatura Cpu
               CPU_temp = getCPUtemperature()

               # Assegna variabile per lettura utilizzo % Cpu
               CPU_usage = getCPUuse()

               # Assegna variabile per lettura data attuale
               DATE_now = (time.strftime("Date:  %d/%m/%y"))

               # Assegna variabile per lettura ora attuale
               HOUR_now = (time.strftime("Time:  %H:%M:%S"))

               #-------------------- PRIMA SCHERMATA ---------------------#

               # Pulisce display
               disp.clear()
               disp.display()
               draw.rectangle((0,0,LCD.LCDWIDTH,LCD.LCDHEIGHT), outline=255, fill=255)

               # Inizializza stringhe da scrivere (coordinate x,y)

               # Temperatura Celsius Cpu
               draw.text((0,0),(CPU_temp),font=font)

               # Utilizzo percentuale Cpu
               draw.text((0,12),(CPU_usage),font=font)

               # Utilizzo Mb Ram
               draw.text((0,24),(mem_usage()),font=font)

               # Utilizzo Mb Sd
               draw.text((0,36),(disk_usage('/')),font=font)

               # Scrive stringhe su display
               disp.image(image)
               disp.display()

               # Attende 5 secondi per nuova schermata
               time.sleep(5)

               #------------------- SECONDA SCHERMATA --------------------#

               # Pulisce display
               disp.clear()
               disp.display()
               draw.rectangle((0,0,LCD.LCDWIDTH,LCD.LCDHEIGHT), outline=255, fill=255)

               # Inizializza stringhe da scrivere (coordinate x,y)

               # Data attuale
               draw.text((0,0),(DATE_now),font=font)

               # Ora attuale
               draw.text((0,12),(HOUR_now),font=font)

               # Tempo trascorso dall'accensione
               draw.text((0,24),(system_up()),font=font)

               # Scrive stringhe su display
               disp.image(image)
               disp.display()

               # Attende 5 secondi per nuovo ciclo
               time.sleep(5)

except KeyboardInterrupt:
       # CTRL+C esce e azzera display
       disp.clear()
       disp.display()
       draw.rectangle((0,0,LCD.LCDWIDTH,LCD.LCDHEIGHT), outline=255, fill=255)
       disp.image(image)
       disp.display()
       print 'Processo terminato'

Come si vede dal codice, ho modificato il carattere del display (quello di default era decisamente brutto) e ho inserito tutte le informazioni che mi necessitano (in due diverse schermate).
Devo ammettere che la lettura dei valori di sistema (temperatura, carico, Ram, Sd, ecc.) NON è accurata/precisa ma a me basta per tenere d'occhio lo stato di salute generale del Raspberry.
Lo script è alquanto raffazzonato (ho preso e messo insieme vari spezzoni) dunque (sicuramente) si può migliorare... e quì casca l'asino (cioè io) perchè NON sono capace di ottimizzare il tutto (magari ci sono parti inutili o la struttura è mal impostata).
Qualcuno mi può aiutare a rendere il tutto un po' più decente ?


Allegati Anteprime
       
 
Risposta
  


Vai al forum:


Navigazione:
Forum con nuovi Post
Forum senza nuovi post
Forum bloccato
Forum Redirect