Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
#
INTELLECTUAL OUTPUT 5
1
Greece
LEIBNIZ UNIVERSITÄT HANNOVERGermany Coordinator ( )
CYPRUS COMPUTER SOCIETY
Cyprus
CIVIC COMPUTING
CDIMM MARAMURES FOUNDATION
2 EK PEIRAIA
EMPHASYS CENTRE
United Kingdom
Romania
Cyprus
WOMEN IN DIGITAL INITIATIVES LUXEMBOURG ASBL
I.E.S. MARÍA MOLINERSpain
Luxemburg
All rights reserved. The content of the publication may be used for educational and other non-commercial
purposes on the condition of using the following name as source in every reproduction: „Erasmus+ Project
Robot4All“.
Leibniz Universität Hannover
PROJECTS WEBSITE:
PROJECT LEADERSHIP:
LAYOUT:
Institut für Didaktik der Demokratie
PROJECT MANAGEMENT:
Richard Heise
Mareike Heldt
Prof. Dr. Dirk Lange
This project has been funded with support from the European Commission. This communication reflects the
views only of the author, and the Commission cannot be held responsible for any use which may be made of the
information contained therein. Project Number: 2017-1-DE02-KA202-004274
www.robovet.eu
1
Greece
LEIBNIZ UNIVERSITÄT HANNOVERGermany Coordinator ( )
CYPRUS COMPUTER SOCIETY
Cyprus
CIVIC COMPUTING
CDIMM MARAMURES FOUNDATION
2 EK PEIRAIA
EMPHASYS CENTRE
United Kingdom
Romania
Cyprus
WOMEN IN DIGITAL INITIATIVES LUXEMBOURG ASBL
I.E.S. MARÍA MOLINERSpain
Luxemburg
All rights reserved. The content of the publication may be used for educational and other non-commercial
purposes on the condition of using the following name as source in every reproduction: „Erasmus+ Project
Robot4All“.
Leibniz Universität Hannover
PROJECTS WEBSITE:
PROJECT LEADERSHIP:
LAYOUT:
Institut für Didaktik der Demokratie
PROJECT MANAGEMENT:
Richard Heise
Mareike Heldt
Prof. Dr. Dirk Lange
This project has been funded with support from the European Commission. This communication reflects the
views only of the author, and the Commission cannot be held responsible for any use which may be made of the
information contained therein. Project Number: 2017-1-DE02-KA202-004274
www.robovet.eu
2 3
03
03
04
19
38
12
05
Lección 5: Arduino básico ........................................................................................................................................
Organización .............................................................................................................................................................
Lección 6: Arduino avanzado ...................................................................................................................................
Introducción .............................................................................................................................................................
Lección 4: Introducción a Arduino y Robótica ........................................................................................................
Anexo .........................................................................................................................................................................
Lista de materiales ...................................................................................................................................................
El objetivo de este curso es crear circuitos robóticos y controlarlos de forma eficiente mediante programación,
utilizando las plataformas Arduino y Tinkercad
Arduino es una plataforma de electrónica de código abierto basada en un hardware y software fáciles de usar.
Arduino nació como una herramienta sencilla de prototipado rápido, pensada para alumnos sin conocimientos de
electrónica y programación. Tan pronto como llegó a una comunidad más extensa, la placa de Arduino empezó a
cambiar para adaptarse a las nuevas necesidades y retos, diferenciando su oferta, desde simples placas de 8 bits a
productos para aplicaciones IoT, impresión 3D, y diseños empotrados. El software es también de código abierto y va
creciendo mediante contribuciones de usuarios de todo el mundo.
Las placas de Arduino son capaces de leer entradas – luz en un sensor, un dedo en un botón, o un mensaje de Twitter
– y convertirlos en una salida – activar un motor, encender un LED, publicar algo online- Puedes ordenar a tu placa
qué hacer enviando al microcontrolador de la placa un conjunto de instrucciones. Para ello se utiliza el lenguaje de
programción Arduino y el Software Arduino.
Hoy en día las habilidades robóticas son esenciales en la mayoría de los procesos industriales y de ingeniería de
nuestro modo de vida. Por lo tanto, para ser capaces de crear, controlar y modificar estos prototipos, debemos
mejorar el currículo de robótica de nuestros alumnos introduciéndoles en este campo.
Grupos objetivo:
Ÿ Profesores de F.P. interesados en robótica y tecnologías de la información
Ÿ Alumnos de F.P. con menores oportunidades.
Los ejercicios están pensados para ser montados físicamente utilizando una protoboard y diferentes
componentes electrónicos, pero pueden ser simplemente simulados, aunque se pierde la diversión y la práctica
del montaje electrónico.
Los ejercicios están organizados en tres bloques: las lecciones 4, 5 y 6. En cada uno de los tres bloques hay
diferentes ejemplos en orden de complejidad creciente, desde los muy básicos hasta los muy avanzados. La
mayoría de los ejercicios están enlazados a una solución online en Tinkercad, donde se puede ver el circuito de
hardware asociado a la solución, así como el código, y se puede simular el funcionamiento del circuito.
INTRODUCCIÓN
ORGANIZACIÓN
ÍNDICE
2 3
03
03
04
19
38
12
05
Lección 5: Arduino básico ........................................................................................................................................
Organización .............................................................................................................................................................
Lección 6: Arduino avanzado ...................................................................................................................................
Introducción .............................................................................................................................................................
Lección 4: Introducción a Arduino y Robótica ........................................................................................................
Anexo .........................................................................................................................................................................
Lista de materiales ...................................................................................................................................................
El objetivo de este curso es crear circuitos robóticos y controlarlos de forma eficiente mediante programación,
utilizando las plataformas Arduino y Tinkercad
Arduino es una plataforma de electrónica de código abierto basada en un hardware y software fáciles de usar.
Arduino nació como una herramienta sencilla de prototipado rápido, pensada para alumnos sin conocimientos de
electrónica y programación. Tan pronto como llegó a una comunidad más extensa, la placa de Arduino empezó a
cambiar para adaptarse a las nuevas necesidades y retos, diferenciando su oferta, desde simples placas de 8 bits a
productos para aplicaciones IoT, impresión 3D, y diseños empotrados. El software es también de código abierto y va
creciendo mediante contribuciones de usuarios de todo el mundo.
Las placas de Arduino son capaces de leer entradas – luz en un sensor, un dedo en un botón, o un mensaje de Twitter
– y convertirlos en una salida – activar un motor, encender un LED, publicar algo online- Puedes ordenar a tu placa
qué hacer enviando al microcontrolador de la placa un conjunto de instrucciones. Para ello se utiliza el lenguaje de
programción Arduino y el Software Arduino.
Hoy en día las habilidades robóticas son esenciales en la mayoría de los procesos industriales y de ingeniería de
nuestro modo de vida. Por lo tanto, para ser capaces de crear, controlar y modificar estos prototipos, debemos
mejorar el currículo de robótica de nuestros alumnos introduciéndoles en este campo.
Grupos objetivo:
Ÿ Profesores de F.P. interesados en robótica y tecnologías de la información
Ÿ Alumnos de F.P. con menores oportunidades.
Los ejercicios están pensados para ser montados físicamente utilizando una protoboard y diferentes
componentes electrónicos, pero pueden ser simplemente simulados, aunque se pierde la diversión y la práctica
del montaje electrónico.
Los ejercicios están organizados en tres bloques: las lecciones 4, 5 y 6. En cada uno de los tres bloques hay
diferentes ejemplos en orden de complejidad creciente, desde los muy básicos hasta los muy avanzados. La
mayoría de los ejercicios están enlazados a una solución online en Tinkercad, donde se puede ver el circuito de
hardware asociado a la solución, así como el código, y se puede simular el funcionamiento del circuito.
INTRODUCCIÓN
ORGANIZACIÓN
ÍNDICE
4 5
LECCIÓN 4: INTRODUCCIÓN
A ARDUINO Y ROBÓTICA
Los ejercicios están pensados como una forma de introducir diferentes elementos que se pueden usar en un
robot (diodos, sensores, LCDs, etc.) en un entorno de simulación sencillo, y simultáneamente hacer la transición
a su uso en hardware real. La metodología sugerida para utilizar estos ejercicios es la siguiente:
Ÿ Buscar en Tinkercad circuitos similares y trabajar sobre ellos.
Ÿ Trabajar en los ejercicios de la lección 4, primero a través de la simulación en Tinkercad y después montando
los circuitos y programando el Arduino UNO.
Ÿ Trabajar en los ejercicios proporcionados con el Kit Elegoo Robot Car, montar el robot y usar los diferentes
sensores y acturadores.
Ÿ Buscar en Tinkercad circuitos similares y trabajar sobre ellos.
Ÿ Trabajar en los ejercicios de la lección 5, primero a través de la simulación en Tinkercad y después montando
los circuitos y programando el Arduino UNO.
Ÿ Trabajar en los ejercicios de la lección 6.
Ÿ 3x resistencias de 220 ohm.
Ÿ Arduino UNO con ATMEGA328P.
Ÿ 2x potenciómetro de 10K.
Ÿ 3 x resistencias de 10K.
Ÿ RMD6300 lector de tarjetas RFID.
Ÿ Micromotor DC.
Ÿ Protoboard, puede ser una pequeña como esta o mejor una grande como esta.
Ÿ Tira de LED RGB.
Ÿ L293 driver de motores.
Ÿ Mosfet canal N.
Ÿ 3 micro pulsadores.
Ÿ Arduino yun o Arduino yun shield para Arduinouno.
Ÿ Sensor de temperatura LM35.
Ÿ Parallax ping sensor de distancia de ultrasonidos. Es un sensor caro y se utiliza en estos ejemplos porque
está modelizado en Tinkercad, pero puede remplazarse, con mínimos cambios, por el HC-SR04 que es mucho
más barato.
Ÿ Leds: rojo, verde y amarillo.
Ÿ RFID tokens.
Ÿ Micro-servo.
Ÿ Crear circuitos elementales con Arduino.
Ÿ Familiarizarse con la programación utilizando bloques.
Ÿ Construir circuitos básicos con Tinkercad.
�
1.Blink (parpadeo)
Después de completar esta lección los alumnos deben ser capaces de:
Ÿ Escribir programas en pequeños programas sencillos en C++ utilizando las estructuras más elementales.
Objetivos:
Ÿ Utilizar dispositivos electrónicos como resistencias, leds, protoboards,…
Ÿ Leer y entender programas básicos en C++
Ejercicios
Ÿ Blink (parpadeo): https://www.tinkercad.com/things/ejt30quxU9d
Ÿ Traffic light (semáforo): https://www.tinkercad.com/things/cdgx8jSsFSo
Ÿ Seguir la secuencia de instrucciones de un programa básico y deducir los resultados de salida.
Ÿ Switch on/off a light (encender/apagar una luz): https://www.tinkercad.com/things/lTBPtStOWzM
Ÿ Utilizando bloques (pseudocódigo) escribir un programa que haga que el led parpadee una vez por segundo.
Ÿ Simular el circuito en Tinkercad.
Ÿ Usando Tinkercad circuits, crear un circuito con Arduino UNO, una protoboard y un led conectado al pin
digital 8 de Arduino.
Ÿ Comparar los bloques con el código generado por Tinkercad (seleccionar la opción block+text y Tinkercad
generará el código).
Ÿ Montar el correspondiente circuito real, programarlo con Arduino IDE y probarlo.
Ÿ ¿Cuál es el valor de la resistencia y por qué?
LISTA DE MATERIALES
4 5
LECCIÓN 4: INTRODUCCIÓN
A ARDUINO Y ROBÓTICA
Los ejercicios están pensados como una forma de introducir diferentes elementos que se pueden usar en un
robot (diodos, sensores, LCDs, etc.) en un entorno de simulación sencillo, y simultáneamente hacer la transición
a su uso en hardware real. La metodología sugerida para utilizar estos ejercicios es la siguiente:
Ÿ Buscar en Tinkercad circuitos similares y trabajar sobre ellos.
Ÿ Trabajar en los ejercicios de la lección 4, primero a través de la simulación en Tinkercad y después montando
los circuitos y programando el Arduino UNO.
Ÿ Trabajar en los ejercicios proporcionados con el Kit Elegoo Robot Car, montar el robot y usar los diferentes
sensores y acturadores.
Ÿ Buscar en Tinkercad circuitos similares y trabajar sobre ellos.
Ÿ Trabajar en los ejercicios de la lección 5, primero a través de la simulación en Tinkercad y después montando
los circuitos y programando el Arduino UNO.
Ÿ Trabajar en los ejercicios de la lección 6.
Ÿ 3x resistencias de 220 ohm.
Ÿ Arduino UNO con ATMEGA328P.
Ÿ 2x potenciómetro de 10K.
Ÿ 3 x resistencias de 10K.
Ÿ RMD6300 lector de tarjetas RFID.
Ÿ Micromotor DC.
Ÿ Protoboard, puede ser una pequeña como esta o mejor una grande como esta.
Ÿ Tira de LED RGB.
Ÿ L293 driver de motores.
Ÿ Mosfet canal N.
Ÿ 3 micro pulsadores.
Ÿ Arduino yun o Arduino yun shield para Arduinouno.
Ÿ Sensor de temperatura LM35.
Ÿ Parallax ping sensor de distancia de ultrasonidos. Es un sensor caro y se utiliza en estos ejemplos porque
está modelizado en Tinkercad, pero puede remplazarse, con mínimos cambios, por el HC-SR04 que es mucho
más barato.
Ÿ Leds: rojo, verde y amarillo.
Ÿ RFID tokens.
Ÿ Micro-servo.
Ÿ Crear circuitos elementales con Arduino.
Ÿ Familiarizarse con la programación utilizando bloques.
Ÿ Construir circuitos básicos con Tinkercad.
�
1.Blink (parpadeo)
Después de completar esta lección los alumnos deben ser capaces de:
Ÿ Escribir programas en pequeños programas sencillos en C++ utilizando las estructuras más elementales.
Objetivos:
Ÿ Utilizar dispositivos electrónicos como resistencias, leds, protoboards,…
Ÿ Leer y entender programas básicos en C++
Ejercicios
Ÿ Blink (parpadeo): https://www.tinkercad.com/things/ejt30quxU9d
Ÿ Traffic light (semáforo): https://www.tinkercad.com/things/cdgx8jSsFSo
Ÿ Seguir la secuencia de instrucciones de un programa básico y deducir los resultados de salida.
Ÿ Switch on/off a light (encender/apagar una luz): https://www.tinkercad.com/things/lTBPtStOWzM
Ÿ Utilizando bloques (pseudocódigo) escribir un programa que haga que el led parpadee una vez por segundo.
Ÿ Simular el circuito en Tinkercad.
Ÿ Usando Tinkercad circuits, crear un circuito con Arduino UNO, una protoboard y un led conectado al pin
digital 8 de Arduino.
Ÿ Comparar los bloques con el código generado por Tinkercad (seleccionar la opción block+text y Tinkercad
generará el código).
Ÿ Montar el correspondiente circuito real, programarlo con Arduino IDE y probarlo.
Ÿ ¿Cuál es el valor de la resistencia y por qué?
LISTA DE MATERIALES
6 7
Circuito:
Las salidas de Arduino son 5V cuando están a nivel alto. El led cuando está encendido tiene una Vled cercana a 2V, por
lo tanto Vr=5V-Vled=3V. Si queremos que el led luzca bien, utilizaremos una corriente de 15mA, por lo tanto
R=3V/15mA = 200ohm.
Bloques:
Code:
delay(500); // During 500 milliseconds
void loop()
{
digitalWrite(8, HIGH); //ON
}
{
digitalWrite(8, LOW); //OFF
p inMode(8, OUTPUT);
void setup()
delay(500); // During 500 milliseconds
}
Circuito:
Ÿ Simular el circuito en Tinkercad.
Ÿ Comparar los bloques con el código generado por Tinkercad (seleccionar la opción block+text y Tinkercad
generará el código).
https://www.tinkercad.com/things/ejt30quxU9d
2. Traffic Light (semáforo)
Ÿ Usando Tinkercad circuits, crear un circuito con Arduino UNO, una protoboard, y tres leds (rojo, amarillo y
verde) conectados a los pines 2,3,4.
Ÿ Usando bloques escribir un programa que implemente un semáforo: la luz verde estará encendida durante
20s, luego la luz amarilla parpadeará 10 veces y luego la luz roja estará encendida durante 20s.
Ÿ Montar el correspondiente circuito real, programarlo con Arduino IDE y probarlo.
Los bloques corresponden al contenido del loop().
Se ejecutará en un bucle infinito.
6 7
Circuito:
Las salidas de Arduino son 5V cuando están a nivel alto. El led cuando está encendido tiene una Vled cercana a 2V, por
lo tanto Vr=5V-Vled=3V. Si queremos que el led luzca bien, utilizaremos una corriente de 15mA, por lo tanto
R=3V/15mA = 200ohm.
Bloques:
Code:
delay(500); // During 500 milliseconds
void loop()
{
digitalWrite(8, HIGH); //ON
}
{
digitalWrite(8, LOW); //OFF
p inMode(8, OUTPUT);
void setup()
delay(500); // During 500 milliseconds
}
Circuito:
Ÿ Simular el circuito en Tinkercad.
Ÿ Comparar los bloques con el código generado por Tinkercad (seleccionar la opción block+text y Tinkercad
generará el código).
https://www.tinkercad.com/things/ejt30quxU9d
2. Traffic Light (semáforo)
Ÿ Usando Tinkercad circuits, crear un circuito con Arduino UNO, una protoboard, y tres leds (rojo, amarillo y
verde) conectados a los pines 2,3,4.
Ÿ Usando bloques escribir un programa que implemente un semáforo: la luz verde estará encendida durante
20s, luego la luz amarilla parpadeará 10 veces y luego la luz roja estará encendida durante 20s.
Ÿ Montar el correspondiente circuito real, programarlo con Arduino IDE y probarlo.
Los bloques corresponden al contenido del loop().
Se ejecutará en un bucle infinito.
8 9
Bloques:
Código:
void setup()
digitalWrite(3, LOW);
pinMode(3, OUTPUT);
digitalWrite(2, LOW);
digitalWrite(4, LOW);
pinMode(2, OUTPUT);
digitalWrite(2, HIGH); //Green
delay(20000); // during 20s
{
{
pinMode(4, OUTPUT);
}
void loop()
}
digitalWrite(4, HIGH);
digitalWrite(3, LOW);
Circuito:
digitalWrite(3, HIGH); //yellow ON
digitalWrite(3, LOW); //yellow OFF
delay(500); // during 500 milliseconds
delay(20000); // during 20s
Ÿ Usando Tinkercad circuits, crear un circuito con Arduino UNO, una protoboard, un led y un micropulsador
para encender/apagar.
Ÿ Montar el correspondiente circuito real, porogramarlo con Arduino IDE y probarlo.
for (int counter = 0; counter < 10; ++counter) //blink 10 times
digitalWrite(2, LOW); //RED
delay(500); // during 500 milliseconds
{
}
https://www.tinkercad.com/things/cdgx8jSsFSo
3. Switch on/off a light (encender/apagar una luz)
Ÿ Usando bloques escribir un programa que espere a que el usuario pulse el pulsador y cambie el estado del led
(encendido/apagado).
Ÿ Simular el circuito en Tinkercad.
Ÿ Comparar los bloques con el código generado por Tinkercad (seleccionar blocks+text y Tinkercad generará el
código).
8 9
Bloques:
Código:
void setup()
digitalWrite(3, LOW);
pinMode(3, OUTPUT);
digitalWrite(2, LOW);
digitalWrite(4, LOW);
pinMode(2, OUTPUT);
digitalWrite(2, HIGH); //Green
delay(20000); // during 20s
{
{
pinMode(4, OUTPUT);
}
void loop()
}
digitalWrite(4, HIGH);
digitalWrite(3, LOW);
Circuito:
digitalWrite(3, HIGH); //yellow ON
digitalWrite(3, LOW); //yellow OFF
delay(500); // during 500 milliseconds
delay(20000); // during 20s
Ÿ Usando Tinkercad circuits, crear un circuito con Arduino UNO, una protoboard, un led y un micropulsador
para encender/apagar.
Ÿ Montar el correspondiente circuito real, porogramarlo con Arduino IDE y probarlo.
for (int counter = 0; counter < 10; ++counter) //blink 10 times
digitalWrite(2, LOW); //RED
delay(500); // during 500 milliseconds
{
}
https://www.tinkercad.com/things/cdgx8jSsFSo
3. Switch on/off a light (encender/apagar una luz)
Ÿ Usando bloques escribir un programa que espere a que el usuario pulse el pulsador y cambie el estado del led
(encendido/apagado).
Ÿ Simular el circuito en Tinkercad.
Ÿ Comparar los bloques con el código generado por Tinkercad (seleccionar blocks+text y Tinkercad generará el
código).
10 11
while (digitalRead(2) == 1) { } //wait release
{
delay(20); // Wait for 20 milliseconds to avoid rebounds when pressing
Bloques:
Código:
int state = 0;
{
void setup()
pinMode(2, INPUT);
pinMode(8, OUTPUT);
}
void loop()
{
if (digitalRead(2) == 1)
} else
{
{
}
} else
}
delay(20); // Wait for 20 milliseconds to avoid rebounds when releasing
{
if (state == 1)
state = 0;
if (state == 0)
{
}
https://www.tinkercad.com/things/lTBPtStOWzM
}
state = 1;
digitalWrite(8, LOW);
digitalWrite(8, HIGH);
10 11
while (digitalRead(2) == 1) { } //wait release
{
delay(20); // Wait for 20 milliseconds to avoid rebounds when pressing
Bloques:
Código:
int state = 0;
{
void setup()
pinMode(2, INPUT);
pinMode(8, OUTPUT);
}
void loop()
{
if (digitalRead(2) == 1)
} else
{
{
}
} else
}
delay(20); // Wait for 20 milliseconds to avoid rebounds when releasing
{
if (state == 1)
state = 0;
if (state == 0)
{
}
https://www.tinkercad.com/things/lTBPtStOWzM
}
state = 1;
digitalWrite(8, LOW);
digitalWrite(8, HIGH);
12 13
LECCIÓN 5:
ARDUINO BÁSICO
�
Ÿ Montar el correspondiente circuito real en protoboard, programarlo con Arduino IDE y probarlo.
Ÿ Usando Tinkercad circuits, crear un circuito con un Arduino UNO, una protoboard y un LCD. Mostrar “Hello
world” en el LCD.
Ÿ Simular el circuito en Tinkercad.
Ÿ ¿Pará qué es el potenciómetro?
Circuito:
1. LCD
Ÿ LCD: https://www.tinkercad.com/things/h6c7oCjkj7L
Ÿ Control de un servo: https://www.tinkercad.com/things/9qYj2rVm0jD
Ÿ Escribir programas básicos en Arduino utilizando librerías con clases y objetos de C++.
Objetivos:
Después de completar esta lección, los alumnos deben ser capaces de:
Ÿ Usar un LCD en Arduino para mostrar mensajes al usuario.
Ÿ Diferenciar entre el uso analógico y digital de las entradas y salidas en Arduino.
Ejercicios
Ÿ Medida de temperatura: https://www.tinkercad.com/things/8h3Z9DviRtp
Ÿ Tabla ASCII: https://www.tinkercad.com/things/icWyROFaZr9
Ÿ Usar diferentes tipos de sensores y actuadores (sensores de temperatura, sensores de distancia, servomotores).
Ÿ Medida de distancia con el sensor Parallax ping: https://www.tinkercad.com/things/kDk54zrw28W
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
}
lcd.setCursor(0, 1);
lcd.print(millis() / 1000);
Ÿ Usando Tinkercad circuits, crear un circuto con Arduino UNO, una protoboard y un LCD. Mostrar la tabla ASCII
completa en el LCD.
Ÿ Montar el circuito real correspondiente, programarlo usando Arduino IDE y probarlo.
#include <LiquidCrystal.h>
Código:
lcd.print("hello, world!");
void loop() {
// set the cursor to column 0, line 1
lcd.begin(16, 2);
void setup() {
// set up the LCD's number of columns and rows:
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
// Print a message to the LCD.
// (note: line 1 is the second row, since counting begins with 0):
// print the number of seconds since reset:
}
https://www.tinkercad.com/things/h6c7oCjkj7L
2. Tabla ASCII
Ÿ Simular el circuito en Tinkercad.
12 13
LECCIÓN 5:
ARDUINO BÁSICO
�
Ÿ Montar el correspondiente circuito real en protoboard, programarlo con Arduino IDE y probarlo.
Ÿ Usando Tinkercad circuits, crear un circuito con un Arduino UNO, una protoboard y un LCD. Mostrar “Hello
world” en el LCD.
Ÿ Simular el circuito en Tinkercad.
Ÿ ¿Pará qué es el potenciómetro?
Circuito:
1. LCD
Ÿ LCD: https://www.tinkercad.com/things/h6c7oCjkj7L
Ÿ Control de un servo: https://www.tinkercad.com/things/9qYj2rVm0jD
Ÿ Escribir programas básicos en Arduino utilizando librerías con clases y objetos de C++.
Objetivos:
Después de completar esta lección, los alumnos deben ser capaces de:
Ÿ Usar un LCD en Arduino para mostrar mensajes al usuario.
Ÿ Diferenciar entre el uso analógico y digital de las entradas y salidas en Arduino.
Ejercicios
Ÿ Medida de temperatura: https://www.tinkercad.com/things/8h3Z9DviRtp
Ÿ Tabla ASCII: https://www.tinkercad.com/things/icWyROFaZr9
Ÿ Usar diferentes tipos de sensores y actuadores (sensores de temperatura, sensores de distancia, servomotores).
Ÿ Medida de distancia con el sensor Parallax ping: https://www.tinkercad.com/things/kDk54zrw28W
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
}
lcd.setCursor(0, 1);
lcd.print(millis() / 1000);
Ÿ Usando Tinkercad circuits, crear un circuto con Arduino UNO, una protoboard y un LCD. Mostrar la tabla ASCII
completa en el LCD.
Ÿ Montar el circuito real correspondiente, programarlo usando Arduino IDE y probarlo.
#include <LiquidCrystal.h>
Código:
lcd.print("hello, world!");
void loop() {
// set the cursor to column 0, line 1
lcd.begin(16, 2);
void setup() {
// set up the LCD's number of columns and rows:
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
// Print a message to the LCD.
// (note: line 1 is the second row, since counting begins with 0):
// print the number of seconds since reset:
}
https://www.tinkercad.com/things/h6c7oCjkj7L
2. Tabla ASCII
Ÿ Simular el circuito en Tinkercad.
14 15
Circuito:
lcd.print("ASCII table");
Código:
#include <LiquidCrystal.h>
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup()
{
lcd.begin(16, 2);
}
void loop()
{
delay(3000);
lcd.print(msg);
}
lcd.setCursor(0, 0);
delay(500);
{
sprintf(msg,"Ascii:%i Char:%c",i,i); //prints code and character
}
lcd.clear();
for(int i=32; i<256; i++) //from blank space to end of ascii table
char msg[20];
3. Medida de temperatura
void setup()
}
{
char msg[20];
lcd.setCursor(0, 0);
// set up the LCD's number of columns and rows:
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
lcd.print(msg);
{
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
Usando un sensor LM35 se deberá mostrar la temperatura actual en un LCD. Consultar la documentación sobre
el LM35 en: http://www.ti.com/lit/ds/symlink/lm35.pdf. Como se puede comprobar, el sensor da una tensión de
10mV/ºC.
Circuito:
Código:
#include <LiquidCrystal.h>
lcd.begin(16, 2);
void loop()
int temp=analogRead(0)*500/1023; //10mV/ºC -> convert to ºC
sprintf(msg,"Temp = %d%cC",temp,178); //create the text string to send to the LCD
} https://www.tinkercad.com/things/8h3Z9DviRtp
https://www.tinkercad.com/things/icWyROFaZr9
14 15
Circuito:
lcd.print("ASCII table");
Código:
#include <LiquidCrystal.h>
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup()
{
lcd.begin(16, 2);
}
void loop()
{
delay(3000);
lcd.print(msg);
}
lcd.setCursor(0, 0);
delay(500);
{
sprintf(msg,"Ascii:%i Char:%c",i,i); //prints code and character
}
lcd.clear();
for(int i=32; i<256; i++) //from blank space to end of ascii table
char msg[20];
3. Medida de temperatura
void setup()
}
{
char msg[20];
lcd.setCursor(0, 0);
// set up the LCD's number of columns and rows:
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
lcd.print(msg);
{
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
Usando un sensor LM35 se deberá mostrar la temperatura actual en un LCD. Consultar la documentación sobre
el LM35 en: http://www.ti.com/lit/ds/symlink/lm35.pdf. Como se puede comprobar, el sensor da una tensión de
10mV/ºC.
Circuito:
Código:
#include <LiquidCrystal.h>
lcd.begin(16, 2);
void loop()
int temp=analogRead(0)*500/1023; //10mV/ºC -> convert to ºC
sprintf(msg,"Temp = %d%cC",temp,178); //create the text string to send to the LCD
} https://www.tinkercad.com/things/8h3Z9DviRtp
https://www.tinkercad.com/things/icWyROFaZr9
16 17
4. Midiendo distancias con el sensor Paralax Ping
Código:
}
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
Circuito:
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
const int ping = 2;
https://www.parallax.com/product/28015.
#include <LiquidCrystal.h>
Utilizar el sensor Ping de Paralax para medir distancia y mostrarla en cm el LCD. Se hará en Tinkercad y se
simulará. Se montará el circuito real correspondiente y se probará. En caso de no disponer del sensor Ping de
Parallax, se puede hacer las modificaciones necesarias para hacer el circuito usando el sensor HC-SR04, pero en
este caso se usará un pin para trigger y otro para echo. Documentación del sensor:
void setup()
{
lcd.begin(16, 2);
void loop()
{
int distance= duration/58;
long duration = pulseIn(ping, HIGH);
// Calculating the distance
lcd.print("Distance: ");
lcd.print(distance);
Se va a controlar la posición de un servo de acuerdo con la posición de un potenciómetro. Se conectará el
potenciómetro de forma que de un valor entre 0 y 5V en el pin A3. Se conectará el servo al pin D9 y se controlará
generando una señal PWM en ese pin utilizando la clase Servo.
5. Control de un servo
}
lcd.setCursor(0, 1);
// Trigger pin start low
pinMode(ping, OUTPUT); // Output
digitalWrite(ping, LOW);
delayMicroseconds(2);
// Generation of a 10us HIGH pulse as trigger
delayMicroseconds(10);
digitalWrite(ping, LOW);
digitalWrite(ping, HIGH);
// Reading the echo duration
pinMode(ping, INPUT); // set to input for echo
https://www.tinkercad.com/things/kDk54zrw28W
16 17
4. Midiendo distancias con el sensor Paralax Ping
Código:
}
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
Circuito:
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
const int ping = 2;
https://www.parallax.com/product/28015.
#include <LiquidCrystal.h>
Utilizar el sensor Ping de Paralax para medir distancia y mostrarla en cm el LCD. Se hará en Tinkercad y se
simulará. Se montará el circuito real correspondiente y se probará. En caso de no disponer del sensor Ping de
Parallax, se puede hacer las modificaciones necesarias para hacer el circuito usando el sensor HC-SR04, pero en
este caso se usará un pin para trigger y otro para echo. Documentación del sensor:
void setup()
{
lcd.begin(16, 2);
void loop()
{
int distance= duration/58;
long duration = pulseIn(ping, HIGH);
// Calculating the distance
lcd.print("Distance: ");
lcd.print(distance);
Se va a controlar la posición de un servo de acuerdo con la posición de un potenciómetro. Se conectará el
potenciómetro de forma que de un valor entre 0 y 5V en el pin A3. Se conectará el servo al pin D9 y se controlará
generando una señal PWM en ese pin utilizando la clase Servo.
5. Control de un servo
}
lcd.setCursor(0, 1);
// Trigger pin start low
pinMode(ping, OUTPUT); // Output
digitalWrite(ping, LOW);
delayMicroseconds(2);
// Generation of a 10us HIGH pulse as trigger
delayMicroseconds(10);
digitalWrite(ping, LOW);
digitalWrite(ping, HIGH);
// Reading the echo duration
pinMode(ping, INPUT); // set to input for echo
https://www.tinkercad.com/things/kDk54zrw28W
18 19
#include <Servo.h>
void setup()
Código:
Servo servo;
#define pinPotentiometer A3
{
servo.attach(9);
void loop()
}
{
int potentiometer=analogRead(pinPotentiometer);
servo.write(position);
}
int position=map(potentiometer,0,1023,0,180);
Circuito:
https://www.tinkercad.com/things/9qYj2rVm0jD
LECCIÓN 6:
ARDUINO AVANZADO
Ÿ Entender y usar estructuras complejas en C++ y clases y objetos complejos.
Ejercicios:
Objetivos:
Ÿ Montar el correspondiente circuito real, programarlo con Arduino IDE y probarlo.
Ÿ Efectos luminosos.
1. Control PWM
�
Circuito:
Ÿ Usar combinaciones complejas de hardware y software en Arduino.
Ÿ Comunicar Arduino con otros plataformas y crear soluciones mixtas de hardware/software.
Ÿ Control PWM: https://www.tinkercad.com/things/hm05Kl1ERG5
Ÿ Control de accesos con Arduino Yun: https://github.com/fperal/AccessControl
Ÿ Crear librerías en C++ con funciones, clases y objetos.
Ÿ Entender los esquemáticos y utilizarlos como una guía para montar circuitos utilizando Arduino y hardware
diverso.
Ÿ Usando Tinkercad circuits, crear un circuito con Arduino UNO, una protoboard, un LCD, un driver y un motor
DC. Deberá tener tres botones: uno fijará la rotación en el sentido de las agujas del reloj, otro fijará la rotación
en sentido contrario a las agujas del reloj y el otro parará el motor. Tendrá un potenciómetro que fijará la
velocidad del motor.
Ÿ Simular el circuito en Tinkercad.
Después de completar esta sesión, los alumnos deben ser capaces de:
18 19
#include <Servo.h>
void setup()
Código:
Servo servo;
#define pinPotentiometer A3
{
servo.attach(9);
void loop()
}
{
int potentiometer=analogRead(pinPotentiometer);
servo.write(position);
}
int position=map(potentiometer,0,1023,0,180);
Circuito:
https://www.tinkercad.com/things/9qYj2rVm0jD
LECCIÓN 6:
ARDUINO AVANZADO
Ÿ Entender y usar estructuras complejas en C++ y clases y objetos complejos.
Ejercicios:
Objetivos:
Ÿ Montar el correspondiente circuito real, programarlo con Arduino IDE y probarlo.
Ÿ Efectos luminosos.
1. Control PWM
�
Circuito:
Ÿ Usar combinaciones complejas de hardware y software en Arduino.
Ÿ Comunicar Arduino con otros plataformas y crear soluciones mixtas de hardware/software.
Ÿ Control PWM: https://www.tinkercad.com/things/hm05Kl1ERG5
Ÿ Control de accesos con Arduino Yun: https://github.com/fperal/AccessControl
Ÿ Crear librerías en C++ con funciones, clases y objetos.
Ÿ Entender los esquemáticos y utilizarlos como una guía para montar circuitos utilizando Arduino y hardware
diverso.
Ÿ Usando Tinkercad circuits, crear un circuito con Arduino UNO, una protoboard, un LCD, un driver y un motor
DC. Deberá tener tres botones: uno fijará la rotación en el sentido de las agujas del reloj, otro fijará la rotación
en sentido contrario a las agujas del reloj y el otro parará el motor. Tendrá un potenciómetro que fijará la
velocidad del motor.
Ÿ Simular el circuito en Tinkercad.
Después de completar esta sesión, los alumnos deben ser capaces de:
20 21
#define clockwise 0
#define ButtonStop 17
#define enable 3
{
Código:
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
#define counterclockwise 1
#define stop 2
#define MotorPositive 9
#include <LiquidCrystal.h>
#define MotorNegative 10
#define ButtonCW 15
#define ButtonCCW 16
void SetMotorDirection(int dir);
void SetMotorSpeed(int percent);
void setup()
// set up the LCD's number of columns and rows:
pinMode(enable,OUTPUT);
pinMode(MotorNegative,OUTPUT);
lcd.begin(16, 2);
pinMode(ButtonCW,INPUT);
pinMode(ButtonCCW,INPUT);
}
pinMode(MotorPositive,OUTPUT);
pinMode(ButtonStop,INPUT);
if (digitalRead(ButtonCW))
{
void loop()
{
{
int speed=analogRead(A0)/10;
lcd.setCursor(0, 0);
lcd.setCursor(0, 0);
lcd.print("Dir: CCW ");
if (digitalRead(ButtonStop))
SetMotorSpeed(speed);
lcd.setCursor(0, 0);
}
lcd.setCursor(0,1);
lcd.print("Dir: stop ");
}
}
SetMotorDirection(stop);
SetMotorDirection(counterclockwise);
SetMotorDirection(clockwise);
lcd.print(speed);
{
lcd.print("Dir: CW ");
if (digitalRead(ButtonCCW))
}
lcd.print("Speed: ");
lcd.print(" ");
20 21
#define clockwise 0
#define ButtonStop 17
#define enable 3
{
Código:
const int rs = 13, en = 11, d4 = 7, d5 = 6, d6 = 5, d7 = 4;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
#define counterclockwise 1
#define stop 2
#define MotorPositive 9
#include <LiquidCrystal.h>
#define MotorNegative 10
#define ButtonCW 15
#define ButtonCCW 16
void SetMotorDirection(int dir);
void SetMotorSpeed(int percent);
void setup()
// set up the LCD's number of columns and rows:
pinMode(enable,OUTPUT);
pinMode(MotorNegative,OUTPUT);
lcd.begin(16, 2);
pinMode(ButtonCW,INPUT);
pinMode(ButtonCCW,INPUT);
}
pinMode(MotorPositive,OUTPUT);
pinMode(ButtonStop,INPUT);
if (digitalRead(ButtonCW))
{
void loop()
{
{
int speed=analogRead(A0)/10;
lcd.setCursor(0, 0);
lcd.setCursor(0, 0);
lcd.print("Dir: CCW ");
if (digitalRead(ButtonStop))
SetMotorSpeed(speed);
lcd.setCursor(0, 0);
}
lcd.setCursor(0,1);
lcd.print("Dir: stop ");
}
}
SetMotorDirection(stop);
SetMotorDirection(counterclockwise);
SetMotorDirection(clockwise);
lcd.print(speed);
{
lcd.print("Dir: CW ");
if (digitalRead(ButtonCCW))
}
lcd.print("Speed: ");
lcd.print(" ");
22 23
digitalWrite(MotorPositive,LOW);
break;
{
analogWrite(enable,percent*2.55);
void SetMotorDirection(int dir)
{
switch(dir)
{
digitalWrite(MotorPositive,HIGH);
digitalWrite(MotorNegative,LOW);
case clockwise:
void SetMotorSpeed(int percent)
}
case counterclockwise:
digitalWrite(MotorNegative,HIGH);
digitalWrite(MotorPositive,HIGH);
case stop:
}
}
break;
digitalWrite(MotorNegative,HIGH);
2. Efectos luminosos
Documentación:
l Vamos a usar la clase fastLED para hacer varios efectos de luz con una tira de leds de color.
break;
Ÿ Fastled class
Ÿ RGB led strip
Ÿ Fastled basic usage
}
for(int i=0; i<NumLeds; i++)
}
Código:
#include "FastLED.h"
{
for(int i=0; i<NumLeds; i++)
void loop()
delay(100);
void setup()
#define DATA_PIN 6
//red increasing gradient
randomSeed(analogRead(0));
leds[i].red=i; FastLED.show();
#define NumLeds 30
{
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NumLeds);
{
{
leds[i] = CRGB::Black; FastLED.show(); delay(30);
CRGB leds[NumLeds];
//white sweep
leds[i] = CRGB::White; FastLED.show(); delay(30);
//clearing red
for(int i=0; i<NumLeds; i++)
//color gradient
}
https://www.tinkercad.com/things/hm
05Kl1ERG5
22 23
digitalWrite(MotorPositive,LOW);
break;
{
analogWrite(enable,percent*2.55);
void SetMotorDirection(int dir)
{
switch(dir)
{
digitalWrite(MotorPositive,HIGH);
digitalWrite(MotorNegative,LOW);
case clockwise:
void SetMotorSpeed(int percent)
}
case counterclockwise:
digitalWrite(MotorNegative,HIGH);
digitalWrite(MotorPositive,HIGH);
case stop:
}
}
break;
digitalWrite(MotorNegative,HIGH);
2. Efectos luminosos
Documentación:
l Vamos a usar la clase fastLED para hacer varios efectos de luz con una tira de leds de color.
break;
Ÿ Fastled class
Ÿ RGB led strip
Ÿ Fastled basic usage
}
for(int i=0; i<NumLeds; i++)
}
Código:
#include "FastLED.h"
{
for(int i=0; i<NumLeds; i++)
void loop()
delay(100);
void setup()
#define DATA_PIN 6
//red increasing gradient
randomSeed(analogRead(0));
leds[i].red=i; FastLED.show();
#define NumLeds 30
{
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NumLeds);
{
{
leds[i] = CRGB::Black; FastLED.show(); delay(30);
CRGB leds[NumLeds];
//white sweep
leds[i] = CRGB::White; FastLED.show(); delay(30);
//clearing red
for(int i=0; i<NumLeds; i++)
//color gradient
}
https://www.tinkercad.com/things/hm
05Kl1ERG5
24 25
delay(100);
//gree increasing gradient
{
leds[i].red=0; FastLED.show();
}
for(int i=0; i<NumLeds; i++)
{
leds[i].green=i; FastLED.show();
}
delay(100);
//clearing gree
for(int i=0; i<NumLeds; i++)
{
leds[i].green=0; FastLED.show();
delay(100);
}
delay(100);
for(int i=0; i<NumLeds; i++)
leds[i].blue=i; FastLED.show();
//clearing blue
{
//blue increasing gradient
for(int i=0; i<NumLeds; i++)
{
delay(100);
}
leds[i].blue=0; FastLED.show();
}
{
green=random(255);
int time=millis();
leds[led].red=red;
red=random(255);
blue=random(255);
Ÿ El programa leerá los tokens a través del RMD6300, que estará conectado al puerto serie de Arduino,
comprobará si el token está autorizado, y abrirá la puerta en caso afirmativo.
FastLED.show();
} while (millis()<(time+5000)); //during 5seconds
leds[led].green=green;
do
}
leds[led].blue=blue;
led=random(NumLeds);
//random colors on each led
int red,green,blue,led;
Ÿ � El Arduino Yun mantendrá un archivo con una lista de los usuarios autorizados y los tokens, y otro archivo
con un log de los accesos.
Documentation :
3. Control de accesos con Arduino Yun
Ÿ El objetivo de este ejercicio es controlar el acceso a un lugar controlando una cerradura eléctrica mediante
tokens RFID y un lector RMD6300 utilizando un Arduino Yun.
Ÿ RMD6300
Ÿ RFID tokens
24 25
delay(100);
//gree increasing gradient
{
leds[i].red=0; FastLED.show();
}
for(int i=0; i<NumLeds; i++)
{
leds[i].green=i; FastLED.show();
}
delay(100);
//clearing gree
for(int i=0; i<NumLeds; i++)
{
leds[i].green=0; FastLED.show();
delay(100);
}
delay(100);
for(int i=0; i<NumLeds; i++)
leds[i].blue=i; FastLED.show();
//clearing blue
{
//blue increasing gradient
for(int i=0; i<NumLeds; i++)
{
delay(100);
}
leds[i].blue=0; FastLED.show();
}
{
green=random(255);
int time=millis();
leds[led].red=red;
red=random(255);
blue=random(255);
Ÿ El programa leerá los tokens a través del RMD6300, que estará conectado al puerto serie de Arduino,
comprobará si el token está autorizado, y abrirá la puerta en caso afirmativo.
FastLED.show();
} while (millis()<(time+5000)); //during 5seconds
leds[led].green=green;
do
}
leds[led].blue=blue;
led=random(NumLeds);
//random colors on each led
int red,green,blue,led;
Ÿ � El Arduino Yun mantendrá un archivo con una lista de los usuarios autorizados y los tokens, y otro archivo
con un log de los accesos.
Documentation :
3. Control de accesos con Arduino Yun
Ÿ El objetivo de este ejercicio es controlar el acceso a un lugar controlando una cerradura eléctrica mediante
tokens RFID y un lector RMD6300 utilizando un Arduino Yun.
Ÿ RMD6300
Ÿ RFID tokens
26 27
Circuito:
////////////////////////////////////////////////////////////////////////////////////////////
//
// Arduino program uses RMD6300 to read RFID tokens
// RFIDYun
// Linino part stores RFID valid numbers in a file named users
// users format is similar to /etc/passwd: one line for each user
// line format is RFIDid:username
// RFIDid is a 7 digit number
#include <FileIO.h>
#include <Bridge.h>
//DEBUG uses "serial" console. If it is not available it freezes at the beginning of the program
//AltSoftSerial work better than softwareserial (better performance)
unsigned long int longCalcCode(char *tag);
//SoftwareSerial RFID(2,8); //(RX=2, TX=8)
//#define DEBUG
//FILEDEBUG uses access log file to log button apen as well as rfid login
unsigned char HexToNum(unsigned char digit);
//it uses a timer
int TagCheck(unsigned long int code, char *tag);
String getTimeStamp();
#include <AltSoftSerial.h>
#define FILEDEBUG
//#include <SoftwareSerial.h>
int ReadUser(File&, char *tag, char *username);
AltSoftSerial RFID; //(RX=13, TX=5)
Código:
26 27
Circuito:
////////////////////////////////////////////////////////////////////////////////////////////
//
// Arduino program uses RMD6300 to read RFID tokens
// RFIDYun
// Linino part stores RFID valid numbers in a file named users
// users format is similar to /etc/passwd: one line for each user
// line format is RFIDid:username
// RFIDid is a 7 digit number
#include <FileIO.h>
#include <Bridge.h>
//DEBUG uses "serial" console. If it is not available it freezes at the beginning of the program
//AltSoftSerial work better than softwareserial (better performance)
unsigned long int longCalcCode(char *tag);
//SoftwareSerial RFID(2,8); //(RX=2, TX=8)
//#define DEBUG
//FILEDEBUG uses access log file to log button apen as well as rfid login
unsigned char HexToNum(unsigned char digit);
//it uses a timer
int TagCheck(unsigned long int code, char *tag);
String getTimeStamp();
#include <AltSoftSerial.h>
#define FILEDEBUG
//#include <SoftwareSerial.h>
int ReadUser(File&, char *tag, char *username);
AltSoftSerial RFID; //(RX=13, TX=5)
Código:
28 29
Console.begin(); //start communication with ethernet console (300bps)
#endif
#ifdef DEBUG
Console.println("Arduino starting......");
//green led pin 8
#define BUTTON 11
//red led pin 10
#define GREEN 8
#define RED 10
RFID.begin(9600); // start serial to RFID reader
pinMode(GREEN, OUTPUT);
void setup()
pinMode(RED, OUTPUT);
Bridge.begin(); //start communication with linino
{
while (!Console); //wait until console is ready
/* //initialize comunication with the filesystem in the linino part
FileSystem.open("users",FILE_READ);
}
char tag[14];
int index = 0;
int i;
FileSystem.begin();
void loop()
{
*/
UsersFile.close(); //finished reading, file closed
File LogFile = FileSystem.open("/root/accesslog", FILE_APPEND);
File UsersFile = FileSystem.open("/root/users", FILE_READ);
{
//create objets UsersFile, linked to users in linino, open for reading
#endif
i = RFID.read();
tag[index++] = i;
Console.println(" "); //sending LF to the console (if not it does not show)
#ifdef DEBUG //printing the code readed to the console terminal
char rfid[10], user[25], userOK[25] = "";
do //making a sweep of the 13 bytes and putting all together in a string
} while (i != 3);
{
if (TagCheck(atol(rfid), tag)) //convert string to number and check against tag
{
Console.print(" ");
OK = 1;
strcpy(userOK, user);
Console.print(i);
#ifdef DEBUG
#endif
int OK = 0;
while (ReadUser(UsersFile, rfid, user) == 0) //we will sweep all users file until user found or EOF
}
if (RFID.available() > 13) //RFID token is 13 bytes long, so I check if there is at least 13 bytes
{
}
//creating log, it will add user to the end of the log file
28 29
Console.begin(); //start communication with ethernet console (300bps)
#endif
#ifdef DEBUG
Console.println("Arduino starting......");
//green led pin 8
#define BUTTON 11
//red led pin 10
#define GREEN 8
#define RED 10
RFID.begin(9600); // start serial to RFID reader
pinMode(GREEN, OUTPUT);
void setup()
pinMode(RED, OUTPUT);
Bridge.begin(); //start communication with linino
{
while (!Console); //wait until console is ready
/* //initialize comunication with the filesystem in the linino part
FileSystem.open("users",FILE_READ);
}
char tag[14];
int index = 0;
int i;
FileSystem.begin();
void loop()
{
*/
UsersFile.close(); //finished reading, file closed
File LogFile = FileSystem.open("/root/accesslog", FILE_APPEND);
File UsersFile = FileSystem.open("/root/users", FILE_READ);
{
//create objets UsersFile, linked to users in linino, open for reading
#endif
i = RFID.read();
tag[index++] = i;
Console.println(" "); //sending LF to the console (if not it does not show)
#ifdef DEBUG //printing the code readed to the console terminal
char rfid[10], user[25], userOK[25] = "";
do //making a sweep of the 13 bytes and putting all together in a string
} while (i != 3);
{
if (TagCheck(atol(rfid), tag)) //convert string to number and check against tag
{
Console.print(" ");
OK = 1;
strcpy(userOK, user);
Console.print(i);
#ifdef DEBUG
#endif
int OK = 0;
while (ReadUser(UsersFile, rfid, user) == 0) //we will sweep all users file until user found or EOF
}
if (RFID.available() > 13) //RFID token is 13 bytes long, so I check if there is at least 13 bytes
{
}
//creating log, it will add user to the end of the log file
30 31
Console.println("OK");
Console.println(userOK);
LogFile.print(userOK); //log access to file
if (OK)
{
#ifdef DEBUG
Console.print("Hello ");
#endif
LogFile.print(" access at "); LogFile.println(getTimeStamp());
digitalWrite(GREEN, HIGH);
delay(2000);
}
else
{
#ifdef DEBUG
Console.println("ERROR");
#endif
digitalWrite(RED, HIGH);
delay(2000);
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
}
LogFile.close();
RFID.flush();
while (RFID.available())RFID.read(); //flush seem not to work well, so I read all data from RFID to empty it
//without this, it reads 6 times each RFID.
delay(3000);
//getting date in seconds from midnight
String sDate=getTimeStamp();
//format HH:MM/O for open the door
{
String line=CalendarFile.readStringUntil('\n');
int OpenTheDoor=0;
unsigned long int LineSeconds=3600*(line.substring(0,2)).toInt()+60*(line.substring(3,5)).toInt();
//Reading lines from the file. The lines are marked with the time in wich we open or close the door
String sHours=sDate.substring(11,13);
if (sDay.toInt()<6) //from monday to friday
{
if (line.substring(6,7)=="O") OpenTheDoor=1;
if (line.substring(6,7)=="C") OpenTheDoor=0;
// calendar file /root/calendar
String sDay=sDate.substring(0,1);
String sSeconds=sDate.substring(17,19);
unsigned long int seconds=3600*sHours.toInt()+60*sMinutes.toInt()+sSeconds.toInt();
//and HH:MM/C for close the door
File CalendarFile = FileSystem.open("/root/calendar", FILE_READ);
while(CalendarFile.available()>0)
{
}
if (line.length()==7 && line.substring(0,1)!="#")
String sMinutes=sDate.substring(14,16);
{
//tranlating HH:MM to seconds from midnight
if (seconds>LineSeconds)
}
}
}
30 31
Console.println("OK");
Console.println(userOK);
LogFile.print(userOK); //log access to file
if (OK)
{
#ifdef DEBUG
Console.print("Hello ");
#endif
LogFile.print(" access at "); LogFile.println(getTimeStamp());
digitalWrite(GREEN, HIGH);
delay(2000);
}
else
{
#ifdef DEBUG
Console.println("ERROR");
#endif
digitalWrite(RED, HIGH);
delay(2000);
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
}
LogFile.close();
RFID.flush();
while (RFID.available())RFID.read(); //flush seem not to work well, so I read all data from RFID to empty it
//without this, it reads 6 times each RFID.
delay(3000);
//getting date in seconds from midnight
String sDate=getTimeStamp();
//format HH:MM/O for open the door
{
String line=CalendarFile.readStringUntil('\n');
int OpenTheDoor=0;
unsigned long int LineSeconds=3600*(line.substring(0,2)).toInt()+60*(line.substring(3,5)).toInt();
//Reading lines from the file. The lines are marked with the time in wich we open or close the door
String sHours=sDate.substring(11,13);
if (sDay.toInt()<6) //from monday to friday
{
if (line.substring(6,7)=="O") OpenTheDoor=1;
if (line.substring(6,7)=="C") OpenTheDoor=0;
// calendar file /root/calendar
String sDay=sDate.substring(0,1);
String sSeconds=sDate.substring(17,19);
unsigned long int seconds=3600*sHours.toInt()+60*sMinutes.toInt()+sSeconds.toInt();
//and HH:MM/C for close the door
File CalendarFile = FileSystem.open("/root/calendar", FILE_READ);
while(CalendarFile.available()>0)
{
}
if (line.length()==7 && line.substring(0,1)!="#")
String sMinutes=sDate.substring(14,16);
{
//tranlating HH:MM to seconds from midnight
if (seconds>LineSeconds)
}
}
}
32 33
}
CalendarFile.close();
{
if(!digitalRead(BUTTON)) //user request to open the door (pull-up)
{
#ifdef DEBUG
Console.println(" / Open / ");
#endif
#ifdef FILEDEBUG
File LogFile = FileSystem.open("/root/accesslog", FILE_APPEND);
LogFile.print("BUTTON access at "); LogFile.println(getTimeStamp());
#endif
digitalWrite(GREEN, HIGH); //it will blink open
if(OpenTheDoor) //if the schedule says the door should be opened now
delay(1000);
digitalWrite(RED,HIGH);
digitalWrite(GREEN, LOW);
}
if(OpenTheDoor) //if the schedule says the door should be opened now
{
digitalWrite(GREEN, LOW);
}
digitalWrite(RED, LOW);
else
}
delay(1000);
/*
{
// HexToNum
// C onvert a HEX digit in ASCII format to a number with its value
{
delay(9000);
//
Console.println(" / Open / ");
delay(1000);
#ifdef DEBUG
digitalWrite(GREEN, LOW);
#endif
#endif
{
delay(10000);
*/
}
#ifdef DEBUG
}
else
Console.println(" / close / ");
digitalWrite(GREEN, HIGH); //it will blink open 1s every 10s
}
///////////////////////////////////////////////////////
//
unsigned char HexToNum(unsigned char digit)
if ( (digit >= '0') && (digit <= '9') ) return digit - 48;
////////////////////////////////////////////////////////
// TagCheck
//
}
if ( (digit >= 'A') && (digit <= 'F') ) return digit - 55;
if ( (digit >= 'a') && (digit <= 'f') ) return digit - 87;
32 33
}
CalendarFile.close();
{
if(!digitalRead(BUTTON)) //user request to open the door (pull-up)
{
#ifdef DEBUG
Console.println(" / Open / ");
#endif
#ifdef FILEDEBUG
File LogFile = FileSystem.open("/root/accesslog", FILE_APPEND);
LogFile.print("BUTTON access at "); LogFile.println(getTimeStamp());
#endif
digitalWrite(GREEN, HIGH); //it will blink open
if(OpenTheDoor) //if the schedule says the door should be opened now
delay(1000);
digitalWrite(RED,HIGH);
digitalWrite(GREEN, LOW);
}
if(OpenTheDoor) //if the schedule says the door should be opened now
{
digitalWrite(GREEN, LOW);
}
digitalWrite(RED, LOW);
else
}
delay(1000);
/*
{
// HexToNum
// C onvert a HEX digit in ASCII format to a number with its value
{
delay(9000);
//
Console.println(" / Open / ");
delay(1000);
#ifdef DEBUG
digitalWrite(GREEN, LOW);
#endif
#endif
{
delay(10000);
*/
}
#ifdef DEBUG
}
else
Console.println(" / close / ");
digitalWrite(GREEN, HIGH); //it will blink open 1s every 10s
}
///////////////////////////////////////////////////////
//
unsigned char HexToNum(unsigned char digit)
if ( (digit >= '0') && (digit <= '9') ) return digit - 48;
////////////////////////////////////////////////////////
// TagCheck
//
}
if ( (digit >= 'A') && (digit <= 'F') ) return digit - 55;
if ( (digit >= 'a') && (digit <= 'f') ) return digit - 87;
34 35
// Check decimal number printed on tag against tag readed
// by RFID sensor in HEX format
// code -> decimal code printed on tag
//
{
unsigned char HexData[4];
for (int i = 3, index = 0; i < 11; i = i + 2, index++) HexData[index] = (HexToNum(tag[i]) << 4) + HexToNum(tag[i +
1]);
//
// tag[] -> character array containig tag in HEX format
int TagCheck(unsigned long int code, char *tag)
unsigned long int CalcCode = HexData[0];
CalcCode = (CalcCode << 8) + HexData[i++]; //generate the code using hex digits weights
while (i < 4)
return code == CalcCode;
////////////////////////////////////////////////////////
}
//
// Convert RFID sensor in HEX format to numeric format
}
int i = 0;
// code -> decimal code printed on tag
//
checksum = checksum ̂ HexData[i];
// longCalcCode
// as printed in tags
int checksum = 0x0A;
{
{
//
int checksum = 0x0A;
// Returns 0 if everything went OK and >0 if there is some error:
unsigned long int longCalcCode(char *tag)
for (int i = 3, index = 0; i < 11; i = i + 2, index++) HexData[index] = (HexToNum(tag[i]) << 4) + HexToNum(tag[i +
1]);
unsigned long int CalcCode = HexData[0];
while (i < 4)
unsigned char HexData[4];
// tag[] -> character array containig tag in HEX format
int i = 0;
}
checksum = checksum ̂ HexData[i];
CalcCode = (CalcCode << 8) + HexData[i++]; //generate the code using hex digits weights
return CalcCode;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// ReadUser
//
}
// Reads linino file for the next tag id
// Returns tagID in string format at tag and username also in string format at username
// 1 -> Error reading file /root/users
// 2 -> Error: /root/users may be empty?
int ReadUser(File& UsersFile, char *tag, char *username)
{
if (UsersFile == 0) return 1;
34 35
// Check decimal number printed on tag against tag readed
// by RFID sensor in HEX format
// code -> decimal code printed on tag
//
{
unsigned char HexData[4];
for (int i = 3, index = 0; i < 11; i = i + 2, index++) HexData[index] = (HexToNum(tag[i]) << 4) + HexToNum(tag[i +
1]);
//
// tag[] -> character array containig tag in HEX format
int TagCheck(unsigned long int code, char *tag)
unsigned long int CalcCode = HexData[0];
CalcCode = (CalcCode << 8) + HexData[i++]; //generate the code using hex digits weights
while (i < 4)
return code == CalcCode;
////////////////////////////////////////////////////////
}
//
// Convert RFID sensor in HEX format to numeric format
}
int i = 0;
// code -> decimal code printed on tag
//
checksum = checksum ̂ HexData[i];
// longCalcCode
// as printed in tags
int checksum = 0x0A;
{
{
//
int checksum = 0x0A;
// Returns 0 if everything went OK and >0 if there is some error:
unsigned long int longCalcCode(char *tag)
for (int i = 3, index = 0; i < 11; i = i + 2, index++) HexData[index] = (HexToNum(tag[i]) << 4) + HexToNum(tag[i +
1]);
unsigned long int CalcCode = HexData[0];
while (i < 4)
unsigned char HexData[4];
// tag[] -> character array containig tag in HEX format
int i = 0;
}
checksum = checksum ̂ HexData[i];
CalcCode = (CalcCode << 8) + HexData[i++]; //generate the code using hex digits weights
return CalcCode;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// ReadUser
//
}
// Reads linino file for the next tag id
// Returns tagID in string format at tag and username also in string format at username
// 1 -> Error reading file /root/users
// 2 -> Error: /root/users may be empty?
int ReadUser(File& UsersFile, char *tag, char *username)
{
if (UsersFile == 0) return 1;
36 37
if (UsersFile.available() == 0) return 2; //no data found. Maybe EOF?
char data[25] = "xx";
int i = 0;
while (UsersFile.available() > 0 && data[i] != '\n') //read file until EOF or LF found
{
tag[i++] = '\0'; //add string terminator
{
tag[i] = data[i];
return 0; //all went OK
// This function return a string with the time stamp
int n = 0;
{
}
i = 0;
} while (data[++i] != '\n');
// getTimeStamp()
// From https://www.arduino.cc/en/Tutorial/YunDatalogger
//////////////////////////////////////////////////////////////////////////////////////////////////////////
if (data[i] != '\n') i++; //next char until LF found
//
//
data[i] = UsersFile.read();
do //read username, until LF found
do //read tag, until : found
username[n++] = data[i];
}
//
username[n] = '\0'; //add end of string
} while (data[++i] != ':');
time.addParameter("+%u %D %T"); // parameters: D for the complete date mm/dd/yy
String getTimeStamp()
{
String result;
Process time;
// date is a command line utility to get the date and the time
// in different formats depending on the additional parameter
time.begin("date");
// T for the time hh:mm:ss
time.run(); // run the command
// read the output of the command
result += c;
if (c != '\n') {
}
}
while (time.available() > 0) {
// u for week day number (1 is monday)
char c = time.read();
}
return result;
https://github.com/fperal/AccessControl
36 37
if (UsersFile.available() == 0) return 2; //no data found. Maybe EOF?
char data[25] = "xx";
int i = 0;
while (UsersFile.available() > 0 && data[i] != '\n') //read file until EOF or LF found
{
tag[i++] = '\0'; //add string terminator
{
tag[i] = data[i];
return 0; //all went OK
// This function return a string with the time stamp
int n = 0;
{
}
i = 0;
} while (data[++i] != '\n');
// getTimeStamp()
// From https://www.arduino.cc/en/Tutorial/YunDatalogger
//////////////////////////////////////////////////////////////////////////////////////////////////////////
if (data[i] != '\n') i++; //next char until LF found
//
//
data[i] = UsersFile.read();
do //read username, until LF found
do //read tag, until : found
username[n++] = data[i];
}
//
username[n] = '\0'; //add end of string
} while (data[++i] != ':');
time.addParameter("+%u %D %T"); // parameters: D for the complete date mm/dd/yy
String getTimeStamp()
{
String result;
Process time;
// date is a command line utility to get the date and the time
// in different formats depending on the additional parameter
time.begin("date");
// T for the time hh:mm:ss
time.run(); // run the command
// read the output of the command
result += c;
if (c != '\n') {
}
}
while (time.available() > 0) {
// u for week day number (1 is monday)
char c = time.read();
}
return result;
https://github.com/fperal/AccessControl
38 39
PROTOBOARD
Una protoboard se usa para montar circuitos de forma rápida sin necesidad de soldar. Los agujeros están
interconectados como se ve en esta imagen.Más información en Wikipedia:
https://en.wikipedia.org/wiki/Breadboard
LED
Uun Diodo Emisor de Luz (Light Emmiting Diode) es un dispositivo optoelectrónico que emite luz coloreada
cuando se polariza en directo. Debe usarse junto con una resistencia para limitar la corriente que circula por él.
Típicamente, tiene una caída de tensión en torno a 2V. Más información en Wikipedia:
https://en.wikipedia.org/wiki/Light-emitting_diode
POTENCIÓMETRO
Es un dispositivo como cualquier otro interruptor. Cierra un circuito.
MICRO PULSADORES
RESISTENCIA
https://en.wikipedia.org/wiki/Resistor
Una resistencia (o resistor) es un dispositivo que proporciona resistencia eléctrica al paso de la corriente. Hay un
código de colores para identificar las resistencias. Más información en Wikipedia:
Es un dispositivo con tres terminales que proporciona resistencia variable. Puede utilizarse como una
resistencia variable o como divisor de tensión. Más información en Wikipedia:
https://en.wikipedia.org/wiki/Potentiometer
ANEXO
38 39
PROTOBOARD
Una protoboard se usa para montar circuitos de forma rápida sin necesidad de soldar. Los agujeros están
interconectados como se ve en esta imagen.Más información en Wikipedia:
https://en.wikipedia.org/wiki/Breadboard
LED
Uun Diodo Emisor de Luz (Light Emmiting Diode) es un dispositivo optoelectrónico que emite luz coloreada
cuando se polariza en directo. Debe usarse junto con una resistencia para limitar la corriente que circula por él.
Típicamente, tiene una caída de tensión en torno a 2V. Más información en Wikipedia:
https://en.wikipedia.org/wiki/Light-emitting_diode
POTENCIÓMETRO
Es un dispositivo como cualquier otro interruptor. Cierra un circuito.
MICRO PULSADORES
RESISTENCIA
https://en.wikipedia.org/wiki/Resistor
Una resistencia (o resistor) es un dispositivo que proporciona resistencia eléctrica al paso de la corriente. Hay un
código de colores para identificar las resistencias. Más información en Wikipedia:
Es un dispositivo con tres terminales que proporciona resistencia variable. Puede utilizarse como una
resistencia variable o como divisor de tensión. Más información en Wikipedia:
https://en.wikipedia.org/wiki/Potentiometer
ANEXO
40 41
LM35
PARALLAX PING
Es un sensor de distancia por ultrasonidos. Emite pulsos de ultrasonidos a 40Khz y mide el tiempo entre el pulso
emitido y el reflejado y genera un pulso de 5V y duración variable proporcional a la distancia medida. Más
información en la web de Parallax:: https://www.parallax.com/product/28015.
El LM35 es un sensor de temperatura integrado. Tiene tres terminales: alimentaciones y salida: La salida es
10mV/ºC. Más información en la página web de Texas Instrument:
MICRO-SERVO
Un micro-servo es un pequeño servomotor. Un servo es un tipo especial de motor controlado por una placa de
control que mantiene el motor en una posición fija. Es posible ajustar la posición con pocos grados de
precisión.La posición del servo se controla mediante el ciclo de trabajo de una señal PWM con una frecuencia
típica de 50Hz ( https://en.wikipedia.org/wiki/Servo_control).
MOSFET A CANAL N
https://www.electronics-tutorials.ws/transistor/tran_6.html
https://en.wikipedia.org/wiki/DC_motor
Es un driver de motor integrado para realizar un puente H. Proporciona control total sobre el motor incluyendo
control bidireccional y frenado. Más información en Wikipedia: https://en.wikipedia.org/wiki/H_bridge
Un micromotor es un pequeño motor de corriente continua capaz de mover un pequeño robot. Debe conectarse
a través de un driver (como L293 o L298) porque necesita corrientes por encima de 100mA para trabajar. Un
micromotor DC normalmente rota a varios miles de rpm y por lo tanto, para bajar su velocidad de giro y aumentar
el par suele ir equipado con una reductora, como este de la imagen. Más información en Wikipedia:
L293
MICRO MOTOR DC
Un MOSFET es un transistor de potencia controlador por tensión de puerta normalmente usado como
interruptor controlador por tensión. Más información:
40 41
LM35
PARALLAX PING
Es un sensor de distancia por ultrasonidos. Emite pulsos de ultrasonidos a 40Khz y mide el tiempo entre el pulso
emitido y el reflejado y genera un pulso de 5V y duración variable proporcional a la distancia medida. Más
información en la web de Parallax:: https://www.parallax.com/product/28015.
El LM35 es un sensor de temperatura integrado. Tiene tres terminales: alimentaciones y salida: La salida es
10mV/ºC. Más información en la página web de Texas Instrument:
MICRO-SERVO
Un micro-servo es un pequeño servomotor. Un servo es un tipo especial de motor controlado por una placa de
control que mantiene el motor en una posición fija. Es posible ajustar la posición con pocos grados de
precisión.La posición del servo se controla mediante el ciclo de trabajo de una señal PWM con una frecuencia
típica de 50Hz ( https://en.wikipedia.org/wiki/Servo_control).
MOSFET A CANAL N
https://www.electronics-tutorials.ws/transistor/tran_6.html
https://en.wikipedia.org/wiki/DC_motor
Es un driver de motor integrado para realizar un puente H. Proporciona control total sobre el motor incluyendo
control bidireccional y frenado. Más información en Wikipedia: https://en.wikipedia.org/wiki/H_bridge
Un micromotor es un pequeño motor de corriente continua capaz de mover un pequeño robot. Debe conectarse
a través de un driver (como L293 o L298) porque necesita corrientes por encima de 100mA para trabajar. Un
micromotor DC normalmente rota a varios miles de rpm y por lo tanto, para bajar su velocidad de giro y aumentar
el par suele ir equipado con una reductora, como este de la imagen. Más información en Wikipedia:
L293
MICRO MOTOR DC
Un MOSFET es un transistor de potencia controlador por tensión de puerta normalmente usado como
interruptor controlador por tensión. Más información:
42 43
TIRA DE LEDS RGB
Es una tira de leds de colores. Cada uno de los leds de la tira se puede controlar de forma individual fijando la
intensidad de cada uno de los tres componentes de color. La tira usada es una tira NeoPixel. Los leds van unidos
en un registro de desplazamiento y se puede fijar el color de cada uno de los componentes de color (rojo, verde y
azul) de cada led con un PWM de 8 bits de precisión (por lo tanto 24 bits/pixel). Más información en Adafruit::
https://www.adafruit.com/product/1376?length=1
LECTOR DE TARJETAS RFID RMD6300 RFID Y TOKENS RFID
El mini módulo RDM6300 125KHz está diseñado para leer códigos de tarjetas compatibles a 125Khz. Tokens de
sólo lectura o tarjetas de lectura/escritura. Más información en Itead wiki:
https://www.itead.cc/wiki/RDM6300
ARDUINO YUN
Arduino Yun es una placa microcontrolada basada en el ATmega32u4 y el Atheros AR9331. El procesador
Atheros soporta una distribución Linux basada en OpenWrt llamada Linino OS. La placa lleva soporte Ethernet y
Wi-Fi incluido, un puerto USB-A, una ranura micro-SD, 20 pines de entrada/salida digitales (7 de ellos pueden ser
usados como salidas PWM y 12 de ellos como entradas analógicas), un oscilador a cristal de 16Mhz, un conector
micro-USB, un conector ICSP y tres botones de reset.
Ÿ https://store.arduino.cc/arduino-yun
Ÿ https://en.wikipedia.org/wiki/OpenWrt
Más información:
42 43
TIRA DE LEDS RGB
Es una tira de leds de colores. Cada uno de los leds de la tira se puede controlar de forma individual fijando la
intensidad de cada uno de los tres componentes de color. La tira usada es una tira NeoPixel. Los leds van unidos
en un registro de desplazamiento y se puede fijar el color de cada uno de los componentes de color (rojo, verde y
azul) de cada led con un PWM de 8 bits de precisión (por lo tanto 24 bits/pixel). Más información en Adafruit::
https://www.adafruit.com/product/1376?length=1
LECTOR DE TARJETAS RFID RMD6300 RFID Y TOKENS RFID
El mini módulo RDM6300 125KHz está diseñado para leer códigos de tarjetas compatibles a 125Khz. Tokens de
sólo lectura o tarjetas de lectura/escritura. Más información en Itead wiki:
https://www.itead.cc/wiki/RDM6300
ARDUINO YUN
Arduino Yun es una placa microcontrolada basada en el ATmega32u4 y el Atheros AR9331. El procesador
Atheros soporta una distribución Linux basada en OpenWrt llamada Linino OS. La placa lleva soporte Ethernet y
Wi-Fi incluido, un puerto USB-A, una ranura micro-SD, 20 pines de entrada/salida digitales (7 de ellos pueden ser
usados como salidas PWM y 12 de ellos como entradas analógicas), un oscilador a cristal de 16Mhz, un conector
micro-USB, un conector ICSP y tres botones de reset.
Ÿ https://store.arduino.cc/arduino-yun
Ÿ https://en.wikipedia.org/wiki/OpenWrt
Más información: