Arduino en lenguaje C. lenguaje de programación arduino

El lenguaje de programación Arduino para principiantes se presenta en detalle en la siguiente tabla. El microcontrolador Arduino está programado en un lenguaje de programación especial basado en C/C++. El lenguaje de programación Arduino es una variante de C++, es decir, no existe un lenguaje de programación independiente para Arduino. Puedes descargar el libro en PDF al final de la página.

En el IDE de Arduino, todos los bocetos escritos se compilan en un programa en C/C++ con cambios mínimos. El compilador Arduino IDE simplifica enormemente la escritura de programas para esta plataforma y la creación de dispositivos en Arduino se vuelve mucho más accesible para personas que no tienen amplios conocimientos del lenguaje C/C++. A continuación daremos una breve referencia que describe las funciones principales del lenguaje Arduino con ejemplos.

Referencia detallada al lenguaje Arduino.

El lenguaje se puede dividir en cuatro secciones: declaraciones, datos, funciones y bibliotecas.

lenguaje arduino Ejemplo Descripción

Operadores

configuración() configuración nula()
{
pinMode(3, ENTRADA);
}
La función se utiliza para inicializar variables, determinar los modos de funcionamiento de los pines del tablero, etc. La función se ejecuta solo una vez, después de cada suministro de energía al microcontrolador.
bucle() bucle vacío()
{
escritura digital (3, ALTA);
retraso(1000);
escritura digital (3, BAJO);
retraso(1000);
}
La función de bucle realiza un bucle, lo que permite que el programa realice y reaccione a los cálculos. Las funciones setup() y loop() deben estar presentes en cada boceto, incluso si estas declaraciones no se utilizan en el programa.

Declaraciones de control

si
si(x>
si(x< 100) digitalWrite (3, LOW );
La declaración if se usa en combinación con operadores de comparación (==, !=,<, >) y comprueba si la condición es verdadera. Por ejemplo, si el valor de la variable x es mayor que 100, entonces el LED en la salida 13 se enciende; si es menor, el LED se apaga.
si...si no
si (x > 100) escritura digital (3, ALTA);
de lo contrario escritura digital (3, BAJO);
El operador else le permite realizar una verificación distinta a la especificada en if, para poder realizar varias verificaciones mutuamente excluyentes. Si ninguna de las comprobaciones recibe un resultado VERDADERO, entonces se ejecuta el bloque de declaraciones en else.
interruptor... caso
cambiar(x)
{


caso 3: ruptura;

}
Al igual que una declaración if, una declaración switch controla un programa permitiéndole especificar acciones que se realizarán en diferentes condiciones. Break es un comando para salir de una declaración; por defecto se ejecuta si no se selecciona ninguna alternativa.
para configuración nula()
{
pinMode(3, SALIDA);
}
bucle vacío()
{
para (int i=0; i<= 255; i++){
escritura analógica(3, i);
retraso(10);
}
}
La construcción for se utiliza para repetir declaraciones encerradas entre llaves. Por ejemplo, la atenuación suave de un LED. El encabezado del bucle for consta de tres partes: for (inicialización; condición; incremento): la inicialización se realiza una vez, luego se verifica la condición, si la condición es verdadera, se realiza el incremento. El ciclo se repite hasta que la condición se vuelve falsa.
mientras bucle vacío()
{
mientras(x< 10)
{
x = x + 1;
Serie.println(x);
retraso(200);
}
}
La declaración while se utiliza como un bucle que se ejecutará siempre que la condición entre paréntesis sea verdadera. En el ejemplo, la instrucción del bucle while repetirá el código entre paréntesis sin cesar hasta que x sea menor que 10.
hacer... mientras bucle vacío()
{
hacer
{
x = x + 1;
retraso(100);
Serie.println(x);
}
mientras(x< 10);
retraso(900);
}
La instrucción del bucle do... while funciona de la misma manera que el bucle while. Sin embargo, si la expresión entre paréntesis es verdadera, el ciclo continúa en lugar de salir del mismo. En el ejemplo anterior, si x es mayor que 10, la operación de suma continuará, pero con una pausa de 1000 ms.
romper
continuar
cambiar(x)
{
caso 1: escritura digital (3, ALTA);
caso 2: escritura digital (3, BAJO);
caso 3: ruptura;
caso 4: continuar;
predeterminado: escritura digital (4, ALTA);
}
Break se utiliza para forzar la salida de los bucles switch, do, for y while sin esperar a que se complete el bucle.
La declaración de continuación omite las declaraciones restantes en el paso del bucle actual.

Sintaxis

;
(punto y coma)

escritura digital (3, ALTA);
Se utiliza un punto y coma para marcar el final de una declaración. Olvidar un punto y coma al final de una línea produce un error de compilación.
{}
(tirantes)
configuración nula()
{
pinMode(3, ENTRADA);
}
El paréntesis de apertura “(” debe ir seguido del paréntesis de cierre “)”. Los paréntesis no coincidentes pueden provocar errores ocultos e ininteligibles al compilar un boceto.
//
(comentario)
x = 5; // comentario

Lo primero que debe comenzar a dominar Arduino es comprar una placa de depuración (sería bueno comprar inmediatamente una placa de circuito, etc.). Ya he descrito qué tipos de placas Arduino hay en el mercado. Si aún no has leído el artículo, te recomiendo que lo leas. Para aprender los conceptos básicos, elegimos una placa Arduino Uno estándar (el original o una buena copia china, tú decides). Al conectar la placa original por primera vez, no debería haber problemas, pero con la "china" tendrás que profundizar un poco más (no te preocupes, te lo mostraré y te lo contaré todo).

Conectamos el Arduino al ordenador con un cable USB. El LED en el tablero debería encenderse. EN". Aparecerá un nuevo dispositivo en el Administrador de dispositivos " Dispositivo desconocido". Necesita instalar el controlador. Aquí agregaré un pequeño ambigüedad(el gato estaba distraído; no recuerdo qué conductor decidió " problema de dispositivo desconocido».

Primero descargué y descomprimí el entorno de software Arduino ( arduino-1.6.6-ventanas). Luego descargué este. Es autoextraíble. Lanzó el archivo CH341SER.EXE. Seleccionado instalación (INSTALAR). Después de la instalación, apareció un mensaje, se hizo clic en " DE ACUERDO"(no tuve tiempo de leerlo).

Luego fui a las propiedades del todavía "dispositivo desconocido" y seleccioné el botón "Actualizar controlador". Seleccioné la opción "Instalar desde una ubicación específica"; indiqué la carpeta con el entorno de software Arduino descomprimido. Y he aquí, todo funcionó correctamente...

Lanzamos el programa Arduino (en mi caso 1.6.6) y permitimos el acceso.

Todos los proyectos (programas) para Arduino constan de dos partes: configuración vacía Y bucle vacío. configuración vacía se realiza una sola vez y bucle vacío se hace una y otra vez.

Antes de continuar, hay dos operaciones obligatorias que deben completarse:

— indique en el entorno del software Arduino qué placa está utilizando. Herramienta->tablero->Arduino Uno. Si la marca ya está en el tablero que necesita, está bien; si no, póngala.

— especifique en el entorno del software qué puerto serie utiliza para comunicarse con la placa. Herramienta->puerto->COM3. Si la marca ya está en el puerto, está bien, si no, pon una marca. Si tiene más de un puerto en la sección de puertos, ¿cómo puede saber cuál se utiliza para conectarse a la placa? Tomamos el tablero y desconectamos el cable. Volvemos a los puertos y vemos cuál ha desaparecido. En mi caso, la pestaña "Puertos" quedó inactiva.

Vuelva a conectar el cable USB.

El primer programa no requiere ningún módulo adicional. Encenderemos el LED, que ya está montado en la placa (en el pin 13 del microcontrolador).

Primero, configuremos el pin 13 (entrada o salida).

Para ello ingresa al bloque “ configuración vacía" equipo modo pin , indicamos los parámetros entre paréntesis (13, SALIDA) (Qué pin está involucrado, modo de funcionamiento). El entorno del software resalta palabras/comandos con el color de fuente apropiado.

Ir al bloque " bucle vacío"e ingrese el comando escritura digital con parametros (13, ALTO) .


El primer programa está listo, ahora solo queda cargarlo en el microcontrolador. Haga clic en el botón CARGAR.

El LED se encendió. Pero no seas tan escéptico acerca de la simplicidad del primer programa. Acabas de dominar el primer comando de control. En lugar de un LED, puedes conectar cualquier carga (ya sea la iluminación de una habitación o un servoaccionamiento que corta el suministro de agua), pero hablaremos de todo esto más adelante...

Encendimos el LED, brilló un poco, es hora de apagarlo. Para hacer esto, modifiquemos el programa que escribimos. En lugar de " ALTO "vamos a escribir" BAJO ».


Haga clic en el botón CARGAR. El LED se apagó.

Ya nos hemos familiarizado con el concepto de "", es hora de utilizarlo. Otros programas serán cada vez más voluminosos y complejos, y trabajar para cambiarlos llevará cada vez más tiempo si continuamos escribiendo código como este.

Miramos el programa (volvemos a encender el LED). Configuremos el número de pin del microcontrolador no como un número 13 , sino una variable a la que se le asignará el valor de la salida correspondiente (en nuestro caso, 13). En el futuro, será muy conveniente cambiar los valores de las variables al inicio del programa, en lugar de hurgar en el código en busca de aquellos lugares donde es necesario cambiar los valores.

Crear una variable global int LED_pin = 13; (tipo de variable, nombre de variable, valor asignado a ella).


Haga clic en el botón CARGAR. El LED se enciende. Todo funciona muy bien.

En esta lección, además de encender/apagar el LED, también aprenderemos a hacer parpadear.

Para hacer esto, ingrese el segundo comando “ escritura digital» con parametros (LED_pin, BAJO).


Haga clic en el botón CARGAR. ¿Y qué vemos? El LED brilla "al máximo". La razón radica en el hecho de que el tiempo de conmutación de dos estados ( ALTO Y BAJO ) es insignificante y el ojo humano no puede detectar estos interruptores. Es necesario aumentar el tiempo que el LED permanece en uno de los estados. Para ello escribimos el comando demora con parámetro (1000 ) . Retraso en milisegundos: 1000 milisegundos – 1 segundo. El algoritmo del programa es el siguiente: enciende el LED - espera 1 segundo, apaga el LED - espera 1 segundo, etc.


Haga clic en el botón CARGAR. El LED comenzó a parpadear. Todo funciona.

Finalicemos el programa creando una variable a la que se le asignará un valor responsable de la duración del retraso.


Haga clic en el botón CARGAR. El LED parpadea como antes.

Finalicemos el programa que escribimos. Las tareas son las siguientes:

  • El LED está encendido durante 0,2 segundos y apagado durante 0,8 segundos;
  • El LED está encendido durante 0,7 segundos y apagado durante 0,3 segundos.

El programa creó 2 variables que son responsables de los retrasos de tiempo. Uno determina el tiempo de funcionamiento del LED encendido y el segundo, el tiempo de funcionamiento del LED apagado.

Gracias por su atención. ¡Nos vemos pronto!

¿En qué consiste el programa?

Para empezar, conviene entender que un programa no se puede leer ni escribir como un libro: de principio a fin, de arriba a abajo, línea por línea. Cualquier programa consta de bloques separados. El comienzo de un bloque de código en C/C++ se indica con una llave izquierda (, su final con una llave derecha).

Hay diferentes tipos de bloques y cuál se ejecutará cuando depende de las condiciones externas. En el programa mínimo de ejemplo puedes ver 2 bloques. En este ejemplo los bloques se llaman definiendo una función. Una función es simplemente un bloque de código con un nombre de pila que alguien puede usar desde afuera.

En este caso, tenemos 2 funciones llamadas configuración y bucle. Su presencia es obligatoria en cualquier programa C++ para Arduino. Puede que no hagan nada, como en nuestro caso, pero deben estar escritos. De lo contrario, obtendrá un error en la etapa de compilación.

Clásico del género: LED intermitente

Ahora complementemos nuestro programa para que al menos algo suceda. En Arduino, se conecta un LED al pin 13. Se puede controlar, que es lo que haremos.

configuración vacía() ( pinMode(13, SALIDA); ) bucle vacío() ( digitalWrite(13, ALTO); retraso(100); digitalWrite(13, BAJO); retraso(900); )

Compile y descargue el programa. Verás que el LED de la placa parpadea cada segundo. Averigüemos por qué este código hace que parpadee cada segundo.

Cada expresión es una orden para que el procesador haga algo. Las expresiones dentro de un bloque se ejecutan una tras otra, estrictamente en orden, sin pausas ni cambios. Es decir, si hablamos de un bloque de código específico, se puede leer de arriba a abajo para comprender lo que se está haciendo.

Ahora comprendamos en qué orden se ejecutan los bloques, es decir, Funciones de configuración y bucle. No se preocupe por el significado de expresiones específicas todavía, simplemente observe el orden.

    Tan pronto como se enciende el Arduino, parpadea o se presiona el botón RESET, “algo” llama a una función configuración. Es decir, obliga a ejecutar las expresiones que contiene.

    Tan pronto como se completa la configuración, "algo" llama inmediatamente a la función de bucle.

    Tan pronto como se completa el bucle, "algo" inmediatamente llama a la función de bucle nuevamente y así hasta el infinito.

Si numeramos las expresiones en orden de ejecución, obtenemos:

configuración vacía () (pinMode (13, SALIDA); ❶) bucle vacío () (escritura digital (13, ALTA); ❷ ❻ ❿ retraso (100); ❸ ❼ … escritura digital (13, BAJO); ❹ ❽ retraso (900) ; ❺ ❾ )

Permítanos recordarle una vez más que no debe intentar percibir todo el programa leyendo de arriba a abajo. Sólo se lee el contenido de los bloques de arriba a abajo. Generalmente podemos cambiar el orden de las declaraciones de configuración y bucle.

bucle vacío () (escritura digital (13, ALTO); ❷ ❻ ❿ retraso (100); ❸ ❼ … escritura digital (13, BAJO); ❹ ❽ retraso (900); ❺ ❾) configuración vacía () (pinMode (13, SALIDA) ) ; ❶ )

El resultado no cambiará ni un ápice: después de la compilación obtendrás un archivo binario absolutamente equivalente.

¿Qué hacen las expresiones?

Ahora intentemos comprender por qué el programa escrito finalmente hace que el LED parpadee.

Como sabes, los pines de Arduino pueden funcionar como salidas y entradas. Cuando queremos controlar algo, es decir, emitir una señal, necesitamos cambiar el pin de control al estado de salida. En nuestro ejemplo, controlamos el LED en el pin 13, por lo que el pin 13 debe tener una salida antes de su uso.

Esto se hace mediante una expresión en la función de configuración:

PinMode(13, SALIDA);

Las expresiones pueden ser diferentes: aritmética, declaraciones, definiciones, condicionales, etc. En este caso implementamos en la expresión llamada de función. ¿Recordar? Tenemos su las funciones de configuración y bucle, que son llamadas por algo que llamamos "algo". Así que ahora Nosotros llamamos funciones que ya están escritas en alguna parte.

Específicamente en nuestra configuración llamamos a una función llamada pinMode. Establece el pin especificado por número en el modo especificado: entrada o salida. Indicamos de qué pin y de qué modo estamos hablando entre paréntesis, separados por comas, inmediatamente después del nombre de la función. En nuestro caso, queremos que el pin 13 actúe como salida. SALIDA significa salida, ENTRADA significa entrada.

Los valores calificados como 13 y SALIDA se denominan argumentos de función. No es en absoluto necesario que todas las funciones tengan 2 argumentos. La cantidad de argumentos que tiene una función depende de la esencia de la función y de cómo la escribió el autor. Puede haber funciones con un argumento, tres, veinte; Las funciones no pueden tener ningún argumento. Luego para llamarlos se abre el paréntesis e inmediatamente se cierra:

Sin interrupciones();

De hecho, habrás notado que nuestras funciones de configuración y bucle tampoco aceptan ningún argumento. Y el misterioso “algo” los llama de la misma manera con paréntesis vacíos en el momento adecuado.

Volvamos a nuestro código. Entonces, dado que planeamos hacer parpadear el LED para siempre, el pin de control debe tener una salida una vez y luego no queremos recordarlo. Esto es para lo que está ideológicamente destinada la función de configuración: configurar el tablero según sea necesario y luego trabajar con él.

Pasemos a la función de bucle:

bucle vacío() (escritura digital(13, ALTO); retraso(100); escritura digital(13, BAJO); retraso(900); )

Como se mencionó, se llama inmediatamente después de la configuración. Y lo llaman una y otra vez tan pronto como termina. La función de bucle se denomina bucle principal del programa y está ideológicamente diseñada para realizar un trabajo útil. En nuestro caso, el trabajo útil es hacer parpadear el LED.

Repasemos las expresiones en orden. Entonces, la primera expresión es una llamada a la función incorporada digitalWrite. Está diseñado para aplicar un cero lógico (BAJO, 0 voltios) o uno lógico (ALTO, 5 voltios) a un pin determinado. Se pasan dos argumentos a la función digitalWrite: el número de pin y el valor lógico. Como resultado, lo primero que hacemos es encender el LED del pin 13, aplicándole 5 voltios.

Una vez hecho esto, el procesador pasa inmediatamente a la siguiente expresión. Para nosotros, esta es una llamada a la función de retraso. La función de retardo es, nuevamente, una función incorporada que hace que el procesador entre en suspensión durante un tiempo determinado. Sólo hace falta un argumento: el tiempo en milisegundos para dormir. En nuestro caso son 100 ms.

Mientras dormimos, todo permanece como está, es decir. el LED permanece encendido. Tan pronto como expiran los 100 ms, el procesador se activa e inmediatamente pasa a la siguiente expresión. En nuestro ejemplo, esto es nuevamente una llamada a la familiar función incorporada digitalWrite. Es cierto que esta vez pasamos el valor BAJO como segundo argumento. Es decir, ponemos un cero lógico en el pin 13, es decir, suministramos 0 voltios, es decir, apagamos el LED.

Una vez que se apaga el LED, procedemos a la siguiente expresión. Una vez más, esta es una llamada a la función de retraso. Esta vez nos quedamos dormidos durante 900 ms.

Una vez que termina el sueño, la función de bucle sale. Al finalizar, “algo” inmediatamente lo vuelve a llamar y todo vuelve a suceder: el LED se enciende, se enciende, se apaga, espera, etc.

Si traduces lo que está escrito al ruso, obtendrás el siguiente algoritmo:

    Encendiendo el LED

    Dormir durante 100 milisegundos

    Apagar el LED

    Dormimos durante 900 milisegundos.

    vamos al punto 1

Así obtuvimos un Arduino con una baliza que parpadea cada 100 + 900 ms = 1000 ms = 1 segundo.

¿Qué se puede cambiar?

Usemos sólo el conocimiento que hemos adquirido para hacer varias variaciones del programa para comprender mejor el principio.

Puede conectar un LED externo u otro dispositivo que deba "parpadear" a un pin diferente. Por ejemplo, el día 5. ¿Cómo debería cambiar el programa en este caso? Debemos reemplazar el número por el 5º donde accedimos al pin 13:

Compilar, descargar, probar.

¿Qué hay que hacer para que el LED parpadee 2 veces por segundo? Reduzca el tiempo de sueño para que el total sea 500 ms:

configuración vacía() ( pinMode(5, SALIDA); ) bucle vacío() ( digitalWrite(5, ALTO); retraso(50); digitalWrite(5, BAJO); retraso(450); )

¿Cómo puedo hacer que el LED parpadee dos veces cada vez que parpadea? Debes encenderlo dos veces con una breve pausa entre encendidos:

configuración vacía() ( pinMode(5, SALIDA); ) bucle vacío() ( digitalWrite(5, ALTO); retraso(50); digitalWrite(5, BAJO); retraso(50); digitalWrite(5, ALTO); retraso (50); escritura digital (5, BAJO);

¿Cómo puedo hacer que el dispositivo tenga 2 LED que parpadeen alternativamente cada segundo? Necesita comunicarse con dos pines y trabajar en bucle con uno u otro:

configuración vacía() ( pinMode(5, SALIDA); pinMode(6, SALIDA); ) void loop() ( digitalWrite(5, ALTO); retraso(100); digitalWrite(5, BAJO); retraso(900); digitalWrite (6, ALTO); retraso (100); escritura digital (6, BAJO);

¿Cómo asegurarse de que el dispositivo tenga 2 LED que se enciendan como un semáforo de ferrocarril: primero se enciende uno y luego el otro? Simplemente no apague el LED encendido de inmediato, sino que espere hasta el momento del cambio:

configuración vacía() ( pinMode(5, SALIDA); pinMode(6, SALIDA); ) void loop() ( digitalWrite(5, ALTO); digitalWrite(6, BAJO); retraso(1000); digitalWrite(5, BAJO) ; escritura digital(6, ALTA); retraso(1000);

No dude en comprobar otras ideas usted mismo. Como puedes ver, ¡todo es sencillo!

Sobre el espacio vacío y el código hermoso

En C++, los espacios, los saltos de línea y los caracteres de tabulación no le importan mucho al compilador. Donde hay un espacio, puede haber un salto de línea y viceversa. De hecho, 10 espacios seguidos, 2 saltos de línea y 5 espacios más equivalen a un espacio.

El espacio vacío es una herramienta de programador con la que se puede hacer que un programa sea comprensible y visual, o desfigurarlo hasta dejarlo irreconocible. Por ejemplo, recuerde el programa para hacer parpadear un LED:

configuración vacía() ( pinMode(5, SALIDA); ) bucle vacío() ( digitalWrite(5, ALTO); retraso(100); digitalWrite(5, BAJO); retraso(900); )

Podemos cambiarlo así:

configuración vacía () (pinMode (5, SALIDA);) bucle vacío () (escritura digital (5, ALTO); retraso (100); escritura digital (5, BAJO); retraso (900); )

Lo único que hicimos fue trabajar un poco con el espacio vacío. Ahora puedes ver claramente la diferencia entre código armonioso y código ilegible.

Para seguir la ley tácita del diseño de programas, que se respeta en los foros, cuando la leen otras personas y usted la percibe fácilmente, siga algunas reglas simples:

1. Aumente siempre la sangría entre ( y ) al comenzar un nuevo bloque. Normalmente se utilizan 2 o 4 espacios. Elija uno de los valores y manténgalo en todo momento.

Gravemente:

bucle vacío() (escritura digital(5, ALTO); retraso(100); escritura digital(5, BAJO); retraso(900); )

Bien:

bucle vacío() (escritura digital(5, ALTO); retraso(100); escritura digital(5, BAJO); retraso(900); )

2. Como en el lenguaje natural: pon un espacio después de la coma y no antes.

Gravemente:

Escritura digital(5, ALTO);

Bien:

escritura digital(5, ALTA);

3. escritura digital(5, ALTO);

Gravemente:

Escritura digital(5, ALTA);

Bien:

Coloque el carácter de inicio de bloque (en una nueva línea en el nivel de sangría actual o al final de la anterior. Y el carácter de fin de bloque) en una línea separada en el nivel de sangría actual:

4. configuración nula() ( pinMode(5, SALIDA); ) configuración nula() ( pinMode(5, SALIDA); ) configuración nula() ( pinMode(5, SALIDA); )

Bien:

configuración vacía() ( pinMode(5, SALIDA); ) configuración vacía() ( pinMode(5, SALIDA); )

Utilice líneas vacías para separar bloques de significado:

Aún mejor:

bucle vacío () (escritura digital (5, ALTO); retraso (100); escritura digital (5, BAJO); retraso (900); escritura digital (6, ALTO); retraso (100); escritura digital (6, BAJO); retraso ( 900); Acerca del punto y coma Quizás te preguntes: ¿por qué hay un punto y coma al final de cada expresión? Estas son las reglas de C++. Estas reglas se llaman

sintaxis del lenguaje

. Por símbolo; el compilador comprende dónde termina la expresión.

El programa es correcto y equivalente a lo que ya hemos visto. Sin embargo, escribir así es de mala educación. El código es mucho más difícil de leer. Entonces, a menos que tenga una razón 100% buena para escribir varias expresiones en la misma línea, no lo haga.

Acerca de los comentarios

Una de las reglas de una buena programación es: “escribir código de manera que quede tan claro que no necesite explicación”. Esto es posible, pero no siempre. Para explicar algunos puntos no obvios del código a sus lectores: a sus colegas o a usted mismo en un mes, existen los llamados comentarios.

Estas son construcciones en el código del programa que el compilador ignora por completo y que sólo tienen significado para el lector. Los comentarios pueden ser de varias líneas o de una sola línea:

/* La función de configuración se llama primero, cuando se aplica energía al Arduino. Y este es un comentario de varias líneas */. configuración nula() ( // establece el pin 13 en modo de salida pinMode(13, SALIDA);

) bucle vacío() ( digitalWrite(13, ALTO); retraso(100); // suspensión durante 100 ms digitalWrite(13, BAJO); retraso(900); )

Como puede ver, puede escribir tantas líneas de comentarios como desee entre los símbolos /* y */. Y después de la secuencia //, todo lo que sigue hasta el final de la línea se considera comentario.

Entonces, esperamos que los principios más básicos de la escritura de programas hayan quedado claros. El conocimiento adquirido le permite controlar mediante programación la fuente de alimentación a los pines Arduino de acuerdo con ciertos patrones de sincronización. Esto no es tanto, pero sí suficiente para los primeros experimentos.

¿El estudio de los microcontroladores parece complicado e incomprensible? Antes de que apareciera Arudino, no era realmente fácil y requería un cierto conjunto de programadores y otros equipos.

Este es un tipo de diseñador electrónico. El objetivo inicial del proyecto es permitir que las personas aprendan fácilmente a programar dispositivos electrónicos, dedicando el mínimo tiempo a la parte electrónica.

El montaje de circuitos complejos y la conexión de placas se puede realizar sin soldador, pero con la ayuda de puentes con conexiones macho y hembra desmontables. De esta manera se pueden conectar tanto elementos montados como placas de expansión, que en el léxico de Arduino se denominan simplemente “escudos”.

¿Cuál es la primera placa Arduino que debe comprar un principiante?

En las tiendas nacionales en 2017 su precio ronda los 4-5 dólares. En los modelos modernos, su corazón es Atmega328.

Imagen de la placa Arduino y explicación de las funciones de cada pin, pinout Arduino UNO

El microcontrolador de esta placa es un chip largo en un paquete DIP28, lo que significa que tiene 28 patas.

La siguiente placa más popular cuesta casi el doble que la anterior: entre 2 y 3 dólares. Esta es una tarifa. Las placas actuales están construidas sobre el mismo Atmega328, son funcionalmente similares a UNO, las diferencias están en el tamaño y la solución para coordinar con USB, más sobre esto más adelante. Otra diferencia es que se proporcionan enchufes en forma de clavija para conectar dispositivos a la placa.

El número de pines (patas) de esta placa es el mismo, pero se puede ver que el microcontrolador está fabricado en un paquete TQFP32 más compacto, se agregan ADC6 y ADC7 a la carcasa, las otras dos patas "extra" duplican el bus de alimentación. . Su tamaño es bastante compacto, aproximadamente del tamaño de su pulgar.

La tercera placa más popular es la que no tiene puerto USB para conectarse a una computadora, te contaré cómo se realiza la conexión un poco más adelante.

Esta es la placa más pequeña de todas las revisadas; por lo demás, es similar a las dos anteriores y su corazón sigue siendo el Atmega328. No consideraremos otros foros, ya que este es un artículo para principiantes y la comparación de foros es el tema de un artículo aparte.

En la parte superior hay un diagrama de conexión USB-UART, el pin "GRN" está conectado al circuito de reinicio del microcontrolador, se puede llamar de otra manera, descubrirá por qué es necesario más adelante.

Si bien UNO es excelente para crear prototipos, Nano y Pro Mini son excelentes para terminar su proyecto porque ocupan poco espacio.

¿Cómo conectar Arduino a la computadora?

Arduino Uno y Nano se conectan a la computadora a través de USB. Sin embargo, no hay soporte de hardware para el puerto USB; aquí se utiliza una solución de circuito de conversión de nivel, generalmente llamada USB a serie o USB-UART (rs-232). Al mismo tiempo, se instala un gestor de arranque Arduino especial en el microcontrolador, lo que permite el flasheo a través de estos buses.

Arduino Uno implementa esta conexión en un microcontrolador con soporte USB: ATmega16U2 (AT16U2). Resulta que se necesita un microcontrolador adicional en la placa para actualizar el firmware del microcontrolador principal.

En Arduino Nano esto se implementa mediante el chip FT232R o su análogo CH340. Este no es un microcontrolador, es un convertidor de nivel, este hecho hace que sea más fácil ensamblar el Arduino Nano desde cero con sus propias manos.

Normalmente, los controladores se instalan automáticamente cuando conecta la placa Arduino. Sin embargo, cuando compré una copia china del Arduino Nano, se identificó el dispositivo, pero no funcionó, había una pegatina redonda en el convertidor con información sobre la fecha de lanzamiento, no sé si esto se hizo a propósito. , pero cuando lo despegué vi la marca CH340.

Nunca me había encontrado con esto antes y pensé que todos los convertidores USB-UART estaban ensamblados en FT232, tuve que descargar los controladores, son muy fáciles de encontrar buscando "controladores Arduino ch340". Después de una instalación simple, ¡todo funcionó!

El microcontrolador también se puede alimentar a través del mismo puerto USB, es decir. si lo conectas a un adaptador desde un teléfono móvil, tu sistema funcionará.

¿Qué debo hacer si mi placa no tiene USB?

La placa Arduino Pro Mini tiene dimensiones más pequeñas. Esto se logró quitando el conector USB para firmware y el mismo convertidor USB-UART. Por tanto, hay que comprarlo por separado. El convertidor más sencillo basado en CH340 (el más barato), CPL2102 y FT232R, cuesta desde 1 dólar.

Al comprar, preste atención al voltaje para el que está diseñado este adaptador. Pro mini viene en versiones de 3,3 y 5 V; los convertidores suelen tener un puente para cambiar la tensión de alimentación.

Al actualizar el firmware Pro Mini, inmediatamente antes de iniciarlo es necesario presionar RESET, sin embargo, en convertidores con DTR esto no es necesario, el diagrama de conexión se encuentra en la siguiente figura.

Están conectados con terminales especiales “Mama-Mama” (hembra-hembra).

En realidad, todas las conexiones se pueden realizar mediante este tipo de terminales (Dupont), vienen con enchufes en ambos lados, o con enchufes, o con un enchufe en un lado y un enchufe en el otro.

¿Cómo escribir programas para Arduino?

Para trabajar con bocetos (el nombre del firmware en el lenguaje de los ingenieros de Arduino), existe un entorno de desarrollo integrado especial para Arduino IDE, puedes descargarlo gratis desde el sitio web oficial o desde cualquier recurso temático, generalmente no hay problemas; con instalación.

Así es como se ve la interfaz del programa. Puede escribir programas en un lenguaje C AVR simplificado especialmente desarrollado para Arduino, esencialmente un conjunto de bibliotecas llamadas Wiring, así como en C AVR puro. cuyo uso simplifica el código y acelera su funcionamiento.

En la parte superior de la ventana hay un menú familiar donde puede abrir un archivo, configuraciones, seleccionar el tablero con el que está trabajando (Uno, Nano y muchos, muchos otros) y también abrir proyectos con ejemplos de código ya preparados. A continuación se muestra un conjunto de botones para trabajar con el firmware; verá la asignación de las teclas en la siguiente figura;

En la parte inferior de la ventana hay un área para mostrar información sobre el proyecto, el estado del código, el firmware y la presencia de errores.

Conceptos básicos de programación IDE de Arduino

Al comienzo del código es necesario declarar variables e incluir bibliotecas adicionales, si las hubiera, esto se hace de la siguiente manera:

#incluye biblioteka.h; // conectamos la biblioteca llamada “Biblioteka.h”

#definir cambio 1234; // Declarar una variable con el valor 1234

El comando Definir permite al compilador elegir el tipo de variable en sí, pero puede configurarlo manualmente, por ejemplo, un entero int o un flotante de punto flotante.

LED int = 13; // creé la variable “led” y le asigné el valor “13”

El programa puede determinar el estado del pin como 1 o 0. 1 es una unidad lógica, si el pin 13 es igual a 1, entonces el voltaje en su pata física será igual al voltaje de suministro del microcontrolador (para Arduino UNO y Nano - 5V)

Una señal digital se escribe usando el comando digitalWrite (pin, valor), por ejemplo:

escritura digital (led, alto); //escribe uno en el pin 13 (lo declaramos arriba) log. Unidades.

Como puedes entender, se accede a los puertos según la numeración de la placa, correspondiente al número. Aquí hay un ejemplo similar al código anterior:

escritura digital (13, alto); // establece el pin 13 en uno

Una función de retardo de tiempo de uso frecuente se llama mediante el comando delay(), cuyo valor se especifica en milisegundos, los microsegundos se logran usando

retrasoMicrosegundos() Retraso(1000); //el microcontrolador esperará 1000 ms (1 segundo)

La configuración del puerto de entrada y salida se especifica en la función void setup() con el comando:

pinMode(NOMERPORTA, SALIDA/ENTRADA); // argumentos - nombre de variable o número de puerto, entrada o salida para elegir

Entendiendo el primer programa Blink

Como una especie de “Hola mundo” para microcontroladores, existe un programa para hacer parpadear un LED, veamos su código:

Al principio con el comando pinMode le dijimos al microcontrolador que asignara el puerto con el LED a la salida. Ya habrás notado que en el código no hay declaración de la variable “LED_BUILTIN”, lo cierto es que en Uno, Nano y otras placas, un LED incorporado está conectado al pin 13 de fábrica y está soldado en el junta. Puede utilizarlo para mostrarlo en sus proyectos o para realizar pruebas sencillas de sus programas de actualización.

A continuación, configuramos el pin al que está soldado el LED en uno (5 V), la siguiente línea hace que el MK espere 1 segundo y luego establece el pin LED_BUILTIN en cero, espera un segundo y el programa se repite en un círculo, por lo que cuando LED_BUILTIN es igual a 1 - el LED (y cualquier otra carga conectada al puerto) se enciende, cuando está en 0 se apaga.

Leemos el valor del puerto analógico y usamos los datos leídos.

El microcontrolador AVR Atmega328 tiene un convertidor analógico a digital de 10 bits incorporado. El ADC de 10 bits le permite leer valores de voltaje de 0 a 5 voltios, en pasos de 1/1024 de toda la amplitud de la señal (5 V).

Para que quede más claro, consideremos la situación, digamos que el valor de voltaje en la entrada analógica es 2.5 V, lo que significa que el microcontrolador leerá el valor del pin "512", si el voltaje es 0 - "0", y si 5 V-(1023). 1023 - porque el conteo comienza desde 0, es decir 0, 1, 2, 3, etc. hasta 1023 - 1024 valores en total.

Así es como se ve en el código, usando el boceto estándar "analogInput" como ejemplo.

sensor intPin = A0;

intledPin = 13;

int valor del sensor = 0;

pinMode(ledPin, SALIDA);

sensorValue = analogRead(sensorPin);

escritura digital (ledPin, ALTA);

retraso (valor del sensor);

escritura digital (ledPin, BAJO);

retraso (valor del sensor);

Declaramos variables:

    Ledpin: asignamos de forma independiente un pin con un LED incorporado a la salida y le damos un nombre individual;

    sensorPin: entrada analógica, configurada según las marcas en la placa: A0, A1, A2, etc.;

    sensorValue: una variable para almacenar el valor entero leído y seguir trabajando con él.

El código funciona así: sensorValue guarda el valor analógico leído desde sensorPin (comando analogRead). - Aquí termina el trabajo con la señal analógica, entonces todo es como en el ejemplo anterior.

Escribimos uno en ledPin, el LED se enciende y esperamos un tiempo igual al valor del sensorValue, es decir. de 0 a 1023 milisegundos. Apagamos el LED y esperamos nuevamente este período de tiempo, luego del cual se repite el código.

Así, posicionando el potenciómetro configuramos la frecuencia de parpadeo del LED.

Función de mapa para Arudino

No todas las funciones para actuadores (no conozco ninguna) admiten "1023" como argumento, por ejemplo, el servo está limitado por el ángulo de rotación, es decir, por media vuelta (180 grados) (media vuelta) del servomotor. el argumento máximo de la función es “180”

Ahora sobre la sintaxis: mapa (el valor que estamos traduciendo, el valor de entrada mínimo, el valor de entrada máximo, el valor de salida mínimo, el valor de salida máximo).

En código se ve así:

(mapa(analogRead(pot), 0, 1023, 0, 180));

Leemos el valor del potenciómetro (analogRead(pot)) de 0 a 1023, y en la salida obtenemos números de 0 a 180

Valores del mapa de valores:

En la práctica, aplicamos esto al funcionamiento del código del mismo servodrive, eche un vistazo al código del IDE de Arduino, si lee atentamente las secciones anteriores, entonces no requiere ninguna explicación.

Y el diagrama de conexión.

Conclusiones Arduino es una herramienta muy conveniente para aprender a trabajar con microcontroladores. Y si usa C AVR puro, o como a veces se le llama "Puro C", reducirá significativamente el peso del código y una mayor cantidad cabe en la memoria del microcontrolador, como resultado obtendrá una excelente fábrica. Placa de depuración hecha con la capacidad de actualizar el firmware a través de USB.

Me gusta Arduino. Es una lástima que muchos programadores experimentados de microcontroladores lo critiquen infundadamente por ser demasiado simplificado. En principio, solo se simplifica el lenguaje, pero nadie te obliga a usarlo, además puedes flashear el microcontrolador a través del conector ICSP y cargar allí el código que desees, sin necesidad de cargadores de arranque innecesarios.

Para aquellos que quieran jugar con la electrónica, como un diseñador avanzado, esto es perfecto, y para programadores experimentados, como placa que no requiere ensamblaje, ¡también será útil!

Para obtener más información sobre Arduino y las características de su uso en varios circuitos, consulte el libro electrónico: .

Entonces tienes un procesador. Probablemente comprenda que el procesador se puede programar de alguna manera para que haga lo que usted desee. Para que se realice un trabajo útil, es necesario (a) escribir un programa útil y (b) entregárselo al procesador para su ejecución.

En general, no importa qué tipo de procesador tengas: el último Intel Pentium en tu computadora portátil o un microcontrolador en una placa Arduino. Principios para escribir un programa, es decir. programación, en ambos casos lo mismo. La única diferencia es la velocidad y el alcance de las capacidades para trabajar con otros dispositivos.

¿Qué es un programa y dónde escribirlo?

El procesador, a pesar de toda la complejidad de la producción, es esencialmente algo bastante simple y directo. No sabe pensar. Sólo puede ejecutar ciegamente, byte a byte, las instrucciones que le fueron entregadas. Se puede dar un ejemplo aproximado de la secuencia de instrucciones:

byte de instrucción¿Qué significa para el procesador?
00001001 significa: tomar el siguiente byte y almacenarlo en la celda No. 1
00000110 ...este es exactamente el siguiente byte que recordamos en la celda número 1: el número 5
00011001 significa: restar uno del valor en la celda No. 1 y dejar allí el resultado actualizado
00101001 significa: comparar el valor de la celda No. 1 con cero y si es cero saltar tantos bytes como se indica en el siguiente byte
00000100 ...si el resultado fue cero, queremos saltar 4 bytes a la penúltima instrucción
10000011
01000001 ...la letra “A” corresponde exactamente a este código
00101000 significa que queremos retroceder tantos bytes como se indica en el siguiente byte
00000110 ...saltaremos 6 bytes atrás a la instrucción No. 3
10000011 significa que queremos mostrar el carácter cuyo código está escrito en el siguiente byte
00100001 ...firmar "!" Este código coincide exactamente

Como resultado de ejecutar dicha secuencia de instrucciones, se mostrará en la pantalla la frase de pánico "¡AAAH!".

¡Mucho código para un propósito tan simple! Está claro que si todos los programas se escribieran así, directamente, el desarrollo de productos complejos llevaría siglos.

¿Por qué son necesarios los lenguajes de programación?

Para simplificar la tarea un millón de veces, se inventaron los lenguajes de programación. Hay muchos de ellos, e incluso de los que se escuchan constantemente, puedes recordar rápidamente una o dos docenas: Assembler, C, C++, C#, Java, Python, Ruby, PHP, Scala, JavaScript.

Los programas en estos idiomas se acercan mucho más al lenguaje humano natural. Y por tanto son más fáciles, rápidos y agradables de escribir, y lo más importante, son mucho más sencillos. leer: a usted inmediatamente después de escribirle, a usted un año después o a su colega.

El problema es que estos lenguajes no son comprensibles para el procesador y antes de darle este programa, es necesario compilar: traduce del lenguaje natural a esas mismas instrucciones en forma de ceros y unos. Esto se hace mediante programas llamados compiladores. Cada idioma, a menos que permanezca en el nivel de fantasía, tiene su propio compilador. Para los idiomas populares, suele haber varios para elegir, de diferentes fabricantes y para diferentes plataformas. La mayoría de ellos están disponibles gratuitamente en Internet.

Entonces, existen programas en un lenguaje completamente comprensible para los humanos: también se les llama “código fuente”, simplemente “código” o “códigos fuente”. Están escritos en archivos de texto simples usando cualquier editor de texto, incluso usando el bloc de notas. Luego se convierten en conjuntos de ceros y unos comprensibles para el procesador que utiliza el compilador: el compilador recibe el código fuente como entrada y crea ejecutable binario, el comprensible para el procesador.

Los archivos binarios no son legibles y generalmente están destinados únicamente a ser ejecutados por el procesador. Pueden ser de diferentes tipos según para qué fueron recibidos: .exe son programas para Windows, .hex son programas para ejecutar mediante un microcontrolador como Arduino, etc.

¿Por qué existen tantos lenguajes de programación y cuál es la diferencia?

    ¿Por qué? Porque hay muchas personas y empresas en la Tierra, y muchas creían que podían hacer lo mejor: más conveniente, más claro, más rápido, más delgado.

    Cuál es la diferencia: diferentes idiomas tienen un equilibrio diferente entre velocidad de escritura, legibilidad y velocidad de ejecución.

Veamos el mismo programa que muestra una canción sobre 99 botellas de cerveza en diferentes lenguajes de programación.

Por ejemplo, el lenguaje Perl. Está escrito rápidamente; es imposible entender lo que quiso decir el programador; ejecutado lentamente:

sub b( $n = 99 - @_ - $_ || No; "$n botella" . "s" x!!-- $n . "de cerveza" ); $w = "en la pared" ; morir mapa ( b. "$w,\norte" . b. ",\n Baja uno y pásalo,\n " . b(0) . "$w.} 0 .. 98

\n\n"

Lenguaje Java. Se necesita relativamente mucho tiempo para escribir; fácil de leer; Se ejecuta bastante rápido, pero ocupa mucha memoria: botellas de clase (public static void main( Cadena botellas de clase (public static void main( argumentos) ( s = "s" ; para (int cervezas= 99 ; cervezas>- 1 ; ) ( s = "s" ; Sistema s = "s" ;.out .print (cervezas + "botella" + s + "de cerveza en la pared", ); .out .println (cervezas + "botella" + s + "de cerveza, " );) ; s = "s" ; si (cervezas== 0 ) ( .fuera .imprimir () ; s = "s" ;"Ve a la tienda, compra un poco más". s = "s" ;.out .print (cervezas + "botella" + s + "de cerveza en la pared", ); .out .println ("99 botellas de cerveza en la pared.\n " s = "s" ;.salir(0); ) demás) ; } } }

"Toma uno y pásalo"

) ; s = (-- cervezas == 1)?"" : "s" ; .out .println (cervezas + "botella" + s +" de cerveza en la pared.\n " Lenguaje ensamblador. Se necesita mucho tiempo para escribir; difícil de leer; se ejecuta muy rápidamente: segmento de código supone cs: código, ds: código org 100h inicio:; Bucle principal mov cx, 99; botellas para comenzar con loopstart: llame a printcx; imprime el número mov dx, desplaza la línea 1 ; imprimir el resto de la primera línea mov ah, 9; Rutina de cadena de impresión de MS-DOS int 21h call printcx; imprime el número mov dx, desplaza la línea 2_3 ; resto de las líneas 2 y 3 mov ah, 9 int 21h dic cx; tomar uno y llamar a printcx; imprime el número mov dx, desplaza la línea 4 ; imprimir el resto de la cuarta línea mov ah, 9 int 21h cmp cx, 0; ¿Se acabó la cerveza? jne inicio de bucle; si no, continúa hasta las 20h; salir a MS-DOS; subrutina para imprimir el registro CX en decimal printcx: mov di, número de desplazamiento; llenar el buffer desde el final mov hacha, cx mov[ds:di],dl; póngalo en el búfer de impresión cmp ax, 0; ¿Algún dígito más para calcular? je printcxend; si no, finalice diciembre di; poner el siguiente dígito antes del actual jmp imprimircxloop; bucle printcxend: mov dx, di; imprimir, comenzando en el último dígito calculado mov ah, 9 int 21h ret; Línea de datos 1 db"botellas de cerveza en la pared" , 13 , 10 , "$" line2_3 db "botellas de cerveza", 13 , 10 ,"Toma uno y pásalo" , 13 , 10 , "$" línea4 db"Botellas de cerveza en la pared".

, 13 , 10 , 13 , 10 , "$" numbuffer db 0 , 0 , 0 , 0 , 0 numbufferend db 0 , "$" código termina fin inicio

¿Cómo se programa Arduino?

Si hablamos de Arduino o microcontroladores de Atmel, ¿en qué idioma se pueden escribir programas para ellos? La respuesta teórica: cualquiera. Pero en la práctica, la elección se limita a los lenguajes Assembler, C y C++. Esto se debe a que, en comparación con una computadora de escritorio, tienen recursos muy limitados. Kilobytes de memoria, no gigabytes. Megahercios en el procesador, no gigahercios. Éste es un precio a pagar por la baratura y la eficiencia energética.

Por lo tanto, necesitamos un lenguaje que pueda compilar y ejecutar de manera eficiente. Es decir, se traduce a esos mismos ceros y unos de las instrucciones de la manera más óptima posible, sin desperdiciar valiosas instrucciones ni memoria. Los lenguajes antes mencionados tienen este tipo de eficiencia. Utilizándolos incluso dentro de los estrechos límites de los recursos del microcontrolador, puede escribir programas ricos en funciones que se ejecuten rápidamente.

Assembler, como has visto, no puede considerarse el más simple y elegante y, como resultado, el lenguaje insignia de Arduino es C/C++.

Muchas fuentes dicen que Arduino está programado en el lenguaje Arduino, Processing, Wiring. Ésta no es una afirmación del todo correcta. Arduino está programado en C/C++, y lo que se llama con estas palabras es simplemente un conveniente "kit de carrocería" que le permite resolver muchos problemas comunes sin tener que reinventar la rueda cada vez.

¿Por qué se mencionan C y C++ en la misma oración? C++ es una superestructura de C. Todo programa en C es un programa C++ válido, pero no al revés. Puedes usar ambos. La mayoría de las veces, ni siquiera pensarás en lo que estás usando para resolver el problema actual.

Más cerca del punto: el primer programa

Vayamos en orden. Escribamos el código fuente. Puedes escribirlo en el bloc de notas o en cualquier otro editor. Sin embargo, para facilitar el trabajo, existen los llamados entornos de desarrollo (IDE: Integrated Development Environment). En forma de una sola herramienta, proporcionan un editor de texto con resaltado y sugerencias, un compilador que se inicia con un botón y muchas otras alegrías. Para Arduino, este entorno se llama Arduino IDE. Está disponible gratuitamente para su descarga en el sitio web oficial.

Instale el entorno y ejecútelo. En la ventana que aparece, verá: la mayor parte del espacio está destinado al editor de texto. El código está escrito en él. El código en el mundo Arduino también se llama bosquejo.

Así que escribamos un boceto que no haga nada. Es decir, el mínimo programa correcto posible en C++, lo que simplemente hace perder el tiempo.

configuración vacía() ( ) bucle vacío() ( )

No nos centremos en el significado del código escrito por ahora. Compilémoslo. Para hacer esto, en el IDE de Arduino, hay un botón "Verificar" en la barra de herramientas. Haz clic en él y en unos segundos el archivo binario estará listo. Esto se anunciará mediante la inscripción "Compilación terminada" debajo del editor de texto.

Como resultado, tenemos un archivo binario con la extensión .hex, que puede ser ejecutado por el microcontrolador.

Ahora necesitas introducirlo en el Arduino. Este proceso se llama arranque, flasheo o inundación. Para cargar al IDE de Arduino, hay un botón "Cargar" en la barra de herramientas. Conecte el Arduino a su computadora mediante un cable USB, haga clic en "Cargar" y en unos momentos el programa se cargará en el Arduino. En este caso se borrará el programa que había anteriormente.

El firmware exitoso se anunciará con la inscripción "Carga finalizada".

Si encuentra un error al intentar descargar, asegúrese de que:

    En el menú Herramientas → Placa, seleccione el puerto al que está realmente conectado el Arduino. Puedes conectar y desconectar el cable USB para ver qué puerto aparece y desaparece: este es el Arduino.

    Ha instalado los controladores necesarios para Arduino. Esto es necesario en Windows, no en Linux y solo en placas Duemilanove anteriores a Arduino en MacOS.

¡Felicidades! Ha pasado de ser una pizarra en blanco a un programa funcional en Arduino. Puede que no haga nada, pero esto ya es un éxito.




Arriba