//Příklad komunikace s bezkontaktním teplotním čidlem MLX90614ESF-AAA //Vzhledem k nutnosti použití nízkoúrovňového řízení sběrnice SMBus //nebylo možné použití Arduino knihovny Wire pro i2c/twi, ale bylo //nutné nadefinovat řízení sběrnice na úrovni registrů. //Použitý přístup je inspirovaný aplikační poznámkou pro komunikaci //Pololu Orangutan kitu s čidlem MLX90614ESF-AAA: //http://www.pololu.com/docs/pdf/0J33/mlx90614esf_smbus_orangutan.pdf //Předpokládáme pouze jedno čidlo na sběrnici, můžeme použít univerzální adresu //Bedřich Himmel 15.11.2009 //pošli START podmínku void smbus_start() { TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); } //zapiš byte, byte může představovat jak adresu, tak příkaz void smbus_write_byte(char data) { TWDR = data; TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); } //přečti byte, pošli ACK char smbus_read_byte() { TWCR = (1 << TWINT) | (1 << TWEA) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); return TWDR; } //přečti PEC byte, pošli NACK void smbus_receive_pec() { TWCR = (1 << TWINT) | (1 << TWEN); while (!(TWCR & (1 << TWINT))); } //pošli STOP podmínku void smbus_stop() { TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); } //Změří teplotu objektu, vrací ve stupních Celsia float smbus_read_temperature() { long low_byte, high_byte; smbus_start(); //zahájení komunikace smbus_write_byte(0); //posíláme adresu, 0 je univerzální adresa pro zápis smbus_write_byte(0x07); //čteme teplotu objektu, TObj1 (0x07) z RAM, změnou adresy můžeme číst další informace smbus_start(); //opakovaně posíláme start podmínku smbus_write_byte(1); //posíláme adresu, 1 je univerzální adresa pro čtení. low_byte = smbus_read_byte(); //čteme změřenou teplotu, která je uložena ve dvou bytech high_byte = smbus_read_byte(); smbus_receive_pec(); //čteme packet error code (PEC) smbus_stop(); //ukončení komunikace return ((2*(256*high_byte+low_byte))-27315)/100.00; //čidlo vrací teplotu v Kelvinech/100, přepočet na stupně Celsia } void setup() { Serial.begin(9600); // inicializace sériové linky na 9600 baudech DDRC = 0; // PORTC nastavíme jako vstup PORTC = (1 << PORTC4) | (1 << PORTC5); // povolení interních pull-up rezistorů pro SDA a SCL (PC4, PC5) TWSR = 0; //nastavení frekvence hodin (SCL) TWBR = 192; } void loop() { Serial.println(smbus_read_temperature()); delay(250); // čekáme 250 ms před dalším měřením }