Bus IC2 - Aprendiendo Arduino
Bus IC2 - Aprendiendo Arduino
Anuncios
REPORT THIS AD
Aprendiendo Arduino
Aprendiendo a manejar Arduino en profundidad
Bus I2C/TWI
Al comenzar a usar Arduino puede resultar algo complejo entender las diferencias entre los diferentes tipos de
interfaces de comunicación (y protocolos asociados).
UART (recepción-transmisión asíncrona universal) es uno de los protocolos serie más utilizados. La mayoría
de los microcontroladores disponen de hardware UART. Usa una línea de datos simple para transmitir y
otra para recibir datos. Comúnmente, 8 bits de datos son transmitidos de la siguiente forma: un bit de
inicio, a nivel bajo, 8 bits de datos y un bit de parada a nivel alto. UART se diferencia de SPI y I2C en que es
asíncrono y los otros están sincronizados con señal de reloj. La velocidad de datos UART está limitado a
2Mbps
SPI es otro protocolo serie muy simple. Un maestro envía la señal de reloj, y tras cada pulso de reloj envía
un bit al esclavo y recibe un bit de éste. Los nombres de las señales son por tanto SCK para el reloj, MOSI
para el Maestro Out Esclavo In, y MISO para Maestro In Esclavo Out. Para controlar más de un esclavo es
preciso utilizar SS (selección de esclavo).
I2C es un protocolo síncrono. I2C usa solo 2 cables, uno para el reloj (SCL) y otro para el dato (SDA). Esto
signi ca que el maestro y el esclavo envían datos por el mismo cable, el cual es controlado por el maestro,
que crea la señal de reloj. I2C no utiliza selección de esclavo, sino direccionamiento.
http://electronics.stackexchange.com/questions/37814/usart-uart-rs232-usb-spi-i2c-ttl-etc-what-are-all-of-
these-and-how-do-th
http://geekenformacion.blogspot.com.es/2013/01/interfaces-de-comunicacion-spi-i2c-uart.html
https://aprendiendoarduino.wordpress.com/2016/11/14/ 1/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
es de 100 kbit/s en el modo estándar, aunque también permite velocidades de 3.4 Mbit/s. Es un bus muy usado
en la industria, principalmente para comunicar microcontroladores y sus periféricos en sistemas integrados
(Embedded Systems) y generalizando más para comunicar circuitos integrados entre si que normalmente residen
en un mismo circuito impreso.
La principal característica de I²C es que utiliza dos líneas para transmitir la información: una para los datos y otra
para la señal de reloj. También es necesaria una tercera línea, pero esta sólo es la referencia (masa). Como
suelen comunicarse circuitos en una misma placa que comparten una misma masa esta tercera línea no suele
ser necesaria.
SDA: datos
SCL: reloj
GND: tierra
Las dos primeras líneas son drenador abierto, por lo que necesitan resistencias de pull-up. Dos o más señales a
través del mismo cable pueden causar con icto, y ocurrirían problemas si un dispositivo envía un 1 lógico al
mismo tiempo que otro envía un 0. Por tanto el bus es “cableado” con dos resistencia para poner el bus a nivel
alto, y los dispositivos envían niveles bajos. Si quieren enviar un nivel alto simplemente lo comunican al bus.
Más información:
http://www.prometec.net/bus-i2c/
http://www.electroensaimada.com/i2c.html
http://www.luisllamas.es/2016/05/arduino-i2c/
http://www.slideshare.net/FabioSierra1/bus-i2-c-de-arduino
https://learn.sparkfun.com/tutorials/i2c
http://www.ehu.eus/micros-virtual/unidad21/
http://robots-argentina.com.ar/Comunicacion_busI2C.htm
http://www.i2c-bus.org/
http://es.wikipedia.org/wiki/I%C2%B2C
Y mucha más información en: http://en.wikipedia.org/wiki/I%C2%B2C donde se explica la capa física más
profundamente.
Los dispositivos conectados al bus I2C tienen una dirección única para cada uno. También pueden ser maestros
o esclavos. El dispositivo maestro inicia la transferencia de datos y además genera la señal de reloj, pero no es
necesario que el maestro sea siempre el mismo dispositivo, esta característica se la pueden ir pasando los
dispositivos que tengan esa capacidad. Esta característica hace que al bus I2C se le denomine bus multimaestro.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 2/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Vdd
Rp
SDA
SCL
μC ADC DAC μC
Master Slave Slave Slave
Las líneas SDA y SCL son del tipo drenaje abierto, es decir, un estado similar al de colector abierto, pero
asociadas a un transistor de efecto de campo (o FET). Se deben polarizar en estado alto (conectando a la
alimentación por medio de resistores “pull-up”) lo que de ne una estructura de bus que permite conectar en
paralelo múltiples entradas y salidas.
Fijaros también que hay unas resistencias de Pullup conectadas a SDA y SCL. Son imperativas, ya que el bus es
activo bajo (Esto es, la señal activa es un 0, no un 1). Cuando vayas a conectar algo al bus I2C, es imprescindible
que leas el manual para saber si los pullups los tienes que poner tú, o vienen puestos en el componente.
Puede haber más de un master. La norma propone un sistema de arbitraje, para transferir el control de uno a
otro, pero en un instante dado, sólo uno puede ser el master.
El maestro comienza la comunicación enviando un patrón llamado “start condition”. Esto alerta a los
dispositivos esclavos, poniéndolos a la espera de una transacción.
El maestro se dirige al dispositivo con el que quiere hablar, enviando un byte que contiene los siete bits
(A7-A1) que componen la dirección del dispositivo esclavo con el que se quiere comunicar, y el octavo bit
(A0) de menor peso se corresponde con la operación deseada (L/E), lectura=1 (recibir del esclavo) y
escritura=0 (enviar al esclavo).
La dirección enviada es comparada por cada esclavo del bus con su propia dirección, si ambas coinciden, el
esclavo se considera direccionado como esclavo-transmisor o esclavo-receptor dependiendo del bit R/W.
Cada byte leído/escrito por el maestro debe ser obligatoriamente reconocido por un bit de ACK por el
dispositivo maestro/esclavo.
Cuando la comunicación naliza, el maestro transmite una “stop condition” para dejar libre el bus.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 3/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
https://aprendiendoarduino.wordpress.com/2016/11/14/ 4/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Cuando los datos son enviados por SDA, los pulsos de reloj son enviados por SCL para mantener el maestro y el
esclavo sincronizados. Puesto que los datos son enviados como un bit en cada pulso de reloj, la transferencia de
datos es un octavo la frecuencia de reloj. La frecuencia del reloj estándar originalmente se puso a 100 KHz y la
mayoría de los integrados y microcontroladores soportan esta velocidad. En posteriores actualizaciones, se
introdujo una fast speed de 400 KHz y una high speed de 1.7 a 3.4 MHz. Arduino puede soportar la velocidad
estándar y fast speed, BeagleBoard tiene tres buses I2C cada uno a una velocidad distinta y tanto BeagleBoard
como Raspberry Pi soportan velocidad estándar y fast speed. Fast speed corresponde a una velocidad de
transferencia de 50Kbytes/sec lo que puede ser una velocidad muy baja para algunas aplicaciones de control.
Una opción en ese caso es usar SPI en lugar de I2C.
I2C también se conoce como TWI (Two Wire Interface) y no dispone de un conector estandarizado. Únicamente
por motivos de licencia se le denomina TWI, no obstante, la patente caducó en 2006, por lo que actualmente no
hay restricción sobre el uso del término I2C.
I2C no tiene limitaciones de velocidad, el maestro genera la velocidad de reloj y I2C provee de un mecanismo que
si el esclavo es más lento es capaz de ponerse el maestro en modo de espera.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 5/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
SMBus (Bus de Administración del Sistema) es un subconjunto del protocolo I2C de nido por Intel en 1995.
Todas las placas bases modernas tienen un bus SMBus al que se conectan la mayor parte de los chips de
monitorización del sistema. Estos chips sirven para medir temperaturas de componentes, velocidad de
ventiladores, voltajes, etc. Toda clase de información sobre hardware.
Direccionamiento I2C
En principio, el número de dispositivos que se puede conectar al bus no tiene límites, aunque hay que observar
que la capacidad máxima sumada de todos los dispositivos no supere los 400 pF. El valor de los resistores de
polarización no es muy crítico, y puede ir desde 1K8 (1.800 ohms) a 47K (47.000 ohms). Un valor menor de
resistencia incrementa el consumo de los integrados pero disminuye la sensibilidad al ruido y mejora el tiempo
de los ancos de subida y bajada de las señales. Los valores más comunes en uso son entre 1K8 y 10K.
Lo más común en los dispositivos para el bus I2C es que utilicen direcciones de 7 bits, aunque existen
dispositivos de 10 bits. Este último caso es raro. Una dirección de 7 bits implica que se pueden poner hasta 128
dispositivos sobre un bus I2C, ya que un número de 7 bits puede ir desde 0 a 127. Cuando se envían las
direcciones de 7 bit, de cualquier modo la transmisión es de 8 bits. El bit extra se utiliza para informarle al
dispositivo esclavo si el dispositivo maestro va a escribir o va a leer datos desde él. Si el bit de lectura/escritura
(R/W) es cero, el dispositivo maestro está escribiendo en el esclavo. Si el bit es 1 el maestro está leyendo desde el
esclavo. La dirección de 7 bit se coloca en los 7 bits más signi cativos del byte y el bit de lectura/escritura es el bit
menos signi cativo.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 6/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Cada fabricante usa su propio direcionamiento para los esclavos, por ejemplo Philips:
http://www.diolan.com/downloads/i2c-address-allocation-table.pdf
I2C en Arduino
Arduino dispone de soporte I2C por hardware vinculado físicamente a ciertos pines. También es posible emplear
cualquier otro grupo de pines como bus I2C a través de software, pero en ese caso la velocidad será mucho
menor.
Los pines a los que está asociado varían de un modelo a otro. La siguiente tabla muestra la disposición en alguno
de los principales modelos. Para otros modelos, consultar el esquema de patillaje correspondiente.
Uno A4 A5
Nano A4 A5
Mini Pro A4 A5
Mega 20 21
Para usar el bus I2C en Arduino, el IDE Standard proporciona la librería “Wire.h”, que contiene las funciones
necesarias para controlar el hardware integrado.
Existen otras librerías más avanzadas que Wire.h para manejar el bus I2C, como por ejemplo I2Cdevlib o I2C
library.
Simple, yet Powerful and Flexible Communication Interface, only two Bus Lines Needed
Both Master and Slave Operation Supported
Device can Operate as Transmitter or Receiver
https://aprendiendoarduino.wordpress.com/2016/11/14/ 7/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
TWCR Two Wire Control Register Controls the actions of the TWI module
TWSR Two Wire Status Register Reports the status of the TWI actions
TWDR Two Wire Data/Address Register Contains the data you want to transmit or have received
TWBR Two Wire Bit Rate Register Controls the frequency of the clock (SCL)
https://aprendiendoarduino.wordpress.com/2016/11/14/ 8/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Esta librería permite comunicar con I2C/TWI Arduino con otros dispositivos. En las placas Arduino con el diseño
R3 (1.0 pinout), la SDA (línea de datos) y SCL (línea de reloj) están en los pines cerca del pin AREF.
El Arduino Due tiene dos interfaces I2C / TWI SDA1 y SCL1 que están cerca del pin AREF y los adicionales en los
pines 20 y 21.
Funciones:
https://www.arduino.cc/en/Reference/Wire
http://playground.arduino.cc/Main/WireLibraryDetailedReference
http://playground.arduino.cc/Code/ATMELTWI
https://aprendiendoarduino.wordpress.com/2016/11/14/ 9/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Aplicaciones I2C
Podríamos usar el bus I2C para comunicar Raspberry Pi con Arduino y otros dispositivos:
https://github.com/quick2wire/quick2wire-python-api
http://elinux.org/Interfacing_with_I2C_Devices
http://www.acmesystems.it/i2c
También disponemos de controladores I2C en caso de no tener disponibles puertos I2C en el microcontrolador:
http://www.nxp.com/documents/application_note/AN10148.pdf que reciben datos en formato pararlelo, lo
pasana serie y lo mandan a un bus I2C y en sentido contrario.
Otro ejemplo de aplicación I2C es este shield que maneja 8 relés usando dos pines I2C e incluso se pueden apilar
para manejar, 16 o 24 relés en el mismo bus I2C:
http://www.freetronics.com.au/products/relay8-8-channel-relay-driver-shield#.WBi_di3hDcs
Esquemático: https://github.com/freetronics/RelayDriverShield8/blob/master/RelayDriverShield8.pdf?
raw=true
Quickstart guide: http://www.freetronics.com.au/pages/relay8-8-channel-relay-driver-shield-quickstart-
guide#.WBjAfC3hDcs
https://aprendiendoarduino.wordpress.com/2016/11/14/ 10/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Como ejemplo curioso de I2C el Wii Remote (conocido como Wiimote) es el dispositivo de entrada principal de
Wii. Es un dispositivo inalámbrico que utiliza la tecnología Bluetooth estándar para comunicarse con la Wii. Está
construido alrededor de un Broadcom BCM2042 bluetooth System-on-a-chip, y contiene múltiples periféricos
que le proporcionan datos, así como un puerto de expansión para complementos externos.
El mando Wii incluye un puerto de expansión de 6 pines que permite conectar periféricos externos. Las
comunicaciones son I2C síncronas bidireccionales y los dispositivos proporcionan un bloque de registro virtual
de longitud 0x100 que está mapeado en 0xa40000 en el espacio de direcciones del Wii Remote (La dirección I2C
de 7 bits es 0x52).
https://aprendiendoarduino.wordpress.com/2016/11/14/ 11/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
http://wiibrew.org/wiki/Wiimote
http://wiibrew.org/wiki/Wiimote/Extension_Controllers
Escaner I2C
Cada componente que conectamos al bus I2C tiene una dirección única, y cada mensaje y orden que
transmitimos al bus, lleva anexa esta dirección, indicando cuál de los muchos posibles, es el receptor del
mensaje.
Esto implica que sabemos la dirección del componente. Lo normal es comprobar la información técnica del
fabricante del componente, y ahí suele decirnos cuál es la dirección por defecto. Pero es posible que tengamos
un dispositivo sin documentación, para ello hay un programa para Arduino, que nos informa, de lo que hay en
nuestro bus y con qué dirección.
Este programa, no tiene ni idea de quien responde y lo que hace, pero bastante es que nos informe de que hay
alguien en la dirección xx. Si no sabemos en qué dirección está un componente dado, basta con colocarlo solo en
el bus, y ver qué dirección nos reporta el I2C scanner.
En algunas ocasiones, sobre todo al comprar en vendedores chinos, el fabricante no nos facilita la dirección del
dispositivo o incluso lo proporciona de forma incorrecta. Esta es una circunstancia común y nada preocupante.
Para eso disponemos de un sketch llamado “Scanner I2C” que realiza un barrido por todas las posibles
direcciones del bus, y muestra el resultado en caso de encontrar un dispositivo en la dirección.El sketch scanner
I2C está disponible en este enlace, o podéis usar la siguiente versión reducida y traducida.
Ver http://playground.arduino.cc/Main/I2cScanner
1 #include "Wire.h"
2 extern "C" {
3 #include "utility/twi.h"
4 }
5 void scanI2CBus(byte from_addr, byte to_addr, void(*callback)(byte address, byte result)
6 {
7 byte rc;
8 byte data = 0;
https://aprendiendoarduino.wordpress.com/2016/11/14/ 12/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
9 for( byte addr = from_addr; addr <= to_addr; addr++ ) {
10 rc = twi_writeTo(addr, &data, 0, 1, 0);
11 callback( addr, rc );
12 }
13 }
14 void scanFunc( byte addr, byte result ) {
15 Serial.print("addr: ");
16 Serial.print(addr,DEC);
17 Serial.print( (result==0) ? " Encontrado!":" ");
18 Serial.print( (addr%4) ? "\t":"\n");
19 }
20
21
22 const byte start_address = 8;
23 const byte end_address = 119;
24
25 void setup()
26 {
27 Wire.begin();
28 Serial.begin(9600);
29 Serial.print("Escaneando bus I2C...");
30 scanI2CBus( start_address, end_address, scanFunc );
31 Serial.println("\nTerminado");
32 }
33
34 void loop()
35 {
36 delay(1000);
37 }
http://arduino.cc/en/Tutorial/MasterWriter
http://arduino.cc/en/Tutorial/MasterReader
http://arduino.cc/en/Tutorial/DigitalPotentiometer
http://www.electroensaimada.com/i2c.html
http://programarfacil.com/blog/conectar-dos-arduinos-i2c/
https://aprendiendoarduino.wordpress.com/2016/11/14/ 13/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Solución: https://github.com/jecrespo/Aprendiendo-Arduino/tree/master/Ejercicio33-I2C
Dispositivos I2C
En el mercado hay multitud de sensores y dispositivos I2C para utilizar con Arduino, veamos alguno de los más
importantes.
Para escribir en el dispositivo I2C las tramas serían las indicadas en el grá co siguiente.
Tras la condición de Start iniciada por el microcontrolador se envía el primer byte conteniendo la dirección del
dispositivo I2C con el que se quiere comunicar y en el último bit aparece el 0 indicando que se va a escribir, la
información pasa del microcontrolador al dispositivo I2C.
Le sigue a esta trama el bit de acknowledgement generado por el esclavo para con rmar la correcta recepción de
byte anterior. El byte siguiente se re ere a la dirección o registro del dispositivo I2C donde se quiere escribir o
enviar el dato desde el microcontrolador.
A partir del tercer byte, se envían los datos de forma sucesiva, y es el dispositivo I2C el que va
autoincrementando la dirección de memoria donde se guarda el dato recibido.Se naliza la comunicación con el
bit de parada.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 14/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Inicia el dispositivo master la comunicación a través del bit de Start. Después viene la dirección del esclavo al que
se dirige, indicando que va realizar la lectura del mismo (bit R/W=1). En este caso, el dispositivo I2C también va
realizando un autoincremento del registro a leer.
http://www.seeedstudio.com/depot/s/i2c.html?search_in_description=0
https://www.sparkfun.com/search/results?term=i2c
http://www.electan.com/advanced_search_result.php?keywords=i2c&osCsid=4l26edd9i9lisn84sk51l0doq2
Cabe destacar: módulos GPS, RTC (Real Time Clock), IMU (Inertial Measurement Unit), Display grá co, EEPROM,
Sensores de temperatura y humedad, sensor de presión, distancia, driver motor, etc…
I2C al tratarse de una comunicación serie también puede convertirse a otros protocolos serie.
http://www.ftdichip.com/Products/ICs/FT201X.html
http://www.acroname.com/products/R286-USB-I2C.html
https://aprendiendoarduino.wordpress.com/2016/11/14/ 15/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Este circuito utiliza el integrado convertidor de USB a Serie de la casa FTDI por lo que hay disponibles
controladores tanto para Windows como para Apple y Linux. Una vez instalado el driver el circuito aparece en el
ordenador como un puerto serie más, por lo que todo lo que hace falta para poder controlar dispositivos I2C es
mandar las órdenes directamente al puerto serie y el circuito se encarga de traspasarlas directamente al bus I2C.
http://www.superrobotica.com/s310425.htm
http://www.robot-electronics.co.uk/htm/usb_i2c_tech.htm
Colección de librerías para usar dispositivos I2C con Arduino: http://www.i2cdevlib.com/ y los dispositivos:
http://www.i2cdevlib.com/devices
Si queremos saber los dispositivos que hay conectados en un bus I2C con las direcciones de cada uno de ellos y
mostrarlo por consola disponemos de este código: I2C scanner http://playground.arduino.cc/Main/I2cScanner
https://aprendiendoarduino.wordpress.com/2016/11/14/ 16/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Una IMU es un dispositivo capaz de medir la fuerza (aceleración) y la velocidad. Generalmente consta de un
Acelerómetro y un Giroscopio. Por lo tanto una IMU no mide ángulos, por lo menos no directamente, requiere
algunos cálculos.
Un dispositivo I2C muy interesante es el MPU-6050 que nos sirve para probar e introducirnos en el mundo de los
giroscopios y acelerómetros.
https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/
datasheet: https://www.cdiweb.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf
De niciones:
https://en.wikipedia.org/wiki/Inertial_measurement_unit
https://es.wikipedia.org/wiki/Unidad_de_medici%C3%B3n_inercial
El MPU-6050 es una IMU de 6DOF (se lee “6 Degrees Of Freedom“ o 6 grados de libertad). Esto signi ca que lleva
un acelerómetro y un giroscopio, ambos de 3 ejes (3+3 = 6DOF). Hay IMUs de 9DOF, en ese caso también llevan
un magnetómetro. Otras pueden tener 5DOF, en cuyo caso el giroscopio sólo mide dos ejes, etc.
El MPU-6050 opera con 3.3 voltios, aunque algunas versiones llevan un regulador que permite conectarla a 5V. El
MPU-6050 utiliza el protocolo de comunicación I2C.
El acelerómetro mide la aceleración. La aceleración puede expresarse en 3 ejes: X, Y y Z, las tres dimensiones
del espacio. Por ejemplo, si mueves la IMU hacia arriba, el eje Z marcará un cierto valor. Si es hacia delante,
marcará el eje X, etc. La gravedad de la Tierra tiene una aceleración de aprox. 9.8 m/s², perpendicular al suelo
como es lógico. Así pues, la IMU también detecta la aceleración de la gravedad terrestre. Gracias a la gravedad
terrestre se pueden usar las lecturas del acelerómetro para saber cuál es el ángulo de inclinación respecto al eje
X o eje Y.
Supongamos que la IMU esté perfectamente alineada con el suelo. Entonces, como puedes ver en la imagen, el
eje Z marcará 9.8, y los otros dos ejes marcarán 0. Ahora supongamos que giramos la IMU 90 grados. Ahora es el
eje X el que está perpendicular al suelo, por lo tanto marcará la aceleración de la gravedad.
Si sabemos que la gravedad es 9.8 m/s², y sabemos qué medida dan los tres ejes del acelerómetro, por
trigonometría es posible calcular el ángulo de inclinación de la IMU. Una buena fórmula para calcular el ángulo
es:
https://aprendiendoarduino.wordpress.com/2016/11/14/ 17/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Dado que el ángulo se calcula a partir de la gravedad, no es posible calcular el ángulo Z (giro sobre si mismo) con
esta fórmula ni con ninguna otra. Para hacerlo se necesita otro componente: el magnetómetro, que es un tipo de
brújula digital. El MPU-6050 no lleva, y por tanto nunca podrá calcular con precisión el ángulo Z. Sin embargo,
para la gran mayoría de aplicaciones sólo se necesitan los ejes X e Y.
El giroscopio mide la velocidad angular, es decir, el número de grados que se gira en un segundo.En un
principio, los giroscopios eléctricos eran unos voluminosos artefactos muy caros usados en aviones y para dirigir
cohetes. Actualmente la miniaturización de circuitos y gracias a la tecnología MEMS, es posible tener un
giroscopio en un chip a un precio muy asequible.
La media de velocidad angular en vez de medirse en grados por segundo, se mide en otra unidad que son
radianes por segundo (1rad/s = 180/PI grados/s). Si sabemos el ángulo inicial de la IMU, podemos sumarle el
valor que marca el giroscopio para saber el nuevo ángulo a cada momento. Supongamos que iniciamos la IMU a
0º. Si el giroscopio realiza una medida cada segundo, y marca 3 en el eje X, tendremos el ángulo con esta sencilla
fórmula:
Dónde Δt es el tiempo que transcurre cada vez que se calcula esta fórmula, AnguloYAnterior es el ángulo
calculado la última vez que se llamó esta fórmula y GiroscopioY es la lectura del ángulo Y del giroscopio.
Y lo mismo pasa con los ejes X, Z. Sólo que se suele ignorar el eje Z, puesto que al no poder calcular un ángulo Z
con el Acelerómetro, no se puede aplicar un Filtro Complementario para el eje Z.
Podemos ver los datos del acelerómetro y giroscopio de nuestro smartphone con
https://play.google.com/store/apps/details?id=com.mtorres.phonetester&hl=es
Error en las medidas. Las IMUs son unos artefactos mágicos que con un poco de trigonometría pueden dar un
ángulo con total exactitud. Pero hay dos problemas muy importantes: el ruido y los errores. El ruido son todas
aquellas interferencias que afectan a los dispositivos electrónicos. El acelerómetro es capaz de medir cualquier
ángulo, sin embargo sus lecturas son ruidosas y tienen un cierto margen de error. Si se dibuja un grá co de las
medidas de un acelerómetro en función del tiempo, se verá algo de este estilo:
https://aprendiendoarduino.wordpress.com/2016/11/14/ 18/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
El ángulo real (ideal) está marcado en azul, y las medidas reales están en rojo. Por si esto fuera poco, el
acelerómetro también detecta cualquier aceleración que no sea la de la gravedad. Por tanto, si mueves la IMU sin
girarla, al aplicar una aceleración en otro eje, la IMU lo detectará como un cambio de rotación.
Por otra parte tenemos el giroscopio. A diferencia del acelerómetro, da las medidas con mucha precisión. Pero al
realizar los cálculos del ángulo es inevitable que se produzca un pequeño error, que con el tiempo va
acomulándose hasta que cualquier similitud con la realidad es pura coincidencia. Esto en inglés se llama drift
(deriva). Hay varias formas de combinar los datos del acelerómetro y el giroscopio para así obtener medidas
exactas. Para ello son necesarios los ltros.
Hay que conseguir eliminar el ruido, el drift y conseguir que el acelerómetro no cambie de ángulo al detectar otra
fuerza que no sea la gravedad. Hay distintos algoritmos, llamados ltros, que hacen esta tarea. Uno de los
mejores es el Filtro de Kálman, se utiliza en los aviones, cohetes y satélites geoestacionarios.
El ltro de Kálman es sorprendente. Capaz de calcular el error de cada medida a partir de las medidas anteriores,
eliminarlo y dar el valor real del ángulo. En cierto modo es un algoritmo que aprende en cada iteración.
Sin embargo tiene dos problemas: Tiene un coste de procesamiento algo elevado y es muy complicado de
entender. Ver https://es.wikipedia.org/wiki/Filtro_de_Kalman
https://aprendiendoarduino.wordpress.com/2016/11/14/ 19/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Existen otros ltros a nuestra disposición. El que vamos a utilizar es conocido como Filtro Complementario o
Complementary Filter en inglés. Es ideal para implementar con Arduino: fácil de utilizar, bajo coste de
procesamiento y con una precisión muy buena.
¿En qué consiste exactamente? El Filtro Complementario es en realidad una unión de dos ltros diferentes: un
High-pass Filter para el giroscopio y un Low-pass Filter para el Acelerómetro. El primero deja pasar únicamente
los valores por encima de un cierto límite, al contrario que el Low-pass lter, que sólo permite a los que están por
debajo.
La fórmula resultante de combinar (complementar, de aquí el nombre) los dos ltros es:
Dónde AnguloGyro es el ángulo del Giroscopio que hemos calculado previamente, y AnguloAccel el ángulo del
Acelerómetro calculado con la fórmula de la tangente. Δt es el tiempo que ha pasado (en segundos) desde la
última vez que se ha calculado el ltro. Esta fórmula es la misma para el eje X, Y.
Es posible probar a cambiar el valor de 0.98 y 0.02 por un valor personalizado. Eso sí, ambos tienen que sumar 1.
http://robologs.net/2014/10/15/tutorial-de-arduino-y-mpu-6050/
http://www.prometec.net/usando-el-mpu6050
Tutorial del Arduino playground: http://playground.arduino.cc/Main/MPU-6050
Una librería más más avanzada para uso de : http://www.i2cdevlib.com/devices/mpu6050#source
Documentación de la librería: http://www.i2cdevlib.com/docs/html/class_m_p_u6050.html
La web del sensor: http://www.invensense.com/products/motion-tracking/6-axis/mpu-6050/
Otros sensores del mismo fabricante: http://www.invensense.com/products/motion-tracking/6-axis/mpu-
6050/
Data Sheet, especi caciones: https://www.cdiweb.com/datasheets/invensense/MPU-
6050_DataSheet_V3%204.pdf
DMP: El MPU6050 IMU contiene un DMP (Digital Motion Processor) que fusiona los datos del acelerómetro y del
giroscopio para minimizar los efectos de los errores inherentes a cada sensor. El DMP calcula los resultados en
términos de cuaterniones, y puede convertir los resultados en ángulos de Euler y realizar otros cálculos con los
datos. Invensense no revelará el algoritmo que utilizan para combinar los datos.
Mientras que la información del giroscopio (velocidad angular) o acelerómetro (aceleración lineal) para cada eje
(X, Y y Z) se puede leer de forma directa, el acceso a los registros del DMP es algo más compleja, debido a que el
fabricante no ha abierto toda la información al respecto.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 20/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
MEMS – sistemas micro-electro-mecánicos. Los IMUs son sistemas MEMS, los avances en el campo de los
semiconductores están dando lugar a circuitos integrados con características tridimensionales e incluso con
piezas móviles. Estos dispositivos, llamados Sistemas Micro electromecánicos (MEMS), pueden resolver muchos
problemas que un microprocesador más el software o con guración no ASIC (Chip integrados de aplicación
especí ca) no pueden. La tecnología MEMS puede aplicarse utilizando un sin número de diferentes materiales y
técnicas de fabricación; la elección dependerá del tipo de dispositivo que se está creando y el sector comercial en
el que tiene que operar.
Los acelerómetros actuales son simples dispositivos MEMS consistentes en una micro estructura suspendida con
una masa determinada de referencia conocida como masa sísmica dentro de una cámara de gas sellada. Bajo la
in uencia de aceleraciones externas la masa cambia de su posición neutral y ese cambio es convertido en una
señal eléctrica mediante piezoresistencias con cambio de la capacitancia.
Los giroscopios basados en sistemas MEMs usan el mismo sistema que el péndulo de Foucault y usa un
elemento vibrante (giroscopios de estructura vibrante). El principio físico subyacente es que un objeto vibrante
tiende a continuar vibrando en el mismo plano que gira su apoyo. En la literatura de ingeniería, este tipo de
dispositivos se conocen como “giroscopio de vibración de Coriolis”, debido a que a medida que el plano de
oscilación gira, la respuesta detectada por el transductor resulta del término de Coriolis presente en sus
ecuaciones de movimiento. Los giroscopios de estructura vibrante son más simples y económicos, que los
giroscopios de rotación convencionales. Los dispositivos de estado sólido que usan este principio son un tipo
económico de indicadores de posición.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 21/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Más información:
https://en.wikipedia.org/wiki/Microelectromechanical_systems
https://es.wikipedia.org/wiki/Sistemas_microelectromec%C3%A1nicos
Acelerometro: https://en.wikipedia.org/wiki/Accelerometer
Giroscopio: https://en.wikipedia.org/wiki/Gyroscope
Giroscopios de estructura vibrante:
https://en.wikipedia.org/wiki/Vibrating_structure_gyroscope#MEMS_gyroscopes y
https://es.wikipedia.org/wiki/Gir%C3%B3scopo_de_estructura_vibrante
Otra IMU con 9DOF es el GY-85. Al contrario que el MPU-6050 tiene en el mismo chip el acelerómetro y el
giroscopio, el GY-85 integra tres sensores: Acelerómetro de 3 ejes, Giroscopio de 3 ejes y sensor de campo
magnético de 3 ejes.
Comprar: http://www.dx.com/es/p/gy-85-6dof-9dof-imu-sensor-module-for-arduino-148436#.VzRp0oSLTcs
https://aprendiendoarduino.wordpress.com/2016/11/14/ 22/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Esquemático:
El MPU6050 que vamos a utilizar es un chip de 6 dof o grados de libertad porque incluye un acelerómetro de 3
ejes y un giróscopo de 3 ejes.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 23/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Aunque lo que miden los sensores internos son aceleraciones lineales y angulares el procesador interno del IMU
es capaz de realizar cálculos sobre la marcha para darnos informaciones más útiles como los ángulos de
inclinación con respecto a los 3 ejes principales. Conseguir los datos en bruto del MPU6050 es la parte fácil,
procesarlos y reaccionar es otra historia que se puede complicar un poco más.
Para estas sesión vamos a utilizar una Breakout board bastante típica llamada GY-521, que incluye un MPU650 y
un regulador de tensión, con lo que podemos alimentar a tanto 3.3V como a 5V
Esquema de conexión
https://aprendiendoarduino.wordpress.com/2016/11/14/ 24/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Probar el I2C scanner http://playground.arduino.cc/Main/I2cScanner con el MPU conectado normal y luego con
AD0 a masa y comprobar que cambia su dirección.
raw_data
advanced_values
Este programa es de lo más sencillo, y lo que hace es leer e imprimir los valores en bruto que los acelerómetros y
giroscopios que le envían a Arduino, es decir sin procesar en absoluto, algo que sirve de muy poco. Son las
medidas reales que producen los acelerómetros y los giróscopos, pero así no valen de mucho.
Hay 6 valores. Los tres primeros corresponden a los acelerómetros y los tres últimos a los giróscopos. Si vas
girando el IMU en direcciones perpendiculares verás con rapidez cual es cada uno de los ejes, porque aunque el
chip esté en movimiento inercial aun detectará la aceleración de la gravedad, claramente en una de las
direcciones.
Vamos a instalar las librerías correspondientes y a probar con uno de los programas de ejemplo que tanto las
conexiones como el MPU6050 están en condiciones operativas.
Para medir los ángulos, vamos a usar estas librerías. Cargar el ejemplo MPU6050_DMP6.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 25/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
El texto que aparece al principio de cada línea “ypr” corresponde a las iniciales en ingles de los tres ángulos de
referencia Yaw, Pitch y Roll. Y los valores que van cambiando son poco más o menos el valor instantáneo de cada
uno de esos ángulos.
Si el IMU dispone además de un magnetómetro de 3 ejes, ya está en condiciones de apuntar al Norte además y
puede jar con precisión el segundo eje, y el tercero cae por su propio peso, pero no es el caso del MPU6050 que
estamos usando.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 26/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Ya conocemos la librería Time para Arduino. Empezamos utilizando el reloj interno, pero tiene varios problemas
evidentes, como el hecho de que el reloj interno se reinicia cada 50 días aproximadamente, y además si
cortamos la corriente a nuestro Arduino, pone el reloj a 00 y vuelve a empezar desde el 1 de enero de 1970. Una
solución, que nos permita usar un reloj able que se mantenga incluso cuando apagamos Arduino es usar un
RTC
Uno RTC muy extendido para reloj digital es el DS1307 de Maxim. Por muy poco dinero realiza todas las
funciones para llevar un reloj con calendario y solo hay que añadirle una batería externa para que no pierda la
hora al perder la corriente.
Un RTC es un reloj:
https://es.wikipedia.org/wiki/Reloj_en_tiempo_real
https://en.wikipedia.org/wiki/Real-time_clock
Generalmente los RTC son dispositivos I2C y los más comunes son el DS1307 y el DS3231.
Para usar un RTC con Arduino es necesaria la librería time que ofrece la funcionalidad de mantener la fecha y
hora en Arduino y se usa el RTC como fuente de sincronización de la hora.
La librería time añade funcionalidades de tiempo a Arduino, ya sea con o sin HW externo. Nos permite obtener la
fecha y hora como año, mes, dia, hora, minuto, segundo, día de la semana, etc… También da la hora con el tipo
https://aprendiendoarduino.wordpress.com/2016/11/14/ 27/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Generalmente encontramos RTCs con bus I2C,pero también se pueden encontrar con puerto serie o bus SPI o 1-
Wire.
Más información:
http://www.prometec.net/relojes-rtc/
El DS1307 de Maxim/Dallas es un circuito integrado capaz de almacenar y llevar la cuenta de la fecha y hora,
además disponemos de unos cuantos bytes de datos de usuario en su memoria RAM no volátil (NVRAM). Arduino
posee una CPU potente, sin embargo aún así es incapaz de mantener la hora correctamente a largo plazo,
debido a los microsegundos que se atrasan al no dividir la frecuencia del reloj principal para dar con el segundo
exacto.
Características DS1307:
RTC: Real Time Clock, o reloj de tiempo real. Que lleva la cuenta de segundos minutos y horas además de
día mes y año automáticamente, válido hasta el año 2100.
56 byte de memoria RAM respaldada por una batería exterior, que mantiene la fecha y hora cuando no hay
corriente.
Detección automática de corte de corriente y cambio a modo batería.
Muy bajo consumo, lo que ayuda a que la batería dure entre 5 y 10 años.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 28/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
El DS1307 requiere un cristal de 32.768 Khz, este valor viene dado por el hecho de que 2^15 = 32,768. Esto quiere
decir que la frecuencia es divisible binariamente para generar un segundo exacto. El cristal ya se incluye si
compramos algún módulo con el DS1307.
El DS1307 requiere dos fuentes de alimentación: Por una parte, requiere alimentación de 5 volts que opera
mientras el circuito está encendido y funcionando y otra fuente que proviene de una batería de litio (tipo reloj)
que mantiene funcionando el reloj/calendario mientras la alimentación principal NO está disponible. El cambio
entre ambas fuentes de alimentación es gestionado por el DS1307 de manera automática.
Disponemos de un pin de salida que puede ser con gurado para que el RTC entregue una onda cuadrada con
una frecuencia con gurable, las frecuencias disponibles se muestran en la siguiente tabla y se con guran
mediante los bits RS1, RS0 y SQWE de registro de control, si se usa este pin hay que agregar una resistencia pull-
up, ya que es del tipo “Open drain” (solo puede “drenar” corriente no es fuente de corriente)
Los registros del DS1307 almacenan la fecha y la hora en formato BCD. La dirección de cada registro y la
información almacenada en cada uno se muestra en la siguiente tabla:
https://aprendiendoarduino.wordpress.com/2016/11/14/ 29/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
El funcionamiento del chip se controla mediante el bit 7 del registro del segundero (0x00) y el registro de control
(0x07): El bit CH del segundero detiene el reloj cuando está en alto (así se entregan los módulos de fábrica) y en
este modo NO se lleva el conteo de tiempo porque el oscilador está detenido. ES MUY IMPORTANTE PONER A 0
ESTE BIT PARA QUE EL RTC FUNCIONE. El registro de control maneja la funcionalidad del pin de salida de onda
cuadrada. A partir de la dirección 0x08 disponemos de memoria RAM no volátil (NVRAM) cuyo contenido no se
borra con la pérdida de energía, este segmento de memoria funciona de manera similar a una memoria
EEPROM.
El el DS1307 es uno de los RTC más usados y mejor documentados para Arduino. Características:
Placa: https://www.sparkfun.com/products/12708
Placa: https://www.adafruit.com/products/264
Chip: https://www.maximintegrated.com/en/products/digital/real-time-clocks/DS1307.html
Datasheet: http://datasheets.maximintegrated.com/en/ds/DS1307.pdf
Tutoriales:
http://bildr.org/2011/03/ds1307-arduino/
http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock
Tutorial Adafruit: https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/overview
http://www.prometec.net/relojes-rtc/
Muy buena explicación: http://www.geekfactory.mx/tutoriales/tutoriales-arduino/ds1307-en-tinyrtc-
con-arduino/
Proyecto con un RTC: https://www.sparkfun.com/products/11734
Con gurar hora en DS1307 con puerto serie: http://www.instructables.com/id/Setting-the-DS1307-Real-
Time-Clock-using-the-Seria/
El DS1307 devuelve los valores de la hora via I2C en formato decimal codi cado en binario (BCD –
https://es.wikipedia.org/wiki/Decimal_codi cado_en_binario). Para evitar hacer los cálculos y olvidarnos del
protocolo I2C disponemos de varias librerías:
https://aprendiendoarduino.wordpress.com/2016/11/14/ 30/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Otros RTCs:
Leer qué hora está dando el reloj con el ejemplo ReadTest de la librería DS1307RTC:
https://github.com/PaulSto regen/DS1307RTC/blob/master/examples/ReadTest/ReadTest.ino
Con gurar el reloj con el ejemplo SetTime de la librería DS1307RTC:
https://github.com/PaulSto regen/DS1307RTC/blob/master/examples/SetTime/SetTime.ino
__DATE__ Y __TIME__ son macros estándar prede nidas en C++ y están disponibles en todos lo compiladores que
implementan el estándar. Podemos aprovechar esto para poner en hora el reloj interno corriendo un programa
que convierta estos valores a formato fecha time_t y asignarlo al valor del reloj interno, como hace SetTime.
https://aprendiendoarduino.wordpress.com/2016/11/14/ 31/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
La macro __DATE__ expande a un string que describe la fecha en la que el preprocesador/compilador está
corriendo. El string contiene 11 caracteres en el formato “mmm dd yyyy”
La macro __TIME__ expande a un string que describe la hora del preprocesador/compilador. El string contiene 8
caracteres en el formato: “hh:mm:ss”
Solución: https://github.com/jecrespo/Aprendiendo-Arduino/tree/master/Ejercicio43-RTC/actualiza_hora_manual
Ejercicio43-RTC2: Mostrar en una pantalla LCD la fecha y hora obtenida del RTC.
Uso: http://playground.arduino.cc/Learning/SparkFunSerLCD
Solución: https://github.com/jecrespo/Aprendiendo-Arduino/blob/master/Ejercicio43-
RTC/Display_Hora/Display_Hora.ino
GPS
Ejemplo: http://arduinoguruji.blogspot.com.es/p/gps-interfacing-with.html
https://aprendiendoarduino.wordpress.com/2016/11/14/ 32/33
5/11/2019 14 | noviembre | 2016 | Aprendiendo Arduino
Librerías:
http://arduiniana.org/libraries/tinygps/
https://www.pjrc.com/teensy/td_libs_TinyGPS.html
Código fuente: https://github.com/mikalhart/TinyGPS/
Librería mejorada: http://arduiniana.org/libraries/tinygpsplus/
Código fuente: https://github.com/mikalhart/TinyGPSPlus
Anuncios
Esta entrada se publicó en Arduino, I2C y está etiquetada con Arduino, I2C, IMU, RTC, TWI en 14 noviembre, 2016
[https://aprendiendoarduino.wordpress.com/2016/11/14/bus-i2ctwi/] .
https://aprendiendoarduino.wordpress.com/2016/11/14/ 33/33