Ardutop: Monitorizar nuestro sistema Linux con Arduino

Bienvenidos a este tutorial sobre Ardutop. Éste es un proyecto 'weekend' sobre el que trabajé la semana pasada. Se basa en mostrar a través de una pantalla LCD 84x48 (PCD8544) los datos de carga del equipo. Resulta útil cuando no tenemos una pantalla tan grande o simplemente no queremos ocupar espacio en nuestros monitores para vigilar la carga del sistema con top o htop. Esto se logra mediante el uso de dos librerías bastante sencillas de aprender: Adafruit_PCD8544 para Arduino y psutils para Python.

Bien, una vez cumplidas las dependencias pasamos a lo bueno. La primera parte de código consiste en una clase que obtiene los datos de memoria RAM y CPU del directorio /proc/meminfo.

El código Python genera un stream de 20 bytes y enviándolo por el puerto serial donde está conectado nuestro Arduino.

# Comunicacion con el puerto serial # Se envian datos a la placa Arduino # coded by: Edgar C. Cardoz (@ecardoz) # FreeMemLinux class by: oz123 # mail edgar.cardoz@gmail.com from time import sleep import time import serial import psutil puerto = serial.Serial('/dev/ttyACM0',9600) class FreeMemLinux(object): """ Non-cross platform way to get free memory on Linux. Note that this code uses the key word as, which is conditionally Python 2.5 compatible! If for some reason you still have Python 2.5 on your system add in the head of your code, before all imports: from __future__ import with_statement """ def __init__(self, unit='kB'): with open('/proc/meminfo', 'r') as mem: lines = mem.readlines() self._tot = int(lines[0].split()[1]) self._free = int(lines[1].split()[1]) self._buff = int(lines[2].split()[1]) self._cached = int(lines[3].split()[1]) self.unit = unit self._convert = self._faktor() def _faktor(self): """determine the convertion factor""" if self.unit == 'kB': return 1 if self.unit == 'k': return 1024.0 if self.unit == 'MB': return 1/1024.0 if self.unit == 'GB': return 1/1024.0/1024.0 if self.unit == '%': return 1.0/self._tot else: raise Exception("Unit not understood") @property def total(self): return self._convert * self._tot @property def used(self): return self._convert * (self._tot - self._free)

En mi caso, hago un sleep de 1.3 segundos para que Arduino ajuste el contraste de la pantalla LCD. Luego se instancia un objeto f para la lectura de los datos del sistema, se crean y calculan lo datos y se empieza con la construcción del stream para los CPU's que estén disponibles, en mi caso 4 cores.

print "Iniciando... " sleep(1.3) while True: f = FreeMemLinux() puerto.flushOutput() stream = "" usedRam = str(int(round(f.used))/1024) freeRam = str(int(round(f.total-f.used))/1024) perCPU  = psutil.cpu_percent(interval=1, percpu=True)   #Array for i in range(len(perCPU)): if int(round(perCPU[i]))

Luego se concatenan los datos de la cantidad de RAM usada.

if int(usedRam) < 1000: if int(usedRam) < 100: if int(usedRam) < 10: stream += "   " else: stream += "  " else: stream += " " stream += usedRam

Y por último los datos de la memoria RAM libre.

if int(freeRam) < 1000: if int(freeRam) < 100: if int(freeRam) < 10: stream += "   " else: stream += "  " else: stream += " " stream += freeRam puerto.write(stream) print stream + " |Tiempo transcurrido: " + str(current_milli_time() - milli)

Conexión en protoboard:

Para las conexiones de los pines es importante notar que no todos los PCD8544 tienen la misma disposición así que deberán hacer los cambios si nos necesarios.

En el sketch:

// pin 7 - Serial clock out (SCLK) // pin 6 - Serial data out (DIN) // pin 5 - Data/Command select (D/C) // pin 4 - LCD chip select (CS) // pin 3 - LCD reset (RST) Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 3, 4);

Vídeo de funcionamiento:

Descarga el código fuente: Github: https://github.com/ecardoz/ardutop