program for temperature reading with mlx90615

Dependencies:   crc8

Files at this revision

API Documentation at this revision

Comitter:
glsfacom
Date:
Wed Jul 15 18:20:00 2020 +0000
Child:
1:c0d057b08394
Commit message:
export to mbed studio;

Changed in this revision

Mlx90615.cpp Show annotated file Show diff for this revision Revisions of this file
Mlx90615.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
smbus.cpp Show annotated file Show diff for this revision Revisions of this file
smbus.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Mlx90615.cpp	Wed Jul 15 18:20:00 2020 +0000
@@ -0,0 +1,114 @@
+#include "Mlx90615.h"
+#include "smbus.h"
+
+I2C i2c(p28, p27);//I2C_SDA, I2C_SCL 
+void Mlx90615::wake()
+{
+	/*SCL = 0;
+	wait_ms(50);
+	SCL = 1;*/
+	MLX_VCC = 1;
+	wait_us(301*1000);//Waiting for valid data as datasheet says
+}
+
+unsigned int Mlx90615::sleep(){
+	MLX_VCC = 0;
+	return 1;
+}
+
+unsigned int Mlx90615::read(unsigned char memory, unsigned char address){
+	unsigned char crc, addr, status = 0;
+	unsigned int read = 0x0000;
+
+	addr = memory + address;
+	
+	i2c.start();
+
+	smbus_send_address(0x5B, WRITE);
+	if(!i2c.ACK) return 0;
+
+	smbus_send_byte(addr);
+	if(!i2c.ACK) return 0;
+
+	i2c.start();
+
+	smbus_send_address(0x5B, READ);
+	if(!i2c.ACK) return 0;
+
+	read = smbus_read_uint(&status, LITTLE_ENDIAN);	
+
+	crc = smbus_read_byte(&status);
+
+	smbus_stop();
+
+	return read;
+}
+
+unsigned int Mlx90615::read_temperature(){
+	unsigned int temp = read(RAM, 0x07);
+	while(temp == 0)
+	{
+		wait_us(5000);
+		temp = read(RAM, 0x07);
+	}
+	return temp;
+}
+
+/*float convert_to_celsius(unsigned int temperature){
+	return temperature * 0.02 - 273.15;
+}*/
+typedef unsigned char uint8_t;
+
+uint8_t gencrc(uint8_t *data, size_t len)
+{
+    uint8_t crc = 0xff;
+    size_t i, j;
+    for (i = 0; i < len; i++) {
+        crc ^= data[i];
+        for (j = 0; j < 8; j++) {
+            if ((crc & 0x80) != 0)
+                crc = (uint8_t)((crc << 1) ^ 0x31);
+            else
+                crc <<= 1;
+        }
+    }
+    return crc;
+}
+
+void Mlx90615::write(unsigned char address, unsigned int value){
+	unsigned char addr = EEPROM + address;
+	unsigned char bytes[4], crc, vh, vl;
+	vh = value >> 8;
+	vl = value;
+	bytes[0] = 0xB6;
+	bytes[1] = addr;
+	bytes[2] = vl;
+	bytes[3] = vh;
+	crc = gencrc(bytes, 4);
+
+	i2c.start();
+
+	smbus_send_address(0x5B, WRITE);
+
+	smbus_send_byte(addr);
+
+	smbus_send_byte(vl);
+
+	smbus_send_byte(vh);
+
+	smbus_send_byte(crc);
+
+	smbus_stop();
+}
+
+void Mlx90615::erase_eeprom_address(unsigned char address){
+	write(address, 0x0000);
+}
+
+void Mlx90615::set_emissivity(float e){
+	unsigned int emissivity;
+	emissivity = 16384 * e;
+	erase_eeprom_address(0x03);
+	wait_us(5*1000);
+	write(0x03, emissivity);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Mlx90615.h	Wed Jul 15 18:20:00 2020 +0000
@@ -0,0 +1,23 @@
+#include "mbed.h"
+
+#ifndef __MLX_h
+#define __MLX_h
+#define EEPROM 0x10
+#define RAM 0x20
+    
+extern DigitalOut MLX_VCC;
+
+class Mlx90615
+{
+public:
+    void wake();
+    unsigned int sleep();
+    unsigned int read_temperature();
+    void erase_eeprom_address(unsigned char address);
+    void set_emissivity(float e);
+private:
+    unsigned int read(unsigned char memory, unsigned char address);
+    void write(unsigned char address, unsigned int value);
+};
+
+#endif // __MLX_h
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jul 15 18:20:00 2020 +0000
@@ -0,0 +1,33 @@
+#include "mbed.h"
+#include "Mlx90615.h"
+
+
+DigitalOut MLX_VCC(p26,1); 
+DigitalInOut c(p30);                // Clock override pin
+Serial pc(USBTX, USBRX);
+
+float temp;
+
+void setup()
+{
+    //Force SMBUS comm
+    c = 0;                              // Setup override pin to pull clock low
+    c.input();                          // Make it input to start with...
+    c.mode(PullUp);                     // ...with pull up
+    c.output();                         // Override clock pin low
+    wait(0.00005);                      // Pause for treq 39ms
+    c.input();                          // Remove override...
+    c.mode(PullUp);                     // ...with pull up
+    wait(0.00005);                      // Pause again
+}
+
+int main(){
+    Mlx90615 mlx90615;
+    setup();
+    pc.printf("Hello World!\n");
+    while(true){
+      temp=mlx90615.read_temperature();
+      pc.printf("%4.2f Celcius\r\n", temp);
+      wait(1);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Jul 15 18:20:00 2020 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smbus.cpp	Wed Jul 15 18:20:00 2020 +0000
@@ -0,0 +1,91 @@
+#include "smbus.h"
+
+void smbus_start()
+{
+	i2c.start();
+}
+
+void smbus_stop()
+{
+	i2c.stop();
+}
+
+unsigned char smbus_send_byte(unsigned char byte)
+{
+	return i2c.write(byte);
+}
+
+unsigned char smbus_send_address(unsigned char address, unsigned char rw)
+{
+	unsigned char addr = address << 1;
+	addr = addr + rw;
+	
+	return smbus_send_byte(addr);
+}
+
+unsigned char smbus_read_byte(unsigned char *status)
+{
+	unsigned char byte;
+	
+	byte = i2c.read(i2c.ACK);
+
+
+	return byte;
+}
+
+unsigned int smbus_read_uint(unsigned char *status, unsigned char read_mode){
+
+	unsigned char byte0, byte1, low, high, sts = 0;
+	unsigned int value = 0x0000;
+	
+	
+	byte0 = smbus_read_byte(&sts);
+	*status = sts;
+
+	if(*status != 0x8B)
+	 return 0;
+
+	byte1 = smbus_read_byte(&sts);
+	*status = sts;
+	
+	if(read_mode == BIG_ENDIAN){
+		high = byte0;
+		low = byte1;
+	}
+	else{
+		high = byte1;
+		low = byte0;
+	}
+
+	value |= low;
+	value |= high<<8;
+
+	return value;
+
+}
+
+unsigned char smbus_write_uint(unsigned char read_mode, unsigned int value){
+
+	unsigned char lsb, msb, byte0, byte1, status;
+
+	lsb = value;
+	msb = value >> 8;
+
+	if(read_mode == BIG_ENDIAN){
+		byte0 = msb;
+		byte1 = lsb;
+	}
+	else{
+		byte1 = msb;
+		byte0 = lsb;
+	}
+
+	status = smbus_send_byte(byte0);
+	if(!i2c.ACK) return status;
+
+	status = smbus_send_byte(byte1);
+	return status;
+	
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smbus.h	Wed Jul 15 18:20:00 2020 +0000
@@ -0,0 +1,18 @@
+#define WRITE 0
+#define READ 1
+
+#define LITTLE_ENDIAN 0
+#define BIG_ENDIAN 1
+
+#include "mbed.h"
+
+extern I2C i2c;
+
+void smbus_start();
+void smbus_stop();
+unsigned char smbus_send_byte(unsigned char byte);
+unsigned char smbus_send_address(unsigned char address, unsigned char rw);
+unsigned char smbus_read_byte(unsigned char *status);
+unsigned int smbus_read_uint(unsigned char *status, unsigned char read_mode);
+unsigned char smbus_write_uint(unsigned char read_mode, unsigned int value);
+