Mostrando entradas con la etiqueta Raspberry Pi. Mostrar todas las entradas
Mostrando entradas con la etiqueta Raspberry Pi. Mostrar todas las entradas

viernes, 20 de febrero de 2026

Ojos animados en OLED con Raspberry Pi: Tutorial Python con expresiones

Muy buenas a todos y todas!!!

Ya hemos visto como configurar una pantalla OLED de 128x64 en nuestra Raspberry Pi junto con la librería Adafruit.

Y como veía mi cluster Pi un poco "triste" decidí animarlo un poco con una pantalla OLED de tipo I2c y algunas animaciones programadas en Python que la hacen más "friendly".


Expresiones y dirección de la mirada

Podemos alternar entre las diferentes expresiones:

  • Normal
  • Contento
  • Triste
  • Sorpresa
  • Dormido

También podemos dirigir la mirada en las siguientes direcciones:

  • Izquierda
  • Centro
  • Derecha



Pero también podemos llamar de manera independiente a cada una de las expresiones con la función "crear_ojos" y "animar_parpadeo"

def crear_ojos(expresion="normal", direccion_mirada="centro", estado_parpadeo=1.0):
    """
    Ojos con sistema de parpadeo realista
    estado_parpadeo: 1.0 = totalmente abierto, 0.0 = totalmente cerrado
    """

Para crear la animación de parpadeo:


def animar_parpadeo(expresion="normal", direccion_mirada="centro"):
    """Animación completa de parpadeo"""
    

Programa completo en python:



# Simulación de ojos con expresiones en OLED 128x64

import time
import random
import board
import adafruit_ssd1306
from PIL import Image, ImageDraw, ImageFont

# Use for I2C.
i2c = board.I2C()  # uses board.SCL and board.SDA

try:
        disp = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C)
        print("\nAdafruit SSD1306 ok")

except Exception as errors:
        print("\nError Adafruit SSD1306:",str(errors), "\nPlease check Raspi-config\n")
        exit()


def crear_ojos(expresion="normal", direccion_mirada="centro", estado_parpadeo=1.0):
    """
    Ojos con sistema de parpadeo realista
    estado_parpadeo: 1.0 = totalmente abierto, 0.0 = totalmente cerrado
    """
    # Crear imagen evitando la franja amarilla superior
    img = Image.new('1', (128, 64), 0)
    draw = ImageDraw.Draw(img)
    
    # Posiciones fijas
    centro_y = 40
    ojo_izq_x = 45
    ojo_der_x = 83
    
    # Tamaño máximo reducido a 40
    max_tam = 40
    
    # Radio de redondeo
    radio = 15
    
    # Determinar tamaños según dirección de mirada
    if direccion_mirada == "izquierda":
        ancho_izq, alto_izq = max_tam, max_tam
        ancho_der, alto_der = 30, 30
    elif direccion_mirada == "derecha":
        ancho_izq, alto_izq = 30, 30
        ancho_der, alto_der = max_tam, max_tam
    else:  # centro
        ancho_izq, alto_izq = 35, 40
        ancho_der, alto_der = 35, 40
    
    def dibujar_ojo(x, y, ancho, alto, radio, apertura=1.0):
        """Dibuja un ojo con sistema de parpadeo"""
        if apertura >= 1.0:
            # Ojo totalmente abierto
            draw.rounded_rectangle([
                (x - ancho//2, y - alto//2),
                (x + ancho//2, y + alto//2)
            ], radius=radio, outline=1, fill=1)
        elif apertura <= 0.0:
            # Ojo totalmente cerrado (línea)
            draw.line([
                (x - ancho//2, y),
                (x + ancho//2, y)
            ], fill=1, width=3)
        else:
            # Ojo parcialmente cerrado - calcular altura visible
            alto_visible = int(alto * apertura)
            if alto_visible < 2:
                alto_visible = 2
            
            # Dibujar el ojo recortado según la apertura
            draw.rounded_rectangle([
                (x - ancho//2, y - alto_visible//2),
                (x + ancho//2, y + alto_visible//2)
            ], radius=min(radio, alto_visible//2), outline=1, fill=1)
    
    # Aplicar expresiones (modifican la apertura base)
    apertura_base = estado_parpadeo
    
    if expresion == "normal":
        apertura = apertura_base
    elif expresion == "contento":
        apertura = apertura_base * 0.7  # Ojos más cerrados
    elif expresion == "triste":
        apertura = apertura_base * 0.9  # Ojos casi normales pero caídos
    elif expresion == "sorpresa":
        apertura = min(apertura_base * 1.2, 1.0)  # Ojos más abiertos
    elif expresion == "dormido":
        apertura = apertura_base * 0.3  # Ojos casi cerrados
    
    # Dibujar ojos con la apertura calculada
    dibujar_ojo(ojo_izq_x, centro_y, ancho_izq, alto_izq, radio, apertura)
    dibujar_ojo(ojo_der_x, centro_y, ancho_der, alto_der, radio, apertura)
    
    return img

def animar_parpadeo(expresion="normal", direccion_mirada="centro"):
    """Animación completa de parpadeo"""
    frames = []
    
    # Fases del parpadeo (apertura de 1.0 a 0.0 y vuelta)
    fases = [1.0, 0.8, 0.5, 0.2, 0.0, 0.2, 0.5, 0.8, 1.0]
    
    for apertura in fases:
        frame = crear_ojos(expresion, direccion_mirada, apertura)
        frames.append(frame)
    
    return frames


# Bucle principal 
if __name__ == "__main__":
    expresiones = ["normal", "contento", "triste", "sorpresa", "dormido"]
    direcciones = ["izquierda", "centro", "derecha"]

    print("Mostrando expresiones sencillas...")
    print("Presiona Ctrl+C para detener")

    try:
        while True:
            for expresion in expresiones:
                for direccion in direcciones:

                    print(f"Expresión: {expresion} dirección: {direccion}")

                    img = crear_ojos(expresion, direccion)
                    disp.image(img)
                    disp.show()
                    time.sleep(5)
                                        # 30% de probabilidad de guiño entre animaciones
                    if random.random() < 0.2:
                        #lado_guiño = random.choice(["izquierdo", "derecho"])
                        print(f"¡papadeo {expresion}!")
                        frames_parpadeo = animar_parpadeo(expresion, direccion)

                        for frame in frames_parpadeo:
                            disp.image(frame)
                            disp.show()

    except KeyboardInterrupt:
        print("\nBucle detenido")

Es un programa que podemos ampliar con otras expresiones o incluso hacer llamadas desde otros programas por ejemplo conectandolo a una Raspi cam para simular que la mirada nos sigue.

Otro idea que se me ocurre es que las llamadas sean según diferentes eventos, como que despierte con el acceso por ssh o utilizar el sensor de temperatura para que nos "mire mal" si nuestra Raspberry Pi se pone lujuriosa.

Añadir programa al iniciar Raspberry PI

Lo ideal es que este programa se inicie al encender la Raspberry pi. Es un buen indicador para saber que la Raspberry Pi arranco sin problemas.

esto lo podemos hacer editando el crontab con el comando "crontab -e" (no hace falta sudo).


@reboot sleep 30 && python3 ~/Eyes_simulation/eyes_simulation.py > ~/Eyes_simulation/eyes.log 2>&1

Recuerda poner "@reboot sleep 30" para darle un tiempo prudente a la Raspberry para inicializar el puerto I2c.

Y siempre puedes ver si todo esta bien o hay algún fallo consultando el archivo que se genera en el inicio llamado "eyes.log".


Conclusión:

Es un programa sencillo que le dará a nuestra maquina un poco más de carisma (por si le faltaba un poco) y que deje de ser un puñado de lucecitas encima del escritorio.

Antes de montar el cluster con las 3 Raspberry Pi, la que máquina que usaba para estas cosas empezó a dar problemas con la tarjeta y lo pude detectar ya que no me miraba igual que siempre...

¿Le puedo poner nombre?


Aquí tienes otros enlaces de este blog relacionados con Raspberry Pi:

domingo, 22 de junio de 2025

Script Bash para Raspberry Pi: Mantenimiento, redes y Bluetooth

Muy buenas a todos y todas!!!

Si hay una cosa que todo el mundo odio por lo tedioso y aburrido que es, es instalar y poner en orden todos los programas básicos para nuestra Raspberry pi, sobre todo en modelos anteriores a la Raspberry pi 4.

El problema suele se la potencia limitada con las que cuentan las Raspberry Pi2 y Raspberry Pi 3, ambos modelos unicamente cuentan con 1 Gb de RAM.

Si bien esto no impide poner un sistema gráfico, el rendimiento no es el mejor. Este articulo va dedicado a los que prefieren el uso de la terminal para el manejo de estos versátiles ordenadores.

viernes, 13 de junio de 2025

Raspberry Pi con sensor DHT11 y DHT22: Temperatura y humedad en Python

Sensor DHT11
DHT11

Uno de los sensores más populares utilizados en conjunto con la Raspberry Pi es el DHT11, un sensor de humedad y temperatura de bajo costo y fácil de usar.


¿Qué son los sensores DHT11 y DHT22?

Los sensores DHT11 y DHT22 son dispositivos electrónicos que mide la temperatura y la humedad relativa del aire. Es un sensor digital, lo que significa que los datos que proporciona son en formato digital y pueden ser fácilmente leídos por un microcontrolador como la Raspberry Pi.


DHTT22 pinout
DHT22

A pesar de su bajo costo, el DHT11 más que el DHT22, son bastante precisos y fiables, lo que los convierte en una excelente opción para una amplia gama de aplicaciones.

El DHT11 esta más indicado para Proyectos educativos o prototipos simples y ambientes interiores controlados como pueden ser habitaciones, oficinas.

Sin embargo el DHT22 será más útil en proyectos de tipo invernadero, neveras y exteriores.

Funciones de los sensores DHT11 y DHT22

  • Medición de temperatura
  • Medición de humedad
  • Salida digital
  • Bajo consumo
  • Fácil de usar

Comparativa: DHT11 vs DHT22

Característica DHT11 DHT22
Precisión (Temp) ±2°C ±0.5°C
Rango (Temp) 0°C a 50°C -40°C a 80°C
Precisión (Hum) ±5% RH ±2% RH
Rango (Hum) 20% a 80% RH 0% a 100% RH
Frecuencia de Muestreo 1 Hz 0.5 Hz
Resolución 1°C / 1% RH 0.1°C / 0.1% RH
Consumo Eléctrico 0.5 - 2.5 mA

Instalación y Configuración en Python:

Para utilizar los sensores DHT11 y DHT22 con una Raspberry Pi, necesitaremos un entorno de programación adecuado y una biblioteca para interactuar con el sensor. Python es uno de los lenguajes de programación más populares para la Raspberry Pi, y existen varias bibliotecas que facilitan la lectura de datos del DHT11.

Necesitamos instalar la biblioteca Adafruit. Ahora en un terminal de tu Raspberry Pi y ejecuta el siguiente comando para instalar la biblioteca adafruit-circuitpython-dht:


pip3 install adafruit-circuitpython-dht



Esta biblioteca proporciona una manera sencilla para leer datos de los sensores DHT11 y DHT22.

Ahora tenemos que conectar el sensor DHT a a la Raspberry Pi. Para esto identificaremos los pines de cada sensor y los conectamos siguiendo las serigrafias que vienen en el sensor:

  • Data: al GPIO21 (pin40)
  • VCC: al cualquier pin 5V
  • GND: al cualquier pin GND

Ahora en la terminal creamos un nuevo archivo Python llamado "dht11_test.py y escribimos el siguiente código que nos mostrará en pantalla los datos de temperatura y humedad del DHT11:



# Código para lectura del sensor DHT11
import time

import board

import adafruit_dht

#Inicia el dispositivo DHT con el pin de datos conectado a:
dhtDevice = adafruit_dht.DHT11(board.D21)

# Si no deseas usar pulseio puedes usar DHT11 use_pulseio=False
# Esto puede ser necesario en ordenadores de tipo Raspberry Pi con Linux
# Pero no funcionará en CircuitPython
# dhtDevice = adafruit_dht.DHT11(board.D18, use_pulseio=False)

while True:
    try:
        # Imprime los valores en el puerto serie
        temperature_c = dhtDevice.temperature
        temperature_f = temperature_c * (9 / 5) + 32
        humidity = dhtDevice.humidity
        print(f"Temp: {temperature_f:.1f} F / {temperature_c:.1f} C    Humidity: {humidity}% ")

    except RuntimeError as error:
	# Los errores ocurren con bastante frecuencia, los DHT son difíciles de leer, 
    simplemente sigue adelante.

        print(error.args[0])
        time.sleep(2.0)
        continue
    except Exception as error:
        dhtDevice.exit()
        raise error

    time.sleep(2.0)


Guarda el archivo como dht11_test.py y ejecútalo desde la terminal:


python3 dht11_test.py
o
python3 -m dht11_test



Para el caso del DHT22 es exactamente igual menos la linea "sensor = adafruit_dht.DHT11" que tenemos que cambiar por "sensor = adafruit_dht.DHT22" y se ve así:


# Código para lectura del sensor DHT22
import time

import board

import adafruit_dht

#Inicia el dispositivo DHT con el pin de datos conectado a:
dhtDevice = adafruit_dht.DHT22(board.D21)

# Si no deseas usar pulseio puedes usar DHT22 use_pulseio=False
# Esto puede ser necesario en ordenadores de tipo Raspberry Pi con Linux
# Pero no funcionará en CircuitPython
# dhtDevice = adafruit_dht.DHT22(board.D21, use_pulseio=False)

while True:
    try:
        # Imprime los valores en el puerto serie
        temperature_c = dhtDevice.temperature
        temperature_f = temperature_c * (9 / 5) + 32
        humidity = dhtDevice.humidity
        print(f"Temp: {temperature_f:.1f} F / {temperature_c:.1f} C    Humidity: {humidity}% ")

    except RuntimeError as error:
	# Los errores ocurren con bastante frecuencia, los DHT son difíciles de leer,
    simplemente sigue adelante.

        print(error.args[0])
        time.sleep(2.0)
        continue
    except Exception as error:
        dhtDevice.exit()
        raise error

    time.sleep(2.0)


Guardamos el archivo como dht22_test.py y ejecutamos desde la terminal:


python3 dht22_test.py
o
python3 -m dht22_test



El código de este ejemplo llamado dht_simpletest.py lo podemos encontrar en el repositorios de Adafruit_CircuitPython_DHT

Solución de errores:

Uno de los errores que más comunes es el uso de la librería "board". Muchas veces podemos recibir el siguiente mensaje:


import board
ModuleNotFoundError: No module named 'board'

O también este:


dhtDevice = adafruit_dht.DHT11(board.D21)
                                   ^^^^^^^^^
AttributeError: module 'board' has no attribute 'D21'

Nos hace referencia a la librería board que se instala normalmente con "pip install board". Pero al estar haciendo uso de Adafruit CircuitPython necesitamos la librería que esta asociadad a Adafruit llamada "Adafruit-Blinka"

Esta librería instalara "board" y otras librerías como "pyserial" o "pyusb".

En el caso de que haya un error nos puede aparecer este mensaje:


Unable to set line 18 to input


Si aparece este error, nos hace referencia al pin, que o bien no esta activo o no es el puerto correcto donde esta conectado el sensor DHT 11.

Aplicaciones del DHT11 y Raspberry Pi

La combinación de Raspberry Pi y DHT11 o DHT22 ofrece un sinfín de posibilidades para proyectos de IoT. Algunas de las aplicaciones más comunes incluyen:

  • Estaciones meteorológicas caseras: Crea una estación meteorológica personalizada para monitorear la temperatura y humedad en tu hogar o jardín.
  • Sistemas de control de invernaderos: Automatiza el riego y la ventilación de tu invernadero en función de las condiciones ambientales.
  • Monitoreo de condiciones ambientales: Utiliza el sensor para monitorear la temperatura y humedad en espacios cerrados, como oficinas o almacenes.
  • Proyectos de domótica: Puedes integrar el sensor en sistemas de domótica para crear ambientes más cómodos y eficientes.
  • Prototipos de IoT: Utilizalos como punto de partida para desarrollar prototipos de dispositivos IoT más complejos.

Conclusión:

El sensor DHT11 es una herramienta invaluable para cualquier persona interesada en proyectos de electrónica y programación. En combinación con la Raspberry Pi, ofrece una plataforma potente y flexible para crear una amplia variedad de aplicaciones.

Con este artículo, has adquirido los conocimientos básicos para comenzar a trabajar con el DHT11 y la Raspberry Pi. ¡Anímate a experimentar y crear tus propios proyectos!

Instalación librería Adafruit-Blinka

Librería adafruit-circuitpython-dht


Un saludo a todas y todos!!!


Aquí tienes otros enlaces de este blog relacionados con Raspberry Pi:

domingo, 8 de junio de 2025

Raspberry Pi 3B+: Soluciona el error "Low Voltage" con módulo LM2590

Muy buenas a todos los amantes de la informática!!!

Hace poco hemos desempolvado unas Raspberry Pi (2x3B + 1x3B+) estaban montadas en un rack y les fui dando diferentes usos hasta que ya los deje un poco de lado por que casi siempre había problemas de alimentación.

Con ellas hemos visto algunos proyectos como la pantalla oled I2C o el uso del PWM para controlar el ventilador de la Raspberry Pi.

En mucho foros y paginas de internet hay referencia al temido mensaje "low-voltage". Este error es debido a que el chip que se encarga de entregar la energía a la Raspberry Pi detecta un voltaje por debajo de los 4.65V.

En este caso usaba una fuente de 3A que iba de maravilla cuando se estaba usando solo una de ellas y aún así al conectar un disco duro sata con conexión USB. En este punto la Raspberry Pi 3B+ arrancaba con el dichoso mensaje pero el disco duro no, y muchas veces ni si quiera arrancaba.

Este mensaje aparece al llegar a los 4.65V. Sabiendo esto medimos los pines +5V y GND del puerto GPIO y si, las sospechas se confirman, incluso sin el HDD el voltaje nunca llegaba a los 5V.

Entre las diferentes soluciones pasan por un buen cargador y un buen cable de alimentación. para este caso se decidió poner una fuente de alimentación de PC Usando la salida de 5V que puede entregar hasta 30A lo que es más que suficiente para alimentar las 3 Raspberry del proyecto.

Tampoco funciono...

Para este punto la frustración era máxima. Pero entro en juego una placa basada en el integrado LM2590.

¿Que es el LM2590?

El LM2590 es un circuito integrado regulador de voltaje. Y voltaje es lo que le falta a la Raspberry. Lo más interesante es el potenciómetro con el que podemos regular hasta el voltaje que queramos. Estas son los valores de entrada y salida así como la corriente capaz de entregar:

  • Tensión de entrada: 4V - 40V
  • Tensión de salida: 1.25V - 37V
  • Corriente máxima: 3A

Así que si medimos en los puertos USB 4.80V, con el potenciómetro podremos regular esos 0.20V que nos hacen falta.

Esto no es una regla de tres, para poder conseguir el voltaje adecuado hay que tener en cuenta que solo podemos subir a un máximo de 5.3V según las especificaciones

Para esta Raspberry Pi 3B+ lo he dejado en 5.15V aunque el display muestre 5.25V. También hay que tener en cuenta que este LM2590 alimenta al HDD mecánico y, sobre todo en el arranque, necesita un extra de potencia.

Por el momento he conectado la alimentación de la Raspberry y el HDD así:


Y en la siguiente fotografía se puede ver la medición con el voltímetro del voltaje que sale hacia los dispositivos:

Como se observa son diferentes dependiendo de si tienen carga o no, en fotografía superior se ve como marca los 5.30V pero realmente salen 5.20V.

Al aplicar la carga (RPI 3B+ + HDD + ventiladores) ese valor fluctuá un poco durante el arranque, pero una que ha cargado el sistema y esta en reposo, el voltaje se mantiene a 5.25V que marca el display y los 5.15V que tenemos realmente si medimos con el voltímetro.


Conclusión:

Y ya está! Después de tantos quebraderos de cabeza el modulo LM2590 es la solución que mejor ha funcionado después de varias pruebas entre cargadores y fuentes de PC.

Estamos pendientes de recibir un par de módulos más para las otras 2 Raspberry Pi 3B que están sin funcionar por el mismo problema.

Y bueno hasta aquí hemos llegado esta semana solucionando este pequeño pero insufrible problema "Low Voltage" que estaban sufriendo las Raspberry.

Esto es aplicable a casi todas las Raspberry Pi, tanto para 3 como 4, aunque para esta ultima no hemos realizado ninguna prueba ya que no tenemos ninguna disponible. Pero en casi todos los artículos y foros en los que se ha comentado, parecen tener el mismo problema.

Con esto no queremos decir que las Raspberry tengan ningún problema, pero imagino que intentamos usar cosas que tenemos por casa, como cargadores o en mi caso una fuente de PC un poco "destartalada" y si no hay un tanto un voltaje de 5.1V como la capacidad de entregar hasta 3A, no tendremos un funcionamiento optimo del sistema.

Aquí podemos descargar las hojas de datos (datasheet) de los diferentes chips y partes como cámaras o sensores para Raspberry Pi.

Muchas gracias a todos! Saludos!

Otros articulos sobre la plataforma Raspberry Pi que te pueden interesar:

domingo, 1 de septiembre de 2024

Pantalla OLED 0.96″ I2C con Raspberry Pi 3: Tutorial y monitorización

Monitorear Raspberry con Oled 128x64 I2CMuy buenas a todos y todas amantes de Raspberry Pi!!!!

Hace un tiempo conecte la Raspbeery pi y la pantalla Oled I2C con la librería "lemur", tenéis toda la información en la entrada 'Raspberry Pi 2 con Oled 128x64 I2C'.

Ahora lo quiero aplicar a la Raspberry Pi 3 y añadirlo al ventilador pwm que ya instalamos anteriormente así que aprovecho para darle una actualización a la entrada anteriormente enlazada y añadir algunos pasos más.

La librería que usamos anteriormente está descontinuada ahora la información ahora la información esta en la propia web de Adafruit.

Los cambios son mínimos ya que solo instalando la librería y cambiando las lineas de configuración todo vuelve a funcionar como antes.

Veamos como instalar las librerías relacionadas adafruit-circuitpython-ssd1306.



sudo apt-get install python3-pip	

pip3 install adafruit-circuitpython-ssd1306

sudo apt-get install python3-pil

sudo apt-get install python3-numpy


Para usar pantalla Oled 128x64 I2C hay que importar la librería de la siguiente manera:



import board
import adafruit_ssd1306
from PIL import Image, ImageDraw, ImageFont

# Use for I2C.
i2c = board.I2C()  # uses board.SCL and board.SDA

try:
	disp = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C, reset=RST)
    print("\nAdafruit SSD1306 ok")
except Exception as errors:
	print("\nError Adafruit SSD1306:",str(errors), "\nPlease check Raspi-config\n")
	exit()


Una vez que tenemos la pantalla funcionando estos son los datos que vamos a mostrar:, 


  • IP de la red
  • Uso del CPU
  • Temperatura del procesador
  • Uso de Ram
  • Velocidad del ventilador (PWM)
  • Tiempo que lleva encendido el sistema
  • Sistema operativo
Para conseguir todos estos datos que queremos mostrar en la pantalla usaremos las librerías externas:
  • psutil
  • subprocess
  • sys

Empecemos por la IP


La ip la podemos obtener con subprocess:



    ## Obtiene la ip del equipo
    # @ return String "0.0.0.0"
    def GetIP():
        return str(subprocess.check_output(['hostname', '-I'])).split(' ')[0].replace("b'", "")


Obtenemos la carga de CPU con psutil:


    ## Obtiene la carga de la CPU
    # @ return float
    def GetCPU():
        return psutil.cpu_percent(1)


La temperatura de la CPU con subprocess:


    ## Obtiene la temperatura de la CPU
    # @ return float
    def GetTemp():
        output = subprocess.run(['vcgencmd', 'measure_temp'], capture_output= True)
        temp_str = output.stdout.decode()
        try:
            return float(temp_str.split('=')[1].split('\'')[0])
        except (IndexError, ValueError):
            raise RuntimeError('no se puede obtener temperatura')


La RAM en uso mediante psutil:


    ## Obtiene la cantidad de RAM en uso
    # @ return float
    def GetRAM():
        return psutil.virtual_memory()[2]


El PWM que aplicamos al pin viene nos lo devuelve la clase healt_pwm_class.py:


    ## Obtiene la velocidad del ventilador
    # @ hpc: healt_pwm_class.System_PWM_Fan
    # @ type_ int: 0=Proporcional, 1=Por pasos de temperatura
    # @ return int: valor de pwm aplicado en el pin
    def GetFanPWM(sef, hpc, type_):
    	if type_ == 0:
        	return hpc.Proportional()
	else:
        	return hpc.Stepped()


El sistema operativo lo obtenemos gracias a sys:


    ## Función que devuelve el SO en uso
    # @ return String
    def getOS():
        platforms = {
        'linux1' : 'linux',
        'linux2' : 'linux',
        'darwin' : 'mac',
        'win32' : 'win32'
        }
        if sys.platform not in platforms:
            return sys.platform
        
        return platforms[sys.platform]    


Y por último el tiempo que lleva encendida la maquina con psutil:


    ## Obtiene el tiempo que lleva la maquina encendida
    # @ return String "0d 00h 00m 00s"
    def GetUpTime():
        boot_time_timestamp = psutil.boot_time()
        current_time_timestamp = time.time()
        uptime_seconds = current_time_timestamp - boot_time_timestamp
        uptime_minutes = uptime_seconds // 60
        uptime_hours = uptime_minutes // 60
        uptime_days = uptime_hours // 24
        uptime_str = f"{int(uptime_days)}d {int(uptime_hours % 24)}h {int(uptime_minutes % 60)}m {int(uptime_seconds % 60)}s"
        # print("Uptime: " + uptime_str)
        return uptime_str


Como todas las funciones están en una clase llamada "system_functions_class.py" podemos llamar a estas funciones de manera individual directamente desde la clase de la siguiente manera:


    # Importamos la clase
    from system_functions_class import *
    
    sfc = System_Functions()
	# Retorna la IP del equipo
    ip = sfc.GetIP()
    
    # Retorna la temperatura de la CPU
    cpu_temp =.sfc.GetTemp()
    
    # Imprime los resultados de ip y cpu_temp
    print("IP: {}, CPU temp: {}".format(ip, cpu_temp))
    

¿Como usamos el programa?

Primero clonamos el repositorio rpi3_healt_system desde GitHub. Vamos a nuestra carpeta de proyectos y escribimos:



https://github.com/Peyutron/python-Warehouse/tree/main/Raspberry_Python/rpi3_healt_system


Con el programa en nuestro equipo, el ejecutable principal se llama "main_rpi_healt.py y lo ejecutamos con:


python3 -m main_rpi_healt


Si todo ha ido bien con la instalación en el terminal recibiremos el siguiente mensaje:


Adafruit ssd1306 ok

y en la pantalla se dibujara lo siguiente:


Los datos que se muestran se guardan en un archivo JSON. Esto nos servirá en un futuro para enviar los datos a otros equipos o como consulta de la última vez que se ejecuto el programa. La información se guarda en un archivo llamado healt_datas.json y este es su contenido:


{
    "filename": "healt_datas.json",
    "ip": "192.168.1.39",
    "m0_cpuf": 39,
    "m0_cpul": 0.0,
    "m0_cput": 45.6,
    "m0_os": "linux",
    "m0_raml": 18.5,
    "m0_ut": "0d 4h 48m 55s"
}


Un saludo a todas y todos!!

Aquí tienes otros enlaces de este blog relacionados con Raspberry Pi:

miércoles, 10 de julio de 2024

PyTermTk: Crea interfaces de usuario en la terminal con Python


Buenas a todos! Hoy he descubierto una librería para Python que me ha dejado una espinita. Se llama PyTermTK y es una biblioteca que ofrece una gran variedad de características para crear TUIs (Terminar User Interfaces).
Tiene un gran parecido a TKinter a la hora de diseñar una interfaz y vamos a ver como se instala y ver algunos de sus ejemplos.
PyTermTK también tiene la opción para un diseñador de interfaces llamado ttkDesigner y veremos también como instalarlo y como usarlo.

Instalación de la librería con pip3:


# Instalación

pip3 install pytermtk

Que nos ofrece PyTermTk:

lunes, 1 de julio de 2024

Raspberry Pi 3: Controla un ventilador PWM por temperatura (tutorial Python)

Muy buenas a todos y todas!!!

Como estamos a Julio y se vienen 'las calores', es hora de refrigerar la Raspberry pi 3. Esta es una Raspberry que adquirí de segunda mano y viene sin ningún tipo de refrigeración y eso no es muy recomendable.

Como le voy a dar varios usos (máquina arcade, probar SO etc) puede ser que tenerla sin un disipador no sea lo mejor.

Ya he encargado unos cuantos disipadores en una web chinesca, pero espero que sea valida para estos pequeños accesorios.

También se me ocurrió ponerle un pequeño ventilador conectado a uno de los puertos GPIO de las Raspberry pi. Como los ventiladores son de 5V DC pero no tienen linea PWM, tenemos que crear un pequeño driver con un transistor que controle el PWM.

Primero tenemos que saber cuales son las temperaturas aproximadas que alcanza el procesador. Investigando un poco he encontrado esta tabla, más o menos representativa:


Temperaturas: Sin disipador Con disipador Disipador activo
Sin carga: ~40ºC ~30ºC 25ºC - 30ºC
Carga media: 50ºC - 60ºC 40ºC - 50ºC 30ºC - 40ºC
Carga intensiva: 60ºC - 80ºC 50ºC - 70ºC 40ºC - 60ºC

Tomando esta tabla como referencia crearemos unos perfiles y por último un perfil personalizado.

También se puede añadir un sensor DHT11 para tener una referencia de la temperatura ambiente, pero eso para otro momento, Por el momento nos vamos a centrar en el PWM;

Programaremos en Python y usaremos las librerías RPi.GPIO para el control de los pines GPIO. La librería time para hacer una pausa antes de mostrar los datos y subprocess para capturar la salida de 'vcgencmd' donde nos mostrará el dato de measure_temp.

Con estos datos y con el perfil que tengamos seleccionado aplicará una velocidad u otra al ventilador.

El programa completo se puede descargar desde Github

En este punto ya tenemos la parte de programación. Ahora le toca el turno a la electrónica.

Como queremos mover un ventilador, aunque pequeño, su carga es mucho más que los 15mA que puede entregar el pin de la Raspberry Pi.

Para solucionar esto usaremos un transistor NPN como el BC548 una resistencia de 10Kohm y un diodo 1N4007.

Usaremos el siguiente diagrama:



Una vez tenemos todo conectado tenemos que habilitar los pines de la Raspberry Pi. Tenemos un diagrama de los pines si en el terminal usamos el comando 'pinout'



Este comando también nos dará información como el modelo, SoC, RAM, puertos USB y algunos parámetros más.

Si necesitas más información sobre la placa podemos usar el comando 'raspinfo'

Ahora solo falta que este programa se ejecute al iniciar la máquina. Esto es muy sencillo solo tenemos que añadir una linea en el 'crontab' ejecutando 'sudo crontab -e' que será la encargada de cargar el programa en el inicio del sistema. Añadiremos la siguiente linea:


@reboot sleep 15; /usr/bin/python3 /home/ruta_del_archivo/pwm_fan_rpi3.py > /dev/null


Lo podemos desglosar el comando de la siguiente manera:

  • @reboot sleep 15; -> Iniciara el script cuando se reinicie la maquina y hayan pasado 15 segundos
  • /usr/bin/python3 -> Ruta donde se encuentra Python3
  • home/.../pwm_fan_rpi3.py -> ruta donde se encuentra el script de Python
  • > /dev/null -> mandamos la salida del programa a null

Tengo que añadir que al intentar ejecutar el programa en el sistema RetroPie que tengo instalado este comando no me ha funcionado correctamente, he tenido que cambiar la linea y poner esta:

  
@reboot sleep 15 && python3 /home/pi/Ruta_del_archivo/pwm_fan_rpi3.py > /home/Ruta_para_log/cron.log 2>&1

Por otro lado al cargar el programa me daba muchos errores de las librerías y la única solución que he encontrado es instalar las librerías con sudo. Haciendo esto todo ha funcionado perfectamente iniciando el ventilador al arrancar el sistema.

Y bueno hasta aquí la parte de programación y teoría. Montaremos los componentes y probaremos que tal va el programa.

Advertencia:

A partir de 80°C, la Raspberry Pi 3 comenzará a reducir su velocidad de reloj (thermal throttling) para protegerse del sobrecalentamiento. Esto puede afectar el rendimiento de la placa.

Superar los 85°C durante un período prolongado puede dañar la Raspberry Pi 3.

Fuente:

the-diy-life.com: Connecting a pwm fan to a Raspberry Pi


Otros articulos sobre la plataforma Raspberry Pi que te pueden interesar:

viernes, 15 de diciembre de 2023

IP fija en Raspberry Pi: Configuración paso a paso (tutorial)

Muchas veces cuando estamos montando un pequeño servidor con Raspberry Pi necesitaremos tener una IP estática.

Además esta guía es valida para cualquier Raspberry pi tanto el modelo 1 como el 2, 3, 4 y 5 siempre que se este ejecutando un sistema linux, que es lo más habitual. Pero primero...

¿Que es la IP estática?

La IP es la dirección donde se recibirán los datos de la red, algo parecido a la dirección de casa. No entraremos mucho en detalles pero lo importante es saber que las principales son la IP publica y ,la que nos interesa, IP privada.

Esta IP privada es la que tenemos en nuestra red de casa. Podríamos decir que el punto medio entre estas dos redes es el router, que es el que se encarga de direccionar los paquetes desde la IP Publica a nuestro ordenador.

De esta manera si estas en estas viendo este blog, solo se muestra en tu pc/movil y no en todos los equipos que tengas en casa.

¿Por qué necesitas una IP Estática en tu Raspberry pi?

Tener una dirección estática nos ofrece ventajas como que tu dispositivo sea fácil de encontrar en la red, tener un acceso remoto consistente, muy útil para SSH, domotica o VPN, mayor seguridad, con firewalls más precisos y la configuración de dispositivos de red, como DHCP, que es el caso que nos ocupa.

Primero tenemos que abrir una terminal en tu Raspberry Pi aunque si vas a montar un servidor, seguramente puedas conectarte con la Raspberry Pi a través de SSH.


lunes, 27 de noviembre de 2023

Instalar RetroPie en Ubuntu

Ayer intente instalar un emulador en el portátil en el que tengo instalada una distribución de Ubuntu y después de probar varios emuladores sueltos, reconozco que me costo hacerlos funcionar.

Y se me vino a la mente RetroPie que es una plataforma de emulación que te permite usar juegos antiguos en una variedad de consolas y sistemas arcade.

Esta es una pequeña guía sobre cómo instalar RetroPie en un sistema con Ubuntu y poder revivir la nostalgia de los juegos retro que a muchos nos acompañaron durante nuestra infancia.

Requisitos previos:

  1. Un sistema con Ubuntu instalado.
  2. Una conexión a Internet estable.
  3. Un controlador (mando) compatible para disfrutar de una experiencia de juego completa.

domingo, 5 de noviembre de 2023

Raspberry pi 2 con Oled 128x64 I2C

 Raspberry Pi ese pequeño ordenador de "bajo coste" que poca presentación necesita. Todos sabemos de su versatilidad y potencia. Raspberry Pi se usa en muchisimos proyectos de robotica, mini PCs, servidores y un largo etcétera. Por su puesto gracias a su puerto GPIO donde podremos conectar otra gran cantidad de sensores y accesorios.

En mi caso tengo un Raspberry Pi 2 Model B. A día de escribir esta entrada ya tiene unos añitos pero sigue dando guerra. La tengo para hacer mis cosillas de programación, también alguna vez como emulador de juegos retro o como es este caso, para cacharrear.

En este caso he añadido una pequeña pantalla Oled de 128x64 y comunicación I2C. Es la que uso generalmente con Arduino y en tiendas de internet lo podemos encontrar por unos 2 o 3 euros.
Si bien es una pantalla pequeña es lo suficiente para poder mostrar cierta información en ella así como imágenes o animaciones.

martes, 7 de febrero de 2023

Mide el tiempo de actividad de tu Raspberry Pi con Python (Código)

Muy buenas a todos y todas!!!

Hace poco que estoy tocando algo de programación con el lenguaje Python para y tenía la duda de cuanto tiempo estaba encendida conectada a una batería o powerbank.

La Raspberry en cuestión es un modelo 2B con algunos añitos a sus espaldas pero que arranca como una campeona!

En cuanto a la batería, no se exactamente cual es su capacidad, debe rondar los 10.000mA con 5 baterías 18650 recicladas de portátil, (unos 2000mA por unidad) Así que me puesto a investigar y este sería el código para que cuente un segundo y lo guarde en un archivo de texto.

Para que no sobreescibiera el archivo cada vez que arranque la Raspberry, el nombre del archivo empieza con la hora y luego el nombre del archivo.


from datetime import datetime
import time
d = datetime.now().strftime("%H%M%S")
namefile = d + "_readme.txt"
print(namefile)

try:

	with open(namefile, 'w') as f.write('Archivo nuevo creado!')
except FileNotFoundError:
	print("no se crea el archivo :(")

inicio = time.time()

time.time.process_time()

contador = 0

while True:
	contador = time.time() - inicio
    #print ("segundo: %02d" % ( contador) )
    time.sleep(1)
    with open(namefile, 'a) as f: 
    f.write("\nsegundo: %02d" % ( contador) )
    

El archivo creado tendrá el siguiente formato:



Archivo nuevo creado!
segundo: 00
segundo: 01
segundo: 02

El resultado han sido 61445 segundos, unas 17 horas. Eso si con apenas carga de trabajo ya que ahora mismo no esta haciendo nada en particular, solo unas pruebas que estoy realizando.

Si bien no es la mejor forma, por el momento para mi propósito que es tener una estimación del tiempo que pueden alimentar las baterías una Raspberry Pi cumple su función a la perfección.

Evidentemente estos datos cambiaran dependiendo del modelo de Raspberry y el pack de báterias que siempre tiene que entregar 2A para no tener problemas de "Undervoltage".

Saludos!!!

Otros articulos sobre Raspberry Pi y Python que te pueden parecer interesantes:

domingo, 19 de noviembre de 2017

Usos para Raspberry Pi

Logo Raspberry PiMuy buenas a todos y todas!!!

Esta publicación va con un poco de retraso... ya tenía la Raspberry Pi 2 desde hacia bastante tiempo, pero como la tenia en otros usos y no he podido hacerle una entrada en el blog como se merece.

En principio esta entrada va a ser un poco presentación de la placa.
Vamos a echar un vistazo a las distintas posibilidades que nos ofrece: