Raspberry
Raspberry
Raspberry
En el proyecto precedente, "Controlando leds con una Raspberry PI", hemos visto como trabajar
con las entradas y las salidas de una Raspberry PI a través de un pequeño programa de tipo
terminal. Esta vez veremos un programa con interfaz gráfica, que permite de activar 3 relés y ver
el estado de 3 entradas digitales.
Como en el caso anterior este proyecto es mas bien un ejemplo de integración entre electrónica y
software, pueden estudiarlo para conocer la tecnología empleada, modificarlo o usarlo como
inspiración para desarrollar proyectos más complejos.
Si necesitan instalar desde 0 il sistema operativo en vuestra Raspberry PI les aconsejo de leer
nuevamente mi artículo anterior "Controlando leds con una Raspberry PI" donde explico en modo
detallado como bajar el software NOOBS, instalarlo y actualizarlo.
Antes de proseguir les cuento que actualmente estoy usando una Raspberry PI modelo 3, sin
necesidad de conectar un monitor, teclado o mouse porque la veo y la controlo en modo remoto a
través de mi red WiFi con el programa VNC. Es muy cómodo de usar y además es gratis. En la
Raspberry, el VNC está ya instalado mientras que en el PC hay que bajarlo e instalarlo. Una vez
instalado y activado en la Raspberry, les aconsejo de ir a la configuración del modem / router WiFi
y de dar una dirección IP fija a la Raspberry (en mi caso por ejemplo puse 192.168.0.90) en modo
tal que el DHCP asigne siempre la misma dirección a la Raspberry y no tener que buscar el IP cada
vez que la encendemos.
Volviendo al proyecto, hacer un programa con interfaz gráfica (GUI: graphical user interface) tiene
su complejidad. Para lograrlo conviene apoyarse a una librería software ya existente. Existen
librerías gráficas de muchos tipos pero al final de cuentas, todas ellas sirven para crear las clásicas
ventanas que estamos acostumbrados a ver y a usar en las pantallas de nuestros ordenadores.
Hay librerías que están proyectadas para funcionar con un determinado sistema operativo mientras
que otras pueden funcionar con más de uno de ellos. Adoptar una librería en lugar de otra depende
de varios factores como por ejemplo el lenguaje de programación que queremos usar, el sistema
operativo, si están ya incorporadas en ambientes de desarrollo visual, la complejidad y la potencia
que necesitamos, la "portabilidad del código" y otros factores.
Si usamos Python con Linux, que es el sistema operativo de la Raspberry PI, la elección se
simplifica bastante: las librerías más populares son PyQt (derivada de QT), PyGTK (derivada de
GTK+), wxPython (derivada de wxWidgets) e Tkinter (derivada de Tcl/Tk). Esta última es la
menos sofisticada pero al mismo tiempo la más liviana y fácil de usar. Tkinter funciona con Linux,
iOS y también con Windows. Además, se encuentra ya incorporada en la distribución de Python, sin
necesidad de ser instalada aparte. Por estos motivos, la adoptaremos para nuestro primer programa
gráfico.
El hardware
Empecemos con el hardware: 3 botones y 3 relés. Para los botones usaremos el mismo circuito del
proyecto anterior pero esta vez las resistencias estarán conectadas a masa mientras que los
pulsadores a positivo como podemos ver en la figura. De esta forma la lógica será positiva: en
reposo las entradas de la Raspberry se encuentran a masa y cuando activamos los botones, pasan a
positivo. La lógica de la Raspberry PI es de 3,3V por lo tanto nuestro positivo no debe superar esta
tensión. El modo más simple es el de usar los 3,3V ya disponibles en el pin 17 del conector
principal de la Raspberry.
Para los relés necesitamos una alimentación separada cuya tensión dependerá de la bobina de los
relés. Yo he usado relés de 12V. Para activarlos podemos usar transistores comunes como explico
detalladamente en mi artículo "controlar un relé con un transistor" o con un circuito integrado
ULN2003 que consiste en 7 drivers hechos con transistores en configuración Darlington y del cual
escribiré próximamente un artículo.
Ambas soluciones son correctas pero con el ULN2003 el circuito es más simple de hacer,
especialmente en el caso de necesitar de muchos canales de salida. El ULN2003 lleva ya a bordo los
diodos de protección para la activación de los relés por lo que no es necesario instalarlos
externamente, en paralelo con las bobinas. Debemos solamente conectar el pin 9 del integrado al
positivo que alimenta los relés.
Para escribir el programa usaremos un editor de texto pensado para Python, que se llama Python3
IDLE y que ya se encuentra instalado en nuestra Raspberry PI. Podemos abrirlo desde:
menu principal -> Programming -> Python 3 (IDLE) como podemos ver en la figura siguiente.
Existe mucha documentación on-line sobre IDLE por lo tanto me limitaré solo a los elementos
necesarios para escribir y hacer funcionar el programa. Si lo hemos abierto para verlo, ahora
podemos cerrarlo porque para llegar a él usaremos otro modo que a continuación describo.
Al interno de la carpeta "pi" aparecerá la nueva carpeta llamada "Inventable". Hacemos doble
click sobre ella para ver su contenido. Estará vacía. Con el mismo método anterior, dentro de
"Inventable" podemos crear la carpeta "in_out_gui". En las figuras de este artículo verán otras
carpetas que he creado y que servirán para otros proyectos.
Por ahora no sirven, usaremos solo la carpeta llamada "in_out_gui". Hacemos doble click sobre
"in_out_gui" para posicionarnos dentro de ella y después, apretamos el botón derecho del mouse,
se abrirá un menú contextual en el cual elegiremos:
Create New -> Empty File.
A este nuevo file lo llamaremos "in_out_gui_v1.py".
Haciendo doble click sobre él se abrirá automáticamente el editor IDLE que nos mostrará
lógicamente, un documento vacío porque todavía no hemos escrito nada. El sistema operativo eligió
automáticamente IDLE como editor porque nuestro archivo tiene la extensión "py", típica de los
programas Python.
Ahora escribimos el siguiente texto en el file vacío para verificar que los componentes software
necesarios para nuestro proyecto estén correctamente instalados (la librería gráfica Tkinter y la
librería de gestión de las entradas y las salidas RPi.GPIO).
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import RPi.GPIO as io
import tkinter as tk
from tkinter import ttk
Una vez hecho esto probamos a ejecutarlo desde el menú RUN -> Run Module del editor o
directamente usando la tecla de función F5.
Si en la pantalla nos aparece el mensaje de la figura, sin indicaciones de error, quiere decir que todo
está funcionando bien y podemos escribir nuestro programa.
A continuación les muestro la primera versión completa del programa y sucesivamente explicaré
cada parte de él. Ustedes pueden escribirlo todo a mano (es un buen ejercicio para familiarizarse
con el lenguaje) o copiarlo y pegarlo en el documento vacío.
Para mayor claridad, he usado instrucciones muy simples y evitando técnicas de programación
avanzadas (como por ejemplo objetos). Les recuerdo que Python divide lógicamente los bloques de
un programa con dos puntos seguidos por la identación del código (sangría) y que es mejor que
esta esté hecha con una cantidad igual de espacios (por norma 4 espacios). No mezclemos espacios
y tabulaciones en el mismo programa porque nos dará un error.
Para probar el programa apretamos la tecla F5 (RUN). Debería aparecer una ventana como la que
vemos en la figura siguiente:
Haciendo click con el mouse sobre los botones de la ventana podemos activar o desactivar los relés
mientras que accionando los pulsadores físicos veremos el cambio de estado de las entradas
respectivas en el programa.
Estos dos renglones sirven para decirle a linux que el file en cuestión es un programa Python
(también llamado script) y que debe ser ejecutado a través del interprete Python. El segundo renglón
dice al interprete de codificar el programa en formato UTF-8 (Unicode Transformation Format, 8
bit).
"""----------------------------------------------------------------------------
Project: In/Out with GUI (graphical user interface)
File: in_out_gui_v1.py
Version: 1.0
Purpose: Controlar 3 entradas y 3 salidas
Author: Gabriel Rapetti / Inventable.eu
Created: 21/10/2017
Copyright: Creative Commons (CC) BY-NC-SA
-------------------------------------------------------------------------------
"""
Los renglones entre grupos de tres comillas (""") son una zona para escribir comentarios y serán
ignorados durante la ejecución del programa por parte del interprete Python. También se pueden
hacer comentarios poniendo el símbolo # al inicio de cada renglón pero la comillas permiten de
crear comentarios que después generarán automáticamente documentación técnica del proyecto. Por
este motivo se usan en las descripciones más importantes del programa. Yo generalmente, creo un
espacio de presentación inicial donde agrego datos generales del proyecto (nombre, autor, fecha,
etc.).
import RPi.GPIO as io
import tkinter as tk
from tkinter import ttk
Estos tres renglones importan las librerías que usaremos para nuestro programa: RPi.GPIO para las
entradas y salidas de las Raspberry, Tkinter para la parte gráfica y ttk que es una extensión de
Tkinter.
in1 = 23
in2 = 24
in3 = 25
out1 = 17
out2 = 27
out3 = 22
io.setmode(io.BCM)
io.setwarnings(False)
io.setup(in1,io.IN)
io.setup(in2,io.IN)
io.setup(in3,io.IN)
io.setup(out1,io.OUT)
io.setup(out2,io.OUT)
io.setup(out3,io.OUT)
Esta parte del programa configura los puertos 23, 24 y 25 del microcontrolador como entradas y los
puertos 17, 27 y 22 como salidas.
def check_inputs():
if io.input(in1):
label1.config(bg = '#FD4')
else:
label1.config(bg = '#BBB')
if io.input(in2):
label2.config(bg = '#FD4')
else:
label2.config(bg = '#BBB')
if io.input(in3):
label3.config(bg = '#FD4')
else:
label3.config(bg = '#BBB')
root.after(50, check_inputs)
Aquí tenemos una función de Python. Se reconoce por la palabra clave "def" seguida por el
nombre de la función y una zona entre paréntesis donde poder pasar parámetros. En este caso no
hay nada entre paréntesis porque no es necesario pasar algún parámetro. Esta función controla las
entradas in1, in2, in3 del micro (que son variables asignadas a los puertos 23, 24 y 25 del micro) y
en base a su estado lógico (alto o bajo) cambia el color de fondo de las label1, label2 y label3. Las
labels son rectángulos con un texto dentro. Pueden ser de color o trasparentes. Serán creadas más
adelante. El último renglón (root.after) dice al programa de retornar a esta función después de 50
milisegundos ("50" pasado como parámetro y que se calcula en milisegundos) . De esta forma se
logra obtener un control periódico de las entradas.
def on_off1():
if push_button1.cget("bg")=='#FD4':
push_button1.config(bg = '#DDD')
io.output(out1,0)
else:
push_button1.config(bg = '#FD4')
io.output(out1,1)
def on_off2():
if push_button2.cget("bg")=='#FD4':
push_button2.config(bg = '#DDD')
io.output(out2,0)
else:
push_button2.config(bg = '#FD4')
io.output(out2,1)
def on_off3():
if push_button3.cget("bg")=='#FD4':
push_button3.config(bg = '#DDD')
io.output(out3,0)
else:
push_button3.config(bg = '#FD4')
io.output(out3,1)
Estas son tres funciones casi iguales, con la diferencia que cada una de ellas trabaja con cada botón
que activan los relés. Son llamadas automáticamente cuando apretamos uno de los botones
diseñados en la pantalla. Como tenemos un solo botón para activar y desactivar cada relé, este
trabaja como un flip flop de tipo "T" (o toggle), es decir, si el relé está activado, cuando lo
tocamos lo desactivamos y viceversa. Para obtener este resultado, el programa lee el color del
botón, si este es '#FD4' (encendido) lo apaga poniendo el color '#DDD' (apagado) y al mismo
tiempo cambia el estado lógico de la salida, por ejemplo io.output(out1,0). Si por el contrario está
apagado (color = '#DDD') lo enciende. Existen diferentes modos de trabajar con los colores en
Python, en este programa uso la notación hexadecimal simplificada donde cada dígito es uno de
los colores RGB, por lo tanto '#000' es negro y '#FFF' es blanco.
root = tk.Tk()
root.title("In/Out Panel")
root.geometry("270x110")
En esta parte creamos la ventana principal de nuestro programa que mide 270 pixel por 110 pixel y
las tres labels que servirán para ver el estado de las entradas. El color inicial de ellas será
"desactivado" (bg = '#BBB'). La sigla "bg" significa background color.
push_button1 = tk.Button(root, text = "OUT 1", width = 6, command = on_off1)
push_button1.place(x = 20, y = 60)
Aquí creamos los botones que activarán los relés. Observen el comando "command = on_off" que
sirve para hacer la llamada automática cuando hacemos "click" con el mouse a una de las tres
funciones "on_off" que hemos visto antes y que gestionan los botones.
check_inputs()
root.mainloop()
El primer renglón es una llamada a la función chek_inputs() que lee las entradas por primera vez,
después no será más necesario llamarla desde aquí porque la misma función de lectura de las
entradas se llamará a si misma.
Para terminar root.mainloop() es el ciclo principal del programa. Este lo mantiene vivo,
gestionando los eventos que llegan a él (por ejemplo las acciones del mouse o el timer para leer las
entradas). El ciclo se interrumpe definitivamente cuando hacemos click sobre la cruz, en alto de
nuestra ventana, terminando el programa.
En la segunda parte de este artículo veremos una nueva versión del programa, más flexible y
modular, gracias al uso de matrices y de ciclos "for".
Hasta la próxima!!
Gabriel
Artículos relacionados:
- Controlemos entradas y salidas de una raspberry pi en python - parte 2
- Controlando leds con una Raspberry PI
- Como controlar un relé con un transistor
Linphone and Raspberry Pi
Last modified by Nicolas Michon on 2019/07/19 14:44
Contents
Using the raspberry pi for video monitoring
Prequisites
Compiling linphone on the rasberry pi
Configuration
Starting linphonec
Automatic start at boot
Common hardware problems
Prequisites
We recommend to use Raspbian, as a base installation to run linphone.
Since linphone heavily makes uses of dual-stack (ipv6 and ipv4) sockets, it is required to enable
ipv6 on the raspberry by doing (as root):
Configuration
First run linphonec once in order to configure your SIP account, so that you can place calls to your
raspberry from another place (typically the linphone app on android or iOS!). We recommend to use
our free sip.linphone.org service, on which accounts can be created using this online form.
cd OUTPUT/no-ui/bin
./linphonec
[.....]
You may also, within the linphonec command prompt, set the sound card to use for capturing sound.
The raspberry-pi has no microphone, but if your plan is to plug a USB camera onto the raspberry
pi, it probably has a built-in microphone. To tell linphonec to use the microphone from the usb
camera, use the "soundcard list" and "soundcard use" commands to select the sound card index to
use.
Now open ~/.linphonerc file with an editor (vim, nano...) in order to tweak a few things:
In section [sound], set
echocancellation=0
Indeed, echo cancellation is not needed, our raspberry pi has no speaker. No need to spend cpu
cycles on this.
In section [video], set vga video size to achieve decent quality, compatible with the pi's
processing capabilities:
size=vga
720p is also possible but the pi2 cpu is a bit too slow for this image format with VP8 codec. svga
tends to work not so bad as well.
Turn on ICE, in section [net] section:
stun_server=stun.linphone.org
firewall_policy=3
Starting linphonec
You can then launch linphonec in background mode in with auto-answer mode. We assume the
current directory is already in the OUTPUT/no-ui/bin directory.
export PATH=$PATH:`pwd`
linphonecsh init -a -C -c ~/.linphonerc -d 6 -l /tmp/log.txt
Notice the "-d 6 -l /tmp/log.txt" which are there to tell linphonec to output all debug messages
into /tmp/log.txt. Looking into this file might be useful should any trouble arrive.
To stop it, do:
linphonecsh exit