Está en la página 1de 30

¿Qué es un programa?

En el capítulo 2, hemos visto cómo los sensores y la electrónica permiten conectar el


mundo físico con un sistema informático, como un microcontrolador. Esta conexión
permite completar el primer paso para la creación de una solución de IoT. Primero se
detectan los datos del mundo físico, luego se hace algo con esos datos. Se almacenan,
transmiten o procesan. En el mundo digital, el procesamiento de datos se realiza mediante
programas de software. En este capítulo repasaremos los conceptos clave de programación
de software y presentaremos Raspberry PI. Aprender a escribir programas informáticos con
RaPI será el segundo paso fundamental en nuestro recorrido hacia los prototipos de
soluciones de IoT.

Un programa es un conjunto de instrucciones solicitadas creado para realizar una tarea


específica. Según esta definición, muchas actividades de la vida diaria se pueden considerar
programas.

Una receta básica de pan puede considerarse un programa:

 Precaliente el horno a 375 ºF. Enmanteque y enharine dos moldes de pan de


9 pulgadas.

 Disuelva la levadura en agua caliente. Agregue azúcar, sal, aceite y 3 tazas de agua.

 Bata hasta que quede homogéneo y mezcle con el resto de la harina.

 Amase en una superficie enharinada entre 8 y 10 minutos.

 Coloque en un bol engrasado y deje levar durante 1 a 2 horas.

 Golpee la masa, divídala en dos y colóquela en los moldes de pan. Cubra y deje
levar hasta que se duplique.

 Hornee a 375 ºF de 30 a 35 minutos.

En este ejemplo, el orden de las instrucciones es relevante. La receta, como un programa de


software, fue diseñada para realizar una tarea específica; en este caso, hacer pan.

La receta pudo haberse escrito en cualquier idioma: inglés, español, chino o árabe. El único
requisito para la opción de idioma es que la persona que hace el pan lo comprenda. Si bien
los diferentes idiomas poseen distintas reglas gramaticales y sintaxis, la lógica de la receta
no debe cambiar.

De manera similar, los programas informáticos son también un conjunto de instrucciones


solicitadas creadas para realizar una tarea específica. También llamados códigos, los
programas informáticos se pueden escribir en otros lenguajes. La sintaxis y las reglas varían
de lenguaje en lenguaje, pero la lógica del programa prácticamente no debe tener cambios

Los programas están en todas partes


Todas las computadoras necesitan programas. Una computadora es un dispositivo que
contiene una CPU, una memoria y dispositivos de E/S (monitor, teclado, ratón, tarjeta de
audio, etc.). Las computadoras de escritorio, los smartphones, las tablets, los relojes
digitales y los dispositivos inteligentes son solo algunos ejemplos de computadoras.
Aunque las computadoras están en todas partes, son inútiles hasta que se ejecutan los
programas.

Los programas informáticos adoptan muchas formas diferentes. Los sistemas operativos, el
firmware y las aplicaciones son ejemplos de programas que se encuentran en las
computadoras.

Un sistema operativo (SO) es un programa que permite que los usuarios interactúen con las
computadoras. Los sistemas operativos modernos incluyen interfaces gráficas para facilitar
la interacción del usuario. Los ejemplos de SO son Windows, Linux, OS X, Apple iOS y
Android.

Firmware son programas creados para permitir que una computadora realice una tarea
específica. El firmware suele estar presente en computadoras pequeñas, como relojes
digitales simples, dispositivos modernos y diversos subsistemas encontrados en
automóviles modernos (por ejemplo, el sistema de frenos antibloqueo (ABS) y las bolsas de
aire). Debido a la memoria limitada y a otras restricciones de recursos, los dispositivos de
IoT a menudo dependen del firmware para su funcionamiento. La funcionalidad del
firmware y el SO se superpone. A veces, el firmware también puede actuar como SO para
computadoras más simples.

Las aplicaciones son programas creados para ayudar al usuario a realizar una tarea
específica. Los ejemplos de aplicaciones son Microsoft Word, Mozilla Firefox y Calculator.

¿Por qué se debe aprender a programar?


Las personas que pueden programar son cada vez más valiosas en el actual mercado
laboral. A pesar de que en el pasado los programadores estaban limitados a la codificación
de aplicaciones de escritorio, el incremento de IoT genera nuevas posibilidades para ellos.
En 1991, Mark Weiser escribió un documento titulado “La computadora del siglo XXI”. En
este documento, previó el futuro de IoT y lo describió como “elementos especializados de
hardware y software, conectados por cables, ondas de radio e infrarrojas, tan ubicuos que
nadie notaría su presencia”. En un mundo cada vez más digital, la naturaleza ubicua de la
computación significa que el software está en todas partes. Actualmente, los programadores
pueden trabajar con el firmware, los controladores de dispositivos, las aplicaciones móviles,
las interfaces web, el análisis de datos y más. Estas áreas laborales estaban disponibles
antes, pero IoT ha aumentado drásticamente la cantidad de empresas y proyectos
disponibles.

La industria de las redes también impulsa la necesidad de más programadores requeridos


para personalizar la red y la infraestructura. Los enfoques emergentes de la red, como las
redes definidas por software (SDN) y la infraestructura centrada en aplicaciones (ACI) de
Cisco proporcionan programabilidad integral a la infraestructura de la red.

Otro beneficio de saber programar es que los programadores pueden crear sus propias
herramientas de software. ¿Necesita un filtro específico de red no disponible en el
mercado? Tal vez un proyecto requiere un análisis de datos específico. Un buen
programador puede cifrarlo.

¿Qué conforma un programa?


Las personas imparten la lógica a las computadoras a través de programas. Los programas
usan expresiones, funciones y estructuras lógicas. Las expresiones son combinaciones de
variables, constantes y operadores que producen un nuevo valor. Las funciones definen una
secuencia de expresiones que debe aplicarse a los argumentos (x, y) para producir el valor
arrojado z. Mediante estructuras lógicas específicas, un programador puede preparar una
computadora para tomar decisiones. Algunos ejemplos de expresiones, funciones y
estructuras lógicas más comunes son:

 Expresiones

 Area_Triangle = (base*height)/2

 Print Area_Triangle

 Funciones

 z= Function(x,y)

 IF - THEN: esta estructura lógica permite que la computadora tome una decisión
según el resultado de una expresión. Un ejemplo de expresión es myVar > 0. Esta
expresión es verdadera si el valor almacenado en la variable myVar es mayor que
cero. Cuando el intérprete o compilador encuentra una estructura IF - THEN, evalúa
la expresión proporcionada. Si la expresión es falsa, la computadora continúa con la
siguiente estructura, ignorando el contenido del bloque IF - THEN. Si la expresión
es verdadera, la computadora ejecuta la acción asociada antes de pasar a la siguiente
instrucción del programa. (Figura 1).

 Bucle FOR: se utiliza para ejecutar un conjunto específico de instrucciones una


cantidad de veces específica según una expresión. El término bucle proviene del
hecho de que un conjunto de instrucciones se ejecuta varias veces. Si bien la
sintaxis del bucle FOR varía de lenguaje en lenguaje, el concepto es el mismo: se
define una variable para que actúe como contador y valor máximo. Cada vez que se
ejecuta el bucle, aumenta la variable del contador. Cuando el contador es igual al
valor máximo definido, se abandona el bucle y los movimientos de ejecución del
siguiente paso. (Figura 2).

 Bucle WHILE: se utiliza para ejecutar un conjunto específico de instrucciones


mientras que una expresión es verdadera. Observe que las instrucciones dentro del
bucle a menudo harán que la expresión se evalúe finalmente como falsa. (Figura 3).

Antes de escribir un código, el programador necesita entender el problema y cómo puede


resolverse dividiéndolo en una secuencia de pasos y decisiones. Es común que los
programadores creen el primer borrador de un programa sin ningún lenguaje específico.
Estos programas independientes del lenguaje se centran en la lógica en lugar de la sintaxis
y se conocen como algoritmos. Un diagrama de flujo es una manera común de representar
un algoritmo. La Figura 4 muestra un ejemplo del diagrama de flujo. Escribir un buen
algoritmo para resolver un problema es una tarea increíble que algunas personas consideran
una forma de arte.

Interpretado frente a compilado


Los lenguajes de computadora se pueden dividir en dos categorías principales:
interpretados y compilados.

Los lenguajes interpretados dependen de otro programa para analizar y ejecutar el código.
Este programa se denomina intérprete. El código permanece en texto legible para el
humano y se envía a un intérprete para su ejecución. Si bien los lenguajes interpretados
facilitan el mantenimiento y la solución de problemas de los códigos, la ejecución es más
lenta que en los lenguajes compilados. Algunos ejemplos de lenguajes interpretados son
Python, JavaScript y PHP.

Los lenguajes compilados dependen de un compilador (otro programa) para convertir el


código legible para el ser humano en un código ejecutable binario. El código compilado se
almacena de forma binaria y puede ejecutarse en cualquier momento sin la necesidad de
volver a compilarse. El código compilado además se ejecuta más rápido porque lo hace
directamente desde la CPU, sin la necesidad de un intérprete. Debido a que el lenguaje
compilado se ejecuta directamente desde la CPU, el compilador y el código compilado
binario que genera son específicos de la plataforma. Código fuente es el término que se usa
para referirse al código de lenguaje compilado antes de su compilación. En esta etapa, el
código es legible para el humano y puede modificarse fácilmente. Si un programador desea
realizar cambios en un programa compilado, debe aplicar dichos cambios al código fuente y
volver a compilarlo antes de su ejecución. Ejemplos de lenguajes compilados son C y C++.

La Figura 1 muestra leap_check.py, un programa escrito en Python para calcular si un año


determinado será un año bisiesto.
La Figura 2 muestra leap_check.c, un programa escrito en C para calcular si un año
determinado será un año bisiesto aún como código fuente antes de la compilación.

La Figura 3 muestra leap_check.c, un programa escrito en C para calcular si un año


determinado será un año bisiesto, en un sistema hexadecimal, después de la compilación.

La Figura 4 muestra el resultado de leap_check, un programa escrito en C para calcular si


un año determinado será un año bisiesto después de tres ejecuciones.

Lenguajes de computadora
Al igual que los idiomas humanos, hay varios lenguajes de computadora diferentes.
Algunos lenguajes de computadora son mejores que otros para ciertos tipos de tareas.

JavaScript, un lenguaje de computadora, está diseñado para crear aplicaciones web. Con
JavaScript, un programador puede crear aplicaciones web que pueden interactuar con los
usuarios y otras aplicaciones.

Python, otro lenguaje interpretado, permite declaraciones más simples. Python es muy fácil
de usar, potente y versátil y se ha convertido en el lenguaje de preferencia de muchos
desarrolladores de IoT. Uno de los motivos principales de popularidad de Python es la
comunidad de desarrolladores; los desarrolladores de Python han creado y puesto a
disposición muchos módulos específicos que pueden importarse a cualquier programa para
prestar inmediatamente mayor funcionalidad.

Blockly es un lenguaje de programación visual que permite a los usuarios crear programas
conectando bloques que representan diversas estructuras de lenguaje lógico en lugar de
escribir el código real. Blockly se ejecuta dentro de un navegador web y puede traducir el
programa visualmente creado, como JavaScript, PHP o Python. En la figura se muestra un
ejemplo de Blockly.

C, un lenguaje compilado, es bueno para crear programas complejos y rápidos, pero sus
reglas y sintaxis estrictas dificultan su desarrollo. Creado a principios de 1970, C se ha
convertido en uno de los lenguajes de programación más utilizado de todos los tiempos. El
sistema operativo Linux se escribe en C.

Java es un lenguaje compilado que se “escribe una sola vez y se ejecuta en cualquier lugar”
(WORA). A pesar del nombre similar, Java y JavaScript no están relacionados. Java está
diseñado para ejecutarse en cualquier plataforma sin la necesidad de la recompilación. Las
aplicaciones basadas en Java requieren una plataforma de JVM (máquina virtual Java)
instalada en la computadora. JVM es el entorno donde se ejecuta el código compilado en
Java.
Procesamiento de datos y dispositivos de
IoT
Una aplicación común para los sistemas de IoT es la recopilación de datos. Los dispositivos
de IoT, como sensores, a menudo se implementan en ubicaciones donde ocurre la
recopilación de datos. La agricultura, el transporte y la manufactura son solo algunos
ejemplos de áreas donde la recopilación de datos se realiza mediante uno o más sistemas de
IoT.

Aunque la recopilación de datos es importante, los datos deben procesarse antes de que
puedan ser útiles. Los datos recopilados se pueden procesar en el punto de recopilación o se
pueden transmitir y almacenar en la nube para procesarlos en otro momento. Con
frecuencia los datos de distintas fuentes se combinan para brindar información más útil. Se
utilizan programas informáticos para procesar eficazmente los datos recolectados.

En un ejemplo agrícola, los dispositivos de IoT se pueden utilizar para supervisar el suelo y
las condiciones climáticas. Los sensores recogen datos sobre la humedad del suelo, la
temperatura y los niveles de acidez. Otros sensores pueden recopilar datos sobre los niveles
de CO2 en el aire además de la temperatura del aire, la presión barométrica y la humedad.
Todos estos datos casi no tienen uso hasta que se procesan. Se puede escribir un programa
de computadora para procesar los datos y calcular las chances de lluvia
API de software
En muchos casos, los programas deben comunicarse con otros programas, sitios web o
dispositivos. Una interfaz de programa de aplicación (API) es un conjunto de rutinas y
herramientas de software que facilita la comunicación entre programas. Gracias a las API,
las aplicaciones que se ejecutan a través de las redes pueden comunicarse entre sí,
compartir datos y solicitar servicios específicos de otras aplicaciones, por ejemplo,
preguntar a una API externa si la persona de la imagen es hombre o mujer.

Hay diferentes tipos de API disponibles, como API de sistema operativo, API de aplicación
y API de sitio web. Al crear una aplicación de administrador de archivos, un desarrollador
de software aprovechará la API de sistema operativo para copiar, mover o eliminar un
archivo. Si la aplicación del desarrollador no tiene el código necesario para realizar estas
funciones, simplemente puede solicitar al sistema operativo que las realice a través de su
API de sistema operativo expuesta.

Las aplicaciones de IoT pueden comunicarse entre sí mediante las API, pero también
pueden utilizarlas para comunicarse con otros servicios basados en la nube.
Independientemente del tipo de API, el objetivo sigue siendo el mismo: permitir que otros
programas interactúen entre sí. Los detalles sobre cómo utilizar una API específica y qué
tareas se exponen se incluyen en la documentación de la API.

La figura muestra un ejemplo de documentación de una API. Observe las tareas expuestas
por la API. Todas las tareas enumeradas pueden se utilizadas por otros programas.

API de REST
La transferencia de estado representativa (REST), o servicio web RESTful, es un tipo de
API diseñado para facilitar la interacción de los programas con Internet. Las API de REST
usan llamadas basadas en HTTP entre las diferentes aplicaciones para manipular y acceder
a la información almacenada en las bases de datos potentes.

Los recursos web solían ser identificados exclusivamente por una URL. Actualmente, los
recursos web abarcan cada entidad o cosa que puede nombrarse, identificarse o abordarse.
Las entidades pueden ser un objetivo de paso del día, una configuración de temperatura de
la casa o la frecuencia cardíaca de un marcapasos. Cada recurso ahora tiene una
identificación de recurso uniforme (URI) que generalmente comienza con una barra
diagonal, por ejemplo, /frecuenciacardíaca. Las API de REST usan el protocolo HTTP y
una URL o URI para solicitar servicios web. Dichas solicitudes REST basadas en la web
activan respuestas en formatos web bien definidos, como XML y JSON (notación de
objetos JavaScript). Mediante el uso de HTTP como protocolo, los servicios RESTful
pueden tomar prestadas operaciones de HTTP, como las acciones HTTP GET, POST, PUT
and DELETE. Un ejemplo puede ser un marcapasos que envía actualizaciones sobre la
frecuencia cardíaca promedio a una base de datos médica. El marcapasos puede utilizar una
llamada de API de REST en un formato específico (PONER de HTTP) para actualizar la
información en la base de datos.

Los sistemas de IoT que aprovechan los servicios en la nube dependen con frecuencia de
los servicios RESTful para comunicarse. Por ejemplo, considere un reloj inteligente con
capacidades climáticas, donde un dispositivo de IoT recopila la información del clima para
su ubicación actual y la muestra al usuario. Este reloj puede programarse para comunicarse
con un sistema meteorológico basado en la web a través de una URL de API de REST
(dirección web). Este tipo de URL y sus parámetros se describirán en la documentación de
la API. La figura muestra un ejemplo de URL de servicio RESTful. De la misma manera en
que un explorador web visita una página web, el reloj se contacta con la URL descrita en la
documentación de la API del sistema meteorológico y solicita, mediante la acción
OBTENER de HTTP, el clima para la ubicación actual (según el sensor del GPS). El
sistema meteorológico responderá, conforme a su propia API, con datos con formato JSON
o XML que contienen la información del clima para dicha ubicación. El código que se
ejecuta en el reloj, también creado según la API del sistema meteorológico, a su vez
muestra la información al usuario.

Protección del código


Un sistema de IoT consta de la interconexión de varios bloques funcionales: dispositivos,
gateways, redes, nube y aplicación real. En cada uno de estos bloques, hay un código que se
ejecuta para cumplir con la función para la que está diseñado. Las mejores prácticas
recomendadas para proteger los dispositivos conectados en IoT deben incluir:

a) Los dispositivos deben protegerse de ataques que afecten su función o permitan que se
usen para fines no deseados sin autorización.

b) Los dispositivos deben proteger las credenciales de autenticación y los materiales clave
privados de la divulgación a partes no autorizadas.

c) Los dispositivos deben proteger la información recibida, transmitida o almacenada


localmente en el dispositivo de la divulgación inadecuada a partes no autorizadas.

d) Los dispositivos deben protegerse contra el uso como vectores para atacar a otros
dispositivos o hosts en Internet.

Para lograr las mejores prácticas de seguridad recomendadas, la seguridad física, la


capacidad de confiar en la integridad del código y la capacidad de actualizarse de forma
remota son fundamentales para el diseño de todos los sistemas y dispositivos de IoT.

Los dispositivos de IoT se encuentran en ubicaciones tradicionales, como centros de datos


en la nube, y también en muchas ubicaciones no tradicionales, como postes de luz,
estacionamientos y cuerpos humanos. Las ubicaciones tradicionales se pueden proteger
mediante cámaras de vigilancia, sistemas de control de acceso, identificación biométrica y
puntos de autenticación múltiples.

La seguridad de los dispositivos de IoT en ubicaciones no tradicionales es más compleja.


Los dispositivos deben fabricarse para ser resistentes a manipulaciones y deben colocarse
de manera tal que no sean obvios y tengan difícil acceso. Aunque uno debe hacer lo mejor
para proteger estos dispositivos físicamente, un hacker determinado aún puede obtener
acceso. La seguridad física, en la mayoría de los casos, es una práctica recomendable pero
no suficiente en sí misma.

Una manera en que un hacker puede cambiar la función de un dispositivo es: acceder al
dispositivo, deshabilitar la función, instalar software nuevo en el dispositivo y reiniciarlo.
Otra forma de proteger el dispositivo es asegurarse de que el código del dispositivo (tanto
firmware como aplicación) sea el código original que se creó. Esta medida de seguridad
puede proteger el dispositivo de intentos de cambiar sus funciones, incluso si se infringió la
seguridad física. Esto se realiza “firmando” criptográficamente el código original y
garantizando que el dispositivo no se inicie si el código no está firmado.  Este es el mismo
método que se utiliza para garantizar la integridad y la procedencia de los documentos. Hay
muchos enfoques que surgen en la industria para satisfacer los diferentes ángulos de este
problema, como la computación de confianza, las tecnologías de anclaje de confianza de
Cisco y el arranque seguro de Cisco.  Por ejemplo, para iOS en un router, el anclaje de
confianza de Cisco y el acceso seguro de Cisco comprueban el código firmado para
garantizar que el código que se ejecuta en las plataformas de hardware de Cisco sea
auténtico y no esté modificado, estableciendo una raíz de confianza a nivel del hardware y
una identidad inmutable del dispositivo para edificar el sistema.  

También es fundamental que los dispositivos de IoT se diseñen para actualizarse de forma
remota. El diseño debe incluir funciones para permitir la administración remota del
dispositivo y las actualizaciones. También deben tenerse en cuenta la eliminación de las
puertas traseras de la fase de desarrollo o las cuentas de acceso de depuración de
codificación rígida y la aplicación del acceso autorizado únicamente.

Los datos deben cifrarse mientras se reciben o transmiten a servidores locales o remotos. El
acceso remoto a los servidores o los terminales remotos también debe protegerse. Esto
garantiza que los datos conserven su integridad dado que permanecen protegidos del acceso
no autorizado y la manipulación. Los algoritmos de encriptación y los protocolos de
transmisión seguros son técnicas de uso general para proteger el software y los datos.

Los dispositivos de IoT toman decisiones


Un aspecto importante de un sistema de IoT es la capacidad de tomar decisiones. Activar
una alarma si los niveles de dióxido de carbono superan un umbral o desbloquear una
puerta al detectar el mando a distancia correcto son dos ejemplos de decisiones que podrían
tomarse a través de dispositivos de IoT. Algunos dispositivos de IoT también son capaces
de tomar decisiones más complejas, como identificar el rostro de una persona desde la
fuente de una cámara.

La capacidad de tomar decisiones se suma a algunos de los dispositivos de IoT mediante el


software. Los programas deben escribirse y cargarse en el dispositivo de IoT para su
ejecución antes de que el dispositivo pueda tomar decisiones.

Raspberry Pi y sus puertos


Raspberry Pi (Pi) es una computadora económica y pequeña. Tiene una cantidad de puertos
USB que pueden usarse para conectar varios dispositivos, como teclados, ratones, unidades
externas y cámaras. Dado que se trata de una computadora completa en un paquete del
tamaño de una tarjeta de crédito, RaPi se ha convertido en la opción para muchos proyectos
de IoT. Pi3 comparte las funciones de su predecesora Pi2, pero añade:

 Una CPU de 1,2 Ghz y 64 bits con procesador de cuatro núcleos ARMv8

 LAN inalámbrica 802.11n

 Bluetooth 4.1

 Bluetooth de baja energía (BLE)

La Figura 1 muestra una vista superior del modelo B de Raspberry Pi 3.

La Figura 2 muestra una vista inferior del modelo B de Raspberry Pi 3.

RaPi además incluye un encabezado de 40 pines con GPIO. Los pines de GPIO
(entrada/salida de uso general) son extremadamente útiles para interactuar con el mundo
físico. Los sensores, los accionadores, los switches y los dispositivos pueden conectarse a la
GPIO y controlarse mediante el código que se ejecuta en RaPi. Otros puertos de RaPi
incluyen una salida de audio, una ranura para tarjeta SD, un puerto Ethernet, 4 puertos
USB, una interfaz de cámara (CSI), una interfaz de dispositivo (DSI) y un conector micro
USB (para alimentación).

La Figura 3 muestra la distribución de terminales de GPIO del modelo B de Raspberry Pi 3.

Creada con base en Raspberry Pi, RaPi se diseñó para ser pequeña y económica. RaPi
puede ejecutar varios sistemas operativos, como Linux y Windows.

La Figura 4 muestra las especificaciones de hardware del modelo B de Raspberry Pi 3.

PL-App
Existen varias maneras de configurar y usar Raspberry Pi. Mediante la conexión física de
una pantalla HDMI, un ratón y un teclado USB, RaPi se convierte en una PC general y
permite al usuario tener acceso físico local. Una vez que se descarga la imagen compatible
del sistema operativo de Raspberry Pi a la tarjeta micro SD, RaPi está lista para usar.

Tradicionalmente, Raspberry Pi se usa como computadora completa con monitor, teclado y


ratón. Estos son los pasos para usar la Raspberry Pi como computadora con acceso físico
local:

Paso 1: Instale una imagen de sistema operativo en la tarjeta micro SD.

Paso 2: Coloque la tarjeta en la ranura para tarjetas micro SD de RaPi.

Paso 3: Conecte un teclado USB.

Paso 4: Conecte un monitor o TV mediante el puerto HDMI.

Paso 5: Encienda el dispositivo con el adaptador de potencia.

Alternativamente, para utilizar la Raspberry Pi como dispositivo de IoT, se debe poder


controlar desde la red. Acéfalo es el término que se utiliza para servidores que solo se
operan de forma remota. Aunque hay disponibles muchas configuraciones acéfalas, este
curso se enfoca en una solución personalizada llamada aplicación de prácticas de
laboratorio de prototipos (PL-App). PL-App permite el acceso a Raspberry Pi directamente
desde la red. El acceso acéfalo permite el funcionamiento sin la necesidad de un monitor,
un teclado o un ratón conectados directamente a RaPi (Figura 1). Desde una segunda PC, el
usuario establece conexiones de red a RaPi y opera a través de estas conexiones. Es
compatible con la GUI y funciona solo con texto. La Figura 2 muestra un ejemplo de una
topología de una clase que ejecuta PL-App en Raspberry Pi.

La Figura 3 muestra una captura de pantalla de los componentes que conforman PL-App.

Tarjeta SD con capacidad de arranque


Las computadoras modernas pueden arrancar el sistema de los dispositivos USB externos y
las tarjetas SD. Con el aumento de su popularidad debido a las tarjetas externas más
grandes y económicas, es común tener sistemas operativos enteros instalados en dichas
tarjetas.

Raspberry Pi 3 incluye una ranura para tarjeta micro SD (Figura 1) que se usará como
dispositivo de almacenamiento para el sistema. Antes de que Raspberry Pi 3 se pueda
utilizar, debe instalarse un sistema operativo en la tarjeta micro SD que se colocará en la
ranura SD para arrancarla.
Si bien hay varias formas de instalar un sistema operativo en una tarjeta micro SD, el más
común (y probablemente el más rápido) es utilizar un archivo de imagen. Un archivo de
imagen es un archivo único que contiene una imagen del sistema de archivos completo. En
ese sentido, el archivo de imagen es una copia exacta del sistema de archivos y puede
utilizarse para reconstruir el sistema de archivos en otros medios. Los formatos de archivo
de imagen comunes son: .iso y .img.

Hay varias opciones disponibles para las herramientas de transferencia de imágenes. El que
se usa en este curso es parte del Iniciador de PL-App. Se trata de una herramienta
personalizada de transferencia de imágenes que simplifica la implementación de las
imágenes utilizadas en el curso. El Iniciador de PL-App además administra la detección y
el control acéfalo de Raspberry Pi conectada a la red.

La Figura 2 muestra los pasos para configurar un dispositivo nuevo.

La Figura 3 muestra cómo conectar un nuevo dispositivo mediante la aplicación del


Iniciador de PL-App.

Si un usuario descarga una imagen sin la herramienta de PL-App especializada, el usuario


deberá obtener el archivo de imagen creado por el fabricante o el encargado de
mantenimiento que habilita la descarga. El usuario simplemente podrá descargarlo de la
página web correspondiente. La base de Raspberry Pi ofrece una imagen de Raspbian, una
variación de Debian Linux personalizada para Raspberry Pi. Este curso utiliza una imagen
de PL-App basada en una versión modificada de Raspbian.

nterpretación de Linux
Linux es un sistema operativo creado en 1991. Fue creado, y es mantenido actualmente, por
una comunidad de programadores. Linux es de código abierto, rápido, confiable y pequeño.
Requiere muy pocos recursos de hardware para ejecutarse y es altamente personalizable.
Linux es parte de diferentes plataformas y puede encontrarse en cualquier lugar, desde
“relojes a supercomputadoras”. Linux es también una opción muy popular en los
dispositivos de IoT.

Otro aspecto importante de Linux es que está diseñado para estar en la red. Las operaciones
de red y las conexiones son simples en Linux, lo que lo convierte en una buena opción para
los profesionales y administradores de redes. Cualquier persona puede obtener el código
fuente del núcleo, examinarlo, modificarlo y volver a compilarlo a disposición. Las
empresas y los usuarios son libres de modificar, reempaquetar y ejecutar el software.
Pueden redistribuir el programa con o sin cargos.

Una distribución de Linux es el término que se utiliza para describir los distintos paquetes
de Linux creados por distintas empresas. Las distribuciones de Linux (o distros) incluyen el
núcleo de Linux más varias herramientas y paquetes de software personalizados. Si bien
algunas proporcionan y cobran el soporte de Linux (orientado a empresas basadas en
Linux), la mayoría ofrece su distribución gratuita sin soporte. Debian, Red Hat, Ubuntu,
Slackware y Mint son solo algunos ejemplos de distribuciones de Linux.

Raspbian es una distribución del sistema operativo Linux creada específicamente para
Raspberry Pi. Raspbian es una variación de Debian Linux y, por lo tanto, mantiene la
estructura de Linux.

La figura muestra una captura de pantalla de Raspbian ejecutándose en Raspberry Pi 3.

Acceso al shell de Linux


El sistema operativo de Linux puede dividirse en núcleo y shell. El núcleo se puede pensar
como el SO en sí, mientras que el shell es solo un programa que se ejecuta en el SO y
ofrece funcionalidades de interacción entre el SO y el usuario.

Para interactuar con el hardware de la máquina, el usuario interactúa con el shell que
interactúa con el núcleo que, a su vez, interactúa con el hardware. La figura es un diagrama
de alto nivel de Linux.

El shell es un interpretador de comandos y, por lo tanto, los términos shell, terminal,


consola y CLI se usan con frecuencia de forma indistinta. Este curso utiliza el término
terminal para referirse al shell. Cuando un usuario se conecta al sistema, el programa de
inicio de sesión revisa el nombre de usuario y la contraseña; si las credenciales son
correctas, el programa de inicio de sesión llama al shell. Desde aquí, un usuario autorizado
puede comenzar a interactuar con el SO a través de los comandos basados en texto.

Históricamente, cuando no había ninguna interfaz gráfica disponible, el shell se basaba en


texto sin soporte para el ratón o las funciones visuales avanzadas. También denominado
interfaz de línea de comandos (CLI), el shell basado en texto era la única forma para que el
usuario interactuara con el SO. Hoy en día, el shell de Linux sigue siendo extremadamente
importante, ya que proporciona acceso al sistema. Aunque muchas distribuciones de Linux
modernas incluyen soporte para las interfaces gráficas de usuario (GUI), el shell aún se
considera el método más eficiente para interactuar con el sistema. Esto es especialmente
cierto cuando la interacción se relaciona con el mantenimiento del sistema o la solución de
problemas.

Como ejemplo de interacción entre el usuario-shell-núcleo, supongamos que un usuario


desea eliminar un archivo llamado myFile. El usuario escribe rm myFile. rm es el
comando para eliminar los archivos y myFile es el nombre del archivo que se eliminará. El
shell busca en el sistema de archivos el programa rm y solicita al núcleo, a través de
llamadas al sistema, que ejecute el programa rm con el parámetro myFile. A medida que el
proceso se ejecuta, el shell no está disponible para el usuario y no presenta ninguna
indicación que señale el estado. Cuando el proceso rm myFile finaliza su ejecución, el
shell muestra el mensaje al usuario que indica que está listo y en espera de más comandos.
La figura muestra un núcleo anidado en un shell dentro de los programas de aplicación.

Acceso a CLI
Se crearon diferentes shells y añadieron muchas funciones para facilitar la escritura y la
interacción del usuario. Algunas de las características importantes del shell incluyen la
compleción de comandos y nombres de archivos con la tecla TAB, el historial de
comandos, los accesos directos del teclado para pasar de línea de comando y otras. Entre
los shells más populares aparecen el shell Bourne (sh), Bash (bash), el shell C (csh), el shell
C mejorado (tcsh) y el shell Z (zsh). Qué shell utilizar es una cuestión de preferencia para la
mayoría de los usuarios.

Aunque haya una CLI aún presente, el SO moderno a menudo arranca en la GUI de manera
predeterminada, ocultando la CLI al usuario. Una forma de acceder a la CLI en un sistema
operativo basado en la GUI es a través de una aplicación del emulador de terminal. Estas
aplicaciones permiten que el usuario acceda al shell y generalmente se denominan con
alguna variación de la palabra “terminal”. En Linux, los emuladores de terminal comunes
son Terminator, eterm, xterm, console y gnome-terminal. La figura muestra una captura de
pantalla de Gnome-Term, una aplicación del emulador de terminal de Linux.

Independientemente del emulador de terminal utilizado, el usuario aún decide qué shell
utilizar dentro de la aplicación del emulador de terminal. Para cambiar el shell, el usuario
debe tener el shell deseado instalado en el sistema y configurar algunas opciones en un
archivo de configuración. Si bien es importante comprender la diferencia entre emulador de
terminal y shell, reemplazar o configurar el shell predeterminado excede el alcance de este
curso.

Comandos básicos de Linux


Los comandos de Linux son básicamente programas creados para realizar una tarea
específica del sistema. Para añadir flexibilidad, algunos comandos admiten parámetros,
opciones y switches. Estos generalmente van precedidos por un guión ("-"). Las opciones y
los switches admitidos por un comando son ingresados por el usuario junto con el
comando. Utilice el comando man para obtener documentación sobre otros comandos. Por
ejemplo, man ls proporcionará documentación sobre el comando ls del manual del usuario
incorporado en la versión que se ejecuta de Linux.

Para invocar un comando a través del shell, simplemente escriba el nombre. El shell
intentará encontrarlo en la ruta del sistema y, si lo encuentra, lo ejecutará.

La figura muestra una lista de algunos comandos básicos de Linux y sus funciones.

Haga clic aquí para experimentar una interfaz de línea de comandos de Linux en su
navegador web.
Proceso de comandos de administración
Proceso es el término que se utiliza para hacer referencia a cualquier tarea ejecutada por el
sistema. Un programa de computadora es pasivo. Es un conjunto de instrucciones
almacenado en un disco como código ejecutable. Un proceso es en la práctica un programa
en acción. Las ID de proceso, o PID, son ID exclusivas asociadas a los procesos utilizadas
por el núcleo para identificarlos. Como con cualquier otro sistema operativo multitarea,
Linux puede administrar varios procesos al mismo tiempo. Linux también incluye
herramientas para la administración y visualización de los procesos. Los siguientes son
algunos comandos de administración de procesos:

 ps: este comando se utiliza para enumerar los procesos en ejecución en el sistema
cuando se invoca. Se puede indicar a ps que muestre los procesos en ejecución que
pertenecen al usuario actual o a otros usuarios. Si bien enumerar procesos no
requiere privilegios de raíz, eliminar o modificar otros procesos del usuario puede
que lo haga.

 top: este comando también se utiliza para indicar procesos en ejecución pero, a
diferencia de ps, top sigue mostrando los procesos en ejecución dinámicamente.
Presione q para salir de top.
 kill:: este comando se utiliza para modificar el comportamiento de un proceso
específico. Según los parámetros, kill eliminará, reiniciará o detendrá un proceso.
En muchos casos, el usuario ejecutará ps o top antes de ejecutar kill. Esto se hace
para que el usuario adquiera la PID de un proceso antes de ejecutar kill.

Si se bloquea un proceso, puede ser necesario eliminarlo manualmente. Esto es común al


crear programas, ya que pueden funcionar de manera incorrecta y bloquearse. Una razón
común para que un programa no responda es un bucle mal construido que se ejecuta
continuamente.

La figura muestra el comando top que se ejecuta en Linux.

Visualización de archivos y operaciones de


archivos
En Linux, la mayoría de las entidades se trata como archivos. Con el objetivo de organizar
el sistema y reforzar los límites dentro del sistema, Linux utiliza permisos de archivos. Una
de las características principales de Linux es que los permisos de archivos se incorporan en
la estructura del sistema de archivos y proporcionan un mecanismo para definir los
permisos en cada archivo. Esto significa que cada archivo en Linux conlleva sus permisos
de archivo que definen qué pueden hacer el usuario, el grupo y otros con el archivo. Los
posibles derechos de permisos son de lectura, escritura y ejecución. Considere el resultado
del comando ls - l a continuación:

rod@machine: $ ls -l My_Awesome_File

-rwxrw-r-- 1 rod staff 1108485 Aug 14 7:34 My_Awesome_File

user@machine: $

El resultado anterior proporciona mucha información sobre My_Awesome_File.

Conforme a las columnas que se muestran en la parte superior de la figura, la primera


columna (extremo izquierdo) del resultado anterior muestra los permisos asociados a
My_Awesome_File. Los permisos de archivos siempre se muestran en el orden Usuario,
Grupo y Otro, lo que significa que My_Awesome_File puede manejarse de la siguiente
manera:

 El usuario que posee el archivo puede leer (Read), escribir (Write) y ejecutar
(eXecute) el archivo. Esto se representa con el primer “rwx” (de izquierda a
derecha).

 El grupo que posee el archivo puede leer (Read) y escribir (Write) el archivo. Esto
se representa con “rw-”.
 Cualquier otro usuario o grupo del sistema solo puede leer (Read) el archivo. Esto
se representa con “r--”.

La segunda columna define el número de enlaces directos al archivo y no es importante


para el alcance de este curso.

La tercera y cuarta columna muestran el usuario y el grupo que poseen el archivo,


respectivamente. En este caso, el usuario rod y el grupo staff tienen un cierto nivel de
propiedad sobre el archivo.

La quinta columna muestra el tamaño del archivo en bytes. My_Awesome_File tiene


1 108 485 bytes o cerca de 1,1 MB.

La sexta columna muestra la fecha y la hora de la modificación más reciente.

La séptima columna muestra el nombre del archivo.

La figura muestra un desglose de los permisos de archivos en Linux.

Como mencionamos antes, los permisos de archivos son una parte fundamental de Linux y
no se pueden eliminar. Un usuario tiene tanto derecho a un archivo como el permiso del
archivo se lo permite. El único usuario que puede anular el permiso de un archivo en un
sistema Linux es el usuario raíz. Al tener el poder de anular los permisos de archivos, el
usuario raíz puede escribir a cualquier archivo. Dado que todo en Linux se trata como un
archivo, el usuario raíz tiene control total sobre el sistema Linux.

El permiso de archivo es un concepto simple, pero extremadamente importante para el


sistema Linux, dado que con los permisos de archivos el sistema estructura su seguridad y
definen sus límites. Un usuario común no puede modificar los archivos o los recursos que
no le pertenecen. Como consecuencia de esta característica inherente, con frecuencia se
requiere el acceso raíz antes de realizar tareas de mantenimiento y administrativas.

Nota: el usuario raíz también es conocido como superusuario.

La Figura 2 muestra algunas herramientas de línea de comandos administrativas.

La Figura 1 muestra un ejemplo de permisos de archivo de Linux que se explican en el


texto. La Figura 2 muestra los comandos administrativos de Linux que incluyen: “ls, que se
utiliza para mostrar los archivos dentro de un directorio. Las opciones comunes para Is
incluyen –l para enumerar los detalles del archivo y -a para enumerar los archivos ocultos.
Observe que las opciones pueden agruparse. cd, que se utiliza para cambiar el directorio
actual. Cuando se proporciona un nombre de directorio, cd intentará alcanzarlo mediante el
actual directorio como punto inicial. Si no se proporciona ningún nombre de directorio, cd
cambiará el actual directorio de inicio del usuario. mkdir, que se usa para crear un
directorio en el directorio actual. mkdir requiere el nombre del directorio nuevo como
parámetro. cp, que copia archivos del origen al destino. cp requiere dos parámetros:
ubicación de origen y nombre de archivo, y ubicación de destino y nombre de archivo. Si
solo se proporciona la ubicación de destino (sin ningún nombre de archivo de destino), cp
mantiene el nombre de archivo de origen. mv, que mueve los archivos a otro directorio. Al
igual que cp, mv también espera un origen y un destino como parámetros. Observe que, a
diferencia de cp, que crea una copia de los archivos y mantiene la versión original, mv
elimina los archivos originales de su ubicación. rm, que elimina los archivos. rm requiere
nombres de archivos como parámetros y también puede utilizarse para eliminar un
directorio. Para eliminar un directorio, también debe proporcionarse la opción –r. chmod,
que se utiliza para modificar los permisos de archivos. chmod espera que se configuren los
permisos para un archivo como parámetros, pero pueden proporcionarse en dos formatos.
Nota: para cambiar los permisos de un archivo, el usuario que ejecuta chmod debe tener
derechos de escritura sobre el archivo que se modificará. chown, que se utiliza para cambiar
la propiedad de un archivo. chown requiere el propietario nuevo como parámetro. Nota: por
razones de seguridad, Linux no permite que un usuario común elimine un archivo. En otras
palabras, solo el usuario raíz puede cambiar el propietario de un archivo. su, que se utiliza
para simular un inicio de sesión como otro usuario. su puede instruirse para que realice un
inicio de sesión completo o para que ejecute un comando como otro usuario. A menos que
el usuario raíz ejecute su, el sistema requerirá la contraseña del usuario raíz. sudo, que se
utilizada para ejecutar un comando único como usuario raíz u otro usuario. Tenga en cuenta
que, a diferencia de su, sudo no permite que un usuario se convierta en otro usuario. sudo
simplemente ejecuta un comando como otro usuario, generalmente el usuario raíz. Si el
usuario que ejecuta sudo no es el usuario raíz, el sistema pedirá una contraseña. Si están
autenticados, los demás comandos sudo publicados dentro de un período breve de tiempo
no requerirán una contraseña”.
Administradores de paquetes
Un administrador de paquetes (también denominado sistema de administrador de paquetes)
es un conjunto de herramientas de software diseñadas para facilitar la instalación, la
eliminación y la actualización de programas informáticos. Los programas informáticos
dependen de programas externos llamados bibliotecas para operar. Mantener tales
programas y sus bibliotecas manualmente no es escalable para un sistema con una gran
cantidad de programas instalados. Un administrador de paquetes puede ayudar a
automatizar el proceso y reducir los errores humanos.

Los diferentes sistemas operativos incluyen distintos administradores de paquetes. Debian y


sus derivados incluyen dpkg (administrador de paquetes Debian GNU/Linux). Para
automatizar el proceso aún más, los usuarios pueden utilizar apt como parte inicial para
dpkg. Red Hat Linux y sus derivados utilizan RPM (administrador de paquetes Red Hat)
como administrador de paquetes predeterminado para las distribuciones de Linux. Otro
administrador de paquetes popular es yum (actualizador Yellowdog modificado). Yum es
capaz de seguir automáticamente las dependencias de un paquete e instalarlas antes de
instalar el paquete.

Un administrador de paquetes generalmente incluye herramientas de usuario y un


repositorio de paquetes remoto. Las herramientas de usuario facilitan la administración de
paquetes y pueden ser CLI o GUI. El administrador de paquetes utiliza el repositorio
remoto para alojar los paquetes. Los administradores de paquetes son también muy útiles
para el versionamiento de paquetes, lo que permite a los usuarios actualizar o volver a la
versión anterior de un paquete o ignorar una versión de paquete específica.

Antes de realizar correctamente cualquier operación del paquete, el usuario debe


sincronizar el índice del repositorio local con el índice remoto (por ejemplo: “apt-get
update”). Un índice de repositorio es simplemente una lista de paquetes y sus últimas
versiones. Cuando se sincronizan los índices locales y remotos de repositorios, el sistema
puede compararlos con la versión actualmente instalada y recomendar actualizaciones.

Según la decisión del usuario de actualizar un paquete o no, el administrador de paquetes


descarga los paquetes necesarios. Si estos paquetes tienen paquetes de dependencias,
también se descargan. Una vez que la descarga se ha completado, el administrador de
paquetes los instala automáticamente.

Como Raspbian es un derivado de Debian, dpkg y apt se incluyen de forma


predeterminada. Instalar, eliminar y actualizar los paquetes en Raspberry Pi puede hacerse
fácilmente con algunos comandos simples.

Variables y declaraciones básicas


Blockly es una herramienta de programación visual creada para ayudar a los principiantes a
comprender los conceptos de programación. Mediante el uso de múltiples tipos de bloques,
Blockly permite que un usuario cree un programa sin introducir ninguna línea de código.

Blockly implementa la programación visual mediante la asignación de diferentes


estructuras de programas a bloques de color. Los bloques también contienen ranuras y
espacios que permiten que los programadores ingresen los valores requeridos por la
estructura. Los programadores pueden unir las estructuras de programación arrastrando y
asociando los bloques adecuados. Las estructuras de programación, como subordinadas,
bucles y variables, están todas disponibles para utilizar.

Una variable es una entidad de programación utilizada para almacenar datos. Básicamente,
una variable es una parte de la memoria que puede recibir un nombre legible para el
almacenamiento de datos y la recuperación. También se puede cambiar el contenido de una
variable mientras se ejecuta el programa.

Crear una nueva variable en Blockly es sencillo: se debe arrastrar el bloque variable al
espacio de trabajo y completar la ranura de valor. La figura muestra una variable de
Blockly.

Blockly también admite funciones. Al igual que las variables, Blockly tiene bloques
específicos para representar funciones. Asimismo, los programadores simplemente
seleccionan y arrastran los bloques de funciones al área del espacio de trabajo y completan
las ranuras requeridas.

Observe que el bloque de variables y la impresión en el bloque de la pantalla tienen una


ficha biselada en la parte inferior y una ranura en la parte superior. Esto significa que los
dos bloques pueden conectarse para crear una secuencia de programa. Blockly ejecutará
primero el bloque en la parte superior y continuará con el bloque en la parte inferior.

Otros bloques están disponibles, como el bloque IF - THEN, el bloque WHILE y el bloque
FOR. También hay bloques específicos para los sensores y los accionadores.

Por último, Blockly se puede utilizar para traducir el código basado en bloques en Python o
JavaScript. Esto es muy útil para los programadores principiantes.

Subordinada IF - THEN
La estructura subordinada IF - THEN se utiliza para permitir que el código tome
decisiones. Al probar la veracidad de una expresión, el programa pasará a la siguiente
declaración si la expresión se evalúa como falsa. Si la expresión es verdadera, la acción
THEN se ejecuta antes de pasar a la siguiente declaración del código.

El programa Blockly que se muestra en la Figura 1 representa un programa que determina


quién es la persona más grande de las dos. El programa solicita al usuario que introduzca la
edad de la primera persona y la almacena en una variable llamada PERSON1. Después el
programa solicita la edad de la segunda persona y la almacena en otra variable llamada
PERSON2. Por último, el programa compara las dos edades y publica cuál es la mayor de
las dos personas.

La Figura 2 muestra el código equivalente de Python.

Bucle FOR
El bucle FOR se utiliza para repetir la ejecución de un bloque específico de un código una
cantidad específica de veces. Es común utilizar el bucle FOR cuando la cantidad de
repeticiones se conoce de antemano.

El programa Blockly que se muestra en la figura utiliza el bucle FOR para determinar todos
los números primos entre 1 y 100. Los números primos son los números divisibles solo por
1 o por el número en sí y se publican en la pantalla, mientras que los números que no son
primos se ignoran.

El programa utiliza dos bucles FOR para calcular el resto de la división entre el número que
se evalúa y los números entre 2 y el número mismo. Si el resto de la división es cero, el
número no es un número primo. Si ninguna división produce un resto equivalente a cero,
entonces es un número primo. El programa publica el número primo en la pantalla y
continúa con la evaluación del siguiente número; solo se detiene cuando llega a 100.

El código de Blockly en la figura es: count with j from 1 to 100 by 1do if j > 1do count with i
from 2 to j by 1do et remainder to remainder of j + iif remainder = 0do break out of
loopelse Write on screen jPrint on screen "is a prime"

Bucle WHILE
El bucle WHILE se utiliza para ejecutar un bloque de códigos siempre que una condición
sea verdadera. El código en el bucle WHILE a menudo modifica las entidades y las
variables para finalmente hacer que la expresión sea falsa. Si la expresión comprobada por
WHILE nunca se torna falsa, el bucle se ejecuta continuamente y se denomina bucle
infinito. Por lo general, no se recomiendan bucles infinitos en la programación.

El programa Blockly que se muestra en la figura utiliza el bucle WHILE para crear un
juego de adivinanzas. El programa elije un número al azar entre 1 y 10 y solicita al usuario
que intente adivinarlo. El programa seguirá repitiendo la conjetura hasta que el usuario
adivine el número correcto.

Uso de Blockly para conocer Python


Python es un lenguaje muy común diseñado para ser fácil de leer y escribir. La comunidad
de desarrolladores de Python agrega valor al lenguaje creando todo tipo de módulos y
poniéndolos a disposición de otros programadores.

La filosofía base del lenguaje se resume en el documento Zen de Python:

 Hermoso es mejor que feo.

 Explícito es mejor que implícito.

 Simple es mejor que complejo.

 Complejo es mejor que complicado.

 La legibilidad es importante

A pesar del hecho de que Python está diseñado para ser simple, aún hay una curva de
aprendizaje. Para que conocer Python sea aún más fácil, un principiante puede utilizar
Blockly para mejorar la comprensión de Python.

Si bien los distintos lenguajes de programación tienen diferente semántica y sintaxis, todos
comparten la misma lógica de programación. Los principiantes pueden utilizar Blockly para
crear fácilmente un programa independiente del lenguaje, exportarlo como código de
Python y usar el código recientemente creado para aprender la sintaxis, la estructura y la
semántica de Python.

Las Figuras 1 y 2 muestran el programa del juego de adivinanzas en formatos de Blockly y


Python.

Interpretador de Python
Python es un lenguaje interpretado; por lo tanto, requiere un intérprete para analizar y
ejecutar el código de Python. El interpretador de Python comprende y ejecuta el código de
Python. El hecho de que el código de Python pueda crearse en cualquier editor de texto y
que los intérpretes de Python estén disponibles para muchos sistemas operativos permite
que los desarrolladores de Python creen e implementen los programas de Python
prácticamente en cualquier sistema operativo. Las herramientas de terceros, como Py2exe y
Pyinstaller, también pueden utilizarse para incluir el código fuente de Python en un
archivo ejecutable, lo que elimina la necesidad de intérpretes de Python al ejecutar el
código de Python.

En las máquinas Linux, el intérprete de Python está instalado generalmente en


/usr/bin/python o /usr/bin/python3 (según las versiones de Python disponibles en el
sistema). Con el nuevo instalador Windows de Python, Python se instala de manera
predeterminada en el directorio de inicio del usuario. En equipos Windows más antiguos,
Python se colocaba en C:\PythonXX (donde XX es la versión de Python). Una vez
instalado el intérprete de Python, funciona de manera similar al shell de Linux. Esto
significa que, cuando se llama sin argumentos, lee y ejecuta comandos de forma interactiva;
cuando se llama con un argumento de nombre de archivo o un archivo como entrada
estándar, lee y ejecuta una secuencia de dicho archivo.

Para iniciar el intérprete, simplemente escriba python o python3 en el indicador del shell.

Algunos sistemas heredados todavía se están ejecutando en una versión anterior de Python
2, pero muchos sistemas nuevos están migrando a la nueva versión 3 de Phyton. La versión
de Python está impresa en la primera línea cuando se inicia el intérprete (Figura 1). Este
curso se basa en código de Python 3 y aunque es bastante compatible con la versión
anterior Python 2, algunas funciones pueden tener diferente conducta.

Cuando se llama al intérprete de Python sin argumentos y los comandos se ingresan


mediante el teclado, el intérprete se dice que está en modo interactivo. En este modo, el
intérprete espera los comandos. El indicador principal está representado por tres signos
mayor que (>>>). Las líneas de seguimiento están representadas por tres puntos (...). La
línea de seguimiento es el indicador secundario predeterminado.

El indicador >>> indica que el intérprete está listo y espera los comandos.

Las líneas de seguimientos son necesarias al introducir un código multilínea. La Figura 2


muestra el bloque IF - THEN escrito en Python.

Otra forma de utilizar el intérprete es python -c command [arg] ... que ejecuta las
declaraciones en el comando. Como las declaraciones de Python suelen contener espacios u
otros caracteres determinados del shell, se recomienda incluir el comando completo entre
comillas simples.

Variables y declaraciones básicas en


Python
El intérprete recibe y ejecuta las declaraciones interactivamente.

El intérprete actúa como calculadora simple. Puede ingresar una expresión y escribirá el
valor. La sintaxis de la expresión es directa. Los operadores +, -, * y / funcionan al igual
que en la mayoría de los otros lenguajes (por ejemplo, Pascal o C). Los paréntesis (())
pueden utilizarse para agrupar, como se muestra en la Figura 1.

El modo interactivo de Python implementa la variable especial “_” para sostener el


resultado de la última expresión publicada, como se muestra en la Figura 2.
Las variables son áreas de memoria rotuladas que se utilizan para almacenar datos de
programas de tiempo de ejecución. Para asignar valores a las variables en Python, use el
signo = (igual). No se muestra ningún resultado antes del siguiente indicador interactivo,
como se muestra en la Figura 3.

Los intentos de utilizar una variable no definida (sin ningún valor asignado) resultarán en
un error, como se muestra en la Figura 4.

Las secuencias, definidas como secuencias de caracteres, también pueden manejarse desde
el modo interactivo. Utilice el carácter de barra invertida (“\”) para sustraerse de los
caracteres. Por ejemplo, una cadena que utiliza comillas dobles, pero que también necesita
utilizar una comilla doble dentro de la cadena. Si la cadena se ingresa de la siguiente
manera: "I really "need" this"., Python se confundirá y pensará que la primera comilla
doble dentro de la cadena finaliza realmente la cadena. Si coloca una barra invertida (\)
antes de las comillas dobles dentro de la cadena de la siguiente manera: "I really \"need\"
this", la barra invertida (\) hará que Python se sustraiga o ignore el carácter que sigue.

Las comillas simples o comillas dobles pueden utilizarse para envolver las cadenas, como
se muestra en la Figura 5.

La declaración de publicación publica el resultado de la expresión dada. Difiere de la


escritura simple de la expresión que se desea escribir (como hicimos anteriormente en los
ejemplos de cálculo) en la manera en que se administran las expresiones y cadenas
múltiples. Las cadenas se publican sin comillas y se inserta un espacio entre los elementos
para formatear las cosas correctamente, como se muestra en la Figura 6.

Las funciones son una parte importante de muchos lenguajes de programación. Las
funciones permiten que un bloque de códigos reciba un nombre y se vuelva a utilizar según
sea necesario. El siguiente ejemplo define una función para agregar dos números y publicar
el resultado, como se muestra en la Figura 7.

El código en la Figura 1 muestra “>>> >>> 25+ 2550>>> 70 + 7*6112>>> (50 - 5.0*6) /


45.0”. El código en la Figura 2 muestra “>>> >>> tax = 12.5 / 100>>> price = 100.50>>>
price * tax12.5625>>> price + _113.0625>>> round(_, 2)113.06”. El código en la Figura 3
muestra “>>> >>> birth_year = 1941>>> curr_year = 2016>>> curr_year - birth_year75”. El
código en la Figura 4 muestra “>>> >>> my_new_variableTraceback (most recent call last):
File "", line 1, in NameError: name 'my_new_variable' is not defined>>>”. El código en la
Figura 5 muestra “>>> >>> 'spam eggs' # single quotes'spam eggs'>>> 'doesn\'t' # use \' to
escape the single quote..."doesn't">>> "doesn't" # ...or use double quotes
instead"doesn't">>> '"Yes," he said.'"Yes," he said.>>> "\"Yes,\" he said."'"Yes," he said.”.
El código en la Figura 6 muestra “>>> >>> i = 256*256>>> print 'The value of i is', iThe
value of i is 65536”. El código en la Figura 7 muestra “# Function to add two numbers:def
add_nums(): a = 5 b = 11print add_num()”.

Funciones útiles y tipos de datos en Python


Python admite muchas funciones y tipos de datos útiles. Algunos de los más importantes
son los siguientes:

Range(): la función range() genera una lista de números utilizados generalmente para iterar
con los bucles FOR. La Figura 1 muestra ejemplos de la función range().

range(stop): cantidad de números enteros a generar desde cero.

range([start], stop[, step]: a partir del número de secuencia, genera números hasta dicho
número (sin incluirlo), diferenciando entre cada número en la secuencia.

Tuplas

Una tupla es una secuencia de objetos incambiables de Python. Las tuplas son secuencias
separadas por paréntesis. La Figura 2 muestra ejemplos de tuplas.

Listas

Las listas son una secuencia de objetos cambiables de Python. Las listas pueden crearse
configurando distintos valores separados por comas entre corchetes. La Figura 3 muestra
ejemplos de listas y cómo pueden actualizarse.

Conjuntos

Los conjuntos son colecciones no ordenadas de elementos exclusivos. Las aplicaciones


comunes incluyen pruebas de membresía, cancelaciones de duplicados de una secuencia y
cálculos de operaciones matemáticas estándar en conjuntos, como intersecciones, uniones,
diferencias y diferencias simétricas. La Figura 4 muestra ejemplos de paquetes.

Diccionario

Un diccionario es una lista de elementos separados por comas. Cada elemento es una
combinación de un valor y una clave única. Cada tecla se separa de su valor por dos puntos.
El diccionario completo se escribe entre llaves. Se puede acceder a, actualizar o eliminar
los elementos del diccionario. También hay muchas funciones integradas en el diccionario,
como la función que compara elementos dentro de diferentes diccionarios y la que
proporciona un conteo de la cantidad total de elementos de un diccionario. La Figura 5
muestra ejemplos de diccionarios.

El código en la Figura 1 muestra “# One parameterfor i in range(3): print (i)012# Two


parametersfor i in range(3, 6):    print (i)345# Three parametersfor i in range(4, 10, 2):
print (i)468”. El código en la Figura 2 muestra “tup1 = ('dancing', 'singing', 400, 1842); tup2
= (1, 2, 3, 4, 5, 6, 7 ); print "tup1[0]: ", tup1[0] print "tup2[1:5]: ", tup2[1:5] When the
above code is executed, it produces the following result −tup1[0]: dancing tup2[1:5]: (2, 3,
4, 5)”. El código en la Figura 3 muestra “list1 = ['car', 'train', 47, 2016];list2 = [1, 2, 3, 4, 5,
6, 7 ];print "list1[0]: ", list1[0]print "list2[1:5]: ", list2[1:5]When the above code is
executed, it produces the following result − list1[0]: car list2[1:5]: [2, 3, 4, 5]” and “list =
['car', 'train', 47, 2016];print "Value available at index 2 : " print list[2] list[2] = 2017; print
"New value available at index 2 : " print list[2] When the above code is executed, it
produces the following result −Value available at index 2 : 47 New value available at index
2 : 2017”. El código en la Figura 4 muestra “x = [1,2,3,1,2,3,1,2,3]set(x) {1, 2, 3}y = [1, 1, 6,
6, 6, 6, 6, 8, 8] set(y) {1, 6, 8}z = [("Bird", "Cat", "Dog", "Dog", "Bird", "Bird")] set(z) {('Bird',
'Cat', 'Dog', 'Dog', 'Bird', 'Bird')}” and “from sets import Setanimals = set(["Cow", "Fish",
"Pig", "Horse"])animals.add ("Cat")print animalsfor group in [animals]: group.discard
("Fish") print groupset(['Fish', 'Cat', 'Horse', 'Cow', 'Pig']) set(['Cat', 'Horse', 'Cow', 'Pig'])”.
El código en la Figura 5 muestra “dict = {'Age' : 34, 'City' : 'Rome', 'Year' : 2016, 'Month' :
'March' }print "dict['City']: ", dict['City']print "dict['Year']: ", dict['Year']dict['City']: Rome
dict['Year']: 2016” and “dict['Year'] = 2015print "dict['Year']: ", dict['Year']dict['Year']:
2015” and “dict['Sport'] = "Swimming"len(dict)5”.

Importación de módulos en el código


Salir del intérprete de Python y volver a ingresar elimina todas las definiciones efectuadas
previamente; las funciones y las variables se perderán en el proceso. Debido a esto, utilice
un editor de texto cuando cree un programa más largo o más complejo. Cuando el programa
esté listo, aliméntelo simplemente en el intérprete para ejecutarse. Con un editor de texto
utilizado de esta manera se crea un tipo de programa llamado secuencia. A medida que los
programas son más largos y más complejos, puede ser necesario dividirlos en programas
más pequeños para un mantenimiento más fácil. Con este enfoque, un programador creará
un programa principal que importe todos los programas más pequeños necesarios. Estos
programas más pequeños se denominan módulos.

Incluso si un programa no es largo o complejo, el programador aún puede beneficiarse con


la importación de un módulo existente en su programa. Un programador puede elegir
reutilizar una buena función ya escrita. Otra opción común es que los programadores
importen los módulos escritos por otra persona para agregar funcionalidad a su código o
mejorar su programa. Python tiene una comunidad grande y muy activa de desarrolladores
que han escrito y compartido módulos para muchas tareas.

La Figura 1 muestra un fragmento del código que crea un módulo de Python para calcular y
publicar la serie Fibonacci hasta el número N.

El código anterior se creó en un editor de texto y guardó como fibo.py. Ahora que el
módulo se ha creado y guardado en el disco, se puede importar a cualquier otro programa
de Python y alimentar al intérprete a través de la palabra clave import, como se muestra en
la Figura 2.

Observe que el intérprete no ejecuta el contenido de fibo.py, sino que sabe dónde encontrar
las funciones fib() y fib2(). Para usar el módulo y sus funciones, simplemente llámelos por
su nombre, como se muestra en la Figura 3.
Los módulos comunes que verá en IoT y en este curso incluyen los módulos de
procesamiento de datos (funciones matemáticas), los módulos de autoevaluación (nivel de
batería y prueba de memoria), los módulos de seguridad (hashes, cifrado/descifrado) y los
módulos de servidor de red y cliente (Web, FTP, NTP, etc.).

La Figura 4 muestra diferentes maneras de utilizar la función de importación.

IF - THEN en Python
Al igual que otros lenguajes, Python implementa la estructura IF - THEN. Los bloques IF -
THEN se pueden utilizar para permitir que el código tome decisiones según el resultado de
una expresión, como se muestra en la figura.

El código realiza algunas pruebas y publica un mensaje conforme a los resultados de la


prueba. Observe que Python también implementa dos subestructuras denominadas ELSE y
ELIF. ELSE permite al programador especificar instrucciones para ejecutar si la expresión
es falsa. La forma abreviada de ELSE IF, ELIF, se usa para realizar una segunda prueba en
caso de que la primera expresión sea falsa y se requiera otra prueba. Puede haber cero o
más ELIF y la parte ELSE es opcional.

Bucle FOR en Python


El bucle FOR en Python itera los elementos de cualquier secuencia (una lista o una cadena)
en el orden en que aparecen en la secuencia, como se muestra en la figura.

Bucle WHILE en Python


El bucle WHILE ejecuta un bloque de códigos si la expresión es verdadera. El programa a
continuación utiliza un bucle WHILE para calcular y publicar una subsecuencia inicial de
la serie Fibonacci, como se muestra en la figura.

La tercera línea contiene un operador de asignación múltiple. Las variables a y b obtienen


los nuevos valores de 0 y 1 en una única declaración.

El bucle WHILE calcula el término siguiente en la serie Fibonacci siempre que la condición
b < 10 sea verdadera. Como en C, Python asume cualquier valor del número entero que no
sea cero como verdadero y cero como falso. La prueba que se utiliza en la figura es una
comparación simple.

Observe que el cuerpo del bucle está indentado. La indentación es la forma en que Python
agrupa las declaraciones. En el indicador interactivo, debe escribir una ficha o espacio para
cada línea indentada. Las entradas más complejas de Python deben realizarse con un editor
de texto. Cuando una declaración compuesta se ingresa interactivamente, debe ir secundada
por una línea en blanco para indicar la finalización (porque el analizador no puede adivinar
qué línea será la última). Observe que cada línea dentro de un bloque básico se debe
indentar por la misma cantidad.

Páncreas artificial hecho con Raspberry Pi


Su tamaño pequeño y bajos requisitos de recursos hacen que Raspberry Pi sea como una
navaja suiza multiuso para IoT. Este tema explora algunos proyectos interesantes que
utiliza Raspberry Pi.

Dana Lewis ha vivido con diabetes tipo 1 desde los 14 años. El páncreas de las personas
con diabetes tipo 1 no produce suficiente insulina para administrar el azúcar en la
circulación sanguínea. Las personas como Dana deben supervisar y corregir los niveles de
insulina. Debido a que el monitor que utilizaba tenía muchos defectos, Dana y su esposo
decidieron utilizar Raspberry Pi para construir un páncreas artificial, como se muestra en la
figura.

Obtenga más información sobre el proyecto en: https://www.raspberrypi.org/blog/artificial-


raspberry-pi-pancreas/.

Robot Pi 4Borg
La figura muestra un equipo robótico asequible de los expertos en robótica de PiBorg. Es
educativo y divertido.

Obtenga más información sobre el proyecto en: https://www.raspberrypi.org/magpi/4borg-


robot-review/

Otro excelente ejemplo de automatización con Raspberry Pi se produjo en una granja de


pepinos en Japón. Se utilizó una cámara como sensor para procesar imágenes y
clasificarlas. Luego se usaron accionadores para seleccionar qué pepinos eran aceptables y
cuáles no. Este proceso ahorra al granjero entre ocho y nueve horas de trabajo manual por
día.

Obtenga más información sobre este proyecto en: https://www.raspberrypi.org/blog/now-


added-cucumbers/.

Control de Arduino a través de Pi


Si bien Raspberry Pi es una computadora eficaz y flexible, existen algunas tareas que no
administra bien. Esto se debe a que RaPi no cuenta con pines analógicos. Los sensores,
como los termómetros, los sensores de luz y los sensores de presión de aire, ofrecen señales
analógicas. Debido a que RaPi no se envía con pines analógicos, deben realizarse algunas
soluciones alternativas.

Otro ejemplo se relaciona con el tamaño; si bien RaPi es muy pequeña y tiene pocos
requisitos de energía, algunos proyectos pueden requerir controladores incluso más
pequeños. Para esas situaciones, puede ser mejor trabajar con un microcontrolador de
Arduino. Arduino también es pequeño y consume muy poca energía, pero incluye pines
analógicos. Esto hace que Arduino sea perfecto para trabajar con sensores y dispositivos
analógicos.

Puede conectar y controlar Arduino direc

Componentes del sistema


En el ejemplo del hogar inteligente, todos los dispositivos se conectan al gateway del hogar.
El gateway del hogar actúa como concentrador para todos los dispositivos, proporcionando
conectividad cableada e inalámbrica. También en el gateway doméstico se crea y aloja la
interfaz web para permitir que los usuarios controlen y monitoreen todos los dispositivos
conectados.

La Figura 1 muestra una captura de pantalla de la ventana del gateway doméstico.

En el modelo, los sensores monitorean el entorno y garantizan que los valores permanezcan
dentro de un umbral predefinido. Si el valor monitoreado supera el umbral definido, se
toman medidas. El detector de humo, un sensor que monitorea los niveles de CO2 en el
hogar, tiene un valor predefinido de 0,4. Si el nivel medido supera 0,4, la alarma se
desactiva. El detector de humo no tiene ninguna funcionalidad controlada por el usuario,
simplemente responde al entorno.

Las conexiones de red entre el gateway doméstico y otros dispositivos de red también están
representadas. Observe cómo el gateway doméstico se conecta a un cable módem que, a su
vez, se conecta a un divisor. El divisor divide la señal proveniente del ISP y envía señales
de televisión por cable al televisor y datos al cable módem. El par de cable módem y
divisor es lo que proporciona conectividad de Internet al gateway doméstico y al hogar
entero.

Nota: si bien PT 7.0 es potente y flexible, varios sensores y accionadores pueden tener
diferentes conexiones. PT 7.0 implementa Ethernet por cable e inalámbrica, pero no
implementa otras conexiones posibles.

Código de la SBC en Packet Tracer


PT 7.0 además presenta una computadora de una sola placa (SBC) y una unidad de
microcontrolador (MCU).
La computadora de una sola placa es una computadora diseñada para adaptarse a todos sus
componentes, como almacenamiento, memoria y E/S dentro de una sola placa. Un buen
ejemplo de SBC es Raspberry Pi. Las SBC son comunes en las soluciones de IoT porque se
utilizan para ejecutar un código y agregar inteligencia a los dispositivos diarios. Una SBC
de PT es un dispositivo de PT creado para simular una SBC mediante la proporción de
capacidades de ejecución de códigos y ciertas conexiones. Específicamente, una SBC de PT
proporciona 2 puertos USB y 10 puertos de E/S digital que se pueden utilizar para conectar
sensores y dispositivos de IoT. Una SBC de PT tiene un intérprete de Python incorporado
que le permite al código nativo de Python escribirse y ejecutarse directamente en el
dispositivo. Puede accederse al intérprete de Python mediante la ficha de programación de
la SBC de PT.

La Figura 1 muestra una captura de pantalla de la ventana de la SBC de PT y la ficha


Configuración.

Una unidad de microcontrolador (MCU) es una pequeña computadora incorporada a un


sistema en un chip (SoC). Es similar a una SBC, pero contiene menos potencia de
procesamiento y funcionalidad. Contiene un núcleo de procesador, una memoria y unidades
periféricas programables de entrada/salida. Los microcontroladores están diseñados para las
aplicaciones incorporadas o las aplicaciones que requieren pocos recursos de computadora.
Algunos ejemplos de aplicaciones que dependen de microcontroladores son sistemas de
control de motores automotrices, dispositivos médicos implantables, controles remotos,
máquinas de oficinas y electrodomésticos. Los microcontroladores de señales combinadas
también son comunes e integran componentes analógicos necesarios para controlar los
sistemas electrónicos no digitales. PT 7.0 brinda soporte al emulador de MCU. Un usuario
puede programar la MCU de PT para que realice tareas similares a las MCU del mundo
real. Para simplificar el proceso, la MCU de PT además puede programarse con Python. La
MCU de PT tiene un puerto USB, seis puertos de E/S digital y cuatro puertos de E/S
analógica. Los puertos de E/S digital en la MCU de PT permiten que un usuario conecte
accionadores y sensores digitales. Los puertos de E/S analógica permiten que un usuario
conecte accionadores y sensores analógicos.

La Figura 2 muestra una captura de pantalla de la ventana de la MCU de PT.

Desde una perspectiva de simulación, la SBC de PT y la MCU de PT difieren muy poco


entre sí. Específicamente, la SBC de PT puede alojar archivos y tiene una ficha Escritorio
con varias aplicaciones, como navegador web y cliente de correo electrónico. La MCU del
PT no aloja archivos ni tiene una ficha Escritorio.

Nota: si bien no es común encontrar Python en las MCU en la vida real, PT 7.0 implementa
el soporte de Python para comodidad de los usuarios.

También podría gustarte