-
1Hardware hookup
Wiring the MLX90614 with the arduino should be straightforward. Just follow the hookup image file provided in this project.
In a nutshell, power the sensor using the 3.3V rail, wire up SDA to analog input pin 4 and SCL to analog pin 5, and add 4.7kΩ pull-up resistors to both the data line and the clock line. The sensor datasheet advises the use of a .1uf capacitor between power and ground but I did not use it and the circuit works well without it.
-
2Software
Before anything else you need to have the ic2master library into your Arduino library folder for any of the code below to work. For convenience I've added the library to this project but you can go download it from where I got it or simply search for "ic2master library".
Once that is out of the way dive right into the code below. Be advised that initial parameters might have to be adjusted for it to work properly. That is something that is intrinsic to the technique due to the wide variations in blood flow and skull thickness from one person to another.
#include <i2cmaster.h> //Parameters int del_noise = 10; //take the average of 10 temp float led_sensitivity = 15000; //255...1000000 float sleep = 20; //read temp every 20ms int led_pin = 11; //LED Pin absolute int equi_step = 100; //1000ms between each equilibration temperature int equi_times = 20; //take 20 steps for equilibration that last *equi_step* float norm[10]; //has to be the same as del_noise float treshold = 10; ///treshold led analog intensity //Variables float avrg = 0; //do not change float celsius_old = 0;//do not change float celsius_old2 = 0;//do not change float analog = 0;//do not change //Functions float i2c(){ int dev = 0x5A<<1; int data_low = 0; int data_high = 0; int pec = 0; i2c_start_wait(dev+I2C_WRITE); i2c_write(0x07); // read i2c_rep_start(dev+I2C_READ); data_low = i2c_readAck(); //Read 1 byte and then send ack data_high = i2c_readAck(); //Read 1 byte and then send ack pec = i2c_readNak(); i2c_stop(); //This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the MLX90614) double tempData = 0x0000; // zero out the data int frac; // data past the decimal point // This masks the error bit of the high byte, then moves it left 8 bits and adds the low byte. tempData = (double)(((data_high & 0x007F) << 8) + data_low); tempData = (tempData * tempFactor)-0.01; float cels = tempData - 273.15; return cels; } void setup(){ pinMode(led_pin, OUTPUT); digitalWrite(led_pin, HIGH); Serial.begin(9600); Serial.println("Setup..."); digitalWrite(led_pin, LOW); i2c_init(); //Initialise the i2c bus PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups digitalWrite(led_pin, HIGH); digitalWrite(led_pin, LOW); digitalWrite(led_pin, HIGH); digitalWrite(led_pin, LOW); Serial.println("Equilibrate..."); for (int i = 0; i < equi_times; i++) { digitalWrite(led_pin, HIGH); delay(equi_step/2); digitalWrite(led_pin, LOW); delay(equi_step/2); } Serial.println("Norming..."); for (int i = 0; i < del_noise; i++) { norm[i] = i2c(); delay(sleep); } } int i = 0; void loop(){ i++; float percent = 0; float celsius = 0; for (int i = 0; i < (del_noise-1); i++) { norm[i] = norm[i+1]; celsius += norm[i]; } norm[del_noise-1]=i2c(); celsius += norm[del_noise-1]; celsius = celsius/del_noise; Serial.println("Celsius"); Serial.println(celsius); Serial.println(celsius_old); if ((celsius_old != 0) && (celsius_old2 != 0)) { percent = (celsius/celsius_old2)-1; analog = percent * led_sensitivity; } celsius_old = celsius; celsius_old2 = celsius_old; if (i == 10){ //write percent each 10th value to serial port Serial.println(percent); i = 0; } if (analog <= treshold) { analog = 0; } if (analog > 255) { analog = 255; } analogWrite(led_pin, analog); delay(sleep); }
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.
This is fantastic. My parts are arriving tomorrow. Thank you for posting this project.
Are you sure? yes | no