Julían Pérez Romero
info@julian-perez.com
Procesos avanzados:
multi-tarea, interruptores, temporizador, eeprom
Resistencias pull-down, pull-up
Comunicación serial, datalogger, módulo Bluetooth
Conexión con datos y servicios, Internet of things: nodeMCU, raspberry Pi
PWM
Analog / Digital
Servomotor / Motor DC
Comunicación serial
Firmata
¿?
¿Cómo gestionamos el tiempo en arduino?
Para comenzar está bien, pero conforme avanzamos hay que aprender otras formas de trabajar con el tiempo. El delay lo utilizaremos para ralentizar lecturas y evitar rebotes
¿Cómo gestionamos el tiempo en arduino?
variable unsigned long (de 0 a 4,294,967,295)
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);
}
unsigned long tiempo=0;
unsigned long tiempoLed=0;
int blink=500;
boolean estado=false;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
tiempo = millis();
if(tiempo >= (tiempoLed+blink)){
tiempoLed=tiempo;
estado = !estado;
digitalWrite(LED_BUILTIN,estado);
}
}
lineal :(
multi-tarea :)
ejemplo blink led
*síncrono
10 minutos
No vale con conectar un interruptor a un pin digital de entrada. Probémoslo
int val;
void setup() {
Serial.begin(9600);
pinMode(7,INPUT);
}
void loop() {
val=digitalRead(7);
if(val == HIGH){
Serial.println("1");
}else{
Serial.print("0");
}
}
Conectando un led lo veremos mejor
int val;
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
pinMode(7,INPUT);
}
void loop() {
val=digitalRead(7);
if(val == HIGH){
digitalWrite(13,HIGH);
Serial.println("1");
}else{
digitalWrite(13,LOW);
Serial.print("0");
}
}
¿Por qué ocurre esto? --> ENTRADA FLOTANTE
Las entradas flotantes en digital no da resultados fiables. Actúa de antena y recibe mucho ruido, pudiendo dar 0 y 1
Referencia de voltaje
El chip ATmega trae integradas resistencias de 20Kohm que podemos utilizar para definir los puertos como entradas con resistencia Pull-Up
Para ello tendremos que definirlo en el código: pinMode(7, INPUT_PULLUP);
int inputPin = 8;
void setup(){
Serial.begin(9600);
pinMode(inputPin, INPUT_PULLUP); //Cambiamos a INPUT
}
void loop(){
Serial.println(digitalRead(inputPin));
}
pull-down
pull-up
10 Kohm
20 minutos
Microcontrolador: ATmega 328p
Nos permite lanzar una serie de instrucciones independientemente de lo que esté pasando en el código principal
2 tipos de interrupciones en Arduino
Definimos una Interrupción:
Condiciones de disparo:
Sólo hay 2 pines que soportan las interrupciones externas que son INT0 e INT1, mapeados al pin 2 y al pin 3
Si necesitas más interrupciones externas --> Arduino MEGA o DUE
En el pin de reset también hay otra interrupción que sólo se dispara cuando detecta voltaje LOW y provoca el reinicio del microcontrolador
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
Ej.: attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
Arduino Reference (ver tabla): attachInterrupt()
Función para utilizar interrupciones
Cosas a tener en cuenta:
Hacemos un contador que vaya sumando en función de las veces que se pulse el botón. Mostramos el resultado por monitor serie
ó
Cambiamos el estado de encendido o apagado con cada pulsación
3 leds. 2 leds parpadean a tiempos diferentes, y el tercer led tiene que encenderse y apagarse con una interrupción externa mediante botón.
Utilizamos módulos que permitan una interrupción externa como por ejemplo:
...
Tiempo de escritura: 3.3ms
Tiempo de lectura: 3.3ms
NO PASA NADA
Existen módulos con memorias EEPROM externas
................................
0 1 2 3 4 5 6 7
1023
Dirección
1 Byte
=
8 bits
Por defecto todas las casillas vienen con valor 1 lógico ( o 255)
#include <EEPROM.h>
void setup() {
Serial.begin(9600);
Serial.print("Capacidad de memoria: ");
Serial.println( EEPROM.length() );
Serial.println(" ");
Serial.print("Valor almacenado en direccion 0: ");
Serial.println( EEPROM.read(0) );
Serial.print("Almacenando numero 39 en direccion 0");
EEPROM.write(0, 39);
}
void loop() {
}
Ejemplo 1
Autor código: Bitwise Ar
................................
0 1 2 3 4 5 6 7
1023
Dirección
1 Byte
=
8 bits
#include <EEPROM.h>
float temperatura = 27.50;
char cadena[] = "Hola esta es una prueba";
void setup() {
Serial.begin(9600);
EEPROM.put(0, temperatura);
EEPROM.put(10, cadena);
Serial.println("Valor de punto flotante en direccion 0:");
Serial.println( EEPROM.get(0, temperatura) );
Serial.println(" ");
Serial.println("Valor de la cadena en direccion 10:");
Serial.println( EEPROM.get(10, cadena) );
}
void loop() {
}
Ejemplo 2
Autor código: Bitwise Ar
TX -> 1
RX <- 0
Librería SoftwareSerial
Inter Integrated Circuit Bus
Inter Integrated Circuit Bus
Inter Integrated Circuit Bus
Código Arduino MASTER
#include <Wire.h>
#define SLAVE_ADDR 9 // Define Slave I2C Address
int analogPin = 0;
int val = 0;
void setup() {
Wire.begin(); //Al iniciar sin datos, arduino sabe que es el master
}
void loop() {
delay(50);
val = analogRead(analogPin)/4;
Wire.beginTransmission(SLAVE_ADDR); //Conectamos al Slave en su address
Wire.write(val); // Escribimos el valor mapeado
Wire.endTransmission(); //Cerramos comunicación
}
Código Arduino SLAVE
#include <Wire.h>
#define SLAVE_ADDR 9
int LED = 13;
int rd; // Variable para los datos recibidos
int br; // Variable para la freq del blink
void setup() {
pinMode(LED, OUTPUT);
Wire.begin(SLAVE_ADDR);
// Funcion que se ejecuta cuando recibe datos desde el Master
Wire.onReceive(receiveEvent);
Serial.begin(9600);
Serial.println("I2C Slave");
}
void receiveEvent() {
rd = Wire.read();
Serial.println(rd);
}
void loop() {
delay(50);
// Calculate blink value
br = map(rd, 1, 255, 100, 2000);
digitalWrite(LED, HIGH);
delay(br);
digitalWrite(LED, LOW);
delay(br);
}
Entramos en modo Configuración
Para entrar en el modo configuración, tenemos que dejar pulsado el botón del módulo con el pin vcc quitado, conectar el pin vcc y esperar 5s hasta que comience a parpadear. Si parpadea más lento que en el modo usuario sabremos que hemos entrado
Comandos AT que usaremos
*En el monitor serie indicamos "Ambos NL & RC" para ver correctamente los mensajes de vuelta del módulo
Conexión con App Bluetooth Serial Controller
Conexión entre 2 Arduinos
MASTER(1)
SLAVE(0)
Código MASTER
#include <SoftwareSerial.h>
SoftwareSerial miBT(10, 11);
int led1 = 13;
int stateLed = 0;
int potVal = 0;
void setup() {
pinMode(led1, OUTPUT);
digitalWrite(led1, LOW);
miBT.begin(38400);
}
void loop() {
if(miBT.available() > 0){ // Están entrando datos por el puerto serie?
stateLed = miBT.read(); // Lee los datos que están entrando: 0 ó 1
}
if (stateLed == '1') {
digitalWrite(led1, HIGH);
stateLed = 0;
}else if (stateLed == '0') {
digitalWrite(led1, LOW);
stateLed = 0;
}
potVal = analogRead(A0)/4;
miBT.write(potVal); // Enviamos valores al servo
delay(10);
}
Código SLAVE
#include <Servo.h>
#include <SoftwareSerial.h>
SoftwareSerial miBT(10, 11);
Servo myServo;
int button = 8;
int state = 20;
int buttonState = 0;
void setup() {
pinMode(button, INPUT);
myServo.attach(9);
miBT.begin(38400);
}
void loop() {
if(miBT.available() > 0){
state = miBT.read();
}
myServo.write(state);
delay(10);
buttonState = digitalRead(button);
if (buttonState == HIGH) {
miBT.write('1');
}
else {
miBT.write('0');
}
}
Versiones Módulo ESP
Versiones Kit NodeMCU
Fuente Imagen: programarfacil.com
Fuente Imagen: programarfacil.com
Fuente Imagen: programarfacil.com
PINOUT
Pines digitales
La referencia en el Arduino IDE corresponde al valor GPIO
Fuente Imagen: programarfacil.com
LEDS
Importante! Para encender leds mandar estado LOW o 0 y viceversa
Drivers USB
Probar sin instalar driver, por si acaso nuestro pc lo tiene instalado ya
Placa NodeMCU en Arduino IDE
https://arduino.esp8266.com/stable/package_esp8266com_index.json
Preferencias > pegar link en campo "Gestor de URLs adicionales de tarjetas", Ok
info@julian-perez.com
twitter: @largocreatura