[2024-feb-29] Sad news: Eric Layton aka Nocturnal Slacker aka vtel57 passed away on Feb 26th, shortly after hospitalization. He was one of our Wiki's most prominent admins. He will be missed.

Welcome to the Slackware Documentation Project

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Próxima revisión
Revisión previa
Próxima revisiónAmbos lados, revisión siguiente
es:howtos:hardware:arm:interfacing_i2c_devices [2019/03/17 23:37 (UTC)] – creado rrampes:howtos:hardware:arm:interfacing_i2c_devices [2019/07/21 23:41 (UTC)] – [Desplazamiento del nivel de tensión] rramp
Línea 1: Línea 1:
-====== Interfacing I2C Devices To Your System ====== +<note important>Traducción en progreso. rramp</note> 
-Inter-Integrated Circuit (I²C or more often written as I2C) is a multimaster serial single-ended computer bus invented by the Philips semiconductor division (see the wikipedia article for more information on [[http://en.wikipedia.org/wiki/I2c | I2C]]) and commonly used in many modern electronic devices including PC.+====== Conectando dispositivos I2C a tu sistema ====== 
 +Circuito Inter-Integrado (I²C o más a menudo también escrito como I2C) es un bus multimaestro en serie de un solo extremo inventado por la división de semiconductores de Philips (consulte el artículo de wikipedia para obtener más información [[http://en.wikipedia.org/wiki/I2c | I2C]])  
 +y de uso común en muchos dispositivos electrónicos modernos, incluyendo PC. 
 +I²C usa solo dos lineas bidireccionales open-drain, Serial Data Line (SDA) y Serial Clock Line(SCL), llevados al nivel lógico 1 por resistencias de pullup. 
 +Típicamente son empleadas tensiones de +5 Volt o +3,3 Volt aunque sistemas con otras tensiones son permitidas. Esto tiene una implicación interesante: el nivel lógico 1 es logrado sin hacer nada, mientras que el nivel lógico 0 debe ser llevado a tierra. Aunque existen desplazadores de nivel de tensión para I2C bidireccionales (PCA9306) puede ser factible experimentar soluciones más simples si en el bus I2C no va a tener muchos dispositivos conectados. 
 +Para más información, consulte la sección "Desplazamiento del nivel de tensión"
  
 I²C uses only two bidirectional open-drain lines, Serial Data Line (SDA) and Serial Clock Line (SCL), pulled to logic level 1 by pullup resistors. Typical voltages used are +5 V or +3.3 V although systems with other voltages are permitted and are often encountered. This has an interesting implication: logic level 1 is achieved by doing nothing whilst logic level 0 needs to be pulled down to ground. Although there are bidirectional I2C voltage level shifters (like the PCA9306) it may be feasible to experiment simpler solutions if on the I2C bus you're not going to have many devices connected. See more on this in the "Voltage Level Shifting" chapter. I²C uses only two bidirectional open-drain lines, Serial Data Line (SDA) and Serial Clock Line (SCL), pulled to logic level 1 by pullup resistors. Typical voltages used are +5 V or +3.3 V although systems with other voltages are permitted and are often encountered. This has an interesting implication: logic level 1 is achieved by doing nothing whilst logic level 0 needs to be pulled down to ground. Although there are bidirectional I2C voltage level shifters (like the PCA9306) it may be feasible to experiment simpler solutions if on the I2C bus you're not going to have many devices connected. See more on this in the "Voltage Level Shifting" chapter.
  
-====== Preface ====== +====== Prefacio ====== 
-Most modern PC have several internal components that communicate vital informationlike internal temperatures of critical componentsover I2C bus. This type of stuff is factory wired into your PC and can be dealt with lm_senosts ... what we want to do here is use an I2C bus on your computer to connect some external I2C sensor like an accelerometerI'm tagging this in the ARM hardware section because I think thatexcluding the lm-sensors stuffmost people will be doing this sort of thing on embedded ARM systems ... but the concepts are applicable to any linux capable system with an I2C bus.+La mayoría de las computadoras personales (PC) modernas tienen componentes internos que comunican información vital, por ejemplo temperaturas criticas de componentessobre un bus I2CEste tipo de cosas están conectadas de fábrica en su PC y pueden ser tratadas con lm_sensors... lo que queremos hacer aquí es usar un bus I2C en su computadora para conectar algún sensor I2C externo como un acelerómetrosEstoy etiquetando esto en la sección de hardware de ARM porque creo queexcluyendo el tema de los sensores lm, la mayoría de la gente estará haciendo este tipo de cosas en sistemas ARM embebidos... pero los conceptos son aplicables a cualquier sistema que admita Linux con un bus I2C
 + 
 +====== Preparando el sistema principal ====== 
 + 
 +Antes de empezar, es posible que desee asegurarse de que el sistema operativo tiene todo lo necesario para gestionar el bus I2C que va a utilizar.  
 +Lo primero que hay que hacer es asegurarse de que tiene el controlador de kernel correcto para cualquier implementación de capa física en su sistema.  
 +Tendrás que investigar en las hojas de datos del hardware de tu sistema... mi Pi tiene bcm2708 así que en mi caso se trataba de cargar el módulo bcm2708_i2c. También puede ser necesario cargar el módulo i2c-dev dependiendo de su configuración.
  
-====== Preparing Your Host System ====== +Una vez que tenga los controladores correctos, es posible que desee disponer de una herramienta de espacio de usuario que le ayude a detectar buses, presentar dispositivos y comunicarse con los dispositivos I2C de cada bus.  
-Before you start you might want to make sure that the OS has all that's required to manage the I2C bus you will be using.  +Utilizo i2ctools para esto pero no está empaquetado entre los paquetes de Slackware y no pude encontrar un tercero que ofreciera un paquete de ARM Slackware, así que descargué las fuentes y las compilé para mí mismo 
-The first thing to do is make sure you have the correct kernel driver for whatever physical layer implementation is on your systemYou will have to research on the datasheets of your system's hardware ... my Pi has bcm2708 so in my case it was a matter of loading the bcm2708_i2c module. It might also be necessary to load i2c-dev module too depending on your setup.+Las fuentes se pueden obtener desde aquí: [[ http://www.lm-sensors.org/wiki/I2CTools |I2CTools]].
  
-Once you have the drivers right you might like to have a user-space tool to help you detect buses, present devices and communicate with the I2C devices each bus. I use i2ctools for this but it's not packaged amongst the Slackware packages and I was unable to find ant third party providing an ARM Slackware package so I downloaded the sources and compiled it for myself. Sources can be gotten from here: [[ http://www.lm-sensors.org/wiki/I2CTools |I2CTools]].+====== Conectando un dispositivo sobre el bus I2C ======
  
 +Siempre que haya resuelto los problemas de nivel de tensión (consulte el capítulo "Desplazamiento del nivel de tensión"), añadir un nuevo dispositivo en el bus es muy sencillo.
 +El bus es multimaster, lo que significa que puedes tener muchos dispositivos (hasta 101) en el mismo bus, así que todo lo que tienes que hacer es hacer 4 conexiones: Potencia, tierra, SDA y SCL.
 +Si es el primer dispositivo que conecta en el bus, puede ser necesario instalar los pullups entre Power-SDA y Power-SCL. Es tan simple como eso y si el sistema está listo con los controladores apropiados y las utilidades del país del usuario, usted está listo para acceder al dispositivo recién conectado.
  
-====== Connecting A Device on the I2C Bus ====== +===== Detectando dispositivos conectados =====
-Provided you've sorted out the voltage level issues (see the "Voltage Level Shifting" chapter) adding a new device in the bus is really simple. The bus is multimaster meaning that you can have many devices (upto 101) on the same bus so all you have to do is make 4 connections: Power, Ground, SDA and SCL. If it's the first device you're connecting on the bus it may be necessary to install the pullups between Power-SDA and Power-SCL. It's as simple as that and if the system is ready with the appropriate drivers and user-land utilities you are ready to access the newly connected device.+
  
-===== Detecting Connected Devices ===== +Hay probablemente muchas formas para determinar que está conectado a un bus I2C. Elegí usar cosas del proyecto [[http://www.lm-sensors.org/wiki/I2CTools | i2ctools]]. No pude encontrar un paquete Slackware ARM para i2ctools, así que lo compilé e instalé en mi sistema.
-There are probably many ways to determine what's connected to an I2C bus, I chose to use stuff out of the [[http://www.lm-sensors.org/wiki/I2CTools | i2ctools]] projectI was unable to find a Slackware ARM package for i2ctools so I compiled and installed it on my system.+
  
-First thing you want to know is what I2C busses are present on your system as there may be more then one and looking in the wrong bus may be frustrating:+Lo primero que debe saber es qué buses I2C están presentes en su sistema, ya que puede haber más de uno y mirar en el bus equivocado puede ser frustrante:
  
   root@pi:~# i2cdetect  -l   root@pi:~# i2cdetect  -l
Línea 27: Línea 40:
   root@pi:~#   root@pi:~#
  
-If you're not sure which bus you connected your stuff on you might want to do this on on all the busses:+Si no estás seguro de en qué bus conectaste tus cosas, es posible que quieras hacer esto en todos los buses:
  
   root@pi:~# i2cdetect -y 1   root@pi:~# i2cdetect -y 1
Línea 41: Línea 54:
   root@pi:~#   root@pi:~#
  
-===== Communicating With An I2C Device ===== +===== Comunicación con un dispositivo I2C ===== 
-Communication with I2C devices id done by reading and writing to it's registersEach device has it's own register list and is something you need to look for in the device's datasheetSome devices even need some preliminary calibration to be done before you can read any sensible data out of them so before you start using i2cget to read out some registers you should at least have an idea of what registers you are interested in and fave figured out if your device needs calibration prior to reading any sensible data+La comunicación con dispositivos I2C se realiza leyendo y escribiendo en sus registros. 
-Registers can be set by using i2cset but do this only if you have read the datasheet.+Cada dispositivo tiene su propia lista de registros y es algo que debe buscar en la hoja de datos del dispositivo. 
 +Algunos dispositivos incluso necesitan que se realice una calibración preliminar antes de que pueda leer cualquier dato sensible de ellos,, así que antes de empezar a usar i2cget para leer algunos registros, debe tener al menos una idea de los registros que le interesan y averiguar si su dispositivo necesita calibración antes de leer cualquier dato sensible. 
 +Los registros se pueden establecer utilizando i2cset, pero hágalo sólo si ha leído la hoja de datos.
  
-Even once you know if your device needs calibration and the registers involvedthe content of the registers may not be in a convenient format for ready useThere are generally various scripts in perl or python that address calibrating and managing data from specific I2C devices so that human readable information can be produced.+Incluso una vez que sepa si su dispositivo necesita calibración y los registros involucradosel contenido de los registros puede no estar en un formato conveniente para su uso inmediatoGeneralmente hay varios scripts en perl python que tratan de la calibración y gestión de datos de dispositivos específicos de I2C para que se pueda producir información legible para el ser humano. 
 + 
 +En este punto es imposible mostrar más información sobre la comunicación I1C sin entrar en detalles sobre un dispositivo específico, así que voy a elegir uno de los dispositivos de mi pcb IMU. Al detectar previamente en mi PI encontré 4 dispositivos con las direcciones hexadecimales fluyentes: 1e,40,69 y 77. 
 +Generalmente cada dispositivo I2C tiene un rango de direcciones que pueden ser configuradas. Nos concentraremos en el dispositivo con dirección 0x69. Haciendo una búsqueda de referencias cruzadas en la hoja de datos de la pcb IMU y en las hojas de datos individuales de cada dispositivo presente en mi IMU, se revela que 0x69 debe ser la dirección de la ITG3200 (giroscopio + sensor de temperatura) y, de hecho, la hoja de datos de la ITG3200 afirma que puede tener una dirección de 0x68 o 0x69 seleccionable por nivel lógico en el pin 9. 
 +No que nosotros necesitamos es la tabla del ITG3200:
  
-At this point it's impossible to show any further info about I1C communication without going into some detail about a specific device so I'll pick one ot the devices on my IMU pcb. While detecting previously on my PI I found 4 devices with the flowing hex addresses: 1e,40,69 and 77. 
-Generally each I2C device has a range of addresses than can set. We shall concentrate on the device with 0x69 address. By doing some cross reference search on the IMU pcb datasheet and on the single datasheets of each device present on my IMU it's revealed that 0x69 should be the address of the ITG3200 (gyro + temp sensor) and indeed the ITG3200 datasheet asserts that it can have either 0x68 or 0x69 address selectable by logic level on pin 9. No what we need is the ITG3200 register chart: 
  
   Addr  Addr     Register Name R/W      Addr  Addr     Register Name R/W   
Línea 67: Línea 84:
    3E    62      PWR_MGM       R/    3E    62      PWR_MGM       R/
  
-I chose the ITG3200 because it has a temperature sensor inside and I'm hoping I can read that without having to do any calibrationjust for the sake of keeping the example as simple as possibleAccording to the chart the temperature register addresses are 1b and 1c so let's go and try and get some data out of there:+Elegí el ITG3200 por que tiene un sensor de temperatura incorporado y espero poder leerlo sin tener que hacer ninguna calibraciónsólo para mantener el ejemplo lo más simple posibleDe acuerdo a la tabla, la dirección del registro de temperatura son 1b 1c, así que vamos a intentar sacar algunos datos de ahí:
  
   root@pi:~# i2cdump  -y -r 0x1b-0x1c 1 0x69 b   root@pi:~# i2cdump  -y -r 0x1b-0x1c 1 0x69 b
Línea 74: Línea 91:
   root@pi:~#   root@pi:~#
  
-The above example dumps registers 1b and 1c from the ITG3200 the same result can be achieved with i2cget:+El ejemplo de arriba muestra los registros de volcado 1b 1c de la ITG3200, se puede lograr el mismo resultado con i2cget:
  
   root@pi:~# i2cget -y  1 0x69  0x1b b   root@pi:~# i2cget -y  1 0x69  0x1b b
Línea 81: Línea 98:
   0x90   0x90
   root@pi:~#   root@pi:~#
- +   
-So we got c090 as our temperature readingAccording to the datasheet this value is a 2's compliment of the temperatureSo let's try and figure out what that would be: c090 written in binary is 1100000010010000, the most significant bit is so the result should be +así que tenemos el registro c090 como nuestro registro de temperaturaDe acuerdo a la hoja de datos este es representado como un complemento a 2 de la temperaturaAsí que vamos a tratar de averiguar qué sería eso: c090 es escrito en binario es 1100000010010000, el bit más significativo es entonces el resultado debería ser:
   16528 - 32768 = -16240     16528 - 32768 = -16240  
-I was unable to find in the datasheet what units this reading is in but they did mention that there was an average offset of 13200. I did a little google search and found this formula:+ 
 +No pude encontrar en la hoja de datos en qué unidades se encuentra esta lectura, pero sí mencionaron que había una compensación promedio de 13200. Hice una pequeña búsqueda en Google y encontré esta fórmula:
  
   35 + ((raw value + 13200) / 280))   35 + ((raw value + 13200) / 280))
   35 + ((13200 - 16240)/280) = 24.14   35 + ((13200 - 16240)/280) = 24.14
  
-Considering that my current ambient temperature is about 20 Celcius I guess that for uncalibrated data that's OK.+Considerando que mi temperatura ambiente actual es cerca de 20 grados Celcius supongo que para los datos no calibrados está bien.
  
-If you want a script that does the maths for you and just reads out the ITG3200 sensor data in a human readable format here's an example:+Si quieres un script que haga las matemáticas para ti y sólo leer la salida del sensor ITG32000 en un formato legible por un humano aquí tienes un ejemplo:
  
   #!/bin/bash   #!/bin/bash
Línea 134: Línea 152:
   echo "ibase=16; input=$RZH$RZL; if ( input >= 8000 ) { raw= input - 10000;} else { raw=input;}; raw / E.177" |bc -l   echo "ibase=16; input=$RZH$RZL; if ( input >= 8000 ) { raw= input - 10000;} else { raw=input;}; raw / E.177" |bc -l
  
-The above script just does one simple dump of the register data and converts the values into human readable formatit does nothing with regards to calibration and averaging out vibrationsMore consistent gyroscopic readings would be achieved if an average over 10 consecutive data samples was made thus averaging out most of the ambient vibrations+El script anterior sólo hace un simple volcado de los datos de registro y convierte los valores en un formato legible para el ser humanono hace nada con respecto a la calibración y el promedio de las vibracionesSe lograrían lecturas giroscópicas más consistentes si se hiciera un promedio de 10 muestras de datos consecutivos, lo que permitiría obtener un promedio de la mayoría de las vibraciones ambientales
  
-A bash script is really not the most suitable way to read data from I2C devicesa faster means of managing the data from the devices is really mandatory in order to do calibrationdata averaging and what more to make the information consistent and useful for further calculationsI found the Linux kernel i2c documentation a usefull reference (<kernel source tree>/Documentation/i2c/dev-interface); it's not the only way that data can be read but it's a good starting point.+Un script en bash no es realmente la forma más adecuada de leer datos de dispositivos I2C, una forma más rápida de gestionar los datos de los dispositivos es realmente obligatorio para realizar calibracionespromedios de datos y, lo que es más, para que la información sea coherente y útil para cálculos posteriores. 
 +La documentación del núcleo de Linux para i2c me pareció una referencia útil (<kernel source tree>/Documentation/i2c/dev-interface); no es la única manera de que los datos puedan ser leídos, pero es un buen punto de partida.
  
-I hate showing my poor programming capabilities but here's some code that uses i2c-dev to read stuff from the ITG3200 and takes an average over 10 readings:+Odio mostrar mis pobres capacidades de programación en C, pero aquí hay un código que usa i2c-dev para leer cosas de la ITG3200 y toma un promedio de más de 10 lecturas:
  
   #include <sys/ioctl.h>   #include <sys/ioctl.h>
Línea 256: Línea 275:
  
  
-====== Voltage Level Shifting ======+====== Desplazamiento del nivel de tensión ====== 
 + 
 +Usted puede terminar con dispositivos de nivel de voltaje heterogéneo y si tiene muchos dispositivos, la manera correcta de solucionar este problema es usando desplazadores de nivel de voltaje I2C bidireccionales como el, [[ http://www.ti.com/lit/ds/symlink/pca9306.pdf |PCA9306]], pero si sólo tiene unos pocos dispositivos agrupados en una placa de circuito impreso como la unidad IMU 10DOF, es posible que desee probar un sistema más sencillo. 
 +Así es como conecté mi pcb IMU de 5V a un bus I2C de 3.3V en mi Raspberry PI:  
 You may end up with heterogeneous voltage level devices and if you have many devices the correct way to work around this problem is by using bidirectional I2C voltage level shifters like the [[ http://www.ti.com/lit/ds/symlink/pca9306.pdf |PCA9306]], but if you only have a few devices all grouped up in a neat PCB like the 10DOF IMU unit you might want to give a simpler system a try. You may end up with heterogeneous voltage level devices and if you have many devices the correct way to work around this problem is by using bidirectional I2C voltage level shifters like the [[ http://www.ti.com/lit/ds/symlink/pca9306.pdf |PCA9306]], but if you only have a few devices all grouped up in a neat PCB like the 10DOF IMU unit you might want to give a simpler system a try.
 This is how I connected my 5v IMU pcb to a 3.3v I2C bus on my RaspberryPI: I took as educated guess that 4.4v (5v with a 4148 diode in series) would still be a tolerable power supply voltage for the whole IMU pcb, this would most likely allow all the I2C devices on the IMU pcb to recognize a minimum of 3.08v (4.4 * 0.7) as the lowest reliable logic level 1 tension allowing it to inter-operate with the PI's 3.3v logig levels. I was not able to find if the PI has internal pullups on the I2C bus or if they have to be externally placed so in doubt I put in 10k pullups between the 4.4v power line and the 2 data lines. I was the able to correctly detect the sensors on the IMU pcb.    This is how I connected my 5v IMU pcb to a 3.3v I2C bus on my RaspberryPI: I took as educated guess that 4.4v (5v with a 4148 diode in series) would still be a tolerable power supply voltage for the whole IMU pcb, this would most likely allow all the I2C devices on the IMU pcb to recognize a minimum of 3.08v (4.4 * 0.7) as the lowest reliable logic level 1 tension allowing it to inter-operate with the PI's 3.3v logig levels. I was not able to find if the PI has internal pullups on the I2C bus or if they have to be externally placed so in doubt I put in 10k pullups between the 4.4v power line and the 2 data lines. I was the able to correctly detect the sensors on the IMU pcb.   
  
-====== Sources ======+====== Fuentes ======
 <!-- If you are copying information from another source, then specify that source --> <!-- If you are copying information from another source, then specify that source -->
 <!-- * Original source: [[http://some.website.org/some/page.html]] --> <!-- * Original source: [[http://some.website.org/some/page.html]] -->
 <!-- Authors are allowed to give credit to themselves! --> <!-- Authors are allowed to give credit to themselves! -->
 <!-- * Originally written by [[wiki:user:xxx | User X]] --> <!-- * Originally written by [[wiki:user:xxx | User X]] -->
-  * Originally written by [[wiki:user:louigi600|louigi600]]+  * Escrito originalmente por [[wiki:user:louigi600|louigi600]]
 +  * Traducido por  --- //[[wiki:user:rramp|rramp]] 2019/07/16 22:51 (UTC)//.
 <!-- * Contributions by [[wiki:user:yyy | User Y]] --> <!-- * Contributions by [[wiki:user:yyy | User Y]] -->
 <!-- Please do not modify anything below, except adding new tags.--> <!-- Please do not modify anything below, except adding new tags.-->
 es:howtos:hardware:arm:interfacing_i2c_devices ()