Electronario II

ELECTRÓNICA BÁSICA PARA LA ENSEÑANZA EN DISEÑO

Julían Pérez Romero

info@julian-perez.com

Escuela Superior de Diseño de Madrid

27-31 Enero 2019

Resumen Curso

  • 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

Breve repaso

PWM

Analog / Digital

Servomotor / Motor DC

Comunicación serial

Firmata

¿?

Pad con anotaciones

DÍA1

  • Tiempo: delay() vs millis()
  • Entrada digital: pull-up/-down

Nuevos métodos de trabajo con Arduino

delay(1000)

¿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?

millis()

  • Devuelve número en milisegundos desde que arranca el programa
  • Puede durar hasta casi 50 días (y vuelve a cero)
  • variable unsigned long (de 0 a 4,294,967,295)

delay()        VS       millis()

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

Ejercicio millis()

blink de un segundo LED parpadeando al doble de velocidad del primer LED

10 minutos

Ejercicio millis()

Diferentes tiempos de encendido y apagado que no se podrían conseguir con delay().

Ejercicio millis()

Entrada digital

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

Entrada digital

¿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

Entrada digital

¿Cómo podemos hacer que funcione bien?

Circuito pull-up / pull-down

Entrada digital: circuito pull-up / pull-down

Referencia de voltaje

Entrada digital: circuito pull-up / pull-down

Entrada digital: circuito pull-up / pull-down

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

INPUT_PULLUP

Entrada digital: circuito pull-up / pull-down

int inputPin = 8;

void setup(){
  Serial.begin(9600);
  pinMode(inputPin, INPUT_PULLUP); //Cambiamos a INPUT
}

void loop(){
  Serial.println(digitalRead(inputPin));
}

INPUT_PULLUP

Entrada digital: circuito pull-up / pull-down

pull-down

pull-up

10 Kohm

Entrada digital: circuito pull-up / pull-down

Ejercicio pull-up/pull-down

Programamos arduino en función de cada circuito

20 minutos

DÍA2

  • Interrupciones externas (ISR)
  • Memoria EEPROM

Nuevos métodos de trabajo con Arduino

Interrupciones

ISR (Interruption Service Rutine)

Interrupciones

Microcontrolador: ATmega 328p

Interrupciones

  • Para qué sirven? para tener una atención inmediata de una entrada. Por ejemplo, un mando de juego, una colisión, etc.
     
  • Con el sistema pullup puede que el tiempo que tarda hasta que el programa llega para leer la entrada sea inaceptable..
     
  • ..y si el pulso es muy corto, o si el procesador está ocupado haciendo otra tarea mientras se produce, es posible que nos saltemos el disparo y nunca lleguemos a verlo.
     
  • Nos permite lanzar una serie de instrucciones independientemente de lo que esté pasando en el código principal

 

Tipos de Interrupciones

  • Interrupciones HW o externas: se pueden producir en cualquier momento independientemente de lo que esté haciendo el MCU en ese momento. Las causas que las producen son externas al procesador y a menudo suelen estar ligadas con los distintos dispositivos de entrada o salida.
     
  • Interrupciones SW: Arduino no soporta las interrupciones por software
     
  • Timer (interno). Son las interrupciones asociadas a los timers y gracias a ellas funciona millis().
     
  • Excepciones: Normalmente son causadas al realizarse operaciones no permitidas tales como la división entre 0, el desbordamiento, el acceso a una posición de memoria no permitida, etc.

Interrupciones en Arduino

2 tipos de interrupciones en Arduino

  • Externas
  • Cambio de pin

Interrupciones externas en Arduino

Definimos una Interrupción:

  • Pin que recibe la señal de disparo
     
  • Condición de disparo
     
  • Función que se ejecuta cuando recibe el disparo (callback function)

Condiciones de disparo:

  • LOW, La interrupción se dispara cuando el pin es LOW
     
  • CHANGE, Se dispara cuando pase de HIGH a LOW o viceversa
     
  • RISING, Dispara en el flanco de subida (Cuando pasa de LOW a HIGH)
     
  • FALLING, Dispara en el flanco de bajada (Cuando pasa de HIGH a LOW)
     
  • *solo para Arduino DUE: HIGH se dispara cuando el pin esta HIGH.

 

Interrupciones externas en Arduino

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

Interrupciones externas en Arduino

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)

Interrupciones externas en Arduino

Ej.: attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);

Arduino Reference (ver tabla): attachInterrupt()

Función para utilizar interrupciones

Interrupciones externas en Arduino

  • Las variables que se vayan a utilizar dentro y fuera de la ISR se tienen que declarar como "volatile"
     
  • No se pueden recibir ni devolver parámetros
     
  • delay() y millis() no se recomiendan dentro de una ISR ya que dependen de otras interrupciones. Serial también, va muy lenta.
     
  • no pueden funcionar varias ISRs a la vez, van una detrás de otra y hay una tabla de prioridad de ISRs
     
  • Una ISR tiene que ser tan corta y rápida como sea posible, entrar y salir

Cosas a tener en cuenta:

Interrupciones externas en Arduino

Ejercicio interruptor

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

Interrupciones externas en Arduino

Ejercicio Multitasking

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.

Interrupciones externas en Arduino

Ejercicio Interrupción

Utilizamos módulos que permitan una interrupción externa como por ejemplo:

  • FotoInterruptor
  • Sensor de llama
  • Sensor de sonido
  • Sensor de inclinación (tilt)
  • Sensor Efecto Hall (imán)
  • Sensor de Knock-knock

...

Memoria EEPROM

Electrically Erasable Programmable Read Only Memory

Memoria EEPROM

Qué tipos de memoria tenemos en Arduino?

  • FLASH, no volátil, donde grabamos el sketch (incluido el bootloader)
     
  • SRAM (static random access memory), volátil, donde se almacenan las variables durante el funcionamiento
     
  • EEPROM, no volátil, que podemos usar para almacenar información entre reinicios.

Memoria EEPROM

Características EEPROM

  • Mantiene los valores almacenados cuando se pierde la alimentación
     
  • Arduino UNO: 1KB. MEGA: 4KB. Poca memoria
     
  • Tiene una vida limitada de escritura: 100.000 cada celda. En realidad 100.000 es lo garantizado por fabricante pero se puede hasta casi 1 millón. Las lecturas son ilimitadas
     
  • Está pensada para realizar escrituras con tiempos largos entre ellas, no un uso constante de la misma

Memoria EEPROM

Tiempos de uso EEPROM

  • Apenas 5 minutos si, por error, grabamos constantemente
     
  • Aproximadamente un día, si grabamos cada segundo
     
  • Unos 27 años si grabamos 10 veces al día

Tiempo de escritura: 3.3ms

Tiempo de lectura: 3.3ms

Memoria EEPROM

Qué pasa si agotamos la vida útil de la EEPROM de nuestro Arduino?

NO PASA NADA

Existen módulos con memorias EEPROM externas

Memoria EEPROM

Algunos ejemplos de la memoria EEPROM

  • Guardar una contraseña personalizada
     
  • Grabar una secuencia de valores corta en el tiempo
     
  • Lista HighScores en un videojuego arcade
     
  • Salvar una serie de configuraciones específicas, por ejemplo una alarma de reloj
     
  • Etc..

Memoria EEPROM

................................

0 1 2 3 4 5 6 7

1023

Dirección

1 Byte

=

8 bits

  • 0 - 255 valores (decimal)
  • 00 - FF (hexadecimal)
  • 00000000 - 11111111 (binario)

Por defecto todas las casillas vienen con valor 1 lógico ( o 255)

Memoria EEPROM

Memoria EEPROM

  • EEPROM.length() --> Tamaño en bytes de nuestra memoria
  • EEPROM.read(dirección) --> lee el valor de la celda (dirección)
  • EEPROM.write(dirección, valor) --> escribe el valor en la celda

Memoria EEPROM

#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

Memoria EEPROM

Memoria EEPROM

................................

0 1 2 3 4 5 6 7

1023

Dirección

1 Byte

=

8 bits

  • int: 2 bytes - 16bits (-32,768 a 32,767)
  • float: 4 bytes - 32bits (3.4028235E+38 a -3.4028235E+38)
  • char [n]: n bytes (cadena de caracteres)

Memoria EEPROM

  • EEPROM.get(dirección de inicio, valor) --> Leer
  • EEPROM.put(dirección de inicio, valor) --> Escribir

Memoria EEPROM

#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

Memoria EEPROM

  • EEPROM.update(dirección de inicio, valor) --> Actualiza. Si la celda tiene el mismo valor no sobreescribe

Memoria EEPROM

Ejercicio EEPROM

  • Con un potenciómetro movemos un servo
     
  • los valores de movimiento los guardamos en la eeprom para hacer un playback después de que usemos todas las direcciones de la memoria
     
  • Importante: hacerlo todo dentro del void setup

DÍA3

  • Comunicación Puerto Serie
  • Comunicación I2C
  • Módulo Bluetooth HC-05

Conectividad entre arduinos

Comunicación Puerto Serie

TX -> 1

RX <- 0

Comunicación Serial

Librería SoftwareSerial

Comunicación I2C

  • Es un protocolo serial para una comunicación de baja velocidad con una interfaz de dos conexiones
     
  • Se desarrolló mayormente en la industria de los televirores pero la podemos encontrar en la mayoría de MCUs. Phillips 1982
     
  • Pequeñas distancias: 1 metro a 1Kbaudio de velocidad
     
  •  Los módulos que trabajan con i2c suelen tener 4 pines: VCC, GND, SCL, SDA

 

Inter Integrated Circuit Bus

Comunicación I2C

Inter Integrated Circuit Bus

Comunicación I2C

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
}

Comunicación I2C

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

Módulo HC-05 Bluetooth

Módulo HC-05 Bluetooth

  • Comunicación de radiofrequencia en una banda de 2.4Ghz de corto alcance (5 a 10 mts.)
  • La comunicación funciona a 38400 Baudios (bps)
  • Bajo consumo
  • Nos comunicamos a través de él serialmente
  • Master/Slave
  • Modo Configuración / Usuario
  • Comandos AT (Hayes)
  • Pin Layout

Módulo HC-05 Bluetooth

Módulo HC-05 Bluetooth

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

Módulo HC-05 Bluetooth

Comandos AT que usaremos

*En el monitor serie indicamos "Ambos NL & RC" para ver correctamente los mensajes de vuelta del módulo

  • AT --> OK (Este es el hello world, con esto sabemos que la conexión está establecida entre arduino y el módulo)
  • AT+NAME? --> Preguntamos el nombre que tiene fijado
  • AT+NAME=MiBluetooth --> Asignamos un nombre al módulo
     
  • AT+PSWD --> Contraseña
  • AT+UART -->Velocidad de transmisión
  • AT+ROLE --> Maestro=1, Esclavo=0
  • AT+ORGL --> Restaura a valores de fábrica
  • AT+RESET --> Sale del modo configuración y pasa al modo Usuario
  • AT+ADDR --> Dirección única de nuestro módulo
  • AT+CMODE=0 --> Conexión fija a una dirección
  • AT+BIND=address(con comas) --> Conexión a una dirección que le indiquemos
     

Módulo HC-05 Bluetooth

Conexión con App Bluetooth Serial Controller

  • Instalamos la app desde el Play Store
  • Vinculamos dispositivos a través de bluetooth. Debe aparecer el nombre que le hayamos indicado previamente
  • Ajustamos parámetros: Name, Command, Repeatable para cada botón

Módulo HC-05 Bluetooth

Ejercicio1: configuramos la interfaz de la app para enviar on/off a un par de leds

 

Ejercicio2: el segundo led controlamos PWM para subir o bajar el brillo

Módulo HC-05 Bluetooth

Conexión entre 2 Arduinos

MASTER(1)

SLAVE(0)

Módulo HC-05 Bluetooth

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

Módulo HC-05 Bluetooth

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

DÍA4

  • NodeMCU v3
  • Adafruit.io+IFTTT

Internet of Things

NodeMCU v3

Placa de desarrollo sobre ESP

Versiones Módulo ESP

Versiones Kit NodeMCU

Fuente Imagen: programarfacil.com

NodeMCU

NodeMCU

  • 32bits
  • 80-160MHz
  • wifi 2.4GHz
  • RAM 50KB
  • 1ADC
  • 17GPIO
  • acceso fácil
  • Antena
  • Led
  • Prototipado
  • Conversor USB-Serie
  • Acceso pines
  • 3 pines 3,3V
  • 1 pin 5V
  • 4 pin GND
  • Leds de estado
  • Botón reset y flash

Fuente Imagen: programarfacil.com

NodeMCU

Fuente Imagen: programarfacil.com

NodeMCU

PINOUT

Pines digitales

La referencia en el Arduino IDE corresponde al valor GPIO

Fuente Imagen: programarfacil.com

NodeMCU

LEDS

  • Led módulo ESP8266 > D4 = GPIO 2
  • Led Kit NodeMCU > D9= GPIO16

Importante! Para encender leds mandar estado LOW o 0 y viceversa

NodeMCU

Drivers USB

  • CP1202 (es el más utilizado en la versión v0.9/V1)
  • CH340 (el más común en la versión v1.0/V2)
  • FT232RL (es el más raro de ver pero hay algunas placas que lo llevan)

Probar sin instalar driver, por si acaso nuestro pc lo tiene instalado ya

NodeMCU

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

NodeMCU

  • Prueba 1: hello world

  • Prueba 2: encendemos led desde un navegador

NodeMCU

  • Creamos una cuenta
  • Creamos un "feed"

NodeMCU

  • Creamos una cuenta
  • Creamos un "feed" (p.ej.: command)
  • Ajustamos parámetros del código

NodeMCU

  • Creamos una cuenta
  • Conectamos servicios que queramos usar
  • Creamos una receta conectando con applet Adafruit.io

Conclusiones

  • Qué os ha parecido el curso?
  • Habéis echado algo en falta?
  • Con qué cosas os habéis quedado que podáis poner en práctica con vuestros alumnos?
  • Alguna idea de proyecto personal o colectivo?

Gracias!!

info@julian-perez.com

twitter: @largocreatura

Made with Slides.com