Module USB-I2C
De MicElectroLinGenMet.
Sommaire |
Description
Documentation en ligne: http://www.robot-electronics.co.uk/htm/usb_i2c_tech.htm ou en local
Le module USB-I2C (USBI2C) fournit une interface entre le PC et le bus I2C. Le module est auto alimenté par le câble USB et peut fournir jusqu'à 70 mA à 5 V. Le module fonctionne uniquement en maître I2C, et non pas en esclave.
Led rouge = power
Led verte = communication i2c.
Fonctionnement
Le module USB-I2C se charge de gérer le protocole du bus I2C telles que start / restart / stop. Il suffira d'envoyer une chaîne d'octets pour piloter le module.
Il y a une liste d'octets de commandes disponibles pour chaque action I2C:
| Command | Value | Description | Available in I2C-USB Version |
| I2C_SGL | 0x53 | Read/Write single byte for non-registered devices, such as the Philips PCF8574 I/O chip. | All |
| I2C_MUL | 0x54 | Read multiple bytes without setting new address (eeprom's, Honeywell pressure sensors, etc). | V5 and higher |
| I2C_AD1 | 0x55 | Read/Write single or multiple bytes for 1 byte addressed devices (the majority of devices will use this one) | All |
| I2C_AD2 | 0x56 | Read/Write single or multiple bytes for 2 byte addressed devices, eeproms from 32kbit (4kx8) and up. | V6 and higher |
| I2C_USB | 0x5A | A range of commands to the USB-I2C module, generally to improve selected communications or provide analogue/digital I/O | All |
Exemples
(Repris de la documention originale)
Writing a single byte to I2C devices without internally addressable registers
These include devices such as the Philips PCF8574 I/O expander. Following the I2C_SGL you send the devices I2C address and the data byte.
| Primary USB-I2C command | Device Address + R/W bit | The data byte | |
| Byte Type | I2C_SGL | Addr+R/W | Data |
| Example | 0x53 | 0x40 | 0x00 |
| Meaning | Direct Read/Write command | PCF8574 I2C address | Set all bits low |
This 3 byte sequence sets all bits of a PCF8574 I/O expander chip low. All 3 bytes should be sent to the USB-I2C in one sequence. A gap will result in the USB-I2C re-starting its internal command synchronization loop and ignoring the message. After all bytes have been received the USB-I2C performs the IC2 write operation out to the PCF8574 and sends a single byte back to the PC. This returned byte will be 0x00 (zero) if the write command failed and non-zero if the write succeeded. The PC should wait for this byte to be returned (timing out after 500mS) before proceeding with the next transaction.
Reading a single byte from I2C devices without internally addressable registers
This is similar to writing, except that you should add 1 to the device address to make it an odd number. To read from a PCF8574 at address 0x40, you would use 0x41 as the address. (When the address goes out on the I2C bus, its the 1 in the lowest bit position that indicates a read cycle is happening). Here is an example of reading the inputs on a PCF8574 I/O expander:
| I2C_SGL | PCF8574 I2C address + Read bit |
| 0x53 | 0x41 |
The USB-I2C module will perform the read operation on the I2C bus and send a single byte (the PCF8574 inputs) back to the PC. The PC should wait for the byte to be returned (timing out after 500mS) before proceeding with the next transaction.
Reading multiple bytes from I2C devices without setting a new address
This is used for devices that do not have an internal register address but returns multiple bytes. Examples of such devices are the Honeywell ASDX DO series pressure sensors. This command can also be used for devices that do have an internal address which it increments automatically between reads and doesn't need to be set each time, such as eeproms. In this case you would use command I2C_AD1 or I2C_AD2 for the first read, then I2C_MUL for subsequent reads. Here is an example of reading the two byte pressure from the Honeywell sensor.
| I2C_MUL | ASDX I2C address + Read bit | Number of bytes to read |
| 0x54 | 0xF1 | 0x02 |
The USB-I2C will perform the read operation on the I2C bus and send two bytes back to the PC - high byte first in this example for the ASDX sensor. The PC should wait for both bytes to be returned (timing out after 500mS) before proceeding with the next transaction.
Writing to I2C devices with a 1 byte internal address register
This includes almost all I2C devices. Following the I2C_AD1 command you send the device I2C address, then the devices internal register address you want to write to and the number of bytes you're writing. The maximum number of data bytes should not exceed 64 so as not to overflow the USB-I2C's internal buffer.
| Primary USB-I2C command | Device Address + R/W bit | Device internal register | Number of data bytes | The data bytes | |
| Byte Type | I2C_AD1 | Addr+R/W | Reg | Byte Count | Data |
| Example | 0x55 | 0xE0 | 0x00 | 0x01 | 0x51 |
| Meaning | Primary USB-I2C command | SRF08 I2C address | SRF08 command Reg | One command byte follows | Start ranging in cm |
This 5 byte sequence starts an SRF08 at address 0xE0 ranging. All 5 bytes should be sent to the USB-I2C in one sequence. A gap will result in the USB-I2C re-starting its internal command synchronization loop and ignoring the message. After all bytes have been received the USB-I2C performs the IC2 write operation out to the SRF08 and sends a single byte back to the PC. This returned byte will be 0x00 (zero) if the write command failed and non-zero if the write succeeded. The PC should wait for this byte to be returned (timing out after 500mS) before proceeding with the next transaction.
Here is another write example - this time an 8 byte sequence to initialize the MD22 motor driver:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Again the USB-I2C will respond with non-zero if the write succeeded and zero if it failed. A failure means that no acknowledge was received from the I2C device.
Reading from I2C devices with a 1 byte internal address register
This is similar to writing, except that you should add 1 to the device address to make it an odd number. To read from an SRF08 at address 0xE0, you would use 0xE1 as the address. (When the address goes out on the I2C bus, its the 1 in the lowest bit position that indicates a read cycle is happening). The maximum number of data bytes requested should not exceed 60 so as not to overflow the USB-I2C's internal buffer. Here is an example of reading the two byte bearing from the CMPS03 compass module:
| I2C_AD1 | CPMS03 I2C address + Read bit | CMPS03 bearing register | Number of bytes to read |
| 0x55 | 0xC1 | 0x02 | 0x02 |
The USB-I2C will perform the read operation on the I2C bus and send two bytes back to the PC - high byte first. The PC should wait for both bytes to be returned (timing out after 500mS) before proceeding with the next transaction.
Writing to I2C devices with a 2 byte internal address register
This is primarily for eeprom's from 24LC32 (4k x 8) to 24LC1024 (2 * 64k x 8). Following the I2C_AD2 you send the device I2C address, then the devices internal register address (2 bytes, high byte first for eeprom's) and then the number of bytes you're writing. The maximum number of data bytes should not exceed 64 so as not to overflow the USB-I2C's internal buffer.
| Primary USB-I2C command | Device Address + R/W bit | High byte of internal Address | Low byte of internal Address | Number of data bytes | The data bytes | |
| Byte Type | I2C_AD2 | Addr+R/W | Address High | Address Low | Byte Count | Data |
| Example | 0x56 | 0xA0 | 0x00 | 0x00 | 0x40 | 0xnn |
| Meaning | Primary USB-I2C command | 24LC32 I2C address | Address 0x0000 | Address 0x0000 | One command byte follows | 64 (0x40) data bytes |
This 69 byte sequence writes the last 64 bytes to address 0x0000 in the eeprom. All 69 bytes should be sent to the USB-I2C in one sequence. A gap will result in the USB-I2C re-starting its internal command synchronization loop and ignoring the message. After all bytes have been received the USB-I2C performs the IC2 write operation out to the eeprom and sends a single byte back to the PC. This returned byte will be 0x00 (zero) if the write command failed and non-zero if the write succeeded. The PC should wait for this byte to be returned (timing out after 500mS) before proceeding with the next transaction.
Reading from I2C devices with a 2 byte internal address register
This is similar to writing, except that you should add 1 to the device address to make it an odd number. To read from an eeprom at address 0xA0, you would use 0xA1 as the address. (When the address goes out on the I2C bus, its the 1 in the lowest bit position that indicates a read cycle is happening). The maximum number of data bytes requested should not exceed 64 so as not to overflow the USB-I2C's internal buffer. Here is an example of reading 64 (0x40) bytes from internal address 0x0000 of an eeprom at I2C address 0xA0.
| I2C_AD2 | Device I2C address + Read bit | High byte of internal Address | Low byte of internal Address | Number of bytes to read |
| 0x56 | 0xA1 | 0x00 | 0x00 | 0x40 |
The USB-I2C will perform the read operation on the I2C bus and send 64 bytes back to the PC. The PC should wait for all 64 bytes to be returned (timing out after 500mS) before proceeding with the next transaction.
USB-I2C Commands
The USB-I2C command format is shown below:
| I2C_USB | USB-I2C Command | Data 1 | Data2 |
| 0x5A | See below | Command Specific | Command Specific |
The USB-I2C commands are always a four byte sequence. They start with the I2C_USB primary command which is followed by the USB-I2C command itself. Two data bytes follow which can be any junk if not used, but they must be included to make up the 4 byte command sequence. These commands are:
| Hex |
| Bytes returned | Purpose |
| 0x01 | REVISION | 1 | Returns the USB-I2C firmware revision number |
| 0x02 | NEW_ADDRESS | 1 | Changes SRF08 I2C address |
| 0x03 | UNUSED | 1 | Unused - for CM02 compatibility only - returns 0x00 |
| 0x04 | SCAN1 | 6 | Send motor data - return battery, compass & sonar data |
| 0x05 | SCAN2 | 9 | Same but for 2 SRF08's |
| 0x06 | SCAN3 | 12 | 3 SRF08's |
| 0x07 | SCAN4 | 15 | 4 |
| 0x08 | SCAN6 | 21 | 6 |
| 0x09 | SCAN8 | 27 | 8 |
| 0x0A | SCAN12 | 39 | 12 |
| 0x0B | SCAN16 | 51 | All 16 possible SRF08's |
| 0x10 | SETPINS | 1 | Sets I/O pins high/low |
| 0x11 | GETPINS | 1 | Gets the status of I/O pins |
| 0x12 | GETAD | 4 | Gets Analogue value on I/O2 and I/O3 |
Test du module avec un PCF8574 et un DS1621
Circuits testés
Programme de test sous Linux
Le module est vu sous Linux comme un port "serial-usb" FTDI.
- Messages kernel à la connexion:
Mar 9 22:13:34 vesta kernel: [19497.869893] usb 2-2: new full speed USB device using uhci_hcd and address 2 Mar 9 22:13:34 vesta kernel: [19498.081415] usb 2-2: configuration #1 chosen from 1 choice Mar 9 22:13:34 vesta kernel: [19498.089958] usb 2-2: New USB device found, idVendor=0403, idProduct=6001 Mar 9 22:13:34 vesta kernel: [19498.089964] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 Mar 9 22:13:34 vesta kernel: [19498.089967] usb 2-2: Product: FT232R USB UART Mar 9 22:13:34 vesta kernel: [19498.089968] usb 2-2: Manufacturer: FTDI Mar 9 22:13:34 vesta kernel: [19498.089970] usb 2-2: SerialNumber: A3000GfS Mar 9 22:13:34 vesta kernel: [19498.450402] usbserial: USB Serial support registered for FTDI USB Serial Device Mar 9 22:13:34 vesta kernel: [19498.450402] ftdi_sio 2-2:1.0: FTDI USB Serial Device converter detected Mar 9 22:13:34 vesta kernel: [19498.450487] ftdi_sio: Detected FT232RL Mar 9 22:13:34 vesta kernel: [19498.450520] usb 2-2: FTDI USB Serial Device converter now attached to ttyUSB2 Mar 9 22:13:34 vesta kernel: [19498.450533] usbcore: registered new interface driver ftdi_sio Mar 9 22:13:34 vesta kernel: [19498.450535] ftdi_sio: v1.4.3:USB FTDI Serial Converters Driver
- Configuration du port série
19200,8N2
Il suffira d'envoyer les commandes au port série comme décrit dans la documentation technique.
Exemple avec Circuit PCF8574
// Test Module usb-i2c par <domos78 at free point fr> // http://www.robot-electronics.co.uk/htm/usb_i2c_tech.htm // gcc -Wall pcf8574_usb-i2c.c -o pcf8574_usb-i2c // 09/03/2009 // Test OK avec PCF8574 (DS1621 sur même circuit) // Adr. i2c PCF8574 = 0x40 (A0, A1, A2 reliés à la masse) // Leds rouge = power, verte = communication i2c. #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <termios.h> #include <sys/fcntl.h> #define I2C_SGL_CMD 0x53 // Read/Write single byte for non-registered devices #define I2C_AD1_CMD 0x55 // Read/Write single or multiple bytes for 1 byte addressed devices #define I2C_USB_CMD 0x5A // A range of commands to the USB-I2C module #define VERSION_CMD 0x01 // Command: Returns the USB-I2C firmware revision number #define SETPINS_CMD 0x10 // Command: Sets I/O pins high/low #define GETPINS_CMD 0x11 // Command: Gets the status of I/O pins #define GETAD_CMD 0x12 // Command: Gets Analogue value on I/O2 and I/O3 #define BAUDRATE B19200 #define SERIALPORT "/dev/ttyUSB2" #define CHARACTERSIZE "8N2" int usbi2c_port ; int res ; unsigned char data ; unsigned char cmd[255] ; unsigned char buff[255] ; struct termios termios_param ; /*------------------------------------------------------------------------------*/ /* Open serial port */ /*------------------------------------------------------------------------------*/ int initserial (void) { int serialfd ; if ( (serialfd=open(SERIALPORT, O_RDWR | O_NOCTTY)) == -1 ) { perror("Erreur ouverture de la liaison serie !"); exit(1) ; } tcgetattr(serialfd,&termios_param) ; // Lecture des parametres courants. cfsetispeed(&termios_param, BAUDRATE) ; // Configure le débit en entrée/sortie. cfsetospeed(&termios_param, BAUDRATE) ; termios_param.c_cflag |= (CLOCAL | CREAD) ; // Active réception et mode local. // CHARACTERSIZE = "8N2" termios_param.c_cflag &= ~PARENB ; // Active 8 bits de donnees sans parite. termios_param.c_cflag &= ~CSIZE; termios_param.c_cflag |= CSTOPB ; // 2 bits de stop termios_param.c_cflag |= CS8 ; // FIN CHARACTERSIZE = "8N2" termios_param.c_cflag &= ~CRTSCTS ; // Désactive control de flux matériel. termios_param.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ; // Mode non-canonique (mode raw) sans echo. termios_param.c_iflag &= ~(IXON | IXOFF | IXANY) ; // Désactive control de flux logiciel. termios_param.c_oflag &= ~OPOST ; // Pas de mode de sortie particulier (mode raw). termios_param.c_cc[VTIME] = 30 ; // time-out à ~3s. termios_param.c_cc[VMIN] = 0 ; // 1 car. attendu. tcflush(serialfd, TCIFLUSH) ; // Efface les données reçues mais non lues. tcsetattr(serialfd,TCSANOW,&termios_param) ; // Sauvegarde des nouveaux parametres return serialfd ; } /*------------------------------------------------------------------------------*/ /* MAIN */ /*------------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { usbi2c_port = initserial() ; printf("Lecture révision Firmware module USB-I2C ...\n") ; cmd[0] = I2C_USB_CMD ; // Commande. cmd[1] = 0x01 ; // Lecture révision. cmd[2] = 0x00 ; // Data null necessaire. cmd[3] = 0x00 ; // Data null necessaire. write(usbi2c_port, cmd, 4); res = read(usbi2c_port, buff, 1) ; if (! res) { printf("Erreur pas de réponse de l'interface usb-i2c !\n") ; close(usbi2c_port); exit(1) ; } else printf("Version firmware: %02X\n", buff[0]) ; printf("Test écriture sur PCF8574 ...\n") ; for(data=0;data<16;data++) { cmd[0] = I2C_SGL_CMD ; // Ecriture direct. cmd[1] = 0x40 ; // Pcf8574 (bit r/w=0). cmd[2] = data + 0xF0 ; // Donnée à écrire. write(usbi2c_port, cmd, 3) ; res = read(usbi2c_port, buff, 1) ; if (! res) { printf("Erreur pas de réponse de l'interface usb-i2c !\n") ; close(usbi2c_port); exit(1) ; } if (! buff[0]) // 0x00 = erreur. { printf("Erreur ecriture PCF8574, code retour %02X !\n", buff[0]) ; close(usbi2c_port); exit(1) ; } else printf("Ecriture %02X, Code retour écriture ok: %02X\n", cmd[2], buff[0]) ; sleep(1); } printf("Test lecture sur PCF8574 ...\n") ; for(data=0;data<16;data++) { cmd[0] = I2C_SGL_CMD ; // lecture direct. cmd[1] = 0x41 ; // Pcf8574 (bit r/w=0). write(usbi2c_port, cmd, 2) ; res = read(usbi2c_port, buff, 1) ; if (! res) { printf("Erreur pas de réponse de l'interface usb-i2c !\n") ; close(usbi2c_port); exit(1) ; } else printf("Lecture = %02X\n", buff[0]) ; sleep(1); } printf("Terminé\n"); /* Fermeture */ close(usbi2c_port); exit(0); }
Exemple avec Circuit DS1621
// Test Module usb-i2c par <domos78 at free point fr> // http://www.robot-electronics.co.uk/htm/usb_i2c_tech.htm // gcc -Wall ds1621_usb-i2c.c -o ds1621_usb-i2c // 09/03/2009 // Test OK avec DS1621 (PCF8574 sur même circuit) // Adr. i2c DS1621 = 0x9E (A0, A1, A2 reliés à Vcc) // Leds rouge = power, verte = communication i2c. #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <termios.h> #include <sys/fcntl.h> #define I2C_SGL_CMD 0x53 // Read/Write single byte for non-registered devices #define I2C_AD1_CMD 0x55 // Read/Write single or multiple bytes for 1 byte addressed devices #define I2C_USB_CMD 0x5A // A range of commands to the USB-I2C module #define VERSION_CMD 0x01 // Command: Returns the USB-I2C firmware revision number #define SETPINS_CMD 0x10 // Command: Sets I/O pins high/low #define GETPINS_CMD 0x11 // Command: Gets the status of I/O pins #define GETAD_CMD 0x12 // Command: Gets Analogue value on I/O2 and I/O3 #define BAUDRATE B19200 #define SERIALPORT "/dev/ttyUSB2" #define CHARACTERSIZE "8N2" int usbi2c_port ; int res ; unsigned char data ; unsigned char cmd[255] ; unsigned char buff[255] ; struct termios termios_param ; /*------------------------------------------------------------------------------*/ /* Open serial port */ /*------------------------------------------------------------------------------*/ int initserial (void) { int serialfd ; if ( (serialfd=open(SERIALPORT, O_RDWR | O_NOCTTY)) == -1 ) { perror("Erreur ouverture de la liaison serie !"); exit(1) ; } tcgetattr(serialfd,&termios_param) ; // Lecture des parametres courants. cfsetispeed(&termios_param, BAUDRATE) ; // Configure le débit en entrée/sortie. cfsetospeed(&termios_param, BAUDRATE) ; termios_param.c_cflag |= (CLOCAL | CREAD) ; // Active réception et mode local. // CHARACTERSIZE = "8N2" termios_param.c_cflag &= ~PARENB ; // Active 8 bits de donnees sans parite. termios_param.c_cflag &= ~CSIZE; termios_param.c_cflag |= CSTOPB ; // 2 bits de stop termios_param.c_cflag |= CS8 ; // FIN CHARACTERSIZE = "8N2" termios_param.c_cflag &= ~CRTSCTS ; // Désactive control de flux matériel. termios_param.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ; // Mode non-canonique (mode raw) sans echo. termios_param.c_iflag &= ~(IXON | IXOFF | IXANY) ; // Désactive control de flux logiciel. termios_param.c_oflag &= ~OPOST ; // Pas de mode de sortie particulier (mode raw). termios_param.c_cc[VTIME] = 30 ; // time-out à ~3s. termios_param.c_cc[VMIN] = 0 ; // 1 car. attendu. tcflush(serialfd, TCIFLUSH) ; // Efface les données reçues mais non lues. tcsetattr(serialfd,TCSANOW,&termios_param) ; // Sauvegarde des nouveaux parametres return serialfd ; } /*------------------------------------------------------------------------------*/ /* MAIN */ /*------------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { usbi2c_port = initserial() ; // Lecture révision. printf("Lecture révision Firmware module USB-I2C ...\n") ; cmd[0] = I2C_USB_CMD ; // Commande. cmd[1] = 0x01 ; // Lecture révision. cmd[2] = 0x00 ; // Data null necessaire. cmd[3] = 0x00 ; // Data null necessaire. write(usbi2c_port, cmd, 4); res = read(usbi2c_port, buff, 1) ; if (! res) { printf("Erreur pas de réponse de l'interface usb-i2c !\n") ; close(usbi2c_port); exit(1) ; } else printf("Version firmware: %02X\n", buff[0]) ; // Init. ds1621 // Ecriture ds1621, init. printf("Init. Ds1621 ...\n") ; cmd[0] = I2C_AD1_CMD ; // Ecriture avec registre. cmd[1] = 0x9E ; // Adr. i2c ds1621 bit r/w=0). cmd[2] = 0xAC ; // Registre. cmd[3] = 0x01 ; // Nb octet à écrire. cmd[4] = 0x01 ; // Octet à écrire. write(usbi2c_port, cmd, 5); res = read(usbi2c_port, buff, 1) ; if (! res) { printf("Erreur pas de réponse de l'interface usb-i2c !\n") ; close(usbi2c_port); exit(1) ; } if (! buff[0]) // 0x00 = erreur. { printf("Erreur ecriture DS1621, code retour %02X !\n", buff[0]) ; close(usbi2c_port); exit(1) ; } else printf("Init. Ds1621 OK\n") ; // Ecriture sur ds1621, start temperature conversion cmd[0] = I2C_SGL_CMD ; // Ecriture direct. cmd[1] = 0x9E ; // Adr. i2c ds1621 bit r/w=0). cmd[2] = 0xEE ; // Donnée à écrire. write(usbi2c_port, cmd, 3); res = read(usbi2c_port, buff, 1) ; usleep(100000) ; //Lecture temp.: printf("Lecture Temp. Ds1621 ...\n") ; int k, count, slope, temp; // Ecriture sur ds1621, stop temperature conversion cmd[0] = I2C_SGL_CMD ; // Ecriture direct. cmd[1] = 0x9E ; // Adr. i2c ds1621 bit r/w=0). cmd[2] = 0x22 ; // Donnée à écrire. write(usbi2c_port, cmd, 3); res = read(usbi2c_port, buff, 1) ; /* Temperature reading (1 Celsius degree precision) */ cmd[0] = I2C_AD1_CMD ; // Lecture avec registre. cmd[1] = 0x9F ; // Adr. i2c ds1621 bit r/w=1). cmd[2] = 0xAA ; // Registre.. cmd[3] = 0x01 ; // Nb octet à lire. write(usbi2c_port, cmd, 4); res = read(usbi2c_port, buff, 1) ; temp = buff[0] ; /* Counter reading (fraction of degree) ) */ cmd[0] = I2C_AD1_CMD ; // Lecture avec registre. cmd[1] = 0x9F ; // Adr. i2c ds1621 bit r/w=1). cmd[2] = 0xA8 ; // Registre.. cmd[3] = 0x01 ; // Nb octet à lire. write(usbi2c_port, cmd, 4); res = read(usbi2c_port, buff, 1) ; count = buff[0] ; /* slope reading */ cmd[0] = I2C_AD1_CMD ; // Lecture avec registre. cmd[1] = 0x9F ; // Adr. i2c ds1621 bit r/w=1). cmd[2] = 0xA9 ; // Registre.. cmd[3] = 0x01 ; // Nb octet à lire. write(usbi2c_port, cmd, 4); res = read(usbi2c_port, buff, 1) ; slope = buff[0] ; if (slope !=0 ) { k = temp*100-25+(100*(slope-count))/slope; } // Affiche la température. printf("Temp DS1621: %2.1f°\n", (float)k/100) ; printf("Terminé\n"); /* Fermeture */ close(usbi2c_port); exit(0); }
Résultat avec le Ds1621
dan@vesta:usb-i2c$ ./ds1621_usb-i2c Lecture révision Firmware module USB-I2C ... Version firmware: 04 Init. Ds1621 ... Init. Ds1621 OK Lecture Temp. Ds1621 ... Temp DS1621: 23.1° Terminé



