Unidad 4 Arduino
Unidad 4 Arduino
Presentación
En esta unidad realizaremos una serie de ejercicios para afianzar los
conocimientos adquiridos y el dominio del lenguaje de programación
C de Arduino, introduciendo nuevos conocimientos como la manipula-
ción de puertos en nuestra placa.
Objetivos:
APRENDER A UTILIZAR LOS PUERTOS DEL ARDUINO
puertos
01
SECCIÓN MANIPULACIÓN DE PUERTOS
REGISTRO DE PUERTOS
Los pines que se utilizan en las placas ATmega8 y Atmega168 poseen tres puertos clasificados de la
siguiente manera:
1.- El registro DDR determina cuando el pin se comporta como INPUT (entrada) (0) o
como OUTPUT (salida) (1).
2.- El registro PORT controla cuando el pin se encuentra en HIGH (alto)(1) o LOW (bajo)
(0).
3.- El registro PIN lee el estado de los pins INPUT mediante pinMode()
los registros DDR y PORT pueden ser escritos y leidos, mientras que el registro PIN corresponde al
estado de los inputs y solamente puede ser leido.
DDRD – El registro de configuración del modo de los pines del puerto D – lectura/escritura
PORTD – Registro de datos del puerto D – lectura/escritura
PIND – Registro de pines de entrada – solo lectura
El PORTB mapea los pines digitales del 8 al 13. Los dos bits 6 y 7 están mapeados a los pines de cris-
tal de curzo y no pueden ser usados.
DDRB – El registro de configuración del modo de los pines del puerto B – lectura/escritura
PORTB – Registro de datos del puerto D – lectura/escritura
PINB – Registro de pines de entrada – solo lectura
DDRC – El registro de configuración del modo de los pines del puerto B – lectura/escritura
PORTC – Registro de datos del puerto D – lectura/escritura
PINC – Registro de pines de entrada – solo lectura
Cada bit de estos registros corresponden con un solo pin; por ejemplo el bit menos significativo de
los registros DDRB, PORTB, y PINB hace referencia al pin PB0 (pin digital 8)
EJEMPLO
Podemos considerar el registro de configuración DDRD para determinar el estado de los pines 0 a 7
de nuestra placa de la siguiente forma.
La instrucción anterior, nos permite en una sola línea de código declarar el estado de 8 pins como
entradas o como salidas.
pin 7 6 5 4 3 2 1 0
valor 1 1 1 1 1 1 1 0
Al final de la unidad anterior hicimos un muy pequeño comentario a la comunicación serie, la cual
se realiza a través de un puerto serie (interface que nos permite la comunicación entre dos termi-
nales). El puerto serie es el que nos permite enviar información mediante una secuencia de bits, y
como comentamos para realizarlo necesitamos por lo menos dos conectores. En la placa arduino
estos conectores son RX (utilizado para la recepción) y TX (utilizado para la transmisión)
Debemos por tanto tener cuidado con el valor dado a estos pines si queremos tener a través de ellos
una comunicación serial, por lo que para considerar este punto debemos dejar la línea anterior
como:
DDRD = B11111110;
DDRD = DDRD | B11111100;
APLICACIÓN 1
void setup() {
DDRD=B11111111;
DDRB=B11111111;
}
void loop() {
byte display1[10]={B00000000,B00000001,B00000010,B00000011,-
B00000100,B00000101,B00000110,B00000111,B00001000,B00001001};
byte display2[10]={B00000000,B00010000,B00100000,B00110000,-
B01000000,B01010000,B01100000,B01110000,B10000000,B10010000};
void setup() {
DDRD=B11111111;
DDRB=B11111111;
}
El valor enviado como HIGH o LOW lo indicamos dentro de loop() de forma de indicar los valores
enviados que se encuentran almacenados en dos arrays de 10 valores cada uno y que mediante un
bucle for enviamos a través de los PORTD y PORTB.
void loop() {
byte display1[10]={B00000000,B00000001,B00000010,B00000011,-
B00000100,B00000101,B00000110,B00000111,B00001000,B00001001};
byte display2[10]={B00000000,B00010000,B00100000,B00110000,-
B01000000,B01010000,B01100000,B01110000,B10000000,B10010000};
Antes de seguír avanzando combiene recordar que los pines los podemos setear de forma individual
con pinMode() de la siguiente manera:
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
pinMode(12,INPUT);
}
DESVENTAJAS:
El código es mucho más difícil de depurar y mantener, y es mucho más difícil de entender para la
gente. Solo lleva algunos microsegundos al procesador ejecutar código, pero podría llevar horas
descubrir por qué no funciona y arreglarlo.
Es mucho más fácil causar mal funcionamiento no intencionado usando el acceso directo a un
puerto. Observa como la línea DDRD = B11111110, de arriba, menciona que el pin 0 se debe dejar
como una entrada. El pin 0 corresponde a (Rx) en el puerto serial, y podría ser muy fácil causar que
el puerto funcionar por cambiar el pin 0 a una salida (1).
VENTAJAS:
Se puede cambiar los pines de estado muy rápido, en fracciones de microsegundos. Las funciones
digitalRead() y digitalWrite() poseen cada una cerca de una docena de líneas de código, lo cual al ser
compilado se convierte en unas cuantas instrucciones máquina. Cada instrucción maquina necesita
un ciclo de reloj a 16MHz, lo cual puede sumar mucho tiempo en aplicaciones muy dependientes
del tiempo. El Registro PORT (Puerto) puede hacer el mismo trabajo en muchos menos ciclos de
trabajo.
Algunas veces necesitamos configurar muchos pines exactamente al mismo tiempo. Por lo que usar
las funciones digitalWrite (10,HIGH), seguida de la función digitalWrite (11,HIGH) , causará que
el pin 11 se ponga en nivel alto varios microsegundos después que el pin 10, lo cual puede confun-
dir circuitos digitales conectados al Arduino, cuyo funcionamiento dependa del tiempo preciso del
cambio de esos bits.
APLICACIÓN 2
Antes de seguir adelante podemos realizar otra aplicación en la cual modificamos el estado de ocho
leds con la ayuda de dos estructuras, un bucle for para recorrer los números del cero al dos y una es-
tructura switch que en función de la variable “i” establece diferentes configuraciones de encendido.
int i=0;
void setup(){
DDRD= B11111111;
DDRD = DDRD | B11111100;
}
void loop(){
for (i=0; i <3; i ++){
switch(i){
case 0:
PORTD= B11111111;
delay(2000);
case 1:
PORTD= B10101010;
delay(2000);
case 2:
PORTD= B01010101;
delay(2000);
}
}
}
bits
02
SECCIÓN OPERACIONES CON BITS
DECLARACIÓN DE BINARIO
En Arduino para declarar un número binario lo realizamos como ya hemos visto, anteponiendo una
“B” a la secuencia de bits, por ejemplo:
B11111111
Esto es debido a que el compilador de C++ que utiliza el Arduino no puede utilizar el prefijo 0b se-
guido de una serie de ceros y unos. La comprensión de como Arduino permite trabajar con binarios
es muy importante y nos basaremos en el manual oficial de Arduino que se encuentra online y al
cual se puede acceder desde:
http://playground.arduino.cc/Code/BitMath#binary
En primer lugar antes de pasar a ver ejemplos del uso del trabajo con binarios definiremos las opera-
ciones que se pueden realizar comenzando por AND.
La operación AND entre dos bytes se realiza bit a bit, en donde si ambos bit son 1 el resultado es 1 y
en otro caso da cero.
0 & 0 == 0
0 & 1 == 0
1 & 0 == 0
1 & 1 == 1
Por ejemplo, tomemos dos números enteros (92 Y 101), si recordamos los mismos están formados
por dos bytes de ocho bits cada uno por lo que al sumar dos números enteros se deben realizar 16
operaciones del tipo AND:
92 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0
101 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 1
68 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0
NOTA: Sin animo de ser repetitivo, notar que la suma de los dos enteros no da 193 sino 68 ya que se
esta sumando bit a bit y no es una suma común de dos números binarios.
NOTA: Uno de los usos más comunes de esta operación es la de seleccionar un determinado bit o bits
de un número entero, esto de denomina masking. Por ejemplo si queremos acceder al bit menos signi-
ficativo de una variable “x”, y guardar el resultado en otra variable “y”, podemos utilizar el siguiente
código.
Bitwise OR - |
En este caso la operación sigue siendo bit a bit pero todos los casos dan uno menos en el cual ambos
bits son ceros.
0 | 0 == 0
0 | 1 == 1
1 | 0 == 1
1 | 1 == 1
Un ejemplo de esta operación realizada con los mismos núneros enteros (92 y 101) nos da:
NOTA: La aplicación más común de esta operación es asegurarnos de que un determinado bit se ha
seteado a 1, por ejemplo para pasar el bit menos significativo de “x” a “y” a la vez que nos aseguramos
que sea seteado a podemos realizarlo de la siguiente manera.
y = x | 1;
En este caso utilizamos el símbolo circunflejo para realizar la operación, aquí el resultado da uno
solo si solo uno de los dos bits es igual a 1.
0 ^ 0 == 0
0 ^ 1 == 1
1 ^ 0 == 1
1 ^ 1 == 0
NOTA: Se suele utilizar para modificar el estado de un determinado bit o bits, por ejemplo para mo-
dificar el estado del bit menos significativo podemos realizarlo de la siguiente manera.
Bitwise NOR - ~
Este operador cambia cada bit por su opuesto, es decir que si el el bit es 1 es cambiado a 0 y si es 0 es
cambiado a 1.
Ejemplo
Estos operadores causan un desplazamiento de los bits de un número binario, veamos un ejemplo:
NOTA: Cuidado ya que al realizar un desplazamiento podemos estar eliminando los bits con valor
igual a 1
EJEMPLO DE APLICACIÓN
Supongamos que queremos obtener el valor de un determinado bit dentro de un byte, podriamos
escribir un programa como el siguiente
Para todos los operadores vistos menos para bitwise NOT podemos escribir una notación abreviada
pudiendo pasar de:
a:
http://playground.arduino.cc/Code/BitMath#binary
Números Binarios
03
SECCIÓN SUMA Y RESTA DE NÚMEROS BINARIOS
Para poder sumar números binarios vamos a partir de los cuatro casos posibles.
Primer valor 1 0 1 0 0 1 0 0
Segundo valor 0 1 0 0 1 0 1 1
Resultado
Primer valor 1 0 1 0 0 1 0
Acarreo 1 1 1
Segundo valor 1 0 1 0 0 1 0
Resultado 1 0 1 0 0 1 0 0
Para poder sumar números binarios vamos a partir de los cuatro casos posibles.
Primer valor 1 0 1 0 0 1 0 0
Segundo valor 0 1 0 0 1 0 1 1
Resultado
Acarreo 1 1
Primer valor 1 0 1 0 0 1 0 0
Acarreo 1 1 1
Segundo valor 0 1 0 0 1 0 1 1
Resultado 0 1 0 1 1 0 0 1
TAREA
Realice una búsqueda en internet de algún conversor de números binarios a hexadecimales o deci-
males, como puede ser el que se encuentra en la siguiente dirección:
http://www.disfrutalasmatematicas.com/numeros/binario-decimal-hexadecimal-conversor.html
EJERICICIO 1: DigitalReadSerial
Ya hemos tomado antes un valor analógico a través del pin A0, ahora tomemos un valor digital a
través del pin 2, para lograr este fin utilizaremos un pulsador y una resistencia y realizaremos la
siguiente configuración.
El código lo podemos encontrar en uno de los ejemplos que vienen por defecto en la plataforma de
Arduino en: Archivo > Ejemplos > 01Basic > DigitalReadSerial.
void setup() {
// Iniciamos la comunicación 9600 bits per second:
Serial.begin(9600);
// Configuramos nuestro pinn como una entrada:
pinMode(pushButton, INPUT);
}
void loop() {
// Leemos el dato de entrada:
int buttonState = digitalRead(pushButton);
// Visualizamos el estado del botón:
Serial.println(buttonState);
// Se agrega un delay entre lectura por estabilidad
delay(1);
}
NOTA: La resistencia está colocada para que el pin 2 no esté conectado directamente a tierra, de otra
forma el valor sería siempre cero.
Referencia: https://www.arduino.cc/en/Reference/Map
Una función de arduino muy útil es map(), la misma nos permite pasar de un rango de variación a
otro, con lo cual por ejemplo podriamos hacer variar la intensidad de un led en un rango de 0 a 255
al tomar valores de un sensor de luz, de forma que cuando el sensor de luz toma su valor más bajo
le asignamos el valor de 255 del led y cuando toma su valor más alto le asignamos el valor más bajo
del led (0), de esta forma podemos hacer que las luces de una habitación se enciendan cuando la luz
ambiente ya es muy tenue y se apaguen cuando la luz ambiente es muy intensa.
En donde:
valor = Valor a mapear
eb = Valor de entrada más bajo del rango.
ea = Valor de entrada más alto del rango.
se = Valor de salida más bajo.
sa = Valor de salida más alto.
NOTA: Otra función útil puede ser constrain(), la cual limita el rango de valores de una variable
constrain(valor, a, b)
En donde:
valor = Variable con valores a restringir.
a = valor mínimo de la restricción
b = valor máximo de la restricción
Referencia: https://www.arduino.cc/en/Reference/Constrain
TAREA: Realizar un circuito y un programa, para convertir un valor analógico (de 0 a 1023 ente-
ro) en voltaje (0 a 5V flotante), sin el uso de map() y que permita visualizar el valor en el monitor.
LIBROS
Beginning C for Arduino, Second Edition - Jack Purdum, Ph.D. – 2015 – USA. – Edito-
rial: Apress.
Arduino Development Cookbook – Cornel Amariei. – 2015 – USA. Editorial: Pack Pu-
blishing.
Getting Started with Arduino – 3rd Edition – Massimo Banzi co-founder of Arduino &
Michael Shiloh – 2009 – USA. – Editorial: Make
Manual online
https://www.arduino.cc/en/Guide/HomePage
En esta unidad vimos como realizar sumas y restas de binarios, que son
los flip-flop, que son los registros de desplazamiento, y como realizar una
conexión entre un arduino y una PC para envió de datos según norma
En esta unidad vimos como realizar sumas y restas de binarios, que son
los flip-flop, que son los registros de desplazamiento, y como realizar una
conexión entre un arduino y una PC para envió de datos según norma
232.
EMAIL: [email protected]
WEB: http://adistancia.frh.utn.edu.ar
E-MAIL: [email protected]