Capitulo I Estructura: Estructuras de Control Operadores Booleanos

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 108

MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

CAPITULO I
Estructura
 setup() (inicialización)
 loop() (bucle) Operadores Booleanos

Estructuras de control  && (y)

 if (comparador si-entonces)  || (o)

 if...else (comparador si...sino)  ! (negación)

 for (bucle con contador) Operadores de Composición

 switch case (comparador múltiple).  ++ (incrementa)

 while (bucle por comparación booleana)  -- (decrementa)

 do... while (bucle por comparación  +=(composición suma)


booleana)  -= (composición resta)
 break (salida de bloque de código)  *=(composición multiplicación)
 continue (continuación en bloque de  /= (composición división)
código)
 return (devuelve valor a programa)
Sint axis
 ; (punto y coma)
 {} (llaves)
 // (comentarios en una línea)
 /* */ (comentarios en múltiples líneas)
Operadores Arit m éticos
 = (asignación)
 + (suma)
 -(resta)
 *(multiplicación)
 / (división) % (resto)
Operadores Comparativos Referencia del Lenguaje C/C++
 == (igual a)
Los programas hechos con Arduino se
 != (distinto de) dividen en tres partes principales:
estructura, valores (variables y
 < (menor que)
constantes), y funciones. El Lenguaje de
 > (mayor que) programación Arduino se basa en C/C++.
 <= (menor o igual que)
 >= (mayor o igual que)

Pag 97
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, o cuando se pulse el botón de reinicio de la placa.
Ejemplo
int buttonPin = 3;
void setup()
{
Serial.begin(9600);
pinMode(buttonPin, INPUT);
}
void loop()
{
// ...
}
loop()
Luego de crear la función setup(), la cual inicializa y prepara los valores inciales, la
función loop() hace justamente lo que su nombre sugiere, por lo tanto se ejecuta
consecutivamente, permitiéndole al programa variar y responder. Úsala para
controlar de forma activa la placa Arduino.
Ejemplo
int buttonPin = 3;
// setup inicializa la comunicación serial y el buttonPin
void setup()
{
beginSerial(9600);
pinMode(buttonPin, INPUT);
}
// loop obtiene el estado del pin del botón cada vez,
// y de estar presionado, lo comunica por serial.
void loop()
{
if (digitalRead(buttonPin) == HIGH)

Pag 98
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

serialWrite('H');
else
serialWrite('L');
delay(1000);
}
1.1 Es tr u ctur as de con tr ol

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 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.
Las llaves pueden ser omitidas luego de una declaración if. De hacer esto, la siguiente
línea (definida por el punto y coma) será la única afectada por la condición.
if (x > 120) digitalWrite(LEDpin, HIGH);
if (x > 120)
digitalWrite(LEDpin, HIGH);
if (x > 120){ digitalWrite(LEDpin, HIGH); }
if (x > 120){
digitalWrite(LEDpin1, HIGH);
digitalWrite(LEDpin2, HIGH);
}
// 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)

Pag 99
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,
por permitir agrupar múltiples comprobaciones. Por ejemplo, un input análogo podría
ser comprobado, y tomarse una acción si el valor del inputes menor a 500, y, otra
acción se ser igual o mayor a 500. El código se vería así:
if (pinCincoInput < 500)
{
// acción A
}
else
{
// acción B
}
else puede proceder a una comprobación if, de esta forma, se pueden realizar
múltiples comprobaciones en una misma estructura de condiciones. Cada
comprobación procederá a la siguiente, sólo cuando su propio resultado sea FALSE.
Cuando el resultado sea TRUE, su bloque de código contenido, será ejecutado, y el
programa esquivará las siguientes comprobaciones hasta el final de la estructura de
comprobaciones. Si ninguna comprobación devuelve valor TRUE, el else será
ejecutado, y de no haber ninguno declarado, simplemente no sucede nada.

Pag 100
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


Descripción
La declaración for es usada para repetir un bloque encerrado entre llaves.
Un incremento de un contador es usado, normalmente, para aumentar y terminar
con el bucle. La estructura for es muy útil para la mayoría de las operaciones
repetitivas, y habitualmente se usa para operaciones con vectores, para operar
sobre conjuntos de datos/pines
El bucle for tiene tres partes o argumentos en su inicialización:
for (initialization; condition; increment) {
//función(es);
}

Pag 101
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 ons ejos de pr ogr amación
El bucle for, en C, es mucho más flexible que otros bucles for en otros lenguajes,
incluyendo BASIC. Cualquiera (o todos) los parámetros pueden ser omitidos, sin
embargo los puntos y coma (;) son obligatorios. También las inicialización, condición
e incremento pueden ser cualquier declaración en C válida, con variables
independientes, y podemos usar cualquier tipo de variable, incluídos los float. Estos
tipos de declaración for poco usuales pueden proporcionar una solución válida a
algunos problemas de programación raros.
Por ejemplo, usando la multiplicación en el parámetro de incremento, podemos
generar una progresión logarítmica.
for(int x = 2; x < 100; x = x * 1.5){
println(x);
}
Este código generará: 2,3,4,6,9,13,19,28,42,63,94
Otro ejemplo es hacer apagarse/encenderse un LED poco a poco, Another example,
fade an LED up and down with one for loop:
void loop()
{
int x = 1;

Pag 102
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
break;
case 2:
//hacer algo cuando sea igual a 2
break;
default:
// si nada coincide, ejecuta el "default"
// el "default" es opcional
}

Sintaxis
switch (var) {
case etiqueta:
// sentencias
break;
case etiqueta:
// sentencias

Pag 103
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
Ver tambié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.
Sintax is
while(expresion){
// sentencia(s)
}
Parámetros
expresion - una sentencia C (booleana) que da como valor verdadero (true) o
falso (false)
Ejemplo
var = 0;
while(var < 200){
// haz algo repetitivo 200 veces
var++;
}

Pag 104
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
condición normal del bucle. Es usado también para salir de una estructura de control
switch.
Ejemplo
for (x = 0; x < 255; x ++)
{
digitalWrite(PWMpin, x);
sens = analogRead(sensorPin);
if (sens > threshold){ // bail out on sensor detect
x = 0;
break; // sale del bucle for.
}
delay(50);
}

Pag 105
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.
Sintax is
return;
return valor; // ambas formas son correctas
Parámetros
valor: cualquier variable o tipo constante
Ejemplos
Una función que compara la entrada de un sensor a un umbral
int comprobarSensor(){
if (analogRead(0) > 400) {
return 1;
else{
return 0;
}
}
La palabra clave return es útil para depurar una sección de código sin tener que
comentar una gran cantidad de líneas de código posiblemente incorrecto.

Pag 106
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
en el punto de inserción que sigue inmediatamente a una llave, y su compañera
lógica será seleccionada.
En la actualidad esta característica tiene un pequeño fallo, el IDE encuentra a menudo
(incorrectamente), llaves en el texto que pueden estar situadas dentro de
comentarios.
Los programadores principiantes y los programadores que llegan a C desde el
lenguaje BASIC a menudo encuentran dificultades o grandes confusiones usando
llaves. Después de todo, las llaves reemplazan el RETURN en una subrutina (función),
el ENDIF en un condicional y el NEXT en un loop FOR.
Dado que el uso de las llaves es tan variado, es una buena práctica de programación
escribir la llave de cierre inmediatamente después de escribir la llave de apertura,
cuando se inserta una construcción que requiere llaves. Después insertar algunos
saltos de línea (líneas en blanco) entre las llaves y comenzar a insertar sentencias. De
esta forma tus llaves y su posición, nunca llegarán a estar desemparejadas.
Llaves desemparejadas a menudo pueden conducir a errores de compilación
misteriosos y difíciles de comprender, que pueden ser complicados de rastrear en un
programa largo. Debido a sus variados usos, las llaves también son increíblemente
importantes para la sintaxis de un programa, el movimiento de una llave una o dos
líneas, a menudo afecta de manera dramática el significado de un programa.

Pag 107
MICROCONTROLADOR ATMEL

U s os pr in cipales de las L lav es


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)
}
Sentencias Condicionales
if (expresión booleana)
{
sentencia(s)
}
else if (expresión booleana)
{
sentencia(s)
}
else
{
sentencia(s)
}

Pag 108
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
*/

Consejo
Cuando estás experimentando con código, "comentar" partes del programa es una útil
de eliminar líneas que puedan contener errores. Así dejamos las líneas en el código,
pero como comentario, así que serán ignoradas por el compilador. Es especialmente
útil cuando estamos intentando localizar el problema, o cuando el compilador rechaza
el programa.
1.2 Operadores Ar itméticos

1.2.1 = operador de asignación (un solo símbolo de "igual")


Guarda el valor en la derecha del símbolo "=" dentro de la variable a la izquierda del
símbolo "=".
El signo de igualdad "=" en el lenguaje de programación C se llama el operador de
asignación. Tiene un significado diferente que en la clase de álgebra en el que se
indica una ecuación o igualdad. El operador de asignación le dice al microcontrolador
que evalúe cualquier valor o expresión en el lado derecho del signo igual, y lo
almacene en la variable a la izquierda del signo igual.

Pag 109
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
Sugerencias de programació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.
Ver tambié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
resultado es mayor que el que se puede almacenar en el tipo de datos (por ejemplo,
la suma de 1 a un int con el valor de 32.767 resulta -32.768). Si los operandos son
de tipos diferentes, se utiliza el tipo del "más grande" para el cálculo.
Si uno de los números (operandos) es del tipo float o del tipo double, se usará coma
flotante para el cálculo.
Ejemplos
y = y + 3;
x = x - 7;
i = j * 6;
r = r / 5;
Sintax is
result = value1 + value2;
result = value1 - value2;
result = value1 * value2;

Pag 110
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

result = value1 / value2;

Parámetros:
value1: cualquier variable o constante
value2: cualquier variable o constante
Sugerencias de programació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
dentro de un rango particular (por ejemplo el tamaño de un array)
Sintax is
resultado = dividendo % divisor
Parametros
Dividendo: el número que se va a dividir
Divisor: el número por el que se va a dividir
Devuelve
el resto de la división
Ejemplo
x = 7 % 5; // x ahora contiene 2
x = 9 % 5; // x ahora contiene 4
x = 5 % 5; // x ahora contiene 0
x = 4 % 5; // x ahora contiene 4
Código de ejemplo
/* actualiza un valor en el array cada vez que se pasa por el bucle */
int valores[10];

Pag 111
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éase también
división

1.3 Oper ador es C o mpar at iv os


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)
{
// hacer 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.
Las llaves pueden ser omitidas luego de una declaración if. De hacer esto, la
siguiente línea (definida por el punto y coma) será la única afectada por la
condición.
if (x > 120) digitalWrite(LEDpin, HIGH);
if (x > 120)
digitalWrite(LEDpin, HIGH);
if (x > 120){ digitalWrite(LEDpin, HIGH); }
if (x > 120){
digitalWrite(LEDpin1, HIGH);
digitalWrite(LEDpin2, HIGH);
}

Pag 112
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
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.4 O pe r ador e s B o ole an os


1.4.1 Operadores Booleanos.
Se pueden usar dentro de operaciones condicionales o en una sentencia if.
1.4.1.1 && (AND lógico)
Verdadero sólo si ambos operadores son Verdadero, por ejemplo:
if (digitalRead(2) == HIGH && digitalRead(3) == HIGH) { // lee dos
pulsadores
// ...
}
Es Verdadero sólo si ambas entradas estás activadas, es decir, en estado HIGH.
1.4.1.2 || (OR lógico)
Verdadero si alguno de los dos operadores es Verdadero, por ejemplo:

Pag 113
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 y
20
Ver también:
& (operador de bits AND)
| (operador de bits OR)
~ (operador de bits NOT)
if

1.4.1.4 Operadores bit a bit: AND (&), OR (|) y XOR (^)


Los operadores bit a bit realizan sus cálculos a nivel de los bits de las variables.
Ayudan a resolver muchos de los problemas más comunes a nivel de programación.
La mayoría del material que sigue está sacado de un excelente tutorial de matemática
lógica, que puede ser encontrado aquí.
De s c r ipc ión y s in t ax is
A continuación se muestras las descripciones y la sintaxis de estos operadores
lógicos. Puedes encontrar más información sobre ellos en el tutorial enlazado sobre
estas líneas.

Pag 114
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.
Uno de los usos más comunes de este operador es seleccionar un determinado
(o determinados) bits dentro de un valor entero, también llamado
enmascaramiento (masking). Más abajo se incluye un ejemplo.
1 . 4 . 1 . 6 O p e r a d o r b i t a b i t O R (| )
Este operador, en C++, se simboliza como una barra vertical, |. Como el
operador AND, este operador trabaja de forma de forma independiente cada
pareja de bits. Sin embargo, lo que hace (lógicamente) es diferente: el
operador OR devuelve un 1, si alguno (o los dos bits) es un 1; mientras que
sólo devuelve un 0 si ambos bits lo son. En otras palabras:
0 0 1 1 operando1
0 1 0 1 operando2
----------
0 1 1 1 (operando1 | operando2) - valor devuelto

A continuación un ejemplo de uso de este operador:


int a = 92; // en binario: 0000000001011100
int b = 101; // en binario: 0000000001100101
int c = a | b; // resultado: 0000000001111101, 125 en decimal.

Pag 115
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

Programa de ejemplo
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(){
DDRD = DDRD | B11111100; // configura los bits (pines) a 1 como salida, sin
tocar el 0 y el 1
// es lo mismo que hacer pinMode(pin, OUTPUT), pero de una sola vez.
Serial.begin(9600);
}
void loop(){
for (i=0; i<64; i++){
PORTD = PORTD & B00000011; // borra todos los bits excepto los dos
primeros, 0 y 1.
j = (i << 2); // desplaza dos posiciones la variable, introduciendo 0 por la
derecha,
// para no interferir con el valor de esos pines
PORTD = PORTD | j; // combina la información del puerto con la nueva para los
pines del LED

Serial.println(PORTD, BIN); // sirve para comprobar la máscara


delay(100);
}

Pag 116
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.
// Blink_Pin_5
// ejemplo de OR exclusiva
void setup(){
DDRD = DDRD | B00100000; // pin 5 configurado como salida,
pinMode(5, OUTPUT);
Serial.begin(9600);
}
void loop(){
PORTD = PORTD ^ B00100000; // invierte el bit 5 (pin digital 5) y
los no modifica el resto
delay(100);
}
Ver también
&&(AND booleana)
||(OR booleana)

Pag 117
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
A veces, el bit de signo en un entero con signo (signed int) puede causar
algunos problemas imprevistos.

1.5 Operadores de Composición

1.5.1 ++ (incremento) / -- (disminución)


Descripción
Incrementa o disminuye una variable
Sintax is
x++; // incrementa x en uno y regresa el valor anterior de x
++x; // incrementa x en uno y regresa el nuevo valor de x

x-- ; // disminuye x en uno y y regresa el valor anterior de x


--x ; // disminuye n uno y regresa el nuevo valor de x
Parámetros
x: un entero o long (puede aceptar sin signo)

Pag 118
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; // x ahora guarda 3, y guarda 3
y = x--; // 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.
Sintax is
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;

Parámetros
x: cualquier tipo de variable
y: cualquier tipo de variable o constante
Ejemplos
x = 2;
x += 4; // x ahora es 6
x -= 3; // x ahora es 3
x *= 10; // x ahora es 30
x /= 2; // x ahora es 15

Pag 119
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

CAPITULO II

Variables
C ons t an t es
HIGH | LOW
INPUT | OUTPUT
true | false
Constantes Numéricas
Tipos de Datos
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)
double (en coma flotante de 32b)
string (cadena de caracteres)
array (cadena)
void (vacío)
Conversión
char()
byte()
int()
long()
float()

Pag 120
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

2.0 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.
2.1.3 HIGH
El significado de HIGH (en referencia a un pin) depende de si el pin está
configurado como entrada (INPUT) o como salida (OUTPUT). Cuando un pin se
configura como entrada (INPUT) usando pinMode, y se lee con digitalRead, el
microcontrolador nos retornará HIGH si en el pin hay 3 voltios o más.
Un pin puede ser configurado como entrada (INPUT) usando pinMode, y
después establecerlo a HIGH con digitalWrite, esto conectará el pin a 5 Voltios
a través de una resistencia interna de 20K, resistencia pull-up , la cual
establecerá el pin al estado de lectura HIGH a menos que la conectemos a una
señal LOW a través de un circuito externo.
Cuando un pin se configura como salida (OUTPUT) con pinMode, y se establece
a HIGH con digitalWrite, el pin tiene 5V. Ene ste estado puede usarse como
fuente de corriente, e.j. Luz y LED que se conectan a través de resistencias en
serie a masa (tierra), o a otro pin configurado como salida y establecido a LOW.
2.1.4 LOW
El significado de LOW difiere también según esté configurado como entrada
(INPUT) o como salida (OUTPUT). Cuando un pin está configurado como
entrada (INPUT) con pinMode, y se lee con digitalRead, el microcontrolador
retornará LOW si el voltaje presente en el pin es de 2V o menor.

Pag 121
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.
Pins configurados como entradas
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.
Pins configurados como salidas
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
necesario añadir circuitería extra.
Ver
pinMode()
Integer Constants
boolean variables
NOTA:
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.
Sint axis
pinMode(pin, modo)
Parametros
pin: el numero del pin que se desea configurar
modo: INPUT (Entrada) o OUTPUT (Salida)
Devuelve
Nada

Pag 122
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

Ejemplo

int ledPin = 13; // LED conectado al pin digital 13


void setup()
{
pinMode(ledPin, OUTPUT); //configura el pin del LED como salida
}
void loop()
{
digitalWrite(ledPin, HIGH); // Enciende el LED
delay(1000); // espera un segundo
digitalWrite(ledPin, LOW); // Apaga el LED
delay(1000); // Espera un segundo
}

Pag 123
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, 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 Comentario
10 (decimal) 123 Ninguno.
2 (binario) B1111011 Antecede "B" Sólo funciona con valores de 8 bits (0 to 255).
Caracteres 0-1 válidos.
8 (octal) 0173 Antecede "0" Caracteres 0-7 válidos.
16 (hexadecimal) 0x7B Antecede "0x" 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:
B101 // igual a 5 decimal ((1 * 2^2) + (0 * 2^1) + 1)
El formateador binario sólo funciona en bytes (8 bits) entre 0 (B0) y 255
(B11111111). Si resulta conveniente ingresar un entero (int, 16 bits) de forma
binaria, puedes hacer un procedimiento de dos pasos, como a continuación:
valorInt = (B11001100 * 256) + B10101010; // B11001100 es el ''byte'' alto.

Octal es base ocho. Sólo caracteres de 0 hasta 7 son válidos. Los valores
Octales son indicados por el prefijo "0"
Ejemplo:
0101 // igual a 65 decimal ((1 * 8^2) + (0 * 8^1) + 1)
Atención
Es posible generar un bug o error difícil de encontrar al incluír (de forma
involuntaria) un cero antecediento una constante, logrando así que el
compilador interprete tu constante como octal.

Hexadecimal (ó hex) es base dieciséis. Los caracteres válidos son del 0 al 9,


y las letras desde la A hasta la F; A tiene el valor de 10, B es 11, C es 12, D es

Pag 124
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

13, E es 14, y la F, como ya habrás adivinado, es 15. Los valores


hexadecimales 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 int con las limitaciones
concomitantes 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
byte
int
unsigned int
long
unsigned long

Pag 125
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()
{
if (digitalRead(switchPin) == LOW)
{ // si el pulsador es accionado la pull-up mantiene el pin en estado
HIGH
delay(100); // retardo para impedir un rebote en el
pulsador
running = !running; // invierte el valor de la variable
running
digitalWrite(LEDpin, running) // enciende el LED
}
}
2.2.2 char
Descripción
Es un tipo de dato que ocupa un byte de memoria y almacena un valor de
carácter. Los carácteres literales se escriben con comillas simples: 'A' (para
varios carácteres -strings- utiliza dobles comillas "ABC").
De todas maneras los carácteres son almacenados como números. Puedes ver
su codificado en la tabla ASCII. Con esto podemos entender que es posible
realizar cálculos aritméticos con los carácteres, en este caso se utiliza el valor
ASCII del carácter (por ejemplo 'A' + 1 tiene el valor de 66, ya que el valor

Pag 126
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
Descripción
Los enteros sin firma (unsigned int) son los mismos enteros de modo que
almacenan un valor de dos bytes. En lugar de almacenar números negativos,
sólo almacenan valores positivos, generando un rango útil desde 0 a 65,535
(2^16 - 1).
La diferencia entre los enteros sin firma y los enteros (firmados), reside en que
el bit más alto, a veces referenciado como el bit "firmado", es interpretado. En
el tipo de dato int de Arduino (que es firmado), si el bit más alto es "1", el
número es interpretado como un número negativo, y los otros 15 bits son
interpretados con complemento a 2.
Ejemplo
unsigned int ledPin = 13;
Sintáx is
unsigned int var = val;
var - el nombre de tu variable unsigned int
val - el valor que asignas a a esa variable

Pag 127
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

Consejo de codificació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'
Sintax is
long var = val;

2.2.7 unsigned long


Descripción
Las variable long sin firmar (unsigned long) son variables extendidas para
almacenar números, y almacenar 32 bits (4 bytes). Por el contrario que las
variables long estándar, las unsigned long no almacenan números negativos,
haciendo que su rango sea de 0 a 4,294,967,295 (2^32 - 1).
Ejemplo
unsigned long tiempo;
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print("Tiempo: ");
tiempo = millis();
//imprime el tiempo desde el inicio del programa
Serial.println(tiempo);

Pag 128
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

// espera un segundo para no enviar cantidade masivas de datos


delay(1000);
}
Sintáx is
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.
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 velocidad para funciones con temporizaciones precisas.
Los programadores normalmente suelen asignar unas longitudes para convertir las
operaciones de coma flotante en cálculos con enteros, para aumentar la velocidad.
Ejemplos
float myfloat;
float sensorCalbrate = 1.117;
Sintax is
float var = val;
var - el nombre de la variable tipo float
val - el valor que le asignas a esa variable
Código de ejemplo
int x;
int y;
float z;

Pag 129
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'};
char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
char Str4[ ] = "arduino";
char Str5[8] = "arduino";
char Str6[15] = "arduino";

Posibilidades de declaración de strings


Declarar un array de caracteres sin incializarlo como en Str1
Declarar un array de caracteres (con un caracter extra) y el compilador añadirá
el caracter NULL requerido, como en STR2
Explicitar el caracter NULL, Str3
Inicializar con un string constante entre comillas dobles; el compilador medirá
el tamaño del array para ajustar el string constante y caracter NULL para
finalizar, Str4
Inicializar el array con un tamaño explícito y un string constante, Str5
Inicializar el array, dejando un espacio extra para un string más largo, Str6

Pag 130
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"
" esta es la segunda linea"
" etcetera";

2.2.11 Arrays de strings


A menudo es conveniente, al trabajar con grandes cantidades de texto, como
proyectos con displays LCD, configurar un array de strings. Como los strings son en sí
mismo arrays, esto es un ejemplo real de un array bidimensional.
En el código de abajo, el asterisco después del tipo de dato char "char*" indica que es
un array de "punteros". Todos los nombres de arrays son punteros, por lo que esto es
necesario para crear un array de aarys. Los punteros son una de las partes más
exotéricas de C como para que los principieantes puedan llegar a entenderlas, pero
no es necesario entender punteros en detalle para usarlos con efectividad.
Ejemplo
char* miStrings[]={"Este es el string 1", "Este es el string 2", "Este es
el string 3",
"Este es el string 4", "Este es el string 5","Este es el string 6"};
void setup(){
Serial.begin(9600);

Pag 131
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 a n d o (D e c l a r a n d o ) u n a m a t 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";

Puedes declarar una matriz sin inicializarla como en myInts.


En myPins se declara una matriz sin establecer un tamaño explícito. El compilador
cuenta el número de elementos y crea la matriz con el tamaño apropiado.
Finalmente, puedes tanto declarar con un tamaño la matriz e inicializarla al mismo
tiempo, como en mySensVals
Accediendo a una matriz o Array
Los Arrays son zero indexed, esto significa que, al referirse a una matriz, el primer
elemento de la matriz está en el indice 0. Por lo tanto:
mySensVals[0] == 2, mySensVals[1] == 4, y sucesivos.
Esto también significa que en una matriz con 10 elementos. el indice 9 es
el último elemento. Por lo tanto:
int myArray[10]={9,3,2,4,3,2,7,8,9,11};
// myArray[9] contiene 11
// myArray[10] es invalido y contiene información aleatoria (de otra
dirección de memoria)
Por esta razón hay que tener cuidado en el acceso a las matrices. El acceso más allá
del final de una matriz (usando un número de índice mayor que el tamaño declarado -
1) resultará la lectura de la memoria que está en uso para otros fines. La lectura de
estos lugares probablemente no va a hacer mucho mal, excepto la lectura de datos

Pag 132
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 as ignar un valor a una matriz:
mySensVals[0] = 10;
To retrieve a value from an array:
x = mySensVals[4];
Matr ices y los bu cles F OR
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
Para ver un programa completo que demuestra el uso de los arrays o matrices, mira
Knight Rider example desde Tutoriales.
Ver tambien
Declaración de variables
PROGMEM

Pag 133
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 <avr/pgmspace.h>

Sintaxis
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
dataType PROGMEM variableName[] = {}; // no esta
PROGMEM dataType variableName[] = {}; // usar esta

PROGMEM puede usarse en una sola variable pero sólo merece la pena su uso en bloques más largos de
datos que necesiten ser guardados, generalmente en un array aunque puede ser otro tipo de estructura.
PROGMEM se usa en dos pasos. Después de guardar los datos en la memoria Flash, requiere métodos
especiales (funciones), definidos también en la librería pgmspace.h, para leer los datos de la memoria de
programa y ponerla en SRAM, para poder usarla.
Es importante usar los tipos de datos definidos en pgmspace.h. Pueden aparecer fallos crípticos si se usan
tipos comunes para llamadas a la memoria de código. Ésta es una lista de tipos disponibles. No están
soportados los números en coma flotante.
prog_char - carácter con signo (1 byte) -127 a 128
prog_uchar - carácter sin signo (1 byte) 0 a 255
prog_int16_t - entero con signo (2 bytes) -32.767 a 32.768
prog_uint16_t - entero sin signo (2 bytes) 0 a 65.535
prog_int32_t - entero largo con signo(4 bytes) -2.147.483,648 a * 2.147.483.647.

Pag 134
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 <avr/pgmspace.h>
// 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)


Muchas veces es conveniente, al trabajar con cantidades grandes de texto como por ejemplo en un
proyecto con un LCD, definir matrices de strings. Como los strings son matrices, en realidad son matrices
bidimensionales.
Éstas tienden a ser estructuras grandes por lo que ponerlas en memoeria de programa es algo a evitar.
Este código ilustra la idea:
/*
PROGMEM string demo
Cómo guardar una tabla de strings en la memoria de programa (flash) y cargarla.
Información resumida de:
http://www.nongnu.org/avr-libc/user-manual/pgmspace.html (inglés)
Primero, definir los strings.
*/
#include <avr/pgmspace.h>
prog_char string_0[] PROGMEM = "String 0"; // "String 0" etc. son strings a guardar.
prog_char string_1[] PROGMEM = "String 1";
prog_char string_2[] PROGMEM = "String 2";
prog_char string_3[] PROGMEM = "String 3";
prog_char string_4[] PROGMEM = "String 4";

Pag 135
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").
Hay que asegurarse de que el string en RAM es suficientemente grande para recibir el dato. */
for (int i = 0; i < 6; i++)
{
strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Casts necesarios e inferencia
Serial.println( buffer );
delay( 500 );
}
}
2.2.13 void
La palabra reservada void se usa sólo en la declaración de funciones. Indica que se
espera que no devuleva información a la función donde fué llamada.
Ejemplo:
// varias acciones se llevan a cabo en las funciones "setup" y "loop"
// pero no se reporta ninguna información al programa principal.
void setup()
{

Pag 136
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 conceptualizar 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 modificaciones, si el código debe ser cambiado.
Las funciones hacen el sketch mas pequeño y mas compacto por que las secciones de código se reutilizan
varias veces.
Hacen mas fácil la reutilización de código en otros programas por hacerlo mas modular y, como efecto
paralelo, usando funciones se obtiene un código mas legible.
Hay dos funciones necesarias en un sketch de Arduino: setup() y loop(). El resto de funciones debe ser definido fuera
de las llaves de estas dos funciones. Como ejemplo vamos a crear una función muy simple que multiplica dos
números.
Ejemplo

Al "invocar" a nuestra pequeña función le pasamos parametros del tipo de dato que ella espera.

Pag 137
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);
}
int myMultiplyFunction(int x, int y){
int result;
result = x * y;
return result;
}
Otro ejemplo:
Esta función leerá un sensor cinco veces con analogRead() y calculará la media de las cinco lecturas. Escala los
datos a 8 bits (0-255), los invierte y devuelve el resultado invertido.
int ReadSens_and_Condition(){
int i;
int sval;
for (i = 0; i < 5; i++){
sval = sval + analogRead(0); // sensor en pin analógico 0
}
sval = sval / 5; // media
sval = sval / 4; // escala a 8 bits (0 - 255)
sval = 255 - sval; // invierte el resultado
return sval; // devuelve el resultado

Pag 138
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.
Sintax is
char(x)
Parámetros
x: un valor de cualquier tipo
Devuelve
char
Mira también
char
byte()
Descripción
Convierte una variable a un tipo de datos byte.
Sintax is
byte(x)
Parámetros
x: una variable de cualquier tipo.
Devuelve
byte

int()
Descripción
Convierte un valor al tipo de datos int.
Sintax is
int(x)
Parámetros
x: un valor de cualquier tipo.
Retorna

Pag 139
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

int
long()
Descripción
Convierte un valor al tipo de datos long.
Sintax is
long(x)
Parámetros
x: un valor para cualquier tipo
Devuelve
long
long()
Descripción
Convierte un valor al tipo de datos long.
Sintax is
long(x)
Parámetros
x: un valor para cualquier tipo
Devuelve
long

Pag 140
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)
constrain() (limita)
map() (cambia valor de rango)
pow() (eleva a un número)
sq() (eleva al cuadrado)
sqrt() (raíz cuadrada)
Trigonometría
sin() (seno)
cos() (coseno)
tan() (tangente)
Números Aleatorios
randomSeed()
random()
Communicación
Serial

Pag 141
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.
Sintax is
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
}
void loop()
{
digitalWrite(ledPin, HIGH); // Enciende el LED
delay(1000); // espera un segundo
digitalWrite(ledPin, LOW); // Apaga el LED
delay(1000); // Espera un segundo
}

Nota
Una entrada analógica puede ser usada como un pin digital, refiriéndose a ellos desde el número 14
(entrada analógica 0) a 19 (entrada analógica 5).

Pag 142
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

3.2 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.
Sintax is
digitalWrite(pin, valor)
Parameters
pin: el número de pin
valor: HIGH o LOW
Devuelve
nada
Ejemplo
int ledPin = 13; // LED conectado al pin digital 13
void setup()
{
pinMode(ledPin, OUTPUT); // establece el pin digital como salida
}
void loop()
{
digitalWrite(ledPin, HIGH); // enciende el LED
delay(1000); // espera por un segundo
digitalWrite(ledPin, LOW); // apaga el LED
delay(1000); // espera por un segundo
}

Pag 143
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
int val = 0; // variable donde se almacena el valor leído
void setup()
{
pinMode(ledPin, OUTPUT); // establece el pin digital número 13
como salida
pinMode(inPin, INPUT); // establece el pin digital número 7 como
entrada
}
void loop()
{
val = digitalRead(inPin); // leer el pin de entrada
digitalWrite(ledPin, val); // establece el LED al valor del botón
}
Establece el pin número 13 al mismo valor que el pin número 7, que es una entrada.

Pag 144
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áx is
tone(pin, frecuencia)
tone(pin, frecuencia, duracion)
Parámetros
pin: el pin en el que generar el tono
frecuencia: la frecuencia del tono en hercios.
duración: la duración del tono en milisegundos (opcional)
NOTA: las frecuencias audibles por el oído humano van de los 20Hz a los
20KHz por lo que el parámetro "frecuencia" debería estar comprendido
entre estos dos valores.
Retorno
Ninguno
4.2 noTone()
Descripción
Detiene la generación de la señal cuadrada que se activa al hacer uso de la
función tone(). No tiene efecto si no se está generando ningún tono.
NOTA: si quieres generar tonos diferentes en múltiples pines , necesitas usar
la función noTone() en el pin antes de llamar a la función tone() en el siguiente
pin.

Pag 145
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

Sintax is
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

Esquemático:

Pag 146
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

Esquemático:

Pag 147
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

. Para más circuitos de ejemplos visita la página del proyecto Fritzing


Esquemático:

Pag 148
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

Pag 149
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
luminosidad de un LED. Lo tienes disponible en la opción "File->Sketchbook->Examples->Analog" del
menú del software de Arduino.
La Modulación por Ancho de Pulso (PWM = Pulse Width Modulation) es una tecnica para simular una
salida analógica con una salida digital. El control digital se usa para crear una onda cuadrada, una señal
que conmuta constantemente entre encendido y apagado. Este patron de encendido-apagado puede
simular voltajes entre 0 (siempre apagado) y 5 voltios (siempre encendido) simplemente variando la
proporción de tiempo entre encendido y apagado. A la duración del tiempo de encendido (ON) se le llama
Ancho de Pulso (pulse width). Para variar el valor analógico cambiamos, o modulamos, ese ancho de
pulso. Si repetimos este patrón de encendido-apagado lo suficientemente rapido por ejemplo con un LED
el resultado es como si la señal variara entre 0 y 5 voltios controlando el brillo del LED.
En el grafico de abajo las lineas verdes representan un periodo regular. Esta duración o periodo es la
inversa de la frecuencia del PWM. En otras palabras, con la Arduino la frecuencia PWM es bastante
proxima a 500Hz lo que equivale a periodos de 2 milisegundos cada uno. La llamada a la función
analogWrite() debe ser en la escala desde 0 a 255, siendo 255 el 100% de ciclo (siempre encendido), el
valor 127 será el 50% del ciclo (la mitad del tiempo encendido), etc.

Pag 150
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).

4.3 shiftOut()
Descripción
Desplaza un byte de datos bit a bit. Empieza desde el bit más significante (el
de más a la izquierda) o el menos significante (el más a la derecha). Cada bit
se escribe siguiendo su turno en un pin de datos, después de conmutar un pin
de reloj (señal de reloj) para indicar que el bit está disponible.
Esto es conocido como protocolo serie síncrono y es la forma común que
utilizan los microcontroladores para comunicarse con sensores y con otros
microcontroladores. Ambos dispositivos permanecen sincronizados, y se
comunican a velocidades cercanas a las máximas, hasta que ambos compartan
la misma linea de reloj. En la documentación del harware interno de los chips
se hace referencia a menudo a esta característica como Serial Peripheral
Interface (SPI).
Sintax is
shiftOut(pinDatos, pinReloj, ordenBits, valor)
Parametros
pinDatos: el pin en el cual extraer cada bit (int)

Pag 151
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
significativo)
datos = 500;
// rota el byte más bajo
shiftOut(pinDatos, pinReloj, LSBFIRST, datos);
// rota el bit más alto
shiftOut(pinDatos, pinReloj, LSBFIRST, (datos >> 8));

Ejemplo
Para ver el circuito asociado a este ejemplo, ver el tutorial para controlar un
registro de desplazamiento 74HC595.
//***********************************************************//
// Name : shiftOutCode, Hello World //
// Author : Carlyn Maw,Tom Igoe //
// Date : 25 Oct, 2006 //
// Version : 1.0 //
// Notes : Código para utilizar un registro de desplazamiento//
// : 74HC595 para contar de 0 a 255 //
//***********************************************************//

Pag 152
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);
//vuelve a poner el latchPin a nivel alto para señalizar que
//no sigue siendo necesario eschuchar más información
digitalWrite(latchPin, HIGH);
delay(1000);
}
}
4.5 pulseIn()
Descripción
Lee un pulso (ya sea HIGH —alto— o LOW —bajo—) en un pin. Por ejemplo, si
value es HIGH, pulseIn() espera a que el pin sea HIGH, empieza a
cronometrar, espera a que el pin sea LOW y entonces detiene la medida de
tiempo. Devuelve la anchura del pulso en microsegundos. Interrumpe la
medida y devuelve 0 si el pulso no ha comenzado en un tiempo especificado.
La medida del tiempo en esta función ha sido determinada de forma empírica y
está sujeta a errores en pulsos largos. Funciona correctamente en pulsos con
una anchura de 10 microsegundos a tres minutos.
Sintax is
pulseIn(pin, value)
pulseIn(pin, value, timeout)

Pag 153
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);
}
5.0 Tiempo
5.1 millis()
Descripción
Devuelve el tiempo en milisegundos transcurridos desde que se arranco la
placa Arduino con el programa actual. Este número de desbordará (volverá a
cero), despues de aproximadamente 50 días.
Parámetros
Ninguno
Devuelve
Tiempo en milisegundos desde que el programa se inició (long sin signo
(unsigned long))
Ejemplo
unsigned long time;
void setup(){
Serial.begin(9600);
}

Pag 154
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éase también
micros()
delay()
delayMicroseconds()
Tutorial: Blink sin retardo

5.2 micros()
Descripción
Devuelve el número de microsegundos desde que la placa Arduino comenzó a
correr el programa. Este número eventualmente volverá a 0 (overflow), luego
de aproximadamente 70 minutos. A 16 MHz, en las placas Arduino (por
ejemplo, Duemilanove ó Nano), éstas función tiene una resolución de cuatro
milisegundos (por ejemplo, el valor devuelto es siempre múltiplo de 4). A 8
MHz, en placas Arduino (como LilyPad), tiene una resolución de 8
microsegundos.
Nota: En un milisegundo hay 1.000 microsegundos y 1,000,000 microsegundos
en un segundo.
Parámetros
Ninguno.
Devuelve
El número de microsegundos desde el inicio del programa (unsigned long)
Ejemplo
unsigned long time;
void setup(){
Serial.begin(9600);

Pag 155
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.
Sintax is
delay(ms)
Parámetros
ms: el número de milisegundos que se desea pausar el programa (unsigned
long)
Devuelve
Nada
Ejemplo
int ledPin = 13; // LED conectado al pin digital 13.
void setup()
{
pinMode(ledPin, OUTPUT); // declara que el pin digital se va a usar como
salida
}
void loop()
{
digitalWrite(ledPin, HIGH); // enciende el LED
delay(1000); // espera durante un segundo
digitalWrite(ledPin, LOW); // apaga el LED
delay(1000); // espera durante un segundo
}

Pag 156
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.
Circuito

Esquema:

Pag 157
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

5.4 delayMicroseconds()
Descr ipció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() .
Sintax is
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
}
void loop()
{
digitalWrite(outPin, HIGH); // establece en encedido el pin
delayMicroseconds(50); // espera por 50 microsegundos
digitalWrite(outPin, LOW); // establece en apagado el ping
delayMicroseconds(50); // espera por 50 microsegundos
}
Configura el pin número 8 para trabajar como pin de salida. Envía una serie
de pulsos con 100 microsegundos de período.
Advertencias y problemas conocidos
Esta función trabaja de manera exacta en el rango de 3 microsegundos y valores
superiores. No podemos asegurar que la función dealyMicroseconds funcionará de
forma precisa para valores menores de retraso.
As of Arduino 0018, delayMicroseconds() no longer disables interrupts. A partir de
Arduino 0018, delayMicroseconds() ya no invalida las interrupciones

Pag 158
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

6.0 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.
Adver tencia
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.
min(a++, 100); // evite esto - puede producir errores
a++;
min(a, 100); // use este método en cambio - mantenga cualquier operación
fuera de los paréntesis

6.2 max(x, y)
Descripción
Calcula el máximo de dos números.
Parámetros
x: El primer número, cualquier tipo de dato.
y: El segundo número, cualquier tipo de dato.
Devuelve
El mayor de ambos parámetros.
Ejemplo
sensVal = max(senVal, 20); // asigna a sensVal su propio valor o, de ser superior, 20.
// (una forma efectiva de asegurarse que el valor mínimo de senVal sea 20)

Pag 159
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
Debido a la forma en la que se ha implementado la función abs(), evite usar
otras funciones como parámetro debido a que puede ocasionar que se devuelva
un resultado incorrecto.
abs(a++); // evite esto - produce errores en el resultado
a++; // hazlo de esta manera -
abs(a); // mantenga cualquier otra operación fuera de la función

6.4 constrain(x, a, b)
Descripción
Restringe un número a un rango definido.
Parámetros
x: el número a restringir, cualquier tipo de datos.
a: El número menor del rango, cualquier tipo de datos.
b: El número mayor del rango, cualquier tipo de datos.
Retorna
x: si x está entre a y b
a: si x es menor que a

Pag 160
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.
La función map() usa matemática de enteros por lo que no generará fracciones,
aunque fuere el resultado correcto. Los resultados en fracciones se truncan, y
no son redondeados o promediados.
Parámetros
value: el número (valor) a mapear.
fromLow: el límite inferior del rango actual del valor.
fromHigh: el límite superior del rango actual del valor.
toLow: límite inferior del rango deseado.
toHigh: límite superior del rango deseado.
Devuelve
El valor mapeado.
Ejemplo
/* Mapea un valor análogo a 8 bits (0 a 255) */
void setup() {}
void loop()
{
int val = analogRead(0);

Pag 161
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)
Exponente: la potencia a la que se quiere elevar la base (float) (Coma flotante)
Devuelve
El resultado de la exponenciación (double)(Doble)
Ejemplo
Mira la función fscale en la librería del código.

6.7 sq(x)

Descripción
Calcula el cuadrado de un número: el numero multiplicado por el mismo.
Parámetros
x: el numero, cualquier tipo de dato
Devuelve
El cuadrado del número

Pag 162
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
Serial.print() y Serial.println() no soportan la impresión de valores de tipo float.

7.2 cos(rad)
Descripción
Calcula el coseno de un ángulo (en radianes). El resultado estará entre -1 y 1.
Parámetros
rad: el ángulo en radianes (float)
Retorna
El coseno del ángulo ("double")
Nota
Serial.print() y Serial.println() no soportan actualmente la impresión de
números con decimales.
7.3 tan(rad)
Descripción
Calcula la tangente de un ángulo (en radianes). El resultado estará entre el
menos infinito y el infinito.
Parámetros

Pag 163
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
velocidad para funciones con temporizaciones precisas. Los programadores normalmente suelen asignar
unas longitudes para convertir las operaciones de coma flotante en cálculos con enteros, para aumentar
la velocidad.

Ejemplos
float myfloat;
float sensorCalbrate = 1.117;
Sintaxis
float var = val;
var - el nombre de la variable tipo float
val - el valor que le asignas a esa variable
Código de ejemplo
int x;
int y;
float z;
x = 1;
y = x / 2; // y ahora contiene 0, la parte entera de la operación

Pag 164
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.
No obstante, puede ser útil usar secuencias pseudoaleatorias que se repitan
exactamente. Esto se consigue llamando a randomSeed() con un número fijo
antes de empezar la generación de la secuencia.
Parámetros
long, int - recibe un número para generar la semilla.
Devuelve
no devuelve nada
Example
long numAleatorio;
void setup(){
Serial.begin(9600);
randomSeed(analogRead(0));
}
void loop(){
randNumber = random(300);

Pag 165
MICROCONTROLADOR ATMEL MANUAL PROGRAMACIÓN

Serial.println(numAleatorio);
delay(50);
}
8.2 random()
Descripción
La función random genera números pseudoaleatorios.
Sintax is
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
desconectado.
No obstante, puede ser útil usar secuencias pseudoaleatorias que se repitan
exactamente. Esto se consigue llamando a randomSeed() con un número fijo
antes de empezar la generación de la secuencia.
Ejemplo
long numAleatorio;
void setup(){
Serial.begin(9600);
// si la entrada analógica 0 no está conectada,
// la llamada a randomSeed() recibirá ruido estático
// (analógico) y se generarán diferentes semillas
// cada vez que se ejecute el sketch.
randomSeed(analogRead(0));
}
void loop() {
// escribe un número aleatorio de 0 a 299

Pag 166
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
los pines 15 (RX) y 14 (TX). Para utilizar estos pines para comunicarse con el
ordenador personal, necesitarás un adaptador USB adicional a serie, ya que no
están conectados al adaptador USB-Serie de la placa Arduino Mega. Para usarlos
para comunicarse con un dispositivo serie externo TTL, conecta el pin TX al pin
RX del dispositivo, el RX al pin TX del dispositivo, y el GND de tu Arduino Mega
a masa del dispositivo. (No conectes estos pines directamente a un puerto
serie RS232, que operan a +/- 12V y esto puede dañar la placa Arduino.)
Funciones
begin() end() available()
read() flush() print()
println() write()
Ejemplos
ASCII Table
Dimmer
Graph

Pag 167
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)
Serial3.begin(spee
d)
Parámetros
speed: Velocidad en bits por segundo (baudios) - long
Devuelve
Nada Ejemplo:
void setup() {
Serial.begin(9600); // abre el puerto serie y establece la
velocidad en
9600 bps
}
void loop() {}
Ejemplo para Arduino Mega:
// Arduino Mega usando sus 4 puertos serie
// (Serial, Serial1, Serial2, Serial3),
// con diferentes velocidades de datos:
void setup(){

Pag 168
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:
Serial1.end()
Serial2.end()
Serial3.end()
Parámetros
ninguno
Devuelve
nada

9.4 available()
Descripción
Devuelve el número de bytes (caracteres) disponibles para ser leidos por el puerto
serie. Se refiere a datos ya recibidos y disponibles en el buffer de recepción del
puerto (que tiene una capacidad de 128 bytes).
Sintaxis
Serial.available()
Sólo para Arduino Mega:
Serial1.available()
Serial2.available()
Serial3.available()

Pag 169
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);
}
}

Ejemplo Arduino Mega:


void setup()
{
Serial.begin(9600);
Serial1.begin(9600);
}
void loop() {
// lee desde el puerto 0, envía al puerto 1:
if (Serial.available()) {
int inByte =
Serial.read();
Serial1.print(inByte,
BYTE);

Pag 170
MICROCONTROLADOR ATMEL

}
// lee del puerto 1, envía al puerto 0:
if (Serial1.available()) {
int inByte =
Serial1.read();
Serial.print(inByte,
BYTE);
}
}
9.5 read()
Descripción
Lee los datos entrantes del puerto serie.
Sintax is
Serial.read()

Solamente en Arduino Mega:


Serial1.read()
Serial2.read()
Serial3.read()
Parámetros
Ninguno
Devuelve
el primer byte disponible recibido por el puerto serie (devuelve -1 si no hay
datos disponibles) - int
Ejemplo
int incomingByte = 0; // para el byte leido
void setup() {
Serial.begin(9600); // abre el puerto serie a 9600 bps
}
void loop() {
// envia datos solamente cuando recibe datos
if (Serial.available() > 0) {
// lee el byte entrante:
incomingByte = Serial.read();
// dice lo que ha recibido:
Serial.print("He recibido: ");
Serial.println(incomingByte, DEC);

Pag 171
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 ().
Sintax is
Serial.flush()
Solamente en Arduino Mega:
Serial1.flush()
Serial2.flush()
Serial3.flush()
Parámetros
ninguno
Retorna
nada

9.7 print()
Descripción
Imprime los datos al puerto serie como texto ASCII. Este comando puede
tomar muchas formas. Los números son impresos mediante un juego de
caracteres ASCII para cada dígito. Los valores de tipo "float" son impresos en
forma de dígitos ASCII con dos decimales por defecto. Los valores tipo "byte"
se envían como un único carácter. Los caracteres y las cadenas se envían tal
cual. Por ejemplo:
Serial.print(78) imprime "78"
Serial.print(1.23456) imprime "1.23"
Serial.print(byte(78)) imprime "N" (cuyo código ASCII es 78)
Serial.print('N') imprime "N"
Serial.print("Hello world.") imprime "Hello world."
Un segundo parámetro opcional especifica la base (formato) a usar; los valores
permitidos son BYTE, BIN (binarios o base 2), OCT (octales o base 8), DEC
(decimales o base 10), HEX (hexadecimales o base 16). Para números de coma
flotante, este parámetro especifica el numero de posiciones decimales a usar.
Por ejemplo:
Serial.print(78, BYTE) imprime "N"
Serial.print(78, BIN) imprime "1001110"

Pag 172
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"
Sintax is
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.
*/
int x = 0; // variable
void setup() {
Serial.begin(9600); // abre el puerto serie a 9600 bps:
}
void loop() {
// print labels
Serial.print("SIN FORMATO"); // imprime un texto
Serial.print("\t"); // imprime un tabulado
Serial.print("DEC");
Serial.print("\t");
Serial.print("HEX");
Serial.print("\t");
Serial.print("OCT");
Serial.print("\t");
Serial.print("BIN");

Pag 173
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
}
Serial.println(""); //imprime otro salto de linea
}

Su ger en cias de pr ogr amación / Pr oblemas con oc idos


El último carácter a imprimir se transmite a través del puerto serie después de que
Serial.print () ha regresado.

9.8 println()
Descripción
Imprime los datos al puerto serie como texto ASCII seguido de un retorno de
carro (ASCII 13, o '\r') y un carácter de avance de línea (ASCII 10, o '\n'). Este
comando tiene la misma forma que Serial.print ().
Sintax is
Serial.println(val)
Serial.println(val, format)
Prarámetros
val: el valor a imprimir - de cualquier tipo

Pag 174
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; // variable para guardar el valor analogico
void setup() {

// abre el puerto serie a 9600 bps:


Serial.begin(9600);
}
void loop() {
// lee la entrada analogica en el pin 0:
analogValue = analogRead(0);
// imprime el valor en varios formatos: Serial.println(analogValue);
// imprime como ASCII decimal Serial.println(analogValue, DEC); //
imprime como ASCII decimal Serial.println(analogValue, HEX); //
imprime como ASCII hexadecimal Serial.println(analogValue, OCT); //
imprime como ASCII octal Serial.println(analogValue, BIN); //
imprime como ASCII binario Serial.println(analogValue, BYTE); //
imprime el valor del byte
// espera 10 milisegundos antes de la siguiente lectura.
delay(10);
}

9.9 Write()
Descripción
Escribe datos binarios en el puerto serie. Estos datos se envían como un byte o
una serie de bytes; para enviar los caracteres que representan los dígitos de un
número usar funcion print () en su lugar.

Pag 175
MICROCONTROLADOR ATMEL

Sy n t ax
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

Pag 176
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() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}

// prints title with ending line break


Serial.println("ASCII Table ~ Character Map");
}

// first visible ASCIIcharacter '!' is number 33:


int thisByte = 33;
// you can also write ASCII characters in single quotes.
// for example. '!' is the same as 33, so you could also use this:
//int thisByte = '!';

void loop() {
// prints value unaltered, i.e. the raw binary version of the
// byte. The serial monitor interprets all bytes as
// ASCII, so 33, the first number, will show up as '!'
Serial.write(thisByte);

Pag 177
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);

// if printed last visible character '~' or 126, stop:


if(thisByte == 126) { // you could also use if (thisByte == '~') {
// This loop loops forever and does nothing
while(true) {
continue;
}
}
// go on to the next character
thisByte++;
}

Output
ASCII Table ~ Character Map
!, dec: 33, hex: 21, oct: 41, bin
4, decúASCII Table ~ Character Map
!, dec: 33, hex: 21, oct: 41, bin: 100001
", dec: 34, hex: 22, oct: 42, bin: 100010
#, dec: 35, hex: 23, oct: 43, bin: 100011
$, dec: 36, hex: 24, oct: 44, bin: 100100
%, dec: 37, hex: 25, oct: 45, bin: 100101
&, dec: 38, hex: 26, oct: 46, bin: 100110
', dec: 39, hex: 27, oct: 47, bin: 100111
(, dec: 40, hex: 28, oct: 50, bin: 101000
), dec: 41, hex: 29, oct: 51, bin: 101001

Pag 178
MICROCONTROLADOR ATMEL

*, dec: 42, hex: 2A, oct: 52, bin: 101010


+, dec: 43, hex: 2B, oct: 53, bin: 101011
,, dec: 44, hex: 2C, oct: 54, bin: 101100
-, dec: 45, hex: 2D, oct: 55, bin: 101101
., dec: 46, hex: 2E, oct: 56, bin: 101110
/, dec: 47, hex: 2F, oct: 57, bin: 101111
0, dec: 48, hex: 30, oct: 60, bin: 110000
1, dec: 49, hex: 31, oct: 61, bin: 110001
2, dec: 50, hex: 32, oct: 62, bin: 110010
3, dec: 51, hex: 33, oct: 63, bin: 110011
4, dec: 52, hex: 34, oct: 64, bin: 110100
5, dec: 53, hex: 35, oct: 65, bin: 110101
6, dec: 54, hex: 36, oct: 66, bin: 110110
7, dec: 55, hex: 37, oct: 67, bin: 110111
8, dec: 56, hex: 38, oct: 70, bin: 111000
9, dec: 57, hex: 39, oct: 71, bin: 111001
:, dec: 58, hex: 3A, oct: 72, bin: 111010
;, dec: 59, hex: 3B, oct: 73, bin: 111011
<, dec: 60, hex: 3C, oct: 74, bin: 111100
=, dec: 61, hex: 3D, oct: 75, bin: 111101
>, dec: 62, hex: 3E, oct: 76, bin: 111110
?, dec: 63, hex: 3F, oct: 77, bin: 111111
@, dec: 64, hex: 40, oct: 100, bin: 1000000
A, dec: 65, hex: 41, oct: 101, bin: 1000001
B, dec: 66, hex: 42, oct: 102, bin: 1000010
C, dec: 67, hex: 43, oct: 103, bin: 1000011
D, dec: 68, hex: 44, oct: 104, bin: 1000100
E, dec: 69, hex: 45, oct: 105, bin: 1000101

...

Pag 179
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

Code
/*
Dimmer
Demonstrates the sending data from the computer to the Arduino board,
in this case to control the brightness of an LED. The data is sent
in individual bytes, each of which ranges from 0 to 255. Arduino
reads these bytes and uses them to set the brightness of the LED.

The circuit:

Pag 180
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:
analogWrite(ledPin, brightness);
}
}

/* Processing code for this example


// Dimmer - sends bytes over a serial port
// by David A. Mellis
//This example code is in the public domain.

import processing.serial.*;
Serial port;

void setup() {
size(256, 150);

println("Available serial ports:");


println(Serial.list());

// Uses the first port in this list (number 0). Change this to

Pag 181
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);
}
*/

Pag 182
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

Código
/*
Graph

A simple example of communication from the Arduino board to the computer:


the value of analog input 0 is sent out the serial port. We call this "serial"
communication because the connection appears to both the Arduino and the
computer as a serial port, even though it may actually use
a USB cable. Bytes are sent one after another (serially) from the Arduino
to the computer.

You can use the Arduino serial monitor to view the sent data, or it can
be read by Processing, PD, Max/MSP, or any other program capable of reading

Pag 183
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
values in the
// range 0 to 1023, followed by a newline, or newline and carriage
return

// Created 20 Apr 2005


// Updated 18 Jan 2008
// by Tom Igoe
// This example code is in the public domain.

import processing.serial.*;

Serial myPort; // The serial port


int xPos = 1; // horizontal position of the graph

void setup () {
// set the window size:
size(400, 300);

// List all the available serial ports


println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my Arduino, so I open Serial.list()[0].

Pag 184
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);

// at the edge of the screen, go back to the beginning:


if (xPos >= width) {
xPos = 0;
background(0);
}
else {
// increment the horizontal position:
xPos++;
}
}
}

*/

Pag 185
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

Code
/*
Serial Call and Response
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 sensor values whenever it gets a byte in.

Pag 186
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()
{
// if we get a valid byte, read analog ins:
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
// read first analog input, divide by 4 to make the range 0-255:
firstSensor = analogRead(A0)/4;
// delay 10ms to let the ADC recover:
delay(10);
// read second analog input, divide by 4 to make the range 0-255:
secondSensor = analogRead(1)/4;
// read switch, map it to 0 or 255L
thirdSensor = map(digitalRead(2), 0, 1, 0, 255);
// send sensor values:
Serial.write(firstSensor);
Serial.write(secondSensor);
Serial.write(thirdSensor);
}
}

void establishContact() {
while (Serial.available() <= 0) {
Serial.print('A'); // send a capital A

Pag 187
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;

// Print a list of the serial ports, for debugging purposes:


println(Serial.list());

// I know that the first port in the serial list on my mac


// is always my FTDI adaptor, so I open Serial.list()[0].
// On Windows machines, this generally opens COM1.
// Open whatever port is the one you're using.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}

void draw() {
background(bgcolor);
fill(fgcolor);
// Draw the shape
ellipse(xpos, ypos, 20, 20);
}

void serialEvent(Serial myPort) {


// read a byte from the serial port:
int inByte = myPort.read();
// if this is the first byte received, and it's an A,

Pag 188
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:
serialCount = 0;
}
}
}
*/

Llamada y respuesta serie (handshaking) con salida codificada en ASCII.


Un ejemplo de comunicación basada en cadenas entre la Arduino y el ordenador
utilizando un método de llamada-respuesta (handshaking).
Este programa envía una cadena ASCII para comenzar y la repite hasta que obtiene una
respuesta desde el ordenador. Después envía tres valores, obtenidos de sensores,
codificados en ASCII, separados con comas y terminados por un fin de línea con retorno
de carro, y espera otra respuesta desde el ordenador.
Puedes usar el monitor serie de Arduino para ver los datos enviados. También pueden
ser leidos por Processing (ver código mas adelante), Flash, PD, Max/MSP (ver ejemplo
mas adelante), etc. Los ejemplos siguientes dividen las cadenas de entrada con comas y
convierten la cadena en números otra vez.
Compara esto con el ejemplo de llamada y respuesta serie. Son similares, ambos
utilizan el método del aptretón de manos (handshaking), pero este codifica las lecturas
de los sensores como cadenas, mientras que el otro envía valores binarios. Mientras que

Pag 189
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.

Hardware Required
Arduino Board

(2) analog sensors (potentiometer, photocell, FSR, etc.)

(1) momentary switch/button

(3) 10K ohm resistors

breadboard

hook-up wire
Software Required
Processing or

Max/MSP version 5

Pag 190
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()
{
// start serial port at 9600 bps and wait for port to open:
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()
{
// if we get a valid byte, read analog ins:
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
// read first analog input:
firstSensor = analogRead(A0);
// read second analog input:
secondSensor = analogRead(A1);
// read switch, map it to 0 or 255L
thirdSensor = map(digitalRead(2), 0, 1, 0, 255);
// send sensor values:

Pag 191
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; // Background color


float fgcolor; // Fill color
float xpos, ypos; // Starting position of the ball

void setup() {
size(640,480);

// List all the available serial ports


println(Serial.list());

// I know that the first port in the serial list on my mac


// is always my Arduino module, so I open Serial.list()[0].
// Change the 0 to the appropriate number of the serial port
// that your microcontroller is attached to.
myPort = new Serial(this, Serial.list()[0], 9600);

// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil('\n');

// draw with smooth edges:


smooth();
}

void draw() {
background(bgcolor);

Pag 192
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);
ypos = map(sensors[1], 0,1023,0,height);
fgcolor = sensors[2];
}
// send a byte to ask for more data:
myPort.write("A");
}

*/

Pag 193
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
puertos serie, como aplicaciones de sincronización de PDA, Bluetooth, controladores USB
(por ejemplo, BlueSoleil), Virtual Daemon Tools, etc

Asegúrate de que no tienes un software de firewall que bloquee el acceso al


puerto serie (por ejemplo ZoneAlarm).

Es posible que debas salir de Processing, PD, vvvv, etc, si los estás utilizando
para leer datos a través de la conexión USB o serie a la placa Arduino.

Si tienes una placa que no es compatible con auto-reset, asegúrate de que


reinicias la placa un par de segundos antes de cargar. (Arduino Diecimila, Duemilanove,
Mega, y Nano soportan auto-reset al igual que LilyPad, Pro y Pro Mini con conector de
programación de 6-pines).

Sin embargo, ten en cuenta que algunos Diecimila fueron programados


accidentalmente con el bootloader incorrecto y tal vez requieran volver a presionar el
botón de reset físico antes de cargar, ver más sobreesta cuestión más adelante.

Sin embargo, en algunos equipos, es posible que tengas que pulsar el botón de
reset en la placa después de clicar el botón de descarga en el entorno Arduino. Pruebe
diferentes intervalos de tiempo entre los dos, hasta 10 segundos o más. Ésto sucede
con ordenadores antiguos o que ejecutan muchos procesos en paralelo.

Pag 194
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.


¿Qué estabas haciendo con la tarjeta antes / cuando dejó de trabajar, y que paquete de
software has añadido o eliminado de tu ordenador?

Los mensajes que aparecen cuando se intenta cargar con salida detallada
habilitada. Para ello, presiona la tecla Mayús mientras haces click en el botón de subida
en la barra de herramientas.

¿Porqué aparece "Build folder disappeared or could not be written" (Mac OS X)?
Esto se produce por una instalación defectuosa del software en tu Mac. ¿Arrastraste la
aplicación Arduino.app al instalar al icono de disco (y en, por ejemplo, la carpeta de
Aplicaciones)? Si no lo hiciste, no serás capaz de cargar los ejemplos, ya que el
programa no será capaz de localizarlos.
Actualización Mac

¿Porqué el software de Arduino no se ejecuta después haber actualizado el Java en mi Mac?


(Arduino 0016)
La última actualización de Java de Apple intenta utilizar la versión de 64 bits de las
bibliotecas nativas, pero la aplicación Arduino viene con una versión de 32 bits de la
biblioteca RXTX. Si inicia Arduino, obtendrás un error como:
@ @ Uncaught exception in main method: java.lang.UnsatisfiedLinkError:
/Applications/arduino-0016/Arduino 16.app/Contents/Resources/Java/librxtxSerial.jnilib:
no suitable image found. Did find: /Applications/arduino-0016/Arduino

Pag 195
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 sketch 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
tener una versión del bootloader que tiene el pin RX sin conectar la resistencia de pull-
up interna. Esto produce que, en ocasiones, el bootloader piense que está recibiendo un
nuevo programa, si bien se trata sólo de datos aleatorios. Esto se puede solucionar
actualizando el bootloader a la última versión o conectando el pin RX con una resistencia
de 10K a tierra.

¿Porqué se congela Arduino cuando intento cargar un programa? (En Windows)?


Esto podría ser causado por un conflicto con el proceso de Logitech LVPrcSrv.exe, que es
un programa residente en tu ordenador. Abre el Administrador de tareas y
comprueba si este programa se está ejecutando, y si es así, cierra ese proceso antes de
intentar subir más datos a la placa [ más información ].
Alimentación

¿Qué pasa si mi tarjeta no se enciende (el LED verde no se enciende)?


Si estás utilizando una tarjeta USB Diecimila o NG, asegúrate de que el puente (pieza de
plástico pequeña cerca del conector USB) es en los pines correctos. Si tienes la certeza
que tu placa recibe alimentación al usar una fuente de alimentación externa (conectado
a la clavija de red), el puente debe ser más cercano a los dos pines para el cable de
alimentación. Si, por el contrario, alimentas tu placa a través del puerto USB, el puente
debe estar en los dos pines más cercanos a los conectores USB. Esta foto muestra la
disposición para la alimentación de la placa del puerto USB.
Attach: jumper.jpg

Pag 196
MICROCONTROLADOR ATMEL

Bootloader equivocado

¿Porqué mi Diecimila necesita tanto tiempo (6-8 segundos) para iniciar mi sketch?
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 arduino.exe 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


Indefinido:
/ Applications/arduino-0004/librxtxSerial.jnilib undefined referencia a _printf $ LDBL128
espera que esté definido en / usr / lib / libSystem.B.dylib
es probable que necesites actualizar a Mac OSX 10.3.9 o posterior. Las versiones
anteriores tienen versiones incompatibles de algunas librerías del sistema.

¿Qué hago si me da un error "UnsatisfiedLinkError ( librxtxSerial.jnilib native library )" al


lanzar Arduino?
Si obtienes un error como este al iniciar Arduino:
@ @ Uncaught exception in main method: java.lang.UnsatisfiedLinkError: Native Library
/Users/anu/Desktop/arduino-0002/librxtxSerial.jnilib already loaded in another
classloader @ @
es probable que tengas una versión antigua de la biblioteca de comunicaciones en tu
ordenador. Busca comm.jar, jcl.jar o en / System / Library / Frameworks /
JavaVM.framework / o en los directorios del CLASSPATH o variables de entorno
PATH.

¿Qué pasa con el error "No se pudo encontrar la clase principal."?


Si recibe este error al lanzar Arduino:
@ @ JJava Virtual Machine Launcher: Could not find the main class. Program will exit. @
@

Pag 197
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 cygwin 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
en el Administrador de dispositivos. Intenta desactivar los dispositivos que usan los
otros puertos COM (por ejemplo, dispositivos Bluetooth).
Puerto Serie

¿Porqué no mi no aparece mi placa en el menú Tools | Serial Port?


Si estás usando una placa USB Arduino, asegúrate de instalar los drivers FTDI (véase el
link de instalación para instrucciones). Si estás utilizando un adaptador de USB a serie
con una placa serie, asegúrate de instalar los drivers correspondientes.
Asegúrate de que la tarjeta está conectada: el menú del puerto serie se actualiza cada
vez que abres la casilla Tools del menú, así que si acabas de desenchufar la placa, no
estará en el menú.
Comprueba que no estás ejecutando ningún programa que escanea todos los puertos
serie, como aplicaciones de sincronización de PDA, Bluetooth controladores USB (por
ejemplo, BlueSoleil), etc
En Windows, el puerto COM asignado a la placa puede ser uno de código muy alto. En
ocasiones se recomienda probar a cambiar el número asignado al chip FTDI por uno más
bajo. Tal y cómo comenta Zeveland:
"Tuve un montón de puertos virtuales COM creados para Bluetooth por lo que la placa
estaba configurada para utilizar COM17. El IDE no fue capaz de encontrarla de modo
que suprimí los otros puertos virtuales en el Panel de control (en XP) y trasladó el
puerto asignado al chip FTDI de Arduino a otro más bajo, en concreto el COM2.

Pag 198
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.<init>()


gnu.io.PortInUseException: Unknown Application
at gnu.io.CommPortIdentifier.open(CommPortIdentifier.java:354)
at processing.app.Serial.<init>(Serial.java:127)
at processing.app.Serial.<init>(Serial.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 o 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 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
grupo de soporte en [email protected].
Arranque Sketch

¿Porqué no arraca mi sketch al encender o reiniciar la placa Arduino?


Lo más probable es que alguna aplicación esté enviando datos en serie a tu placa al
arrancar. Durante los primeros segundos, el bootloader (que viene pregrabado en tu
placa) escucha la llegada de datos desde el ordenador. Después de unos segundos sin
comunicación, el bootloader inicia el sketch que ya está en la placa. Si continúa el envío
de datos hacia el bootloader, nunca se determinará el final de ejecución del bootloader y
tu sketch no arrancará. Tendrás que encontrar una manera de cesar el envío de datos
serie a la placa durante el tiempo que esta necesita para arrancar o grabar tu sketch en
la placa con un programador externo, que sustituya al bootloader.

¿Porqué mi sketch parece que carga correctamente, pero no hace nada?


Es posible que hayas seleccionado tu placa apropiadamente, pero con la opción de
microcontrolador equivocado. Asegúrate de que el microcontrolador corresponde al de tu
placa (ya sea Atmega8, ATmega168, ATmega328, o ATmega1280) - el nombre está
escrito en el más grande de los chips en la placa.
Comprueba si usas una fuente de alimentación ruidosa. Esto podría causar al chip
perder su sketch.
Por otra parte, el sketch puede ser demasiado grande para la tarjeta. Al subir tu sketch,
Arduino 0004 y posteriores comprueban si es demasiado grande para el ATmega8, pero

Pag 199
MICROCONTROLADOR ATMEL

basa su cálculo en un bootloader 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, 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 el menú Tools | Burn 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 (ver: instrucciones sobre cómo encontrar el archivo?).
Tamaño

¿Cómo puedo reducir el tamaño de mi sketch?


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 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
(ATmega168) sólo es compatible con PWM / analogWrite () en los pines determinados.
Llamadas analogWrite () en las patas otro dará alto (5 voltios) para valores mayores de
128 y bajo (0 voltios) para valores inferiores a 128. (Nótese que placas Arduino
antiguas con Atmega8 sólo trabajan con salida PWM en los pines 9, 10 y 11.)

¿Por qué recibo errores acerca de funciones o tipos no declaradas?


El entorno Arduino intenta generar automáticamente prototipos de sus funciones, de
modo que puedas llamarlos a tu gusto en tus programas. Este proceso, sin embargo, no
es perfecto, y en ocasiones produce mensajes de error.
Si declaras un tipo personalizado en el código y creas una función que acepte o devuelva
valores de ese tipo, obtendrás un error al intentar compilar el sketch. Esto se debe a
que el prototipo automático para esa función aparecerá sobre la definición de tipo.
Si declaras una función con un tipo de retorno de dos palabras (por ejemplo, "unsigned
int"), el entorno no se dará cuenta de que es una función y no creará un prototipo para
ello. Eso significa que debes proporcionar tu propia definición, o colocar la definición de
la función por encima de cualquier llamada a la misma.

Pag 200
MICROCONTROLADOR ATMEL

¿Por qué recibo errores sobre un dispositivo de firma no válida cuando se trata de subir un
sketch?
Si obtienes un error como:

avrdude: Yikes! Invalid device signature.


Double check 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 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

Pag 201
VIN

RN1A 10K
8
+5V

1
X1
CMP L13 POWERSUPPLY_DC21MMX U1

8
3 U5A NCP1117ST50T3G +5V

7 RN1B
1 3 VIN 3 4

2
C1 3 IN OUT +5V
+3V3 2 2

8
100n

2
1K

YELLOW RN2A
LMV358IDGKR SCK 5 U5B D1

GATE_CMD
4

10K
7 M7

2
1

1
6 PWRIN PC1 PC2 C2

+
LMV358IDGKR 47u 47u 100n
GND GND

L
GND GND GND GND
+5V GND
GND
1 +5V
USBVCC +5V IN OUT 5 +3V3
+5V GREEN

FDN340P
T1
3 C3 POWER
ON/OFF ON

GND
1u 1 4 5
2 GND NC/FB 4 2 RN4D 1K
RESET 3 3 6
+3V3 4 RN4C 1K
GND GND 5
6
7
VIN 8

2x2 M - NM
4
2
+5V GND 8x1F-H8.5
GND

JP2
3
1
ICSP1
MISO2 1 2 GND +5V

5
2
1

RESET
SCK2 3 4 MOSI2 ICSP C4
CD1206-S01575

RESET2 5 6 1 2
10x1F-H8.5
6 RN1C

100n

4
3
3 4

TS42031-160R-TR-7260
3

D3

3x2 M RESET-EN 5 6 AD5/SCL10 SCL


1 2 +5V AD4/SDA 9 SDA

CD1206-S01575
U3
10K

AREF

100n

RN1D 10K
GND 3x2 M GND 8

C5
21 PB7 GND 7

5
(PCINT7/OC0A/OC1C)PB7

D2
(PCINT6)PB6 20 PB6 SCK 6
RESET2 24 19 PB5 MISO 5 13
F1 RESET(PC1/DW) (PCINT5)PB5 ZU4 12

4
USB-B_TH USBVCC 18 PB4 MOSI 4
22p 22p

(T1/PCINT4)PB4
C11

RESET 11

DTR
MF-MSMF050-2 500mA XT2 (PD0/MISO/PCINT3)PB3 17 MISO2 1 RESET (SCK)PB5 19 SS 3
X2 10
16MHz

Y1

2 16 MOSI2 18 2
1

22R XTAL2(PC0) (PDI/MOSI/PCINT2)PB2 (MISO)PB4 9


8 RN3A GND
GND

1 XUSB 1 R1 15 SCK2 XTAL2 17 1


C9

(SCLK/PCINT1)PB1 (MOSI)PB3 8
USB

2 D- RD- 1M 1 XTAL1 (SS/PCINT0)PB0 14 R2 10 XTAL2 (SS)PB2 16 SS


2

3 D+ XT1 XT1 1M 15 IO9 IOH


P$2
P$1

22R (OC1)PB1
5 RN3D 6x1F-H8.5
CG0603MLC-05E

CG0603MLC-05E

4 4 RD+ XTAL1 9 XTAL1 (ICP)PB0 14 IO8


32 22 CSTCE16M0V53-R0 16MHZ 6

USB boot En
+5V AVCC (INT4/ICP1/CLK0)PC7

5 RN2D
23 AREF 21 28 AD5/SCL 5 2 7

4
(OC1A/PCINT8)PC6 AREF (ADC5)PC5
P$2
P$1

UGND

(PCINT9/OC1B)PC5 25 20 AVCC (ADC4)PC4 27 AD4/SDA 4 RN3B 22R


4 VCC (PCINT10)PC4 26 22 AGND (ADC3)PC3 26 AD3 3
Z1

Z2

+5V
1K
3 GND (AIN2/PCINT11)PC2 5 (ADC2)PC2 25 AD2 2 3 6
7 VCC (ADC1)PC1 24 AD1 1 RN3C 22R
(CTS/HWB/AIN6/TO/INT7)PD7 13 GND C6 8 GND (ADC0)PC0) 23 AD0
TP_VUCAP 27 UCAP (RTS/AIN5/INT6)PD6 12 100n AD
USHIELD USBVCC 31 11 TXLED 13 IO7 8x1F-H8.5
UVCC (XCK/AIN4/PCINT12)PD5 +5V (AIN1)PD7
RD- 30 D- (INT5/AIN3)PD4 10 RXLED (AIN0)PD6 12 IO6 8
RD+ 29 9 M8RXD 11 IO5 7 7
100n D+ (TXD1/INT3)PD3 1K (T1)PD5 6
UGND 28 8 M8TXD 6 RN2C
3 GND 6 IO4 6
BLM21

C7 UGND (RXD1/AIN1/INT2)PD2 (T0)PD4 5


7 5 IO3 5
2 1 33
(AIN0/INT1)PD1
6 TX (INT1)PD3
4 4 4
IO2
L1

C8 PAD (OC0B/INT0)PD0 YELLOW (INT0)PD2 3


1u (TXD)PD1 3 IO1 3
GND GROUND ATMEGA16U2-MU(R) 2 IO0 2 2
RN2B (RXD)PD0 1
GND 7 2 1
ATMEGA328P-PU 0
RX 1K IOL
M8RXD 1K
7 RN4B2
YELLOW
M8TXD 1K
8 RN4A
1

Arduino(TM) UNO Rev3


SCK
MISO
TS42
RESET

GND +5V
3
4
ICSP ICSP

3x2M_NM
1 2
1
2
5

3 4 MOSI
RESET 5 6

+5V

CD1206-S01575 C1 C2
RN1D 10K
+5V
100n 100n IO ALT1 ALT2 ALT3
5

U1 U2
D2

34 VCC1 (PCINT7/OC0A/OC1C/#RTS)PB7 12 IO11* +5V 34 VCC1 (PCINT7/OC0A/OC1C/#RTS)PB7 12 IO11* IO11* 11# #PWM 8/16bit
4

AGND 43 GND3 (PCINT6/OC1B/OC4B/ADC13)PB6 30 IO10* AGND 43 GND3 (PCINT6/OC1B/OC4B/ADC13)PB6 30 IO10* IO10* 10# #PWM 16bit +A11
13 RESET (PCINT5/OC1A/#OC4B/ADC12)PB5 29 IO9* RESET13 RESET (PCINT5/OC1A/#OC4B/ADC12)PB5 29 IO9* IO9* 9# #PWM 16bit +A10 +PWM COMPL IO10
22p
C3

RESET (ADC11/PCINT4)PB4 28 IO8 (ADC11/PCINT4)PB4 28 IO8 IO8 8 +A9


GND

(PD0/MISO/PCINT3)PB3 11 MISO (PD0/MISO/PCINT3)PB3 11 MISO MISO


XTAL2 16 10 MOSI XTAL2 16 10 MOSI MOSI
Y1 R1
XTAL2 (PDI/MOSI/PCINT2)PB2
(SCLK/PCINT1)PB1 9 SCK
XTAL2 (PDI/MOSI/PCINT2)PB2
(SCLK/PCINT1)PB1 9 SCK SCK TO ICSP
1M XTAL1 17 XTAL1 (SS/PCINT0)PB0 8 RXLED XTAL1 17 XTAL1 (SS/PCINT0)PB0 8 RXLED
GND

16MHz KX-7 L1
AVCC 44 AVCC 44
22p
C4

AVCC1 AVCC1
MH2029-300Y
24 AVCC (ICP3/CLK0/OC4A)PC7 32 IO13* 24 AVCC (ICP3/CLK0/OC4A)PC7 32 IO13* IO13* 13 #PWM 10bit
(OC3A/#0C4A)PC6 31 D5* (OC3A/#0C4A)PC6 31 D5*
AREF 42 AREF AREF 42 AREF
C5 14 VCC (INT6/AIN0)PE6 1 D7 +5V 14 VCC (INT6/AIN0)PE6 1 D7 USB boot En
6 RN1C
10K

GND
100n 15 GND (#HWB)PE2 33 HWB GND 15 GND (#HWB)PE2 33 HWB 3
GND

1uF 23 GND1 GND 23 GND1


GND

C6 35 GND2 (T0/OC4D/ADC10)PD7 27 D6* GND 35 GND2 (T0/OC4D/ADC10)PD7 27 D6*


UCAP 6 UCAP (T1/#OC4D/ADC9)PD6 26 IO12 UCAP 6 UCAP (T1/#OC4D/ADC9)PD6 26 IO12 12 +A7 PWM 16bit COMPL D6
C7
AGND

2 UVCC (XCK1/#CTS)PD5 22 TXLED +5V 2 UVCC (XCK1/#CTS)PD5 22 TXLED


GND RD- 3 D- (ICP1/ADC8)PD4 25 D4 RD- 3 D- (ICP1/ADC8)PD4 25 D4 D7 7 +AIN0
1uF RD+ 4 D+ (TXD1/INT3)PD3 21 D1/TX RD+ 4 D+ (TXD1/INT3)PD3 21 D1/TX D6* 6# #PWM Hi-Speed +A8
UGND 5 UGND (RXD1/AIN1/INT2)PD2 20 D0/RX UGND 5 UGND (RXD1/AIN1/INT2)PD2 20 D0/RX D5* 5# #PWM Hi-Speed
7 VBUS (SDA/INT1)PD1 19 D2/SDA VUSB 7 VBUS (SDA/INT1)PD1 19 D2/SDA D4 4 +A6
VUSB (OC0B/SCL/INT0)PD0 18 D3/SCL (OC0B/SCL/INT0)PD0 18 D3/SCL D3/SCL 3# #PWM 8bit
D2/SDA 2
(ADC7/TDI)PF7 36 A0 (ADC7/TDI)PF7 36 A0 D1/TX 1
(ADC6/TDO)PF6 37 A1 (ADC6/TDO)PF6 37 A1 D0/RX 0
VUSB (ADC5/TMS)PF5 38 A2 (ADC5/TMS)PF5 38 A2
R2 R3 39 39
AGND (ADC4/TCK)PF4 A3 (ADC4/TCK)PF4 A3
NM NM
GND EXP PAD GND P$1 PAD
GND

UGND

(ADC1)PF1 40 A4 (ADC1)PF1 40 A4
(ADC0)PF0 41 A5 GND (ADC0)PF0 41 A5
GND ATMEGA32U4-XUMU ATMEGA32U4-XUAU
GND UGND
IO13* 3 IC2A
1
USB NOT USED 2

13
12
10
11
LMV358IDGKR

10x1F-H8.5
ORIGIN
F1

9
8

8x1F-H8.5
XUSB VUSB

7
6
5
4
3
2
1
0
MF-MSMF050-2 500mA LL
2 7

JP1
10
9
8
7
6
5
4
3
2
1

8
7
6
5
4
3
2
1
J1

J2
RN3B 22R
P1 XUSB 5 4 RD- 6 3

D2/SDA
D3/SCL
VBUS

D0/RX
D1/TX
GND S1 P2 D-

D2/SDA
22R RN3D 22R RN3C

D3/SCL
SH1 D- +5V
S2 P3 D+

D6*
D5*
IO13*

IO10*
IO11*
SH2 D+

D7

D4
IO12

IO9*
S3 P4 USBID 8 1 RD+ IC1

IO8
SH3 ID
S4 SH4 GND P5 22R RN3A 3 IN OUT 4
S5 SH5 2

7 RN2B
AREF
S6

2
GND
SH6

6 RN2C

5 RN2D

RN2A
3

1
VUSB
1

USB MICRO
MH2029-300Y EXTPOWER NCP1117ST50T3G

1K

1K
GND UGND POWERSUPPLY_DC21MMX

GND

1K

1K

8
CG0603MLC-05E

CG0603MLC-05E

L2

+5V

Yellow

Yellow

Yellow
UGND 3 3 VIN GND

A5
A4
A3
A2
A1
A0
100n
+

RX
C8

TX
1

RESET
+3V3

VIN

Green
L
10u
M7
D1

IOREF
C9

ON
Z1

Z2

RFU
VIN
+

GND C10 +5V GND


10u

J3

8x1F-H8.5

6x1F-H8.5

J4
GND GND TXLED

1
2
3
4
5
6
7
8

6
5
4
3
2
1
RXLED
GND +5V GND
GND

GND
+

C12
10u
+5V VIN +5V AUTO SELECTOR
8 RN1A

GND
1

CMP 5 IC2B +5V


7 GATE_CMD
10K

+3V3 6 +3V3
8

LMV358IDGKR 1 IN OUT 5
C14
RN1B 10K

C13
100n 3 1u
7

C22 ON/OFF
100n VUSB
4

2 GND NC/FB 4
2

T1
FDN340P GND
GND GND C11 GND
1u

GND
+3V3
L1 MH2029-300Y
10n VDDANA
C20

+3V3

+3V3
MASTER-RESET L2 MH2029-300Y
RN3D 1k GREEN

TS42
ON

GND
5 4

RESET
VDDOUTMI

3
4
PWM13 3 IC1A YELLOW

+
L

+3V3
GND
10u 100n 100n 100n 100n 100n 100n 100n 10u 100n 10u

1
2
5
1 L13 6 3
2 C1 C18 C4 C5 C6 C7 C8 C9 C2 C10 C3

RN1C 100K
RN1D 100K
LMV358IDGKR 1k RN3C

6 RN2C

7 RN2B
3

5
+3V3
GND VDDOUT
CONNECT TXL

5 RN2D
7 RN1B

8 RN1A

8 RN2A
2 7 GND

100K
100K

4
JTAG

+
RN3B 1k

+3V3
TX JR1 10u 100n 100n 100n 100n 100n 100n 1 2
YELLOW JTAG_TMS
C11 C12 C13 C14 C15 C16 C17

100K

100K

100K

100K
0R 3 4 JTAG_TCK
CONNECT RXL 1 8 5 6 JTAG_TDO
RX RN3A 1k L3 MH2029-300Y 7 8 JTAG_TDI
9 10 R1
YELLOW JTAG_RESET MASTER-RESET
AREF AVREF GND 0R
100n 100n L5 MH2029-300Y GND +5V
C34 C19 VDDPLL SPI
MISO 1 2
SPCK 3 4 MOSI

+
GND GND 100n 10u MASTER-RESET 5 6

VDDOUT
C32 C33

+3V3

69 N.C. - internal pullup


47 MASTER-RESET
VDDOUTMI 3x2M GND
GND

GND
VDDANA
18x2F-H8.5

100K
XUSB +5V+3V3

R4
+3V3 36 35

AVREF
C21 GND VDDPLL 53 CANTX1/IO 34 33 AD14(RXD3) 52
22p 51 PIN51 32 31 PIN50 50 POWER
PWMH

50 N.C.
49 PIN49 30 29 PIN48 48 1
SCL1 10 TWCK0 47 PIN47 28 27 PIN46 46 2 IOREF

105
125

104
124
GND
GND

GND

39

46

53

75

57

62

73
52
41

56
34

10
45
61

74
33
54
44
11
SDA1 9 TWD0 45 PIN45 26 25 PIN44 44 MASTER-RESET 3
AREF 8 AREF 43 PIN43 24 23 PIN42 42 4

GND
Y1 GND 7 41 PIN41 22 21 PIN40 40 5
R8

GND
NRST

VDDOUT
VBUS

FWUP
SHDN

NRSTB

VDDIN
JTAGSEL

ADVREF

VDDANA
VDDBU

GNDANA

GNDBU
VDDIO1
VDDIO2
VDDIO3
VDDIO4

VDDUTMI

VDDPLL

VDDCORE1
VDDCORE2
VDDCORE3
VDDCORE4
VDDCORE5

GNDPLL

GNDUTMI
12MHz KX-7 20pF 51 TST GND1 12 PWM13 6 13 39 PIN39 20 19 PIN38 38 6
C22 58 PWM12 5 12 37 PIN37 18 17 PIN36 36 7
22p 0R_NM GND2
XOUT 35 XOUT GND3 106 PWM11 4 11 35 PIN35 16 15 PIN34 34 VIN 8
C23 XIN 36 126 SS0/PWM10 3 10 ETH-CS 33 PIN33 14 13 PIN32 32
22pF_NM XIN GND4
PWM9 2 9 31 PIN31 12 11 PIN30 30 8x1F-H8.5
XOUT32 49 XOUT32 PD10 32 PIN32 PWM8 1 8 29 PIN29 10 9 PIN28 28 GND
48 XIN32 PD9 22 PIN30 27 PIN27 8 7 PIN26 26
21 PWM12 10x1F-H8.5 25 PIN25 6 5 PIN24 24
R5 39R 1% PD8

GND
Y2 D- 38 DHSDM PD7 20 PWM11 PWML 23 PIN23 4 3 PIN22 22
C24 32.768Khz 43 19 PIN29 PWM7 8 7 2 1
22pF_NM DFSDM PD6 +5V
D+ 39R 1% 37 18 RXD0 PWM6 7 6
R6 42
DHSDP PD5
17 6 XIO
XIN32 DFSDP PD4 TXD0 PWM5 5 TWI pullups
VBG 40 VBG PD3 16 PIN28 SS1/PWM4 5 4 SD-CS
PD2 15 PIN27 PWM3 4 3
PD1 14 PIN26 PWM2 3 2
R7 PD0 13 PIN25 TX 2 1 UTXD
22p

10n
6k8 1% RX 1 0 URXD

C26
C25 103 RXL
PC30

GND
CANTX0 23 102 SS0/PWM10 8x1F-H8.5
XUSB PA0 PC29 COMMUNICATION
CANRX0 24 PA1 PC28 139 PWM3
GND AD7 85 PA2 PC27 138 SCL0-3 8 21 TWCK1
F1 AD6 84 PA3 PC26 137 SS1/PWM4 SDA0-3 7 20 TWD1
MF-MSMF050-2 500mA AD5 83 PA4 PC25 136 PWM5 RXD2 6 19
USB AB XUSB USBVCC EEXTINT 25
AD4 82
PA5
PA6
PC24
PC23
135
134
PWM6
PWM7
TXD2
RXD1
5
4
18
17
USB1 PIN31 26 PA7 PC22 133 PWM8 TXD1 3 16
R2 RX 27 132 PWM9 RXD0 2 15

+
10u 10u PA8 PC21
VUSB 1 XUSB 10K TX 2 PA9 PC20 131 TXD0 1 14
2 D- C27 C35 RXD2 3 101 PIN44
D- PA10 PC19 8x1F-H8.5
D+ 3 D+ TXD2 4 PA11 PC18 100 PIN45
CG0603MLC-05E

CG0603MLC-05E
ID 4 UOTGID RXD1 5 PA12 PC17 99 PIN46
UGND 5 GND TXD1 6 PA13 PC16 98 PIN47
PIN23 7 97 PIN48

+3V3
PA14 PC15
SH1 S1 PIN24 8 PA15 PC14 96 PIN49
SH2 S2 AD0 78 PA16 PC13 95 PIN50
Z1

Z2

SH3 S3 SDA1 9 PA17 PC12 94 PIN51


S4 SCL1 70 93 ADCL ADCH
SH4 PA18 PC11
PIN42 71 PA19 PC10 117 AD7 8 AD7 CANTX0 8 I2C Voltage Translator

5 RN5D

6 RN5C
8 RN5A

1K5 RN5B
P$1 PIN43 72 67 PIN41 AD6 7 AD6 CANRX0 7

3
G1 PA20 PC9
G2 P$2 TXL 107 PA21 PC8 66 PIN40 AD5 6 AD5 DAC1 6
G3 P$3 AD3 81 PA22 PC7 65 PIN39 AD4 5 AD4 DAC0(CANRX1) 5

1K5

1K5
1K5
CG0603MLC-05E

7
G4 P$4 GND AD2 80 PA23 PC6 64 PIN38 AD3 4 AD3 AD11(TXD3) 4
G5 P$5 AD1 79 PA24 PC5 63 PIN37 AD2 3 AD2 AD10 3
G6 P$6 MISO 108 PA25 PC4 116 PIN36 AD1 2 AD1 AD9 2
G7 P$7 MOSI 109 PA26 PC3 60 PIN35 AD0 1 AD0 AD8 1 SCL0-3 SCL0-3
G8 P$8 SPCK 110 PA27 PC2 59 PIN34 SDA0-3 SDA0-3
Z5

P$9 (ETH) SS0/PWM10 111 55 PIN33 8x1F-H8.5 8x1F-H8.5


G9 PA28 PC1

PB10

PB12
PB13
PB14
PB15
PB16
PB17
PB18
PB19
PB20
PB21
PB22
PB23
PB24
PB25
PB26
PB27
PB28
PB29
PB30
PB31
PB11
P$10 (SD) SS1/PWM4 112 130

PB0
PB1
PB2
PB3
PB4
PB5
PB6
PB7
PB8
PB9
G10 PA29 PC0
P$11

ERASE_S
G11 100K
UOTGID ERASE +3V3 7 RN4B
2
MICRO-USB-AB1 U1

ETX_CLK 113
114
115
118
119
120
121
122
123
127
UOTGVBOF 128
129
86
87
140
DAC0(CANRX1) 76
77
88
89
90
91
92
141
142
143
144
1
68
28
29
30
31
ATSAM3X8EA-AU VIN

RN4C 100K
+5V
ERASE

JTAG_TDO
JTAG_TMS
JTAG_TCK
FDN340P GND

JTAG_TDI

+3V3
+5V

ERX_ER
T3

ERX_DV
ETX_EN

UOTGID

AD14(RXD3)
CMP 5 IC4

AD11(TXD3)

PWM13
SDA0-3
SCL0-3
ERXD0
ERXD1

CANTX1/IO
EMDIO
ETXD0
ETXD1

PWM2
EMDC

SS3
7 GATE_CMD

PIN22
NCP1117ST33T3G -3V3

DAC1

AD10
AD8
AD9

3
+3V3 6 3 4 +3V3

8
IN OUT
2
ERASE_CMD Q2 IC1B

+
JTAG BC847BSMD LMV358IDGKR +5V C29
10u
C30
100n

1
RN4A 100K
R3

4
5 RN4D
4
C31

8
1K 100n
USBVCC +5V GND GND

100K
GND

1
T1

ETX_CLKA
UOTGVBOF FDN340P

ERX_ERA

ETX_ENA
X2

ERXD1A
ERXD0A
ETXD1A
ETXD0A
EEXTINTA
ERX_DVA
EMDCA
POWERSUPPLY_DC21MMX EMDIOA
L6 Forces OFF the power supply to USB port GND
3 3 MH2029-300Y when the USB port is in HOST mode FDN340P
VIN (board powered from external power supply) T2
1

USBVCCU2
M7
D1

13
11
9
7
5
3
1
ETH
1

MACB
VIN+ PC1 VBUSPO: VBus Polarity Off
+

47u 0: The UOTGVBOF output signal is in its default mode (active high)
14
12
10
8
6
4
2 1: The UOTGVBOF output signal is inverted (active low)
RESETA GND
GND GND
GND

4
2
2x2M - NM

JP5
3
1
8PB7
8PB6
8PB5
8PB4

+5V

ICSP1
MISO2 1 2
SCK2 3 4 MOSI2
CD1206-S01575

RESET2 5 6
D2

3x2M R13 D3
10K IC2 CD1206-S01575 +5V
GND GND IC6 LM2734Y BOOST
C42
R23

21 1
10K

(PCINT7/OC0A/OC1C)PB7 BOOST
USB B (PCINT6)PB6 20 VIN 5 VIN L4
22p

RESET_CMD

RESET2 24 19 MASTER-RESET 6 SW 10n

+
C28 C41
C40

RESET(PC1/DW) (PCINT5)PB5 SW

R10

GND
18 EN 4 10u SRR0604-100ML

10k
100n (T1/PCINT4)PB4 10u EN DEBUG
XT2 17 MISO2 3
F2 (PD0/MISO/PCINT3)PB3 FB

K
J3 2 16 MOSI2

SS1P3L
XVCC USBVCCU2 PC2 1

+
XTAL2(PC0) (PDI/MOSI/PCINT2)PB2
GND
GND

GND

VBUS P1 MF-MSMF050-2 500mA R9 (SCLK/PCINT1)PB1 15 SCK2 47u JTAG_TCK 2

D4
2
1M_NM

R12
S1 P2 BD- RD- 1 14 GND JTAG_TMS 3

A
52K3
SH1 D- XTAL1 (SS/PCINT0)PB0
22R 22R
R20 R19

S2 SH2 D+ P3 BD+ RD+ Y4 FB MASTER-RESET 4


CG0603MLC-05E

S3 SH3 ID P4 12MHz KX-7 20pF


XT1 GND
+5V
CG0603MLC-05E

S4 P5 32 22 RESET_CMD GND STRIP 4x1V M


C39

SH4 GND AVCC (INT4/ICP1/CLK0)PC7


22p

S5 SH5 (OC1A/PCINT8)PC6 23 ERASE_CMD IF LM2736Y


S6 SH6 (PCINT9/OC1B)PC5 25 R2=1K GND GND
P$1 SH7 4 VCC (PCINT10)PC4 26 N$1 USBVCC R3=330R
Z3

Z4

R18

P$2 USB-MICRO 3 5

R11
B
10K

SH8 GND (AIN2/PCINT11)PC2


1K
R21

10K
P$3 SH9
GND

P$4 SH10 (CTS/HWB/AIN6/TO/INT7)PD7 13


P$5 SH11 VUCAP 27 UCAP (RTS/AIN5/INT6)PD6 12 USB boot En
P$6 USBVCCU2 31 11 TXL-U2 +5V
SH12 UVCC (XCK/AIN4/PCINT12)PD5
P$7 SH13 GND RD- 30 D- (INT5/AIN3)PD4 10 RXL-U2 GND
P$8 SH14 RD+ 29 D+ (TXD1/INT3)PD3 9 16U2-TX
GND 28 UGND (RXD1/AIN1/INT2)PD2 8 TX
1u 7
100n (AIN0/INT1)PD1 TX1
1K
R14

C38 33 PAD (OC0B/INT0)PD0 6 YELLOW


C36
ATMEGA16U2-MU

CONFIG 5V RX1
1K
R15

GND GND GND YELLOW


GND
TM
16U2-TX 16U2-TX
1

IC10
TX TX 2 4 RX
74LVC1G125DCK
C37 IC10P

GND

VCC
5 GND
3

Arduino Due Reference Design


100n

+3V3

También podría gustarte