0% encontró este documento útil (0 votos)
218 vistas33 páginas

Unidad 4 Arduino

Este documento explica cómo manipular los puertos en una placa Arduino. Introduce los conceptos de registros de puertos, que controlan los pines de entrada y salida, y cómo establecer el estado de los pines individualmente o en grupos usando valores binarios. Además, presenta ejemplos de código que encienden LEDs usando diferentes configuraciones de puertos.

Cargado por

Brian Marin
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
218 vistas33 páginas

Unidad 4 Arduino

Este documento explica cómo manipular los puertos en una placa Arduino. Introduce los conceptos de registros de puertos, que controlan los pines de entrada y salida, y cómo establecer el estado de los pines individualmente o en grupos usando valores binarios. Además, presenta ejemplos de código que encienden LEDs usando diferentes configuraciones de puertos.

Cargado por

Brian Marin
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 33

Arduino U4

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

EJERCITAR EL CONOCIMIETNO DEL LENGUAJE DE PROGRAMACIÓN DE


NUESTRA PLACA Y EL CONOCIMIENTO DE SOBRE LA MISMA.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


Manipulación de
01
SECCIÓN

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:

B: pines digitales del 8 al 13


C: entradas analógicas
D: pines digitales del 0 al 7

La siguiente figura nos muestra estos pines:

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


8
Cada puerto está controlado por tres registros, los cuales son definidos como variables en el lenguaje
de Arduino.

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.

El PORTD mapea los pines digitales del 0 al 7

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

El PORTC mapea los pines de entrada analógica de 0 a 5

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.

DDRD = B11111110; // En este caso los pines del 1 al 7 se han


seteado como salidas, mientras que el pin 0 se encuentra seteado
como entrada.

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.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


9
NOTA: En el valor anterior los pines son tomados desde el 7 al cero por lo que podemos representar en
una tabla la relación entre el valor y el pin de la siguiente manera:

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

En la unidad anterior vimos el siguiente ejemplo:

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};

for ( int i=0; i<=9; i++) {


for( int j=0; j<=9; j++){
PORTD=display1[j];
PORTB=display2[i];
delay(1000);
}
}

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


10
En este ejemplo no estamos considerando la posibilidad de utilizar Rx y Tx en transmisión serie,
sino que estamos seteando todos los pins a 1, o sea como salidas de datos OUTPUT. El seteo lo
realizamos dentro de setup()

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};

for ( int i=0; i<=9; i++) {


for( int j=0; j<=9; j++){
PORTD=display1[j];
PORTB=display2[i];
delay(1000);
}
}

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

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


11
VENTAJAS Y DESVENTAJAS DEL USO DE REGISTRO DE PUERTO:

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.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


12
CÓDIGO

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

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


13
Operaciones con
02
SECCIÓN

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.

Bitwise 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:

int a = 92; // en binario: 0000000001011100


int b = 101; // en binario: 0000000001100101
int c = a & b; // resultado: 0000000001000100, or 68 in decimal.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


16
Presentado en una tabla para que no queden dudas nos queda así:

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.

int x = 5; // en binario: 101


int y = x & 1; // por lo que y == 1
x = 4; // en binario: 100
y = x & 1; // por lo que y == 0

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:

int a = 92; // en binario: 0000000001011100


int b = 101; // en binario: 0000000001100101
int c = a | b; // resultado: 0000000001111101, or 125 in de-
cimal.

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;

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


17
Bitwise XOR - ^

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

Un ejemplo de esta operación puede quedar como sigue:

int x = 12; // binary: 1100


int y = 10; // binary: 1010
int z = x ^ y; // binary: 0110, or decimal 6

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.

y = x ^ 1; //Esto permite modificar el bit menos significativo de


x y guardar el resultado en y

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

int a = 103; // binario: 0000000001100111


int b = ~a; // binario: 1111111110011000 = -104

NOTA: ~x es igual a -x-1

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


18
Operadores de desplazamiento - Bit Shift Operators

Los dos operadores de desplazamiento utilizados en C++ son:

El operador de desplazamiento hacia la izquierda <<


El operador de desplazamiento hacia la derecha >>

Estos operadores causan un desplazamiento de los bits de un número binario, veamos un ejemplo:

int a = 5; // binario: 0000000000000101


int b = a << 3; // binario: 0000000000101000, or 40 en de-
cimal
int c = b >> 3; // binario: 0000000000000101, lo cual nos
retorna al valor de “a”

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

bool valor( byte x, int ubicacion)


{
int b = x >> ubicacion ;
b = b & 1 ;
return b ;
}

Esto nos retorna TRUE o FALSE según el valor sea 1 o 0.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


19
Notación abreviada.

Para todos los operadores vistos menos para bitwise NOT podemos escribir una notación abreviada
pudiendo pasar de:

int x = 1; // binary: 0000000000000001


x = x << 3; // binary: 0000000000001000
x = x | 3; // binary: 0000000000001011 - ya que 3 is 11 en bina-
rio
x = x & 1; // binary: 0000000000000001
x = x ^ 4; // binary: 0000000000000101
x = x ^ 4; // binary: 0000000000000001

a:

int x = 1; // binary: 0000000000000001


x <<= 3; // binary: 0000000000001000
x |= 3; // binary: 0000000000001011 - ya que 3 is 11 en bina-
rio
x &= 1; // binary: 0000000000000001
x ^= 4; // binary: 0000000000000101
x ^= 4; // binary: 0000000000000001

http://playground.arduino.cc/Code/BitMath#binary

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


20
Suma y Resta de
03
SECCIÓN

Números Binarios
03
SECCIÓN SUMA Y RESTA DE NÚMEROS BINARIOS

Ampliemos nuestro conocimiento sobre los números binarios, viendo como se


realizan operaciones básicas.

SUMA DE NÚMEROS BINARIOS

Para poder sumar números binarios vamos a partir de los cuatro casos posibles.

0+0=0 1+0=1 0+1=1 1 + 1 = 0 y acarreo 1


Primer valor 0 1 0 1
Segundo valor 0 0 1 1
Resultado 0 1 1 0
acarreo --- --- --- 1

En el caso de 1 + 1 el resultado es 1 y nos llevamos 1 a la columna siguiente, veamos un ejemplo de


la suma de 82 + 82. Esta suma en binario sería:

Primer valor 1 0 1 0 0 1 0 0
Segundo valor 0 1 0 0 1 0 1 1
Resultado

Nos quedaría asÍ:

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

El primer valor es sumado al acarreo y el resultado sumado al segundo valor.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


22
RESTA DE NÚMEROS BINARIOS

Para poder sumar números binarios vamos a partir de los cuatro casos posibles.

0-0=0 1-0=1 0 - 1 = 1 y acarreo 1 1-1=0


Primer valor 0 1 0 1
Segundo valor 0 0 1 1
Resultado 0 1 1 0
acarreo --- --- 1 ---

En el caso de 0 - 1 el resultado es 1 y nos llevamos 1 a la columna siguiente, veamos un ejemplo de la


resta de 164 - 75. Esta resta en binario sería:

Primer valor 1 0 1 0 0 1 0 0
Segundo valor 0 1 0 0 1 0 1 1
Resultado

Nos quedaría asÍ:

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

y realice algunas sumas y restas de binarios chequeando sus resultados.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


23
Ejercicios
04
SECCIÓN
04
SECCIÓN EJERCICIOS

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.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


26
/*
DigitalReadSerial
Reads a digital input on pin 2, prints the result to the serial
monitor

This example code is in the public domain.


*/

// El pin 2 posee asociado un pulsador al cual se le da el si-


guiente nombre
int pushButton = 2;

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.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


27
EJERCICIO 2 - uso de map()

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.

Los parámetros de map son:

map(valor, eb, ea, se, sa)

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.

TAREA: Realizar un ejemplo que tome datos de la variación de un potenciometro y lo transforme


en la variación de un led.

NOTA: Otra función útil puede ser constrain(), la cual limita el rango de valores de una variable

Los parámetros de constrain son:

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.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


28
Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]
29
BIBLIOGRAFÍA

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

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


30
TEMAS DE LA UNIDAD

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

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


31
TEMAS DE LA UNIDAD SIGUIENTE

En la siguiente unidad veremos cómo alimentar motores a través de un


H bridge L293D, limitación de integrados y como realizar el armado de
un vehículo con Lego.

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


32
DATOS FINALES

FORMA DE APROBACIÓN DEL CURSO

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.

DATOS DEL DOCENTE

TÍTULO: MBA Ing.

NOMBRE: Juan M. Barreto R.

EMAIL: [email protected]

DATOS UTN HAEDO

DIRECCIÓN: Párís 532 - Haedo

WEB: http://adistancia.frh.utn.edu.ar

TELÉFONO: + 54 11 4443-7466 // +54 11 4659-2575

E-MAIL: [email protected]

Cursos Semipresencial - UTN HAEDO MBA. Ing. Juan Barreto - [email protected]


33

También podría gustarte