Sie sind auf Seite 1von 262

Libera tu innovación

Freenove es una plataforma de electrónica de código abierto.


www.freenove.com
Atención

Cuando compra o usa Freenove Ultimate Starter Kit para Raspberry Pi, tenga en cuenta lo siguiente:
 Este producto contiene piezas pequeñas. Ingerirlos u operarlos de forma inadecuada pueden causar
infecciones graves y la muerte. Busque atención médica inmediata cuando ocurrió el accidente.
 No permita que niños menores de 3 años jueguen con este producto o cerca de él. Coloque este producto
donde los niños menores de 3 años no puedan acceder.
 No permita que los niños carezcan de la capacidad de usar este producto en forma segura sin el cuidado de los padres.
 Nunca use este producto y sus piezas cerca de una toma de corriente alterna u otros circuitos para evitar el
riesgo potencial de descarga eléctrica.
 Nunca use este producto cerca de ningún líquido y fuego.
 Mantenga alejados los materiales conductores de este producto.
 Nunca almacene ni use este producto en ningún entorno extremo, como extremo frío o calor, alta humedad,
etc.
 Recuerde apagar los circuitos cuando no esté en uso este producto o cuando lo deje.
 No toque ninguna parte móvil y giratoria de este producto mientras está en funcionamiento.
 Algunas partes de este producto pueden calentarse al tacto cuando se usan en ciertos diseños de circuitos. Esto
es normal. La operación incorrecta puede causar un sobrecalentamiento excesivo.
 Usar este producto que no esté de acuerdo con la especificación puede causar daños al producto.

A cerca de

Freenove es una plataforma de electrónica de código abierto. Freenove se compromete a ayudar al cliente a
realizar rápidamente la idea creativa y los prototipos del producto, facilitando el inicio para los entusiastas de la
programación y la electrónica y lanzando productos innovadores de código abierto. Nuestros servicios incluyen:
 Componentes electrónicos y módulos
 Kits de aprendizaje para Arduino
 Kits de aprendizaje para Raspberry
 Kits de aprendizaje para Arduino de Tecnología
 Kits de robots
 Herramientas auxiliares para creaciones

Nuestro código y circuito son de código abierto. Puede obtener los detalles y la información más reciente
visitando los siguientes sitios web:
http://www.freenove.com
https://github.com/freenove

Sus comentarios y sugerencias son muy bien recibidos, y envíelos a la siguiente dirección de correo
electrónico:
support@freenove.com
Referencias

Puede descargar los bocetos y las referencias utilizadas en este producto en los siguientes sitios web:
http://www.freenove.com
https://github.com/freenove
Si tiene alguna dificultad, puede enviar un correo electrónico al soporte técnico para obtener ayuda.

Las referencias de este producto se denominan Freenove Ultimate Starter Kit para Raspberry Pi, que incluye las
siguientes carpetas y archivos:
 Ficha de datos Ficha de datos para los componentes electrónicos y sus módulos
 Código Código para experimentar
 Readme.txt Instrucciones

Apoyo

Freenove proporciona asistencia técnica gratuita y rápida, que incluye pero no se limita a:
 Problemas de calidad de los productos
 Problemas al usar productos
 Preguntas para el aprendizaje y la tecnología
 Opiniones y sugerencias
 Ideas y pensamientos

Por favor envíe un correo electrónico a:


support@freenove.com
En un día hábil, generalmente le respondemos dentro de las 24 horas.

Copyright (Derechos de autor)

Freenove se reserva todos los derechos de este libro. No se permiten copias o plagios para fines de uso
comercial.
El código y el circuito implicados en este producto se publican como Creative Commons Attribution ShareAlike
3.0. Esto significa que puede usarlos en sus propios trabajos derivados, en parte o completamente, siempre y
cuando también adopte la misma licencia. La marca Freenove y el logotipo de Freenove son propiedad de
Freenove Creative Technology Co., Ltd y no pueden utilizarse sin un permiso formal.
█ www.freenove.com Contents I

Contents

Contenidos:
Prefacio......................................................................... 1
Raspberry Pi .......................................................................................................................................................... 1
GPIO Tablero de extensión .................................................................................................................................. 4
Módulo de potencia para tablero ........................................................................................................................ 5
Código C y código Python..................................................................................................................................... 6

Capítulo 0 Preparación................................................. 7
Paso 0.1 Instalar el Sistema................................................................................................................................. 7
Paso 0.2 Instalar WiringPi ................................................................................................................................. 14
Paso 0.3 Obtener el código de experimento ..................................................................................................... 17
Paso 0.4 Código Editor ....................................................................................................................................... 18
Siguiente ............................................................................................................................................................ 23

Capítulo 1 LED ............................................................ 24


Proyecto 1.1 Blink (Parpadeo)............................................................................................................................. 24

Capítulo 2 Button & LED ............................................ 32


Proyecto 2.1 Botón y LED................................................................................................................................... 32
Proyecto 2.2 MINI tabla lámpara....................................................................................................................... 37

Capítulo3 LEDBar Graph(Barra Gráfica) .................... 43


Proyecto 3.1 Luz de agua corriente ................................................................................................................... 43

Capítulo 4 Analog & PWM ......................................... 48


Proyecto 4.1 Breathing LED(RespiraciónLED)................................................................................................... 48

Capítulo 5 RGB LED.................................................... 54


Proyecto 5.1 Color full LED ............................................................................................................................... 54

Capítulo 6 Buzzer(Zumbador) ................................... 60


Proyecto 6.1 Doorbell(Timbre)........................................................................................................................ 60
Proyecto 6.2 Alertor............................................................................................................................................66

Capítulo 7 PCF8591 ................................................... 71


Proyecto 7.1 Leer el Voltaje de un Potenciómetro...........................................................................................71

Capítulo 8 Potenciómetro & LED .............................. 82


Proyecto 8.1 Soft Luz ................................................................................................................................... 82
II Contents www.freenove.com █

Capítulo 9 Potenciómetro & RGBLED...................... 87


Proyecto 9.1 Colorful................................................................................................................................... 87

Capítulo 10 Fotoresistor & LED................................94


Proyecto 10.1 NightLamp ............................................................................................................................ 94

Capítulo 11 Thermistor ......................................... 100


Proyecto 11.1 Thermometer ..................................................................................................................... 100

Capítulo 12 Joystick ...............................................106


Proyecto 12.1 Joystick .................................................................................................................................106

Capítulo 13 Motor & Driver ................................... 113


Proyecto 13.1 Control Motor with Potentiometer.................................................................................... 113

Capítulo14 Relay & Motor..................................... 124


Proyecto 14.1.1 Relay & Motor ................................................................................................................. 124

Capítulo 15 Servo ...................................................131


Proyecto 15.1 Servo Sweep........................................................................................................................ 131

Capítulo 16 Stepping Motor .................................. 140


Proyecto 16.1 Stepping Motor ................................................................................................................... 140

Capítulo 17 74HC595 & LEDBar Graph .................. 151


Proyecto 17.1 Flowing Water Light........................................................................................................... 151

Capítulo 18 74HC595 & 7-segment display...........159


Proyecto18.1 7-segment display. ...............................................................................................................159
Proyecto 18.2 4-Digit 7-segment display .................................................................................................. 165

Capítulo 19 74HC595 & LED Matrix ...................... 177


Proyecto 19.1 LED Matrix........................................................................................................................ 177

Capítulo 20 LCD1602 ............................................ 188


Proyecto 20.1 I2C LCD1602........................................................................................................................ 188

Capítulo 21 Hygrothermograph DHT11 ............... 198


Proyecto21.1 Hygrothermograph............................................................................................................. 198

Capítulo 22 Matrix Keypad ................................... 205


Proyecto 22.1 Matrix Keypad.....................................................................................................................205
█ www.freenove.com Contents III

Capítulo 23 Sensor de movimiento infrarrojo ..... 215


Proyecto23.1 Sense LED......................................................................................................................... 215

Capítulo 24 Rango ultrasónico. ........................... 221


Proyecto 24.1 Ultrasonic Ranging (Rango Ultrasónico)......................................................................... 221

Capítulo 25 Sensor de posición MPU6050 ..........229


Proyecto25.1 Read MPU6050............................................................................................................... 229

Capítulo 26 WebIOPi & IOT ................................. 237


Proyecto 26.1 Remote LED ................................................................................................................... 237

Capítulo 27 Placa de circuito de soldadura.........242


Proyecto 27.1 Soldar un Zumbador ..................................................................................................... 242
Proyecto 27.2 Solder a Flowing Water Light (Soldar una luz de agua corriente)................................... 246

¿Que sigue?........................................................ 254


█ www.freenove.com Preface 1

Prefacio
Si quieres convertirte en un creador, es posible que hayas oído hablar de Pi Raspberry o Arduino antes. Si no, no
importa. Al hacer referencia a este tutorial, puede relajarse usando Raspberry Pi para crear docenas de proyectos
electrónicos interesantes, y gradualmente darse cuenta de la diversión de usar Raspberry Pi para completar
trabajos creativos.
Raspberry Pi y Arduino tienen muchos seguidores en el mundo. Están interesados en la exploración, la innovación
y el bricolaje, y contribuyeron con una gran cantidad de códigos de fuente abierta de alta calidad, circuitos y una
gran base de conocimientos. Para que podamos realizar nuestra propia creatividad de manera más eficiente
mediante el uso de estos recursos gratuitos. Por supuesto, también puedes aportar tu propia fuerza al recurso.
Raspberry Pi, diferente de Arduino, es más como un centro de control con un sistema operativo completo, que
puede deasl con más tareas al mismo tiempo. Por supuesto, también puede combinar las ventajas de ellos para
hacer algo creativo.
Generalmente, un proyecto de Raspberry Pi consiste en código y circuito. Si está familiarizado con el lenguaje
informático y está muy interesado en el módulo electrónico. Entonces este tutorial es muy adecuado para ti.
Explicará, de fácil a difícil, los conocimientos de programación de Raspberry Pi, el uso de varios tipos de
componentes electrónicos y módulos de sensores y su principio de funcionamiento. Y asignamos aplicaciones de
escena para la mayor parte del módulo. Proporcionamos el código de las versiones en lenguaje C y Python para
cada proyecto, por lo tanto, ya sea que usted sea un usuario del lenguaje C o un usuario del lenguaje Python,
puede captar fácilmente el código en este tutorial. El kit de soporte, Freenove Ultimate Starter Kit para Raspberry
Pi, contiene todos los componentes electrónicos y módulos necesarios para completar estos proyectos. Después
de completar todos los proyectos en este tutorial, también puede usar estos componentes y módulos para lograr
su propia creatividad, como la casa inteligente, el automóvil inteligente y el robot. Además, si tiene alguna
dificultad o pregunta sobre este tutorial y el kit, siempre puede solicitarnos asistencia técnica rápida y gratuita.

Raspberry Pi

Raspberry Pi (llamado RPi, RPI, RasPi, el texto que estas palabras se usarán alternativamente detrás), una
microcomputadora con el tamaño de una tarjeta, barrió rápidamente el mundo desde su debut. Es ampliamente
utilizado en estaciones de trabajo de escritorio, centros de medios, hogares inteligentes, robots e incluso
servidores, etc. Puede hacer casi cualquier cosa, lo que continúa atrayendo a los fanáticos a explorarlo. Raspberry
Pi solía ejecutarse en el sistema Linux y, junto con el lanzamiento de Windows 10 IoT, también podemos
ejecutarlo en Windows. Raspberry Pi (con interfaces para USB, red, HDMI, cámara, audio, pantalla y GPIO), como
microordenador, puede ejecutarse en modo línea de comando y modo de sistema de escritorio. Además, es fácil
de operar al igual que Arduino, e incluso puede operar directamente el GPIO de la CPU. Hasta ahora, Pi Raspberry
tiene 7 versiones: tipo A, tipo A +, tipo B, tipo B +, tipo B de segunda generación, tipo B de tercera generación y
versión Zero, respectivamente. Los cambios en las versiones van acompañados de un aumento y actualizaciones
en el hardware. Un tipo y tipo B, la primera generación de productos, se han detenido debido a varias razones.
Las otras versiones son populares y activas, y lo más importante es que son consistentes en el orden y número de
pines, lo que hace que la compatibilidad de los dispositivos periféricos mejore mucho entre las diferentes
versiones. Los proyectos en este tutorial, sin ninguna nota especial, están usando Raspberry Pi 3 Modelo B
(RPi3B), que es compatible con Raspberry Pi A +, B +, 2B y Zero.
2 Preface www.freenove.com █

El diagrama esquemático de RPi3B se muestra a continuación:


Imagen práctica de un Raspberry Pi 3 Model B: Modelo diagrama de un Raspberry Pi 3 Modelo B:

Hardware interface diagrama de un RPi3B se muestra a continuación:

GPIO
Connector
USB
Connector
Display
Connector

Ethernet
Power Connector
Connector

HDMI Camera Audio


Connector Connector Connector
█ www.freenove.com Preface 3

GPIO

Entrada / salida de propósito general; en este caso específico, los pines en la Raspberry Pi y lo que puedes hacer
con ellos. Llamado así porque puedes usarlos para todo tipo de propósitos; la mayoría se puede usar como
entradas o salidas, dependiendo de su programa.
Al programar los pines GPIO hay dos formas diferentes de referirse a ellos: numeración GPIO y numeración
física.
NUMERACIÓN DE GPIO
Estos son los pines GPIO cuando la computadora los ve. Los números no tienen ningún sentido para los
humanos, saltan por todos lados, así que no hay una manera fácil de recordarlos. Necesitará una referencia
impresa o un tablero de referencia que se ajuste a los alfileres.
NUMERACIÓN FÍSICA
La otra forma de referirse a los pines es simplemente contando hacia arriba y hacia abajo desde el pin 1 en la
parte superior izquierda (más cercana a la tarjeta SD). Esta es la 'numeración física' y se ve así:

Cada pin se define de la siguiente manera:

Para obtener más información sobre la definición de GPIO, consulte http://pinout.xyz/


4 Preface www.freenove.com █

GPIO Tablero de extensión


Cuando usamos RPi para hacer el experimento, es mejor que usemos GPIO, que es más conveniente para
extender todos los puertos IO de RPi directamente al tablero de pan. La secuencia GPIO en Extension Board es
idéntica a la secuencia GPIO de RPi. Como el GPIO de diferentes versiones de RPi es diferente, las extensiones
correspondientes también son diferentes. Por ejemplo, una placa de extensiones GPIO con 40 pines está
conectada a RPi de la siguiente manera:

Imagen real práctica de la conexión:


█ www.freenove.com Preface 5

Entre ellos, GPIO Extension Board y su esquema se muestran a continuación:


GPIO Placa de extensión Definición de los pins

Módulo de potencia para tablero

Breadboard Power Module es una placa independiente que puede proporcionar alimentación independiente de
5 V o 3,3 V para la placa de pan cuando se usa para construir el circuito, lo que puede evitar una carga excesiva
que dañe la potencia de RPi. El diagrama esquemático del módulo de potencia de tablero se muestra a
continuación:

Power Switch Power Light


USB Output Port
Power Jack

Output voltage selection Output voltage selection

Output port for power Output port for power


6 Preface www.freenove.com █

La conexión entre el módulo de alimentación de tablero y la placa de procesamiento se muestra a continuación:

Código C y código Python

Los experimentos que implican la programación en este tutorial usan lenguajes C y python. Y cada tipo de código
se explicará en detalle, y será seguido por comentarios detallados para garantizar que pueda dominarlo
rápidamente. Además, también puede contactarnos directamente para obtener otra ayuda.
Estos códigos están disponibles en http://github.com/freenove.
█ www.freenove.com Capítulo 0 Preparation 7

Capítulo 0 Preparación
¿Por qué es "Capítulo 0"? Porque en el código del programa, todos los recuentos están comenzando desde 0.
Elegimos seguir esta regla (solo una broma). En este capítulo, haremos algunos trabajos de preparación
necesarios: inicie su Pi Raspberry e instale algunas bibliotecas necesarias. Si su Raspberry Pi se puede iniciar
normalmente y usar normalmente, puede omitir este capítulo.

Paso 0.1 Instalar el Sistema

En primer lugar, instale un sistema para su RPi.

Listado de componentes

Componentes requeridos
Raspberry Pi 3B x1 5V/2A Adaptador de alimentación

Micro USB Cable x1 Micro SD Tarjeta(TF Tarjeta)x1; Tarjeta Reader x1

Además, RPi también necesita un cable de red utilizado para conectarlo a una red de área amplia.
Todos estos componentes son necesarios. Entre ellos, la fuente de alimentación se requiere al menos 5 V / 2 A,
porque la falta de suministro de energía dará lugar a muchos problemas anormales, incluso daños a su RPI. Así
que el uso de la fuente de alimentación con 5V / 2A es muy recomendable. SD Card Micro (capacidad
recomendada de 8 GB o más) es un disco duro para RPi, que se utiliza para almacenar el sistema y los archivos
personales. En los últimos experimentos, la lista de componentes con un RPi contendrá estos componentes
requeridos, usando solo RPi como representante en lugar de presentar detalles.
8 Capítulo 0 Preparación www.freenove.com █

Componentes opcionales
1. Pantalla con interfaz HDMI
2.Mouse y teclado con interfaz USB
Entre estos componentes opcionales, la pantalla como pantalla para RPi. Si no, no importa, puede usar un
escritorio remoto de su PC personal para controlar su RPi. El mouse y el teclado son iguales; si no, use el
escritorio remoto y comparta un juego de teclado y mouse personal con la PC.
Herramienta de software
Se necesita una herramienta Disk Imager Win32 para escribir el sistema. Puede descargarlo e instalarlo visitando
el sitio web: https://sourceforge.net/projects/win32diskimager/
Seleccionar sistema
Visite el sitio web oficial de RPi (https://www.Raspberry Pi.org/), haga clic en "Descargas" y elija descargar
"RASPBIAN". RASPBIAN con el apoyo de RPI es un sistema operativo basado en Linux, que contiene una serie de
contenidos necesarios para RPi. Recomendamos el sistema RASPBIAN a los principiantes. Todos los experimentos
en este tutorial se operan bajo el sistema RASPBIAN.

Después de la descarga, extraiga el archivo con el sufijo (.img). La preparación está lista para comenzar a hacer el sistema.
█ www.freenove.com Capítulo 0 Preparación 9

Escribir el sistema en la tarjeta Micro SD

Primero, coloque su tarjeta Micro SD en el lector de tarjetas y conéctela al puerto USB de la PC. A continuación,
abra Win32 Disk Imager, elija la letra correcta de su tarjeta Micro SD (aquí está "J"), abra el archivo extraído
".img" y luego haga clic en "Escribir".

Step2. open the extracted “.img” file Step1. choose the correct letter

Step3. Click Write to write the system

Comience Raspberry Pi

Después de que el sistema se haya escrito correctamente, saque la tarjeta Micro SD y colóquela en la ranura para
tarjeta de RPi. Luego, conecte RPi a la pantalla a través del HDMI, al mouse y al teclado a través del puerto USB,
al cable de red a través de la interfaz de la tarjeta de red y a la fuente de alimentación. Entonces tu RPi comienza
inicialmente. Más tarde, debe ingresar el nombre de usuario y la contraseña para iniciar sesión. El nombre de
usuario predeterminado: Pi; contraseña: frambuesa Ingrese e inicie sesión. Después de iniciar sesión, puede
ingresar a la siguiente interfaz.
10 Capítulo 0 Preparación www.freenove.com █

Ahora, ha instalado con éxito el sistema operativo RASPBIAN para su RPi.

Escritorio remoto

Si no tiene una pantalla, un mouse y un teclado de repuesto para su RPi, puede usar un escritorio remoto para
compartir una pantalla, teclado y mouse con su PC. A continuación se muestra cómo usar el escritorio remoto
para controlar RPi bajo el sistema operativo Windows.
Instalar Xrdp Services
Primero, descargue el software de la herramienta Masilla. Su dirección oficial: http://www.putty.org/
O descárgalo aquí:http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
Luego, use el cable para conectar su RPi a los enrutadores de su PC LAN para asegurar que su PC y su RPi estén en
la misma LAN. Luego coloque la tarjeta TF del sistema preparada antes en la ranura del RPi y encienda la fuente
de alimentación esperando el RPi de inicio. Más tarde, ingrese el terminal de control del enrutador a la dirección
IP de consulta denominada "raspberrypi". Por ejemplo, he consultado que mi dirección IP RPi es "192.168.1.108".
Luego abra Putty, ingrese la dirección, seleccione SSH y luego haga clic en "ABRIR", como se muestra a
continuación:

Step1: enter Step2:


the IP address Select SSH

Step3:
Click “OPEN”
█ www.freenove.com Capítulo 0 Preparación 11

Aparecerá una advertencia de seguridad en el primer inicio de sesión. Simplemente haga click“YES”.

Luego habrá una interfaz de inicio de sesión (RPi nombre de usuario predeterminado: pi; la contraseña:
frambuesa). Cuando ingrese la contraseña, no se mostrará en la pantalla, pero esto no significa que no ingresó.
Después de la salida correcta, presione "Enter" para confirmar.

Luego ingrese la línea de comando de RPi, lo que significa que ha iniciado sesión exitosamente en el modo de
línea de comando RPi.
12 Capítulo 0 Preparación www.freenove.com █

A continuación, instale un servicio xrdp, un servidor de protocolo de escritorio remoto (rdp) de código abierto
para RPi. Escriba el siguiente comando, luego presione enter para confirmar:
sudo apt-get install xrdp
Más tarde, la instalación comienza.
█ www.freenove.com Capítulo 0 Preparación 13

Ingrese "Y", presione la tecla "Enter" para confirmar.


Una vez completada la instalación, puede usar las aplicaciones de escritorio remoto de Windows para iniciar
sesión en su RPi.
Inicie sesión en el escritorio remoto de Windows
Use "WIN + R" o la función de búsqueda, abra la aplicación de escritorio remoto "mstsc.exe" en Windows, ingrese
la dirección IP de RPi y luego haga clic en "Conectar".

Más tarde, habrá una pantalla de inicio de sesión xrdp. Ingrese el nombre de usuario y la contraseña de RPi (RPi
nombre de usuario predeterminado: pi; contraseña: frambuesa) y haga clic en "Aceptar".

Más tarde, puede ingresar al sistema de escritorio RPi.


14 Capítulo 0 Preparación www.freenove.com █

Aquí, ha utilizado con éxito el inicio de sesión de escritorio remoto para RPi.
Luego continúe haciendo algunos trabajos de preparación: instale un archivo de la biblioteca GPIO para su RPi.

Paso 0.2 Instalar WiringPi

WiringPi es una biblioteca de acceso GPIO escrita en C para BCM2835 / BMC2836 / BMC2837 utilizada en
Raspberry Pi. Se lanzó bajo la licencia GNU LGPLv3 y se puede usar desde C y C ++ y muchos otros idiomas con
envoltorios adecuados (Ver a continuación). Está diseñado para ser familiar para las personas que han usado el
sistema de "cableado" Arduino. (Para obtener más detalles, consulte http://wiringpi.com/ )

Pasos de instalación de WiringPi

abre la terminal:

Terminal
█ www.freenove.com Capítulo 0 Preparación 15

Siga estos pasos y comandos para completar la instalación.


Ingrese el siguiente comando en la terminal para obtener WiringPi usando GIT:
git clone git://git.drogon.net/wiringPi
Una vez completada la operación de clonación, vaya a la carpeta de cableado y actualice la última WiringPi.
cd wiringPi
git pull origin
Ejecute el archivo de compilación para comenzar la instalación.
./build
El nuevo guión de compilación lo compilará e instalará por usted; utiliza el comando sudo en un punto, por lo que
es posible que desee inspeccionar el script antes de ejecutarlo.
Ejecute el comando gpio para verificar la instalación:
gpio -v
gpio readall
Eso debería darte confianza de que está funcionando bien.
16 Capítulo 0 Preparación www.freenove.com █

Numeración WiringPi GPIO


A diferencia de los dos tipos mencionados anteriormente de números de serie de GPIO, se volvió a numerar el
número de serie RPi GPIO del WiringPi. Aquí tenemos tres tipos de modo de número GPIO: basado en el número
de chips BCM, basado en el número de secuencia física y basado en el cableadoPi. La correspondencia entre estos
tres números GPIO se muestra a continuación:

(Para más detalles sobre wiringPi, consulte https://projects.drogon.net/raspberry-pi/wiringpi/pins/ )


█ www.freenove.com Capítulo 0 Preparación 17

También puede usar el siguiente comando para ver su correspondencia.


gpio readall

Para más detalles sobre wiringPi, consulte http://wiringpi.com/ .

Paso 0.3 Obtenga el código de experimento

Una vez hecho el trabajo anterior, puede visitar nuestro sitio web oficial (http://www.freenove.com) or our
github (https://github.com/freenove) para descargar el último código de experimento. Proporcionamos tanto
el lenguaje C como el código Python para cada experimento con el fin de aplicarlo a usuarios expertos en
diferentes idiomas.
Método para obtener el código:
En
gitelclone
directorio pi del terminal RPi, ingrese el siguiente comando:
https://github.com/freenove/Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi
Coloque el archivo en el directorio de usuario pi / y el archivo de código en
Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi / Code. Hay dos carpetas "código C" y "código Python" que se
usan para almacenar el código C y el código Python de cada experimento por separado.
18 Capítulo 0 Preparación www.freenove.com █

Paso 0.4 Editor de código

vi, nano, Geany

Aquí presentaremos tres tipos de editor de código: vi, nano y Geany. Entre ellos, nano y vi se utilizan para editar
archivos directamente en la terminal, y Geany es un software de edición independiente. Usaremos los tres
editores para abrir un código de ejemplo "Hello.c" respectivamente. Primero para demostrar el uso del editor vi y
nano: Primero, use el comando cd para ingresar la carpeta de código de muestra.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/00.0.0_Hello
Use el editor vi para abrir el archivo "Hello.c", luego presione": q" and “Enter” to exit.
vi Hello.c
Como se muestra a continuación:

Usa el editor nano para abrir el archivo"Hello.c", then press " Ctrl+X " to exit.
nano Hello.c
Como se muestra a continuación:
█ www.freenove.com Capítulo 0 Preparación 19

Use el siguiente comando para compilar el código para generar el archivo ejecutable“Hello”.
gcc Hello.c –o Hello
Use el siguiente comando para ejecutar el archivo ejecutable “Hello”.
sudo ./Hello
Después de la ejecución, "Hello, World!" está impreso en la terminal.

A continuación, aprende a usar el editor de Geany. Use el siguiente comando para abrir Geany en el
archivo de muestra "Hello.c" ruta del directorio de archivos.
geany Hello.c
20 Capítulo 0 Preparación www.freenove.com █

O encuentre y abra Geany directamente en el menú principal del escritorio, y luego haga clic File->Open para
abrir el "Hello.c", o arrastrar "Hello.c" para Geany directamente.
█ www.freenove.com Capítulo 0 Preparación 21

Genera un archivo ejecutable haciendo clic en la barra de menú Build->Build, luego ejecuta el archivo
generado haciendo clic en la barra de menú Build->Execute.

Después de la ejecución, habrá una terminal que imprimirá los caracteres "Hello, World!", Como se muestra a
continuación:

Puede hacer clic en Build-> Set Build Commands para establecer los comandos del compilador. En experimentos
posteriores, usaremos varias opciones de comando del compilador. Si elige usar Geany, necesitará cambiar el
comando del compilador aquí. Como se muestra a continuación:
22 Capítulo 0 Preparación www.freenove.com █

Sumario

Aquí presentamos tres editores de código. También hay muchos otros buenos editores de código, y puedes elegir
el que más te guste. En experimentos posteriores, sobre la ruta de entrada y los comandos de ejecución del
compilador, operaremos los contenidos en la terminal como ejemplos. No enfatizaremos el proceso de edición
del código, pero explicaremos el contenido del código en detalles.
█ www.freenove.com Capítulo 0 Preparación 23

Siguiente

Aquí, todas las preparaciones preliminares han sido completadas. A continuación, combinaremos el RPi y los
componentes electrónicos para hacer una serie de experimentos de fáciles a difíciles y centrarnos en explicar el
conocimiento relevante del circuito electrónico.
24 Capítulo 1 LED www.freenove.com █

Capítulo 1 LED
Este capítulo es el punto de partida del viaje para explorar experimentos electrónicos RPi. Comencemos con simple
“Blink”.

Proyecto 1.1 Blink (parpadeo)

En este proyecto, intentemos utilizar RPi para controlar el parpadeo del LED.

Lista de componentes

Raspberry Pi 3B x1 GPIO Extension Board & Wire x1

BreadBoard x1
█ www.freenove.com Capítulo 1 LED 25

LED x1 Resistor 220Ω x1 Jumper Wire M/M x2

En la lista de componentes, 3B GPIO, Extension Shield Raspberry y Breadboard son necesarios para cada
experimento. Se enumerarán solo en forma de texto.

Conocimiento del componente

LED
LED es un tipo de diodo. El LED brillará solo si el pin largo del LED está conectado al electrodo positivo y el pin
corto está conectado al electrodo negativo.
Esta es también la característica del diodo común. El diodo funciona solo si el voltaje de su electrodo positivo es
más alto que su electrodo negativo.

El LED no se puede conectar directamente a la fuente de alimentación, lo que puede dañar el componente. Una
resistencia con cierta resistencia debe conectarse en serie en el circuito de LED.
Resistor
La unidad de resistencia (R) es el ohmio (Ω). 1MΩ = 1000kΩ, 1kΩ = 1000Ω.
La resistencia es un componente eléctrico que limita o regula el flujo de corriente en un circuito electrónico.
La izquierda es la apariencia de la resistencia. y el derecho es el símbolo de resistencia representado en el
circuito.

Los anillos de color unidos a la resistencia se utilizan para indicar su resistencia. Para obtener más información
sobre el código de color de la resistencia, consulte el apéndice de este tutorial.
26 Capítulo 1 LED www.freenove.com █

Con el mismo voltaje, habrá menos corriente con más resistencia. Y los enlaces entre la corriente, el voltaje y la
resistencia se pueden expresar mediante la siguiente fórmula: I = U / R.
En el siguiente diagrama, la corriente a través de R1 es:I=U/R=5V/10kΩ=0.0005A=0.5mA.

No conecte los dos polos de la fuente de alimentación con baja resistencia, lo que hará que la corriente sea
demasiado alta para dañar los componentes electrónicos.
█ www.freenove.com Capítulo 1 LED 27

Circuito

Desconecte RPi de GPIO Extension Shield primero. Luego construya el circuito de acuerdo con el diagrama del
circuito y el diagrama de conexión del hardware. Una vez que el circuito esté construido y confirmado, conecte
RPi a GPIO Extension Shield. Además, debe evitarse el cortocircuito (especialmente 5V y GND, 3.3V y GND), ya
que el cortocircuito puede causar un funcionamiento anormal del circuito o incluso daños a PRi.
Diagrama esquemático

Conexión de hardware

Debido a que la numeración de GPIO Extension Shield es igual a RPi GPIO, el último diagrama de conexión de
hardware solo mostrará la parte de la placa de prueba y GPIO Extension Shield.
28 Capítulo 1 LED www.freenove.com █

Código
De acuerdo con el circuito, cuando el GPIO17 de salida RPi de alto nivel, el LED se enciende. Por el contrario,
cuando el nivel de salida de GPIO17 RPi es bajo, el LED se apaga. Por lo tanto, podemos permitir que la salida
GPIO17 sea de alto y bajo nivel cíclicamente para que el LED parpadee. Utilizaremos el código C y el código
Python para alcanzar el objetivo.
Código C 1.1.1 Blink
Primero, observe el fenómeno experimental y luego analice el código.

1. Use el comando cd para ingresar 01.1.1_Blink directory of C code.


cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/01.1.1_Blink
2. Utilice el siguiente comando para compilar el código "Blink.c" y generar el archivo ejecutable "Blink". gcc
Blink.c –o Blink -lwiringPi
3. A continuación, ejecute el archivo generado "Blink".
sudo ./Blink
Ahora, el LED comienza a parpadear. Puede presionar "Ctrl + C" para finalizar el programa.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define ledPin 0
5
6 int main(void)
7 {
8 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
9 printf("setup wiringPi failed !");
10 return 1;
11 }
12 //when initialize wiring successfully,print message to screen
13 printf("wiringPi initialize successfully, GPIO %d(wiringPi pin)\n",ledPin);
14
15 pinMode(ledPin, OUTPUT);
16
17 while(1){
18 digitalWrite(ledPin, HIGH); //led on
19 printf("led on...\n");
20 delay(1000);
21 digitalWrite(ledPin, LOW); //led off
22 printf("...led off\n");
23 delay(1000);
24 }
25
26 return 0;
27 }
█ www.freenove.com Capítulo 1 LED 29

GPIO conectado a ledPin en el circuito es GPIO17. Y GPIO17 se define como 0 en el cableadoPi. Entonces, ledPin
debería definirse como el 0 pin. Puede consultar la tabla correspondiente en el Capítulo 0.
#define ledPin 0
En la función principal principal (), inicialice primero el cableadoPi y luego imprima los resultados iniciales. Una
vez que la inicialización falla, salga del programa.
if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
printf("setup wiringPi failed !");
return 1;
}
//when initialize wiring successfully,print message to screen
printf("wiringPi initialize successfully, GPIO %d(wiringPi pin)\n",ledPin);
Después de que el cableado Pi se inicialice correctamente, configure el ledPin en modo de salida. Y luego ingrese el ciclo
while, que es un ciclo sin fin. Es decir, el programa siempre se ejecutará en este ciclo, a menos que se termine afuera.
En este ciclo, use digitalWrite (ledPin,HIGH) para hacer que la salida de ledPin sea de alto nivel, entonces el LED se
enciende. Después de un período de retraso, utilice digitalWrite (ledPin,LOW) para hacer que la salida del ledPin sea de
bajo nivel, el LED se apaga, seguido de un retraso. Repite el ciclo, luego se encenderá el LED blinking.

pinMode(ledPin, OUTPUT);
while(1){
digitalWrite(ledPin, HIGH); //led is turned on
printf("led on...\n");
delay(1000);
digitalWrite(ledPin, LOW); //led is turned off
printf("...led off\n");
delay(1000);
}
Entre ellos, la función de configuración para GPIO se muestra a continuación como:
void pinMode(int pin, int mode);
Esto establece el modo de un pin en INPUT, OUTPUT, PWM_OUTPUT o GPIO_CLOCK. Tenga en cuenta que
solo el cableado del pin 1 (BCM_GPIO 18) admite la salida PWM y solo el cableado del pin 7 (BCM_GPIO 4)
admite los modos de salida CLOCK.
Esta función no tiene efecto cuando está en modo Sys. Si necesita cambiar el modo pin, puede hacerlo con el
programa gpio en un script antes de iniciar su programa
void digitalWrite (int pin, int value);
Escribe el valor HIGHT(ALTO) o LOW(BAJO) (1 o 0) en el pin determinado que debe haberse establecido previamente como salida.
Para más funciones relacionadas, consulte http://wiringpi.com/reference/ Python Code
1.1.1 Blink(Parpadear)
Net, usaremos el lenguaje Python para que el LED parpadee.
Primero, observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 01.1.1_Blink del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/01.1.1_Blink
2. Use el comando python para ejecutar el código python
python Blink.py
Ahora, el LED comienza a parpadear(Blink).
El siguiente es el código del programa:
30 Capítulo 1 LED www.freenove.com █

1 import RPi.GPIO as GPIO


2 import time
3
4 ledPin = 11 # RPi Board pin11
5
6 def setup():
7 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs based on physical location
8 GPIO.setup(ledPin, GPIO.OUT) # Set ledPin to output mode
9 GPIO.output(ledPin, GPIO.LOW) # Set ledPin low to turn off led
10 print 'using pin%d'%ledPin
11
12 def loop():
13 while True:
14 GPIO.output(ledPin, GPIO.HIGH) # led is turned on
15 print '...led on'
16 time.sleep(1)
17 GPIO.output(ledPin, GPIO.LOW) # led is turned off
18 print 'led off...'
19 time.sleep(1)
20
21 def destroy():
22 GPIO.output(ledPin, GPIO.LOW) # led is turned off
23 GPIO.cleanup() # Release resource
24
25 if __name__ == '__main__': # Program start from here
26 setup()
27 try:
28 loop()
29 except KeyboardInterrupt: # When “Ctrl+C” is pressed, the subprogram destroy()
30 will be executed.
31 destroy()

En la configuración de subfunción (), GPIO.setmode (GPIO.BOARD) se utiliza para establecer el número de serie
de GPIO según la ubicación física del pin. El GPIO17 usa el pin11 de la placa, por lo tanto, defina el ledPin como 11
y configure el ledPin como modo de salida ((output low(nivel bajo de salida)).
ledPin = 11 # RPi Board pin11

def setup():
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(ledPin, GPIO.OUT) # Set ledPin to output mode
GPIO.output(ledPin, GPIO.LOW) # Set ledPin to low level to turn off led
print 'using pin%d'%ledPin
En la subfunción de loop (), hay un ciclo while, que es un ciclo sin fin. Es decir, el programa siempre se
ejecutará en este ciclo, a menos que se termine afuera. En este ciclo, configure el nivel de salida de ledPin alto,
luego LED es encendido. Después de un período de tiempo de retardo, establezca el nivel bajo de salida del
ledPin, luego se apaga el LED, que es seguido por un retraso. Repite el ciclo, luego se encenderá el LED blinking.
█ www.freenove.com Capítulo 1 LED 31

def loop():
while True:
GPIO.output(ledPin, GPIO.HIGH) # led is turned on
print '...led on'
time.sleep(1)
GPIO.output(ledPin, GPIO.LOW) # led is turned off
print 'led off...'
time.sleep(1)

Finalmente, cuando finalice el programa, se ejecutará la subfunción, el LED se apagará y luego se liberará el puerto
IO. Si cierra directamente la terminal del programa, el programa también terminará, pero la función destroy () no se
ejecutará. Por lo tanto, los recursos de GPIO no se liberarán, en el mensaje de advertencia puede aparecer la
próxima vez que use GPIO. Por lo tanto, no es una buena costumbre cerrar directamente la terminal del programa.
def destroy():
GPIO.output(ledPin, GPIO.LOW) # led is turned off
GPIO.cleanup() # Release resource
Acerca de RPi.GPIO:
RPi.GPIO
Este es un módulo de Python para controlar GPIO en una Raspberry Pi. Incluye función de salida básica y entrada
función de GPIO, y la función utilizada para generar PWM.
GPIO.setmode(mode)
Establezca el modo para el número de serie del pin GPIO.
mode=GPIO.BOARD, que representa el número de serie del pin GPIO se basa en la ubicación física de RPi.
mode=GPIO.BCM, que representa el número de serie del pin se basa en la CPU del chip BCM.
GPIO.setup(pin,mode)
Establecer el pin para el modo de entrada o el modo de salida. “pin” for the GPIO pin, “mode” for INPUT or OUTPUT.
GPIO.output(pin,mode)
Establecer el pin para el modo salida(output ). “pin” for the GPIO pin, “mode” for HIGH (high level) or LOW (low level).

Para más funciones relacionadas con RPi.GPIO, consulte:


https://sourceforge.net/p/raspberry-gpio-python/wiki/Examples/
32 Capítulo 2 Botón y LED www.freenove.com █

Capítulo 2 Botón y LED


Por lo general, hay tres partes esenciales en un dispositivo de control automático completo: ENTRADA, SALIDA y
CONTROL. En la última sección, el módulo LED es la parte de salida y RPI es la parte de control. En aplicaciones
prácticas, no solo dejamos que las luces LED se enciendan, sino que hacemos que el dispositivo detecte el
entorno, recibamos instrucciones y luego realicemos las acciones apropiadas, como encender el LED, emitir un
pitido, etc.

Control: RPI,
Arduino, MCU
and etc.

Entrada: Salida:
botones, interruptores, LED, zumbador, motor
sensores y etc. y etc.put:

A continuación, construiremos un sistema de control simple para controlar el LED a través de un botón.

Proyecto 2.1 Botón & LED

En el experimento, controle el estado del LED a través de un botón. Cuando se presiona el botón, el LED se
encenderá, y cuando se lo suelte, el LED se apagará.

Listado de componentes

Raspberry Pi 3B x1 LED x1 Resistor 220Ω Resistor 10kΩ Push


GPIO Extension Board & Wire x1 x1 x2 button x1
BreadBoard x1

Jumper M/M x5

Conocimiento del componente

Push button
El botón tiene 4 pines. Se conectan dos pines a la izquierda y el derecho es similar a la izquierda, que se muestra a
continuación:
█ www.freenove.com Capítulo 2 Botón y LED 33

Cuando se presiona el botón, el circuito se enciende.

Circuito

Diagrama esquemático

Hardware de conexión
34 Capítulo 2 Botón y LED www.freenove.com █

Código

Este experimento está diseñado para saber cómo usar el botón para controlar el LED. Primero debemos leer el
estado del botón y luego determinar si encender el LED de acuerdo con el estado del botón.
C Code 2.1.1 ButtonLED
Primero, observe los fenómenos experimentales, luego analice el código.
1. Use el comando cd para ingresar al directorio 02.1.1_ButtonLED del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/02.1.1_ButtonLED
2. Utilice el siguiente comando para compilar el código "ButtonLED.c" y generar el archivo ejecutable "ButtonLED"
gcc ButtonLED.c –o ButtonLED-lwiringPi
3. Luego ejecute el archivo generado "ButtonLED".
sudo ./ButtonLED
Más tarde, la ventana de la terminal continúa imprimiendo los caracteres "led off ...". Presione el botón, luego se
enciende el LED y luego la ventana de terminal imprime el "led encendido ...". Suelte el botón, luego el LED se apaga y
luego la ventana de terminal imprime el "led apagado ...". Puede presionar "Ctrl + C" para finalizar el programa.
El siguiente es el código del programa:

1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define ledPin 0 //define the ledPin
5 #define buttonPin 1 //define the buttonPin
6
7 int main(void)
8 {
9 if(wiringPiSetup() == -1){ //when initialization for wiring fails,print message to
10 screen
11 printf("setup wiringPi failed !");
12 return 1;
13 }
14
15 pinMode(ledPin, OUTPUT);
16 pinMode(buttonPin, INPUT);
17
18 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
19 while(1){
20
21 if(digitalRead(buttonPin) == LOW){ //button has pressed down
22 digitalWrite(ledPin, HIGH); //led on
23 printf("led on...\n");
24 }
25 else { //button has released
26 digitalWrite(ledPin, LOW); //led off
27 printf("...led off\n");
█ www.freenove.com Capítulo 2 Botón y LED 35

28 }
29 }
30 return 0;
31 }

En la conexión del circuito, LED y botón están conectados con GPIO17 y GPIO18 respectivamente, que
corresponden a 0 y 1 respectivamente en WiringPI. Así que define ledPin y buttonPin como 0 y 1 respectivamente.
#define ledPin 0 //define the ledPin
#define buttonPin 1 //define the buttonPin
En el ciclo while de la función principal, use digitalRead (buttonPin) para determinar el estado de Button. Cuando
se presiona el botón, la función devuelve un nivel bajo, el resultado de "si" es verdadero, y luego enciende el LED.
O apague el LED.
if(digitalRead(buttonPin) == LOW){ //button has pressed down
digitalWrite(ledPin, HIGH); //led on
printf("led on...\n");
}
else { //button has released
digitalWrite(ledPin, LOW); //led off
printf("...led off\n");
}
About digitalRead():
int digitalRead (int pin);
Esta función devuelve el valor leído en el pin dado. Será “HIGH”or“LOW”(1 or 0)("ALTO" o "BAJO" (1 o 0))
dependiendo del nivel lógico en el pin.

El código del lenguaje Python se muestra a continuación.


Python Code 2.1.1 ButtonLED
Primero, observe los fenómenos experimentales, luego analice el código.
1. Use el comando cd para ingresar al directorio 01.1.1_btnLED del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/02.1.1_ButtonLED
2. Use el comando Python para ejecutar btnLED.py.
python ButtonLED.py
Más tarde, la ventana del terminal continúa imprimiendo los caracteres "led off ...", presione el botón, luego se
enciende el LED y luego la ventana de terminal imprime el "led encendido ...". Suelte el botón, luego el LED se apaga y
luego la ventana de terminal imprime el "led apagado ...". Puede presionar "Ctrl + C" para finalizar el programa.
El siguiente es el código del programa:

1 import RPi.GPIO as GPIO


2
3 ledPin = 11 # define the ledPin
4 buttonPin = 12 # define the buttonPin
5
6 def setup():
7 print 'Program is starting...'
8 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
36 Capítulo 2 Botón y LED www.freenove.com █

9 GPIO.setup(ledPin, GPIO.OUT) # Set ledPin's mode is output


10 GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
11 input, and pull up to high level(3.3V)
12
13 def loop():
14 while True:
15 if GPIO.input(buttonPin)==GPIO.LOW:
16 GPIO.output(ledPin,GPIO.HIGH)
17 print 'led on ...'
18 else :
19 GPIO.output(ledPin,GPIO.LOW)
20 print 'led off ...'
21
22 def destroy():
23 GPIO.output(ledPin, GPIO.LOW) # led off
24 GPIO.cleanup() # Release resource
25
26 if __name__ == '__main__': # Program start from here
27 setup()
28 try:
29 loop()
30 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
31 will be executed.
32 destroy()

En la configuración de subfunción (), GPIO.setmode (GPIO.BOARD) se usa para establecer el número de serie del GPIO,
que se basa en la ubicación física del pin. Entonces, GPIO17 y GPIO18 corresponden a pin11 y pin12 respectivamente
en el circuito. A continuación, configure ledPin en modo de salida, botónPin en modo de entrada con una resistencia
de extracción.
ledPin = 11 # define the ledPin
buttonPin = 12 # define the buttonPin
def setup():
print 'Program is starting...'
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(ledPin, GPIO.OUT) # Set ledPin's mode is output
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
input, and pull up to high level(3.3V)
En la función de bucle mientras está en circulación, continúe juzgando si se presiona la tecla. Cuando se presiona
el botón, el GPIO.input (buttonPin) regresará al nivel bajo, luego el resultado de "if" es verdadero, ledPin produce
un alto nivel, el LED se enciende. O bien, el LED se apagará.
def loop():
while True:
if GPIO.input(buttonPin)==GPIO.LOW:
GPIO.output(ledPin,GPIO.HIGH)
print 'led on ...'
█ www.freenove.com Capítulo 2 Botón y LED 37

else :
GPIO.output(ledPin,GPIO.LOW)
print 'led off ...'
Ejecute la función destroy (), cierre el programa y libere el recurso. Acerca de la función
GPIO.input ():
GPIO.input()
Esta función devuelve el valor leído en el pin dado. Será “HIGH”or“LOW”("ALTO" o "BAJO") (1 o 0)
dependiendo del nivel lógico en el pin.

Proyecto 2.2 Lámpara de mesa MINI

También utilizaremos un botón, LED y UNO para hacer una lámpara de mesa MINI. Pero la función es diferente:
presione el botón, el LED se encenderá, y presione el botón nuevamente, el LED se apagará.
Primero, aprendamos algo de conocimiento sobre el botón.

Rebote al pulsar el botón(Efecto rebote)

Cuando se presiona un botón, no cambiará de un estado a otro inmediatamente. Debido a la vibración mecánica,
habrá un golpe continuo antes de que se convierta en otro estado. Y la situación de liberación es similar con ese
proceso.
press stable release stable

Ideal state

Virtual state

Por lo tanto, si detectamos directamente el estado del botón pulsador, puede haber varias acciones de presionar y
soltar en un proceso de presión. El golpeteo inducirá a error a la operación de alta velocidad del microcontrolador para
causar muchos juicios falsos. Entonces, necesitamos eliminar el impacto del golpeteo. Nuestra solución es: juzgar el
estado del botón varias veces. Solo cuando el estado del botón se estabiliza después de un período de tiempo, puede
indicar que el botón está presionado.
Este proyecto necesita los mismos componentes y circuitos con la última sección.
38 Capítulo 2 Botón y LED www.freenove.com █

Código

En el experimento, todavía detectamos el estado de Button para controlar el LED. Aquí tenemos que definir una
variable para guardar el estado del LED. Y cuando se presiona el botón una vez, el estado del LED cambiará una
vez. Esto ha logrado la función de la lámpara de mesa.
C Code 2.2.1 Tablelamp(Lámpara de mesa)
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 02.2.1_Tablelamp del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/02.1.1_Tablelamp
2. Utilice el siguiente comando para compilar "Tablelamp.c" y generar el archivo ejecutable "Tablelamp".
gcc Tablelamp.c –o Tablelamp-lwiringPi
3. Tablelamp(Lámpara de mesa). A continuación, ejecute el archivo generado "Tablelamp"("Lámpara de mesa").
sudo ./Tablelamp
Cuando se ejecuta el programa, presione el Botón una vez, luego se enciende el LED. Presione el botón otra vez,
luego el LED se apaga.
1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define ledPin 0 //define the ledPin
5 #define buttonPin 1 //define the buttonPin
6 int ledState=LOW; //store the State of led
7 int buttonState=HIGH; //store the State of button
8 int lastbuttonState=HIGH;//store the lastState of button
9 long lastChangeTime; //store the change time of button state
10 long captureTime=50; //set the button state stable time
11 int reading;
12 int main(void)
13 {
14 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
15 printf("setup wiringPi failed !");
16 return 1;
17 }
18 printf("Program is starting...\n");
19 pinMode(ledPin, OUTPUT);
20 pinMode(buttonPin, INPUT);
21
22 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
23 while(1){
24 reading = digitalRead(buttonPin); //read the current state of button
25 if( reading != lastbuttonState){ //if the button state has changed ,record the
26 time point
27 lastChangeTime = millis();
28 }
█ www.freenove.com Capítulo 2 Botón y LED 39

29 //if changing-state of the button last beyond the time we set,we considered that
30 //the current button state is an effective change rather than a buffeting
31 if(millis() - lastChangeTime > captureTime){
32 //if button state is changed ,update the data.
33 if(reading != buttonState){
34 buttonState = reading;
35 //if the state is low ,the action is pressing
36 if(buttonState == LOW){
37 printf("Button is pressed!\n");
38 ledState = !ledState;
39 if(ledState){
40 printf("turn on LED ...\n");
41 }
42 else {
43 printf("turn off LED ...\n");
44 }
45 }
46 //if the state is high ,the action is releasing
47 else {
48 printf("Button is released!\n");
49 }
50 }
51 }
52 digitalWrite(ledPin,ledState);
53 lastbuttonState = reading;
54 }
55 return 0;
56 }

Este código se enfoca en eliminar el golpeteo del botón. Definimos varias variables para guardar el estado del LED
y el botón. Luego lea constantemente el estado del botón en while () y determine si el estado ha cambiado. Si lo
es, registre este punto de tiempo.
reading = digitalRead(buttonPin); //read the current state of button
if( reading != lastbuttonState){
lastChangeTime = millis();
}

millis()
Devuelve la cantidad de milisegundos desde que la placa Arduino comenzó a ejecutar el programa actual.
Luego, de acuerdo con el punto de tiempo registrado, juzgue la duración del cambio de estado del botón. Si la
duración excede el tiempo de captura (tiempo de amortiguación) que establecemos, indica que el estado del
botón ha cambiado. Durante ese tiempo, while () sigue detectando el estado del botón, por lo que si hay un
cambio, el punto de tiempo de cambio se actualizará. Entonces la duración será juzgada de nuevo hasta que la
duración de allí sea estable excede el tiempo que establecemos.
40 Capítulo 2 Botón y LED www.freenove.com █

if(millis() - lastChangeTime > captureTime){


//if button state is changed ,update the data.
if(reading != buttonState){
buttonState = reading;
Finalmente, juzgue el estado de Button. Y si es de bajo nivel, el estado cambiante indica que se presiona el botón,
si el estado es de alto nivel, entonces se suelta el botón. Aquí, cambiamos el estado de la variable LED y luego
actualizamos el estado del LED.
if(buttonState == LOW){
printf("Button is pressed!\n");
ledState = !ledState;
if(ledState){
printf("turn on LED ...\n");
}
else {
printf("turn off LED ...\n");
}
}
//if the state is high ,the action is releasing
else {
printf("Button is released!\n");
}

Python Code 2.2.1 Tablelamp


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 02.2.1_Tablelamp del código de Python
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/02.2.1_Tablelamp
2. Utilice el comando python para ejecutar el código python "Tablelamp.py". python
Tablelamp.py
Cuando se ejecuta el programa, presione el Botón una vez, luego se enciende el LED. Presione el botón otra vez,
luego el LED se apaga.
1 import RPi.GPIO as GPIO
2
3 ledPin = 11 # define the ledPin
4 buttonPin = 12 # define the buttonPin
5 ledState = False
6
7 def setup():
8 print 'Program is starting...'
9 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
10 GPIO.setup(ledPin, GPIO.OUT) # Set ledPin's mode is output
11 GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
12 input, and pull up to high
13
14 def buttonEvent(channel):
█ www.freenove.com Capítulo 2 Botón y LED 41

15 global ledState
16 print 'buttonEvent GPIO%d'%channel
17 ledState = not ledState
18 if ledState :
19 print 'Turn on LED ... '
20 else :
21 print 'Turn off LED ... '
22 GPIO.output(ledPin,ledState)
23
24 def loop():
25 #Button detect
26 GPIO.add_event_detect(buttonPin,GPIO.FALLING,callback = buttonEvent,bouncetime=300)
27 while True:
28 pass
29
30 def destroy():
31 GPIO.output(ledPin, GPIO.LOW) # led off
32 GPIO.cleanup() # Release resource
33
34 if __name__ == '__main__': # Program start from here
35 setup()
36 try:
37 loop()
38 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
39 will be executed.
40 destroy()

RPi.GPIO nos proporciona una función simple y efectiva para eliminar el jitter, que es GPIO.add_event_detect ().
Utiliza la función de devolución de llamada. Una vez que detecta que el buttonPin tiene una acción especificada
FALLING, ejecuta la función especificada buttonEvent (). En la función buttonEvent, cada vez que se invierte el
ledState, se actualizará el estado del LED.
def buttonEvent(channel):
global ledState
print 'buttonEvent GPIO%d'%channel
ledState = not ledState
if ledState :
print 'Turn on LED ... '
else :
print 'Turn off LED ... '
GPIO.output(ledPin,ledState)

def loop():
#Button detect
GPIO.add_event_detect(buttonPin,GPIO.FALLING,callback = buttonEvent,bouncetime=300)
42 Capítulo 2 Botón y LED www.freenove.com █

while True:
pass
Por supuesto, también puede usar la misma idea de programación del código C anterior para lograr este objetivo.

GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback, bouncetime=200)


Esta es una función de detección de eventos. El primer parámetro especifica el puerto IO que se detectará. El
segundo parámetro especifica la acción que se detectará. El tercer parámetro especifica un nombre de
función, la función se ejecutará cuando se detecte la acción especificada. Y el cuarto parámetro se utiliza para
establecer el tiempo de fluctuación de fase.
█ www.freenove.com Capítulo 3 Gráfico LEDBar 43

Capítulo 3 Gráfico LEDBar


Hemos aprendido cómo controlar el parpadeo de un LED, y luego aprenderemos cómo controlar un número de LED.

Proyecto 3.1 Flowing Water Light(Proyecto 3.1 Luz de agua corriente)

En este experimento, usamos varios LED para hacer que fluya la luz del agua.

Listado de componentes

Raspberry Pi 3B x1 LED bar graph x1 Resistor 220Ω x10


GPIO Extension Board & Wire x1
BreadBoard x1

Jumper M/M x11

Conocimiento del componente

Permítanos aprender sobre las características básicas de los componentes para usarlos mejor.
LED bar graph
El gráfico de barras LED es un componente de integración compuesto por 10 LED. Hay dos filas de alfileres en su parte
inferior.
44 Capítulo 3 Gráfico LEDBar www.freenove.com █

Circuito

La etiqueta de red se utiliza en el siguiente diagrama de circuito, y los pines con la misma etiqueta de red están
conectados a la fuente.
Schematic diagram

Hardware connection

En este circuito, el cátodo del LED está conectado a GPIO, que es diferente del circuito frontal. Por lo tanto, el LED
se encenderá cuando GPIO muestre bajo nivel en el programa.
█ www.freenove.com Capítulo 3 Gráfico LEDBar 45

Código

Este experimento está diseñado para hacer una lámpara de agua. Primero encienda el primer LED y luego apáguelo. Luego enciende
el segundo LED, y luego apáguelo ....... Hasta que se encienda el último LED, entonces se apaga. Y repite el
proceso para lograr el efecto de la luz del agua que fluye.
C Code 3.1.1 LightWater
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 03.1.1_LightWater del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/03.1.1_LightWater
2. Use el siguiente comando para compilar "LightWater.c" y generar el archivo ejecutable "LightWater".
gcc LightWater.c –o LightWater-lwiringPi
3. Luego ejecute el archivo generado "LightWater".
sudo ./LightWater
Después de ejecutar el programa, verá que el Gráfico LEDBar comienza con el flujo de agua para encenderse de
izquierda a derecha y luego de derecha a izquierda.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #define leds 10
4 int pins[leds] = {0,1,2,3,4,5,6,8,9,10};
5 void led_on(int n)//make led_n on
6 {
7 digitalWrite(n, LOW);
8 }
9
10 void led_off(int n)//make led_n off
11 {
12 digitalWrite(n, HIGH);
13 }
14
15 int main(void)
16 {
17 int i;
18 printf("Program is starting ... \n");
19 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
20 printf("setup wiringPi failed !");
21 return 1;
22 }
23 for(i=0;i<leds;i++){ //make leds pins' mode is output
24 pinMode(pins[i], OUTPUT);
25 }
26 while(1){
27 for(i=0;i<leds;i++){ //make led on from left to right
46 Capítulo 3 Gráfico LEDBar www.freenove.com █

28 led_on(pins[i]);
29 delay(100);
30 led_off(pins[i]);
31 }
32 for(i=leds-1;i>-1;i--){ //make led on from right to left
33 led_on(pins[i]);
34 delay(100);
35 led_off(pins[i]);
36 }
37 }
38 return 0;
39 }
En el programa, configure GPIO0-GPIO9 en el modo de salida. Luego, en el interminable ciclo "while" de la función
principal, use dos ciclo "for" para realizar la luz del flujo de agua de izquierda a derecha y de derecha a izquierda.
while(1){
for(i=0;i<leds;i++){ //make led on from left to right
led_on(pins[i]);
delay(100);
led_off(pins[i]);
}
for(i=leds-1;i>-1;i--){ //make led on from right to left
led_on(pins[i]);
delay(100);
led_off(pins[i]);
}
}

Python Code 3.1.1 LightWater


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 03.1.1_LightWater del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/03.1.1_LightWater
2. Utilice el comando de Python para ejecutar el código de Python "LightWater.py".
python LightWater.py
Después de ejecutar el programa, verá que el Gráfico LEDBar comienza con el flujo de agua para encenderse de
izquierda a derecha y luego de derecha a izquierda.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3 ledPins = [11, 12, 13, 15, 16, 18, 22, 3, 5, 24]
4 def setup():
5 print 'Program is starting...'
6 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
7 for pin in ledPins:
8 GPIO.setup(pin, GPIO.OUT) # Set all ledPins' mode is output
█ www.freenove.com Capítulo 3 Gráfico LEDBar 47

9 GPIO.output(pin, GPIO.HIGH) # Set all ledPins to high(+3.3V) to off led


10 def loop():
11 while True:
12 for pin in ledPins: #make led on from left to right
13 GPIO.output(pin, GPIO.LOW)
14 time.sleep(0.1)
15 GPIO.output(pin, GPIO.HIGH)
16 for pin in ledPins[10:0:-1]: #make led on from right to left
17 GPIO.output(pin, GPIO.LOW)
18 time.sleep(0.1)
19 GPIO.output(pin, GPIO.HIGH)
20 def destroy():
21 for pin in ledPins:
22 GPIO.output(pin, GPIO.HIGH) # turn off all leds
23 GPIO.cleanup() # Release resource
24 if __name__ == '__main__': # Program start from here
25 setup()
26 try:
27 loop()
28 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
29 will be executed.
30 destroy()
En el programa, primero defina 10 pines conectados al LED, y configúrelos en el modo de salida en la configuración de funciones
secundarias (). Luego, en la función de bucle (), use dos ciclos "para" para relizar la luz del agua que fluye de derecha a izquierda y de
izquierda a derecha. Entre ellos, ledPins [10: 0: -1] se usa para atravesar elementos de ledPins en orden inverso.

def loop():
while True:
for pin in ledPins: #make led on from left to right
GPIO.output(pin, GPIO.LOW)
time.sleep(0.1)
GPIO.output(pin, GPIO.HIGH)
for pin in ledPins[10:0:-1]: #make led on from right to left
GPIO.output(pin, GPIO.LOW)
time.sleep(0.1)
GPIO.output(pin, GPIO.HIGH)
48 Capítulo 4 Analógico y PWM www.freenove.com █

Capítulo 4 Analógico y PWM


En el estudio anterior, hemos sabido que el botón tiene dos estados: presionado y liberado, y el LED tiene
encendido / apagado, ¿cómo ingresar a un estado intermedio? ¿Cómo se genera un estado intermedio para que
el LED sea "semi brillante"? Eso es lo que vamos a aprender.
Primero, aprendamos cómo controlar el brillo de un LED.

Proyecto 4.1 Breathing LED(Respiración LED)

La luz de respiración, es decir, el LED se apaga y enciende gradualmente, gradualmente de encendido a apagado,
al igual que "respirando". Entonces, ¿cómo controlar el brillo de un LED? Utilizaremos PWM para lograr este
objetivo.

Listado de componentes

Raspberry Pi 3B x1 LED x1 Resistor 220Ω x1


GPIO Extension Board & Wire x1
BreadBoard x1

Jumper M/M x2

Conocimiento del circuito

Analog & Digital


La señal analógica es una señal continua en tiempo y valor. Por el contrario, la señal digital es una señal discreta
en tiempo y valor. La mayoría de las señales en la vida son señales analógicas, por ejemplo, la temperatura en un
día está cambiando continuamente, y no aparecerá un cambio repentino directamente de 0 ℃ a 10 ℃, mientras
que la señal digital es un cambio de salto, que puede ser directamente de 1 a 0.
Su diferencia puede ilustrarse con la siguiente figura.

En la aplicación práctica, a menudo usamos la señal binaria como señal digital, es decir 0 y 1. La señal binaria solo tiene
█ www.freenove.com Capítulo 4 Analógico y PWM 49

dos formas (0 o 1), por lo que tiene una gran estabilidad. Y la señal digital y la señal analógica se pueden convertir
entre sí.
PWM
PWM, concretamente Width Modulation Pulse, es una técnica muy efectiva para usar señales digitales para
controlar circuitos analógicos. Los procesadores comunes no pueden emitir señales analógicas directamente. La
tecnología PWM lo hace muy conveniente para lograr este propósito.
La tecnología PWM utiliza pines digitales para enviar cierta frecuencia de ondas cuadradas, es decir, la salida de
alto nivel y bajo nivel que duran un tiempo alternativamente. El tiempo total para cada conjunto de nivel alto y
bajo generalmente es fijo, lo que se denomina período (el recíproco del período es la frecuencia). El tiempo de
salida de alto nivel generalmente se llama ancho de pulso, y el porcentaje de ancho de pulso se denomina ciclo de
trabajo.
Cuanto más larga sea la salida del último nivel, mayor será el ciclo de trabajo y mayor será el voltaje
correspondiente en la señal analógica. Las siguientes figuras muestran cómo el voltaje de las señales analógicas
varía entre 0V-5V (nivel alto es 5V) correspondiente al ancho del impulso 0% -100%:

Cuanto mayor sea el ciclo de trabajo de PWM, mayor será la potencia de salida. Entonces podemos usar PWM
para controlar el brillo del LED, la velocidad del motor de CC, etc.
De lo anterior se desprende que PWM no es analógico real, y el valor efectivo de la tensión es equivalente al
correspondiente analógico. entonces, podemos controlar la potencia de salida del LED y otros módulos de salida
para lograr diferentes efectos.
En RPi, solo GPIO18 tiene la capacidad de generar PWM con una precisión de 10 bits, es decir, el 100% del ancho
del pulso se puede dividir en 210 = 1024 partes iguales.
50 Capítulo 4 Analógico y PWM www.freenove.com █

Circuito

Schematic diagram Hardware connection

Código

Este experimento está diseñado para hacer que la salida PWM GPIO18 con ancho de pulso aumente de 0% a
100%, y luego se reduzca de 100% a 0% gradualmente.
C Code 4.1.1 BreathingLED
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 04.1.1_BreathingLED del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/04.1.1_BreathingLED
2. Use el siguiente comando para compilar "BreathingLED.c" y genere el archivo ejecutable "BreathingLED".
gcc BreathingLED.c –o BreathingLED -lwiringPi
3. A continuación, ejecute el archivo generado "BreathingLED"
sudo ./ BreathingLED
Después de ejecutar el programa, verá que el LED se enciende y se apaga y luego se apaga y se enciende
gradualmente como la respiración.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #define ledPin 1 //Only GPIO18 can output PWM
4 int main(void)
5 {
6 int i;
7 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
8 printf("setup wiringPi failed !");
█ www.freenove.com Capítulo 4 Analógico y PWM 51

9 return 1;
10 }
11
12 pinMode(ledPin, PWM_OUTPUT);//pwm output mode
13 while(1){
14 for(i=0;i<1024;i++){
15 pwmWrite(ledPin, i);
16 delay(2);
17 }
18 delay(300);
19 for(i=1023;i>=0;i--){
20 pwmWrite(ledPin, i);
21 delay(2);
22 }
23 delay(300);
24 }
25 return 0;
26 }
Como solo GPIO18 de RPi tiene capacidad de hardware para emitir PWM, el ledPin debe definirse como 1 y
establecer su modo de salida como PWM_OUTPUT en función del gráfico correspondiente a los pines.
pinMode(ledPin, PWM_OUTPUT);//pwm output mode
Hay dos ciclos "For"("para")en el próximo ciclo “while”("mientras") interminable. El primero hace que el PWM de
salida ledPin sea de 0% a 100% y el segundo hace que el PWM de salida ledPin pase de 100% a 0%.
while(1){
for(i=0;i<1024;i++){
pwmWrite(ledPin, i);
delay(2);
}
delay(300);
for(i=1023;i>=0;i--){
pwmWrite(ledPin, i);
delay(2);
}
delay(300);
}
También puede ajustar la tasa de cambio de estado del LED cambiando los parámetros de la función de delay()
(retardo ()) en el ciclo "For"("para").
void pwmWrite (int pin, int value) ;
Escribe el valor en el registro PWM para el pin dado. El Raspberry Pi tiene un pin PWM a bordo, pin 1
(BCM_GPIO 18, Phys 12) y el rango es 0-1024. .
52 Capítulo 4 Analógico y PWM www.freenove.com █

Python Code 4.1.1 BreathingLED


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 04.1.1_BreathingLED del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/04.1.1_BreathingLED
2. Use el comando python para ejecutar el código python“BreathingLED.py”.
python BreathingLED.py
Después de ejecutar el programa, verá que el LED se enciende y se apaga y luego se apaga y se enciende
gradualmente como la respiración.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3 LedPin = 12
4 def setup():
5 global p
6 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
7 GPIO.setup(LedPin, GPIO.OUT) # Set LedPin's mode is output
8 GPIO.output(LedPin, GPIO.LOW) # Set LedPin to low
9 p = GPIO.PWM(LedPin, 1000) # set Frequece to 1KHz
10 p.start(0) # Duty Cycle = 0
11 def loop():
12 while True:
13 for dc in range(0, 101, 1): # Increase duty cycle: 0~100
14 p.ChangeDutyCycle(dc) # Change duty cycle
15 time.sleep(0.01)
16 time.sleep(1)
17 for dc in range(100, -1, -1): # Decrease duty cycle: 100~0
18 p.ChangeDutyCycle(dc)
19 time.sleep(0.01)
20 time.sleep(1)
21 def destroy():
22 p.stop()
23 GPIO.output(LedPin, GPIO.LOW) # turn off led
24 GPIO.cleanup()
25 if __name__ == '__main__': # Program start from here
26 setup()
27 try:
28 loop()
29 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
30 will be executed.
31 destroy()

El LED está conectado al puerto IO llamado GPIO18. Y LedPin se define como 12 y se establece en modo de salida
de acuerdo con el cuadro correspondiente para los pines. Luego, cree una instancia de PWM y configure la
frecuencia de PWM en 1000HZ, el ciclo de trabajo inicial en 0%.
█ www.freenove.com Capítulo 4 Analógico y PWM 53

LedPin = 12
def setup():
global p
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(LedPin, GPIO.OUT) # Set LedPin's mode is output
GPIO.output(LedPin, GPIO.LOW) # Set LedPin to low
p = GPIO.PWM(LedPin, 1000) # set Frequece to 1KHz
p.start(0) # Duty Cycle = 0
Hay dos ciclos "for"("para") que se usan para realizar la respiración del LED en el siguiente ciclo interminable “while” ("mientras"). El
primero hace que el PWM de salida ledPin sea de 0% a 100% y el segundo hace que el PWM de salida ledPin pase de 100% a 0%.

def loop():
while True:
for dc in range(0, 101, 1): # Increase duty cycle: 0~100
p.ChangeDutyCycle(dc) # Change duty cycle
time.sleep(0.01)
time.sleep(1)
for dc in range(100, -1, -1): # Decrease duty cycle: 100~0
p.ChangeDutyCycle(dc)
time.sleep(0.01)
time.sleep(1)
Las funciones relacionadas de PWM se describen de la siguiente manera:
p = GPIO.PWM(channel, frequency)
Para crear una instancia de PWM:
p.start(dc)
Para iniciar PWM:, donde dc es el ciclo de trabajo(0.0 <= dc <= 100.0)
p.ChangeFrequency(freq)
Para cambiar la frecuencia, donde freq es la nueva frecuencia en Hz
p.ChangeDutyCycle(dc)
Para cambiar el ciclo de trabajo,where 0.0 <= dc <= 100.0
p.stop()
To stop PWM。
Para obtener más detalles sobre el método de uso de PMW de RPi.GPIO, consulte:
https://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/
54 Capítulo 5 RGBLED www.freenove.com █

Capítulo 5 RGBLED
En este capítulo, aprenderemos cómo controlar un RGBLED.
El LED RGB ha integrado 3 LED que pueden emitir respectivamente luz roja, verde y azul. Y tiene 4 pines. El pin
largo (1) es el puerto común, es decir, el puerto positivo o negativo de 3 LED. El LED RGB con puerto positivo
común y su símbolo se muestran a continuación. Podemos hacer que los LED RGB emitan varios colores de luz
controlando estos 3 LED para emitir luz con diferente brillo,

La luz roja, verde y azul se llaman 3 colores primarios. Cuando combina estas tres luces de color primario con
diferente brillo, puede producir casi todo tipo de luces visibles. Las pantallas de la computadora, un solo píxel de
la pantalla del teléfono celular, el neón, etc. están funcionando bajo este principio.

RGB

Si usamos tres PWM de 8 bits para controlar RGBLED, en teoría, podemos crear 28 * 28 * 28 = 16777216 (16
millones) de colores a través de diferentes combinaciones.
A continuación, usaremos RGBLED para hacer un LED colorido.

Proyecto 5.1 Colorful LED

En este experimento, haremos un LED colorido. Y podemos controlar RGBLED para cambiar diferentes colores de
forma automática.
█ www.freenove.com Capítulo 5 RGBLED 55

Listado de componentes

Raspberry Pi 3B x1 RGBLED x1 Resistor 220Ω x3


GPIO Extension Board & Wire x1
BreadBoard x1

Jumper M/M x4

Circuito

Schematic diagram

Hardware connection
56 Capítulo 5 RGBLED www.freenove.com █

Código

Dado que esta prueba requiere 3 PWM, pero en RPi, solo un GPIO tiene la capacidad de hardware para emitir
PWM, necesitamos usar el software para hacer la salida GPIO ordinaria PWM.
C Code 5.1.1 ColorfulLED
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 05.1.1_ColorfulLED del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/05.1.1_ColorfulLED
2. Utilice el siguiente comando para compilar "ColorfulLED.c" y generar el archivo ejecutable "ColorfulLED".
Nota: en este experimento, el software PWM utiliza un mecanismo de subprocesamiento múltiple. Entonces
la opción "-lpthread" necesita ser agregada al compilador.
gcc ColorfulLED.c –o ColorfulLED -lwiringPi –lpthread
3. Y luego ejecuta el generado por“ColorfulLED”.
sudo ./ColorfulLED
Después de ejecutar el programa, verá que RGBLED muestra luz de diferente color al azar. El siguiente es
el código del programa:
1 #include <wiringPi.h>
2 #include <softPwm.h>
3 #include <stdio.h>
4
5 #define ledPinRed 0
6 #define ledPinGreen 1
7 #define ledPinBlue 2
8
9 void ledInit(void)
10 {
11 softPwmCreate(ledPinRed, 0, 100);
12 softPwmCreate(ledPinGreen,0, 100);
13 softPwmCreate(ledPinBlue, 0, 100);
14 }
15
16 void ledColorSet(int r_val, int g_val, int b_val)
17 {
18 softPwmWrite(ledPinRed, r_val);
19 softPwmWrite(ledPinGreen, g_val);
20 softPwmWrite(ledPinBlue, b_val);
21 }
22
23 int main(void)
24 {
25 int r,g,b;
26 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
27 printf("setup wiringPi failed !");
█ www.freenove.com Capítulo 5 RGBLED 57

28 return 1;
29 }
30 printf("Program is starting ...\n");
31 ledInit();
32
33 while(1){
34 r=random()%100;
35 g=random()%100;
36 b=random()%100;
37 ledColorSet(r,g,b);
38 printf("r=%d, g=%d, b=%d \n",r,g,b);
39 delay(300);
40 }
41 return 0;
42 }

Primero, en la función secundaria de ledInitI (), cree los pines de control PWM del software utilizados para
controlar el pin R G, RGBLED, B, respectivamente.
void ledInit(void)
{
softPwmCreate(ledPinRed, 0, 100);
softPwmCreate(ledPinGreen,0, 100);
softPwmCreate(ledPinBlue, 0, 100);
}
Luego crea la función secundaria y configura el PWM de tres pines.
void ledColorSet(int r_val, int g_val, int b_val)
{
softPwmWrite(ledPinRed, r_val);
softPwmWrite(ledPinGreen, g_val);
softPwmWrite(ledPinBlue, b_val);
}
Finalmente, en el ciclo "while" de la función principal, obtenga tres números aleatorios y especifíquelos como el ciclo de trabajo
PWM, que se asignará a los pines correspondientes. Entonces RGBLED puede cambiar el color aleatoriamente todo el tiempo.

while(1){
r=random()%100;
g=random()%100;
b=random()%100;
ledColorSet(r,g,b);
printf("r=%d, g=%d, b=%d \n",r,g,b);
delay(300);
}
58 Capítulo 5 RGBLED www.freenove.com █

La función relacionada de Software PWM se puede describir de la siguiente manera:


int softPwmCreate (int pin, int initialValue, int pwmRange) ;
Esto crea un pin PWM controlado por software.
void softPwmWrite (int pin, int value) ;
Esto actualiza el valor de PWM en el pin dado.
long random();
Esta función devolverá un número aleatorio.

Para obtener más detalles sobre Software PWM, consulte: http://wiringpi.com/reference/software-pwm-library/

Python Code 5.1.1 ColorfulLED


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 05.1.1_ColorfulLED del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/05.1.1_ColorfulLED
2. Use el comando python para ejecutar el código python “ColorfulLED.py”.
python ColorfulLED.py
Después de ejecutar el programa, verá que RGBLED muestra luz de diferente color al azar. El siguiente es
el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3 import random
4 pins = {'pin_R':11, 'pin_G':12, 'pin_B':13} # pins is a dict
5 def setup():
6 global p_R,p_G,p_B
7 print 'Program is starting ... '
8 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
9 for i in pins:
10 GPIO.setup(pins[i], GPIO.OUT) # Set pins' mode is output
11 GPIO.output(pins[i], GPIO.HIGH) #Set pins to high(+3.3V) to off led
12 p_R = GPIO.PWM(pins['pin_R'], 2000) # set Frequece to 2KHz
13 p_G = GPIO.PWM(pins['pin_G'], 2000)
14 p_B = GPIO.PWM(pins['pin_B'], 2000)
15 p_R.start(0) # Initial duty Cycle = 0
16 p_G.start(0)
17 p_B.start(0)
18 def setColor(r_val,g_val,b_val):
19 p_R.ChangeDutyCycle(r_val) # Change duty cycle
20 p_G.ChangeDutyCycle(g_val)
21 p_B.ChangeDutyCycle(b_val)
22 def loop():
23 while True :
24 r=random.randint(0,100)
25 g=random.randint(0,100)
26 b=random.randint(0,100)
█ www.freenove.com Capítulo 5 RGBLED 59

27 setColor(r,g,b)
28 print 'r=%d, g=%d, b=%d '%(r ,g, b)
29 time.sleep(0.3)
30 def destroy():
31 p_R.stop()
32 p_G.stop()
33 p_B.stop()
34 GPIO.cleanup()
35 if __name__ == '__main__': # Program start from here
36 setup()
37 try:
38 loop()
39 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
40 will be executed.
41 destroy()
En el último capítulo, hemos aprendido a usar el lenguaje de Python para hacer una salida de PIN PWM. En este experimento,
permitimos que tres pines emitan PWM, y el uso es exactamente el mismo que el del capítulo anterior. En el ciclo "while" de la
función "loop", primero obtenemos tres números aleatorios, y luego especificamos estos tres números aleatorios como el valor
PWM de los tres pines.o que la conmutación RGBLED de diferentes colores aleatoriamente.

def loop():
while True :
r=random.randint(0,100)
g=random.randint(0,100)
b=random.randint(0,100)
setColor(r,g,b)
print 'r=%d, g=%d, b=%d '%(r ,g, b)
time.sleep(0.3)
Acerca de la función randint():
random.randint(a, b)
La función puede devolver un entero aleatorio dentro del rango especificado (a, b).
60 Capítulo 6 zumbador www.freenove.com █

Capítulo 6 zumbador
En este capítulo, aprenderemos un componente que puede sonar, zumbador.

Proyecto 6.1 Doorbell (Timbre de la puerta)

Haremos este tipo de timbre: cuando se presiona el botón, suena el timbre; y cuando se suelta el botón, el
zumbador deja de sonar.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x7


GPIO Extension Board & Wire x1
BreadBoard x1
NPN transistorx1 Active buzzer x1 Push button x1 Resistor 1kΩ x1 Resistor 10kΩ x2
█ www.freenove.com Capítulo 6 zumbador 61

Conocimiento del componente

Buzzer
Zumbador es un componente de sonido, que es ampliamente utilizado en dispositivos electrónicos como
calculadora, reloj de advertencia electrónico, alarma. Zumbador tiene tipo activo y pasivo. El zumbador activo
tiene un oscilador adentro, y sonará mientras esté alimentado. El zumbador pasivo requiere una señal de
oscilador externo (generalmente usa PWM con diferente frecuencia) para hacer un sonido.

Activebuzzer Passive buzzer

El zumbador activo es fácil de usar. Generalmente, solo puede hacer una frecuencia específica de sonido. El
zumbador pasivo requiere un circuito externo para hacer un sonido, pero se puede controlar para hacer un
sonido con diferente frecuencia. La frecuencia de resonancia del zumbador pasivo es de 2 kHz, lo que significa
que el zumbador pasivo es más fuerte cuando su frecuencia de resonancia es de 2 kHz.
A continuación, usaremos un timbre activo para hacer un timbre y un timbre pasivo para hacer una alarma.

Transistor
Debido a que el funcionamiento actual del zumbador es tan grande que no se puede satisfacer la capacidad de
salida de GPIO de RPi, aquí se necesita un transistor de tipo NPN para amplificar la corriente.

Transistor, el nombre completo: transistor semiconductor, es un dispositivo semiconductor que controla la


corriente. El transistor se puede usar para amplificar la señal débil o funciona como un interruptor. Tiene tres
electrodos (PIN): base (b), colector (c) y emisor (e). Cuando hay un paso de corriente entre "be", "ce" permitirá
un pase de corriente de varias veces (aumento del transistor), en este punto, el transistor funciona en el área de
amplificación. Cuando la corriente entre "be" excede un cierto valor, "ce" no permitirá que la corriente aumente
más, en este punto, el transistor funciona en el área de saturación. El transistor tiene dos tipos que se muestran a
continuación: PNP y NPN,
PNP transistor NPN transistor

De acuerdo con las características del transistor, a menudo se usa como un interruptor en circuitos digitales. Para
que la capacidad de salida del microcontrolador sea muy débil, usaremos un transistor para amplificar la
corriente y conducir componentes de corriente grande.
62 Capítulo 6 zumbador www.freenove.com █

Cuando utilice transistor NPN para activar el zumbador, a menudo adoptamos el siguiente método. Si GPIO emite
un nivel alto, la corriente fluirá a través de R1, se realizará el transistor y el zumbador emitirá un sonido. Si GPIO
emite un nivel bajo, no fluye corriente a través de R1, el transistor no se realizará y el zumbador no sonará.
Cuando utilice transistor PNP para activar el zumbador, a menudo adoptamos el siguiente método. Si GPIO emite
un nivel bajo, la corriente fluirá a través de R1, el transistor se realizará y el zumbador emitirá un sonido. Si GPIO
emite un nivel alto, no fluye corriente a través de R1, el transistor no se realizará y el zumbador no sonará.

NPN transistor to drive buzzer PNP transistor to drive buzzer


█ www.freenove.com Capítulo 6 zumbador 63

Circuito

Schematic diagram

Hardware connection

Nota: en este circuito, la fuente de alimentación para el zumbador es de 5 V, y la resistencia de pull-up del botón
conectado a la potencia de 3.3V. El zumbador puede funcionar cuando está conectado a una potencia de 3.3V,
pero reducirá el volumen.
64 Capítulo 6 zumbador www.freenove.com █

Código

En este experimento, el zumbador es controlado por el botón. Cuando se presiona el botón, suena el timbre. Y cuando
se suelta el botón, el zumbador deja de sonar. En la lógica, es lo mismo que usar el botón para controlar el LED.
C Code 6.1.1 Doorbell
Primero observe el fenómeno experimental y luego analice el código.

1. Use el comando cd para ingresar al directorio 06.1.1_Doorbell del código C.


cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/06.1.1_Doorbell
2. Use el siguiente comando para compilar "Doorbell.c" y generar archivo ejecutable“Doorbell.c”.
gcc Doorbell.c –o Doorbell -lwiringPi
3. Luego ejecuta el archivo generado “Doorbell”.
sudo ./Doorbell
Después de ejecutar el programa, presione el botón, luego sonará un zumbador. Y cuando se suelta el botón, el
zumbador dejará de sonar.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define buzzeRPin 0 //define the buzzeRPin
5 #define buttonPin 1 //define the buttonPin
6
7 int main(void)
8 {
9 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
10 printf("setup wiringPi failed !");
11 return 1;
12 }
13
14 pinMode(buzzeRPin, OUTPUT);
15 pinMode(buttonPin, INPUT);
16
17 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
18 while(1){
19
20 if(digitalRead(buttonPin) == LOW){ //button has pressed down
21 digitalWrite(buzzeRPin, HIGH); //buzzer on
22 printf("buzzer on...\n");
23 }
24 else { //button has released
25 digitalWrite(buzzeRPin, LOW); //buzzer off
26 printf("...buzzer off\n");
27 }
█ www.freenove.com Capítulo 6 zumbador 65

28 }
29
30 return 0;
31 }
El código es exactamente el mismo que usar el botón para controlar el LED lógicamente. Puede intentar usar el
transistor PNP para lograr el funcionamiento de su circuito una vez más.
Python Code 6.1.1 Doorbell
Primero observe el fenómeno experimental, luego analice el código.
1. Use el comando cd para ingresar al directorio 06.1.1_Doorbell del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/06.1.1_Doorbell
2. Use el comando python para ejecutar el código python “Doorbell.py”.
python Doorbell.py
Después de ejecutar el programa, presione el botón, luego sonará un zumbador. Y cuando se suelta el botón, el
zumbador dejará de sonar.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2
3 buzzeRPin = 11 # define the buzzeRPin
4 buttonPin = 12 # define the buttonPin
5
6 def setup():
7 print 'Program is starting...'
8 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
9 GPIO.setup(buzzeRPin, GPIO.OUT) # Set buzzeRPin's mode is output
10 GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
11 input, and pull up to high level(3.3V)
12
13 def loop():
14 while True:
15 if GPIO.input(buttonPin)==GPIO.LOW:
16 GPIO.output(buzzeRPin,GPIO.HIGH)
17 print 'buzzer on ...'
18 else :
19 GPIO.output(buzzeRPin,GPIO.LOW)
20 print 'buzzer off ...'
21
22 def destroy():
23 GPIO.output(buzzeRPin, GPIO.LOW) # buzzer off
24 GPIO.cleanup() # Release resource
25
26 if __name__ == '__main__': # Program start from here
27 setup()
28 try:
29 loop()
66 Capítulo 6 zumbador www.freenove.com █

30 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()


31 will be executed.
32 destroy()
El código es exactamente el mismo que usar el botón para controlar el LED lógicamente. Puede intentar usar el
transistor PNP para lograr el funcionamiento de su circuito una vez más.

Proyecto 6.2 Alertor

A continuación, usaremos un zumbador pasivo para hacer una alarma.


La lista de componentes y la parte del circuito es similar a la última sección. En el circuito del timbre de puerta,
solo el zumbador activo debe reemplazarse con un zumbador pasivo.

Código

En este experimento, la alarma del timbre se controla con el botón. Presione el botón, luego sonará el zumbador. Si suelta el botón,
el zumbador dejará de sonar. En la lógica, es lo mismo que usar el botón para controlar el LED. En el método de control, el
zumbador pasivo requiere PWM de cierta frecuencia para que suene.
C Code 6.2.1 Alertor
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 06.2.1_Alertor del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/06.2.1_Alertor
2. Utilice el siguiente comando para compilar "Alertor.c" y generar el archivo ejecutable "Alertor". Las opciones
del compilador "-lm" y "-lpthread" son necesarias para agregar aquí.
gcc Alertor.c –o Alertor –lwiringPi –lm -lpthread
3. Luego ejecuta el archivo generado “Alertor”.
sudo ./ Alertor
Después de ejecutar el programa, presione el botón, luego sonará un zumbador. Y cuando se suelta el botón, el
zumbador dejará de sonar.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <softTone.h>
4 #include <math.h>
5 #define buzzeRPin 0 //define the buzzeRPin
6 #define buttonPin 1 //define the buttonPin
7 void alertor(int pin){
8 int x;
9 double sinVal, toneVal;
10 for(x=0;x<360;x++){ // The frequency is based on the sine curve.
11 sinVal = sin(x * (M_PI / 180));
12 toneVal = 2000 + sinVal * 500;
13 softToneWrite(pin,toneVal);
14 delay(1);
█ www.freenove.com Capítulo 6 zumbador 67

15 }
16 }
17 void stopAlertor(int pin){
18 softToneWrite(pin,0);
19 }
20 int main(void)
21 {
22 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
23 printf("setup wiringPi failed !");
24 return 1;
25 }
26 pinMode(buzzeRPin, OUTPUT);
27 pinMode(buttonPin, INPUT);
28 softToneCreate(buzzeRPin);
29 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
30 while(1){
31 if(digitalRead(buttonPin) == LOW){ //button has pressed down
32 alertor(buzzeRPin); //buzzer on
33 printf("alertor on...\n");
34 }
35 else { //button has released
36 stopAlertor(buzzeRPin); //buzzer off
37 printf("...buzzer off\n");
38 }
39 }
40 return 0;
41 }
El código es el mismo para el zumbador activo lógicamente, pero la forma de controlar el zumbador es diferente. El zumbador pasivo
requiere PWM de cierta frecuencia para controlar, por lo que debe crear un pin de PWM de software a través de softToneCreate
(buzzeRPin). Aquí softTone está dedicado a generar ondas cuadradas con frecuencia variable y ciclo de trabajo fijado al 50%, que es
una mejor opción para controlar el zumbador.

softToneCreate(buzzeRPin);
En el ciclo while de la función principal, cuando se presiona el botón, se llamará a la alerta de subfunción () y la alerta emitirá un
sonido de advertencia. La curva de frecuencia de la alarma se basa en la curva sinusoidal. Necesitamos calcular el valor del seno de 0
a 360 grados y multiplicar un cierto valor (aquí es 500) y más la frecuencia de resonancia del zumbador. Podemos configurar la
frecuencia PWM a través de softToneWrite (pin, toneVal).

void alertor(int pin){


int x;
double sinVal, toneVal;
for(x=0;x<360;x++){ //The frequency is based on the sine curve.
sinVal = sin(x * (M_PI / 180));
toneVal = 2000 + sinVal * 500;
softToneWrite(pin,toneVal);
delay(1);
68 Capítulo 6 zumbador www.freenove.com █

}
}
Si desea cerrar el zumbador, simplemente ajuste la frecuencia PWM del pin del zumbador en 0.
void stopAlertor(int pin){
softToneWrite(pin,0);
}
Las funciones relacionadas de softTone se describen de la siguiente manera:
int softToneCreate (int pin) ;
Esto crea un pin de tono controlado por software.
void softToneWrite (int pin, int freq) ;
Esto actualiza el valor de frecuencia de tono en el pin dado.
Para obtener más detalles sobre softTone, consulte: http://wiringpi.com/reference/software-tone-library/
Python Code 6.2.1 Alertor
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 06.2.1_Alertor del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/06.2.1_Alertor
2. Use el comando python para ejecutar el código Python“Alertor.py”.
python Alertor.py
Después de ejecutar el programa, presione el botón, luego sonará el zumbador. Cuando se suelta el botón, el
zumbador dejará de sonar.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3 import math
4
5 buzzeRPin = 11 # define the buzzeRPin
6 buttonPin = 12 # define the buttonPin
7
8 def setup():
9 global p
10 print 'Program is starting...'
11 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
12 GPIO.setup(buzzeRPin, GPIO.OUT) # Set buzzeRPin's mode is output
13 GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
14 input, and pull up to high level(3.3V)
15 p = GPIO.PWM(buzzeRPin, 1)
16 p.start(0);
17
18 def loop():
19 while True:
20 if GPIO.input(buttonPin)==GPIO.LOW:
21 alertor()
22 print 'buzzer on ...'
23 else :
█ www.freenove.com Capítulo 6 zumbador 69

24 stopAlertor()
25 print 'buzzer off ...'
26 def alertor():
27 p.start(50)
28 for x in range(0,361):
29 sinVal = math.sin(x * (math.pi / 180.0))
30 toneVal = 2000 + sinVal * 500
31 p.ChangeFrequency(toneVal)
32 time.sleep(0.001)
33
34 def stopAlertor():
35 p.stop()
36 def destroy():
37 GPIO.output(buzzeRPin, GPIO.LOW) # buzzer off
38 GPIO.cleanup() # Release resource
39 if __name__ == '__main__': # Program start from here
40 setup()
41 try:
42 loop()
43 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
44 will be executed.
45 destroy()
El código es el mismo para el zumbador activo lógicamente, pero la forma de controlar el zumbador es diferente.
El zumbador pasivo requiere PWM de cierta frecuencia para controlar, por lo que debe crear un pin de PWM de
software a través de softToneCreate (buzzeRPin). La forma de crear PMW también se introdujo anteriormente en
las secciones sobre BreathingLED y RGBLED.
def setup():
global p
print 'Program is starting...'
GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
GPIO.setup(buzzeRPin, GPIO.OUT) # Set buzzeRPin's mode is output
GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
input, and pull up to high level(3.3V)
p = GPIO.PWM(buzzeRPin, 1)
p.start(0);
En el ciclo while de la función principal, cuando se presiona el botón, se llamará a la alerta de subfunción () y la alerta
emitirá un sonido de advertencia. La curva de frecuencia de la alarma se basa en la curva sinusoidal. Necesitamos
calcular el valor del seno de 0 a 360 grados y multiplicar un cierto valor (aquí es 500) y más la frecuencia de resonancia
del zumbador. Podemos configurar la frecuencia PWM a través de p.ChangeFrequency (toneVal).
def alertor():
p.start(50)
for x in range(0,361):
sinVal = math.sin(x * (math.pi / 180.0))
toneVal = 2000 + sinVal * 500
70 Capítulo 6 zumbador www.freenove.com █

p.ChangeFrequency(toneVal)
time.sleep(0.001)
Cuando se suelta el botón, el zumbador se cerrará.
def stopAlertor():
p.stop()
█ www.freenove.com Capítulo 7 PCF8591 71

Capítulo 7 PCF8591
Hemos aprendido cómo controlar el brillo del LED a través de la salida PWM y comprendimos que PWM no es el
análogo real anterior. En este capítulo, aprenderemos cómo leer cantidades analógicas a través de PCF8591,
convertirlo en cantidad digital y convertir la cantidad digital en salida analógica. Es decir, ADC y DAC.

Proyecto 7.1 Leer el voltaje del potenciómetro

En este experimento, usaremos la función ADC de PCF8591 para leer el valor de voltaje del potenciómetro. Y
luego envíe el valor de voltaje a través del DAC para controlar el brillo del LED.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x16


GPIO Extension Board & Wire x1
BreadBoard x1
Rotary potentiometer x1 PCF8591 x1 Resistor 10kΩ x2 Resistor 220Ω x1 LED x1
72 Capítulo 7 PCF8591 www.freenove.com █

Conocimiento del circuito

ADC
ADC, convertidor analógico a digital, es un dispositivo utilizado para convertir de analógico a digital. El rango del
ADC en PCF8591 es de 8 bits, lo que significa que la resolución es 2 ^ 8 = 256, y representa que el rango (aquí es
3.3V) se dividirá equitativamente en 256 partes. El análogo de cada rango corresponde a un valor de ADC. Por lo
tanto, cuantos más bits tenga el ADC, más densa será la partición del análogo, también será mayor la precisión de
la conversión.

Subsección 1: el análogo en sonar de 0V-3.3 / 256 V corresponde a 0 digital;


Subsección 2: el análogo en sonar de 3.3 / 256 V-2 * 3.3 / 256V corresponde a digital 1;
...
El siguiente análogo se dividirá en consecuencia.
DAC
DAC, es decir, convertidor digital a analógico, es el proceso inverso de ADC. El puerto de E / S digital puede
generar un nivel alto y bajo, pero no puede emitir un valor de voltaje intermedio, que puede resolverse mediante
DAC. PCF8591 tiene un pin de salida DAC con una precisión de 8 bits, que puede dividir VDD (aquí es 3.3V) en 28 =
256 partes. Por ejemplo, cuando la cantidad digital es 1, el voltaje de salida es 3.3 / 256 * 1 V, y cuando la cantidad
digital es 128, el voltaje de salida es 3.3 / 256 * 128 = 1.65V, la mayor precisión de PCF8591 es , cuanto mayor sea
la precisión del valor de voltaje de salida.
█ www.freenove.com Capítulo 7 PCF8591 73

Conocimiento del componente


Potenciómetro
El potenciómetro es un elemento resistivo con tres partes terminales y la resistencia se puede ajustar de
acuerdo con una cierta variación. El potenciómetro a menudo está formado por resistencia y cepillo extraíble.
Cuando el cepillo se mueve a lo largo del cuerpo de la resistencia, habrá una resistencia o voltaje que tiene cierta
relación con el desplazamiento en el lado de salida (3). La figura que se muestra a continuación es el
potenciómetro deslizante lineal y su símbolo.

Lo que entre el pin 1 del potenciómetro y el pin 2 es el cuerpo de la resistencia, y los pines 3 están conectados al
pincel. Cuando el pincel se mueve de los pines 1 al pin 2, la resistencia entre el pin 1 y el pin 3 aumentará linealmente
hasta la resistencia del cuerpo, y la resistencia entre el pin 2 y el pin 3 disminuirá a 0 linealmente.
En el circuito. Los dos lados del cuerpo de resistencia a menudo están conectados al electrodo positivo y negativo de
la potencia. Cuando desliza el pin pin 3, puede obtener un cierto voltaje en el rango de la fuente de alimentación.

Potenciómetro rotatorio
El potenciómetro rotatorio y el potenciómetro lineal tienen una función similar; la única diferencia es: la
resistencia se ajusta girando el potenciómetro.
74 Capítulo 7 PCF8591 www.freenove.com █

PCF8591
El PCF8591 es un dispositivo de adquisición de datos CMOS de 8 bits y bajo consumo de 8 bits de un solo chip con
cuatro entradas analógicas, una salida analógica y una interfaz de bus serie I2C.
CARACTERISTICAS:
 Fuente de alimentación individual  Selección de canal de incremento automático
 Voltaje de suministro operativo de 2.5 V a 6 V  Rango de voltaje analógico de VSS a VDD
 Baja corriente de espera  Circuito de seguimiento y retención en chip
 Entrada / salida en serie a través del bus I2C  Conversión A / D de aproximación sucesiva de 8 bits
 Dirección por 3 pines de dirección de hardware  Multiplicando DAC con una salida analógica.
 Velocidad de muestreo dada por la velocidad del bus I2C  4 entradas analógicas programables como single-
 Entradas diferenciales ended o
PINNING
SYMBOL PIN DESCRIPTION TOP VIEW
AIN0 1
AIN1 2
Analog inputs (A/D converter)
AIN2 3
AIN3 4
A0 5
A1 6 Hardware address
A2 7
Vss 8 Negative supply voltage
SDA 9 I2C-bus data input/output
SCL 10 I2C-bus clock input
OSC 11 Oscillator input/output
EXT 12 external/internal switch for oscillator
input
AGND 13 Analog ground
Vref 14 Voltage reference input
AOUT 15 Analog output(D/A converter)
Vdd 16 Positive supplay voltage
Para más detalles sobre PCF8591, consulte la hoja de datos.
I2C communication
I2C (Inter-Integrated Circuit) es un modo de comunicación en serie de dos cables que se puede usar para la
conexión del microcontrolador y su equipo periférico. Los dispositivos que utilizan la comunicación I2C deben
conectarse a la línea de datos serie (SDA) y a la línea de reloj serie (SCL) (llamada bus I2C). Cada dispositivo tiene
una dirección única y se puede usar como un transmisor o receptor para comunicarse con los dispositivos
conectados al bus.
█ www.freenove.com Capítulo 7 PCF8591 75

Circuit

Schematic diagram

Hardware connection
76 Capítulo 7 PCF8591 www.freenove.com █

Configure I2C

Enable I2C
La interfaz I2C raspberry pi está cerrada por defecto. Debe abrirlo manualmente. Puede habilitar la interfaz I2C
de la siguiente manera.
Escriba comando en la terminal:
sudo raspi-config
A continuación, abra el siguiente cuadro de diálogo:

Escoger “9 Advanced Options” “A6 I2C”“Yes”“Finish” en orden y reinicia tu RPi más tarde. Luego se inicia
el módulo I2C.
Escriba un comando para verificar si el módulo I2C está iniciado:
lsmod | grep i2c
Si se ha iniciado el módulo I2C, se mostrará el siguiente contenido:
█ www.freenove.com Capítulo 7 PCF8591 77

Install I2C-Tools
Escriba el comando para instalar I2C-Tools.
sudo apt-get install i2c-tools
Detección de dirección del dispositivo I2C:
i2cdetect –y 1

Aquí 48 (HEX)es la dirección I2C dePCF8591.

Código

C Code 7.1.1 pcf8591


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 07.1.1_ PCF8591 del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/07.1.1_PCF8591
2. Utilice el siguiente comando para compilar "PCF8591.c" y generar el archivo ejecutable "PCF8591". gcc
PCF8591.c –o PCF8591 –lwiringPi
3. Tejecutar el archivo generado "PCF8591".
sudo ./PCF8591
Después de ejecutar el programa, cambie el potenciómetro, luego el terminal imprimirá el valor del voltaje del
potenciómetro y el contenido digital convertido. Cuando el voltaje es mayor que 1.6V (el voltaje necesita
encender el LED rojo), el LED comienza a emitir luz. Si continúa aumentando el voltaje de salida, el LED se volverá
más brillante gradualmente.
78 Capítulo 7 PCF8591 www.freenove.com █

El siguiente es el código:
1 #include <wiringPi.h>
2 #include <pcf8591.h>
3 #include <stdio.h>
4
5 #define address 0x48 //pcf8591 default address
6 #define pinbase 64 //any number above 64
7 #define A0 pinbase + 0
8 #define A1 pinbase + 1
9 #define A2 pinbase + 2
10 #define A3 pinbase + 3
11
12 int main(void){
13 int value;
14 float voltage;
15 wiringPiSetup();
16 pcf8591Setup(pinbase,address);
17 while(1){
18 value = analogRead(A0); //read A0 pin
19 analogWrite(pinbase+0,value);
20 voltage = (float)value / 255.0 * 3.3; // calculate voltage
21 printf("ADC value : %d ,\tVoltage : %.2fV\n",value,voltage);
22 delay(100);
23 }
24 }
La dirección I2C predeterminada de PCF8591 es 0x48. La base pin es un valor cualquiera mayor que o igual a 64. Y
hemos definido el canal de entrada ADC A1, A2, A0, A3 de PCF8591.
#define address 0x48 //pcf8591 default address
#define pinbase 64 //any number above 64
#define A0 pinbase + 0
#define A1 pinbase + 1
#define A2 pinbase + 2
#define A3 pinbase + 3
En la función principal, después de que PCF8591 es inicializado por pcf8591Setup(pinbase, address), puedes usar
la función analogRead() y analogWrite() para operar el ADC y DAC.
pcf8591Setup(pinbase,address);
En el ciclo "while", analogRead (A0) se utiliza para leer el valor de ADC del puerto A0 (potenciómetro conectado),
luego el valor de ADC leído se envía a través de analogWrite (). Y luego se calculará y se mostrará el valor de
voltaje real correspondiente.
while(1){
value = analogRead(A0); //read A0 pin
analogWrite(pinbase+0,value);
voltage = (float)value / 255.0 * 3.3; // calculate voltage
printf("ADC value : %d ,\tVoltage : %.2fV\n",value,voltage);
█ www.freenove.com Capítulo 7 PCF8591 79

delay(100);
}
Detalles sobre analogRead () y analogWrite ():
void analogWrite (int pin, int value) ;
Esto escribe el valor dado en el pin analógico suministrado. Deberá registrar módulos analógicos adicionales
para habilitar esta función para dispositivos.
int analogRead (int pin) ;
Esto devuelve el valor leído en el pin de entrada analógica suministrado. Deberá registrar módulos analógicos
adicionales para habilitar esta función para dispositivos.

Para obtener instrucciones más detalladas sobre PCF8591 de wiringPi, consulte:


http://wiringpi.com/extensiones/i2c-pcf8591/

Python Code 7.1.1 pcf8591


Primero instale un módulo smbus, y el comando es el siguiente:
sudo apt-get install python-smbus
Una vez completada la instalación, opere según los siguientes pasos. Observe el fenómeno experimental y luego
analice el código.
1. Use el comando cd para ingresar al directorio 07.1.1_pcf8591 del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/07.1.1_pcf8591
2. Utilice el comando python para ejecutar el código de Python "pcf8591.py" ..
python pcf8591.py
Después de ejecutar el programa, cambie el potenciómetro, luego el terminal imprimirá el valor del voltaje del
potenciómetro y el contenido digital convertido. Cuando el voltaje es mayor que 1.6V (el voltaje necesita
encender el LED rojo), el LED comienza a emitir luz. Si continúa aumentando el voltaje de salida, el LED se volverá
más brillante gradualmente.

El siguiente es el código:
1 import smbus
2 import time
3
4 address = 0x48 #default address of PCF8591
5 bus=smbus.SMBus(1)
6 cmd=0x40 #command
7
80 Capítulo 7 PCF8591 www.freenove.com █

8 def analogRead(chn):# read ADC value,chn:0,1,2,3


9 value = bus.read_byte_data(address,cmd+chn)
10 return value
11
12 def analogWrite(value):#write DAC value
13 bus.write_byte_data(address,cmd,value)
14
15 def loop():
16 while True:
17 value = analogRead(0) # read the ADC value of channel 0
18 analogWrite(value) # write the DAC value
19 voltage = value / 255.0 * 3.3 # calculate the voltage value
20 print 'ADC Value : %d, Voltage : %.2f'%(value,voltage)
21 time.sleep(0.01)
22
23 def destroy():
24 bus.close()
25
26 if __name__ == '__main__':
27 print 'Program is starting ... '
28 try:
29 loop()
30 except KeyboardInterrupt:
31 destroy()
Primero, defina la dirección I2C y la palabra de control de PCF8591, y luego cree una instancia del bus de objetos
de SMBus, que puede usarse para operar ADC y DAC de PCF8591.
address = 0x48 # default address of PCF8591
bus=smbus.SMBus(1)
cmd=0x40 # command
Esta función secundaria se usa para leer el ADC. Su parámetro "chn" representa el número del canal de entrada: 0, 1, 2,
3. Su valor de retorno es el valor ADC leído.
def analogRead(chn):# read ADC value,chn:0,1,2,3
value = bus.read_byte_data(address,cmd+chn)
return value
Esta función secundaria se usa para escribir DAC. Su parámetro “value”("valor") representa la calidad digital que
debe escribirse, entre 0-255.
def analogWrite(value):# write DAC value
bus.write_byte_data(address,cmd,value)
En el ciclo "while", primero lea el valor ADC del canal 0, y luego anote el valor como la calidad digital DAC y la
tensión de salida correspondiente en el pin Aout de PCF8591. Luego calcule el valor de voltaje correspondiente e
imprímalo.
def loop():
while True:
value = analogRead(0) #read the ADC value of channel 0
█ www.freenove.com Capítulo 7 PCF8591 81

analogWrite(value) # write ADC value


voltage = value / 255.0 * 3.3 # calculate voltage value
print 'ADC Value : %d, Voltage : %.2f'%(value,voltage)
time.sleep(0.01)
Sobre el módulo smbus:
smbus Module
Es System Management Bus. Este módulo define un tipo de objeto que permite transacciones SMBus en hosts que ejecutan el
kernel de Linux. El kernel de host debe tener compatibilidad con I2C, soporte de interfaz de dispositivo I2C y un controlador de
adaptador de bus. Todos estos pueden integrarse en el núcleo o cargarse desde módulos.
En Python, puede usar la ayuda (smbus) para ver la función relevante y sus descripciones.
bus=smbus.SMBus(1):Create an SMBus class object.
bus.read_byte_data(address,cmd+chn): Lea un byte de datos de una dirección y devuélvala.
bus.write_byte_data(address,cmd,value): Escribe un byte de datos en una dirección.
82 Capítulo 8 Potenciómetro y LED www.freenove.com █

Capítulo 8 Potenciómetro y LED


Hemos aprendido cómo usar ADC y DAC antes. Cuando se usa salida DAC analógica para conducir el LED, encontramos
que, cuando el voltaje de salida es menor que el voltaje de encendido del led, el LED no se enciende, el voltaje
analógico de salida es mayor que el voltaje del LED, el LED se encenderá. Esto conduce a un cierto grado de desperdicio
de recursos. Por lo tanto, en el control del brillo del LED, debemos elegir una forma más razonable de control de PWM.
En este capítulo, aprendemos a controlar el brillo del LED a través de un potenciómetro.

Proyecto 8.1 Soft Light(Luz suave)

En este experimento, haremos una luz suave. Use PCF8591 para leer el valor ADC de los potenciómetros y
asignarlo a la relación del ciclo de trabajo de PWM utilizado para controlar el brillo del LED. Entonces puede
hacer que el brillo del LED cambie al cambiar el potenciómetro.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x17


GPIO Extension Board & Wire x1
BreadBoard x1
Rotary potentiometer x1 PCF8591 x1 Resistor 10kΩ x2 Resistor 220Ω x1 LED x1
█ www.freenove.com Capítulo 8 Potenciómetro y LED 83

Circuito

El circuito de este experimento es similar al del último capítulo. La única diferencia es que el pin utilizado para
controlar el LED es diferente.
Schematic diagram

Hardware connection
84 Capítulo 8 Potenciómetro y LED www.freenove.com █

Código

C Code 8.1.1 Softlight


Primero observe el fenómeno experimental, y luego analice el código.
1. Use el comando cd para ingresar al directorio 08.2.1_Softlight del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/08.1.1_Softlight
2. Use el siguiente comando para compilar "Softlight.c" y generar el archivo ejecutable "Softlight".
gcc Softlight.c –o Softlight–lwiringPi –lpthread
3. Luego ejecute el archivo generado "Softlight".
sudo ./Softlight
Después de ejecutar el programa, cambie el potenciómetro, luego la ventana del terminal imprimirá el valor de
voltaje del potenciómetro y la cantidad digital convertida. Y el brillo del LED cambiará en consecuencia.
El siguiente es el código:

1 #include <wiringPi.h>
2 #include <pcf8591.h>
3 #include <stdio.h>
4 #include <softPwm.h>
5
6 #define address 0x48 //pcf8591 default address
7 #define pinbase 64 //any number above 64
8 #define A0 pinbase + 0
9 #define A1 pinbase + 1
10 #define A2 pinbase + 2
11 #define A3 pinbase + 3
12
13 #define ledPin 0
14 int main(void){
15 int value;
16 float voltage;
17 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
18 printf("setup wiringPi failed !");
19 return 1;
20 }
21 softPwmCreate(ledPin,0,100);
22 pcf8591Setup(pinbase,address);
23
24 while(1){
25 value = analogRead(A0); //read A0 pin
26 softPwmWrite(ledPin,value*100/255);
27 voltage = (float)value / 255.0 * 3.3; // calculate voltage
28 printf("ADC value : %d ,\tVoltage : %.2fV\n",value,voltage);
29 delay(100);
█ www.freenove.com Capítulo 8 Potenciómetro y LED 85

30 }
31 return 0;
32 }
En el código, lea el valor ADC de los potenciómetros y asigne al ciclo de trabajo de PWM para controlar el brillo del LED.
Python Code 8.1.1 Softlight
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 08.2.1_Softlight del código Python
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/08.1.1_Softlight
2. Utilice el comando python para ejecutar el código de Python "Softlight.py".
python Softlight.py
Después de ejecutar el programa, cambie el potenciómetro, luego la ventana del terminal imprimirá el valor de
voltaje del potenciómetro y la cantidad digital convertida. Y el brillo del LED cambiará en consecuencia.
El siguiente es el código:

1 import RPi.GPIO as GPIO


2 import smbus
3 import time
4
5 address = 0x48
6 bus=smbus.SMBus(1)
7 cmd=0x40
8 ledPin = 11
9
10 def analogRead(chn):
11 value = bus.read_byte_data(address,cmd+chn)
12 return value
13
14 def analogWrite(value):
15 bus.write_byte_data(address,cmd,value)
16
17 def setup():
18 global p
19 GPIO.setmode(GPIO.BOARD)
20 GPIO.setup(ledPin,GPIO.OUT)
21 GPIO.output(ledPin,GPIO.LOW)
22
23 p = GPIO.PWM(ledPin,1000)
24 p.start(0)
25
26 def loop():
27 while True:
28 value = analogRead(0)
29 p.ChangeDutyCycle(value*100/255)
30 voltage = value / 255.0 * 3.3
86 Capítulo 8 Potenciómetro y LED www.freenove.com █

31 print 'ADC Value : %d, Voltage : %.2f'%(value,voltage)


32 time.sleep(0.01)
33
34 def destroy():
35 bus.close()
36 GPIO.cleanup()
37
38 if __name__ == '__main__':
39 print 'Program is starting ... '
40 setup()
41 try:
42 loop()
43 except KeyboardInterrupt:
44 destroy()
En el código, lea el valor ADC de los potenciómetros y asigne al ciclo de trabajo de PWM para controlar el brillo del LED.
█ www.freenove.com Capítulo 9 Potenciómetro y LED RGB 87

Capítulo 9 Potenciómetro y LED RGB


En este capítulo, utilizaremos 3 potenciómetros para controlar el brillo de 3 LED de RGBLED para que muestre
diferentes colores.

Proyecto 9.1 Colorful Light

En este experimento, se usan 3 potenciómetros para controlar RGBLED y el principio es el mismo con la luz suave
frontal. A saber, lea el valor de voltaje del potenciómetro y luego conviértalo en PWM para controlar el brillo del
LED. La diferencia es que el frontal solo necesita un LED, pero este experimento necesita un RGBLED (3 LED).

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x25


GPIO Expansion Board & Wire x1
BreadBoard x1
Rotary potentiometer x3 PCF8591 x1 Resistor 10kΩ x2 Resistor 220Ω x3 RGBLED x1
88 Capítulo 9 Potenciómetro y LED RGB www.freenove.com █

Circuito

Schematic diagram
█ www.freenove.com Capítulo 9 Potenciómetro y LED RGB 89

Hardware connection
90 Capítulo 9 Potenciómetro y LED RGB www.freenove.com █

Código

C Code 9.1.1 Colorful Softlight


Primero observe el fenómeno experimental, y luego analice el código.
1. Use el comando cd para ingresar al directorio 09.1.1_ColorfulSoftlight del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/09.1.1_ColorfulSoftlight
2. Utilice el siguiente comando para compilar "ColorfulSoftlight.c" y generar el archivo ejecutable "ColorfulSoftlight".
gcc ColorfulSoftlight.c –o ColorfulSoftlight –lwiringPi –lpthread
3. Luego ejecuta el archivo generado"ColorfulSoftlight".
sudo ./ColorfulSoftlight
Después de ejecutar el programa, gire uno de los potenciómetros, luego el color de RGBLED cambiará en
consecuencia. Y la ventana del terminal imprimirá el valor de ADC de cada potenciómetro.

El siguiente es el código del programa:


1 #include <wiringPi.h>
2 #include <pcf8591.h>
3 #include <stdio.h>
4 #include <softPwm.h>
5
6 #define address 0x48 //pcf8591 default address
7 #define pinbase 64 //any number above 64
8 #define A0 pinbase + 0
9 #define A1 pinbase + 1
10 #define A2 pinbase + 2
11 #define A3 pinbase + 3
12
13 #define ledRedPin 3 //define 3 pins of RGBLED
14 #define ledGreenPin 2
15 #define ledBluePin 0
16 int main(void){
17 int val_Red,val_Green,val_Blue;
18 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
19 printf("setup wiringPi failed !");
20 return 1;
21 }
22 softPwmCreate(ledRedPin,0,100); //creat 3 PMW output pins for RGBLED
23 softPwmCreate(ledGreenPin,0,100);
█ www.freenove.com Capítulo 9 Potenciómetro y LED RGB 91

24 softPwmCreate(ledBluePin,0,100);
25 pcf8591Setup(pinbase,address); //initialize PCF8591
26
27 while(1){
28 val_Red = analogRead(A0); //read 3 potentiometers
29 val_Green = analogRead(A1);
30 val_Blue = analogRead(A2);
31 softPwmWrite(ledRedPin,val_Red*100/255); //map the read value of
32 potentiometers into PWM value and output it
33 softPwmWrite(ledGreenPin,val_Green*100/255);
34 softPwmWrite(ledBluePin,val_Blue*100/255);
35 //print out the read ADC value
36 printf("ADC value val_Red: %d ,\tval_Green: %d ,\tval_Blue: %d
37 \n",val_Red,val_Green,val_Blue);
38 delay(100);
39 }
40 return 0;
41 }
En el código, lea el valor ADC de 3 potenciómetros y asócielos en el ciclo de trabajo PWM para controlar los 3 LED
de control con diferente color de RGBLED, respectivamente.
92 Capítulo 9 Potenciómetro y LED RGB www.freenove.com █

Python Code 9.1.1 ColorfulSoftlight


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 09.1.1_ColorfulSoftlight del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/09.1.1_ ColorfulSoftlight
2. Use el comando python para ejecutar el código python "ColorfulSoftlight.py".
python ColorfulSoftlight.py
Después de ejecutar el programa, gire uno de los potenciómetros, luego el color de RGBLED cambiará en
consecuencia. Y la ventana del terminal imprimirá el valor de ADC de cada potenciómetro.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import smbus
3 import time
4
5 address = 0x48
6 bus=smbus.SMBus(1)
7 cmd=0x40
8
9 ledRedPin = 15 #define 3 pins of RGBLED
10 ledGreenPin = 13
11 ledBluePin = 11
12
13 def analogRead(chn): #read ADC value
14 bus.write_byte(address,cmd+chn)
15 value = bus.read_byte(address)
16 value = bus.read_byte(address)
17 return value
18
19 def analogWrite(value):
20 bus.write_byte_data(address,cmd,value)
21
22 def setup():
23 global p_Red,p_Green,p_Blue
24 GPIO.setmode(GPIO.BOARD)
25 GPIO.setup(ledRedPin,GPIO.OUT) #set 3 pins of RGBLED to output mode
26 GPIO.setup(ledGreenPin,GPIO.OUT)
27 GPIO.setup(ledBluePin,GPIO.OUT)
28
29 p_Red = GPIO.PWM(ledRedPin,1000) #configure PMW to 3 pins of RGBLED
30 p_Red.start(0)
31 p_Green = GPIO.PWM(ledGreenPin,1000)
32 p_Green.start(0)
33 p_Blue = GPIO.PWM(ledBluePin,1000)
34 p_Blue.start(0)
35
█ www.freenove.com Capítulo 9 Potenciómetro y LED RGB 93

36 def loop():
37 while True:
38 value_Red = analogRead(0) #read ADC value of 3 potentiometers
39 value_Green = analogRead(1)
40 value_Blue = analogRead(2)
41 p_Red.ChangeDutyCycle(value_Red*100/255) #map the read value of potentiometers
42 into PWM value and output it
43 p_Green.ChangeDutyCycle(value_Green*100/255)
44 p_Blue.ChangeDutyCycle(value_Blue*100/255)
45 #print read ADC value
46 print 'ADC Value
47 value_Red: %d ,\tvlue_Green: %d ,\tvalue_Blue: %d'%(value_Red,value_Green,value_Blue)
48 time.sleep(0.01)
49
50 def destroy():
51 bus.close()
52 GPIO.cleanup()
53
54 if __name__ == '__main__':
55 print 'Program is starting ... '
56 setup()
57 try:
58 loop()
59 except KeyboardInterrupt:
60 destroy()
En el código, lea el valor ADC de 3 potenciómetros y asócielos en el ciclo de trabajo PWM para controlar los 3 LED
de control con diferente color de RGBLED, respectivamente.
94 Capítulo 10 Photoresistor y LED www.freenove.com █

Capítulo 10 Photoresistor y LED


En este capítulo, aprenderemos a usar fotorresistor.

Proyecto 10.1 NightLamp

Photoresistor is very sensitive to illumination strength. So we can use this feature to make a nightlamp, when
ambient light gets darker, LED wil become brighter automaticly, and when the ambient light gets brighter, LED
wil become darker automaticly.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x15


GPIO Extension Board & Wire x1
BreadBoard x1
Photoresistor x1 PCF8591 x1 Resistor 10kΩ x3 Resistor 220Ω x1 LED x1
█ www.freenove.com Capítulo 10 Photoresistor y LED 95

Conocimiento del componente

Photoresistor
Photoresistor es una resistencia sensible a la luz. Cuando la fuerza que arroja la luz sobre la superficie del
fotorresistor no es la misma, la resistencia del fotoresistor cambiará. Con esta característica, podemos usar
fotoresistores para detectar la intensidad de la luz. Photoresistor y símbolo son los siguientes.

El siguiente circuito se usa a menudo para detectar el cambio de resistencia de fotorresistencia:

En el circuito anterior, cuando la resistencia del fotorresistor cambia debido a la intensidad de la luz, el
voltaje entre el fotorresistor y la resistencia R1 cambiará, por lo que la intensidad de la luz se puede obtener
midiendo el voltaje.
96 Capítulo 10 Photoresistor y LED www.freenove.com █

Circuito

El circuito de este experimento es similar al del último capítulo. La única diferencia es que la señal de entrada del
pin AIN0 del PCF8591 cambia de un potenciómetro a una combinación de un fotoresistor y una resistencia.
Schematic diagram

Hardware connection
█ www.freenove.com Capítulo 10 Photoresistor y LED 97

Código

El código de este experimento es idéntico al del último capítulo lógicamente. C Code 10.1.1
Nightlamp
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 010.1.1_Nightlamp del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/10.1.1_Nightlamp
2. Use el siguiente comando para compilar "Nightlamp.c" y generar archivo ejecutable “Nightlamp”.
gcc Nightlamp.c –o Nightlamp –lwiringPi -lpthread
3. Luego ejecuta el archivo generado“Nightlamp”.
sudo ./Nightlamp
Después de ejecutar el programa, cuando cubra la resistencia fotosensible o haga una linterna hacia el
fotorresistor, el brillo del LED aumentará o se debilitará. Y la ventana del terminal imprimirá el valor actual de la
tensión de entrada del pin PCF8591 AIN0 y la cantidad digital convertida.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <pcf8591.h>
3 #include <stdio.h>
4 #include <softPwm.h>
5
6 #define address 0x48 //pcf8591 default address
7 #define pinbase 64 //any number above 64
8 #define A0 pinbase + 0
9 #define A1 pinbase + 1
10 #define A2 pinbase + 2
11 #define A3 pinbase + 3
12
13 #define ledPin 0
14 int main(void){
15 int value;
16 float voltage;
17 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
18 printf("setup wiringPi failed !");
19 return 1;
20 }
21 softPwmCreate(ledPin,0,100);
22 pcf8591Setup(pinbase,address);
23
24 while(1){
25 value = analogRead(A0); //read A0 pin
26 softPwmWrite(ledPin,value*100/255);
27 voltage = (float)value / 255.0 * 3.3; // calculate voltage
28 printf("ADC value : %d ,\tVoltage : %.2fV\n",value,voltage);
98 Capítulo 10 Photoresistor y LED www.freenove.com █

29 delay(100);
30 }
31 return 0;
32 }
Python Code 10.1.1 Nightlamp
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 09.1.1_Nightlamp del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/10.1.1_Nightlamp
2. Use el comando python para ejecutar el código Python “Nightlamp.py”. python
Nightlamp.py
Después de ejecutar el programa, cuando cubra la resistencia fotosensible o haga una linterna hacia el
fotorresistor, el brillo del LED aumentará o se debilitará. Y la ventana del terminal imprimirá el valor actual de la
tensión de entrada del pin PCF8591 AIN0 y la cantidad digital convertida.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import smbus
3 import time
4
5 address = 0x48
6 bus=smbus.SMBus(1)
7 cmd=0x40
8 ledPin = 11
9
10 def analogRead(chn):
11 value = bus.read_byte_data(address,cmd+chn)
12 return value
13
14 def analogWrite(value):
15 bus.write_byte_data(address,cmd,value)
16
17 def setup():
18 global p
19 GPIO.setmode(GPIO.BOARD)
20 GPIO.setup(ledPin,GPIO.OUT)
21 GPIO.output(ledPin,GPIO.LOW)
22
23 p = GPIO.PWM(ledPin,1000)
24 p.start(0)
25
26 def loop():
27 while True:
28 value = analogRead(0)
29 p.ChangeDutyCycle(value*100/255)
30 voltage = value / 255.0 * 3.3
█ www.freenove.com Capítulo 10 Photoresistor y LED 99

31 print 'ADC Value : %d, Voltage : %.2f'%(value,voltage)


32 time.sleep(0.01)
33
34 def destroy():
35 bus.close()
36 GPIO.cleanup()
37
38 if __name__ == '__main__':
39 print 'Program is starting ... '
40 setup()
41 try:
42 loop()
43 except KeyboardInterrupt:
44 destroy()
100 Capítulo 11 Termistor www.freenove.com █

Capítulo 11 Termistor
En este capítulo, aprenderemos otro tipo nuevo de resistencia, termistor.

Proyecto 11.1 Termómetro

La resistencia del termistor cambiará con el cambio de temperatura. Entonces podemos hacer un termómetro de
acuerdo con esta característica.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x14


GPIO Extension Board & Wire x1
BreadBoard x1
Thermistor x1 PCF8591 x1 Resistor 10kΩ x3
█ www.freenove.com Capítulo 11 Termistor 101

Conocimiento del componente

Thermistor
El termistor es una resistencia sensible a la temperatura. Cuando la temperatura cambia, la resistencia del
termistor cambiará. Con esta característica, podemos usar un termistor para detectar la intensidad de la
temperatura. Termistor y símbolo son los siguientes.

La relación entre el valor de resistencia y la temperatura del termistor es:


Rt=R*EXP [B*(1/T2-1/T1)]
Dónde:
Rt es la resistencia del termistor bajo la temperatura T2;
R está en la resistencia nominal del termistor bajo la temperatura T1;
EXP [n] es enésima potencia de E;
B es para índice térmico;
T1, T2 es la temperatura Kelvin (temperatura absoluta).
Temperatura Kelvin = temperatura 273.15 + celsius.

Los parámetros del termistor que utilizamos son: B = 3950, R = 10k, T1 = 25.
El método de conexión del circuito del termistor es similar al fotorresistor, como el siguiente método:

Podemos usar el valor medido por el pin analógico de UNO para obtener el valor de resistencia del termistor, y
luego podemos usar la fórmula para obtener el valor de temperatura.
En consecuencia, la fórmula de la temperatura puede concluirse:
T2 = 1/(1/T1 + ln(Rt/R)/B)
102 Capítulo 11 Termistor www.freenove.com █

Circuito

El circuito de este experimento es similar al del último capítulo. La única diferencia es que el fotorresistor es
reemplazado por el termistor.
Schematic diagram

Hardware connection
█ www.freenove.com Capítulo 11 Termistor 103

Código

En este código experimental, aún es necesario leer el valor de ADC, y la diferencia es que se usa una fórmula
específica para calcular el valor de la temperatura.
C Code 11.1.1 Thermometer
Primero observe el fenómeno experimental y luego analice el código.
Use el comando cd para ingresar al directorio 11.1.1_Thermometer del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/11.1.1_Thermometer
1. Use el siguiente comando para compilar "Termómetro.c" y genere el archivo ejecutable "Termómetro". La
opción "-lm" es necesaria.
gcc Thermometer.c –o Thermometer –lwiringPi –lm
2. Luego ejecuta el archivo generado “Thermometer”.
sudo ./Thermometer
Después de que se ejecuta el programa, la ventana del terminal imprimirá el valor actual de ADC, el valor de
voltaje y el valor de temperatura. Intente pellizcar el termistor (no toque el pin) con la mano durando un rato,
luego aumentará el valor de la temperatura.

El siguiente es el código:
1 #include <wiringPi.h>
2 #include <pcf8591.h>
3 #include <stdio.h>
4 #include <math.h>
5
6 #define address 0x48 //pcf8591 default address
7 #define pinbase 64 //any number above 64
8 #define A0 pinbase + 0
9 #define A1 pinbase + 1
10 #define A2 pinbase + 2
11 #define A3 pinbase + 3
12
13 int main(void){
104 Capítulo 11 Termistor www.freenove.com █

14 int adcValue;
15 float tempK,tempC;
16 float voltage,Rt;
17 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
18 printf("setup wiringPi failed !");
19 return 1;
20 }
21 pcf8591Setup(pinbase,address);
22 while(1){
23 adcValue = analogRead(A0); //read A0 pin
24 voltage = (float)adcValue / 255.0 * 3.3; // calculate voltage
25 Rt = 10 * voltage / (3.3 - voltage); //calculate resistance value of thermistor
26 tempK = 1/(1/(273.15 + 25) + log(Rt/10)/3950.0); //calculate temperature (Kelvin)
27 tempC = tempK -273.15; //calculate temperature (Celsius)
28 printf("ADC value : %d ,\tVoltage : %.2fV,
29 \tTemperature : %.2fC\n",adcValue,voltage,tempC);
30 delay(100);
31 }
32 return 0;
33 }

En el código, lea el valor de ADC del puerto PCF8591 A0 y luego calcule el voltaje y la resistencia del termistor de
acuerdo con la ley de Ohms. Finalmente, calcule la temperatura actual. de acuerdo con la fórmula frontal.
Python Code 11.1.1 Thermometer
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 11.1.1_Thermometer del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/11.1.1_Thermometer
2. Use el comando python para ejecutar el código python “Thermometer.py”.
python Thermometer.py
Después de que se ejecuta el programa, la ventana del terminal imprimirá el valor actual de ADC, el valor de
voltaje y el valor de temperatura. Intente pellizcar el termistor (no toque el pin) con la mano durando un rato,
luego aumentará el valor de la temperatura.

El siguiente es el código:
█ www.freenove.com Chapter 11 Thermistor 105

1 import RPi.GPIO as GPIO


2 import smbus
3 import time
4 import math
5
6 address = 0x48
7 bus=smbus.SMBus(1)
8 cmd=0x40
9
10 def analogRead(chn):
11 value = bus.read_byte_data(address,cmd+chn)
12 return value
13
14 def analogWrite(value):
15 bus.write_byte_data(address,cmd,value)
16
17 def setup():
18 GPIO.setmode(GPIO.BOARD)
19
20 def loop():
21 while True:
22 value = analogRead(0) #read A0 pin
23 voltage = value / 255.0 * 3.3 #calculate voltage
24 Rt = 10 * voltage / (3.3 - voltage) #calculate resistance value of thermistor
25 tempK = 1/(1/(273.15 + 25) + math.log(Rt/10)/3950.0) #calculate temperature
26 (Kelvin)
27 tempC = tempK -273.15 #calculate temperature (Celsius)
28 print 'ADC Value : %d, Voltage : %.2f, Temperature : %.2f'%(value,voltage,tempC)
29 time.sleep(0.01)
30
31 def destroy():
32 GPIO.cleanup()
33
34 if __name__ == '__main__':
35 print 'Program is starting ... '
36 setup()
37 try:
38 loop()
39 except KeyboardInterrupt:
40 destroy()
En el código, lea el valor de ADC del puerto PCF8591 A0 y luego calcule el voltaje y la resistencia del termistor de
acuerdo con la ley de Ohms. Finalmente, calcule la temperatura actual. de acuerdo con la fórmula frontal.
106 Capítulo 12 Joystick www.freenove.com █

Capítulo 12 Joystick
En el capítulo anterior, hemos aprendido a usar el potenciómetro rotativo. Ahora, aprendamos un nuevo Joystick
de módulo electrónico que funciona con el mismo principio que el potenciómetro rotativo.

Proyecto 12.1 Joystick

En este experimento, leeremos los datos de salida de Joystick e imprimiremos en la pantalla.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x12 M/F x5


GPIO Expansion Board & Wire x1
BreadBoard x1
PCF8591 x1 Resistor 10kΩ x2 Joystick x1
█ www.freenove.com Capítulo 12 Joystick 107

Conocimiento del componente

Joystick
Joystick es un tipo de sensor que se usa con los dedos, que se usa ampliamente en gamepad y control remoto.
Puede cambiar en la dirección Y o en la dirección X al mismo tiempo. Y también se puede presionar en la
dirección Z.
X
Y

Dos potenciómetros giratorios dentro del joystick están configurados para detectar la dirección de cambio
del dedo, y un botón pulsador en dirección vertical está configurado para detectar la acción de presionar. .

Cuando se leen los datos del joystick, hay algunos diferentes entre ejes: los datos de los ejes X e Y son analógicos,
que necesitan usar ADC. Los datos del eje Z son digitales, por lo que puede usar directamente el GPIO para leer, o
también puede usar ADC para leer.
108 Capítulo 12 Joystick www.freenove.com █

Circuito

Schematic diagram

Hardware connection
█ www.freenove.com Capítulo 12 Joystick 109

Código

En este código experimental, leeremos el valor ADC de los ejes X e Y de Joystick, y leeremos la calidad digital del
eje Z, luego imprimiremos estos datos.
C Code 12.1.1 Joystick
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 12.1.1_Joystick del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/12.1.1_ Joystick
2. Utilice el siguiente comando para compilar "Joystick.c" y generar el archivo ejecutable "Joystick.c". La opción
"-lm" es necesaria.
gcc Joystick.c –o Joystick–lwiringPi –lm
3. Luego ejecuta el archivo generado "Joystick".
sudo ./Joystick
Después de ejecutar el Programa, la ventana del terminal imprimirá los datos de 3 ejes X, Y, Z. Y al cambiar el
Joystick o al presionarlo, los datos cambiarán.

El flujo es el código:
1 #include <wiringPi.h>
2 #include <pcf8591.h>
3 #include <stdio.h>
4 #include <softPwm.h>
5
6 #define address 0x48 //pcf8591 default address
7 #define pinbase 64 //any number above 64
8 #define A0 pinbase + 0
9 #define A1 pinbase + 1
10 #define A2 pinbase + 2
11 #define A3 pinbase + 3
12
13 #define Z_Pin 1 //define pin for axis Z
14
15 int main(void){
16 int val_X,val_Y,val_Z;
17 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
110 Capítulo 12 Joystick www.freenove.com █

18 printf("setup wiringPi failed !");


19 return 1;
20 }
21 pinMode(Z_Pin,INPUT); //set Z_Pin as input pin and pull-up mode
22 pullUpDnControl(Z_Pin,PUD_UP);
23 pcf8591Setup(pinbase,address); //initialize PCF8591
24
25 while(1){
26 val_Z = digitalRead(Z_Pin); //read digital quality of axis Z
27 val_Y = analogRead(A1); //read analog quality of axis X and Y
28 val_X = analogRead(A2);
29 printf("val_X: %d ,\tval_Y: %d ,\tval_Z: %d \n",val_X,val_Y,val_Z);
30 delay(100);
31 }
32 return 0;
33 }
En el código, configure Z_Pin para activar el modo de entrada. En while cycle of main function, use analogRead ()
para leer el valor de los ejes X e Y y utilice digitalRead () para leer el valor del eje Z, luego imprímalos.
while(1){
val_Z = digitalRead(Z_Pin); //read digital quality of axis Z
val_Y = analogRead(A1); //read analog quality of axis X and Y

val_X = analogRead(A2);
printf("val_X: %d ,\tval_Y: %d ,\tval_Z: %d \n",val_X,val_Y,val_Z);
delay(100);
}
█ www.freenove.com Capítulo 12 Joystick 111

Python Code 12.1.1 Joystick


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 12.1.1_Joystick del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/12.1.1_ Joystick
2. Use el comando python para ejecutar el código python."Joystick.py".
python Joystick.py
Después de ejecutar el Programa, la ventana del terminal imprimirá los datos de 3 ejes X, Y, Z. Y al cambiar el
Joystick o al presionarlo, los datos cambiarán.

El siguiente es el código del programa:


1 import RPi.GPIO as GPIO
2 import smbus
3 import time
4
5 address = 0x48
6 bus=smbus.SMBus(1)
7 cmd=0x40
8 Z_Pin = 12 #define pin for Z_Pin
9 def analogRead(chn): #read ADC value
10 bus.write_byte(address,cmd+chn)
11 value = bus.read_byte(address)
12 value = bus.read_byte(address)
13 #value = bus.read_byte_data(address,cmd+chn)
14 return value
15
16 def analogWrite(value):
17 bus.write_byte_data(address,cmd,value)
18
19 def setup():
20 global p_Red,p_Green,p_Blue
21 GPIO.setmode(GPIO.BOARD)
22 GPIO.setup(Z_Pin,GPIO.IN,GPIO.PUD_UP) #set Z_Pin to pull-up mode
23 def loop():
24 while True:
25 val_Z = GPIO.input(Z_Pin) #read digital quality of axis Z
26 val_Y = analogRead(1) #read analog quality of axis X and Y
27 val_X = analogRead(2)
112 Capítulo 12 Joystick www.freenove.com █

28 print 'value_X: %d ,\tvlue_Y: %d ,\tvalue_Z: %d'%(val_X,val_Y,val_Z)


29 time.sleep(0.01)
30
31 def destroy():
32 bus.close()
33 GPIO.cleanup()
34
35 if __name__ == '__main__':
36 print 'Program is starting ... '
37 setup()
38 try:
39 loop()
40 except KeyboardInterrupt:
41 destroy()
En el código, configure Z_Pin para activar el modo de entrada. En while cycle of loop, use analogRead () para leer
el valor de los ejes X e Y y use GPIO.input () para leer el valor del eje Z, luego imprímalos.
while True:
val_Z = GPIO.input(Z_Pin) #read digital quality of axis Z
val_Y = analogRead(1) #read analog quality of axis X and Y
val_X = analogRead(2)
print 'value_X: %d ,\tvlue_Y: %d ,\tvalue_Z: %d'%(val_X,val_Y,val_Z)
time.sleep(0.01)
█ www.freenove.com Capítulo 13 Motor y conductor 113

Capítulo 13 Motor & Driver


En este capítulo, aprenderemos algunos conocimientos sobre el motor de CC y la unidad de motor de CC, y cómo
controlar la velocidad y la dirección del motor.

Proyecto 13.1 Motor de control con potenciómetro

En este experimento, se usa un potenciómetro para controlar el motor. Cuando el potenciómetro está en la
posición de punto medio, el motor parará de girar, y cuando se aleje de la posición media, la velocidad del motor
aumentará. Cuando el potenciómetro se desplaza a extremos limitados, la velocidad del motor alcanza el
máximo. Cuando la posición del potenciómetro está en el lado diferente de la posición media, la dirección del
motor es diferente.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x22


GPIO Extension Board & Wire x1
BreadBoard x1
Breadboard power module x1 9V Battery (provided by yourself) & battery cable

Rotary potentiometer x1 Motor x1 Resistor 10kΩ x2 PCF8591 x1 L293D


114 Capítulo 13 Motor & Driver www.freenove.com █

Conocimiento del componente


Motor
El motor es un dispositivo que convierte la energía eléctrica en energía mecánica. El motor consta de dos partes:
estator y rotor. Cuando el motor funciona, la parte estácionaria es estator, y la parte giratoria es rotor. El estator
suele ser la carcasa exterior del motor y tiene terminales para conectarlo a la corriente. El rotor suele ser el eje
del motor y puede conducir otros dispositivos mecánicos para funcionar. El siguiente diagrama es un pequeño
motor de CC con dos pines.

Cuando el motor se conecta a la fuente de alimentación, girará en una dirección. Invierta la polaridad de la
fuente de alimentación, luego el motor gira en dirección opuesta.

+ - - +
L293D
L293D es un chip integrado con un motor de 4 canales. Puede conducir un motor unidireccional con 4 puertos o
un motor bidireccional con 2 puertos o un motor paso a paso.
█ www.freenove.com Capítulo 13 Motor & Driver 115

La descripción del puerto del módulo L293D es la siguiente:


Pin name Pin number Description
In x 2, 7, 10, 15 Canal x pin de entrada de señal digital
Out x 3, 6, 11, 14 Canal x pin de salida, entrada de nivel alto o bajo de acuerdo con In x pin,
conectarse a + Vmotor o 0V
Enable1 1 Canal 1 y canal 2 habilitan el pin, habilitación de alto nivel
Enable2 9 Channel 3 y Channel 4 enable pin, habilitación de alto nivel
0V 4, 5, 12, 13 Cátodo de potencia (GND)
+V 16 Electrodo positivo (VCC) de la fuente de alimentación, voltaje de suministro 4.5~36V
+Vmotor 8 Electrodo positivo de la fuente de alimentación de carga, proporcionar suministro de
energía para la salida pin x, the supply voltage is +V~36V

Para obtener más detalles, consulte la hoja de datos.


Cuando se utiliza L293D para impulsar el motor de CC, generalmente hay dos tipos de conexión.
La siguiente conexión utiliza un canal y puede controlar la velocidad del motor a través de PWM, pero el motor
solo puede girar en una dirección.

La siguiente conexión utiliza dos canales: un canal emite ondas PWM y otro canal conecta GND para que pueda
controlar la velocidad del motor. Cuando se intercambian estas dos señales de canal, se puede invertir la
dirección actual del motor y el motor girará en dirección inversa. Esto no solo puede controlar la velocidad del
motor, sino que también puede controlar la dirección del motor.

GND

GND

En uso real, el motor generalmente está conectado al canal 1 y 2, emite un nivel diferente a in1 e in2 para
controlar la dirección de rotación del motor, y la salida de onda PWM al puerto Enable1 para controlar la
velocidad de rotación del motor. O bien, conecte el motor al canal 3 y 4, envíe un nivel diferente a in3 e in4
para controlar la dirección de rotación del motor, y envíe la onda PWM al pin Enable2 para controlar la
velocidad de rotación del motor.
116 Capítulo 13 Motor & Driver www.freenove.com █

Circuito

Al conectar el circuito, preste atención a eso porque el motor es un componente de alta potencia, no use la
potencia provista por el RPi, lo que puede dañar su RPi. el circuito lógico puede ser alimentado por energía RPi o
por una fuente de alimentación externa que debe tener conexión a tierra con RPi.
Schematic diagram
█ www.freenove.com Capítulo 13 Motor & Driver 117

Hardware connection

Change the jumper cap


position to change supply
Logic voltage supply voltage for motor.
end ( must select
3.3V)
118 Capítulo 13 Motor & Driver www.freenove.com █

Código

En este código experimental, primero lea el valor de ADC, y luego controle la dirección de rotación y la velocidad
del motor de acuerdo con el valor del ADC.
C Code 13.1.1 Motor
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 13.1.1_Motor del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/13.1.1_Motor
2. Use el siguiente comando para compilar "Motor.c" y generar el archivo ejecutable "Motor". La opción "-lm" y
"-lpthread" es necesaria.
gcc Motor.c –o Motor–lwiringPi –lm -lpthread
3. A continuación, ajuste el archivo generado ”Motor”.
sudo ./Motor
Después de ejecutar el programa, mueva el potenciómetro, luego la velocidad de rotación y la dirección del motor cambiarán con él.
Y cuando el potenciómetro se gira a la posición de punto medio, el motor deja de funcionar. Cuando se aleje de la posición
intermedia, la velocidad del motor aumentará. Cuando a ambos extremos, la velocidad del motor alcanza el máximo. Cuando el
potenciómetro se gira a un lado diferente de la posición media, el motor funcionará con una dirección diferente. Mientras tanto, el
terminal imprimirá el valor ADC del potenciómetro, la dirección del motor y el ciclo de trabajo PWM utilizado para controlar la
velocidad del motor.

El siguiente es el código:
1 #include <wiringPi.h>
2 #include <pcf8591.h>
3 #include <stdio.h>
4 #include <softPwm.h>
5 #include <math.h>
6 #include <stdlib.h>
7
8 #define address 0x48 //pcf8591 default address
9 #define pinbase 64 //any number above 64
█ www.freenove.com Capítulo 13 Motor & Driver 119

10 #define A0 pinbase + 0
11 #define A1 pinbase + 1
12 #define A2 pinbase + 2
13 #define A3 pinbase + 3
14
15 #define motoRPin1 2 // define the pin connected to L293D
16 #define motoRPin2 0
17 #define enablePin 3
18 // Map function: map the value from a range of mapping to another range.
19 long map(long value,long fromLow,long fromHigh,long toLow,long toHigh){
20 return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow;
21 }
22 //motor function: determine the direction and speed of the motor according to the ADC
23 value to be input.
24 void motor(int ADC){
25 int value = ADC -128;
26 if(value>0){
27 digitalWrite(motoRPin1,HIGH);
28 digitalWrite(motoRPin2,LOW);
29 printf("turn Forward...\n");
30 }
31 else if (value<0){
32 digitalWrite(motoRPin1,LOW);
33 digitalWrite(motoRPin2,HIGH);
34 printf("turn Back...\n");
35 }
36 else {
37 digitalWrite(motoRPin1,LOW);
38 digitalWrite(motoRPin2,LOW);
39 printf("Motor Stop...\n");
40 }
41 softPwmWrite(enablePin,map(abs(value),0,128,0,255));
42 printf("The PWM duty cycle is %d%%\n",abs(value)*100/127);//print the PMW duty cycle.
43 }
44 int main(void){
45 int value;
46 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
47 printf("setup wiringPi failed !");
48 return 1;
49 }
50 pinMode(enablePin,OUTPUT);// set mode for the pin
51 pinMode(motoRPin1,OUTPUT);
52 pinMode(motoRPin2,OUTPUT);
53 softPwmCreate(enablePin,0,100);// define PMW pin
120 Capítulo 13 Motor & Driver www.freenove.com █

54 pcf8591Setup(pinbase,address);//initialize PCF8591
55
56 while(1){
57 value = analogRead(A0); //read A0 pin
58 printf("ADC value : %d \n",value);
59 motor(value); // start the motor
60 delay(100);
61 }
62 return 0;
63 }

Hemos estado familiarizados con la lectura del valor de ADC. Entonces, aprendamos directamente el motor de vacío de la subfunción
(int ADC): primero, compare el valor de ADC con 128 (valor correspondiente al punto medio). Cuando el valor actual de ADC es
mayor, haga que la salida de motoRPin1 sea de alto nivel y la salida de motoRPin2 de bajo nivel para controlar que el motor funcione
con la dirección de corotación. Cuando el valor actual de ADC, haga que la salida de motoRPin1 sea de bajo nivel y la salida de
motoRPin2 de alto nivel para controlar la marcha con dirección inversa. Cuando el valor ADC es igual a 128, haga que motoRPin1 y
motoRPin2 salgan a bajo nivel, luego el motor se detiene. Y luego determine el ciclo de trabajo de PWM de acuerdo con la diferencia
entre el valor de ADC y 128. Debido a que el valor de la diferencia absoluta se mantiene dentro de 0-128. Necesitamos usar la
función secundaria map () mapeando el valor de la diferencia al rango de 0-255. Finalmente imprima el ciclo de trabajo.

void motor(int ADC){


int value = ADC -128;
if(value>0){
digitalWrite(motoRPin1,HIGH);
digitalWrite(motoRPin2,LOW);
printf("turn Forward...\n");
}
else if (value<0){
digitalWrite(motoRPin1,LOW);
digitalWrite(motoRPin2,HIGH);
printf("turn Backward...\n");
}
else {
digitalWrite(motoRPin1,LOW);
digitalWrite(motoRPin2,LOW);
printf("Motor Stop...\n");
}
softPwmWrite(enablePin,map(abs(value),0,128,0,255));
printf("The PWM duty cycle is %d%%\n",abs(value)*100/127);// print out PMW duty
cycle.
}
█ www.freenove.com Capítulo 13 Motor & Driver 121

Pyhton Code 13.1.1 Motor


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 13.1.1_Motor del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/13.1.1_Motor
2. Use el comando python para ejecutar el código python“Motor.py”.
python Motor.py
Después de ejecutar el programa, mueva el potenciómetro, luego la velocidad de rotación y la dirección del
motor cambiarán con él. Y cuando el potenciómetro se gira a la posición de punto medio, el motor deja de
funcionar. Cuando se aleje de la posición intermedia, la velocidad del motor aumentará. Cuando a ambos
extremos, la velocidad del motor alcanza el máximo. Cuando el potenciómetro se gira a un lado diferente de la
posición media, el motor funcionará con una dirección diferente. Mientras tanto, el terminal imprimirá el valor
ADC del potenciómetro, la dirección del motor y el ciclo de trabajo PWM utilizado para controlar la velocidad del
motor.

The following is the code:


1 import RPi.GPIO as GPIO
2 import smbus
3 import time
4
5 address = 0x48
6 bus=smbus.SMBus(1)
7 cmd=0x40
8 # define the pin connected to L293D
9 motoRPin1 = 13
10 motoRPin2 = 11
11 enablePin = 15
12
13 def analogRead(chn):
14 value = bus.read_byte_data(address,cmd+chn)
15 return value
16
17 def analogWrite(value):
18 bus.write_byte_data(address,cmd,value)
19
122 Capítulo 13 Motor & Driver www.freenove.com █

20 def setup():
21 global p
22 GPIO.setmode(GPIO.BOARD) # set mode for pin
23 GPIO.setup(motoRPin1,GPIO.OUT)
24 GPIO.setup(motoRPin2,GPIO.OUT)
25 GPIO.setup(enablePin,GPIO.OUT)
26
27 p = GPIO.PWM(enablePin,1000)# creat PWM
28 p.start(0)
29 #mapNUM function: map the value from a range of mapping to another range.
30
31 def mapNUM(value,fromLow,fromHigh,toLow,toHigh):
32 return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow
33 #motor function: determine the direction and speed of the motor according to the ADC
34 value to be input.
35 def motor(ADC):
36 value = ADC -128
37 if (value > 0):
38 GPIO.output(motoRPin1,GPIO.HIGH)
39 GPIO.output(motoRPin2,GPIO.LOW)
40 print 'Turn Forward...'
41 elif (value < 0):
42 GPIO.output(motoRPin1,GPIO.LOW)
43 GPIO.output(motoRPin2,GPIO.HIGH)
44 print 'Turn Backward...'
45 else :
46 GPIO.output(motoRPin1,GPIO.LOW)
47 GPIO.output(motoRPin2,GPIO.LOW)
48 print 'Motor Stop...'
49 p.start(mapNUM(abs(value),0,128,0,100))
50 print 'The PWM duty cycle is %d%%\n'%(abs(value)*100/127) #print PMW duty cycle.
51
52 def loop():
53 while True:
54 value = analogRead(0)
55 print 'ADC Value : %d'%(value)
56 motor(value)
57 time.sleep(0.01)
58
59 def destroy():
60 bus.close()
61 GPIO.cleanup()
62
63 if __name__ == '__main__':
█ www.freenove.com Capítulo 13 Motor & Driver 123

64 print 'Program is starting ... '


65 setup()
66 try:
67 loop()
68 except KeyboardInterrupt:
69 destroy()

Hemos estado familiarizados con la lectura del valor de ADC. Entonces, aprendamos directamente el motor de definición de
subfunción (ADC): primero, compare el valor de ADC con 128 (valor correspondiente al punto medio). Cuando el valor actual de ADC
es mayor, haga que la salida de motoRPin1 sea de alto nivel y la salida de motoRPin2 de bajo nivel para controlar que el motor
funcione con la dirección de corotación. Cuando el valor actual de ADC, haga que la salida de motoRPin1 sea de bajo nivel y la salida
de motoRPin2 de alto nivel para controlar la marcha con dirección inversa. Cuando el valor ADC es igual a 128, haga que motoRPin1 y
motoRPin2 salgan a bajo nivel, luego el motor se detiene. Y luego determine el ciclo de trabajo de PWM de acuerdo con la diferencia
entre el valor de ADC y 128. Debido a que el valor de la diferencia absoluta se mantiene dentro de 0-128. Necesitamos usar la función
secundaria map () mapeando el valor de la diferencia al rango de 0-255. Finalmente imprima el ciclo de trabajo.

def motor(ADC):
value = ADC -128
if (value > 0):
GPIO.output(motoRPin1,GPIO.HIGH)
GPIO.output(motoRPin2,GPIO.LOW)
print 'Turn Forward...'
elif (value < 0):
GPIO.output(motoRPin1,GPIO.LOW)
GPIO.output(motoRPin2,GPIO.HIGH)
print 'Turn Backward...'
else :
GPIO.output(motoRPin1,GPIO.LOW)
GPIO.output(motoRPin2,GPIO.LOW)
print 'Motor Stop...'
p.start(mapNUM(abs(value),0,128,0,100))
print 'The PWM duty cycle is %d%%\n'%(abs(value)*100/127) #print PMW duty cycle.
124 Capítulo 14 Relé y motor www.freenove.com █

Capítulo 14 Relé y motor


En este capítulo, aprenderemos un tipo de módulo de conmutación especial, módulo de relés.

Proyecto 14.1.1 Relé & Motor

En este experimento, usaremos un botón para controlar un relé y conducir el motor.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x8


GPIO Expansion Board & Wire x1
BreadBoard x1
9V battery (prepared by yourself) & battery line

Breadboard extension x1 Resistor 10kΩ x2 Resistor 1kΩ x1 Resistor 220Ω x1

NPN Relay x1 Motor x1 Push button x1 LED x1 Diode x1


transistor x1
█ www.freenove.com Capítulo 14 Relé y motor 125

Conocimiento del componente

Relay
El relé es un interruptor seguro que puede usar un circuito de baja potencia para controlar el circuito de alta
potencia. Consiste en electroimán y contactos. El electroimán está controlado por un circuito de baja potencia y
los contactos se usan en un circuito de alta potencia. Cuando el electroimán está energizado, atraerá contactos.
El siguiente es un diagrama de principio del relé común y el símbolo de función y circuito del relé 5V utilizado en
este experimento:
Diagram Feature: Symbol

El pin 5 y el pin 6 están conectados entre sí en el interior. Cuando el pin3 y 4 de la bobina se conectan a la fuente
de alimentación de 5V, el pin 1 se desconectará a los pin 5 y 6 y el pin 2 se conectará a los pin 5 y 6. Así que el pin
1 se llama extremo cerrado, el pin 2 se llama extremo abierto.
Inductor
La unidad de inductancia (L) es la henry (H). 1H = 1000mH, 1mH = 1000μH.
Inductor es un dispositivo de almacenamiento de energía que convierte la energía eléctrica en energía
magnética. Generalmente, consiste en una bobina de arrollamiento, con una cierta cantidad de inductancia. El
inductor obstaculizará la corriente cambiante que pasa a través del inductor. Cuando la corriente que pasa a
través del inductor aumenta, intentará obstaculizar la tendencia creciente de la corriente; y cuando la corriente
que pasa a través del inductor disminuye, intentará obstaculizar la tendencia decreciente de la corriente.
Entonces la corriente que pasa a través del inductor no es transitoria.

El circuito de referencia para el relé es el siguiente. La bobina del relé puede ser equivalente a un inductor,
cuando el transistor desconecta la fuente de alimentación del relé, la corriente en la bobina del relé no puede
detenerse inmediatamente, lo que causa un impacto en la fuente de alimentación. Por lo tanto, un diodo
paralelo se conectará a ambos extremos del pin de la bobina del relé en la dirección de inversión, luego la
corriente pasará a través del diodo, evitando el impacto en la fuente de alimentación.
126 Capítulo 14 Relé y motor www.freenove.com █

Circuito

Preste atención a la tensión de la fuente de alimentación necesaria para los componentes en el circuito, en los
que el relé necesita una tensión de alimentación de 5V y el motor necesita 3.3V. Además, se utiliza un LED como
indicador del relé (encendido o apagado).
Schematic diagram
█ www.freenove.com Capítulo 14 Relé y motor 127

Hardware connection
128 Capítulo 14 Relé y motor www.freenove.com █

Código

El código experimental está en la misma lógica que TableLamp. Presione el botón para conducir el transistor
realizado. Debido a que el relé y el LED están conectados en paralelo, se abrirán al mismo tiempo. Y si presiona el
botón otra vez, se cerrarán.
C Code 14.1.1 Relay
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar 14.1.1_Relajar el directorio del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/14.1.1_Relay
2. Utilice el siguiente comando para compilar "Relay.c" y generar el archivo ejecutable "Relay".
gcc Relay.c –o Relay –lwiringPi
3. Ejecute el archivo generado "Relay".
sudo ./Relay
Después de ejecutar el programa, presione el botón, luego se abre el relevador, el motor comienza a girar y se
enciende el LED. Si presiona el botón nuevamente, el relé se cierra, el motor se detiene y el LED se apaga.
El siguiente es el código del programa:

1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define relayPin 0 //define the relayPin
5 #define buttonPin 1 //define the buttonPin
6 int relayState=LOW; //store the State of relay
7 int buttonState=HIGH; //store the State of button
8 int lastbuttonState=HIGH;//store the lastState of button
9 long lastChangeTime; //store the change time of button state
10 long captureTime=50; //set the button state stable time
11 int reading;
12 int main(void)
13 {
14 if(wiringPiSetup() == -1){ //when initialize wiring fairelay,print messageto screen
15 printf("setup wiringPi fairelay !");
16 return 1;
17 }
18 printf("Program is starting...\n");
19 pinMode(relayPin, OUTPUT);
20 pinMode(buttonPin, INPUT);
21 pullUpDnControl(buttonPin, PUD_UP); //pull up to high level
22 while(1){
23 reading = digitalRead(buttonPin); //read the current state of button
24 if( reading != lastbuttonState){ //if the button state has changed ,record the
25 time point
26 lastChangeTime = millis();
█ www.freenove.com Capítulo 14 Relé y motor 129

27 }
28 //if changing-state of the button last beyond the time we set,we considered that
29 //the current button state is an effective change rather than a buffeting
30 if(millis() - lastChangeTime > captureTime){
31 //if button state is changed ,update the data.
32 if(reading != buttonState){
33 buttonState = reading;
34 //if the state is low ,the action is pressing
35 if(buttonState == LOW){
36 printf("Button is pressed!\n");
37 relayState = !relayState;
38 if(relayState){
39 printf("turn on relay ...\n");
40 }
41 else {
42 printf("turn off relay ...\n");
43 }
44 }
45 //if the state is high ,the action is releasing
46 else {
47 printf("Button is released!\n");
48 }
49 }
50 }
51 digitalWrite(relayPin,relayState);
52 lastbuttonState = reading;
53 }
54
55 return 0;
56 }
El código está en la misma lógica que el código TableLamp anterior.

Pyhton Code 14.1.1 Relay


Primero observe el fenómeno experimental, y luego analice el código.
1. Use el comando cd para ingresar al directorio 14.1.1_Relay del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/14.1.1_ Relay
2. Use el comando python para ejecutar el código "Relay.py".
python Relay.py
Después de ejecutar el programa, presione el botón, luego se abre el relevador, el motor comienza a girar y se
enciende el LED. Si presiona el botón nuevamente, el relé se cierra, el motor se detiene y el LED se apaga.
El siguiente es el código del programa:

1 import RPi.GPIO as GPIO


2
130 Capítulo 14 Relé y motor www.freenove.com █

3 relayPin = 11 # define the relayPin


4 buttonPin = 12 # define the buttonPin
5 relayState = False
6
7 def setup():
8 print 'Program is starting...'
9 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
10 GPIO.setup(relayPin, GPIO.OUT) # Set relayPin's mode is output
11 GPIO.setup(buttonPin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Set buttonPin's mode is
12 input, and pull up to high
13
14 def buttonEvent(channel):
15 global relayState
16 print 'buttonEvent GPIO%d'%channel
17 relayState = not relayState
18 if relayState :
19 print 'Turn on relay ... '
20 else :
21 print 'Turn off relay ... '
22 GPIO.output(relayPin,relayState)
23
24 def loop():
25 #Button detect
26 GPIO.add_event_detect(buttonPin,GPIO.FALLING,callback = buttonEvent,bouncetime=300)
27 while True:
28 pass
29
30 def destroy():
31 GPIO.output(relayPin, GPIO.LOW) # relay off
32 GPIO.cleanup() # Release resource
33
34 if __name__ == '__main__': # Program start from here
35 setup()
36 try:
37 loop()
38 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
39 will be executed.
40 destroy()
El código está en la misma lógica que el código TableLamp anterior.
█ www.freenove.com Capítulo 15 Servo 131

Capítulo 15 Servo
Hemos aprendido cómo controlar la velocidad y la dirección del motor antes. En este capítulo, aprenderemos un
tipo de motor que puede rotar a un ángulo específico, el servo.

Proyecto 15.1 Servo Sweep

Primero, aprendamos cómo hacer que el servo gire.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x3


GPIO Expansion Board & Wire x1
BreadBoard x1
Servo x1
132 Capítulo 15 Servo www.freenove.com █

Component knowledge

Servo
Servo es un sistema de autocontrol que consta de un motor de CC, engranaje de reducción, sensor y circuito de
control. Por lo general, puede rotar en el rango de 180 grados. El servo puede generar un mayor torque y es
ampliamente utilizado en aeromodelos, robots, etc. Tiene tres líneas, incluidas dos para la línea de alimentación
eléctrica positiva (2-VCC, roja), negativa (3-GND, marrón) y la línea de señal (1-señal, naranja).

Usamos señal PWM de 50Hz con un ciclo de trabajo en un cierto rango para conducir el servo. El tiempo de
duración de 0.5ms-2.5ms de alto nivel de ciclo único de PWM corresponde al ángulo del servo de 0 grados - 180
grados linealmente. Parte de los valores correspondientes son los siguientes:
High level time Servo angle
0.5ms 0 degree
1ms 45 degree
1.5ms 90 degree
2ms 135 degree
2.5ms 180 degree

Cuando cambie la señal del servo, el servo girará a la posición designada.


█ www.freenove.com Capítulo 15 Servo 133

Circuito

Preste atención a que la fuente de alimentación para el motor paso a paso es 5v, y no confunda la secuencia de línea.
Schematic diagram

Hardware connection
134 Capítulo 15 Servo www.freenove.com █

Código

En este experimento, hacemos que el servo gire de 0 grados a 180 grados, y luego de 180 grados a 0 grados.
C Code 15.1.1 Sweep
Primero observe el fenómeno experimental y luego analice el código.

1. Use el comando cd para ingresar el directorio 15.1.1_Sweep del código C.


cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/15.1.1_Sweep
2. Use el siguiente comando para compilar "Sweep.c" y generar el archivo ejecutable "Sweep". gcc
Sweep.c –o Sweep –lwiringPi
3. Ejecute el archivo generado "Sweep".
sudo ./Sweep
Después de que se ejecuta el programa, el servo girará de 0 grados a 180 grados, y luego de 180 grados a 0
grados, circularmente.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <softPwm.h>
3 #include <stdio.h>
4 #define OFFSET_MS 3 //Define the unit of servo pulse offset: 0.1ms
5 #define SERVO_MIN_MS 5+OFFSET_MS //define the pulse duration for minimum angle of
6 servo
7 #define SERVO_MAX_MS 25+OFFSET_MS //define the pulse duration for maximum angle of
8 servo
9
10 #define servoPin 1 //define the GPIO number connected to servo
11 long map(long value,long fromLow,long fromHigh,long toLow,long toHigh){
12 return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow;
13 }
14 void servoInit(int pin){ //initialization function for servo PMW pin
15 softPwmCreate(pin, 0, 200);
16 }
17 void servoWrite(int pin, int angle){ //Specif a certain rotation angle (0-180) for the
18 servo
19 if(angle > 180)
20 angle = 180;
21 if(angle < 0)
22 angle = 0;
23 softPwmWrite(pin,map(angle,0,180,SERVO_MIN_MS,SERVO_MAX_MS));
24 }
25 void servoWriteMS(int pin, int ms){ //specific the unit for pulse(5-25ms) with
26 specific duration output by servo pin: 0.1ms
27 if(ms > SERVO_MAX_MS)
28 ms = SERVO_MAX_MS;
█ www.freenove.com Capítulo 15 Servo 135

29 if(ms < SERVO_MIN_MS)


30 ms = SERVO_MIN_MS;
31 softPwmWrite(pin,ms);
32 }
33
34 int main(void)
35 {
36 int i;
37 if(wiringPiSetup() == -1){ //when initialize wiring faiservo,print messageto screen
38 printf("setup wiringPi faiservo !");
39 return 1;
40 }
41 printf("Program is starting ...\n");
42 servoInit(servoPin); //initialize PMW pin of servo
43 while(1){
44 for(i=SERVO_MIN_MS;i<SERVO_MAX_MS;i++){ //make servo rotate from minimum angle
45 to maximum angle
46 servoWriteMS(servoPin,i);
47 delay(10);
48 }
49 delay(500);
50 for(i=SERVO_MAX_MS;i>SERVO_MIN_MS;i--){ //make servo rotate from maximum angle
51 to minimum angle
52
53 servoWriteMS(servoPin,i);
54 delay(10);
55 }
56 delay(500);
57 }
58 return 0;
59 }
Se requiere un pulso de 50 Hz, concretamente un ciclo de 20 ms, para controlar Servo. En la función
softPwmCreate (int pin, int initialValue, int pwmRange), la unidad del tercer parámetro pwmRange es 100US, es
decir, 0.1ms. Para obtener el PWM con un ciclo de 20 ms, el pwmRange debería establecerse en 200. Por lo
tanto, en la función secundaria de servoInit (), creamos un pin PWM con pwmRange 200.
void servoInit(int pin){ //initialization function for servo PMW pin
softPwmCreate(pin, 0, 200);
}

Como 0-180 grados de servo corresponde a ancho de pulso PWM 0.5-2.5ms, con PwmRange 200 y unidad 0.1ms.
Entonces, en la función softPwmWrite (int pin, int value), el alcance 5-25 del valor del parámetro corresponde a
0-180 grados de servo. Además, el número escrito en la subfunción servoWriteMS () debería estar dentro del
rango de 5-25. Sin embargo, en la práctica, debido al error de fabricación de cada servo, el ancho del pulso
también tendrá desviación. Entonces, definimos un ancho de pulso mínimo y uno máximo y un desplazamiento
de error.
136 Capítulo 15 Servo www.freenove.com █

#define OFFSET_MS 3 //Define the unit of servo pulse offset: 0.1ms


#define SERVO_MIN_MS 5+OFFSET_MS //define the pulse duration for minimum angle of
servo
#define SERVO_MAX_MS 25+OFFSET_MS //define the pulse duration for maximum angle of
servo
……
void servoWriteMS(int pin, int ms){
if(ms > SERVO_MAX_MS)
ms = SERVO_MAX_MS;
if(ms < SERVO_MIN_MS)
ms = SERVO_MIN_MS;
softPwmWrite(pin,ms);
}
En la subfunción servoWrite (), ingrese directamente el ángulo (0-180 grados), y asigne el ángulo al ancho del
pulso y luego déjelo salir.
void servoWrite(int pin, int angle){ //Specif a certain rotation angle (0-180) for the
servo
if(angle > 180)
angle = 180;
if(angle < 0)
angle = 0;
softPwmWrite(pin,map(angle,0,180,SERVO_MIN_MS,SERVO_MAX_MS));
}
Finalmente, en el ciclo "while" de la función principal, use dos ciclo "for" para hacer el servo ratate de 0 grados a
180 grados, y luego de 180 grados a 0 grados.
while(1){
for(i=SERVO_MIN_MS;i<SERVO_MAX_MS;i++){ //make servo rotate from minimum angle
to maximum angle
servoWriteMS(servoPin,i);
delay(10);
}
delay(500);
for(i=SERVO_MAX_MS;i>SERVO_MIN_MS;i--){ //make servo rotate from maximum angle
to minimum angle
servoWriteMS(servoPin,i);
delay(10);
}
delay(500);
}
█ www.freenove.com Capítulo 15 Servo 137

Pyhton Code 15.1.1 Sweep


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar el directorio 15.1.1_Sweep del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/15.1.1_Sweep
2. Use el comando python para ejecutar el código "Sweep.py".
python Sweep.py
Después de que se ejecuta el programa, el servo girará de 0 grados a 180 grados, y luego de 180 grados a 0
grados, circularmente.

El siguiente es el código del programa:


1 import RPi.GPIO as GPIO
2 import time
3 OFFSE_DUTY = 0.5 #define pulse offset of servo
4 SERVO_MIN_DUTY = 2.5+OFFSE_DUTY #define pulse duty cycle for minimum angle of servo
5 SERVO_MAX_DUTY = 12.5+OFFSE_DUTY #define pulse duty cycle for maximum angle of servo
6 servoPin = 12
7
8 def map( value, fromLow, fromHigh, toLow, toHigh):
9 return (toHigh-toLow)*(value-fromLow) / (fromHigh-fromLow) + toLow
10
11 def setup():
12 global p
13 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
14 GPIO.setup(servoPin, GPIO.OUT) # Set servoPin's mode is output
15 GPIO.output(servoPin, GPIO.LOW) # Set servoPin to low
16
17 p = GPIO.PWM(servoPin, 50) # set Frequece to 50Hz
18 p.start(0) # Duty Cycle = 0
19
20 def servoWrite(angle): # make the servo rotate to specific angle (0-180 degrees)
21 if(angle<0):
22 angle = 0
23 elif(angle > 180):
24 angle = 180
25 p.ChangeDutyCycle(map(angle,0,180,SERVO_MIN_DUTY,SERVO_MAX_DUTY))#map the angle to
26 duty cycle and output it
27
28 def loop():
29 while True:
30 for dc in range(0, 181, 1): #make servo rotate from 0° to 180°
31 servoWrite(dc) # Write to servo
32 time.sleep(0.001)
33 time.sleep(0.5)
34 for dc in range(180, -1, -1): #make servo rotate from 180°to 0°
138 Capítulo 15 Servo www.freenove.com █

35
36 servoWrite(dc)
37 time.sleep(0.001)
38 time.sleep(0.5)
39
40 def destroy():
41 p.stop()
42 GPIO.cleanup()
43
44 if __name__ == '__main__': #Program start from here
45 print 'Program is starting...'
46 setup()
47 try:
48 loop()
49 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
50 will be executed.
51 destroy()

Se requiere un pulso de 50 Hz, concretamente un ciclo de 20 ms, para controlar Servo. Entonces, necesitamos
establecer la frecuencia PMW de servoPin a 50Hz.
p = GPIO.PWM(servoPin, 50) # set Frequece to 50Hz

Como 0-180 grados de servo corresponde a ancho de pulso PWM 0.5-2.5ms dentro del ciclo 20ms y al ciclo de
trabajo 2.5% -12.5%. En la subfunción servoWrite (angle)(ángulo), mapee el ángulo al ciclo de trabajo para enviar
el PWM, luego el servo rotará un ángulo específico. Sin embargo, en la práctica, debido al error de fabricación de
cada servo, el ancho del pulso también tendrá desviación. Entonces, definimos un ancho de pulso mínimo y uno
máximoOFFSE_DUTY
y un desplazamiento
= 0.5 de error.#define pulse offset of servo
SERVO_MIN_DUTY = 2.5+OFFSE_DUTY #define pulse duty cycle for minimum angle of servo
SERVO_MAX_DUTY = 12.5+OFFSE_DUTY #define pulse duty cycle for maximum angle of servo
……
def servoWrite(angle): #make the servo rotate to specific angle (0-180 degrees)
if(angle<0):
angle = 0
elif(angle > 180):
angle = 180
p.ChangeDutyCycle(map(angle,0,180,SERVO_MIN_DUTY,SERVO_MAX_DUTY))
█ www.freenove.com Capítulo 15 Servo 139

Finalmente, en el ciclo "while" de la función principal, use dos ciclo "for" para hacer el servo ratate de 0 grados a
180 grados, y luego de 180 grados a 0 grados.
def loop():
while True:
for dc in range(0, 181, 1): #make servo rotate from 0°to 180°
servoWrite(dc) # Write to servo
time.sleep(0.001)
time.sleep(0.5)
for dc in range(180, -1, -1): #make servo rotate from 180°to 0°
servoWrite(dc)
time.sleep(0.001)
time.sleep(0.5)
140 Capítulo 16 Motor de escalonamiento www.freenove.com █

Capítulo 16 Motor de escalonamiento


Hemos aprendido el motor y el servo de CC antes: el motor de CC puede girar constantemente pero no podemos
hacer que gire a un ángulo específico. Por el contrario, el servo normal puede girar hasta cierto ángulo pero no
puede girar constantemente. En este capítulo, aprenderemos un motor que puede girar no solo de forma
constante, sino también a un ángulo específico, motor paso a paso. El uso del motor paso a paso puede lograr
una mayor precisión de movimiento mecánico con facilidad.

Proyecto 16.1 Motor de escalonamiento

In this experiment, we will learn how to drive stepping motor, and understand its working principle.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x1 M/F x6


GPIO Expansion Board & Wire x1
BreadBoard x1
Stepping Motor x1 ULN2003 Stepper Motor Driver x1
█ www.freenove.com Capítulo 16 Motor de escalonamiento 141

Conocimiento del componente

Stepping Motor
El motor paso a paso es un dispositivo de control de bucle abierto que convierte la señal de impulso eléctrico en
desplazamiento angular o desplazamiento lineal. En condiciones sin sobrecarga, la velocidad del motor y la
ubicación de la parada dependen solo de la frecuencia de la señal de impulso y del número de pulso, y no se ven
afectados por los cambios de carga. Un pequeño motor paso a paso de desaceleración de cuatro fases se muestra
de la siguiente manera:

El diagrama esquemático del motor paso a paso de cuatro fases se muestra a continuación:

La pieza exterior es el estator y el interior es el rotor del motor. Hay un cierto número de bobinas, por lo
general múltiplo entero del número de fases, en el estator y, cuando está encendido, se formará un
electroimán para atraer una parte convexa (generalmente hierro o imán permanente) del rotor. Por lo tanto, el
motor eléctrico puede ser conducido conduciendo las bobinas en el estator ordenadamente.
142 Capítulo 16 Motor de escalonamiento www.freenove.com █

Un proceso de manejo común es el siguiente:

En el curso anterior, el motor paso a paso gira un cierto ángulo una vez, lo que se denomina paso. Al controlar el
número de pasos de rotación, puede controlar el ángulo de rotación del motor paso a paso. Al controlar el
tiempo entre dos pasos, puede controlar la velocidad de rotación del motor paso a paso. Al girar en el sentido de
las agujas del reloj, el orden de la bobina encendida es:ABCDA…… . Y el rotor girará de acuerdo con
el orden, paso a paso hacia abajo, llamado cuatro pasos cuatro palmaditas. Si las bobinas están encendidas en el
orden inverso, DCBAD… , el rotor girará en sentido contrario a las agujas del reloj.
El motor paso a paso tiene otros métodos de control, como la fase A de conexión, luego conecta la fase A, el
estator estará ubicado en el medio de la A B, solo medio paso. De esta manera puede mejorar la estabilidad del
motor paso a paso y reducir el ruido, la secuencia de la bobina encendida es:AABBBCCCDDDA
A……, el rotor girará de acuerdo con el orden, medio paso por medio paso, llamado cuatro paso ocho pat.
Igualmente, si la bobina se enciende en orden inverso, el motor paso a paso girará en rotación inversa.

El estator del motor paso a paso que utilizamos tiene 32 polos magnéticos, por lo que un círculo necesita 32
pasos. El eje de salida del motor paso a paso está conectado con un juego de engranajes de reducción, y la
relación de reducción es 1/64. Entonces, el eje de salida final gira un círculo que requiere un paso de 32 * 64 =
2048.
█ www.freenove.com Capítulo 16 Motor de escalonamiento 143

ULN2003 Stepping motor driver(Conductor de motor de escalonamiento)


El controlador de motor paso a paso ULN2003 se utiliza para convertir la señal débil en una poderosa señal de
control para conducir el motor paso a paso. La señal de entrada IN1-IN4 corresponde a la señal de salida A-D, y 4
LED está integrado en la placa para indicar el estado de las señales. La interfaz PWR se puede utilizar como fuente
de alimentación para motor paso a paso. Por defecto, PWR y VCC están conectados por un cortocircuito.

Circuito

Al construir el circuito, la tensión nominal del motor paso a paso es de 5 V, y utiliza la fuente de alimentación de
la placa de prueba de forma independiente, y no utiliza la fuente de alimentación RPi. Además, la fuente de
alimentación de la placa de circuitos impresos necesita compartir tierra con RPi.
Schematic diagram
144 Capítulo 16 Motor de escalonamiento www.freenove.com █

Hardware connection
█ www.freenove.com Capítulo 16 Motor de escalonamiento 145

Código

Este código utiliza el modo pat de cuatro pasos para conducir el motor paso a paso hacia adelante y hacia atrás.
C Code 16.1.1 SteppingMotor
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 16.1.1_SteppingMotor del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/16.1.1_SteppingMotor
2. Utilice el siguiente comando para compilar "SteppingMotor.c" y generar el archivo ejecutable "SteppingMotor". gcc
SteppingMotor.c –o SteppingMotor–lwiringPi
3. Ejecute el archivo generado "SteppingMotor".
sudo ./SteppingMotor
Después de que se ejecuta el programa, el motor paso a paso girará 360 ° en el sentido de las agujas del reloj y
luego 360 ° en el sentido contrario a las agujas del reloj, circularmente.
El siguiente es el código del programa:
1 #include <stdio.h>
2 #include <wiringPi.h>
3
4 const int motorPins[]={1,4,5,6}; //define pins connected to four phase ABCD of stepper
5 motor
6 const int CCWStep[]={0x01,0x02,0x04,0x08}; //define power supply order for coil for
7 rotating anticlockwise
8 const int CWStep[]={0x08,0x04,0x02,0x01}; //define power supply order for coil for
9 rotating clockwise
10 //as for four phase stepping motor, four steps is a cycle. the function is used to drive
11 the stepping motor clockwise or anticlockwise to take four steps
12 void moveOnePeriod(int dir,int ms){
13 int i=0,j=0;
14 for (j=0;j<4;j++){ //cycle according to power supply order
15 for (i=0;i<4;i++){ //assign to each pin, a total of 4 pins
16 if(dir == 1) //power supply order clockwise
17 digitalWrite(motorPins[i],(CCWStep[j] == (1<<i)) ? HIGH : LOW);
18 else //power supply order anticlockwise
19 digitalWrite(motorPins[i],(CWStep[j] == (1<<i)) ? HIGH : LOW);
20 printf("motorPin %d, %d \n",motorPins[i],digitalRead(motorPins[i]));
21 }
22 printf("Step cycle!\n");
23 if(ms<3) //the delay can not be less than 3ms, otherwise it will exceed
24 speed limit of the motor
25 ms=3;
26 delay(ms);
27 }
28 }
29
146 Capítulo 16 Motor de escalonamiento www.freenove.com █

30 //continuous rotation function, the parameter steps specifies the rotation cycles, every
31 four steps is a cycle
32 void moveSteps(int dir, int ms, int steps){
33 int i;
34 for(i=0;i<steps;i++){
35 moveOnePeriod(dir,ms);
36 }
37 }
38 void motorStop(){ //function used to stop rotating
39 int i;
40 for(i=0;i<4;i++){
41 digitalWrite(motorPins[i],LOW);
42 }
43 }
44 int main(void){
45 int i;
46
47 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
48 printf("setup wiringPi failed !");
49 return 1;
50 }
51 for(i=0;i<4;i++){
52 pinMode(motorPins[i],OUTPUT);
53 }
54
55 while(1){
56 moveSteps(1,3,512); //rotating 360° clockwise, a total of 2048 steps in a
57 circle, namely, 512 cycles.
58 delay(500);
59 moveSteps(0,3,512); //rotating 360° anticlockwise
60 delay(500);
61 }
62 return 0;
63 }
En el código, defina cuatro pines del orden de suministro de potencia del motor paso a paso y de la bobina del modo de rotación de cuatro pasos.

const int motorPins[]={1,4,5,6}; //define pins connected to four phase ABCD of stepper
motor
const int CCWStep[]={0x01,0x02,0x04,0x08}; //define power supply order for coil for
rotating anticlockwise
const int CWStep[]={0x08,0x04,0x02,0x01}; //define power supply order for coil for
rotating clockwise
La subfunción moveOnePeriod ((int dir, int ms) hará que el motor paso a paso gire cuatro pasos en el sentido de
las agujas del reloj o en el sentido contrario, mientras que el parámetro "dir" indica la dirección de rotación, si
"dir" es 1, el servo se inclinará hacia adelante , de lo contrario, gira en dirección inversa. El parámetro "ms" indica
el tiempo entre cada
█ www.freenove.com Capítulo 16 Motor de escalonamiento 147

dos pasos. El "ms" de motor paso a paso utilizado en este experimento es de 3 ms (el tiempo más corto), menos
de 3 ms excederá el límite de velocidad del motor paso a paso, lo que provocará que el motor no pueda girar.
void moveOnePeriod(int dir,int ms){
int i=0,j=0;
for (j=0;j<4;j++){ //cycle according to power supply order
for (i=0;i<4;i++){ //assign to each pin, a total of 4 pins
if(dir == 1) //power supply order clockwise
digitalWrite(motorPins[i],(CCWStep[j] == (1<<i)) ? HIGH : LOW);
else //power supply order anticlockwise
digitalWrite(motorPins[i],(CWStep[j] == (1<<i)) ? HIGH : LOW);
printf("motorPin %d, %d \n",motorPins[i],digitalRead(motorPins[i]));
}
printf("Step cycle!\n");
if(ms<3) //the delay can not be less than 3ms, otherwise it will exceed
speed limit of the motor
ms=3;
delay(ms);
}
}
Subfunction moveSteps (int dir, int ms, int steps) se usa para un número de ciclo específico de motor paso a paso.
void moveSteps(int dir, int ms, int steps){
int i;
for(i=0;i<steps;i++){
moveOnePeriod(dir,ms);
}
}
Sunbfunction motorStop () se usa para detener el motor paso a paso.
void motorStop(){ //function used to stop rotating
int i;
for(i=0;i<4;i++){
digitalWrite(motorPins[i],LOW);
}
}
Finalmente, en el ciclo while de la función principal, gire un círculo en el sentido de las agujas del reloj y luego un círculo
en el sentido contrario a las agujas del reloj. De acuerdo con el conocimiento previo del motor paso a paso, se puede
saber que la rotación del motor paso a paso para un círculo requiere 2048 pasos, es decir, 2048/4 ciclos = 512.
while(1){
moveSteps(1,3,512); //rotating 360° clockwise, a total of 2048 steps in a
circle, namely, this function(four steps) will be called 512 times.
delay(500);
moveSteps(0,3,512); //rotating 360° anticlockwise
delay(500);
}
148 Capítulo 16 Motor de escalonamiento www.freenove.com █

Pyhton Code 16.1.1 SteppingMotor


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 16.1.1_SteppingMotor del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/16.1.1_ SteppingMotor
2. Utilice el comando python para ejecutar el código "SteppingMotor.py"
python SteppingMotor.py
Después de que se ejecuta el programa, el motor paso a paso girará 360 ° en el sentido de las agujas del reloj y
luego 360 ° en el sentido contrario a las agujas del reloj, circularmente.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3
4 motorPins = (12, 16, 18, 22) #define pins connected to four phase ABCD of stepper
5 motor
6 CCWStep = (0x01,0x02,0x04,0x08) #define power supply order for coil for rotating
7 anticlockwise
8 CWStep = (0x08,0x04,0x02,0x01) #define power supply order for coil for rotating
9 clockwise
10
11 def setup():
12 print 'Program is starting...'
13 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
14 for pin in motorPins:
15 GPIO.setup(pin,GPIO.OUT)
16 #as for four phase stepping motor, four steps is a cycle. the function is used to drive
17 the stepping motor clockwise or anticlockwise to take four steps
18 def moveOnePeriod(direction,ms):
19 for j in range(0,4,1): #cycle for power supply order
20 for i in range(0,4,1): #assign to each pin, a total of 4 pins
21 if (direction == 1):#power supply order clockwise
22 GPIO.output(motorPins[i],((CCWStep[j] == 1<<i) and GPIO.HIGH orGPIO.LOW))
23 else : #power supply order anticlockwise
24 GPIO.output(motorPins[i],((CWStep[j] == 1<<i) and GPIO.HIGH or GPIO.LOW))
25 if(ms<3): #the delay can not be less than 3ms, otherwise it will exceed
26 speed limit of the motor
27 ms = 3
28 time.sleep(ms*0.001)
29 #continuous rotation function, the parameter steps specifies the rotation cycles, every
30 four steps is a cycle
31 def moveSteps(direction, ms, steps):
32 for i in range(steps):
33 moveOnePeriod(direction, ms)
34 #function used to stop rotating
35 def motorStop():
█ www.freenove.com Capítulo 16 Motor de escalonamiento 149

36 for i in range(0,4,1):
37 GPIO.output(motorPins[i],GPIO.LOW)
38
39 def loop():
40 while True:
41 moveSteps(1,3,512) #rotating 360° clockwise, a total of 2048 steps in a
42 circle, namely, 512 cycles.
43 time.sleep(0.5)
44 moveSteps(0,3,512) #rotating 360° anticlockwise
45 time.sleep(0.5)
46
47 def destroy():
48 GPIO.cleanup() # Release resource
49
50 if __name__ == '__main__': # Program start from here
51 setup()
52 try:
53 loop()
54 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
55 will be executed.
56 destroy()
En el código, defina cuatro pines del orden de suministro de potencia del motor paso a paso y de la bobina del modo de rotación de cuatro pasos.

motorPins = (12, 16, 18, 22) #define pins connected to four phase ABCD of stepper
motor

CCWStep = (0x01,0x02,0x04,0x08) #define power supply order for coil for rotating
anticlockwise
CWStep = (0x08,0x04,0x02,0x01) #define power supply order for coil for rotating
clockwise
La subfunción moveOnePeriod (dirección, ms) hará que el motor paso a paso gire cuatro pasos en el sentido de
las agujas del reloj o en el sentido contrario a las agujas del reloj, en cuatro pasos como un ciclo. Donde el
parámetro "dir" indica la dirección de rotación, si "dir" es 1, el servo se inclinará hacia adelante, de lo contrario,
gira en dirección inversa. El parámetro "ms" indica el tiempo entre cada dos pasos. El "ms" de motor de steping
utilizado en este experimento es de 3 ms (el tiempo más corto), menos de 3 ms excederá el límite de velocidad
del motor
defpaso a paso, lo que provocará que el motor no pueda rotar.
moveOnePeriod(direction,ms):
for j in range(0,4,1): #cycle for power supply order
for i in range(0,4,1): #assign to each pin, a total of 4 pins
if (direction == 1):#power supply order clockwise
GPIO.output(motorPins[i],((CCWStep[j] == 1<<i) and GPIO.HIGH orGPIO.LOW))
else : #power supply order anticlockwise
GPIO.output(motorPins[i],((CWStep[j] == 1<<i) and GPIO.HIGH or GPIO.LOW))
if(ms<3): #the delay can not be less than 3ms, otherwise it will exceed
speed limit of the motor
ms = 3
150 Chapter 16 Stepping Motor www.freenove.com █

time.sleep(ms*0.001)
Subfunction moveSteps (direction, ms, steps) se usa para un número de ciclo específico de motor paso a paso.
def moveSteps(direction, ms, steps):
for i in range(steps):
moveOnePeriod(direction, ms)

Sunbfunction motorStop () se usa para detener el motor paso a paso.


def motorStop():
for i in range(0,4,1):
GPIO.output(motorPins[i],GPIO.LOW)
Finalmente, en el ciclo while de la función principal, gire un círculo en el sentido de las agujas del reloj y luego un círculo en el
sentido contrario a las agujas del reloj. De acuerdo con el conocimiento previo del motor paso a paso, se puede saber que la rotación
del motor paso a paso para un círculo requiere 2048 pasos, es decir, 2048/4 ciclos = 512.

while True:
moveSteps(1,3,512) #rotating 360° clockwise, a total of 2048 steps in a
circle, namely, 512 cycles.
time.sleep(0.5)
moveSteps(0,3,512) #rotating 360° anticlockwise
time.sleep(0.5)
█ www.freenove.com Capítulo 17 74HC595 y Gráfico LEDBar 151

Capítulo 17 74HC595 y Gráfico LEDBar


Hemos utilizado LEDBar Graph para hacer que flowing water light(fluya una luz de agua), en la que 10 puertos
GPIO de RPi están ocupados. Más puertos GPIO significan que se pueden conectar más periféricos a RPi, por lo
que el recurso GPIO es muy valioso. ¿Podemos hacer que la luz del agua fluya con menos GPIO? En este capítulo,
aprenderemos un componente, 74HC595, que puede alcanzar el objetivo.

Proyecto 17.1 Flowing Water Light (Luz de agua corriente)

Ahora aprendamos cómo usar 74HC595 para hacer que la luz del agua fluya con menos GPIO.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x17


GPIO Extension Board & Wire x1
BreadBoard x1
74HC595 x1 LEDBar Graph x1 Resistor 220Ω x8
152 Capítulo 17 74HC595 y Gráfico LEDBar www.freenove.com █

Conocimiento del componente

74HC595
El chip 74HC595 se usa para convertir datos seriales en datos paralelos. 74HC595 puede convertir los datos en
serie de un byte a 8 bits y enviar su nivel correspondiente a los 8 puertos correspondientes. Con esta
característica, 74HC595 se puede utilizar para expandir el puerto IO de la placa Arduino. Al menos 3 puertos en la
placa RPI necesitan controlar 8 puertos de 74HC595.

Los puertos de 74HC595 se describen de la siguiente manera:


Pin name Pin number Description
Q0-Q7 15, 1-7 Salida de datos paralelos
VCC 16 El electrodo positivo de la fuente de alimentación, el voltaje es de 2 ~ 6V
GND 8 El electrodo negativo de la fuente de alimentación
DS 14 Entrada de datos en serie
OE 13 Habilitar salida,
Cuando este pin está en nivel alto, Q0-Q7 está en estado de alta resistencia
Cuando este pin está en nivel bajo, Q0-Q7 está en modo de salida
ST_CP 12 Salida de actualización en paralelo: cuando su nivel eléctrico está aumentando,
actualizará la salida de datos en paralelo.
SH_CP 11 Reloj de cambio en serie: cuando su nivel eléctrico está aumentando, el registro
de entrada de datos en serie hará un cambio.
MR 10 Eliminar registro de desplazamiento: cuando este pin está en nivel bajo, el
contenido en el registro de desplazamiento se borrará.
Q7' 9 Salida de datos en serie: se puede conectar a más 74HC595 en serie.
Para obtener más detalles, consulte la hoja de datos.
█ www.freenove.com Capítulo 17 74HC595 y Gráfico LEDBar 153

Circuito

Schematic diagram

Hardware connection
154 Capítulo 17 74HC595 y Gráfico LEDBar www.freenove.com █

Código

En este experimento, haga una luz de agua que fluye con 74HC595 para conocer su uso.
C Code 17.1.1 LightWater02
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 17.1.1_LightWater02 del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/17.1.1_LightWater02
2. Utilice el siguiente comando para compilar "LightWater02.c" y generar archivo ejecutable“LightWater02”. gcc
LightWater02.c –o LightWater02 –lwiringPi
3. Luego ejecuta el archivo generado“LightWater02”.
sudo ./LightWater02
Después de que se ejecuta el programa, LEDBar Graph comienza a mostrar la luz del agua que fluye de izquierda
a derecha, luego de derecha a izquierda.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <wiringShift.h>
4
5 #define dataPin 0 //DS Pin of 74HC595(Pin14)
6 #define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
7 #define clockPin 3 //SH_CP Pin of 74HC595(Pin11)
8
9 int main(void)
10 {
11 int i;
12 unsigned char x;
13 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
14 printf("setup wiringPi failed !");
15 return 1;
16 }
17 pinMode(dataPin,OUTPUT);
18 pinMode(latchPin,OUTPUT);
19 pinMode(clockPin,OUTPUT);
20 while(1){
21 x=0x01;
22 for(i=0;i<8;i++){
23 digitalWrite(latchPin,LOW); // Output low level to latchPin
24 shiftOut(dataPin,clockPin,LSBFIRST,x);// Send serial data to 74HC595
25 digitalWrite(latchPin,HIGH); // Output high level to latchPin, and 74HC595
26 will update the data to the parallel output port.
27 x<<=1; // make the variable move one bit to left once, then the bright LED
28 move one step to the left once.
29 delay(100);
█ www.freenove.com Capítulo 17 74HC595 y Gráfico LEDBar 155

30 }
31 x=0x80;
32 for(i=0;i<8;i++){
33 digitalWrite(latchPin,LOW);
34 shiftOut(dataPin,clockPin,LSBFIRST,x);
35 digitalWrite(latchPin,HIGH);
36 x>>=1;
37 delay(100);
38 }
39 }
40 return 0;
41 }
42
En el código, configuramos tres pines para controlar el 74HC595. Y defina una variable de un byte para controlar
el estado de 8 LED a través de los 8 bits de la variable. El LED se enciende cuando el bit correspondiente es 1. Si la
variable está asignada a 0x01, es decir 00000001 en binario, solo habrá un LED encendido
x=0x01;
En el ciclo "while" de la función principal, use el ciclo "for" para enviar x al pin de salida 74HC595 para controlar
el LED. En el ciclo "for"("para"), x se desplazará un bit hacia la izquierda en un ciclo, luego en la siguiente ronda
cuando los datos de x se envíen a 74HC595, el LED encendido se moverá un bit hacia la izquierda una vez.
for(i=0;i<8;i++){
digitalWrite(latchPin,LOW); // Output low level to latchPin
shiftOut(dataPin,clockPin,LSBFIRST,x);// Send serial data to 74HC595
digitalWrite(latchPin,HIGH); // Output high level to latchPin, and 74HC595
will update the data to the parallel output port.
x<<=1; // make the variable move one bit to left once, then the bright LED
move one step to the left once.
delay(100);
}

En el segundo ciclo "for"("para"), la situación es la misma. La diferencia es que x es un cambio de 0x80 a la derecha en
orden.
<< operator
"<<" es el operador de desplazamiento a la izquierda, que puede hacer que todos los bits de 1 byte cambien en varios bits a la
dirección izquierda (alta) y agregue 0 a la derecha (bajo). Por ejemplo, cambie el 00000001 binario por 1 bit a la izquierda:
byte x = 1 << 1;
← ← ← ← ← ← ←
← 0 0 0 0 0 0 0 1 ← 0
El resultado de X es 2(binary 00000010)。
0 0 0 0 0 0 1 0

Hay otro operador similar" >>". Por ejemplo, shift binary 00000001 by 1 bit a derecha:
byte x = 1 >> 1;
→ → → → → → →
0 → 0 0 0 0 0 0 0 1 →
156 Capítulo 17 74HC595 y Gráfico LEDBar www.freenove.com █

El resultado de x es 0(00000000)。
0 0 0 0 0 0 0 0

X <<= 1 is equivalent to x = x << 1 and x >>= 1 is equivalent to x = x >> 1


Acerca de la función de cambio:
uint8_t shiftIn (uint8_t dPin, uint8_t cPin, uint8_t order) ;
Esto desplaza un valor de datos de 8 bits con los datos que aparecen en el dPin y el reloj que se envía en el
cPin. El orden es LSBFIRST o MSBFIRST. Los datos se muestrean después de que el cPin sube. (Entonces cPin
alto, datos de muestra, cPin bajo, repetir para 8 bits) La función devuelve el valor de 8 bits.
void shiftOut (uint8_t dPin, uint8_t cPin, uint8_t order, uint8_t val) ;
Cambia un val de valor de datos de 8 bits con los datos que se envían en dPin y el reloj que se envía en el cPin.
el orden es como el anterior. Los datos se sincronizan en el borde ascendente o descendente, es decir. dPin
está establecido, luego cPin se toma alto y luego bajo - se repite para los 8 bits.
Para más detalles sobre la función de cambio, consulte: http://wiringpi.com/reference/shift-library/
Pyhton Code 17.1.1 LightWater02
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 17.1.1_LightWater02 del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/17.1.1_LightWater02
2. Use el comando python para ejecutar el código python“LightWater02.py”.
python LightWater02.py
Después de que se ejecuta el programa, LEDBar Graph comienza a mostrar la luz del agua que fluye de izquierda
a derecha, luego de derecha a izquierda.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3 # Defines the data bit that is transmitted preferentially in the shiftOut function.
4 LSBFIRST = 1
5 MSBFIRST = 2
6 #define the pins connect to 74HC595
7 dataPin = 11 #DS Pin of 74HC595(Pin14)
8 latchPin = 13 #ST_CP Pin of 74HC595(Pin12)
9 clockPin = 15 #SH_CP Pin of 74HC595(Pin11)
10
11 def setup():
12 GPIO.setmode(GPIO.BOARD) # Number GPIOs by its physical location
13 GPIO.setup(dataPin, GPIO.OUT)
14 GPIO.setup(latchPin, GPIO.OUT)
15 GPIO.setup(clockPin, GPIO.OUT)
16 # shiftOut function, use bit serial transmission.
17 def shiftOut(dPin,cPin,order,val):
18 for i in range(0,8):
19 GPIO.output(cPin,GPIO.LOW);
20 if(order == LSBFIRST):
21 GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
█ www.freenove.com Capítulo 17 74HC595 y Gráfico LEDBar 157

22 elif(order == MSBFIRST):
23 GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
24 GPIO.output(cPin,GPIO.HIGH);
25
26 def loop():
27 while True:
28 x=0x01
29 for i in range(0,8):
30 GPIO.output(latchPin,GPIO.LOW) #Output low level to latchPin
31 shiftOut(dataPin,clockPin,LSBFIRST,x)#Send serial data to 74HC595
32 GPIO.output(latchPin,GPIO.HIGH)#Output high level to latchPin, and 74HC595
33 will update the data to the parallel output port.
34 x<<=1# make the variable move one bit to left once, then the bright LED move
35 one step to the left once.
36 time.sleep(0.1)
37 x=0x80
38 for i in range(0,8):
39 GPIO.output(latchPin,GPIO.LOW)
40 shiftOut(dataPin,clockPin,LSBFIRST,x)
41 GPIO.output(latchPin,GPIO.HIGH)
42 x>>=1
43 time.sleep(0.1)
44
45 def destroy(): # When 'Ctrl+C' is pressed, the function is executed.
46 GPIO.cleanup()
47
48 if __name__ == '__main__': # Program starting from here
49 print 'Program is starting...'
50 setup()
51 try:
52 loop()
53 except KeyboardInterrupt:
54 destroy()
En el código, definimos una función shiftOut (), que se usa para enviar val con el bit en orden. Y donde dPin para
el pin de datos, cPin para el orden de reloj y amd para el indicador de bit prioritario (alto o bajo). Esta función se
ajusta al modo de operación de 74HC595.
def shiftOut(dPin,cPin,order,val):
for i in range(0,8):
GPIO.output(cPin,GPIO.LOW);
if(order == LSBFIRST):
GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
elif(order == MSBFIRST):
GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
GPIO.output(cPin,GPIO.HIGH);
158 Capítulo 17 74HC595 y Gráfico LEDBar www.freenove.com █

En la función loop (), usamos dos ciclos "for" para alcanzar el objetivo. Primero, defina una variable x = 0x01,
00000001 binario. Cuando se transfiere al puerto de salida de 74HC595, el bit bajo emite un nivel alto, luego se
enciende un LED. A continuación, x se desplaza un bit, cuando x se transfiere al puerto de salida de 74HC595 una
vez más, el LED encendido se desplazará. Repita la operación, se formará el efecto de la luz del agua que fluye. Si
la dirección de la operación de cambio para x es diferente, la dirección de flujo es diferente.
def loop():
while True:
x=0x01
for i in range(0,8):
GPIO.output(latchPin,GPIO.LOW) #Output low level to latchPin
shiftOut(dataPin,clockPin,LSBFIRST,x)#Send serial data to 74HC595
GPIO.output(latchPin,GPIO.HIGH)#Output high level to latchPin, and 74HC595
will update the data to the parallel output port.
x<<=1# make the variable move one bit to left once, then the bright LED move
one step to the left once.
time.sleep(0.1)
x=0x80
for i in range(0,8):
GPIO.output(latchPin,GPIO.LOW)
shiftOut(dataPin,clockPin,LSBFIRST,x)
GPIO.output(latchPin,GPIO.HIGH)
x>>=1
time.sleep(0.1)
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 159

Capítulo 18 74HC595 y pantalla de 7 segmentos.


En este capítulo, aprenderemos un nuevo componente, pantalla de 7 segmentos.

Proyecto 18.1 Pantalla de 7 segmentos.

Utilizaremos 74HC595 para controlar la visualización de 7 segmentos. y hacer que muestre dieciséis caracteres decimales
"0-F".

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x18


GPIO Extension Board & Wire x1
BreadBoard x1
74HC595 x1 7-segment display x1 Resistor 220Ω x8
160 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

Conocimiento del componente

7-segment display
La pantalla de 7 segmentos es un dispositivo de visualización electrónico digital. Hay una cifra de "8" y un punto
decimal, que consta de 8 LED. De acuerdo con la diferencia sobre el cátodo común y el ánodo. su estructura
interna y el diagrama de pines se muestran a continuación:

Como se sabe por el diagrama de circuito anterior, podemos controlar el estado de cada LED por separado. Por lo tanto,
a través de la combinación de LED con diferentes estados, podemos mostrar diferentes números. Por ejemplo, visualice
la figura 0: tenemos que encender el segmento LED A, B, C, D, E, F y apagar el segmento LED G y DP.

En este experimento, utilizamos una pantalla de 7 segmentos (ánodo común). Por lo tanto, cuando el nivel bajo
de entrada a un segmento LED, el LED se encenderá. Defina el segmento "A" como el nivel más bajo, el segmento
"DP" como el nivel más alto, es decir, de mayor a menor: "DP", "G", "F", "E", "D", "C "," B "," A ". Y el carácter "0"
corresponde al código: 1100 0000b = 0xc0.
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 161

Circuito

Schematic diagram

Hardware connection
162 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

Código

En este código, usa 74HC595 para controlar la pantalla de 7 segmentos. El uso de 74HC595 es generalmente el
mismo que en la última sección. El contenido 74HC595 salidas es diferente. Necesitamos el carácter de código "0"
- "F" uno por uno, y luego emitirlos con 74HC595.
C Code 18.1.1 SevenSegmentDisplay
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 18.1.1_SevenSegmentDisplay del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/18.1.1_SevenSegmentDisplay
2. Utilice el siguiente comando para compilar "SevenSegmentDisplay.c" y generar el archivo ejecutable
"SevenSegmentDisplay".
gcc SevenSegmentDisplay.c –o SevenSegmentDisplay –lwiringPi
3. Ejecuta el archivo generado "SevenSegmentDisplay".
sudo ./SevenSegmentDisplay
Después de que se ejecuta el programa, SevenSegmentDisplay comienza a mostrar el carácter "0" - "F"
sucesivamente. El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <wiringShift.h>
4
5 #define dataPin 0 //DS Pin of 74HC595(Pin14)
6 #define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
7 #define clockPin 3 //SH_CP Pin of 74HC595(Pin11)
8 // encoding for character 0-F of common anode SevenSegmentDisplay.
9 unsigned char
10 num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
11
12 int main(void)
13 {
14 int i;
15 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
16 printf("setup wiringPi failed !");
17 return 1;
18 }
19 pinMode(dataPin,OUTPUT);
20 pinMode(latchPin,OUTPUT);
21 pinMode(clockPin,OUTPUT);
22 while(1){
23 for(i=0;i<sizeof(num);i++){
24 digitalWrite(latchPin,LOW);
25 shiftOut(dataPin,clockPin,MSBFIRST,num[i]);//Output the figures and the
26 highest level is transfered preferentially.
27 digitalWrite(latchPin,HIGH);
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 163

28 delay(500);
29 }
30 for(i=0;i<sizeof(num);i++){
31 digitalWrite(latchPin,LOW);
32 shiftOut(dataPin,clockPin,MSBFIRST,num[i] & 0x7f);// Use the "&0x7f" to
33 display the decimal point.
34 digitalWrite(latchPin,HIGH);
35 delay(500);
36 }
37 }
38 return 0;
39 }
Primero, ponga la codificación de "0" - "F" en la matriz.
unsigned char
num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
En el ciclo "for" de la función loop (), use 74HC595 para generar los contenidos de la matriz "num" sucesivamente.
SevenSegmentDisplay puede mostrar correctamente los caracteres correspondientes. Preste atención a que en la
función shiftOut, el bit de transmisión, el bit más alto de la bandera se transmitirá de manera preferente.
for(i=0;i<sizeof(num);i++){
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,MSBFIRST,num[i]);//Output the figures and the
highest level is transfered preferentially.
digitalWrite(latchPin,HIGH);
delay(500);
}
Si desea visualizar el punto decimal, haga que el bit más alto de cada matriz se convierta en 0, que se puede
implementar fácilmente por num [i] &0x7f.
shiftOut(dataPin,clockPin,MSBFIRST,num[i] & 0x7f);

Pyhton Code 18.1.1 SevenSegmentDisplay


Primero observe el fenómeno experimental, y luego analice el código.
1. Use el comando cd para ingresar al directorio 18.1.1_SevenSegmentDisplay del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/18.1.1_SevenSegmentDisplay
2. Utilice el comando python para ejecutar el código python "SevenSegmentDisplay.py".
python SevenSegmentDisplay.py
Después de que se ejecuta el programa, SevenSegmentDisplay comienza a mostrar el carácter "0" - "F"
sucesivamente. El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3
4 LSBFIRST = 1
5 MSBFIRST = 2
6 #define the pins connect to 74HC595
7 dataPin = 11 #DS Pin of 74HC595(Pin14)
164 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

8 latchPin = 13 #ST_CP Pin of 74HC595(Pin12)


9 clockPin = 15 #SH_CP Pin of 74HC595(Pin11)
10 #SevenSegmentDisplay display the character “0”- “F” successively
11 num = [0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e]
12 def setup():
13 GPIO.setmode(GPIO.BOARD) # Number GPIOs by its physical location
14 GPIO.setup(dataPin, GPIO.OUT)
15 GPIO.setup(latchPin, GPIO.OUT)
16 GPIO.setup(clockPin, GPIO.OUT)
17
18 def shiftOut(dPin,cPin,order,val):
19 for i in range(0,8):
20 GPIO.output(cPin,GPIO.LOW);
21 if(order == LSBFIRST):
22 GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
23 elif(order == MSBFIRST):
24 GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
25 GPIO.output(cPin,GPIO.HIGH);
26
27 def loop():
28 while True:
29 for i in range(0,len(num)):
30 GPIO.output(latchPin,GPIO.LOW)
31 shiftOut(dataPin,clockPin,MSBFIRST,num[i])# Output the figures and the
32 highest level is transfered preferentially.
33 GPIO.output(latchPin,GPIO.HIGH)
34 time.sleep(0.5)
35 for i in range(0,len(num)):
36 GPIO.output(latchPin,GPIO.LOW)
37 shiftOut(dataPin,clockPin,MSBFIRST,num[i]&0x7f)#Use “&0x7f”to display the
38 decimal point.
39 GPIO.output(latchPin,GPIO.HIGH)
40 time.sleep(0.5)
41
42 def destroy(): # When 'Ctrl+C' is pressed, the function is executed.
43 GPIO.cleanup()
44
45 if __name__ == '__main__': # Program starting from here
46 print 'Program is starting...'
47 setup()
48 try:
49 loop()
50 except KeyboardInterrupt:
51 destroy()
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 165

Primero, ponga la codificación de "0" - "F" en la matriz.


num = [0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e]
In the “for” cycle of loop() function, use 74HC595 to output contents of array “num” successively.
SevenSegmentDisplay can correctly display the corresponding characters. Pay attention to that in shiftOut
function, the transmission bit, flag bit highest bit will be transmitted preferentially.
for i in range(0,len(num)):
GPIO.output(latchPin,GPIO.LOW)
shiftOut(dataPin,clockPin,MSBFIRST,num[i])#Output the figures and the highest
level is transfered preferentially.
GPIO.output(latchPin,GPIO.HIGH)
time.sleep(0.5)
Si desea visualizar el punto decimal, haga que el bit más alto de cada matriz se convierta en 0, que se puede
implementar fácilmente por num [i] &0x7f.
shiftOut(dataPin,clockPin,MSBFIRST,num[i]&0x7f)# Use “&0x7f”to display the decimal
point.

Proyecto 18.2 4 Pantallas de 7 segmentos

Ahora, intentemos controlar más pantallas Digit de 7 segmentos

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x27


GPIO Expansion Board & Wire x1
BreadBoard x1
74HC595 x1 PNP 4-Digit 7-segment display x1 Resistor 220Ω Resistor 1KΩ
transistor x4 x8 x4
166 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

Conocimiento del componente


4 Digit 7-Segment Display
En el componente de 4 digitos de 7 segmentos se integra cuatro pantallas de 7 segmentos, por lo que puede
mostrar más números. De acuerdo con la diferencia sobre el cátodo común y el ánodo. su estructura interna y el
diagrama de pines se muestran a continuación:

El circuito interno se muestra a continuación, y los 8 pines de cátodo LED de cada pantalla de 7 segmentos están
conectados entre sí.

El método de visualización de la pantalla de 4 dígitos y 7 segmentos es similar a la visualización de 1 dígito de 7


segmentos. La diferencia entre ellos es que la pantalla de 4 dígitos a su vez, uno por uno, no juntos. Primero
envíe el nivel alto al extremo común del primer tubo, y envíe el nivel bajo al resto de los tres extremos comunes,
y luego envíe el contenido a 8 pines de cátodo LED del primer tubo. En este momento, la primera pantalla de 7
segmentos mostrará el contenido y el resto, tres en estado cerrado.
De manera similar, la segunda, la tercera y la cuarta pantalla de 7 segmentos muestran el contenido, es decir, la
pantalla de escaneo. Aunque los cuatro números se muestran a la vez por separado, este proceso es muy rápido
y, debido al efecto de resplandor óptico posterior y al efecto de persistencia de personas en visión, podemos ver
los 4 números al mismo tiempo. Por el contrario, si cada figura se muestra durante un tiempo prolongado, puede
ver que los números se muestran por separado.
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 167

Circuito

Schematic diagram
168 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

Hardware connection
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 169

Código

En este código, utilizamos 74HC595 para controlar la visualización de 4 segmentos de 7 segmentos, y utilizamos la
forma de exploración dinámica para mostrar los números cambiantes.
C Code 18.2.1 StopWatch
Primero observe el fenómeno experimental y luego analice el código.

1. Use el comando cd para ingresar al directorio 16.1.1_SteppingMotor del código C.


cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/18.2.1_StopWatch
2. Use el siguiente comando para compilar "StopWatch.c" y generar el archivo ejecutable "StopWatch".
gcc StopWatch.c –o StopWatch –lwiringPi
3. Ejecute el archivo generado "SteppingMotor".
sudo ./StopWatch
Después de que se ejecuta el programa, los 4 dígitos y 7 segmento comienza a mostrar dinámicamente un
número de cuatro dígitos, y el testamento más 1 en cada segundo sucesivo.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <wiringShift.h>
4 #include <signal.h>
5 #include <unistd.h>
6 #define dataPin 5 //DS Pin of 74HC595(Pin14)
7 #define latchPin 4 //ST_CP Pin of 74HC595(Pin12)
8 #define clockPin 1 //CH_CP Pin of 74HC595(Pin11)
9 const int digitPin[]={0,2,3,12}; // Define 7-segment display common pin
10 // character 0-9 code of common anode 7-segment display
11 unsigned char num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
12 int counter = 0; //variable counter,the number will be displayed by 7-segment display
13 //Open one of the 7-segment display and close the remaining three, the parameter digit is
14 optional for 1,2,4,8
15 void selectDigit(int digit){
16 digitalWrite(digitPin[0],((digit&0x08) == 0x08) ? LOW : HIGH);
17 digitalWrite(digitPin[1],((digit&0x04) == 0x04) ? LOW : HIGH);
18 digitalWrite(digitPin[2],((digit&0x02) == 0x02) ? LOW : HIGH);
19 digitalWrite(digitPin[3],((digit&0x01) == 0x01) ? LOW : HIGH);
20 }
21 void outData(int8_t data){ //function used to output data for 74HC595 输出数据函数
22 digitalWrite(latchPin,LOW);
23 shiftOut(dataPin,clockPin,MSBFIRST,data);
24 digitalWrite(latchPin,HIGH);
25 }
26 void display(int dec){ //display function for 7-segment display
27 selectDigit(0x01); //select the first, and display the single digit
170 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

28 outData(num[dec%10]);
29 delay(1); //display duration
30 selectDigit(0x02); //select the second, and display the tens digit
31 outData(num[dec%100/10]);
32 delay(1);
33 selectDigit(0x04); //select the third, and display the hundreds digit
34 outData(num[dec%1000/100]);
35 delay(1);
36 selectDigit(0x08); //select the fourth, and display the thousands digit
37 outData(num[dec%10000/1000]);
38 delay(1);
39 }
40 void timer(int sig){ //Timer function
41 if(sig == SIGALRM){ //If the signal is SIGALRM, the value of counter plus 1, and
42 update the number displayed by 7-segment display
43 counter ++;
44 alarm(1); //set the next timer time
45 printf("counter : %d \n",counter);
46 }
47 }
48 int main(void)
49 {
50 int i;
51 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
52 printf("setup wiringPi failed !");
53 return 1;
54 }
55 pinMode(dataPin,OUTPUT); //set the pin connected to74HC595 for output mode
56 pinMode(latchPin,OUTPUT);
57 pinMode(clockPin,OUTPUT);
58 //set the pin connected to 7-segment display common end to output mode
59
60 for(i=0;i<4;i++){
61 pinMode(digitPin[i],OUTPUT);
62 digitalWrite(digitPin[i],LOW);
63 }
64 signal(SIGALRM,timer); //configure the timer
65 alarm(1); //set the time of timer to 1s
66 while(1){
67 display(counter); //display the number counter
68 }
69 return 0;
70 }
Primero, defina el pin de 74HC595 y el extremo común de visualización de 7 segmentos, codificación de caracteres y una
variable
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 171

"counter"("contador")para mostrar contador.


#define dataPin 5 //DS Pin of 74HC595(Pin14)
#define latchPin 4 //ST_CP Pin of 74HC595(Pin12)
#define clockPin 1 //CH_CP Pin of 74HC595(Pin11)
const int digitPin[]={12,3,2,0}; //Define the pin of 7-segment display common end
// character 0-9 code of common anode 7-segment display
unsigned char num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
int counter = 0; //variable counter, the number will be dislayed by 7-segment display
La Subfunction selectDigit (int digit)función de selección de subfunción (dígito interno) se utiliza para abrir una de
las pantallas de 7 segmentos y cerrar la otra pantalla de 7 segmentos, donde el valor del dígito del parámetro
puede ser 1,2,4,8. Usando "|" puede abrir una cantidad de pantalla de 7 segmentos.
void selectDigit(int digit){
digitalWrite(digitPin[0],((digit&0x08) == 0x08) ? LOW : HIGH);
digitalWrite(digitPin[1],((digit&0x04) == 0x04) ? LOW : HIGH);
digitalWrite(digitPin[2],((digit&0x02) == 0x02) ? LOW : HIGH);
digitalWrite(digitPin[3],((digit&0x01) == 0x01) ? LOW : HIGH);
}
La subfunción outData (datos int8_t) se usa para hacer que la salida del 74HC595 sea de 8 bits inmediatamente.
void outData(int8_t data){ // function used to output data for 74HC595 输出数据函数
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,MSBFIRST,data);
digitalWrite(latchPin,HIGH);
}
La Subfunction display (int dec)(pantalla de subfunción (int dec))se usa para hacer que la pantalla de 4 segmentos y 7 segmentos
muestre un entero de 4 bits. Primero abra el extremo común de la primera pantalla de 7 segmentos y cerca de los otros tres, en este
momento, se puede usar como pantalla de 7 segmentos de 1 dígito. El primero se usa para mostrar un solo dígito de "dec", el
segundo para decenas de dígitos, el tercero para cientos de dígitos y el cuarto para miles de dígitos, respectivamente. Cada dígito se
mostrará durante un período de tiempo mediante el uso de delay (). El tiempo en este código es muy corto, por lo que verá que los
diferentes dígitos están en un lío. Si el tiempo se establece lo suficiente, verá que cada dígito es independiente de la pantalla.

void display(int dec){ //display function for 7-segment display


selectDigit(0x01); //select the first, and display the single digit
outData(num[dec%10]);
delay(1); //display duration
selectDigit(0x02); //Select the second, and display the tens digit
outData(num[dec%100/10]);
delay(1);
selectDigit(0x04); //Select the third, and display the hundreds digit
outData(num[dec%1000/100]);
delay(1);
selectDigit(0x08); //Select the fourth, and display the thousands digit
outData(num[dec%10000/1000]);
delay(1);
}
Subfunction timer (int sig) (El temporizador de subfunción (int sig)) es la función del temporizador, que configurará una
señal de alarma. Esta función será ejecutada una vez
172 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

a intervalos establecidos. Acompañado por la ejecución, el contador variable se agregará 1, y luego reiniciará el
tiempo del temporizador a 1s.
void timer(int sig){ //timer function
if(sig == SIGALRM){ //If the signal is SIGALRM, the value of counter plus 1, and
update the number displayed by 7-segment display
counter ++;
alarm(1); //set the next timer time
}
}
Finalmente, en la función principal, configure todo el GPIO y configure la función del temporizador.
pinMode(dataPin,OUTPUT); //set the pin connected to74HC595 for output mode
pinMode(latchPin,OUTPUT);
pinMode(clockPin,OUTPUT);
//set the pin connected to 7-segment display common end to output mode
for(i=0;i<4;i++){
pinMode(digitPin[i],OUTPUT);
digitalWrite(digitPin[i],LOW);
}
signal(SIGALRM,timer); //configure the timer
alarm(1); //set the time of timer to 1s
En el ciclo while, configure el valor del contador variable de la pantalla digital. El valor cambiará en la function timer ()(temporizador
de función ()), por lo que el contenido visualizado por la visualización de 7 segmentos cambiará en consecuencia.

while(1){
display(counter); //display number counter
}
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 173

Pyhton Code 18.2.1 StopWatch


Este código utiliza el modo pat de cuatro pasos para conducir el motor paso a paso hacia adelante y hacia atrás.
1. Use el comando cd para ingresar al directorio 16.1.1_SteppingMotor del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/18.2.1_StopWatch
2. Use el comando python para ejecutar el código "StopWatch.py".
python StopWatch.py
Después de que se ejecuta el programa, el segmento de 4 dígitos y 7 comienza a mostrar dinámicamente un
número de cuatro dígitos, y el testamento más 1 en cada segundo sucesivo.

El siguiente es el código del programa:


1 import RPi.GPIO as GPIO
2 import time
3 import threading
4
5 LSBFIRST = 1
6 MSBFIRST = 2
7 #define the pins connect to 74HC595
8 dataPin = 18 #DS Pin of 74HC595(Pin14)
9 latchPin = 16 #ST_CP Pin of 74HC595(Pin12)
10 clockPin = 12 #SH_CP Pin of 74HC595(Pin11)
11 num = (0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90)
12 digitPin = (19,15,13,11) # Define the pin of 7-segment display common end
13 counter = 0 # Variable counter, the number will be dislayed by 7-segment display
14 t = 0 # defien the Timer object
15 def setup():
16 GPIO.setmode(GPIO.BOARD) # Number GPIOs by its physical location
17 GPIO.setup(dataPin, GPIO.OUT) # Set pin mode to output
18 GPIO.setup(latchPin, GPIO.OUT)
19 GPIO.setup(clockPin, GPIO.OUT)
20 for pin in digitPin:
21 GPIO.setup(pin,GPIO.OUT)
22
23 def shiftOut(dPin,cPin,order,val):
24 for i in range(0,8):
25 GPIO.output(cPin,GPIO.LOW);
26 if(order == LSBFIRST):
27 GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
28 elif(order == MSBFIRST):
29 GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
30 GPIO.output(cPin,GPIO.HIGH)
31
32 def outData(data): #function used to output data for 74HC595
33 GPIO.output(latchPin,GPIO.LOW)
174 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

34 shiftOut(dataPin,clockPin,MSBFIRST,data)
35 GPIO.output(latchPin,GPIO.HIGH)
36
37 def selectDigit(digit): # Open one of the 7-segment display and close the remaining
38 three, the parameter digit is optional for 1,2,4,8
39 GPIO.output(digitPin[0],GPIO.LOW if ((digit&0x08) == 0x08) else GPIO.HIGH)
40 GPIO.output(digitPin[1],GPIO.LOW if ((digit&0x04) == 0x04) else GPIO.HIGH)
41 GPIO.output(digitPin[2],GPIO.LOW if ((digit&0x02) == 0x02) else GPIO.HIGH)
42 GPIO.output(digitPin[3],GPIO.LOW if ((digit&0x01) == 0x01) else GPIO.HIGH)
43
44 def display(dec): #display function for 7-segment display
45 outData(0xff) #eliminate residual display
46 selectDigit(0x01) #Select the first, and display the single digit
47 outData(num[dec%10])
48 time.sleep(0.003) #display duration
49 outData(0xff)
50 selectDigit(0x02) # Select the second, and display the tens digit
51 outData(num[dec%100/10])
52 time.sleep(0.003)
53 outData(0xff)
54 selectDigit(0x04) # Select the third, and display the hundreds digit
55 outData(num[dec%1000/100])
56 time.sleep(0.003)
57 outData(0xff)
58 selectDigit(0x08) # Select the fourth, and display the thousands digit
59 outData(num[dec%10000/1000])
60 time.sleep(0.003)
61 def timer(): #timer function
62 global counter
63 global t
64 t = threading.Timer(1.0,timer) #reset time of timer to 1s
65 t.start() #Start timing
66 counter+=1
67 print "counter : %d"%counter
68
69 def loop():
70 global t
71 global counter
72 t = threading.Timer(1.0,timer) #set the timer
73 t.start() # Start timing
74 while True:
75 display(counter) # display the number counter
76
77 def destroy(): # When "Ctrl+C" is pressed, the function is executed.
█ www.freenove.com Capítulo 18 74HC595 y pantalla de 7 segmentos. 175

78 global t
79 GPIO.cleanup()
80 t.cancel() #cancel the timer
81
82 if __name__ == '__main__': # Program starting from here
83 print 'Program is starting...'
84 setup()
85 try:
86 loop()
87 except KeyboardInterrupt:
89 destroy()
First, define the pin of 74HC595 and 7-segment display common end, character encoding and a variable
"counter" to be displayed counter.
dataPin = 18 #DS Pin of 74HC595(Pin14)
latchPin = 16 #ST_CP Pin of 74HC595(Pin12)
clockPin = 12 #CH_CP Pin of 74HC595(Pin11)
num = (0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90)
digitPin = (19,15,13,11) # Define the pin of 7-segment display common end
counter = 0 # Variable counter, the number will be dislayed by 7-segment display
Subfunction selectDigit (digit). Esta función se utiliza para abrir una de las pantallas de 7 segmentos y cerrar la
otra pantalla de 7 segmentos, donde el valor del dígito del parámetro puede ser 1,2,4,8. Usando "|" puede abrir
una cantidad de pantalla de 7 segmentos.
def selectDigit(digit): #Open one of the 7-segment display and close the remaining three,
the parameter digit is optional for 1,2,4,8
GPIO.output(digitPin[0],GPIO.LOW if ((digit&0x08) == 0x08) else GPIO.HIGH)
GPIO.output(digitPin[1],GPIO.LOW if ((digit&0x04) == 0x04) else GPIO.HIGH)
GPIO.output(digitPin[2],GPIO.LOW if ((digit&0x02) == 0x02) else GPIO.HIGH)
GPIO.output(digitPin[3],GPIO.LOW if ((digit&0x01) == 0x01) else GPIO.HIGH)
The subfunction outData (data) se usa para hacer que la salida del 74HC595 sea de 8 bits inmediatamente.
def outData(data): #function used to output data for 74HC595
GPIO.output(latchPin,GPIO.LOW)
shiftOut(dataPin,clockPin,MSBFIRST,data)
GPIO.output(latchPin,GPIO.HIGH)
Subfunction display (dec) se usa para hacer que la pantalla de 7 segmentos de 7 segmentos muestre un entero de 4 bits.
Primero abra el extremo común de la primera pantalla de 7 segmentos y cerca de los otros tres, en este momento, se puede usar
como pantalla de 7 segmentos de 1 dígito. El primero se usa para mostrar un solo dígito de "dec", el segundo para decenas de
dígitos, el tercero para cientos de dígitos y el cuarto para miles de dígitos, respectivamente. Cada dígito se mostrará durante un
período de tiempo mediante el uso de delay (). El tiempo en este código es muy corto, por lo que verá que los diferentes dígitos
están en un lío. Si el tiempo se establece lo suficiente, verá que cada dígito es independiente de la pantalla.

def display(dec): #display function for 7-segment display


outData(0xff) #eliminate residual display
selectDigit(0x01) #Select the first, and display the single digit
outData(num[dec%10])
time.sleep(0.003) #display duration
176 Capítulo 18 74HC595 y pantalla de 7 segmentos. www.freenove.com █

outData(0xff)
selectDigit(0x02) #Select the second, and display the tens digit
outData(num[dec%100/10])
time.sleep(0.003)
outData(0xff)
selectDigit(0x04) #Select the third, and display the hundreds digit
outData(num[dec%1000/100])
time.sleep(0.003)
outData(0xff)
selectDigit(0x08) #Select the fourth, and display the thousands digit
outData(num[dec%10000/1000])
time.sleep(0.003)
Subfunction timer () es la función de devolución de llamada del temporizador. Cuando se acabe el tiempo, esta
función será eliminada. Acompañado por la ejecución, el contador variable se agregará 1, y luego reiniciará el
tiempo del temporizador a 1s. 1 segundo, la función se ejecutará nuevamente.
def timer(): #timer function
global counter
global t
t = threading.Timer(1.0,timer) #reset time of timer to 1s
t.start() #Start timing
counter+=1
print "counter : %d"%counter
Subfunction setup()Configuración de subfunción (), configure todos los modos de salida de entrada para el pin
GPIO utilizado.
Finalmente, en la función de bucle, haga que el tubo muestre digital el valor del contador variable en el ciclo
while. Eldef loop():cambiará en el temporizador de función (), por lo que el contenido visualizado por la
valor
visualización de 7 segmentos cambiará
global t en consecuencia.
global counter
t = threading.Timer(1.0,timer) # set the timer
t.start() #Start timing
while True:
display(counter) #display the number counter
Después de ejecutar el programa, presione la tecla "Ctrl + C", luego, haga clic en la subfunción destroy () y
haga los recursos y temporizadores de GPIO en esta subfunción.
def destroy(): # When 'Ctrl+C' is pressed, the function is executed.
global t
GPIO.cleanup()
t.cancel() # cancel the timer
█ www.freenove.com Capítulo 19 74HC595 y matriz LED 177

Capítulo 19 74HC595 y matriz LED


Hemos aprendido cómo usar 74HC595 para controlar LEDBar Graph y Seven-SegmentDisplay. Y continuaremos
utilizando el 74HC595 para controlar más LED, LEDMatrix.

Proyecto 19.1 LED Matrix

En este experimento, utilizaremos dos 74HC595 para controlar una matriz LED monocromática (8 * 8) para que
muestre algunos gráficos y caracteres.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x41


GPIO Extension Board & Wire x1
BreadBoard x1
74HC595 x2 8*8 LEDMatrix x1 Resistor 220Ω x8
178 Capítulo 19 74HC595 y matriz LED www.freenove.com █

Conocimiento del componente

LED matrix
La matriz LED es un módulo de pantalla rectangular que consiste en varios LED. La siguiente es una matriz LED
monocromática 8 * 8 con 64 LED (8 filas y 8 columnas).

Para facilitar la operación y guardar los puertos, el polo positivo de los LED en cada fila y el polo negativo de los
LED en cada columna están conectados respectivamente dentro del módulo de matriz LED, que se denomina
Ánodo común. Hay otra forma. El polo negativo de los LED en cada fila y el polo positivo de los LED en cada
columna están conectados entre sí, respectivamente, lo que se denomina Cátodo común.
El que usamos en este experimento es un ánodo común LEDMatrix.
Conexion modo ánodo común Conexion modo cátodo común
█ www.freenove.com Capítulo 19 74HC595 y matriz LED 179

Aprendamos cómo funciona el modo de conexión del ánodo común. Elija 16 puertos en la placa RPI para
conectarse a los 16 puertos de LED Matrix. Configurado un puerto en columnas para bajo nivel, que hace que la
columna del puerto sea seleccionada. Luego configure los ocho puertos en la fila para mostrar el contenido en la
columna seleccionada. Demora por un momento. Y luego selecciona la siguiente columna y muestra el contenido
correspondiente. Este tipo de operación a columna se llama exploración. Si desea mostrar la siguiente imagen de
una cara sonriente, puede mostrarla en 8 columnas y cada columna se representa con un byte.

1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0
0 0 1 1 1 1 0 0
0 1 0 0 0 0 1 0
1 0 1 0 0 1 0 1
1 0 0 0 0 0 0 1
1 0 0 1 1 0 0 1
0 1 0 0 0 0 1 0
0 0 1 1 1 1 0 0

Column Binary Hexadecimal


1 0001 1100 0x1c
2 0010 0010 0x22
3 0101 0001 0x51
4 0100 0101 0x45
5 0100 0101 0x45
6 0101 0001 0x51
7 0010 0010 0x22
8 0001 1100 0x1c

Primero, visualice la primera columna, luego apague la primera columna y visualice la segunda columna ... apague
la séptima columna y mostrar la octava columna, y luego comenzar de nuevo desde la primera columna como el
control de Graph LEDBar. Todo el programa se repetirá rápidamente y circularmente. Debido al efecto Afterglow
del LED y al efecto residual visual de los ojos humanos, veremos una imagen de una cara sonriente directamente
en lugar de LED que se enciende una columna por una columna (aunque de hecho es la situación real).
Scaning rows es otra forma de visualización de matriz de puntos. Ya sea que escanee líneas o columnas, se
requieren 16 GPIO. Para guardar GPIO de la placa de control, se utilizan dos 74HC595. Cada pieza de 74HC595
tiene ocho puertos de salida paralelos, por lo que dos piezas tienen 16 puertos en total, lo suficiente. La línea de
control y la línea de datos de dos 74HC595 no están todas conectadas al RPi, sino que conectan el pin Q7 de la
primera etapa 74HC595 al pin de datos del segundo, es decir, dos 74HC595 están conectados en serie. Es lo
mismo que usar un "74HC595" con 16 puertos de salida paralelos.
180 Capítulo 19 74HC595 y matriz LED www.freenove.com █

Circuito

En este circuito experimental, el pin de alimentación de 74HC595 está conectado a 3.3V. También se puede
conectar a 5V para hacer LEDMatrix más brillante.
Schematic diagram
█ www.freenove.com Capítulo 19 74HC595 y matriz LED 181

Hardware connection

Second stage
74HC595:B

First stage
74HC595:A
182 Capítulo 19 74HC595 y matriz LED www.freenove.com █

Código

Dos 74HC595 se utilizan en este experimento utilizado, uno para controlar columnas de LEDMatrix, otro para
líneas. Y dos 74HC595 están conectados en forma de cascada (serie) y tiene 16 puertos de salida. Beacause
shiftOut () función de salida de datos de 8 bits una vez, se requieren dos veces la función shiftOut () y los datos de
la segunda etapa 74HC595 deben transmitirse de manera preferente. Hay dos 74HC595 en este circuito
experimental, A (primera etapa) y B (segunda etapa). Cuando el RPi usa la función shiftOut () para enviar datos
"data1", los datos del puerto A serán "data1", y los datos de B serán 0. Luego, use shiftOut () para enviar "data2",
luego data "data1" de A se moverá a B y los datos nuevos "datos2" se moverán a A. De acuerdo con la conexión
del circuito, los datos de línea deben enviarse primero, luego enviar datos de columna. El siguiente código hará
que LEDMatrix muestre una cara sonriente y luego muestre el carácter de desplazamiento "0-F".
C Code 19.1.1 LEDMatrix
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 19.1.1_LEDMatrix del lenguaje C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/19.1.1_LEDMatrix
2. Utilice el siguiente comando para compilar "LEDMatrix.c" y generar archivo ejecutable“LEDMatrix”.
gcc LEDMatrix.c –o LEDMatrix –lwiringPi
3. Luego ejecuta el archivo generado “LEDMatrix”.
sudo ./LEDMatrix
Después de que se ejecuta el programa, LEDMatrix mostrará una cara sonriente, y luego la pantalla desplazando
el carácter "0-F", circularmente.
El siguiente es el código del programa:
1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <wiringShift.h>
4
5 #define dataPin 0 //DS Pin of 74HC595(Pin14)
6 #define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
7 #define clockPin 3 //SH_CP Pin of 74HC595(Pin11)
8 // data of smiling face
9 unsigned char pic[]={0x1c,0x22,0x51,0x45,0x45,0x51,0x22,0x1c};
10 unsigned char data[]={ // data of "0-F"
11 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
12 0x00, 0x00, 0x3E, 0x41, 0x41, 0x3E, 0x00, 0x00, // "0"
13 0x00, 0x00, 0x21, 0x7F, 0x01, 0x00, 0x00, 0x00, // "1"
14 0x00, 0x00, 0x23, 0x45, 0x49, 0x31, 0x00, 0x00, // "2"
15 0x00, 0x00, 0x22, 0x49, 0x49, 0x36, 0x00, 0x00, // "3"
16 0x00, 0x00, 0x0E, 0x32, 0x7F, 0x02, 0x00, 0x00, // "4"
17 0x00, 0x00, 0x79, 0x49, 0x49, 0x46, 0x00, 0x00, // "5"
18 0x00, 0x00, 0x3E, 0x49, 0x49, 0x26, 0x00, 0x00, // "6"
19 0x00, 0x00, 0x60, 0x47, 0x48, 0x70, 0x00, 0x00, // "7"
20 0x00, 0x00, 0x36, 0x49, 0x49, 0x36, 0x00, 0x00, // "8"
21 0x00, 0x00, 0x32, 0x49, 0x49, 0x3E, 0x00, 0x00, // "9"
█ www.freenove.com Capítulo 19 74HC595 y matriz LED 183

22 0x00, 0x00, 0x3F, 0x44, 0x44, 0x3F, 0x00, 0x00, // "A"


23 0x00, 0x00, 0x7F, 0x49, 0x49, 0x36, 0x00, 0x00, // "B"
24 0x00, 0x00, 0x3E, 0x41, 0x41, 0x22, 0x00, 0x00, // "C"
25 0x00, 0x00, 0x7F, 0x41, 0x41, 0x3E, 0x00, 0x00, // "D"
26 0x00, 0x00, 0x7F, 0x49, 0x49, 0x41, 0x00, 0x00, // "E"
27 0x00, 0x00, 0x7F, 0x48, 0x48, 0x40, 0x00, 0x00, // "F"
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " "
29 };
30 int main(void)
31 {
32 int i,j,k;
33 unsigned char x;
34 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
35 printf("setup wiringPi failed !");
36 return 1;
37 }
38 pinMode(dataPin,OUTPUT);
39 pinMode(latchPin,OUTPUT);
40 pinMode(clockPin,OUTPUT);
41 while(1){
42 for(j=0;j<500;j++){// Repeat enough times to display the smiling face a period of
43 time
44 x=0x80;
45 for(i=0;i<8;i++){
46 digitalWrite(latchPin,LOW);
47 shiftOut(dataPin,clockPin,LSBFIRST,pic[i]);// first shift data of line
48 information to the first stage 74HC959
49 shiftOut(dataPin,clockPin,LSBFIRST,~x);//then shift data of column
50 information to the second stage 74HC959
51
52 digitalWrite(latchPin,HIGH);//Output data of two stage 74HC595 at the
53 same time
54 x>>=1;// display the next column
55 delay(1);
56 }
57 }
58 for(k=0;k<sizeof(data)-8;k++){ //sizeof(data) total number of "0-F" columns
59 for(j=0;j<20;j++){// times of repeated displaying LEDMatrix in every frame,
60 the bigger the “j”, the longer the display time
61 x=0x80; // Set the column information to start from the first column
62 for(i=k;i<8+k;i++){
63 digitalWrite(latchPin,LOW);
64 shiftOut(dataPin,clockPin,LSBFIRST,data[i]);
65 shiftOut(dataPin,clockPin,LSBFIRST,~x);
184 Capítulo 19 74HC595 y matriz LED www.freenove.com █

66 digitalWrite(latchPin,HIGH);
67 x>>=1;
68 delay(1);
69 }
70 }
71 }
72 }
73 return 0;
74 }
El primer ciclo “for” (ciclo "para") en el ciclo “while” (ciclo "mientras") se usa para mostrar una sonrisa estática. Muestra la información de la columna
de izquierda a derecha, una columna por una columna, totalmente 8 columnas. Repita 500 veces para asegurar el tiempo de visualización suficiente.

for(j=0;j<500;j++){// Repeat enough times to display the smiling face a period


of time
x=0x80;
for(i=0;i<8;i++){
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,LSBFIRST,pic[i]);
shiftOut(dataPin,clockPin,LSBFIRST,~x);
digitalWrite(latchPin,HIGH);
x>>=1;
delay(1);
}
}
El segundo ciclo "for"(ciclo "para") se usa para mostrar los caracteres de desplazamiento "0-F", totalmente 18 * 8 = 144
columnas. Muestra la columna 0-8, columna 1-9, columna 2-10 ...... 138-144 columna a su vez para lograr el efecto de
desplazamiento. La exhibición de cada fotograma se repite un cierto número de veces, y cuantas más veces se repitan,
más larga es la visualización de un solo fotograma, más lenta es la reproducción.
for(k=0;k<sizeof(data)-8;k++){ //sizeof(data) total number of "0-F" columns
for(j=0;j<20;j++){// times of repeated displaying LEDMatrix in every frame,
the bigger the “j”, the longer the display time
x=0x80; // Set the column information to start from the first column
for(i=k;i<8+k;i++){
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,LSBFIRST,data[i]);
shiftOut(dataPin,clockPin,LSBFIRST,~x);
digitalWrite(latchPin,HIGH);
x>>=1;
delay(1);
}
}
}
█ www.freenove.com Capítulo 19 74HC595 y matriz LED 185

Pyhton Code 19.1.1 LEDMatrix


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 19.1.1_LEDMatrix del lenguaje Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/19.1.1_LEDMatrix
2. Use el comando python para ejecutar el código python "LEDMatrix.py".
python LEDMatrix.py
Después de que se ejecuta el programa, LEDMatrix mostrará una cara sonriente, y luego la pantalla desplazando
el carácter "0-F", circularmente.
El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3
4 LSBFIRST = 1
5 MSBFIRST = 2
6 #define the pins connect to 74HC595
7 dataPin = 11 #DS Pin of 74HC595(Pin14)
8 latchPin = 13 #ST_CP Pin of 74HC595(Pin12)
9 clockPin = 15 #SH_CP Pin of 74HC595(Pin11)
10 pic = [0x1c,0x22,0x51,0x45,0x45,0x51,0x22,0x1c]# data of smiling face
11 data = [#data of "0-F"
12 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # " "
13 0x00, 0x00, 0x3E, 0x41, 0x41, 0x3E, 0x00, 0x00, # "0"
14 0x00, 0x00, 0x21, 0x7F, 0x01, 0x00, 0x00, 0x00, # "1"
15 0x00, 0x00, 0x23, 0x45, 0x49, 0x31, 0x00, 0x00, # "2"
16 0x00, 0x00, 0x22, 0x49, 0x49, 0x36, 0x00, 0x00, # "3"
17 0x00, 0x00, 0x0E, 0x32, 0x7F, 0x02, 0x00, 0x00, # "4"
18 0x00, 0x00, 0x79, 0x49, 0x49, 0x46, 0x00, 0x00, # "5"
19 0x00, 0x00, 0x3E, 0x49, 0x49, 0x26, 0x00, 0x00, # "6"
20 0x00, 0x00, 0x60, 0x47, 0x48, 0x70, 0x00, 0x00, # "7"
21 0x00, 0x00, 0x36, 0x49, 0x49, 0x36, 0x00, 0x00, # "8"
22 0x00, 0x00, 0x32, 0x49, 0x49, 0x3E, 0x00, 0x00, # "9"
23 0x00, 0x00, 0x3F, 0x44, 0x44, 0x3F, 0x00, 0x00, # "A"
24 0x00, 0x00, 0x7F, 0x49, 0x49, 0x36, 0x00, 0x00, # "B"
25 0x00, 0x00, 0x3E, 0x41, 0x41, 0x22, 0x00, 0x00, # "C"
26 0x00, 0x00, 0x7F, 0x41, 0x41, 0x3E, 0x00, 0x00, # "D"
27 0x00, 0x00, 0x7F, 0x49, 0x49, 0x41, 0x00, 0x00, # "E"
28 0x00, 0x00, 0x7F, 0x48, 0x48, 0x40, 0x00, 0x00, # "F"
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # " "
30 ]
31 def setup():
32 GPIO.setmode(GPIO.BOARD) # Number GPIOs by its physical location
33 GPIO.setup(dataPin, GPIO.OUT)
34 GPIO.setup(latchPin, GPIO.OUT)
35 GPIO.setup(clockPin, GPIO.OUT)
186 Capítulo 19 74HC595 y matriz LED www.freenove.com █

36
37 def shiftOut(dPin,cPin,order,val):
38 for i in range(0,8):
39 GPIO.output(cPin,GPIO.LOW);
40 if(order == LSBFIRST):
41 GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
42 elif(order == MSBFIRST):
43 GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
44 GPIO.output(cPin,GPIO.HIGH);
45
46 def loop():
47 while True:
48 for j in range(0,500):# Repeat enough times to display the smiling face a period
49 of time
50 x=0x80
51 for i in range(0,8):
52 GPIO.output(latchPin,GPIO.LOW)
53 shiftOut(dataPin,clockPin,LSBFIRST,pic[i]) #first shift data of line
54 information to first stage 74HC959
55
56 shiftOut(dataPin,clockPin,LSBFIRST,~x) #then shift data of column
57 information to second stage 74HC959
58 GPIO.output(latchPin,GPIO.HIGH)# Output data of two stage 74HC595 at the
59 same time
60 time.sleep(0.001)# display the next column
61 x>>=1
62 for k in range(0,len(data)-8):#len(data) total number of "0-F" columns
63 for j in range(0,20):# times of repeated displaying LEDMatrix in every frame,
64 the bigger the “j”, the longer the display time.
65 x=0x80 # Set the column information to start from the first column
66 for i in range(k,k+8):
67 GPIO.output(latchPin,GPIO.LOW)
68 shiftOut(dataPin,clockPin,LSBFIRST,data[i])
69 shiftOut(dataPin,clockPin,LSBFIRST,~x)
70 GPIO.output(latchPin,GPIO.HIGH)
71 time.sleep(0.001)
72 x>>=1
73 def destroy(): # When 'Ctrl+C' is pressed, the function is executed.
74 GPIO.cleanup()
75 if __name__ == '__main__': # Program starting from here
76 print 'Program is starting...'
77 setup()
78 try:
79 loop()
█ www.freenove.com Capítulo 19 74HC595 y matriz LED 187

80 except KeyboardInterrupt:
81 destroy()
El primer“for”(ciclo en el ciclo "para")"while" se usa para mostrar una sonrisa estática. Muestra la información de la columna de izquierda a
derecha, una columna por una columna, totalmente 8 columnas. Repita 500 veces para asegurar el tiempo de visualización suficiente.

for j in range(0,500):# Repeat enough times to display the smiling face a period
of time
x=0x80
for i in range(0,8):
GPIO.output(latchPin,GPIO.LOW)
shiftOut(dataPin,clockPin,LSBFIRST,pic[i])#first shift data of line
information to first stage 74HC959
shiftOut(dataPin,clockPin,LSBFIRST,~x)#then shift data of column
information to first stage 74HC959

GPIO.output(latchPin,GPIO.HIGH)# Output data of two stage 74HC595 at the


same time.
time.sleep(0.001)# display the next column
x>>=1
El segundo“for” (ciclo "para") se usa para mostrar los caracteres de desplazamiento "0-F", totalmente 18 * 8 =
144 columnas. Muestra la columna 0-8, columna 1-9, columna 2-10 ...... 138-144 columna a su vez para lograr el
efecto de desplazamiento. La exhibición de cada fotograma se repite un cierto número de veces, y cuantas más
veces se repitan, más larga es la visualización de un solo fotograma, más lenta es la reproducción.

for k in range(0,len(data)-8):#len(data) total number of “O-F” columns.


for j in range(0,20):# times of repeated displaying LEDMatrix in every frame,
the bigger the “j”, the longer the display time
x=0x80 # Set the column information to start from the first column
for i in range(k,k+8):
GPIO.output(latchPin,GPIO.LOW)
shiftOut(dataPin,clockPin,LSBFIRST,data[i])
shiftOut(dataPin,clockPin,LSBFIRST,~x)
GPIO.output(latchPin,GPIO.HIGH)
time.sleep(0.001)
x>>=1
188 Capítulo 20 LCD1602 www.freenove.com █

Capítulo 20 LCD1602
En este capítulo, aprenderemos una pantalla de visualización, LCD1602.

Proyecto 20.1 I2C LCD1602

LCD1602 puede mostrar 2 líneas de caracteres en 16 columnas. Puede mostrar números, letras, símbolos, código
ASCII, etc. Como se muestra abajo, hay una pantalla LCD monocroma LCD1602 y su diagrama de pin de circuito:

I2C LCD1602 integra una interfaz I2C, que conecta el módulo de entrada serie y salida en paralelo a LCD1602. Solo
usamos 4 líneas para operar LCD1602 fácilmente.

El chip de serie a paralelo utilizado en este módulo es PCF8574 (PCF8574A), y su dirección I2C predeterminada es
0x27 (0x3F), y puede ver todo el bus RPI en su dirección de dispositivo I2C a través del comando "i2cdetect -y 1"
para . (consulte la sección "configuración I2C" a continuación) a continuación se muestra el diagrama
esquemático del pin PCF8574 y el diagrama de pin del bloque:

PCF8574 chip pin diagram: PCF8574 module pin diagram

El pin del módulo PCF8574 y el pin LCD1602 se corresponden entre sí y se conectan entre sí:
█ www.freenove.com Capítulo 20 LCD1602 189

Por lo tanto, podemos usar solo 4 pines para controlar LCD1602 con 16 pines fácilmente a través de la interfaz
I2C.
En este experimento, usaremos I2C LCD 1602 para mostrar algunos caracteres estáticos y variables dinámicas.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x4


GPIO Extension Board & Wire x1
BreadBoard x1
I2C LCD1602 Module x1
190 Capítulo 20 LCD1602 www.freenove.com █

Circuito

Tenga en cuenta que la fuente de alimentación para I2CLCD1602 en este circuito es de 5V.
Schematic diagram

Hardware connection
█ www.freenove.com Capítulo 20 LCD1602 191

Código

Este código obtendrá la temperatura de la CPU y el tiempo del sistema de RPi, los mostrará en la LCD 1602.
C Code 20.1.1 I2CLCD1602
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar el directorio 20.1.1_ I2CLCD1602 del código C.
cd Freenove_Super_Starter_Kit_for_Raspberry_Pi/Code/C_Code/20.1.1_I2CLCD1602
2. Abra el archivo I2CLCD1602.c y encuentre la definición de macro "pcf8574_address". Si su módulo de serie a
paralelo usa el chip PCF8574, establezca el valor macro "dirección_acf8574_" en 0x27. Si su módulo de serie a
paralelo usa el chip PCF8574A, establezca el valor macro "dirección_acf8574_" en 0x3F.

3. Utilice el siguiente comando para compilar "I2CLCD1602.c" y generar archivo ejecutable “I2CLCD1602”.
gcc I2CLCD1602.c –o I2CLCD1602 –lwiringPi –lwiringPiDev
4. Luego ejecuta el archivo generado“I2CLCD1602”.
sudo ./ I2CLCD1602
Después de que se ejecuta el programa, la pantalla LCD1602 mostrará la temperatura actual de la CPU y la hora
del sistema. Si no hay pantalla o la pantalla no está clara, ajuste el potenciómetro del módulo PCF8574 para
ajustar el contraste de LCD1602 hasta que la pantalla pueda mostrarse claramente.
El siguiente es el código del programa:
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <wiringPi.h>
4 #include <pcf8574.h>
5 #include <lcd.h>
6 #include <time.h>
7
8 //#define pcf8574_address 0x27 // default I2C address of Pcf8574
9 #define pcf8574_address 0x3F // default I2C address of Pcf8574A
10 #define BASE 64 // BASE is not less than 64
11 //////// Define the output pins of the PCF8574, which are directly connected to the
12 LCD1602 pin.
13 #define RS BASE+0
14 #define RW BASE+1
15 #define EN BASE+2
16 #define LED BASE+3
17 #define D4 BASE+4
18 #define D5 BASE+5
19 #define D6 BASE+6
20 #define D7 BASE+7
21
22 int lcdhd;// used to handle LCD
23 void printCPUTemperature(){// sub function used to print CPU temperature
192 Capítulo 20 LCD1602 www.freenove.com █

24 FILE *fp;
25 char str_temp[15];
26 float CPU_temp;
27 // CPU temperature data is stored in this directory.
28 fp=fopen("/sys/class/thermal/thermal_zone0/temp","r");
29 fgets(str_temp,15,fp); // read file temp
30 CPU_temp = atof(str_temp)/1000.0; // convert to Celsius degrees
31 printf("CPU's temperature : %.2f \n",CPU_temp);
32 lcdPosition(lcdhd,0,0); // set the LCD cursor position to (0,0)
33 lcdPrintf(lcdhd,"CPU:%.2fC",CPU_temp);// Display CPU temperature on LCD
34 fclose(fp);
35 }
36 void printDataTime(){//used to print system time
37 time_t rawtime;
38 struct tm *timeinfo;
39 time(&rawtime);// get system time
40 timeinfo = localtime(&rawtime);// convert to local time
41 printf("%s \n",asctime(timeinfo));
42 lcdPosition(lcdhd,0,1);// set the LCD cursor position to (0,1)
43 lcdPrintf(lcdhd,"Time:%d:%d:%d",timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
44 //Display system time on LCD
45 }
46 int main(void){
47 int i;
48
49 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
50 printf("setup wiringPi failed !");
51 return 1;
52 }
53 pcf8574Setup(BASE,pcf8574_address);// initialize PCF8574
54 for(i=0;i<8;i++){
55 pinMode(BASE+i,OUTPUT); // set PCF8574 port to output mode
56 }
57 digitalWrite(LED,HIGH); // turn on LCD backlight
58 digitalWrite(RW,LOW); // allow writing to LCD
59 lcdhd = lcdInit(2,16,4,RS,EN,D4,D5,D6,D7,0,0,0,0);// initialize LCD and return “handle”
60 used to handle LCD
61 if(lcdhd == -1){
62 printf("lcdInit failed !");
63 return 1;
64 }
65 while(1){
66 printCPUTemperature();// print CPU temperature
67 printDataTime(); // print system time
█ www.freenove.com Capítulo 20 LCD1602 193

68 delay(1000);
69 }
70 return 0;
}
Se puede ver en el código que PCF8591 y PCF8574 tienen muchas similitudes, están a través de la interfaz I2C
para expandir el GPIO RPI. Primero define la dirección I2C del PCF8574 y la extensión del pin GPIO, que está
conectado al pin GPIO del LCD1602.
//#define pcf8574_address 0x27 // default I2C address of Pcf8574
#define pcf8574_address 0x3F // default I2C address of Pcf8574A
#define BASE 64 // BASE is not less than 64
//////// Define the output pins of the PCF8574, which are directly connected to the
LCD1602 pin.
#define RS BASE+0
#define RW BASE+1
#define EN BASE+2
#define LED BASE+3
#define D4 BASE+4
#define D5 BASE+5
#define D6 BASE+6
#define D7 BASE+7
Luego, en la función principal, inicialice el PCF8574, configure todos los pines en el modo de salida y encienda la
luz de fondo LCD1602.
pcf8574Setup(BASE,pcf8574_address);// initialize PCF8574
for(i=0;i<8;i++){
pinMode(BASE+i,OUTPUT); // set PCF8574 port to output mode
}
digitalWrite(LED,HIGH); // turn on LCD backlight
Luego use lcdInit () para inicializar LCD1602 y configure el pin RW de LCD1602 en 0 (es decir, puede escribir)
según los requisitos de esta función. El valor de retorno de la función llamada "Handle" se usa para manejar el
LCD1602 "next".
lcdhd = lcdInit(2,16,4,RS,EN,D4,D5,D6,D7,0,0,0,0);// initialize LCD and return
“handle” used to handle LCD
Detalles sobre lcdInit():
int lcdInit (int rows, int cols, int bits, int rs, int strb,
int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;
Esta es la función de inicialización principal y debe invocarse antes de utilizar cualquier otra función de LCD.
Las filas y columnas son las filas y columnas en la pantalla (por ejemplo, 2, 16 o 4,20). Bits es la cantidad de bits
de ancho en la interfaz (4 u 8). El rs y el strb representan los números de pin de las pantallas RS pin y Strobe (E)
pin. Los parámetros d0 a d7 son los números de pin de los 8 pines de datos conectados desde Pi a la pantalla.
Solo los primeros 4 se usan si está ejecutando la pantalla en el modo de 4 bits.
El valor de retorno es el "identificador" que se utilizará para todas las llamadas posteriores a la biblioteca lcd
cuando se trate con esa pantalla LCD, o -1 para indicar una falla. (Por lo general, parámetros incorrectos)
Para obtener más información sobre la Biblioteca LCD, consulte: https://projects.drogon.net/raspberry-pi/
wiringpi/lcd-library/
194 Capítulo 20 LCD1602 www.freenove.com █

En el siguiente "while", se invocan dos subfunciones para mostrar la temperatura y el tiempo de la CPU. Primero
mire la función secundaria printCPUTemperature (). Los datos de temperatura de la CPU se almacenan en "/sys/
class/thermal/thermal_zone0/temp " archivo. Necesitamos leer el contenido del archivo y convertirlo en un
valor de temperatura almacenado en la variable CPU_temp, y usar lcdPrintf () para mostrarlo en la pantalla LCD.
void printCPUTemperature(){//sub function used to print CPU temperature

FILE *fp;
char str_temp[15];
float CPU_temp;
// CPU temperature data is stored in this directory.
fp=fopen("/sys/class/thermal/thermal_zone0/temp","r");
fgets(str_temp,15,fp); // read file temp
CPU_temp = atof(str_temp)/1000.0; // convert to Celsius degrees
printf("CPU's temperature : %.2f \n",CPU_temp);
lcdPosition(lcdhd,0,0); // set the LCD cursor position to (0,0)
lcdPrintf(lcdhd,"CPU:%.2fC",CPU_temp);// Display CPU temperature on LCD
fclose(fp);
}
Detalles sobre lcdPosition () y lcdPrintf ():
lcdPosition (int handle, int x, int y);
Establezca la posición del cursor para la posterior entrada de texto.
lcdPutchar (int handle, uint8_t data)
lcdPuts (int handle, char *string)
lcdPrintf (int handle, char *message, …)
Estos producen un único carácter ASCII, una cadena o una cadena formateada utilizando los comandos de
formateo de printf habituales.
A continuación está la función secundaria printDataTime () utilizada para imprimir la hora del sistema. Primero,
obtuve la hora estándar y la almacené en tiempo variable variable, y luego la convertí a la hora local y la cambié a
timeinfo, y finalmente visualicé la información de tiempo en LCD1602.
void printDataTime(){//used to print system time
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);// get system time
timeinfo = localtime(&rawtime);// convert to local time
printf("%s \n",asctime(timeinfo));
lcdPosition(lcdhd,0,1);// set the LCD cursor position to (0,1)
lcdPrintf(lcdhd,"Time:%d:%d:%d",timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
//Display system time on LCD
}
█ www.freenove.com Capítulo 20 LCD1602 195

Pyhton Code 20.1.1 I2CLCD1602


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar el directorio 20.1.1_ I2CLCD1602 del código de Python.
cd Freenove_Super_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/20.1.1_I2CLCD1602
2. Utilice el comando python para ejecutar el código python "I2CLCD1602.py".
python I2CLCD1602.py
Después de que se ejecuta el programa, la pantalla LCD1602 mostrará la temperatura actual de la CPU y la hora
del sistema. Si no hay pantalla o la pantalla no está clara, ajuste el potenciómetro del módulo PCF8574 para
ajustar el contraste de LCD1602 hasta que la pantalla pueda mostrarse claramente.
El siguiente es el código del programa:
1 from PCF8574 import PCF8574_GPIO
2 from Adafruit_LCD1602 import Adafruit_CharLCD
3
4 from time import sleep, strftime
5 from datetime import datetime
6
7 def get_cpu_temp(): # get CPU temperature and store it into file
8 “/sys/class/thermal/thermal_zone0/temp”
9 tmp = open('/sys/class/thermal/thermal_zone0/temp')
10 cpu = tmp.read()
11 tmp.close()
12 return '{:.2f}'.format( float(cpu)/1000 ) + ' C'
13
14 def get_time_now(): # get system time
15 return datetime.now().strftime(' %H:%M:%S')
16
17 def loop():
18 mcp.output(3,1) # turn on LCD backlight
19 lcd.begin(16,2) # set number of LCD lines and columns
20 while(True):
21 #lcd.clear()
22 lcd.setCursor(0,0) # set cursor position
23 lcd.message( 'CPU: ' + get_cpu_temp()+'\n' )# display CPU temperature
24 lcd.message( get_time_now() ) # display the time
25 sleep(1)
26
27 def destroy():
28 lcd.clear()
29
30 PCF8574_address = 0x27 # I2C address of the PCF8574 chip.
31 PCF8574A_address = 0x3F # I2C address of the PCF8574A chip.
32 # Create PCF8574 GPIO adapter.
33 try:
34 mcp = PCF8574_GPIO(PCF8574_address)
196 Capítulo 20 LCD1602 www.freenove.com █

35 except:
36 try:
37 mcp = PCF8574_GPIO(PCF8574A_address)
38 except:
39 print 'I2C Address Error !'
40 exit(1)
41 # Create LCD, passing in MCP GPIO adapter.
lcd = Adafruit_CharLCD(pin_rs=0, pin_e=2, pins_db=[4,5,6,7], GPIO=mcp)

if __name__ == '__main__':
print 'Program is starting ... '
try:
loop()
except KeyboardInterrupt:
destroy()
Se usan dos módulos en el código, PCF8574.py y Adafruit_LCD1602.py. Estos dos documentos y el archivo de código se almacenan en el
mismo directorio, y ninguno de ellos es prescindible. Por favor no lo borres PCF8574.py se utiliza para proporcionar el modo de
comunicación I2C y el método de operación de algunos puertos para chips RPi y PCF8574. El módulo de Adafruit Adafruit_LCD1602.py se
utiliza para proporcionar algún método de funcionamiento de función para LCD1602.
En el código, primero obtenga el objeto utilizado para operar el puerto PCF8574, luego obtenga el objeto utilizado para operar LCD1602.

address = 0x27 # I2C address of the PCF8574 chip.


# Create PCF8574 GPIO adapter.
mcp = PCF8574_GPIO(address)
# Create LCD, passing in MCP GPIO adapter.
lcd = Adafruit_CharLCD(pin_rs=0, pin_e=2, pins_db=[4,5,6,7], GPIO=mcp)
De acuerdo con la conexión del circuito, el puerto 3 de PCF8574 está conectado al polo positivo de la luz de
fondo LCD1602. Luego, en la función de loop () (bucle()), use mcp.output (3,1) para encender la luz de fondo
LCD1602 y configure el número de líneas y columnas de LCD.
def loop():
mcp.output(3,1) # turn on the LCD backlight
lcd.begin(16,2) # set number of LCD lines and columns
En el siguiente ciclo while, establece la posición del cursor y muestra la temperatura y la hora de la CPU.
while(True):
#lcd.clear()
lcd.setCursor(0,0) # set cursor position
lcd.message( 'CPU: ' + get_cpu_temp()+'\n' )# display CPU temperature
lcd.message( get_time_now() ) # display the time
sleep(1)
La temperatura de la CPU se almacena en el archivo "/ sys / class / thermal / thermal_zone0 / temp". Abra
el archivo y lee el contenido del archivo y luego lo convierte a grados Celsius y lo devuelve. La función
secundaria utilizada para obtener la temperatura de la CPU se muestra a continuación:

def get_cpu_temp(): # get CPU temperature and store it into file


“/sys/class/thermal/thermal_zone0/temp”
tmp = open('/sys/class/thermal/thermal_zone0/temp')
█ www.freenove.com Capítulo 20 LCD1602 197

cpu = tmp.read()
tmp.close()
return '{:.2f}'.format( float(cpu)/1000 ) + ' C'
Sub function usada para get time:
def get_time_now(): # get the time
return datetime.now().strftime(' %H:%M:%S')

Detalles acerca de PCF8574.py y Adafruit_LCD1602.py:


Module PCF8574
Este módulo proporciona dos clases PCF8574_I2C and PCF8574_GPIO. Class PCF8574_I2C:proporciona
métodos de lectura y escritura para PCF8574. Class PCF8574_GPIO:proporciona un conjunto estandarizado
de funciones GPIO.
Se puede ver más información a través de la apertura PCF8574.py. Módulo Adafruit_LCD1602

Module Adafruit_LCD1602
Este módulo proporciona el método básico de funcionamiento de LCD1602, incluida la clase
Adafruit_CharLCD. Algunas funciones miembro se describen de la siguiente manera:
def begin(self, cols, lines):establece el número de líneas y columnas de la pantalla.
def clear(self): limpiar la pantalla
def setCursor(self, col, row): establecer la posición del cursor
def message(self, text): mostrar contenido
Se puede ver más información abriendo Adafruit_CharLCD.py.
198 Capítulo 21 Hygrothermograph DHT11 www.freenove.com █

Capítulo 21 Hygrothermograph DHT11


En este capítulo, aprenderemos un sensor comúnmente utilizado, Hygrothermograph DHT11.

Proyecto 21.1 Higrotermógrafo

El higrotermógrafo es una herramienta importante en nuestra vida para recordarnos de mantener el calor y
reponer la humedad a tiempo. En este experimento, usaremos RPi para leer los datos de temperatura y humedad
de DHT11.

Lista de componentes

Raspberry Pi 3B x1 DHT11 x1 Resistor 10kΩ x1


GPIO Expansion Board & Wire x1
BreadBoard x1

Jumper M/M x4

Conocimiento del componente

Sensor de temperatura y humedad DHT11 es un sensor compuesto de temperatura y humedad, y la señal digital
de salida se ha calibrado en el interior.

Tiene el tiempo de inicialización de 1S después de encenderse. El voltaje de operación está dentro del rango de 3.3V-5.5V.
█ www.freenove.com Capítulo 21 Hygrothermograph DHT11 199

Circuito

Schematic diagram

Hardware connection
200 Capítulo 21 Hygrothermograph DHT11 www.freenove.com █

Código

El código se usa para leer los datos de temperatura y humedad de DHT11 e imprimirlos. C Code
21.1.1 DHT11
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 21.1.1_DHT11 del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/21.1.1_DHT11
2. El código de este experimento contiene un archivo de encabezado personalizado. Utilice el siguiente
comando para compilar el código DHT11.cpp y DHT.cpp y generar el archivo ejecutable DHT11. Y el archivo de
encabezado personalizado se compilará al mismo tiempo.
gcc DHT.cpp DHT11.cpp –o DHT11 –lwiringPi
3. Ejecute el archivo generado "DHT11".
sudo ./DHT11
Después de que se ejecuta el programa, la ventana del terminal mostrará el número total actual de tiempos de
lectura, el estado de lectura, así como el valor de temperatura y humedad. Como se muestra a continuación:

El siguiente es el código del programa:


1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include "DHT.hpp"
5
6 #define DHT11_Pin 0 //define the pin of sensor
7
8 int main(){
9 DHT dht; //create a DHT class object
10 int chk,sumCnt;//chk:read the return value of sensor; sumCnt:times of reading sensor
11 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
12 printf("setup wiringPi failed !");
13 return 1;
14 }
15 while(1){
█ www.freenove.com Capítulo 21 Hygrothermograph DHT11 201

16 chk = dht.readDHT11(DHT11_Pin); //read DHT11 and get a return value. Then


17 determine whether data read is normal according to the return value.
18 sumCnt++; //counting number of reading times
19 printf("The sumCnt is : %d \n",sumCnt);
20 switch(chk){
21 case DHTLIB_OK: //if the return value is DHTLIB_OK, the data is normal.
22 printf("DHT11,OK! \n");
23 break;
24 case DHTLIB_ERROR_CHECKSUM: //data check has errors
25 printf("DHTLIB_ERROR_CHECKSUM! \n");
26 break;
27 case DHTLIB_ERROR_TIMEOUT: //reading DHT times out
28 printf("DHTLIB_ERROR_TIMEOUT! \n");
29 break;
30 case DHTLIB_INVALID_VALUE: //other errors
31 printf("DHTLIB_INVALID_VALUE! \n");
32 break;
33 }
34 printf("Humidity is %.2f %%, \t Temperature is %.2f
35 *C\n\n",dht.humidity,dht.temperature);
36 delay(1000);
37 }
38 return 1;
39 }
En este código experimental, usamos un archivo de biblioteca personalizado "DHT.hpp". Se encuentra en el mismo directorio con los
archivos de programa "DHT11.cpp" y "DHT.cpp", y los métodos para leer el sensor DHT se proporcionan en el archivo de la
biblioteca. Al usar esta biblioteca, podemos leer fácilmente el sensor DHT. Primero crea un objeto de clase DHT en el código.

DHT dht;
Y luego en el ciclo "while", use chk = dht.readDHT11 (DHT11_Pin) para leer el DHT11 y determine si la lectura de
datos es normal de acuerdo con el valor de retorno "chk". Y luego use la variable sumCnt para registrar la
cantidad de horas de lectura.
while(1){
chk = dht.readDHT11(DHT11_Pin); //read DHT11 and get a return value. Then
determine whether data read is normal according to the return value.
sumCnt++; //读取次数计数 count number of times of reading
printf("The sumCnt is : %d \n",sumCnt);
switch(chk){
case DHTLIB_OK: //if the return value is DHTLIB_OK, the data is normal.
printf("DHT11,OK! \n");
break;
case DHTLIB_ERROR_CHECKSUM: //data check has errors
printf("DHTLIB_ERROR_CHECKSUM! \n");
break;
case DHTLIB_ERROR_TIMEOUT: //reading DHT times out
202 Capítulo 21 Hygrothermograph DHT11 www.freenove.com █

printf("DHTLIB_ERROR_TIMEOUT! \n");
break;
case DHTLIB_INVALID_VALUE: //other errors
printf("DHTLIB_INVALID_VALUE! \n");
break;
}
Finalmente imprima los resultados:
printf("Humidity is %.2f %%, \t Temperature is %.2f *C\n\n",dht.humidity,dht.temperature);
El archivo de biblioteca "DHT.hpp" contiene una clase DHT y sus funciones de miembro público int readDHT11 (pin int) se usa para
leer el sensor DHT11 y almacenar los datos de temperatura y humedad leídos a las variables miembro doble humedad y
temperatura. El método de implementación de la función se incluye en el archivo "DHT.cpp".

1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <stdint.h>
4
5 ////read return flag of sensor
6 #define DHTLIB_OK 0
7 #define DHTLIB_ERROR_CHECKSUM -1
8 #define DHTLIB_ERROR_TIMEOUT -2
9 #define DHTLIB_INVALID_VALUE -999
10
11 #define DHTLIB_DHT11_WAKEUP 18
12 #define DHTLIB_DHT_WAKEUP 1
13
14 #define DHTLIB_TIMEOUT 100
15
16 class DHT{
17 public:
18 double humidity,temperature; //use to store temperature and humidity data read
19 int readDHT11(int pin); //read DHT11
20 private:
21 int bits[5]; //Buffer to receiver data
22 int readSensor(int pin,int wakeupDelay); //
23
24 };

Pyhton Code 21.1.1 DHT11


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 21.1.1_DHT11 del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/21.1.1_DHT11
2. Use el comando python para ejecutar el código "DHT11.py".
python DHT11.py
Después de que se ejecuta el programa, la ventana del terminal mostrará el número total actual de lectura, el
estado de lectura, así como el valor de temperatura y humedad. Como se muestra a continuación:
█ www.freenove.com Capítulo 21 Hygrothermograph DHT11 203

El siguiente es el código del programa:


1 import RPi.GPIO as GPIO
2 import time
3 import Freenove_DHT as DHT
4 DHTPin = 11 #define the pin of DHT11
5
6 def loop():
7 dht = DHT.DHT(DHTPin) #create a DHT class object
8 sumCnt = 0 #number of reading times
9 while(True):
10 sumCnt += 1 #counting number of reading times
11 chk = dht.readDHT11(DHTPin) #read DHT11 and get a return value. Then
12 determine whether data read is normal according to the return value.
13 print"The sumCnt is : %d, \t chk : %d"%(sumCnt,chk)
14 if (chk is dht.DHTLIB_OK): #read DHT11 and get a return value. Then
15 determine whether data read is normal according to the return value.
16 print"DHT11,OK!"
17 elif(chk is dht.DHTLIB_ERROR_CHECKSUM): #data check has errors
18 print"DHTLIB_ERROR_CHECKSUM!!"
19 elif(chk is dht.DHTLIB_ERROR_TIMEOUT): #reading DHT times out
20 print"DHTLIB_ERROR_TIMEOUT!"
21 else: #other errors
22 print"Other error!"
23
24 print"Humidity : %.2f, \t Temperature : %.2f \n"%(dht.humidity,dht.temperature)
25 time.sleep(1)
26
27 if __name__ == '__main__':
28 print 'Program is starting ... '
29 try:
30 loop()
204 Capítulo 21 Hygrothermograph DHT11 www.freenove.com █

31 except KeyboardInterrupt:
32 GPIO.cleanup()
33 exit()
En este código experimental, usamos un módulo "Freenove_DHT.py", que proporciona el método de lectura del
sensor DHT. Se encuentra en el mismo directorio con los archivos de programa "DHT11.py". Al usar esta
biblioteca, podemos leer fácilmente el sensor DHT. Primero crea un objeto de clase DHT en el código.
dht = DHT.DHT(DHTPin) #create a DHT class object
Y luego, en el ciclo "while", use chk = dht.readDHT11 (DHT11Pin) para leer el DHT11 y determine si la lectura de
datos es normal de acuerdo con el valor de retorno "chk". Y luego use la variable sumCnt para registrar la
cantidad de horas de lectura.
while(True):
sumCnt += 1 #counting number of reading times
chk = dht.readDHT11(DHTPin) #read DHT11 and get a return value. Then
determine whether data read is normal according to the return value.
print"The sumCnt is : %d, \t chk : %d"%(sumCnt,chk)
if (chk is dht.DHTLIB_OK): #read DHT11 and get a return value. Then
determine whether data read is normal according to the return value.
print"DHT11,OK!"
elif(chk is dht.DHTLIB_ERROR_CHECKSUM): #data check has errors
print"DHTLIB_ERROR_CHECKSUM!!"
elif(chk is dht.DHTLIB_ERROR_TIMEOUT): #reading DHT times out
print"DHTLIB_ERROR_TIMEOUT!"

else: #other errors


print"Other error!"

Finalmente imprima los resultados:


print"Humidity : %.2f, \t Temperature : %.2f \n"%(dht.humidity,dht.temperature)
El módulo "Freenove_DHT.py" contiene una clase DHT. Y las funciones de clase def readDHT11 (pin) se usa para
leer el sensor DHT11 y almacenar los datos de temperatura y humedad leídos a las variables de humedad y
temperatura.
Freenove_DHT Module
Este es un módulo de Python para leer los datos de temperatura y humedad del sensor DHT. Las
funciones y variables parciales se describen de la siguiente manera:
Variable humidity: almacenar los datos de humedad leídos del sensor
Variable temperature:almacenar datos de temperatura leídos del sensor
def readDHT11 (pin):lee la temperatura y la humedad del sensor DHT11, y los valores de retorno
utilizados para determinar si los datos son normales.
█ www.freenove.com Capítulo 22 Teclado Matriz 205

Capítulo 22 Matrix Keypad(Teclado Matriz)


Hemos aprendido el uso de un solo botón antes. En este capítulo, aprenderemos un dispositivo que integra una
cantidad de teclas, teclado de matriz.

Proyecto 22.1 Matrix Keypad(Teclado Matriz)

En este experimento, intentaremos obtener cada código de tecla en el teclado.

Lista de componentes

Raspberry Pi 3B x1 4x4 Matrix Keypad x1


GPIO Expansion Board & Wire x1
BreadBoard x1

Jumper M/M x8
206 Capítulo 22 Teclado Matriz www.freenove.com █

Conocimiento del componente

4x4 Matrix Keypad


El teclado es un dispositivo que integra varias teclas. Como se muestra abajo, un teclado 4x4 integra 16 teclas:

Al igual que la integración de la matriz LED, en el teclado 4x4 cada fila de teclas está conectada con un pin y es
igual a cada columna. Dicha conexión puede reducir la ocupación del puerto del procesador. El circuito interno se
muestra a continuación.

El método de uso es similar al LED de matriz, es decir, utiliza un escaneo de fila o un método de escaneo de
columna para detectar el estado de la clave en cada columna o fila. Tome el método de escaneo en columna
como ejemplo, envíe un nivel bajo a la primera columna 1 (Pin 1), detecte el estado del nivel de la fila 5, 6, 7, 8
para juzgar si se presionan las teclas A, B, C, D. Y luego envíe un nivel bajo a la columna 2, 3, 4 para detectar si se
presionan otras teclas. Entonces, puedes obtener el estado de todas las teclas.
█ www.freenove.com Capítulo 22 Teclado Matriz 207

Circuito

Schematic diagram
208 Capítulo 22 Teclado Matriz www.freenove.com █

Hardware connection
█ www.freenove.com Capítulo 22 Teclado Matriz 209

Código

Este código se usa para obtener todo el código de tecla del teclado de 4x4 Matriz, cuando se presiona una de las
teclas, el código de tecla se imprimirá en la ventana de la terminal.
C Code 22.1.1 MatrixKeypad
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar el directorio 22.1.1_MatrixKeypad del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/22.1.1_MatrixKeypad
2. El código de este experimento contiene un archivo de encabezado personalizado. Utilice el siguiente
comando para compilar el código MatrixKeypad.cpp, Keypad.cpp y Key.cpp y generar el archivo ejecutable
MatrixKeypad. Y el archivo de encabezado personalizado se compilará al mismo tiempo.
gcc MatrixKeypad.cpp Keypad.cpp Key.cpp –o MatrixKeypad –lwiringPi
3. Ejecute el archivo generado"MatrixKeypad".
sudo ./MatrixKeypad
Después de ejecutar el programa, presione cualquier tecla en MatrixKeypad, el terminal imprimirá el código de
tecla correspondiente. Como se muestra a continuación:

El siguiente es el código del programa:


1 #include "Keypad.hpp"
2 #include <stdio.h>
3 const byte ROWS = 4; //four rows
4 const byte COLS = 4; //four columns
5 char keys[ROWS][COLS] = { //key code
6 {'1','2','3','A'},
7 {'4','5','6','B'},
8 {'7','8','9','C'},
9 {'*','0','#','D'}
10 };
11 byte rowPins[ROWS] = {1, 4, 5, 6 }; //connect to the row pinouts of the keypad
12 byte colPins[COLS] = {12,3, 2, 0 }; //connect to the column pinouts of the keypad
13 //create Keypad object
210 Capítulo 22 Teclado Matriz www.freenove.com █

14 Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );


15
16 int main(){
17 printf("Program is starting ... \n");
18 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
19 printf("setup wiringPi failed !");
20 return 1;
21 }
22 char key = 0;
23 keypad.setDebounceTime(50);
24 while(1){
25 key = keypad.getKey(); //get the state of keys
26 if (key){ //if a key is pressed, print out its key code
27 printf("You Pressed key : %c \n",key);
28 }
29 }
30 return 1;
31 }
En este código experimental, utilizamos dos archivos de biblioteca personalizados "Keypad.hpp" and "Key.hpp".
Están ubicados en el mismo directorio con archivos de programa "MatrixKeypad.cpp", "Keypad.cpp" and
"Key.cpp".El teclado de la biblioteca se trasplanta desde el teclado de la biblioteca Arduino. Y este archivo de biblioteca
proporciona un método para leer el teclado. Al usar esta biblioteca, podemos leer fácilmente el teclado de la matriz.
Primero, defina la información del teclado de matriz utilizado en este experimento: el número de filas y columnas, el
código de cada clave y el pin GPIO conectado a cada columna y cada fila. Es necesario incluir el archivo de encabezado
"Keypad.hpp".

#include "Keypad.hpp"
#include <stdio.h>
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = { //key code
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {1, 4, 5, 6 }; //connect to the row pinouts of the keypad
byte colPins[COLS] = {12,3, 2, 0 }; //connect to the column pinouts of the keypad
Y luego, en base a la información anterior, cree una instancia de un objeto de clase del Teclado para operar el teclado de
la matriz.
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
Establezca el tiempo de eliminación de rebote en 50 ms, y este valor se puede establecer en función del uso real
del teclado de manera flexible, con un tiempo predeterminado de 10 ms.
keypad.setDebounceTime(50);
En el ciclo "while", use la tecla de función = teclado.getKey () para leer el teclado constantemente. Si hay una tecla
presionada, su código de tecla se almacenará en la variable "clave", luego se imprimirá.
█ www.freenove.com Capítulo 22 Teclado Matriz 211

while(1){
key = keypad.getKey(); //get the state of keys
if (key){ // if a key is pressed, print out its key code
printf("You Pressed key : %c \n",key);
}
}

El teclado de la biblioteca utilizado para RPi se trasplanta desde el teclado de la biblioteca Arduino. Y los archivos
fuente se pueden obtener visitando http://playground.arduino.cc/Code/Keypad. En cuanto a la biblioteca de
funciones trasplantadas, la función y el método de todas las clases, funciones, variables, etc. son los mismos que
los de la biblioteca original. Los contenidos parciales de la biblioteca del teclado se describen a continuación:
class Keypad
Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols);
Constructor, los parámetros son: código de tecla del teclado, pin de fila, pin de columna, el número de filas, el
número de columnas.
char getKey();
Obtenga el código de tecla de la tecla presionada. Si no se presiona ninguna tecla, el valor de retorno es NULL.
void setDebounceTime(uint);
Establezca el tiempo de eliminación del rebote. Y el tiempo predeterminado es 10 ms.
void setHoldTime(uint);
Establezca el tiempo cuando la tecla se mantiene estable después de presionar.
bool isPressed(char keyChar);
Juzgue si se presiona la tecla con el código "keyChar".
char waitForKey();
Espere a que se presione una tecla, y regrese el código de tecla de la tecla presionada.
KeyState getState();
Obtener estado de las teclas.
bool keyStateChanged();
Juzgue si hay un cambio de estado clave, luego devuelva True o False.
Para obtener más información sobre el teclado, visite: http://playground.arduino.cc/Code/Keypad o a través
del archivo de apertura "Keypad.hpp".
212 Capítulo 22 Teclado Matriz www.freenove.com █

Pyhton Code 22.1.1 MatrixKeypad


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar el directorio 22.1.1_MatrixKeypad del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/22.1.1_MatrixKeypad
2. Use el comando python para ejecutar el código "MatrixKeypad.py".
python MatrixKeypad.py
Después de ejecutar el programa, presione cualquier tecla en MatrixKeypad, el terminal imprimirá el código de
tecla correspondiente. Como se muestra a continuación:

El siguiente es el código del programa:


1 import Keypad #import module Keypad
2 ROWS = 4 # number of rows of the Keypad
3 COLS = 4 #number of columns of the Keypad
4 keys = [ '1','2','3','A', #key code
5 '4','5','6','B',
6 '7','8','9','C',
7 '*','0','#','D' ]
8 rowsPins = [12,16,18,22] #connect to the row pinouts of the keypad
9 colsPins = [19,15,13,11] #connect to the column pinouts of the keypad
10
11 def loop():
12 keypad = Keypad.Keypad(keys,rowsPins,colsPins,ROWS,COLS) #creat Keypad object
13 keypad.setDebounceTime(50) #set the debounce time
14 while(True):
15 key = keypad.getKey() #obtain the state of keys
16 if(key != keypad.NULL): #if there is key pressed, print its key code.
17 print "You Pressed Key : %c "%(key)
18
19 if __name__ == '__main__': #Program start from here
20 print "Program is starting ... "
21 try:
22 loop()
█ www.freenove.com Capítulo 22 Teclado Matriz 213

23 except KeyboardInterrupt: #When 'Ctrl+C' is pressed, exit the program.


24 GPIO.cleanup()

En este código experimental, usamos dos módulos personalizados"Keypad.py", que se encuentra en el mismo directorio con el
archivo de programa "MatrixKeypad.py".Y este archivo de biblioteca, que se trasplanta desde el teclado de la biblioteca de
funciones Arduino, proporciona un método para leer el teclado. Al usar esta biblioteca, podemos leer fácilmente el teclado de la
matriz. Primero, importar el módulo Teclado. A continuación, defina la información del teclado de matriz utilizado en este
experimento: el número de filas y columnas, el código de cada clave y el pin GPIO conectado a cada columna y cada fila.

import Keypad #import module Keypad


ROWS = 4 #number of rows of the Keypad
COLS = 4 #number of columns of the Keypad
keys = [ '1','2','3','A', #key code
'4','5','6','B',
'7','8','9','C',
'*','0','#','D' ]
rowsPins = [12,16,18,22] #connect to the row pinouts of the keypad
colsPins = [19,15,13,11] #connect to the column pinouts of the keypad
Y luego, en base a la información anterior, cree una instancia de un objeto de clase del Teclado para operar el teclado de la matriz.
keypad = Keypad.Keypad(keys,rowsPins,colsPins,ROWS,COLS)
Establezca el tiempo de eliminación de rebote en 50 ms, y este valor se puede establecer en función del uso real
del teclado de manera flexible, con un tiempo predeterminado de 10 ms.
keypad.setDebounceTime(50)
En el ciclo "while", use la función key= keypad.getKey () para leer el teclado constantemente. Si se pulsa una
tecla, su código de tecla se almacenará en la variable "clave", y luego se imprimirá.
while(True):
key = keypad.getKey() #get the state of keys
if(key != keypad.NULL): # if a key is pressed, print out its key code
print "You Pressed Key : %c "%(key)
214 Capítulo 22 Teclado Matriz www.freenove.com █

El teclado de la biblioteca utilizado para RPi se trasplanta desde el teclado de la biblioteca Arduino. Los archivos fuente
están escritos por lenguaje C ++ y traducidos a Python pueden ser obtenidos visitando http://playground.arduino.cc/
Code/Keypad. En cuanto a la biblioteca de funciones trasplantadas, la función y el método de todas las clases,
funciones, variables, etc. son los mismos que los de la biblioteca original. Los contenidos parciales de la biblioteca del
teclado se describen a continuación:
class Keypad
def __init__(self,usrKeyMap,row_Pins,col_Pins,num_Rows,num_Cols):
Función construida, los parámetros son: código de tecla del teclado, pin de fila, pin de columna, el número de
filas, el número de columnas.
def getKey(self):
Obtener una tecla presionada Si no se presiona ninguna tecla, el valor de retorno es el teclado NULL.
def setDebounceTime(self,ms):
Establezca el tiempo de eliminación del rebote. Y el tiempo predeterminado es 10 ms.
def setHoldTime(self,ms):
Establezca el tiempo cuando la tecla se mantiene estable después de presionar.
def isPressed(keyChar):
Juzgue si se presiona la tecla con el código "keyChar".
def waitForKey():
Espere a que se presione una tecla, y regrese el código de tecla de la tecla presionada.
def getState():
Obtener estado de las teclas.
def keyStateChanged():
Juzgue si hay un cambio de estado clave, luego devuelva True o False.
Para obtener más información sobre el teclado, visite: http://playground.arduino.cc/Code/Keypad o a través
del archivo de apertura "Keypad.py".
█ www.freenove.com Capítulo 23 Sensor de movimiento infrarrojo 215

Capítulo 23 Sensor de movimiento infrarrojo


En este capítulo, aprenderemos un sensor ampliamente utilizado, el Sensor de movimiento infrarrojo.

Proyecto 23.1 Sense LED

En este proyecto, crearemos un LED de sentido con los sensores piroeléctricos infrarrojos del cuerpo humano.
Cuando alguien se acerca al LED, se enciende automáticamente. Por el contrario, saldrá.
Este sensor de movimiento infrarrojo es un tipo de sensor que puede detectar el infrarrojo emitido por humanos
y animales.

Lista de componentes

Raspberry Pi 3B x1 Jumper M/M x2 M/F x3


GPIO Expansion Board & Wire x1
BreadBoard x1
HC SR501 x1 LED x1 Resistor 220Ω x1
216 Capítulo 23 Sensor de movimiento infrarrojo www.freenove.com █

Conocimiento del componente

El siguiente es el diagrama del sensor de movimiento infrarrojo(HC SR-501):


Parte superior Fondo Esquemático

Descripción:
1. Voltaje de funcionamiento: 5v-20v (DC) Corriente estática: 65uA.
2. Disparador automático Cuando el cuerpo ingrese al área activa del sensor, el módulo emitirá un nivel alto
(3.3V). Cuando el cuerpo deja de funcionar, emitirá un nivel alto que durará por el tiempo T, luego emitirá un
nivel bajo (0V). El tiempo de retardo T se puede ajustar con el potenciómetro R1.
3. Según la posición de la tapa del puente, puede elegir el modo de disparo no repetible o el modo repetible.
L: modo de disparo no repetible. El módulo de salida de alto nivel después del cuerpo de detección, luego
cuando el tiempo de demoraha terminado, el módulo emitirá bajo nivel. Y durante el tiempo de alto nivel, el
sensor ya no detecta el cuerpo.
H: modo de disparo repetible. La distinción de L es que puede detectar el cuerpo hasta que el cuerpo se va
durante el período de salida de alto nivel. Y luego comienza a tiempo y produce un nivel bajo después de
retrasar la hora T.
4. Tiempo de bloqueo de inducción: la inducción permanecerá en estado bloqueado y no inducirá la señal
externa en un momento (menos que el tiempo de retardo) después de emitir un nivel alto o bajo
5. Tiempo de inicialización: el módulo necesita aproximadamente 1 minuto para inicializarse después de
encenderse. Durante este período, generará un nivel alto o bajo alternativamente.
6. En consideración de la característica de este sensor, cuando el cuerpo se acerca o se aleja del lado de
edgewise, el sensor funcionará con alta sensibilidad. Cuando el cuerpo se acerca o se aleja en dirección
vertical, el sensor no puede funcionar bien, lo que debería llamar su atención. La distancia de detección se
ajusta mediante un potenciómetro.

Podemos considerar este sensor como un simple interruptor inductivo cuando está en uso.
█ www.freenove.com Capítulo 23 Sensor de movimiento infrarrojo 217

Circuito

Schematic diagram

Hardware connection
218 Capítulo 23 Sensor de movimiento infrarrojo www.freenove.com █

Código

En este experimento, usamos un sensor de movimiento infrarrojo para controlar el LED, y tomamos el sensor de movimiento
infrarrojo como un interruptor, por lo que el código es muy similar al experimento frontal "Botón y LED" en lógica. La diferencia es
que, cuando el sensor de movimiento infrarrojo detecta cambios, dará un alto nivel de salida; cuando se presiona el botón, emitirá
un nivel bajo. Cuando el nivel de salida del sensor sea alto, el LED se encenderá o se apagará.
C Code 23.1.1 SenseLED
Primero observe el fenómeno experimental y luego analice el código.

1. Use el comando cd para ingresar al directorio 23.1.1_SenseLED del código C.


cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/23.1.1_SenseLED
2. Utilice el siguiente comando para compilar "SenseLED.c" y generar el archivo ejecutable "SenseLED".
gcc SenseLED.c –o SenseLED –lwiringPi
3. Ejecute el archivo generado "SenseLED".
sudo ./SenseLED
Una vez que se haya ejecutado el programa, intente alejarse o cerrarse del infrarrojo del sensor de movimiento y
observar si el LED se encenderá o apagará. La ventana de terminal imprimirá el estado del LED constantemente.
Como se muestra a continuación:

El siguiente es el código del programa:


1 #include <wiringPi.h>
2 #include <stdio.h>
3
4 #define ledPin 1 //define the ledPin
5 #define sensorPin 0 //define the sensorPin
6
7 int main(void)
8 {
9 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
10 printf("setup wiringPi failed !");
11 return 1;
12 }
13
14 pinMode(ledPin, OUTPUT);
15 pinMode(sensorPin, INPUT);
16
17 while(1){
18
19 if(digitalRead(sensorPin) == HIGH){
█ www.freenove.com Capítulo 23 Sensor de movimiento infrarrojo 219

20 digitalWrite(ledPin, HIGH); //led on


21 printf("led on...\n");
22 }
23 else {
24 digitalWrite(ledPin, LOW); //led off
25 printf("...led off\n");
26 }
27 }
28
29 return 0;
30 }
Primero observe el fenómeno experimental y luego analice el código.

Python Code 23.1.1 SenseLED


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar el directorio 22.1.1_MatrixKeypad del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/23.1.1_SenseLED
2. Use el comando python para ejecutar el código"SenseLED.py".
python SenseLED.py
Una vez que se haya ejecutado el programa, intente alejarse o cerrarse del infrarrojo del sensor de movimiento y
observar si el LED se encenderá o apagará. La ventana de terminal imprimirá el estado del LED constantemente.
Como se muestra a continuación:

El siguiente es el código del programa:


1 import RPi.GPIO as GPIO
2
3 ledPin = 12 # define the ledPin
4 sensorPin = 11 # define the sensorPin
5
6 def setup():
7 print 'Program is starting...'
8 GPIO.setmode(GPIO.BOARD) # Numbers GPIOs by physical location
9 GPIO.setup(ledPin, GPIO.OUT) # Set ledPin's mode is output
10 GPIO.setup(sensorPin, GPIO.IN) # Set sensorPin's mode is input
11 def loop():
12 while True:
13 if GPIO.input(sensorPin)==GPIO.HIGH:
14 GPIO.output(ledPin,GPIO.HIGH)
220 Capítulo 23 Sensor de movimiento infrarrojo www.freenove.com █

15 print 'led on ...'


16 else :
17 GPIO.output(ledPin,GPIO.LOW)
18 print 'led off ...'
19
20 def destroy():
21 GPIO.cleanup() # Release resource
22
23 if __name__ == '__main__': # Program start from here
24 setup()
25 try:
26 loop()
27 except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy()
28 will be executed.
29 destroy()
Se puede ver que el código se basa en la misma lógica con el código "ButtonLED" además de determinar el nivel
de la señal de entrada.
█ www.freenove.com Capítulo 24 Rango ultrasónico 221

Capítulo 24 Rango ultrasónico


En este capítulo, aprendemos un módulo que usa ultrasonidos para medir la distancia, HC SR04.

Proyecto 24.1 Rango ultrasónico

En este proyecto, utilizamos el módulo de medición ultrasónica para medir la distancia e imprimir los datos en la terminal.

Lista de componentes

Raspberry Pi 3B x1 HC SR501 x1
GPIO Expansion Board & Wire x1
BreadBoard x1
Jumper M/F x4
222 Capítulo 24 Rango ultrasónico www.freenove.com █

Conocimiento de componentes

El módulo de rango ultrasónico utiliza el principio de que el ultrasonido se reflejará cuando encuentre obstáculos.
Comience a contar el tiempo en que se transmite el ultrasonido. Y cuando el ultrasonido encuentra un obstáculo,
se reflejará de nuevo. El conteo terminará después de que se reciba el ultrasonido, y la diferencia de tiempo es el
tiempo total de transmisión de ultrasonido para recibir. Porque la velocidad del sonido en el aire es constante, y
es aproximadamente v = 340 m / s. Entonces podemos calcular la distancia entre el modle y el obstáculo: s = vt /
2.

2S=V·t.
El módulo ultrasónico integra un transmisor y un receptor. El transmisor se usa para convertir señales eléctricas
(energía eléctrica) en ondas de sonido (energía mecánica) y la función del receptor es opuesta. La imagen del
objeto y el diagrama del módulo ultrasónico HC SR04 se muestran a continuación:

Pin descripción:
VCC power supply pin
Trig triger pin
Echo Echo pin
GND GND
Especificaciones técnicas:
Voltaje de funcionamiento: 5V
Corriente de trabajo: 12mA
Distancia mínima medida: 2 cm
Distancia máxima medida: 200cm
Tamaño: 45 mm * 20 mm * 15 mm
Instrucciones de uso: generar un pulso de alto nivel en el pin Trig de al menos 10uS. Entonces el módulo
comienza a transmitir ultrasonido. Al mismo tiempo, el pin Echo se levantará. Cuando el módulo recibe el
ultrasonido devuelto, el pasador de eco se bajará. La duración del nivel alto en el pin Echo es el tiempo total que
el ultrasonido transmite a la recepción, s = vt / 2.
█ www.freenove.com Capítulo 24 Rango ultrasónico 223

Circuit

Tenga en cuenta que el voltaje del módulo ultrasónico es de 5 V en el circuito.


Schematic diagram

Hardware connection
224 Capítulo 24 Rango ultrasónico www.freenove.com █

Código

C Code 24.1.1 UltrasonicRanging


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 24.1.1_UltrasonicRanging del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/24.1.1_UltrasonicRanging
2. Utilice el siguiente comando para compilar "UltrasonicRanging.c" y generar archivo ejecutable
"UltrasonicRanging".
gcc UltrasonicRanging.c –o UltrasonicRanging –lwiringPi
3. Luego ejecuta el archivo generado "UltrasonicRanging".
sudo ./UltrasonicRanging
Después de ejecutar el programa, haga que el detector del módulo de medición ultrasónica apunte al plano de
un objeto, luego la distancia entre el módulo ultrasónico y el objeto se mostrará en el terminal. Como se muestra
a continuación:

The following is the program code:


1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <sys/time.h>
4
5 #define trigPin 4
6 #define echoPin 5
7 #define MAX_DISTANCE 220 // define the maximum measured distance
8 #define timeOut MAX_DISTANCE*60 // calculate timeout according to the maximum measured
9 distance
10 //function pulseIn: obtain pulse time of a pin
11 int pulseIn(int pin, int level, int timeout);
12 float getSonar(){ // get the measurement results of ultrasonic module,with unit: cm
13 long pingTime;
14 float distance;
15 digitalWrite(trigPin,HIGH); //trigPin send 10us high level
16 delayMicroseconds(10);
17 digitalWrite(trigPin,LOW);
18 pingTime = pulseIn(echoPin,HIGH,timeOut); //read plus time of echoPin
19 distance = (float)pingTime * 340.0 / 2.0 / 10000.0; // the sound speed is 340m/s,and
20 calculate distance
21 return distance;
22 }
█ www.freenove.com Capítulo 24 Rango ultrasónico 225

23
24 int main(){
25 printf("Program is starting ... \n");
26 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
27 printf("setup wiringPi failed !");
28 return 1;
29 }
30 float distance = 0;
31 pinMode(trigPin,OUTPUT);
32 pinMode(echoPin,INPUT);
33 while(1){
34 distance = getSonar();
35 printf("The distance is : %.2f cm\n",distance);
36 delay(1000);
37 }
38 return 1;
39 }

Primero, defina los pines y la distancia máxima de medición.


#define trigPin 4
#define echoPin 5
#define MAX_DISTANCE 220 //define the maximum measured distance

Si el módulo no devuelve un nivel alto, no podemos esperar para siempre. Entonces, debemos calcular el tiempo
duradero sobre la distancia máxima, es decir, el tiempo de inactividad. timOut=
2*MAX_DISTANCE/100/340*1000000. La parte constante detrás es aproximadamente igual a 58.8.
#define timeOut MAX_DISTANCE*60

Subfunción getSonar () función se utiliza para iniciar el módulo ultrasónico para una medición, y devolver la
distancia medida con la unidad cm. En esta función, primero deje que trigPin envíe 10us de alto nivel para iniciar
el módulo ultrasónico. Entonces usa pulseIn () para leer el módulo ultrasónico y devolver la duración del alto
nivel. Finalmente calcule la distancia medida según el tiempo.
float getSonar(){ // get the measurement results of ultrasonic module,with unit: cm
long pingTime;
float distance;
digitalWrite(trigPin,HIGH); //trigPin send 10us high level
delayMicroseconds(10);
digitalWrite(trigPin,LOW);
pingTime = pulseIn(echoPin,HIGH,timeOut); //read plus time of echoPin
distance = (float)pingTime * 340.0 / 2.0 / 10000.0; // the sound speed is 340m/s,and
calculate distance
return distance;
}
226 Capítulo 24 Rango ultrasónico www.freenove.com █

Finalmente, en el ciclo while de la función principal, obtenga la distancia de medición e imprima constantemente.
while(1){
distance = getSonar();
printf("The distance is : %.2f cm\n",distance);
delay(1000);
}
Acerca de la función pulseIn():
int pulseIn(int pin, int level, int timeout);
Regrese la duración del pulso (en microsegundos) o 0 si no se completa el pulso antes del tiempo de espera
(largo sin signo).

Python Code 24.1.1 UltrasonicRanging


Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 24.1.1_UltrasonicRanging del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/24.1.1_UltrasonicRanging
2. Use el comando python para ejecutar el código "UltrasonicRanging.py".
python UltrasonicRanging.py
Después de ejecutar el programa, haga que el detector del módulo de medición ultrasónica apunte al plano de
un objeto, luego la distancia entre el módulo ultrasónico y el objeto se mostrará en el terminal. Como se muestra
a continuación:

El siguiente es el código del programa:


1 import RPi.GPIO as GPIO
2 import time
3
4 trigPin = 16
5 echoPin = 18
6 MAX_DISTANCE = 220 #define the maximum measured distance
7 timeOut = MAX_DISTANCE*60 #calculate timeout according to the maximum measured distance
8 def pulseIn(pin,level,timeOut): # function pulseIn: obtain pulse time of a pin
9 t0 = time.time()
10 while(GPIO.input(pin) != level):
11 if((time.time() - t0) > timeOut*0.000001):
12 return 0;
13 t0 = time.time()
14 while(GPIO.input(pin) == level):
15 if((time.time() - t0) > timeOut*0.000001):
16 return 0;
17 pulseTime = (time.time() - t0)*1000000
█ www.freenove.com Capítulo 24 Rango ultrasónico 227

18 return pulseTime
19
20 def getSonar(): #get the measurement results of ultrasonic module,with unit: cm
21 GPIO.output(trigPin,GPIO.HIGH) #make trigPin send 10us high level
22 time.sleep(0.00001) #10us
23 GPIO.output(trigPin,GPIO.LOW)
24 pingTime = pulseIn(echoPin,GPIO.HIGH,timeOut) #read plus time of echoPin
25 distance = pingTime * 340.0 / 2.0 / 10000.0 # the sound speed is 340m/s, and
26 calculate distance
27 return distance
28
29 def setup():
30 print 'Program is starting...'
31 GPIO.setmode(GPIO.BOARD) #numbers GPIOs by physical location
32 GPIO.setup(trigPin, GPIO.OUT) #
33 GPIO.setup(echoPin, GPIO.IN) #
34
35 def loop():
36 GPIO.setup(11,GPIO.IN)
37 while(True):
38 distance = getSonar()
39 print "The distance is : %.2f cm"%(distance)
40 time.sleep(1)
41
42 if __name__ == '__main__': #program start from here
43 setup()
44 try:
45 loop()
46 except KeyboardInterrupt: #when 'Ctrl+C' is pressed, the program will exit
47 GPIO.cleanup() #release resource

Primero, defina los pines y la distancia máxima de medición.


trigPin = 16
echoPin = 18
MAX_DISTANCE = 220 # define the maximum measured distance

Si el módulo no devuelve un nivel alto, no podemos esperar para siempre. Entonces, debemos calcular el tiempo
duradero sobre la distancia máxima, es decir, el tiempo de inactividad. timOut=
2*MAX_DISTANCE/100/340*1000000. La parte constante detrás es aproximadamente igual a 58.8.
timeOut = MAX_DISTANCE*60

Subfuncción getSonar () función se utiliza para iniciar el módulo ultrasónico para una medición, y devolver la
distancia medida con la unidad cm. En esta función, primero deje que trigPin envíe 10us de alto nivel para iniciar
el módulo ultrasónico. Entonces usa pulseIn () para leer el módulo ultrasónico y devolver la duración del alto
nivel. Finalmente calcule
228 Capítulo 24 Rango ultrasónico www.freenove.com █

la distancia medida según el tiempo.


def getSonar(): #get the measurement results of ultrasonic module,with unit: cm
GPIO.output(trigPin,GPIO.HIGH) #make trigPin send 10us high level
time.sleep(0.00001) #10us
GPIO.output(trigPin,GPIO.LOW)
pingTime = pulseIn(echoPin,GPIO.HIGH,timeOut) #read plus time of echoPin
distance = pingTime * 340.0 / 2.0 / 10000.0 # the sound speed is 340m/s, and
calculate distance
return distance

Finalmente, en el ciclo while de la función principal, obtenga la distancia de medición e imprima constantemente.
while(True):
distance = getSonar()
print "The distance is : %.2f cm"%(distance)
time.sleep(1)

Acerca de la función def pulseIn(pin,level,timeOut):


def pulseIn(pin,level,timeOut):
Regrese la duración del pulso (en microsegundos) o 0 si no se completa el pulso antes del tiempo de espera
(largo sin signo).
█ www.freenove.com Capítulo 25 Sensor de posicion MPU6050 229

Capítulo 25 Sensor de attitude(Posición,localización)


MPU6050
En este capítulo, aprenderemos un sensor de actitud que integra acelerómetro y giroscopio, MPU6050.

Proyecto 25.1 Leer MPU6050

Vamos a leer datos de aceleración y datos de giroscopio de MPU6050 en este experimento.

Lista de componentes

Raspberry Pi 3B x1 HC SR501 x1
GPIO Expansion Board & Wire x1
BreadBoard x1
Jumper M/M x4
230 Capítulo 25 Sensor de posición MPU6050 www.freenove.com █

Conocimiento del componente

MPU6050
MPU6050 es un sensor que integra acelerómetro de 3 ejes, acelerómetro angular de 3 ejes (llamado giroscopio) y
1 procesador de actitud o posicion digital (DMP). El rango de acelerómetro y giroscopio de MPU6050 se puede
cambiar. Un sensor de temperatura digital con un amplio rango y alta precisión se integra para compensación de
temperatura, y el valor de temperatura también se puede leer. El módulo MPU6050 sigue el protocolo de
comunicación I2C y la dirección predeterminada es 0x68.

La descripción del puerto del módulo MPU6050 es la siguiente:


Pin name Pin number Description
VCC 1 Polo positivo de la fuente de alimentación con voltaje 5V
GND 2 Polo negativo de la fuente de alimentación
SCL 3 Pin de reloj de comunicación I2C
SDA 4 Pin de datos de comunicación I2C
XDA 5 Pin de datos de host I2C que se puede conectar a otros dispositivos.
XCL 6 Pin de reloj host I2C que se puede conectar a otros dispositivos.
AD0 7 Pin de control de bit de dirección I2C.
Nivel bajo: la dirección del dispositivo es 0x68
Nivel alto: la dirección del dispositivo es 0x69
INT 8 Pin de interrupción de salida
Para obtener más detalles, consulte la hoja de datos.

MPU6050 es ampliamente utilizado en el campo del equilibrio de vehículos, aviones y otros que necesitan
controlar la posición.
█ www.freenove.com Capítulo 25 Sensor de posición MPU6050 231

Circuito

Tenga en cuenta que el voltaje de la fuente de alimentación para el módulo MPU6050 es de 5 V en el circuito.
Schematic diagram

Hardware connection
232 Capítulo 25 Sensor de posición MPU6050 www.freenove.com █

Código

En este experimento, leeremos los datos de aceleración y los datos del giroscopio de MPU6050, y los imprimiremos.
C Code 25.1.1 MPU6050RAW
Primero observe el fenómeno experimental y luego analice el código.
1. Use el comando cd para ingresar al directorio 25.1.1_MPU6050RAW del código C.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/C_Code/24.1.1_MPU6050RAW
2. Utilice el siguiente comando para compilar "MPU6050RAW.c", "MPU6050.cpp" e "I2Cdev.cpp" y genere un
archivo ejecutable "MPU6050RAW".
gcc MPU6050RAW.cpp MPU6050.cpp I2Cdev.cpp –o MPU6050RAW
3. Luego ejecuta el archivo generado "MPU6050RAW".
sudo ./MPU6050RAW
Una vez que se haya ejecutado el programa, el terminal mostrará los datos originales de aceleración y giroscopio
de MPU6050, así como la conversión a aceleración por gravedad y velocidad angular como la unidad de datos.
Como se muestra en la siguiente figura:

El siguiente es el código del programa:


1 #include <stdio.h>
2 #include <stdint.h>
3 #include <unistd.h>
4 #include "I2Cdev.h"
5 #include "MPU6050.h"
6
7 MPU6050 accelgyro; //instantiate a MPU6050 class object
8
9 int16_t ax, ay, az; //store acceleration data
10 int16_t gx, gy, gz; //store gyroscope data
11
12 void setup() {
13 // initialize device
14 printf("Initializing I2C devices...\n");
15 accelgyro.initialize(); //initialize MPU6050
16
17 // verify connection
18 printf("Testing device connections...\n");
█ www.freenove.com Capítulo 25 Sensor de posición MPU6050 233

19 printf(accelgyro.testConnection() ? "MPU6050 connection successful\n" : "MPU6050


20 connection failed\n");
21 }
22
23 void loop() {
24 // read raw accel/gyro measurements from device
25 accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
26 // display accel/gyro x/y/z values
27 printf("a/g: %6hd %6hd %6hd %6hd %6hd %6hd\n",ax,ay,az,gx,gy,gz);
28 printf("a/g: %.2f g %.2f g %.2f g %.2f d/s %.2f d/s %.2f d/s
29 \n",(float)ax/16384,(float)ay/16384,(float)az/16384,
30 (float)gx/131,(float)gy/131,(float)gz/131);
31 }
32
33 int main()
34 {
35 setup();
36 while(1){
37 loop();
38 }
39 return 0;
40 }
Dos archivos de biblioteca"MPU6050.h" y "I2Cdev.h" se usan en el código. Se compilarán como otros. La clase
MPU6050 se usa para operar el MPU6050. Cuando se usa, primero crea una instancia de un objeto.
MPU6050 accelgyro;
En la función de configuración, el MPU6050 se inicializa y se juzgará el resultado de la inicialización.
void setup() {
// initialize device
printf("Initializing I2C devices...\n");
accelgyro.initialize(); //initialize MPU6050

// verify connection
printf("Testing device connections...\n");
printf(accelgyro.testConnection() ? "MPU6050 connection successful\n" : "MPU6050
connection failed\n");
}
En la función de bucle, lea los datos originales de MPU6050 e imprímalos, y luego convierta los datos originales
en la aceleración y velocidad angular correspondientes, luego imprima los datos convertidos.
void loop() {
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// display accel/gyro x/y/z values
printf("a/g: %6hd %6hd %6hd %6hd %6hd %6hd\n",ax,ay,az,gx,gy,gz);
234 Capítulo 25 Sensor de actitud MPU6050 www.freenove.com █

printf("a/g: %.2f g %.2f g %.2f g %.2f d/s %.2f d/s %.2f d/s
\n",(float)ax/16384,(float)ay/16384,(float)az/16384,
(float)gx/131,(float)gy/131,(float)gz/131);
}
Finalmente, las funciones principales, la función de configuración de llamada y la función de bucle, respectivamente.
int main()
{
setup();
while(1){
loop();
}
return 0;
}
Acerca de la clase MPU6050:
Class MPU6050
Esta es una biblioteca de clases utilizada para operar MPU6050, que puede leer directamente y configurar
MPU6050. Aquí hay algunas funciones de miembros:
MPU6050()/MPU6050(uint8_t address):
Constructor. El parámetro es la dirección I2C, y la dirección I2C predeterminada es 0x68.
void initialize();
Función de inicialización, utilizada para activar MPU6050. El rango del acelerómetro es ± 2g y el rango del
giroscopio es de ± 250 grados / seg.
void getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz);
Obtenga los datos originales del acelerómetro y el giroscopio.
int16_t getTemperature();
Obtenga los datos de temperatura originales de MPU6050.
Para obtener más información acerca de las funciones de miembro más relevantes, haga clic en MPU6050.ho
visite: https://github.com/jrowberg/i2cdevlib
█ www.freenove.com Capítulo 25 Sensor de posición MPU6050 235

Python Code 25.1.1 MPU6050RAW


Primero observe el fenómeno experimental, y luego analice el código.
1. Use el comando cd para ingresar el directorio 25.1.1_MPU6050RAW del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/25.1.1_MPU6050RAW
2. Use el comando python para ejecutar el código "MPU6050RAW.py".
python MPU6050RAW.py
Una vez que se haya ejecutado el programa, el terminal mostrará los datos originales de aceleración y giroscopio
de MPU6050, así como la conversión a aceleración por gravedad y velocidad angular como la unidad de datos.
Como se muestra en la siguiente figura:

El siguiente es el código del programa:


1 import MPU6050
2 import time
3
4 mpu = MPU6050.MPU6050() #instantiate a MPU6050 class object
5 accel = [0]*3 #store accelerometer data
6 gyro = [0]*3 #store gyroscope data
7 def setup():
8 mpu.dmp_initialize() #initialize MPU6050
9
10 def loop():
11 while(True):
12 accel = mpu.get_acceleration() #get accelerometer data
13 gyro = mpu.get_rotation() #get gyroscope data
14 print"a/g:%d\t%d\t%d\t%d\t%d\t%d
15 "%(accel[0],accel[1],accel[2],gyro[0],gyro[1],gyro[2])
16 print"a/g:%.2f g\t%.2f g\t%.2f g\t%.2f d/s\t%.2f d/s\t%.2f
17 d/s"%(accel[0]/16384.0,accel[1]/16384.0,
18 accel[2]/16384.0,gyro[0]/131.0,gyro[1]/131.0,gyro[2]/131.0)
19 time.sleep(0.1)
20
21 if __name__ == '__main__': # Program start from here
22 print"Program is starting ... "
23 setup()
24 try:
25 loop()
236 Capítulo 25 Sensor de posición MPU6050 www.freenove.com █

26 except KeyboardInterrupt: # When 'Ctrl+C' is pressed,the program will exit.


27 pass
El módulo "MPU6050.py" se usa en el código. El módulo incluye una clase utilizada para operar MPU6050.
Cuando se usa, primero crea una instancia de un objeto.
mpu = MPU6050.MPU6050()
En la función de configuración, el MPU6050 se inicializa.
def setup():
mpu.dmp_initialize()
En la función de bucle, lea los datos originales de MPU6050 e imprímalos, y luego convierta los datos originales
en la aceleración y velocidad angular correspondientes, luego imprima los datos convertidos.
def loop():
while(True):
accel = mpu.get_acceleration() #get accelerometer data
gyro = mpu.get_rotation() #get gyroscope data
print"a/g:%d\t%d\t%d\t%d\t%d\t%d
"%(accel[0],accel[1],accel[2],gyro[0],gyro[1],gyro[2])
print"a/g:%.2f g\t%.2f g\t%.2f g\t%.2f d/s\t%.2f d/s\t%.2f
d/s"%(accel[0]/16384.0,accel[1]/16384.0,
accel[2]/16384.0,gyro[0]/131.0,gyro[1]/131.0,gyro[2]/131.0)
time.sleep(0.1)
Acerca de la clase MPU6050:
Class MPU6050
Esta es una biblioteca de clases utilizada para operar MPU6050, que puede leer directamente y configurar
MPU6050. Aquí hay algunas funciones de miembros:
def __init__(self, a_bus=1, a_address=C.MPU6050_DEFAULT_ADDRESS,
a_xAOff=None, a_yAOff=None, a_zAOff=None, a_xGOff=None,
a_yGOff=None, a_zGOff=None, a_debug=False):
Constructor
def dmp_initialize(self):
Función de inicialización, utilizada para activar MPU6050. El rango del acelerómetro es ± 2g y el rango del
giroscopio es de ± 250 grados / seg. .
def get_acceleration(self): & def get_rotation(self):
Obtenga los datos originales del acelerómetro y el giroscopio.
Para obtener más información sobre funciones de miembros más relevantes, consulte MPU6050.py.
█ www.freenove.com Capítulo 26 WebIOPi y IOT 237

Capítulo 26 WebIOPi y IOT


En este capítulo, aprenderemos cómo usar GPIO para controlar RPi a través de una red remota y cómo crear un
servicio WebIOPi en el RPi.
"IOT" es Internet de las cosas. El desarrollo de IOT cambiará en gran medida nuestros hábitos y hará que
nuestras vidas sean más prácticas y eficientes.
"WebIOPi" es el marco de Raspberry Pi Internet of Things. Después de completar la configuración de WebIOPi en
su RPi, puede usar el navegador web en teléfonos móviles, computadoras y otros equipos para controlar,
depurar y utilizar RPi GPIO cómodamente. También es compatible con muchos protocolos de comunicación de
uso común, como seriales, I2C, SPI, etc., y una gran cantidad de equipos, como el convertidor AD / DA pcf8591
utilizado anteriormente y así sucesivamente. Luego, sobre esta base, al agregar algunos circuitos periféricos,
puede crear su propia casa inteligente.
Para obtener más detalles sobre WebIOPi, consulte: http://webiopi.trouch.com/

Project 26.1 Remote LED

En este experimento, necesitamos construir un servicio WebIOPi, y luego controlar el RPi GPIO para controlar un
LED a través del navegador web del teléfono o la PC.

Lista de componentes

Raspberry Pi 3B x1 LED x1 Resistor 220Ω x1


GPIO Extension Board & Wire x1
BreadBoard x1

Jumper M/M x2
238 Capítulo 26 WebIOPi y IOT www.freenove.com █

Circuito

Schematic diagram

Hardware connection
█ www.freenove.com Capítulo 26 WebIOPi y IOT 239

Build WebIOPi Service Framework(Desarrollar el marco de servicio de


WebIOPi)
La siguiente es la parte clave de este capítulo. Los pasos de instalación se refieren al oficial de WebIOPi. Y también
puede referirse directamente a los pasos de instalación de la instalación oficial. La última versión (hasta
2016-6-27) WebIOPi es 0.7.1. Entonces, si su modelo de RPi es 2B o 3B, es posible que tenga algunos problemas
en el uso. Explicaremos estos problemas y brindaremos la solución en los siguientes pasos de instalación.
Estos son los pasos para construir WebIOPi:
Instalación
1. Visita http://webiopi.trouch.com/DOWNLOADS.html para obtener el último paquete de instalación. Puede
usar el siguiente comando para obtener.
wget http://sourceforge.net/projects/webiopi/files/WebIOPi-0.7.1.tar.gz
2. Extraiga el paquete y genere una carpeta llamada "WebIOPi-0.7.1". Luego ingrese la carpeta.
tar xvzf WebIOPi.tar.gz
cd WebIOPi-0.7.1
3. Ejecute setup.sh para iniciar la instalación y el proceso dentro de un período de espera.
wget https://raw.githubusercontent.com/doublebind/raspi/master/webiopi-pi2bplus.patch
patch -p1 -i webiopi-pi2bplus.patch
4. Ejecute setup.sh para iniciar la instalación y el proceso necesitará un período de espera.
sudo ./setup.sh
Run
Una vez completada la instalación, puede usar el comando webiopi para comenzar a ejecutar.
$ sudo webiopi [-h] [-c config] [-l log] [-s script] [-d] [port]

Options:
-h, --help Display this help
-c, --config file Load config from file
-l, --log file Log to file
-s, --script file Load script from file
-d, --debug Enable DEBUG

Arguments:
port Port to bind the HTTP Server
Por ejemplo, para comenzar con la salida detallada y el archivo de configuración predeterminado:
$ sudo webiopi -d -c /etc/webiopi/config
El puerto es 8000 por defecto.
Hasta ahora, se ha lanzado WebIOPi, y puede presionar "Ctrl + C" para finalizar el servicio.
Access WebIOPi over local network
En la misma red, use el navegador del teléfono móvil o de PC para abrir su dirección IP de RPi y agregue un número
de puerto como 8000. Por ejemplo, mi dirección IP de raspberry pi es 192.168.1.109. Luego, en el navegador, debe
ingresar: http://192.168.1.109:8000/
El usuario predeterminado es "webiopi" y la contraseña es "raspberry".
Luego, ingrese la interfaz de control principal:
240 Capítulo 26 WebIOPi y IOT www.freenove.com █

Haga clic en el encabezado de GPIO para ingresar a la interfaz de control de GPIO.


█ www.freenove.com Capítulo 26 WebIOPi y IOT 241

Métodos de control:
 Click/Tap the OUT/IN para cambiar la dirección GPIO.
 Click/Tap pines para cambiar el estado de salida GPIO.
Completed
De acuerdo con el circuito que construimos, configure GPIO17 en OUT, luego haga clic en
Header11 para controlar el LED.

Acerca de WebIOPi

La razón para cambiar el archivo en el proceso de configuración es que el modelo de la nueva generación de CPU
RPi es diferente del antiguo, lo que da como resultado algunos de los problemas durante el uso.
WebIOPi no ha proporcionado el paquete de instalación correspondiente para RPi 2B y 3B a tiempo. Por lo tanto,
hay dos cambios en la configuración, y es posible que exista algún BUG que cause algunos problemas a la función
WebIOPi. Esperamos que el autor de WebIOPi proporcione un conjunto completo de la última versión del
paquete de instalación para que coincida con RPi. WebIOPi puede lograr mucho más que esto, por lo que
también esperamos aprender y explorar con la diversión.
242 Capítulo 27 Placa de circuito de soldadura www.freenove.com █

Capítulo 27 Placa de circuito de soldadura


De los capítulos anteriores, hemos aprendido el conocimiento de los circuitos electrónicos y componentes, y
construimos una variedad de circuitos. Ahora, vamos a dar un paso más, hacer una pieza de circuito por su
cuenta.
Utilizaremos la placa general para soldar el circuito y los componentes. Y cuando termine este capítulo,
esperamos ayudarlo a dominar la idea de cómo diseñar su propio circuito, construir e imprimir tarjetas de
circuitos.
Para finalizar este capítulo, debe preparar los equipos de soldadura necesarios, incluida la plancha eléctrica y la
soldadura. Hemos preparado la placa general para usted, preste atención a la seguridad cuando realice estos
experimentos.

Project 27.1 Solder a Buzzer

Hemos tratado de usar el zumbador del capítulo anterior, y ahora vamos a soldar un circuito que cuando se
presiona el botón, suena el zumbador
Este circuito no necesita programación y puede funcionar cuando está encendido. Y cuando el botón no está
presionado, no hay consumo de energía.
Puede instalarlo en su bicicleta, en la puerta del dormitorio o en cualquier otro lugar donde sea necesario.

Lista de componentes

Pin header x2 LED x1 Resistor 220Ω x1 Active buzzer x1 Push button x1

AA Battery Holder x1
█ www.freenove.com Capítulo 27 Placa de circuito de soldadura 243

Circuito

Soldaremos el siguiente circuito en la placa general.


Schematic diagram Hardware connection
244 Capítulo 27 Placa de circuito de soldadura www.freenove.com █

Soldar el circuito

Inserte los componentes en la placa general y suelde el circuito en la parte posterior.

Diagrama de efectos después de la soldadura:


Frente Espalda
█ www.freenove.com Capítulo 27 Placa de circuito de soldadura 245

Circuito de prueba

Conecte la placa de circuito a la fuente de alimentación (3 ~ 5V). Puede usar el tablero Raspberry Pi o la caja
de la batería como fuente de alimentación.

Tear the label off

Anode

Cathode

Presione el botón luego de conectar la alimentación, y luego el zumbador emitirá un sonido.


246 Capítulo 27 Placa de circuito de soldadura www.freenove.com █

Proyecto 27.2 Soldar una luz de agua corriente

Del capítulo anterior, hemos aprendido a hacer una luz de agua que fluye con LED. Ahora, soldaremos una placa
de circuito y usaremos el código mejorado para hacer una luz de agua que fluya más interesante.

Lista de componentes

Pin header x5 Resistor 220Ω x8 LED x8 74HC595 x1

Circuit

Suelde el siguiente circuito en la placa general.


Schematic diagram Hardware connection
█ www.freenove.com Capítulo 27 Placa de circuito de soldadura 247

Soldar el circuito

Inserte los componentes en la placa general, y suelde el circuito en la parte posterior.

Diagrama de efectos después de la soldadura:


Front Back
248 Capítulo 27 Placa de circuito de soldadura www.freenove.com █

Conecta el circuito

Conecte la placa a Raspberry Pi con el cable de puente de la siguiente manera.

VCC —3.3V/5V
GND —GND
SH_CP—GPIO22
ST_CP —GPIO27
DS —GPIO.17

Código

Esta es la tercera vez que hacemos la luz del agua que fluye. En este experimento, soldamos un nuevo circuito
completamente nuevo para la luz del agua que fluye. Además, el programa también es diferente de los
anteriores. Cuando esta luz fluye, traerá una larga cola.
C Code 27.2.1 LightWater03
Primero observe el fenómeno experimental y luego analice el código.
4. Use el comando cd para ingresar al directorio 27.2.1_LightWater03 del código C.
cd Freenove_Super_Ultimate_Kit_for_Raspberry_Pi/Code/C_Code/27.2.1_LightWater03
5. Use el siguiente comando para compilar "LightWater03.c" y generar el archivo ejecutable "LightWater03". gcc
LightWater03.c –o LightWater03 –lwiringPi
6. Luego ejecuta el archivo generado“LightWater03”.
sudo ./LightWater03
Después de que se ejecuta el programa, los LED se iluminarán en forma de flujo de agua y transportarán una larga cola.
█ www.freenove.com Capítulo 27 Placa de circuito de soldadura 249

El siguiente es el código del programa:


1 #include <wiringPi.h>
2 #include <stdio.h>
3 #include <wiringShift.h>
4 #include <unistd.h>
5
6 #define dataPin 0 //DS Pin of 74HC595(Pin14)
7 #define latchPin 2 //ST_CP Pin of 74HC595(Pin12)
8 #define clockPin 3 //SH_CP Pin of 74HC595(Pin11)
9 //Define an array to save the pulse width of LED. Output the signal to the 8 adjacent
10 LEDs in order.
11 const int pluseWidth[]={0,0,0,0,0,0,0,0,64,32,16,8,4,2,1,0,0,0,0,0,0,0,0};
12 void outData(int8_t data){
13 digitalWrite(latchPin,LOW);
14 shiftOut(dataPin,clockPin,LSBFIRST,data);
15 digitalWrite(latchPin,HIGH);
16 }
17 int main(void)
18 {
19 int i,j,index; //index:current position in array pluseWidth
20 int moveSpeed = 100; //move speed delay, the greater, the slower
21 long lastMove; //Record the last time point of the move
22 if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen
23 printf("setup wiringPi failed !");
24 return 1;
25 }
26 pinMode(dataPin,OUTPUT);
27 pinMode(latchPin,OUTPUT);
28 pinMode(clockPin,OUTPUT);
29 index = 0; //Starting from the array index 0
30 lastMove = millis(); //the start time
31 while(1){
32 if(millis() - lastMove > moveSpeed) { //speed control
33 lastMove = millis(); //Record the time point of the move
34 index++; //move to next
35 if(index > 15) index = 0; //index to 0
36 }
37 for(i=0;i<64;i++){ //The cycle of PWM is 64 cycles
38 int8_t data = 0; //This loop of output data
39 for(j=0;j<8;j++){ //Calculate the output state of this loop
40 if(i < pluseWidth[index+j]){ //Calculate the LED state according to
41 the pulse width
42 data |= 0x01<<j ; //Calculate the data
43 }
250 Capítulo 27 Placa de circuito de soldadura www.freenove.com █

44 }
45 outData(data); //Send the data to 74HC595
46 }
47 }
48 return 0;
49 }

Podemos ver que este programa es diferente al anterior. Definimos una matriz para modular diferentes anchuras
de pulso PWM para LED, de modo que diferentes LED puedan emitir un brillo diferente. Comenzando desde el
índice de matriz 0, tome una matriz de 8 números adyacentes como el ciclo de trabajo del LED y déjelo salir a la
vez. Aumenta el número de índice de inicio por turno, luego creará un efecto de flujo.

const int pluseWidth[]={0,0,0,0,0,0,0,0,64,32,16,8,4,2,1,0,0,0,0,0,0,0,0};


Al registrar el punto de tiempo en movimiento para controlar la velocidad del movimiento del número de índice,
es decir, controlar la velocidad de flujo de la luz del agua que fluye. Variable moveSpeed guarda el intervalo de
tiempo de cada movimiento, y cuanto mayor es el valor, más lenta es la velocidad de flujo. Por el contrario,
cuanto más rápido fluya.
if(millis() - lastMove > moveSpeed) { //speed control
lastMove = millis(); //Record the time point of the move
index++; //move to next
if(index > 15) index = 0; //index to 0
}

Finalmente, en un ciclo "for"(ciclo "para") con i = 64, module el ancho del pulso de salida de la onda cuadrada
PWM. Y el progreso, desde el comienzo de la implementación del ciclo para el final, es un ciclo de PWM. En el
ciclo, hay un anthoer para el ciclo con j = 8. Y en este ciclo, compare el número de ciclo "i" con el valor de la
matriz para determinar el nivel de salida alto o bajo. Por fin, los datos serán enviados a 74HC595.

for(i=0;i<64;i++){ //The cycle of PWM is 64 cycles


int8_t data = 0; //This loop of output data
for(j=0;j<8;j++){ //Calculate the output state of this loop
if(i < pluseWidth[index+j]){ //Calculate the LED state according to
the pulse width
data |= 0x01<<j ; //Calculate the data
}
}
outData(data); //Send the data to 74HC595
}
█ www.freenove.com Capítulo 27 Placa de circuito de soldadura 251

Pyhton Code 27.2.1 LightWater03


Primero observe el fenómeno experimental, y luego analice el código.
3. Use el comando cd para ingresar al directorio 27.2.1_LightWater03 del código de Python.
cd Freenove_Ultimate_Starter_Kit_for_Raspberry_Pi/Code/Python_Code/27.2.1_LightWater03
4. Use el comando python para ejecutar el código python “LightWater03.py”.
python LightWater03.py
Después de que se ejecuta el programa, los LED se iluminarán en forma de flujo de agua y transportarán
una larga cola. El siguiente es el código del programa:
1 import RPi.GPIO as GPIO
2 import time
3
4 LSBFIRST = 1
5 MSBFIRST = 2
6 #define the pins connect to 74HC595
7 dataPin = 11 #DS Pin of 74HC595(Pin14)
8 latchPin = 13 #ST_CP Pin of 74HC595(Pin12)
9 clockPin = 15 #SH_CP Pin of 74HC595(Pin11)
10 #Define an array to save the pulse width of LED. Output the signal to the 8 adjacent LEDs
11 in order.
12 pluseWidth = [0,0,0,0,0,0,0,0,64,32,16,8,4,2,1,0,0,0,0,0,0,0,0]
13
14 def setup():
15 GPIO.setmode(GPIO.BOARD) # Number GPIOs by its physical location
16 GPIO.setup(dataPin, GPIO.OUT)
17 GPIO.setup(latchPin, GPIO.OUT)
18 GPIO.setup(clockPin, GPIO.OUT)
19
20 def shiftOut(dPin,cPin,order,val):
21 for i in range(0,8):
22 GPIO.output(cPin,GPIO.LOW);
23 if(order == LSBFIRST):
24 GPIO.output(dPin,(0x01&(val>>i)==0x01) and GPIO.HIGH or GPIO.LOW)
25 elif(order == MSBFIRST):
26 GPIO.output(dPin,(0x80&(val<<i)==0x80) and GPIO.HIGH or GPIO.LOW)
27 GPIO.output(cPin,GPIO.HIGH);
28
29 def outData(data):
30 GPIO.output(latchPin,GPIO.LOW)
31 shiftOut(dataPin,clockPin,LSBFIRST,data)
32 GPIO.output(latchPin,GPIO.HIGH)
33
34 def loop():
35 moveSpeed = 0.1 #move speed delay, the greater, the slower
36 index = 0 #Starting from the array index 0
252 Capítulo 27 Placa de circuito de soldadura www.freenove.com █

37 lastMove = time.time() #the start time


38 while True:
39 if(time.time() - lastMove > moveSpeed): #speed control
40 lastMove = time.time() #Record the time point of the move
41 index +=1 #move to next
42 if(index > 15): #index to 0
43 index = 0
44
45 for i in range(0,64): #The cycle of PWM is 64 cycles
46 data = 0 #This loop of output data
47 for j in range(0,8): #Calculate the output state of this loop
48 if(i < pluseWidth[j+index]): #Calculate the LED state according to the
49 pulse width
50 data |= 1<<j #Calculate the data
51 outData(data) #Send the data to 74HC595
52
53 def destroy(): # When 'Ctrl+C' is pressed, the function is executed.
54 GPIO.cleanup()
55
56 if __name__ == '__main__': # Program starting from here
57 print 'Program is starting...'
58 setup()
59 try:
60 loop()
61 except KeyboardInterrupt:
62 destroy()

Podemos ver que este procedimiento es diferente de la lámpara de agua corriente anterior, definimos una matriz
para la modulación de diferentes anchuras de pulso de LED PWM, por lo que diferentes LED tienen diferente
brillo. A partir del índice de matriz 0, cada uno toma una matriz de 8 números adyacentes, ya que la salida del
ciclo de trabajo del LED, que a su vez aumenta el número de índice, producirá un efecto de flujo. .

pluseWidth = [0,0,0,0,0,0,0,0,64,32,16,8,4,2,1,0,0,0,0,0,0,0,0]

Al registrar el punto de tiempo en movimiento para controlar la velocidad del movimiento del número de índice,
es decir, controlar la velocidad de flujo de la luz del agua que fluye. Variable moveSpeed guarda el intervalo de
tiempo de cada movimiento, y cuanto mayor es el valor, más lenta es la velocidad de flujo. Por el contrario,
cuanto más rápido fluya.

if(time.time() - lastMove > moveSpeed): #speed control


lastMove = time.time() #Record the time point of the move
index +=1 #move to next
if(index > 15): #index to 0
index = 0
█ www.freenove.com Capítulo 27 Placa de circuito de soldadura 253

Finalmente, en un ciclo "para" con i = 64, module el ancho del pulso de salida de la onda cuadrada PWM. Y el
progreso, desde el comienzo de la implementación del ciclo para el final, es un ciclo de PWM. En el ciclo, hay un
anthoer para el ciclo con j = 8. Y en este ciclo, compare el número de ciclo "i" con el valor de la matriz para
determinar el nivel de salida alto o bajo. Por fin, los datos serán enviados a 74HC595.

for i in range(0,64): #The cycle of PWM is 64 cycles


data = 0 #This loop of output data
for j in range(0,8): #Calculate the output state of this loop
if(i < pluseWidth[j+index]): #Calculate the LED state according to the
pulse width
data |= 1<<j #Calculate the data
outData(data) #Send the data to 74HC595
254 ¿Que sigue? www.freenove.com █

¿Que sigue?
Gracias por tu lectura.

Este tutorial está aquí. Si encuentra errores u omisiones o tiene otras ideas y preguntas sobre el contenido de
este tutorial o el kit, etc., no dude en contactarnos, y lo revisaremos y corregiremos lo antes posible.

Si desea obtener más información sobre Arduino, Raspberry Pi, autos inteligentes, robots y otros productos
interesantes en ciencia y tecnología, continúe centrándose en nuestro sitio web. Seguiremos lanzando
productos rentables, innovadores y emocionantes.

Gracias de nuevo por elegir los productos Freenove.

Das könnte Ihnen auch gefallen