Lenguajes de Programación

Entre los distintos lenguajes de programación disponibles para elaborar proyectos de Electrónica, Robótica e IOT se pueden mencionar los siguientes.

Assembler

Uno de los lenguajes de bajo nivel más emblemáticos. Se recomienda para entornos de recursos muy limitados y donde la eficiencia sea escencial. Es especialmente bueno para usarlo junto al microcontrolador PIC16f877a.

Si bien usar C es posible para reemplazar a Assembler en una gran variedad de casos de uso, el utilizar Assembler permite una granularidad exacta y fina sobre el uso de memoria del microcontrolador, logrando programas que puedan exprimir todo el potencial del mismo.

Encender un Led para PIC16f877a, fuente: ("PIC Assembly Code Examples" 2017)
list p=16f84a
include
COUNT1 EQU 08h
COUNT2 EQU 09h

org 0x00
goto start

start bsf STATUS, RP0 ;bank 1
movlw 0xFE
movwf TRISB ;set all PORTB input except for RB0
bcf STATUS, RP0 ;bank 0

main bsf PORTB, 0 ;make RB0 high
call delay ;delay subroutine
bcf PORTB, 0 ;make RB0 low
goto main

delay
loop1 decfsz COUNT1,1 ;decrement COUNT1 variable until zero
goto loop1
decfsz COUNT2,1 ;decrement COUNT2, if not zero, go back to loop1
goto loop1
return
end

C y C++

El lenguaje de programación C es uno de los lenguajes de programación más antiguos y populares. Fue desarrollado por Dennis Ritchie en los laboratorios Bell en la década de 1970 como parte del sistema operativo UNIX. Desde entonces, ha sido ampliamente utilizado en una variedad de aplicaciones, desde sistemas operativos hasta aplicaciones de usuario y juegos.

C es conocido por su eficiencia y su capacidad para acceder directamente a las funciones del sistema operativo y al hardware de la computadora. Es un lenguaje de programación de nivel medio, lo que significa que combina características de lenguajes de programación de bajo nivel, como la capacidad de manipular directamente la memoria, con características de lenguajes de alto nivel, como estructuras de datos avanzadas y abstracciones de programación.

Uno de los aspectos más destacados de C es su sintaxis clara y concisa, lo que lo hace relativamente fácil de leer y escribir. Sin embargo, también es un lenguaje poderoso y flexible que permite a los programadores realizar una amplia variedad de tareas, desde el desarrollo de sistemas operativos hasta la creación de aplicaciones de usuario. (Vieito, 2024)

C++ fue creado por Bjarne Stroustrup en 1979 como una extensión del lenguaje C, con la intención de añadir mecanismos orientados a objetos. Inicialmente llamado "C con clases", posteriormente se adoptó el nombre C++ en 1983. El objetivo era combinar la eficiencia de C con la capacidad de modelar problemas complejos usando objetos. ("Historia e Introducción de C++" n.d.)

Encender un Led para PIC16f877a, fuente: ("Microside" n.d.)
#include <16F877A.h>                // Incluye el microcontrolador con el que se va a trabajar
#use delay(clock=20Mhz, crystal)    // Tipo de oscilador y frecuencia dependiendo del microcontrolador

#define LED PIN_A1                  // Pin donde está conectado el LED del X-TRAINER

void main(void) {
   set_tris_a(0xFD);                // Pin RA1 como salida

   while(1) {
      output_HIGH (LED);            // Cambio de estado en el pin RA1
      delay_ms (500);               // Retardo
      output_LOW (LED);             // Cambio de estado en el pin RA1
      delay_ms (500) ;              // Retardo
   }
}

Ada

En la década de 1970, el Departamento de Defensa de los Estados Unidos (DOD) sufrió una explosión en la cantidad de lenguajes de programación, con diferentes proyectos utilizando distintos dialectos no estándar o subconjuntos/superconjuntos de lenguajes. El DOD decidió resolver este problema emitiendo una solicitud de propuestas para un lenguaje de programación común y moderno. La propuesta ganadora fue presentada por Jean Ichbiah, de CII Honeywell-Bull.

El primer estándar de Ada se publicó en 1983; posteriormente fue revisado y mejorado en 1995, 2005, 2012 y 2022, con cada revisión incorporando características nuevas y útiles.

Ada es un lenguaje de programación muy bien diseñado y una excelente alternativa a C, C++ y Rust, en el sentido de que toma las grandes y monolíticas características de otros lenguajes y las descompone en sus partes constituyentes, de modo que puedes elegir qué porciones de esas características deseas usar.

Ada descompone la programación orientada a objetos en características separadas como: encapsulamiento, reutilización, herencia, y despacho dinámico. En Ada, puedes optar por cada una de esas cosas por separado, dependiendo de para qué necesitas la "programación orientada a objetos". Esto contrasta mucho con Java, donde escribes la palabra clave “class” y todo eso viene incluido automáticamente.

Hoy en día, Ada se utiliza ampliamente en sistemas incrustados en tiempo real, muchos de los cuales son críticos para la seguridad. Aunque Ada puede usarse como un lenguaje de propósito general, realmente destaca en aplicaciones de bajo nivel:

  • Sistemas incrustados con requisitos de poca memoria (no se permite recolector de basura).

  • Interfaz directa con hardware.

  • Sistemas en tiempo real, ya sean blandos o estrictos.

  • Programación de sistemas de bajo nivel.

Algunos dominios específicos donde se utiliza Ada incluyen el aeroespacial y defensa, aviación civil, ferrocarriles, entre muchos otros.

Ada es una excelente alternativa para la programación de microcontroladores del tipo ARM Cortex-M como Arduino.

Los sistemas incrustados que carecen de una unidad de punto flotante representan un problema para los programadores en C, ya que las dos clasificaciones de tipos primitivos en C son tipos enteros y tipos de punto flotante. La ausencia de un procesador de punto flotante en un sistema incrustado requiere que todas las representaciones y operaciones en punto flotante se implementen por software en lugar de hardware. Esta limitación incrementa el tamaño del software de punto flotante en C y reduce la velocidad de cálculo de las operaciones de punto flotante.

Ada proporciona tipos enteros, tipos de punto flotante y tipos de punto fijo. Los tipos de punto fijo pueden sustituirse fácilmente por tipos de punto flotante en sistemas que carecen de un procesador de punto flotante. Las operaciones con punto fijo utilizan el procesador de enteros del hardware y no requieren espacio de memoria para una mantisa y un exponente.

Ada cuenta con facilidades integradas para enlazarse con bibliotecas en C o C+\+, lo que permite que los programas en Ada interactúen con bibliotecas del procesador escritas en C.

Ada facilita la programación incrustada con menos esfuerzo por parte del programador que el requerido para implementar los mismos datos y comportamientos usando C.

(“Ada Core Documentation",” n.d.)

Encender un Led con Ada, fuente: https://github.com/kylelk/blink-example/
with GPIO;
with Ada.Text_IO;

procedure main is
   package TIO renames Ada.Text_IO;

   Pin_Num     : constant GPIO.Pin_Number := 0;
   Button_Pin  : constant GPIO.Pin_Number := 1;
   Blink_Delay : constant Float           := 0.25;

   type LED_Modes is (LED_Off, LED_Blink, LED_On);

   task type Blinking_Light is
      entry Mode (Mode_Value : LED_Modes);
   end Blinking_Light;

   task body Blinking_Light is
      Current_Mode : LED_Modes := LED_Off;
   begin
      loop
         select
            accept Mode (Mode_Value : LED_Modes) do
               Current_Mode := Mode_Value;
            end Mode;
         else
            if Current_Mode = LED_Off then
               GPIO.Digital_Write (Pin_Num, GPIO.Low);

            elsif Current_Mode = LED_Blink then
               GPIO.Digital_Write (Pin_Num, GPIO.High);
               delay Duration (Blink_Delay);
               GPIO.Digital_Write (Pin_Num, GPIO.Low);
               delay Duration (Blink_Delay);

            elsif Current_Mode = LED_On then
               GPIO.Digital_Write (Pin_Num, GPIO.High);
            end if;

         end select;
      end loop;
   end Blinking_Light;

   Light      : Blinking_Light;
   Light_Mode : LED_Modes := LED_Off;
   Down_Press : Boolean   := True;

   procedure Button_Clicked is
   begin
      if Down_Press then
         TIO.Put_Line ("button clicked " & LED_Modes'Image (Light_Mode));
         Light.Mode (Light_Mode);
         if Light_Mode = LED_Modes'Last then
            Light_Mode := LED_Modes'First;
         else
            Light_Mode := LED_Modes'Val (LED_Modes'Pos (Light_Mode) + 1);
         end if;
      end if;
      Down_Press := not Down_Press;
   end Button_Clicked;

begin
   GPIO.Setup;
   GPIO.Pin_Mode (Pin_Num, GPIO.Output);
   GPIO.Pin_Mode (Button_Pin, GPIO.Input);

   -- register button callback
   GPIO.Pin_Interrupt (Button_Pin, GPIO.Edge_Both, Button_Clicked'Access);
end main;

Erlang y Elixir

El ESP32 típico viene con 520 KB de RAM y 4 MB de almacenamiento flash, aproximadamente las especificaciones de una computadora de escritorio de mediados de los años 80. Además, la mayoría de los entornos de microcontroladores no admiten APIs POSIX nativas para interactuar con un sistema operativo y, en muchos casos, las abstracciones comunes de un sistema operativo, como procesos, hilos o archivos, simplemente no están disponibles.

Sin embargo, dado que la BEAM proporciona un entorno de multitarea con planificación preventiva (pre-emptive), muchas de las abstracciones comunes de los sistemas operativos, especialmente las relacionadas con hilos y concurrencia, simplemente no son necesarias. Como lenguajes orientados a la concurrencia, Erlang y Elixir admiten “procesos” ligeros, con el paso de mensajes como mecanismo para la comunicación entre procesos (de Erlang), multitarea con planificación preventiva, y asignación de memoria y recolección de basura por proceso.

En muchos aspectos, el modelo de programación de Erlang y Elixir se asemeja más al de un sistema operativo con múltiples procesos concurrentes ejecutándose en él, donde los procesos del sistema operativo son unidades individuales de ejecución, se comunican mediante el paso de mensajes (señales) y no comparten estado entre sí.

Esto contrasta con la mayoría de los lenguajes de programación populares en la actualidad (C, C++, Java, Python, etc.), que utilizan abstracciones de hilos para lograr concurrencia dentro de un único espacio de memoria, y que, por lo tanto, requieren especial atención en los casos en que múltiples CPUs operan sobre una región de memoria compartida, lo cual exige el uso de hilos, bloqueos, semáforos, etc.

La BEAM permite desarrollar aplicaciones en dispositivos pequeños (AtomVM). Esto hace que escribir código concurrente para microcontroladores (por ejemplo, una aplicación que lea datos de sensores, atienda solicitudes HTTP y actualice el reloj del sistema, todo al mismo tiempo) sea increíblemente simple y natural, mucho más fácil que escribir programas concurrentes en C, C++ o incluso, por ejemplo, en MicroPython (“Welcome to AtomVM! — AtomVM Documentation,” n.d.).

Ejemplo de Blinky en Erlang
-module(blinky).
-export([start/0]).

-define(PIN, 2).

start() ->
    gpio:set_pin_mode(?PIN, output),
    loop(?PIN, low).

loop(Pin, Level) ->
    io:format("Setting pin ~p ~p~n", [Pin, Level]),
    gpio:digital_write(Pin, Level),
    timer:sleep(1000),
    loop(Pin, toggle(Level)).

toggle(high) ->
    low;
toggle(low) ->
    high.

Otros

Existen otras alternativas válidas como: