MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
CAPITULO I Estructura
setup() (inicialización)
loop() (bucle)
E structuras de control
Operadores Boole anos
&& (y)
if (comparador si-entonces)
|| (o)
if...else (comparador si...sino)
! (negación)
for (bucle con contador) switch case (comparador múltiple).
while (bucle por comparación booleana) do... while (bucle por comparación booleana)
break (salida de bloque de código)
continue (continuación en bloque de código) return (devuelve valor a programa)
Sint axis
; (punto y coma)
{} (llaves)
Operadores de Composición
++ (incrementa)
-- (decrementa) +=(composición suma)
-= (composición resta)
*=(composición multiplicación)
/= (composición división)
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
CAPITULO I. 1. Estructura setup() La función setup() se establece cuando se inicia un programa -sketch. Se emplea para iniciar variables, establecer el estado de los pins, inicializar librerías, etc. Esta función se ejecutará una única vez después de que se conecte la placa Arduino a la fuente de alimentación, alimentació n, o cuando se pulse el botón de reinicio de la placa. Ejemplo int buttonPin = 3; void setup() { Serial.begin(9600); pinMode(buttonPin, pinMode(butto nPin, INPUT); I NPUT); } void loop() { // ... } loop()
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
serialWrite('H'); else serialWrite('L'); delay(1000); 1.1
} E s t r u ct u r as de co n t r o l
1.1.1 if (condicional) y ==, !=, <, > (operadores de comparación) if , el cual puede ser usado en conjunto con uno o más operadores de comparación, comprueba si cierta condición se cumple, por ejemplo, si un input posee un valor mayor a cierto número. El formato para una comprobación if es el siguiente: if (algunaVariable > 50) { // hacer algo algo aquí. } Este programa comprueba si la variable algunaVariable es mayor a 50. Si lo es, el programa toma una acción particular. Dicho de otra forma, si la declaración escrita dentro de los paréntesis es verdadera (true), el código dentro de las llaves se ejecutará. Sino, el programa ignora dicho código.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
x < y (x es menor a y) x > y (x es mayor a y) x <= y (x es menor o igual a y) x >= y (x es mayor o igual a y) Atención: Ten cuidado de no usar un signo de igual solo (Ej. if (x = 10) ). Un signo de igual solo es el operador que indica la asignación de un valor, y va a asignar 10 a x. En su lugar usa el signo de igual doble (Ej. if (x == 10) ), el cual es el operador de comparación, y comprueba si x equivale a 10 o no. El último ejemplo sólo da true si x equivale a 10, pero el ejemplo anterior (con un sólo símbolo =) dará siempre TRUE. Esto es porque C evalúa la declaración if (x=10) de la siguiente manera: 10 es asignado a x (Recuerda que un signo = solo, es el operador de asignación), por lo tanto x ahora contiene 10. Entonces el condicional if evalúa 10, el cual siempre resulta TRUE, debido a que cualquier valor numérico mayor a 0 es evaluado como TRUE. Consecuentemente, if (x = 10) siempre será evaluado como TRUE, lo cual no es el resultado deseado cuando se usa una declaración if. Adicionalmente, la variable x será definida en 10, lo que tampoco es una acción deseada. if también puede ser parte de una estructura de control de ramificación usando la construcción if...else. 1.1.2 if / else if/else permite mayor control sobre el flujo del código que la declaración if básica,
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Entonces un bloque else if puede ser usado con o sin else al final. La cantidad de declaraciones else if , y sus ramificaciones son ilimitadas. if (pinCincoInput < 500) { // ejecutar A } else if (pinCincoInput >= 1000) { // ejecutar B } else { // ejecutar C } Otra forma de expresar ramificaciones (branching en inglés), y realizar comprobaciones mutuamente exclusivas, es con la declaración switch case, la cual resulta más idónea en algunos casos. 1.1.3
Declaración FOR
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
La initialization, o inicialización, se produce sólo la primera vez. Cada vez que se va a repetir el bucle, se revisa la condition, o condición: si es cierta, el bloque de funciones (y el incremento del contador) se ejecutan, y la condición vuelve a ser comprobada de nuevo. Si la condición es falsa, el bucle termina. Ejemplo // Variar la intensidad de un LED usando un salida PWM int PWMpin = 10; // En el pin 10 hay un LED en serie con una resistencia de 470 ohmios void setup() { // no es necesario nada aquí } void loop() { for (int i=0; i <= 255; i++){ analogWrite(PWMpin, i); delay(10); } } C o ns e j de ión
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
for (int i = 0; i > -1; i = i + x){ analogWrite(PWMpin, i); if (i = 255) x = -1; // cambia de signo para apagarlo delay(10); } } 1.1.4 Sentencia switch / case Como las sentencias if , switch...case controla el flujo de programas permitiendo a los programadores especificar diferentes códigos que deberían ser ejecutados en función de varias condiciones. En particular, una sentencia switch compara el valor de una variable con el valor especificado en las sentencias case. Cuando se encuentra una sentencia case cuyo valor coincide con dicha variable, el código de esa sentencia se ejecuta. La palabra clave break sale de la sentencia switch, y es usada típicamente al final de cada case. Si una sentencia break, la sentencia switch continuaría ejecutando las siguientes expresiones ("falling-through") hasta encontrar un break, o hasta llegar al final de la sentencia switch. Ejemplo switch (var) { case 1: //hacer algo cuando sea igual a 1
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
break; default: // sentencias } Parámetros var: la variable cuyo valor comparas con los varios "case" etiqueta: un valor para comparar con la variable V er t am bi én : if...else 1.1.5
Bucles while Descripción Los bucles while se ejecutan continuamente, hasta que la expresión de dentro del paréntesis, (), pasa a ser falsa. Algo debe modificar la variable comprobada, el bucle while nunca terminará. Lo que modifique la variable puede estar en el código, como una variable que se incrementa, o ser una condición externa, como el valor que da un sensor. Sintaxis while(expresion){ // sentencia(s)
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
1.1.6 do - while El bucle "'do'" trabaja de la misma manera que el bucle "'while'", con la excepcion de que la condición se comprueba al final del bucle, por lo que este bucle se ejecuta "siempre" al menos una vez. do { // bloque de instrucciones } while (condición); Ejemplo: do { delay(50); // espera a que los sensores se estabilicen x = readSensors(); // comprueba los sensores } while (x < 100);
//si se cumple la condición se repite el bucle
1.1.7 break break es usado para salir de los bucles do, for, o while, pasando por alto la
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
1.1.8 continue La sentencia continue omite el resto de iteracciones de un bucle ( do, for, o while). Continúa saltando a la condición de bucle y procediendo con la siguiente iteracción. Ejemplo for (x = 0; x < 255; x ++) { if (x > 40 && x < 120){ // crea un salto en estos valores continue; } digitalWrite(PWMpin, x); delay(50); } 1.1.9
return Termina una función y devuelve un valor a la función que la llama. Puede no devolver nada. Sintaxis return; return valor; // ambas formas son correctas
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
void loop(){ // código magnífico a comprobar aquí return; // el resto del programa del que se desconfía // que nunca será ejecutado por estar detrás de return } SINTAXIS ; punto y coma Utilizado para terminar una declaración. Ejemplo int a = 13; 1.1.10
{} Llaves Las Llaves son un parte importante del lenguaje de programación C. Se utilizan en diferentes construcciones (ver ejemplos al final), esto a veces puede ser confuso para los principiantes. Una llave de apertura "{" siempre debe ir seguida de una llave de cierre "}". Esta es una condición a la que se suele referir como llaves emparejadas. El IDE (Entorno Integrado de Desarrollo) Arduino incluye una característica para comprobar si las llaves están emparejadas. Sólo tienes que seleccionar una Llave o incluso hacer click
MICROCONTROLADOR ATMEL
U so s p r in c i p a l e s d e l a s L la v e s Funciones void myfunction(tipodato argumento){ sentencia(s) } Loops while (expresión booleana) { sentencia(s) } do { sentencia(s) } while (expresión booleana); for (inicialización; condición final; expresión incremento) { sentencia(s)
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
1.1.11 Comentarios Los comentarios son líneas en el programa para aclarar a tí o a otros sobre el funcionamiento del programa. Estas líneas son ignoradas por el compilador y no se exportan al procesador. No ocupan por tanto espacio en el Chip Atmega El único propósito de los comentarios es que entiendas o entiendan (o recuerdes) cual es el funcionamiento de tu programa. Existen dos maneras distintas de marcar una línea como comentario: Ejemplo x = 5; // Esto es una línea simple de comentario. Todo lo que va después de la doble barra es un comentario // Hasta el final de la línea /* Esto es un comentario multilínea - úsalo para comentar bloques enteros de código if (gwb == 0){ // Una líne de comentario sencilla puede usarse dentro de un comentario multilínea x = 3; /* pero no otro comentario multilínea- esto no es válido */ } // No olvides cerrar el comentario multilínea
MICROCONTROLADOR ATMEL Ejemplo int sensVal; // declara una variable int llamada sensVal senVal = analogRead(0); // guarda el valor (digitalizado) del voltaje de entrada del pin analógico 0 en SensVal S u ge r en c ia s d e p r o g ra ma c i ó n La variable en el lado izquierdo del operador de asignación (signo "=") tiene que ser capaz de mantener el valor almacenado en ella. Si no es suficientemente grande para contenerlo, el valor almacenado en la variable será incorrecto. No confunda el operador de asignación [=] (un solo signo igual) con el operador de comparación [==] (un signo igual doble), que evalúa si dos expresiones son iguales. V er t am bi én if (operadores de comparación) char int long
1.2.2 Suma, Resta, Multiplicación y División Descripción Estos operadores devuelven la suma, diferencia, producto o cociente (respectivamente) de los dos operandos. La operación se lleva a cabo utilizando el tipo de datos de los operandos, por lo que, por ejemplo, 9 / 4 resulta 2 desde 9 y 4 que son enteros int. Esto también significa que la operación puede desbordarse si el
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
result = value1 / value2; Parámetros: value1: cualquier variable o constante value2: cualquier variable o constante S u ge r en c ia s d e p r o g ra ma c i ó n: Debes saber que las integer constants por defecto son int, así que algunos cálculos con constantes pueden provocar desbordamiento (p.e. 60 * 1000 devolverá un resultado negativo) Elige los tamaños de variable que sean suficientemente grandes como para alojar el resultado de tus calculos. Debes saber en que punto tu variable se desbordará en su máximo, y que esto también ocurre en su mínimo. p.e. (0 - 1) o también (0 - - 32768) Para cálculos matemáticos que requieren fracciones, usa variables float, pero ten en cuenta los inconvenientes: gran tamaño, velocidades bajas de cálculo Usa el operador de conversión (casting). Por ejemplo: (int)myFloat para convertir el tipo de una variable en el momento. 1.2.3 EL % (módulo) Descrición Calcula el resto de la división entre dos enteros. Es útil para mantener una variable
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
int i = 0; void setup() {} void loop() { valores[i] = analogRead(0); i = (i + 1) % 10; // el operador módulo prevalece sobre la variable } Nota El operador modulo no funciona con datos en coma flotante (float) V é as e t a m b i é n división 1 .3
O pe r a d o r e s C o m p ar a t i v o s 1.3.1 if (condicional) y ==, !=, <, > (operadores de comparación) if , el cual puede ser usado en conjunto con uno o más operadores de comparación, comprueba si cierta condición se cumple, por ejemplo, si un input posee un valor mayor a cierto número. El formato para una comprobación if es el siguiente: if (algunaVariable > 50)
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
// todos los ejemplos son correctos. Las declaraciones a evaluar dentro de los paréntesis, requieren el uso de uno o más operadores: Operadores de Comparación: x == y (x es igual a y) x != y (x no es igual a y) x < y (x es menor a y) x > y (x es mayor a y) x <= y (x es menor o igual a y) x >= y (x es mayor o igual a y) Atención: Ten cuidado de no usar un signo de igual solo (ej. if (x = 10) ). Un signo de igual solo es el operador que indica la asignación de un valor, y va a asignar 10 a x . En su lugar usa el signo de igual doble (ej. if (x == 10) ), el cual es el operador de comparación, y compryeba si x equivale a 10 o no. El último ejemplo sólo da true si x equivale a 10, pero el ejemplo anterior (con un sólo símbolo =) dará siempre TRUE . Esto es porque C evalúa la declaración if (x=10) de la siguiente manera: 10 es asignado a x (Recuerda que un signo = solo, es el operador de asignación), por lo tanto x ahora contiene 10. Entonces el condicional if evalúa 10, el cual siempre resulta TRUE , debido a que cualquier valor numérico mayor a 0 es evaluado como TRUE . Consecuentemente, if (x = 10) siempre será evaluado como TRUE , lo cual no
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
if (x > 0 || y > 0) { // ... } Es Verdadero si alguno de los valores x ó y es mayor que 0. 1.4.1.3 ! (NOT) Verdadero si el operador es Falso, por ejempo: if (!x) { // ... } Es Verdadero si el valor de x es Falso (p. e. si x es igual a 0). Atención. Asegúrate de no confundir el operador AND booleano && (doble signo &) con el operador AND para bits & (un solo signo &). De la misma manera no hay que confundir el operador OR booleano || (doble barra vertical) con el operador OR para bits | (una sola barra vertical). El operador NOT de bits ~ (tilde) tiene una apariencia muy diferente del operador NOT booleano! (exclamación o "bang", como lo llaman algunos programadores), pero debes asegurarte de usar cada uno de ellos dentro del contexto adecuado. Ejemplos. if (a >= 10 && a <= 20){} // Verdadero sólo si el valor de a está entre 10
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
1 . 4 . 1 . 5 O p e r a d o r b i t a b i t A N D (& ) te operador, en C++, es un ampersand (&) simple, usado entre dos expresiones enteras. Opera en cada posición de bit en ambas expresiones de forma independiente, de acuerdo a esta regla: si ambas posiciones de entrada son un 1, el resultado devuelto es un 1; en otro caso, será un 0. Por ejemplo: 0 0 1 1 operando1 0 1 0 1 operando2 ---------0 0 0 1 (operando1 & operando2) - resultado devuelto En Arduino, el tipo entero (int) ocupa 16bits, pero usando & entre dos expresiones tipo int, causa 16 operaciones AND simultáneas. En el siguiente código: int a = 92; // en binario: 0000000001011100 int b = 101; // en binario: 0000000001100101 int c = a & b; // resultado: 0000000001000100, 68 en decimal. Cada uno de los 16bits de las palabras a y b son procesados usando el operador bit a bit AND y se guarda el resultado en la palabra c.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
P ro gr am a d e e je mp lo Un trabajo común de los operadores vistos hasta ahora es leer-modificar-escribir en un puerto. En los microcontroladores, un puerto es un número de 8bits que representa la condición (estado) de cada pin. Escribir en un puerto controla todos los pines de ese puerto a la vez. PORTD es una constante definida para referirse a los estados de salida de los pines digitales 0, 1, 2, 3, 4, 5, 6 y 7. Si hay un 1 en una determinada posición, ese pin se encuentra a nivel alto (HIGH). (Los pines necesitan estar declarados como salida usando la instrucción pinMode). Entonces, si escribimos PORTD = B00010100;, pondremos los pines 2 y 4 a nivel alto. Un ligero problema es que, al asignarle un valor al puerto directamente, se puede modificar el valor de otro pin, por ejemplo, el valor del bit 0 y 1 del puerto D, usados por el Arduino en comunicaciones serie, por lo que podríamos estar interfiriendo en esa comunicación. Explicado esto, el algoritmo del programa de ejemplo es: Leer el valor actual del puerto y borrar sólo los bits correspondientes con los pines que queremos controlar (operador AND). Combinar el valor modificado del puerto con el valor real del puerto, para que se reflejen los cambios en los bits que controlamos (operador OR). int i; // variable de contador int j; void setup(){
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
} 1 . 4 . 1 . 7 O p e r a d o r b i t a b i t X O R (^ ) Este es un operador poco usado en C++, llamado o-exlcusiva (X-OR). Este operador es escrito usando el caracter ^. Es similar al operador or (|), pero sólo devuelve un 1 cuando los bits son diferentes; devolviendo 0 en el resto de los casos. Por ejemplo: 0 0 1 1 operando1 0 1 0 1 operando2 ---------0 1 1 0 (operando1 ^ operando2) - valor devuelto A continuación un pequeño código de ejemplo: int x = 12; // binario: 1100 int y = 10; // binario: 1010 int z = x ^ y; // binario: 0110, 6 en decimal Este operador se suele usar para invertir (cambiar 0s a 1, o viceversa, también llamado toggle), algunos (o todos) bits de una expresión. Siempre que una posición de la máscara esté a 1, esa posición será invertida en la palabra de entrada. Si hay un 0 en la máscara, esa posición no se verá afectada. A continuación un ejemplo para hacer parpadear un LED en la salida digital 5.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
1.4.1.8 Operador NOT (~) a nivel de bits El operador bit a bit NOT, en C++, es el caracter ~. A diferencia de los operadores AND (&) y OR (|), el operador NOT es aplicado únicamente a un operando. Este operador lo que hace es cambiar cada bit de la palabra por su contrario: los 0 pasan a ser 1, y viceversa. Por ejemplo: 0 1 operando1 ---------1 0 ~ operando1 int a = 103; // en binario: 0000000001100111 int b = ~a; // en binario: 1111111110011000 = -104 Posiblemente te sorprendas de ver que el resultado da un valor negativo. Esto es debido a que el bit más significativo (msb) es llamado, también, bit de signo. Si este bit es un 0, el valor del número será interpretado como positivo, mientras que si es 1, se interpretará como un negativo. Esta codificación para los números positivos y negativos se denomina "'Complemento a 2'" (Ca2). Para más información, lee el artículo correspondiente en la Wikipedia en complemento a dos. Como anotación, es interesante saber que para cualquier entero X, ~X es lo mismo que X-1
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Devuelve El valor original o el resultante del incremento o disminución de la variable. Ejemplos x = 2; y = ++x; y = x--;
// x ahora guarda 3, y guarda 3 // x guarda 2 de nuevo, y sigue guardando 3
1.5.2 += , -= , *= , /= (Composicion Suma) Descripción Realiza una operación matemática con una variable con respecto a otra variable o una constante. El operador += (y los demás operadores) son una forma simplificada de la sintaxis completa, tal y como se muestra más abajo. Sintaxis x += y; // equivalente a la expresión x = x + y; x -= y; // equivalente a la expresión x = x - y; x *= y; // equivalente a la expresión x = x * y; x /= y; // equivalente a la expresión x = x / y;
MICROCONTROLADOR ATMEL
CAPITULO II Variables Constantes HIGH | LOW INPUT | OUTPUT true | false Constantes Numéricas T ip o s d e D a t o s boolean (booleano) char (carácter) byte int (entero) unsigned int (entero sin signo) long (entero 32b) unsigned long (entero 32b sin signo) float (en coma flotante)
MANUAL PROGRAMACIÓN
MICROCONTROLADOR ATMEL
2.0
MANUAL PROGRAMACIÓN
Variables 2.1 Constantes Las constantes variables que vienen predefinidas en el lenguaje de Arduino. Se usan para facilitar la lectura de los programas. Clasificamos las constantes en grupos. Las que definen niveles lógicos, verdadero (true) y falso (false) (Constantes Booleanas) Existen dos constantes para representar si algo es cierto o falso en Arduino: true, y false. 2.1.1 false false es el más sencillo de definir. false se define como 0 (cero). 2.1.2 true true se define la mayoría de las veces como 1, lo cual es cierto, pero tiene una definición más amplia. Cualquier entero que es no-cero es TRUE, en un sentido Booleano. Así, en un sentido Booleano, -1, 2 y -200 son todos true. Ten en cuenta que las constantes true y false se escriben en minúsculas, al contrario que HIGH, LOW, INPUT, y OUTPUT. Las que definen el nivel de los pines, nivel alto (HIGH) y nivel bajo (LOW) Cuando leemos o escribimos en un pin digital, existen sólo dos valores que podemos obtener o asignar: HIGH y LOW.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Cuando un pin es configurado como salida (OUTPUT) con pinMode,y establecido LOW con digitalWrite, el pin tiene 0 voltios. En este estado puede meter corriente, e.j. Luz y LED que se conectan a través de resistencias en serie a +5 voltios, o a otro pin configurado como salida, y establecido a HIGH. Las que definen los pines digitales, INPUT y OUTPUT Los pines digitales pueden se usados como entrada (INPUT) o como salida (OUTPUT). Cambiando un pin de INPUT a OUTPUT con pinMode() el comportamiento eléctrico del pin cambia drásticamente. P i n s c o n f i g u r a d o s c o m o e n t r a da s Los pins de Arduino (Atmega) configurados como INPUT con pinMode() se dice que se encuentran en un estado de alta impedancia. Una forma de explicar esto es que un pin configurado como entrada se le aplica una muy baja demanda, es decir una resistencia en serie de 100 Megohms. Esto lo hace muy útil para leer un sensor, pero no para alimentar un LED. P in s c on fi gu r a do s c om o s al id as Los pins configurados como salida (OUTPUT) con pinMode() se dice que estan en estado de baja impedancia. Esto implica que pueden proporcionar una sustancial cantidad de corriente a otros circuitos. Los pins de Atmega pueden alimentar (proveer de corriente positiva) or meter (proveer de masa) hasta 40 mA (miliamperios) de corriente a otros dispositivos/circuitos. Esto o hace muy útil para alimentar LED's pero inservible para leer sensores. Los pins configurados como salida pueden deteriorarse o romperse si ocurre un cortocircuito hacia los 5V o 0V. La cantidad de corriente que puede proveer un pin del Atmega no es suficiente para la mayoría de los relés o motores, y es
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
E j e j e m p l o l o
int ledPin = 13;
// LED conectado al pin digital 13
void setup() { pinMode(ledPin, OUTPUT); OUTPUT); //configura el pin del LED LED como salida } void loop() { digitalWrite(ledPin, HIGH); // Enciende el LED delay(1000);
// espera un segundo
digitalWrite(ledPin, LOW); delay(1000); }
// Apaga el LED
// Espera un segundo
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
2.1.5 Integer Constants Integer Constants son números utilizados directamente en un sketch, como 123. Por defecto, éstos números son tratados como int, int, pero puedes cambiarlo con las letras U y L (ver abajo). Normalmente, las constantes integer son tratadas como enteros base 10 (decimales), pero se puede utilizar notación especial (formateadores) para ingresar números en otras bases. Base
Ejemplo
Formateador
10 (decimal)
123
Ninguno.
2 (binario)
B1111011
Comentario
Antecede "B" Sólo funciona con valores de 8 bits (0 to 255). Caracteres 0-1 válidos.
8 (octal)
0173
Antecede "0"
16 (hexadecimal)
0x7B
Antecede "0x"
Caracteres 0-7 válidos. Caracteres 0-9, A-F, a-f válidos.
Decimal es base 10. Esta es la matemática de sentido común con que se conocen. Para constantes sin otros prefijos, se asume el formato decimal. Ejemplo: 101 // igual a 101 decimal ((1 * 10^2) + (0 * 10^1) + 1) Binary es base dos. Sólo caracteres 0 y 1 son válidos. Ejemplo:
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
13, E es 14, y la F, como ya habrás adivinado, es 15. Los valores hexadecimales hexadecim ales se indican con el prefijo "0x". Nota que los valores de la A a la F , pueden ser escritos en mayúscula o minúscula. Ejemplo: 0x101 // igual a 257 decimal ((1 * 16^2) + (0 * 16^1) + 1) Formateadors U & L Por defecto, una constante en enteros es tratada como co mo int con las limitaciones concomitantes concomi tantes en los valores. Para especificar una constante en enteros con otro tipo de datos, continúala con: una 'u' ó 'U' para forzar la constante a un formato de datos unsigned . Ejemplo: 33u una 'l' ó 'L' para forzar la constante a un formato de datos long. Ejemplo: 100000L un 'ul' ó 'UL' para forzar la constante a un formato de datos unsigned long. Ejemplo: 32767ul Ver También
constants #define
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
2.2 Tipos de Datos 2.2.1 booleanos Un booleano sólo puede tomar dos valores, Verdadero o Falso. Cada booleano ocupa un único byte en la memoria. Ejemplo: int LEDpin = 5; // LED en el pin 5 int switchPin = 13; // pulsador en el pin 13, su otra patilla conectada en GND boolean running = false; // crea la variable booleana running y le asisga el valor Falso (false)
void setup() { pinMode(LEDpin, OUTPUT); pinMode(switchPin, INPUT); digitalWrite(switchPin, HIGH); // conecta la resistencia pull-up interna del pin 13
} void loop() {
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
ASCII de la letra mayúscula A es 65). Mira Serial.println para tener mas información de como son traducidos a números los carácteres. El tipo de datos char tiene signo. esto significa que codifica números desde 128 hasta 127. Para un dato de un byte (8bits), utiliza el tipo de dato "byte". Ejemplo char miChar = 'A'; char miChar = 65; // los dos son equivalentes 2.2.3 byte Descripción Un byte almacena un número sin signo de 8-bit, desde 0 hasta 255. Ejemplo byte b = B10010; // "B" es el formateador binario (B10010 = 18 decimal) 2.2.4 word Descripción Una variable tipo word almacena un valor de 16bits sin signo, desde 0 hasta 65535. Es lo mismo que una tipo unsigned int . Ejemplo word w = 10000; 2.2.5 unsigned int
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
C on se j o d e c od if ic ac ió n Cuando las variables sobrepasan su capacidad máxima dan la vuelta a su mínima capacidad. Ten en cuenta que esto sucede en ambas direcciones. unsigned int x x = 0; x = x - 1; // x ahora contiene 65535 - da la vuelta en dirección negativa x = x + 1; // x ahora contiene 0 - da la vuelta 2.2.6 long Descripción Las variables de tipo Long son variables de tamaño extendido para almacenamiento de números, y 32 bits (4 bytes), desde -2,147,483,648 hasta 2,147,483,647. Ejemplo long speedOfLight = 186000L; // ver Constantes Integer para la explicación de la 'L' Sintaxis long var = val; 2.2.7 unsigned long Descripción
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
// espera un segundo para no enviar cantidade masivas de datos delay(1000); } Sintáxis unsigned long var = val; 2.2.8 float Descripcion El tipo variable para los números en coma flotante (número decimal). Estos números son usados, habitualmente, para aproximar valores analógicos y continuos, debido a que ofrecen una mayor resolución que los enteros. Las variables tipo float tienen el valor máximo 3.4028235E+38, y como mínimo pueden alcanzar el -3.4028235E+38. Ocupan 4bytes (32bits). Los floats tienen una precisión de 6 o 7 dígitos decimales. Esto significa el número total de dígitos, no el número a la derecha de la coma decimal. Al contrario que en otras plataformas, donde tu podrías obtener mayor precisión usando una variable tipo double (por ejemplo, por encima de 15 dígitos), en Arduino los double tienen el mismo tamaño que los float. Los números en coma flotante no son exactos, y muchos proporcionan falsos resultados cuando son comparados. Por ejemplo, 6.0 / 3.0 puede no ser igual a 2.0. Debes comprobar que el valor absoluto de la diferencia entre los números pertenezca a un rango pequeño.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
x = 1; y = x / 2; // y ahora contiene 0, la parte entera de la operación z = (float)x / 2.0; // z ahora contiene 0.5 (se debe usar 2.0, en lugar de 2) 2.2.9 double Descripcion Número en coma flotante de doble precisión. Ocupa 4 bytes. La implementación "double" en Arduino es exactamente lo mismo que la FLOAT, sin ganar nada de precisión. Consejo Los usuarios que porten código de otras fuentes y que incluyan variable tipo double deberían examinar el código para ver si la precisión necesaria es diferente a la que se puede lograr en Arduino. 2.2.10 string Descripción Los strings se representan como arrays de caracteres (tipo char) que terminan con el caracter NULL. Ejemplos Todas las siguientes son declaraciones válidas de strings. char Str1[15]; char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Terminación NULL Generalmente, los strings se finalizan con un caracter NULL (código ASCII 0). Esto permite a funciones (como Serial.print()) establecer dónde está el final del string. De otra forma, seguiría leyendo los siguientes bytes de la memoria que no forman parte del string. Esto significa que tu string necesita tener espacio para un caracter más del texto que quieres que contenga. Esto es por lo que Str2 y Str5 necesitan 8 caracteres, incluso aunque "arduino" tenga sólo 7 - la última posición es automáticamante completada con un caracter NULL. Str4 será automáticamente dimensionada a 8 caracteres, uno para el NULL extra. En Str3, hemos incluido nosotros mismos el caracter NULL (escrito como '\0'). Ten en cuenta que es posible tener un string sin un caracter NULL al final (p.e. si tú has especificado la longitud de Str2 como 7 en lugar de 8). Esto romperá la mayoría de funciones que usen strings, por lo que no deberías hacerlo intencionadamente. Por lo tanto, si detectas algún comportamiento extraño (operando con los caracteres, no con el string), este podría se el problema Comillas simples o dobles Los string siempre se definen entre comillas dobles ("Abc") y los caracteres siempre se definen dentro de comillas simples ('A'). Envolviendo string largos Puedes envolver strings largos de ésta manera: char miString[] = "Esta es la primera linea"
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
} void loop(){ for (int i = 0; i < 6; i++){ Serial.println(miStrings[i]); delay(500); } } 2.2.12 Arrays Una matriz o "array" es una colección de variables que son accedidas mediante un número de índice. Los "arrays" en el lenguaje de programación C, en el cual está basado Arduino, pueden ser complicados, pero usar "arrays" simples es relativamente sencillo. C r e an d o (D e c l a r a n d o ) u n a m at r i z o A r r a y Todos los métodos de abajo son formas válidas de crear (declarar) una matriz. int myInts[6]; int myPins[] = {2, 4, 8, 3, 6}; int mySensVals[6] = {2, 4, -8, 3, 2}; char message[6] = "hola";
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
no válidos. Escribir en las localidades de memoria aleatoria es definitivamente una mala idea y, a menudo puede conducir a resultados inesperados como fallos o mal funcionamiento del programa. Esto también puede ser un error difícil encontrar. A diferencia de BASIC o JAVA, el compilador de C no realiza ninguna comprobación para ver si el acceso a una matriz está dentro de los límites del tamaño de la matriz que ha declarado. Para asignar un valor a un a matriz: mySensVals[0] = 10; T o retrieve a value from an array: x = mySensVals[4]; M a t r i c e s y l o s b u c l e s F O R Las matrices se utilizan muchas veces en el interior de bucles for, donde el contador de bucle se utiliza como el índice de cada elemento de la matriz. Por ejemplo, para imprimir los elementos de una matriz a través del puerto serie, se podría hacer algo como esto: int i; for (i = 0; i < 5; i = i + 1) { Serial.println(myPins[i]); } Ejemplo
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
NOTA: PROGMEM
Guarda datos en la memoria flash (la de programa) en vez de en la SRAM. Hay una descripción de los tipos de memoria disponible en una placa Arduino. La palabra PROGMEM es un modificador de variable. Debería usarse sólo con los tipos de datos definidos en pgmspace.h. Le dice al compilador que ponga la información en la memoria flash en vez de en la SRAM, que es donde normalmente se guarda. PROGMEM es parte de la librería pgmspace.h, por ello hay que incluir la librería al principio del sketch, de esta forma: #include
S i n t a x i s
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...}; dataType: tipo de datos en la memoria de programa: cualquier tipo de datos de variables variableName - el nombre de la variable matriz. Hay que tener en cuenta que PROGMEM es un modificador de variable por lo que no hay reglas escritas sobre dónde debería ir, por lo que el compilador acepta cualquiera de las definiciones siguientes, que son sinónimas. Aun así, se han llevado a cabo experimentos que han concluído que en varias versiones de Arduino (relacionado con la versión de GCC), PROGMEM puede funcionar en una posición y no en otra. La tabla siguiente ha sido probada con Arduino 13. En versiones anteriores del IDE es posible que funcione mejor si PROGMEM se incluye después del nombre de la variable dataType variableName[] PROGMEM = {}; // usar esta
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
prog_uint32_t - entero largo sin signo (4 bytes) 0 a 4.294.967.295 Ejemplo
En el siguiente código se indica cómo leer y escribir caracteres sin signo (bytes) y enteros (2 bytes) en PROGMEM. #include // guardar enteros sin signo PROGMEM prog_uint16_t charSet[] = { 65000, 32796, 16843, 10, 11234}; // guardar caracteres prog_uchar signMessage[] PROGMEM = {"I AM PREDATOR, UNSEEN COMBATANT. CREATED BY THE UNITED STATES DEPART"}; unsigned int displayInt; int k; // variable contador char myChar; // leer entero de 2 bytes displayInt = pgm_read_word_near(charSet + k) // leer carácter myChar = pgm_read_byte_near(signMessage + k); Matrices de cadenas de caracteres (arrays de strings)
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
prog_char string_5[] PROGMEM = "String 5"; // Definir una tabla para guardar los strings PROGMEM const char *string_table[] = { string_0, string_1, string_2, string_3, string_4, string_5 }; char buffer[30]; // debe ser tan grande como el string más grande. void setup() { Serial.begin(9600); } void loop() { /* La función strcpy_P copia un string del espacio de programa a un string en RAM ("buffer").
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
// ... } void loop() { // ... } Ver también
declaración de funciones NOTA: Funciones.
Segmentar el código en funciones permite al programador crear piezas modulares de código que realizan una tarea definida y vuelven a la zona del programa en la que fueron llamadas. El caso típico para crear un función es cuan do uno necesita realizar la misma acción múltiples veces dentro de un mismo programa. Para programadores acostumbrados a utilizar BASIC las funciones en Arduino permiten (y extienden) la utilidad de usar subrutinas (GOSUB en BASIC). La estandarización de fragmentos de código en funciones tiene diversas ventajas: Las funciones ayudan al programador a ser organizado. Además ayudan a concept ualizar el programa. Las funciones codifican una acción en un lugar, así que sólo deben ser depuradas de errores una vez. Reducen las posibilidades de error en modif icaciones, si el código debe ser cambiado.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
void loop{ int i = 2; int j = 3; int k; k = myMultiplyFunction(i, j); // k ahora contiene 6 } Nuestra función necesita ser declarada fuera de cualquier otra función, por ello "myMultiplyFunction()" puede ir antes o despues de la función "loop()". El sketch completo podría ser algo como esto: void setup(){ Serial.begin(9600); } void loop{ int i = 2; int j = 3; int k; k = myMultiplyFunction(i, j); // k ahora contiene 6 Serial.println(k); delay(500); }
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
}
Para llamar a nuestra función solo tenemos que asignarla a una variable. int sens; sens = ReadSens_and_Condition();
Conversión char() Descripción Convierte un valor a un tipo de dato char. Sintaxis char(x) Parámetros x: un valor de cualquier tipo Devuelve char M i r a t a mb i é n char byte() Descripción
MICROCONTROLADOR ATMEL
int long() Descripción Convierte un valor al tipo de datos long. Sintaxis long(x) Parámetros x: un valor para cualquier tipo Devuelve long long() Descripción Convierte un valor al tipo de datos long. Sintaxis long(x) Parámetros x: un valor para cualquier tipo Devuelve
MANUAL PROGRAMACIÓN
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
CAPITULO III Funciones E/S Digitales pinMode() digitalWrite() digitalRead() E/S Analógicas analogRead() analogWrite() - PWM (modulación por ancho de pulso) E/S Avanzadas tone() noTone() shiftOut() pulseIn() Tiempo millis() micros() delay() delayMicroseconds() Matemáticas min() (mínimo) max() (máximo) abs() (valor absoluto)
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
3.0 E/S Digitales 3.1 pinMode() Descripción Configura el pin especificado para comportarse como una entrada o una salida. Mira la descripción de See the description of pines digitales para más información. Sintaxis pinMode(pin, modo) Parametros pin: el numero del pin que se desea configurar modo: INPUT (Entrada) o OUTPUT (Salida) Devuelve Nada Ejemplo int ledPin = 13; // LED conectado al pin digital 13 void setup() { pinMode(ledPin, OUTPUT); //configura el pin del LED como salida
MICROCONTROLADOR ATMEL
3.2
MANUAL PROGRAMACIÓN
digitalWrite()
Descripción Escribe un valor HIGH o LOW hacia un pin digital. Si el pin ha sido configurado como OUTPUT con pinMode(), su voltaje será establecido al correspondiente valor: 5V ( o 3.3V en tarjetas de 3.3V) para HIGH, 0V (tierra) para LOW. Si el pin es configurado como INPUT, escribir un valor de HIGH con digitalWrite() habilitará una resistencia interna de 20K conectada en pullup (ver el tutorial de pines digitales). Escribir LOW invalidará la resistencia. La resistencia es sufuciente para hacer brillar un LED de forma opaca, si los LEDs aparentan funcionar, pero no muy iluminados, esta puede ser la causa. La solución es establecer el pin como salida con la función pinMode(). NOTA: El pin digital número 13 es más difícil de usar que los otros pines digitales por que tiene un LED y una resistencia adjuntos, los cuales se encuentran soldados a la tarjeta, y la mayoría de las tarjetas se encuentran así. Si habilitas la resistencia interna en pullup, proporcionará 1.7V en vez de los 5V esperados, por que el LED soldado en la tarjeta y resistencias bajan el nivel de voltaje, significando que siempre regresará LOW. Si debes usar el pin número 13 como entrada digital, usa una resistencia externa conectada a pulldown. Sintaxis digitalWrite(pin, valor) Parameters
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Establece el pin número 13 a HIGH, hace un retraso con la duración de un segundo, y regresa el pin a LOW. Nota Los pines analógicos pueden ser usados como pines digitales con los números 14 (entrada analógica número 0) hasta 19 (entrada analógica número 5). 3.3
digitalRead() Descripción Lee el valor de un pin digital especificado, HIGH o LOW. Sintaxis digitalRead(pin) Parámetros pin: el número de pin digital que quieres leer ( int ) Devuelve HIGH o LOW Ejemplo int ledPin = 13; // LED conecado al pin digital número 13 int inPin = 7; // botón (pushbutton) conectado al pin digital número 7
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Nota Si el pin no esta conectado a algo, digitalRead() puede regresar HIGH o LOW (y esto puede cambiar aleatoriamente). Los pines analógicos pueden ser usados como pines digitales con los números 14 (entrada analógica número 0) hasta 19 (entrada analogica número 5). 4.0
E/S Analógicas 4.1 tone() Descripción Genera una onda cuadrada de la frecuencia especificada (y un 50% de ciclo de trabajo) en un pin. La duración puede ser especificada, en caso contrario la onda continua hasta que haya una llamada a noTone(). El pin puede conectarse a un zumbador piezoeléctrico u otro altavoz que haga sonar los tonos. Sólo puede generarse un tono cada vez. Si un tono está sonando en un pin diferente, la llamada a tone() no tendrá efecto. Si el tono está sonando en el mismo pin, la llamada establecerá la nueva frecuencia. El uso de la función tone() interferirá con la salida PWM en los ins 3 y 11 (en otras placas distintas de la Mega). NOTA: si quieres hacer sonar diferentes tonos en múltiples pins necesitas llamar a noTone() en un pin antes de llamar a tone() en el siguiente pin. Sintáxis
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Sintaxis noTone(pin) Parámetros pin: el pin en el cual se va a parar de generar el tono. Devuelve Nada Ejemplos > Digital I/O Reproduce un tono usando la función tone()
Este ejemplo muestra como usar la función tone() para generar notas. Reproduce una pequeña melodia que quizás hayas escuchado antes. Circuito
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Código
El código de abajo usa un archivo extra, pitches.h. Este archivo contiene todos los valores de las frecuencias de las notas típica. Por ejemplo, NOTE_C4 es una C media. NOTE_FS4 es F aguda, y así sucesivamente. Esta tabla de notas fue originalmente escrita por Brett Hagman, en el que está basada la función tone(). La encontrarás util cada vez que tengas que reproducir notas musicales. Para crear este archivo, haz click en el botón "new Tab" (nueva pestaña) en la esquina superior derecha de la ventana. Queda algo así: Ejemplos > E/S Digital Seguidor de tono usando la función tone()
Este ejemplo muestra como usar la función tone() para generar un tono que sigue los valores de una entrada analógica. Circuito
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Código
El código de este ejemplo es muy simple. Simplemente lee una entrada analógica y lo convierte en un valor en un rango comprendido en el rango de frecuencia audible. Los humanos podemos oír frecuencias entre 20 y 20.000 Hz, pero 100 - 1000 funciona bien para este programa. Necesitaras encontrar el rango de variación de tu entrada analógica para poder hacer la conversión. En el circuito que se muestra el rango de la entrada analógica va desde 400 hasta aproximadamente 1000.Cambia los valores en la función map() para que se ajusten al rango de tu sensor. Teclado simple usando la función tone()
Este ejemplo muestra como usar el comando tone() para generar diferentes tonos dependiendo que sensor se presiona. Circuito
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Código
El programa de abajo lee tres sensores analógicos. Si alguno de los sensores supera un valor umbral, la nota correspondiente será reproducida. El código de abajo usa un archivo extra, pitches.h. Este archivo contiene todos los valores de las frecuencias de las notas típica. Por ejemplo, NOTE_C4 es una C media. NOTE_FS4 es F aguda, y así sucesivamente. Eta tabla de notas fue originalmente escrita por Brett Hagman, en el que está basada la función tone(). La encontrarás util cada vez que tengas que reproducir notas musicales. Para crear este archivo, haz click en "new Tab" (Nueva pestaña) el cual se encuentra en la esquina superior derecha de la ventana. Es algo así: Ejemplos > E/S Digital Reproducir tonos en distintas salidas usando la función tono()
Este ejemplo muestra como usar el comando tone() para reproducir diferentes notas en múltiples salidas. El comando tono () usando uno de los temporizadores internos del ATmega, configurándolo con la frecuencia que deseas, y usando el temporizador para enviar pulsos a través del pin de salida. Como solo usa un temporizador, solo puedes reproducir una nota a la vez. Sin embargo, puedes producir tonos en múltiples pines secuencialmente. Para hacerlo, necesitas apagar el temporizador en un pin para moverlo al siguiente. Circuito
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Esquematico:
Código
El programa de abajo reproduce un tono en cada uno de los altavoces en secuencia, apagando el primer altavoz primero. Ten en cuenta que el tiempo de duración de cada tono vienen determinado por el retraso que hay justo después de el. PWM
El ejemplo "Fading" demuestra el uso de una salida analógica (PWM) para atenuar y aumentar la
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Una vez cargado y ejecutado el ejemplo mueve la arduino de un lado a otro, lo que ves es esencialmente un mapeado del tiempo a lo largo del espacio. A nuestros ojos el movimiento difumina cada parpadeo del LED en una linea. A medida que la luminosidad del LED se incrementa o atenua esas pequeñas lineas crecen o se reducen. Ahora estas viendo el ancho de pulso (pulse width).
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
pinReloj: el pin que hay que conmutar cada vez que a un pinDatos le ha sido enviado el valor correcto (int) ordenBits: en qué orden desplazar los bits; si hacia el MSBFIRST (bit más significante primero) o hacia el LSBFIRST (bit menos significante primero). valor: los datos que rotar. ( byte) Retorno Ninguno Nota El pinDatos y pinReloj deben estar ya configurados como salida con una llamada previa a pinMode(). 4.4
shiftOut se encuentra actualmente configurada para extraer un byte (8 bits) por lo que necesita realizar una operación de dos pasos para extraer valores más grandes de 255. // Haz esto para una comunicación serie MSBFIRST (primero el bit más significativo) int datos = 500; // rota el byte más alto shiftOut(pinDatos, pinReloj, MSBFIRST, (datos >> 8)); // rota el byte más bajo shiftOut(datos, pinReloj, MSBFIRST, datos); // O haz esto para una comunicación serie LSBFIRST (primero el bit menos
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
//Pin conectado al pin ST_CP del 74HC595 int latchPin = 8; //Pin connectado al pin SH_CP del 74HC595 int clockPin = 12; ////Pin conectado al pin DS del 74HC595 int dataPin = 11; void setup() { // Configura como salida los pines que se direccionan en el bucle principal (loop) pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { //rutina de conteo for (int j = 0; j < 256; j++) { //pone a nivel bajo el latchPin y lo mantienen a nivel bajo todo el tiempo que estés transmitindo digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, j);
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Parámetros pin: el número del pin en el que se realiza la medida del pulso. (int ) value: tipo de pulso. Puede ser HIGH o LOW. (int ) timeout (opcional): el tiempo en microsegundos máximo a esperar antes de que se inicie el pulso. ( unsigned long) Devuelve el ancho del pulso (en microsegundos) ó 0 si el pulso no ha empezado antes del timeout (unsigned long) Ejemplo int pin = 7; unsigned long duracion; void setup() { pinMode(pin, INPUT); } void loop() { duracion = pulseIn(pin, HIGH);
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
void loop(){ Serial.print("Tiempo: "); time = millis(); //Imprime el tiempo desde que se inició el programa Serial.println(time); // espera un segundo para no enviar demasiados datos delay(1000); } Consejo: Ten en cuenta que el parametro que devuelve millis() es un long sin signo por lo que pueden producirse errores si el programador intenta llevar a cabo operaciones matemáticas con otros tipos de dato como enteros. V é as e t a m b ié n micros() delay() delayMicroseconds() Tutorial: Blink sin retardo 5.2
micros()
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
} void loop(){ Serial.print("Tiempo: "); time = micros(); //Imprime el tiempo desde el comienzo del programa Serial.println(time); // espera un segundo para no enviar datos una cantidad exagerada de datos. delay(1000); } 5.3 delay() Descripción Pausa el programa por un tiempo determinado (en milisegundos) especificado por un parámetro. Hay 1000 milisegundos en un segundo. Sintaxis delay(ms) Parámetros ms: el número de milisegundos que se desea pausar el programa ( unsigned long)
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Advertencia Aunque es fácil crear un LED parpadeante con la función delay() y muchos sketches usan pausas cortas para estas tareas, el uso de delay() en un sketch tiene problemas importantes. Mientras se pausa el programa no se leen sensores, ni se hacen cálculos, ni puede haber manipulación de los pines. En definitiva, hace que (casi) toda la actividad se pare. Una alternativa para controlar el tiempo es el uso de la función millis() y el sketch mostrado abajo. Normalmente se evita el uso de delay() para tiempos mayores de decenas de milisegundos excepto en programas muy simples. Algunas cosas siguen funcionando mientras se ejecuta la función delay() porque no se deshabilitan las interrupciones. La comunicación serie de los pines RX sigue funcionando, los valores de PWM ( analogWrite) y los estados de los pines se mantienen y las interrupciones siguen funcionando correctamente. Ejemplos > E/S (I/O) Digital
Parpadeo sin retardo (delay ) En ocasiones puede ser necesario hacer parpadear un LED (o alguna otra cuestión visible) al mismo tiempo que se hacen otras cosas (como controlar la pulsación de un boton). Esto implica no poder utilizar delay(), o todo se pararda mientras el LED parpadea. Aqui tienes un código que muestra como hacer parpadear el LED sin usar delay(). Controla la última vez que se encendió o apaga el LED. Entonces, cada vez que pasa por el bucle() compara si ha transcurrido un intervalo suficiente de tiempo y si es asi, apaga el LED si estaba encendido o viceversa.
MICROCONTROLADOR ATMEL
5.4
MANUAL PROGRAMACIÓN
delayMicroseconds()
Descripción Detiene brevemente el programa por la cantidad en tiempo (en microsegundos) especificada como parámetro. Existen mil microsegundos en un milisegundo, y un millon de microsegundos en un segundo. Actualmente, el valor más grande producirá un retraso exacto es 16383. Esto puede cambiar en una futura versión de Arduino. Para retrazos más largos que algunos miles de microsegundos, deberías usar delay() . Sintaxis delayMicroseconds(us) Parametros us: el número de microsegundos a detener ( unsigned int ) Devuelve Nada Ejemplo int outPin = 8; // selecciona el pin 8 void setup() { pinMode(outPin, OUTPUT); // establece el pin digital como salida
MICROCONTROLADOR ATMEL
6.0
MANUAL PROGRAMACIÓN
Matemáticas 6.1 min(x, y) Descripción Calcula el mínimo de dos números. Parametros x: el primer número, cualquier tipo de dato y: el segundo número, cualquier tipo de dato Devuelve El más pequeño entre los dos números. Ejemplos sensVal = min(sensVal, 100); // asigna sensVal al menor entre sensVal y 100 // asegurando que nunca pasará de 100. Nota La función max() es usualmente usada para limitar el límite inferior del rango de una variable, mientras que la función min() es usada para limitar el límite superior del rango de una variable. Advertencia Debido a la forma en la que se ha implementado la función min(), evite realizar operaciones en el argumentos de la función ya que podría producir errores.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Nota max() suele ser usado para restringir el valor más bajo del rango de una variable, mientras que min() es utilizado para restringir el valor máximo del
rango. Atención Debido a la forma en que la función max() es implementada, debes evitar usar otras funciones al definir los parámetros, puede derivar en resultados incorrectos. max(a--, 0); // evitar esto - puede dar resultados incorrectos. a--; // en su lugar, hacerlo así max(a, 0); // mantener cualquier operación fuera de los paréntesis. 6.3 abs(x) Descripción Calcula el valor absoluto de un número. Parámetros x: El numero cuyo valor absoluto deseamos calcular Devuelve x: si x is mayor o igual que 0. -x: si x es menor que 0. Precaución
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
b: si x es mayor que b Ejemplo sensVal = constrain(sensVal, 10, 150); // limita el valor del sensor entre 10 y 150 6.5 map(value, fromLow, fromHigh, toLow, toHigh) Descripción Re-mapea un número desde un rango hacia otro. Ésto significa que, un valor (value) con respecto al rango fromLow-fromHight será mapeado al rango toLow-toHigh. No se limitan los valores dentro del rango, ya que los valores fuera de rango son a veces objetivos y útiles. La función constrain() puede ser usada tanto antes como después de ésta función, si los límites de los rangos son deseados. Ten en cuenta que los límites "inferiores" de algún rango pueden ser mayores o menores que el límite "superior" por lo que map() puede utilizarse para revertir una serie de números, por ejemplo: y = map(x, 1, 50, 50, 1); La función maneja correctamente también los números negativos, por ejemplo: y = map(x, 1, 50, 50, -100); también es válido y funciona correctamente.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
val = map(val, 0, 1023, 0, 255); analogWrite(9, val); } Apéndice Para los interesados en el funcionamiento de la función, aquí está su código: long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } 6.6 pow(base, exponente) Descripción Calcula el valor de un número elevado a otro número. Pow() puede ser usado para elevar un número a una fracción. Esta función es útil para generar datos exponenciales o curvas. Parámetros Base: base que queremos elevar ( float ) (Coma flotante)
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
6.8 sqrt(x) Descripción Calcula la raíz cuadrada de un numero. Parámetros x: el numero, cualquier tipo de dato Devuelve doble, la raíz cuadrada del numero. 7.0
Trigonometría 7.1 sin(rad) Descripción Calcula el seno de un ángulo (en raianes). El resultado será entre -1 y 1. Parametros rad: el ángulo en radianes ( float ) Retorno El seno del ángulo ( double) Nota
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
rad: el ángulo en radianes ( float ) Retorno La tangente del ángulo ( double) Nota Serial.print() y Serial.println() no soportan actualmente imprimir variales de tipo float. NOTA: float Descripcion
El tipo variable para los números en coma flotante (número decimal). Estos números son usados, habitualmente, para aproximar valores analógicos y contínuos, debido a que ofrecen una mayor resolución que los enteros. Las variables tipo float tienen el valor máximo 3.4028235E+38, y como mínimo pueden alacanzar el -3.4028235E+38. Ocupan 4bytes (32bits). Los floats tienen una precisión de 6 o 7 dígitos decimales. Esto significa el número total de dígitos, no el número a la derecha de la coma decimal. Al contrario que en otras plataformas, donde tu podrías obtener mayor precisión usando una variable tipo double (por ejemplo, por encima de 15 dígitos), en Arduino los double tienen el mismo tamaño que los float. Los números en coma flotante no son exactos, y muchos proporcionan falsos resultados cuando son comparados. Por ejemplo, 6.0 / 3.0 puede no ser igual a 2.0. Debes comprobar que el valor absoluto de la diferencia entre los números pertenezca a un rango pequeño. La matemática en coma flotante es mucho más lenta que la matemática de enteros para realizar operaciones, por lo que deberías evitarla si, por ejemplo, un bucle tiene que ejecutarse a la máxima
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
z = (float)x / 2.0; // z ahora contiene 0.5 (se debe usar 2.0, en lugar de 2) double Descripcion
Número en coma flotante de doble precisión. Ocupa 4 bytes. La implementación "double" en Arduino es exactamente lo mismo que la FLOAT, sin ganar nada de precisión. Consejo
Los usuarios que porten código de otras fuentes y que incluyan variable tipo double deberían examinar el código para ver si la precisión necesaria es diferente a la que se puede lograr en Arduino.
8.0
Números Aleatorios 8.1 randomSeed(seed) Descripción randomSeed() inicializa el generador de números pseudoaleatorios, haciéndole empezar en un punto arbitrario de su secuencia aleatoria. Esta secuencia, aunque muy larga y aleatoria, es siempre la misma. Si es importante que la secuencia de valores generada por random() difiera en ejecuciones sucesivas de un programa, es recomendable utilizar randomSeed() (seed en inglés, semilla) para inicializar el generador de números aleatorios con una entrada mínimamente aleatoria como analogRead() en un pin desconectado.
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Serial.println(numAleatorio); delay(50); } 8.2 random() Descripción La función random genera números pseudoaleatorios. Sintaxis random(max) random(min, max) Parámetros min - límite inferior del valor aleatorio, inclusive (opcional) max - límite superior del valor aleatorio, exclusive (se devuelve hasta el anterior) Devuelve un número aleatorio entre min y max ( long) Nota: Si es importante que la secuencia de valores generada por random() difiera en ejecuciones sucesivas de un programa, es recomendable utilizar randomSeed() (seed en inglés, semilla) para inicializar el generador de números aleatorios con una entrada mínimamente aleatoria como analogRead() en un pin
MICROCONTROLADOR ATMEL
numAleatorio = random(300); Serial.println(numAleatorio); // escribe un número aleatorio de 10 a 19 numAleatorio = random(10, 20); Serial.println(numAleatorio); delay(50); } 9.0 Comunicación: 9.1 Serial Se utiliza para la comunicación entre la placa Arduino y un ordenador u otros dispositivos. Todas las placas Arduino tienen al menos un puerto serie (también conocido como UART o USART): Serial. Se comunica a través de los pines digitales 0 (RX) y 1 (TX), así como con el ordenador mediante USB. Por lo tanto, si utilizas estas funciones, no puedes usar los pines 0 y 1 como entrada o salida digital. Puedes utilizar el monitor del puerto serie incorporado en el entorno Arduino para comunicarte con la placa Arduino. Haz clic en el botón del monitor de puerto serie en la barra de herramientas y selecciona la misma velocidad en baudios utilizada en la llamada a begin(). La placa Arduino Mega tiene tres puertos adicionales de serie: Serial1 en los pines 19 (RX) y 18 (TX), Serial2 en los pines 17 (RX) y 16 (TX), Serial3 en
MICROCONTROLADOR ATMEL
MANUAL PROGRAMACIÓN
Physical Pixel Virtual Color Mixer Serial Call Response Serial Call Response ASCII FUNCIONES DE COMUNICACIÓN SERIAL. 9.2 begin() Descripción Establece la velocidad de datos en bits por segundo (baudios) para la transmisión de datos en serie. Para comunicarse con el computador, utilice una de estas velocidades: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 o 115200. Sin embargo, puedes especificar otras velocidades - por ejemplo, para comunicarte a través de los pines 0 y 1 con un componente que requiere una velocidad de transmisión en particular. Sintaxis Serial.begin(speed) Solamente en Arduino Mega: Serial1.begin(speed) Serial2.begin(spee d)
MICROCONTROLADOR ATMEL
Serial.begin(9600); Serial1.begin(38400); Serial2.begin(19200); Serial3.begin(4800); Serial.println("Hola Ordenador"); Serial1.println("Hola Serial 1"); Serial2.println("Hola Serial 2"); Serial3.println("Hola Serial 3"); } void loop() {}
9.3
end() Descripción
Desactiva la comunicación serie, permitiendo a los pines RX and TX ser usados como entradas o salidas digitales. Para reactivar la comunicación serie, llama al método Serial.begin(). Sintaxis Serial.end() Solamente en Arduino Mega:
MICROCONTROLADOR ATMEL
Parametros Ninguno Devuelve El número de bytes disponibles para ser Leídos Ejemplo int incomingByte = 0; // para los datos de entrada serie void setup() { Serial.begin(9600); // abre el puerto serie, establece la velocidad a 9600 bps } void loop() { // envía datos solo cuando recibe datos: if (Serial.available() > 0) { // lee el byte de entrada: incomingByte = Serial.read(); // muestra lo que tiene: Serial.print("He recibido: "); Serial.println(incomingByte, DEC);
MICROCONTROLADOR ATMEL
9.5
} // lee del puerto 1, envía al puerto 0: if (Serial1.available()) { int inByte = Serial1.read(); Serial.print(inByte, BYTE); } } read() Descripción Lee los datos entrantes del puerto serie. Sintaxis Serial.read() Solamente en Arduino Mega:
Serial1.read() Serial2.read() Serial3.read() Parámetros Ninguno
MICROCONTROLADOR ATMEL
} } 9.6
flush() Descripción Vacía el búfer de entrada de datos en serie. Es decir, cualquier llamada a Serial.read () o Serial.available () devolverá sólo los datos recibidos después la llamada más reciente a Serial.flush (). Sintaxis Serial.flush() Solamente en Arduino Mega:
Serial1.flush() Serial2.flush() Serial3.flush() Parámetros ninguno Retorna nada 9.7
print()
MICROCONTROLADOR ATMEL
Serial.print(78, OCT) imprime "116" Serial.print(78, DEC) imprime "78" Serial.print(78, HEX) imprime "4E" Serial.println(1.23456, 0) imprime "1" Serial.println(1.23456, 2) imprime "1.23" Serial.println(1.23456, 4) imprime "1.2346" Sintaxis Serial.print(val) Serial.print(val, format) Parámetros val: el valor a imprimir - de cualquier tipo format: especifica el número de la base (para números enteros) o el número de posiciones decimales (para números de coma flotante o tipo "float") Devuelve Nada Ejemplo: /* Usa un bucle FOR para los datos e imprime un número en varios formatos. */
MICROCONTROLADOR ATMEL
Serial.print("\t"); Serial.println("BYTE"); for(x=0; x< 64; x++){ // solo una parte de la tabla // imprime en varios formatos: Serial.print(x); // imprime como codificado ASCII decimal - igual que "DEC" Serial.print("\t"); // imprime un tabulado Serial.print(x, DEC); // imprime como codificado ASCII decimal Serial.print("\t"); // imprime un tabulado Serial.print(x, HEX); // imprime como codificado ASCII hexadecimal Serial.print("\t"); // imprime un tabulado Serial.print(x, OCT); // imprime como codificado ASCII octal Serial.print("\t"); // imprime un tabulado Serial.print(x, BIN); // imprime como codificado ASCII binario Serial.print("\t"); // imprime un tabulado Serial.println(x, BYTE);// imprime el valor en bruto del byte, // y añade el salto de linea con "println" delay(200); // espera 200 milisegundos }
MICROCONTROLADOR ATMEL
format: especifica el número de la base (para números enteros) o el número de posiciones decimales (para números de coma flotante o tipo "float") Devuelve Nada Example: /* Analog input Lee el pin analógico 0, e imprime su valor por el puerto serie. */ int analogValue = 0; void setup() {
// variable para guardar el valor analogico
// abre el puerto serie a 9600 bps: Serial.begin(9600); } void loop() { // lee la entrada analogica en el pin 0: analogValue = analogRead(0);
MICROCONTROLADOR ATMEL
Syntax Serial.write(val) Serial.write(str) Serial.write(buf, len) Arduino Mega tambien soporta: Serial1, Serial2, Serial3 (en lugar de Serial)
Parámetros val: un valor para enviar como un solo byte str: una cadena 'string' para enviar como una serie de bytes buf: un 'array' para enviar como una serie de bytes len: longitud del búfer
MICROCONTROLADOR ATMEL
EJEMPLOS Tabla ASCII Muestra las funciones avanzadas de impresión serie mediante la generación de una tabla de caracteres ASCII y sus valores en decimal, hexadecimal, octal y binario. Para más información sobre ASCII, mira http://www.asciitable.com y http://en.wikipedia.org/wiki/ASCII. Code /*
ASCII table Prints out byte values in all possible formats: * as raw binary values * as ASCII-encoded decimal, hex, octal, and binary values For more on ASCII, see http://www.asciitable.com and http://en.wikipedia.org/wiki/ASCII The circuit: No external hardware needed. */
void setup() {
MICROCONTROLADOR ATMEL
Serial.print(", dec: "); // prints value as string as an ASCII-encoded decimal (base 10). // Decimal is the default format for Serial.print() and Serial.println(), // so no modifier is needed:
Serial.print(thisByte);
// But you can declare the modifier for decimal if you want to. //this also works if you uncomment it: // Serial.print(thisByte, DEC);
Serial.print(", hex: "); // prints value as string in hexadecimal (base 16):
Serial.print(thisByte, HEX); Serial.print(", oct: ");
// prints value as string in octal (base 8);
Serial.print(thisByte, OCT); Serial.print(", bin: ");
// prints value as string in binary (base 2) // also prints ending line break:
Serial.println(thisByte, BIN);
MICROCONTROLADOR ATMEL
*, +, ,, -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <, =, >, ?, @, A, B, C, D, E,
dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec: dec:
42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex: hex:
2A, 2B, 2C, 2D, 2E, 2F, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 3A, 3B, 3C, 3D, 3E, 3F, 40, 41, 42, 43, 44, 45,
oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct: oct:
52, bin: 101010 53, bin: 101011 54, bin: 101100 55, bin: 101101 56, bin: 101110 57, bin: 101111 60, bin: 110000 61, bin: 110001 62, bin: 110010 63, bin: 110011 64, bin: 110100 65, bin: 110101 66, bin: 110110 67, bin: 110111 70, bin: 111000 71, bin: 111001 72, bin: 111010 73, bin: 111011 74, bin: 111100 75, bin: 111101 76, bin: 111110 77, bin: 111111 100, bin: 1000000 101, bin: 1000001 102, bin: 1000010 103, bin: 1000011 104, bin: 1000100 105, bin: 1000101
MICROCONTROLADOR ATMEL
Atenuador (Dimmer) Muestra el envío de datos desde el ordenador a la placa Arduino, en este caso para controlar el brillo de un LED. Los datos se envían en bytes individuales, cada uno de ellos oscila entre 0 y 255. Arduino lee estos bytes y los utiliza para ajustar el brillo de los LED. Puedes enviar bytes al Arduino desde cualquier software que tenga acceso al puerto serie del ordenador. Puedes ver ejemplos para Processing y Max/MSP versión 5 mas abajo. Circuito Un LED conectado al pin 9 utilizando la resistencia adecuada, según sea necesario. Para la mayoría de los LEDs comunes, generalmente se puede prescindir de la resistencia, ya que la corriente de salida de los pines de E/S digitales es limitada. Esquema
MICROCONTROLADOR ATMEL
LED attached from digital pin 9 to ground. Serial connection to Processing, Max/MSP, or another serial application This example code is in the public domain. */
const int ledPin = 9;
// the pin that the LED is attached to
void setup() { // initialize the serial communication:
Serial.begin(9600);
// initialize the ledPin as an output:
}
pinMode(ledPin, OUTPUT);
void loop() { byte brightness; // check if data has been sent from the computer:
if (Serial.available()) {
// read the most recent byte (which will be from 0 to 255):
brightness = Serial.read();
// set the brightness of the LED:
MICROCONTROLADOR ATMEL
// select the port corresponding to your Arduino board. The last // parameter (e.g. 9600) is the speed of the communication. It // has to correspond to the value passed to Serial.begin() in your // Arduino sketch. port = new Serial(this, Serial.list()[0], 9600); // If you know the name of the port used by the Arduino board, you // can specify it directly like this. //port = new Serial(this, "COM1", 9600); } void draw() { // draw a gradient from black to white for (int i = 0; i < 256; i++) { stroke(i); line(i, 0, i, 150); } // write the current X-position of the mouse to the serial port as // a single byte port.write(mouseX); } */
MICROCONTROLADOR ATMEL
Gráfico
Un ejemplo sencillo de comunicaciones desde la placa Arduino al ordenador: el valor de una entrada analógica es visualizado. Llamomos a esto comunicación "serie" porque la conexión tanto en Arduino como en el ordenador es un tradicional y modernizado puerto serie, aunque en realidad actualmente uses un cable USB. Puedes utilizar el monitor serie de Arduino para ver los datos enviados, o pueden ser leidos mediante Processing (ver código mas abajo), Flash, PD, Max/MSP, etc. Circuito Una entrada analógica conectada al pin 0 analógico. Esquema
MICROCONTROLADOR ATMEL
data from a serial port. The Processing code below graphs the data received so you can see the value of the analog input changing over time. The circuit: Any analog input sensor is attached to analog in pin 0. */ void setup() { // initialize the serial communication: Serial.begin(9600); } void loop() { // send the value of analog input 0: Serial.println(analogRead(A0)); // wait a bit for the analog-to-digital converter // to stabilize after the last reading: delay(2); } /* Processing code for this example // Graphing sketch // This program takes ASCII-encoded strings // from the serial port at 9600 baud and graphs them. It expects
MICROCONTROLADOR ATMEL
// Open whatever port is the one you're using. myPort = new Serial(this, Serial.list()[0], 9600); // don't generate a serialEvent() unless you get a newline character: myPort.bufferUntil('\n'); // set inital background: background(0); } void draw () { // everything happens in the serialEvent() } void serialEvent (Serial myPort) { // get the ASCII string: String inString = myPort.readStringUntil('\n'); if (inString != null) { // trim off any whitespace: inString = trim(inString); // convert to an int and map to the screen height: float inByte = float(inString); inByte = map(inByte, 0, 1023, 0, height); // draw the line: stroke(127,34,255); line(xPos, height, xPos, height - inByte);
MICROCONTROLADOR ATMEL
Llamada y respuesta Serial (handshaking) Un ejemplo de la comunicación multi-byte desde la placa de Arduino al ordenador utilizando un metodo de llamada-y-respuesta (handshaking). Este programa envía un ASCII A (byte de valor 65) en el arranque y lo repite hasta que el serial responde desde el ordenador. Entonces envía tres valores del sensor como bits simples, y queda esperando otra respuesta del ordenador. Puedes uilizar el monitor de serie de Arduino para ver los datos enviados, o puede ser leido por processing (ver código siguiente), flash, PD, Max/MSP (ver siguiente ejemplo), etc. Circuito Las entradas analógicas conectadas a los pines de entrada analógica 0 y 1. Interruptor conectado a la I/O digital 2. Esquemas
MICROCONTROLADOR ATMEL
Thanks to Greg Shakar and Scott Fitzgerald for the improvements The circuit: * potentiometers attached to analog inputs 0 and 1 * pushbutton attached to digital I/O 2 */
int firstSensor = 0; // first analog sensor int secondSensor = 0; // second analog sensor int thirdSensor = 0; // digital sensor int inByte = 0; // incoming serial byte void setup() { // start serial port at 9600 bps:
Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only }
}
pinMode(2, INPUT); // digital sensor is on digital pin 2 establishContact(); // send a byte to establish contact until receiver responds
void loop() {
MICROCONTROLADOR ATMEL
}
}
delay(300);
/* Processing sketch to run with this example: // This example code is in the public domain. import processing.serial.*; int bgcolor; // Background color int fgcolor; // Fill color Serial myPort; // The serial port int[] serialInArray = new int[3]; // Where we'll put what we receive int serialCount = 0; // A count of how many bytes we receive int xpos, ypos; // Starting position of the ball boolean firstContact = false; // Whether we've heard from the microcontroller void setup() { size(256, 256); // Stage size noStroke(); // No border on the next thing drawn // Set the starting position of the ball (middle of the stage) xpos = width/2; ypos = height/2;
MICROCONTROLADOR ATMEL
// clear the serial buffer and note that you've // had first contact from the microcontroller. // Otherwise, add the incoming byte to the array: if (firstContact == false) { if (inByte == 'A') { myPort.clear(); // clear the serial port buffer firstContact = true; // you've had first contact from the microcontroller myPort.write('A'); // ask for more } } else { // Add the latest byte from the serial port to array: serialInArray[serialCount] = inByte; serialCount++; // If we have 3 bytes: if (serialCount > 2 ) { xpos = serialInArray[0]; ypos = serialInArray[1]; fgcolor = serialInArray[2]; // print the values (for debugging purposes only): println(xpos + "\t" + ypos + "\t" + fgcolor); // Send a capital A to request new sensor readings: myPort.write('A'); // Reset serialCount:
MICROCONTROLADOR ATMEL
enviar cadenas codificadas como ASCII consume más bytes, lo cual significa que puedes enviar fácilmente valores mayores de 255 para cada lectura del sensor. Circuito.
Entradas analógicas conectadas a los pines analógicos 0 y 1. Interruptor conectado a la E/S digital 2. Esquema.
MICROCONTROLADOR ATMEL
Code /*
Serial Call and Response in ASCII Language: Wiring/Arduino This program sends an ASCII A (byte of value 65) on startup and repeats that until it gets some data in. Then it waits for a byte in the serial port, and sends three ASCII-encoded, comma-separated sensor values, truncated by a linefeed and carriage return, whenever it gets a byte in. Thanks to Greg Shakar and Scott Fitzgerald for the improvements The circuit: * potentiometers attached to analog inputs 0 and 1 * pushbutton attached to digital I/O 2 */
int firstSensor = 0; // first analog sensor int secondSensor = 0; // second analog sensor int thirdSensor = 0; // digital sensor int inByte = 0; // incoming serial byte void setup() {
MICROCONTROLADOR ATMEL
}
}
Serial.print(firstSensor); Serial.print(","); Serial.print(secondSensor); Serial.print(","); Serial.println(thirdSensor);
void establishContact() { while (Serial.available() <= 0) { Serial.println("0,0,0"); // send an initial string delay(300); } } /* Processing code to run with this example: // This example code is in the public domain. import processing.serial.*; // import the Processing serial library Serial myPort; // The serial port float bgcolor; float fgcolor; float
// Background color // Fill color // Starting position of the ball
MICROCONTROLADOR ATMEL
fill(fgcolor); // Draw the shape ellipse(xpos, ypos, 20, 20); } // serialEvent method is run automatically by the Processing applet // whenever the buffer reaches the byte value set in the bufferUntil() // method in the setup(): void serialEvent(Serial myPort) { // read the serial buffer: String myString = myPort.readStringUntil('\n'); // if you got any bytes other than the linefeed: myString = trim(myString); // split the string at the commas // and convert the sections into integers: int sensors[] = int(split(myString, ',')); // print out the values you got: for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) { print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t"); } // add a linefeed after all the sensor values are printed: println(); if (sensors.length > 1) { xpos = map(sensors[0], 0,1023,0,width);
MICROCONTROLADOR ATMEL
Solución de problemas con el Arduino ¿Por qué no puedo subir mis programas a la placa Arduino?
Hay algunas cosas que podrían no estar bien. En primer lugar asegúrate de que tu placa está encendida (el LED verde está encendido) y conectada al ordenador (si no es así, consulta la sección "¿qué pasa si mi placa no se activa?"). A continuación, comprueba que el puerto correcto se ha seleccionado en el menú Tools > Serial Port (si el puerto no aparece, reinicia el IDE con la placa conectada al ordenador). Asegúrate de que tiene el item correcto seleccionado en el menú Tools>Board. En particular, las nuevas placas Arduino Duemilanove vienen con un ATmega328, mientras que las antiguas tienen un ATmega168. Para comprobarlo, lee el texto impreso sobre el microcontrolador (el chip más grande) en tu placa Arduino. Para obtener más información sobre los ítems del menú Board, consulta la Guía para el entorno Arduino. Desconecta los pines digitales 0 y 1, mientras que secarga el firmware (pueden conectarse y utilizarse después de que el código se haya subido). Trata de cargar con nada más conectado a la placa (aparte del cable USB, por supuesto). Asegúrate que la placa no toca nada metálico o conductor. Comprueba que no estás ejecutando ningún programa que escanee todos los
MICROCONTROLADOR ATMEL
Si recibes este error: [VP 1] device is not responding correctly. Intenta cargar el programa otra vez (es decir, resetea la placa y pulse el botón de descarga por segunda vez). Asegúrate de que hay un bootloader en la placa Arduino. Para comprobarlo, conectar un LED al pin 13 (Arduino Duemilanove, Diecmila y Mega tienen un LED marcado con L que ya está conectado al pin 13) y resetea la placa. El LED debe parpadear. Si no es así, consulta la página del bootloader para obtener instrucciones sobre la grabación de un bootloader en la placa. Si tienes una placa Arduino muy antigua, puede que tengas que cambiar la velocidad de transmisión de carga de sketches a 9.600 (19.200 es lo normal, o 57.600 para Arduino Mega). Tendrás que cambiar la velocidad en el archivo preferences directamente. Ver la página sobre el fichero de preferencias para obtener instrucciones sobre cómo encontrarlo. Búscalo en tu equipo y cambia la propiedad serial.download_rate para que coincida con la de tu placa. Lo dicho, si tu placa es muy antigua (Arduino NG o anterior), se recomienda que actualices al último bootloader (que funciona a 19.200 baudios). Esto se puede hacer con el menú Tools > Burn Bootloader por medio de un programador de hardware externo. Si aún así no funciona, puedes pedir ayuda en el foro. Por favor incluye la siguiente información: Tu sistema operativo. ¿Qué tipo de placa es la que tienes? Si se trata de un Mini, LilyPad u opción que requiera cableado adicional, incluye una foto de tu circuito, si es posible. Independientemente de si fuiste capaz alguna vez de cargar software a la tarjeta.
MICROCONTROLADOR ATMEL
16.app/Contents/Resources/Java/librxtxSerial.jnilib: no matching architecture in universal wrapper @ @ Para solucionar este problema, haz click en la aplicación Arduino (por ejemplo, Arduino 16.app) en el Finder y selecciona Obtener Información de la casilla Archivo del menú. En el panel de información, haz click en la casilla Abrir en modo 32 bits. A continuación, deberías ser capaz de ejecutar Arduino normalmente. # StackOverflow ¿Por qué aparece un java.lang.StackOverflowError cuando intento compilar mi programa?
El entorno de desarrollo hace algunas transformaciones en el sketch de Arduino manipulando el código utilizando expresiones regulares. Esto a veces se confunde con ciertas cadenas de texto. Si aparece un error como: java.lang.StackOverflowError at java.util.Vector.addElement(Unknown Source) at java.util.Stack.push(Unknown Source) at com.oroinc.text.regex.Perl5Matcher._pushState(Perl5Matcher.java) esto es lo que está pasando. Puedes buscar secuencias inusuales que supongan "comillas dobles", "comilla simple", las barras invertidas \, comentarios, etc, en particular la secuencia '\ "' parece ser la causa problemas, se recomienda el uso de '"' en su lugar. Alimentación Externa ¿Porqué no arranca mi s k e t c h cuando estoy alimentando la tarjeta con una fuente de alimentación externa? (Arduino Diecimila o anterior)
Hay una serie de tarjetas Arduino antiguas (unas 1000) que presentan el problema de
MICROCONTROLADOR ATMEL
Bootloader equivocado ¿Porqué mi Diecimila necesita tanto tiempo (6-8 segundos) para iniciar mi s k e t c h ?
Algunas de las placas de Arduino Diecimila (unas 1000) salieron de fábrica accidentalmente con el bootloader Arduino NG, este es un error que en ningún caso debiera manifestarse en placas Arduino posteriores al año 2008. En cualquier caso, tu placa funciona bien, pero requiere hacer reset manual de la placa al subir un sketch y necesita de ese tiempo de espera. Se puede reconocer el bootloader NG porqué el LED en el pin 13 parpadeará tres veces al efectuar presionar el botón de reset en la placa (el bootloader de la Diecimila sólo parpadeará una vez). Puede el bootloader correcto en su Diecimila, consulte la página del bootloader para más detalles. Inicio ¿Qué debo hacer si me da un error al lanzar a r d u i n o . e x e en Windows?
Si obtienes un error al hacer doble click en el ejecutable arduino.exe en Windows, por ejemplo: @ @ Arduino has encountered a problem and needs to close. @ @ tendrás que poner en marcha Arduino utilizando el archivo run.bat situado en la misma carpeta. Por favor, ten paciencia, el entorno Arduino puede tomar algún tiempo para abrir según la configuración de tu ordenador. ¿Porqué no se ejecuta Arduino en las versiones anteriores de Mac OSX?
Si obtienes un error como este: Link (dyld) error: dyld: / Applications/arduino-0004/Arduino 04.app/Contents/MacOS/Arduino símbolos
MICROCONTROLADOR ATMEL
asegúrate de que descomprimiste correctamente el contenido del fichero Arduino.zip en particular, que el directorio lib está dentro del directorio Arduino y contiene el archivo pde.jar. ¿Qué puedo hacer al respecto de conflictos con c y g w i n en Windows?
Si ya tienes cygwin instalado en tu máquina, podrías obtener un error como este al intentar compilar un sketch en Arduino: @ @ [main] ? (3512) C:\Dev\arduino-0006\tools\avr\bin\avr-gcc.exe: *** fatal error C:\Dev\arduino-0006\tools\avr\bin\avr-gcc.exe: *** system shared memory version mismatch detected - 0x75BE0084/0x75BE009C. This problem is probably due to using incompatible versions of the cygwin DLL. Search for cygwin1.dll using the Windows Start->Find/Search facility and delete all but the most recent version. The most recent version *should* reside in x:\cygwin\bin, where 'x' is the drive on which you have installed the cygwin distribution. Rebooting is also suggested if you are unable to find another cygwin DLL. @ @ Si es así, primero asegúrate de que no tienes cygwin en ejecución cuando se utiliza Arduino. Si esto no funciona, puedes intentar eliminar las librerías cygwin1.dll del directorio Arduino y cambiarlas por cygwin1.dll de tu instalación existente de cygwin (probablemente en c: \ cygwin \ bin). ¿Porqué tardan el software Arduino y/o el menú Herramientas mucho tiempo en abrir (en Windows)?
Si el software Arduino tarda mucho tiempo en ponerse en marcha y parece bloquearse al intentar abrir el menú Herramientas, existe un conflicto con otro dispositivo en su sistema. El software de Arduino, al arrancar y al abrir el menú Tools, trata de obtener una lista de todos los puertos COM de tu ordenador. Es posible que un puerto COM creado por uno de los dispositivos de tu equipo ralentice este proceso. Echa un vistazo
MICROCONTROLADOR ATMEL
Asegúrate de configurar el IDE de Arduino para utilizar el nuevo puerto y buena suerte. " En Mac, si tienes una versión antigua de los controladores de FTDI, puede ser necesario borrarlos y reinstalar la última versión. Mas información en esta conversación del foro para instrucciones en cómo proceder (gracias a GCK). ¿Qué pasa si recibo una "gnu.io.PortInUseException" al cargar código o utilizando el monitor de serie (en Mac)?
Error inside Serial.() gnu.io.PortInUseExcepti gnu.io.Port InUseException: on: Unknown Application at gnu.io.Com gnu.io.CommPortIdentifier. mPortIdentifier.open(Comm open(CommPortIdentifier. PortIdentifier.java:354) java:354) at processing processing.app.Serial.(S .app.Serial.(Serial.java:127) erial.java:127) at processing processing.app.Serial.(S .app.Serial.(Serial.java:72) erial.java:72) Esto probablemente significa que el puerto está actualmente en uso por otra aplicación. Por favor, asegúrate de que no estás ejecutando otros programas con acceso al puerto serie o puertos USB de tu placa, como la aplicación de sincronización de PDA, los administradores de dispositivos bluetooth, ciertos servidores de seguridad, etc. Además, ten en cuenta que algunos programas (por ejemplo, Max/MSP Max/MSP o o Puredata Puredata)) mantienen el puerto serie abierto, incluso cuando no los usas - puedes necesitar cerrar todos los parches que usan el puerto serie o salir de la l a aplicación por completo. Si obtienes este error con Arduino 0004 o anterior, debieras actualizar a la última versión. Tengo problemas con los controladores USB FTDI.
Intenta instalar los controladores más recientes de FTDI o ponte en contacto con su
MICROCONTROLADOR ATMEL
basa su cálculo en un bootloader de de 1 Kb. Podrías tener bootloaders de mayor tamaño (p.ej. 2 Kb de los 8 Kb disponibles en tu placa). Si empleas placas Arduino oficiales, oficiales, este problema no se presentará. Si tienes acceso a un AVR-ISP, AVR-ISP-MKII, el programador de puerto paralelo, o cualquier otro dispositivo externo de programación de chips de la marca Atmel, puedes grabar la última versión del bootloader desde desde el menú Tools | Burn Bootloader. Bootloader. De lo contrario, puedes determinar en el entorno Arduino la cantidad de espacio disponible para tus programas editando la variable upload.maximum_size en su archivo de preferencias preferenci as (ver: instrucciones sobre cómo encontrar el archivo? archivo ?). Tamaño ¿Cómo puedo reducir el tamaño de mi s k e t c h ?
Los chips ATmega en la placa Arduino son barato, pero tienen limitaciones en el espacio reservado para tus programas: 7Kb para el ATmega8, 14Kb para el ATmega168 y ATmega328, y 124Kb para el ATmega1280 (el resto del espacio es usado por el ). bootloader ). Por ejemplo, un truco consiste en limitar que librerías usas. Si estás utilizando operaciones en coma flotante, trata de reescribir el código para usar números enteros, lo que debería ahorrar cerca de 2 Kb. Elimine los # include declaraciones include declaraciones en la parte superior de tu programa para eliminar las bibliotecas que no estás usando. También puedes tratar de hacer tu programa más corto. En cualquier caso, desde Arduino trabajamos para reducir el tamaño del núcleo de Arduino para dejar más espacio para tus programas. ¿Porqué no puedo obtener un PWM (una salida analógica) cuando llamo analogWrite () en los otros pines que 3, 5, 6, 9, 10 o 11? (Arduino Duemilanove y Diecimila)
El microcontrolador de la placa Arduino Duemilanove (ATmega328) y Diecimila
MICROCONTROLADOR ATMEL
¿Por qué recibo errores sobre un dispositivo de firma no válida cuando se trata de subir un s k e t c h ?
Si obtienes un error como: avrdude: Yikes! Invalid device device signature. signature. Double check connections connections and try again, or use -F to override this check. Puede significar una de dos cosas. Bien seleccionaste la placa equivocada en el menú Tools > Board Board o no estás usando la versión correcta de avrdude. Arduino utiliza una versión ligeramente modificada de avrdude para subir programas a la placa Arduino. La versión estándar consulta la firma del dispositivo en un modo que el bootloader no es capaz de comprender. Asegúrate de que estás utilizando la versión de avrdude que viene con Arduino
VIN
K
8 0 1
+5V
A 1
1 N R
CMP
8
B 2 1 N R 7 K 0 1
C1 100n 4
GND
X1 POWERSUPPLY _DC21MMX
L13
U5A
3
1
+3V3
8
2
LMV358IDGKR D M C _ E T A G
GND
SCK
1
K 1
A 2 N 1 R W LMV358IDGKR O L L E L Y U5B
5
7
6
3
3 2
1
2
3
VIN D1 M7 PC1 + 47u
PWRIN
IN OUT
1
+5V 1 P T 0 4 3 N D F
3 2
IN
OUT
C3 1u
ON/OFF GND NC/FB
4
+5V
1 2 3 4 5 6 7 8
RESET
GND
M 4 2 N M 2 3 1 2 x P 2 J
ICSP1
3x2 M
X2 1
B 2 S 2 1 3 $ $ 4 U P P 2 1 $ $ P P
XUSB
D N G 1 U Z
USHIELD
1 L
C 3 1 3 N D R 6 K GND 0 1
5 7 5 1 0 S 6 0 2 1 D C
RESET2 p USBVCC 1 2 1 2 XT2 MF-MSMF050-2 500mA C z 1 H 1 Y p 22R RN3A D 9 2 M R1 8 1 N 2 6 1M DRD- G C 1 D+ XT1 2 22R E E 5 RN3D 4 RD+ 5 5 0 0 +5V C C L L M M 3 3 0 2 0 6 Z 6 0 0 G G C C TP_VUCAP USBVCC RDRD+ 100n 1 UGND C7 2 M L 2 1 C8 B 1u GROUND GND GND F1
USB-B_TH
MOSI2
2 1
XT1
4 3
27 31 30 29 28 33
AVCC
VCC GND
UCAP UVCC DD+ UGND PAD
(INT4/ICP1/CLK0)PC7 (OC1A/PCINT8)PC6 (PCINT9/OC1B)PC5 (PCINT10)PC4 (AIN2/PCINT11)PC2 (CTS/HWB/AIN6/TO/INT7)PD7 (RTS/AIN5/INT6)PD6 (XCK/AIN4/PCINT12)PD5 (INT5/AIN3)PD4 (TXD1/INT3)PD3 (RXD1/AIN1/INT2)PD2 (AIN0/INT1)PD1 (OC0B/INT0)PD0
GND
21 PB7 20 PB6 19 PB5 18 PB4 17 MISO2 16 MOSI2 15 SCK2 14
22 23 25 26 5 13 12 11 TXLED 10 RXLED 9 M8RXD 8 M8TXD 7 6
5
GREEN ON
RN4D 1K 3
D N G
6
RN4C 1K
GND 5 2 1
R2 1M n E D 4 t 2 o o N b R 5 B K S 1 U GND
10
XTAL2
9 XTAL1 XTAL1 CSTCE16M0V53-R016MHZ AREF 21 AREF
+5V
20 22
7 8
C6 100n
AVCC AGND VCC GND
1K 6 RN2C 3
GND
TX YELLOW 7
RX YELLOW
RN2B
1K
2
+5V
GND ICSP 1 3 5
C4 2 4 6
100n
3x2 M
(SCK)PB5 (MISO)PB4 (MOSI)PB3 (SS)PB2 (OC1)PB1 (ICP)PB0 (ADC5)PC5 (ADC4)PC4 (ADC3)PC3 (ADC2)PC2 (ADC1)PC1 (ADC0)PC0) (AIN1)PD7 (AIN0)PD6 (T1)PD5 (T0)PD4 (INT1)PD3 (INT0)PD2 (TXD)PD1 (RXD)PD0
+5V
ATMEGA16U2-MU(R)
Arduino(TM) UNO Rev3
4
8x1F-H8.5
T E S 0 E 6 R 2 RESET-EN 7 +5V 1 2 5 7 R n K 5 T 0 5 0 0 1 R 5 1 0 0 C 1 2 D S D - 6 1 6 1 0 1 4 N R 2 3 ZU4 1 01 RESET R D 2 RESET T C 4 D GND S XTAL2 T
U3
24
32
GND
4 3
(PCINT7/OC0A/OC1C)PB7 (PCINT6)PB6 RESET(PC1/DW) (PCINT5)PB5 (T1/PCINT4)PB4 (PD0/MISO/PCINT3)PB3 XTAL2(PC0) (PDI/MOSI/PCINT2)PB2 (SCLK/PCINT1)PB1 XTAL1 (SS/PCINT0)PB0
GND
POWER
VIN
2 4 6
PC2 C2 47u 100n
+5V
+3V3
+5V
1 3 5
+
GND
5 +3V3
GND
MISO2 SCK2 RESET2
+5V
GND GND
USBVCC
+5V
4 2
1
GND
+5V
U1 NCP1117ST50T3G
GND
19 18 17 16 15 14 28 27 26 25 24 23 13 12 11 6 5 4 3 2
AREF GND
10x1F-H8.5 AD5/SCL10 SCL AD4/SDA 9 SDA SCK MISO MOSI SS
SS IO9 IO8 AD5/SCL AD4/SDA AD3 AD2 AD1 AD0 IO7 IO6 IO5 IO4 IO3 IO2 IO1 IO0
8 7 6 5 4 3 2 1
IOH 6x1F-H8.5 6 5 4 3 2 1
1K 7 RN4B 2
M8TXD
1K 8 RN4A 1
2
8 7 6 5 4 3 2 1
IOL
7
RN3B 22R 3
6
RN3C 22R
AD 8x1F-H8.5
ATMEGA328P-PU M8RXD
13 12 11 10 9 8
7 6 5 4 3 2 1 0
SCK MISO
2 4 T S T 3 4 E S E R
+5V
GND
ICSP
ICSP
1 3 5
1 2 5
RESET
2 4 6
M N
_ MOSI M 2 x 3
+5V 5 7 K 5 0 1 5 1 0 2 D S D 6 1 0 4 N 2 R 1 D RESET C
p 3 2 C 2
D N G
C2
100n
100n
+5V U1 34 43 13
AGND
R1 1M 16MHz KX-7
MH2029-300Y
42 14 15 23 35 6 2 3 4 5 7
AREF
C5 100n
D N G
1uF
D N G
C6 UCAP
C7
D N G A
GND
RDRD+
1uF
XTAL1
44 AVCC1 24 AVCC
AVCC
UGND
AGND
R2
(INT6/AIN0)PE6 (#HWB)PE2 (T0/OC4D/ADC10)PD7 (T1/#OC4D/ADC9)PD6 (XCK1/#CTS)PD5 (ICP1/ADC8)PD4 (TXD1/INT3)PD3 (RXD1/AIN1/INT2)PD2 (SDA/INT1)PD1 (OC0B/SCL/INT0)PD0 (ADC7/TDI)PF7 (ADC6/TDO)PF6 (ADC5/TMS)PF5 (ADC4/TCK)PF4
VUSB
R3
NM
(ICP3/CLK0/OC4A)PC7 (OC3A/#0C4A)PC6
AREF VCC GND GND1 GND2 UCAP UVCC DD+ UGND VBUS
VUSB
NM D N G
EXP
GND
D N G U
PAD (ADC1)PF1 (ADC0)PF0
GND GND
12 30 29 28 11 10 9 8
(PCINT7/OC0A/OC1C/#RTS)PB7 (PCINT6/OC1B/OC4B/ADC13)PB6 (PCINT5/OC1A/#OC4B/ADC12)PB5 (ADC11/PCINT4)PB4 (PD0/MISO/PCINT3)PB3 (PDI/MOSI/PCINT2)PB2 (SCLK/PCINT1)PB1 (SS/PCINT0)PB0
XTAL2
17
XTAL1 L1
p 4 2 2 C
U2
VCC1 GND3 RESET
16
XTAL2
Y1
D N G
C1
IO11* IO10* IO9* IO8 MISO MOSI SCK RXLED IO13* D5*
1 33
D7 HWB
27 26 22 25 21 20 19 18
D6* IO12 TXLED D4 D1/TX D0/RX D2/SDA D3/SCL A0 A1 A2 A3
40 41
A4 A5
VCC1 GND3 RESET
XTAL2 16
XTAL2
XTAL1 17
XTAL1
(PCINT7/OC0A/OC1C/#RTS)PB7 (PCINT6/OC1B/OC4B/ADC13)PB6 (PCINT5/OC1A/#OC4B/ADC12)PB5 (ADC11/PCINT4)PB4 (PD0/MISO/PCINT3)PB3 (PDI/MOSI/PCINT2)PB2 (SCLK/PCINT1)PB1 (SS/PCINT0)PB0
AVCC 44 AVCC1
32 31
36 37 38 39
+5V 34 AGND 43 RESET13
24
AREF 42 +5V 14 GND 15 GND 23 GND 35 UCAP 6 2 +5V 3 RD4 RD+ UGND 5 VUSB 7
GND P$1
(ICP3/CLK0/OC4A)PC7 (OC3A/#0C4A)PC6
AVCC AREF VCC GND GND1 GND2 UCAP UVCC DD+ UGND VBUS
(INT6/AIN0)PE6 (#HWB)PE2 (T0/OC4D/ADC10)PD7 (T1/#OC4D/ADC9)PD6 (XCK1/#CTS)PD5 (ICP1/ADC8)PD4 (TXD1/INT3)PD3 (RXD1/AIN1/INT2)PD2 (SDA/INT1)PD1 (OC0B/SCL/INT0)PD0
ATMEGA32U4-XUMU
IO11* IO10* IO9* IO8 MISO MOSI SCK RXLED
32 31
IO13* D5*
1 33
D7 HWB
27 26 22 25 21 20 19 18
D6* IO12 TXLED D4 D1/TX D0/RX D2/SDA D3/SCL
(ADC7/TDI)PF7 (ADC6/TDO)PF6 (ADC5/TMS)PF5 (ADC4/TCK)PF4
36 A0 37 A1 38 A2 39 A3
(ADC1)PF1 (ADC0)PF0
40 A4 41 A5
PAD
GND
12 30 29 28 11 10 9 8
IO11* IO10* IO9* IO8 MISO MOSI SCK
F1
XUSB
P1 XUSB P2 DP3 D+ P4USBID P5
VUSB MF-MSMF050-2 500mA
2
5
4
8
1
3 2 1 0 5 . 1 1 1 1 9 8 8 H F 1 x 0 9 8 7 6 5 4 3 2 1 1 0 1 P 1 J
7
RN3B 22R 6
RD-
22R RN3D
3
RD+
3
VUSB E 5 0 C L M 3 0 2 6 Z 0
UGND 1 Z
G C
100n
C8 + 10u
C9
1 1
3
IN OUT
3
VIN
4 2
2
1 7 D M
VIN
+
C10 10u
+5V
8
C13 100n
A 1 1 N R 8 K 0 1
GND
+5V
GND
5 6
GND
7
C22 100n
GND
+5V
IC2B GATE_CMD
1
LMV358IDGKR
K 0
7 1
B 1 N 2 R
4
C12 10u
+5V AUTO SELECTOR +3V3
3
VUSB
2
T1 FDN340P
T 3 E V F S 3 E E + U R F R
O R I 3 J
N I V
+PWM COMPL IO10
+A7
PWM 16bit COMPL D6
#PWM 10bit
D N G
7 6# 5# 4 3# 2 1 0
+AIN0 +A8
#PWM Hi-Speed #PWM Hi-Speed
+A6
#PWM 8bit
C11 GND 1u GND
IN
OUT
5
+3V3 C14 1u
ON/OFF GND NC/FB
4
GND
3
IC2A 1
2 5 . 8
LMV358IDGKR 7 6 5 4 3 2 1 0
H F 1 8 7 6 5 4 3 2 1 x 2 8 J L A X C D X S S T / R * * / / / 7 6 5 4 3 2 1 0 D D D D D D D D
+5V
B 2 2 N R 7 K 1 5 4 3 2 1 0 A A A A A A
ORIGIN
LL
w o l l e L Y
C 3 2 N R 6 K 1
w o l l X e T Y
D 4 2 N R 5 K 1
A 1 2 N K R 1 8
w o l l X e R Y
n e e N r O G
GND 5 . H F 1 x 8
+
CMP
D N G
1 2 3 4 5 6 7 8 8
GND
VIN
* * * 3 2 1 0 * 1 1 1 1 9 8 O O O O O O I I I I I I
V 5 +
GND
GND GND
+5V
ALT3
+A11 +A10 +A9
12
F E D R N A G
NCP1117ST50T3G
2
GND GND
IC1
1
EXTPOWER POWERSUPPLY_DC21MMX
E 5 0 C L M 3 0 6 0 G C
L A C D S S / / 3 2 D D
22R RN3C
22R RN3A
USB MICRO MH2029-300Y GND UGND L2
ALT2
ATMEGA32U4-XUAU
NOT USED
J1 VBUS SH1 DSH2 D+ SH3 ID SH4 GND SH5 SH6
13
D7 D6* D5* D4 D3/SCL D2/SDA D1/TX D0/RX
IO13*
S1 S2 S3 S4 S5 S6
#PWM 8/16bit #PWM 16bit #PWM 16bit
UGND
USB
GND
ALT1
11# 10# 9# 8
TO ICSP
IO13* USB boot En 10K 6 RN1C 3
IO
5 4 . 8 6 5 4 3 2 1 J H F 1 x 6
TXLED RXLED GND