HELP!! changing sketch so that it can read a temp from a MLX90614 and serial co

ok, so I have written a sketch that I will use to control when a valve opens and closes on a compressor. here it is

const double maxO = 65.0;                 //maximum oil temperature before solenoid remains closed for set time
const double maxD = 38.5;                 //maximum discharge temperature
const double mIncrease = 0.25;            //the maximum increase rate of the oil temperature before solenoid closes.
unsigned long time = 5;                   //the time between the 1st oil temp reading and the 2nd oil temp(seconds)
unsigned long timeClosed = 480000;        //how long the solenoid once open will remain open (milliseconds)
unsigned long timerClosed = 480000;       //how long the solenoid once open will remain open (milliseconds)

const int     oTempPin = A1;        //Analog pin used to read current oil temperature
int           oValue = 0;           //oil temp pin value. analogRead values go from 0 to 1023
double        oTemp;                //oil temperature
const int     dTempPin = A2;        //pin used to read current discharge temperature
int           dValue = 0;           //discharge temp pin value. analogRead values go from 0 to 1023
double        dTemp;                //discharge temperature
const int     solenoidPin = A3;     //pin used to open solenoid
int           oil1;                 //1st timed reading of oil temperature (0s)
int           oil2;                 //2nd timed reading of oil temperature (delay time set by "double time")
double        increase;             //=oil temp at time(milliseconds) divided by oil temp at 0seconds(degrees per second)
boolean       solenoid = 0;         //shows if the solenoid is closed or open;
unsigned long reset = 0;

void setup() {
  Serial.begin(9600);              //im not sure what this is needed for but i see it in 90% of the source code i look at

  //  pinMode(oTempPin, INPUT);    //sets the pin used to moniter the oil temperature to an input (not needed for analog inputs)
  //  pinMode(dTempPin, INPUT);    //sets the pin used to moniter the discharge temperature to an input
  pinMode(solenoidPin, OUTPUT);    //sets the solenoid open/close pin to an output

}

void loop() {
  unsigned long timerOpen = millis();             //this variable is used to start a timer when the valve opens.  
  unsigned long timer = millis();                 //this timer will be used to time the difference between the 1st oil temp (1oil) reading and the 2nd oil temp(2oil) reading                                                           
  int i = 0;                                      //i used this to stop my first reading of the oil temp from refreshing everytime loop() runs.
  int j = 0;                                      //the solenoid needs to open when the compressor is first started so i used this variable in an if statement below

  oValue = analogRead(oTempPin);                  //read the analog value for oil temperature
  oTemp = ((oValue*0.0049));                      //i dont know yet what voltage == what temperature
  if(i==0) {
    oil1 = oTemp;                                 //first reading of oil temp 
  }
  
  i=1;
  
  dValue = analogRead(dTempPin);                  //read the analog value for discharge temperature
  dTemp = ((dValue*0.0049));                      //i dont know yet what voltage == what temperature

  if(j == 0 & oTemp < maxO) {
    digitalWrite(solenoidPin,HIGH);               //when the program first starts running open solenoid if the oil temperature is below the max oil temperature.
    j++;
  }

  if(solenoid == 0 & timerClosed >= timeClosed) {   //im not sure if i need to check for the solenoid being closed as well as checking the timer
    digitalWrite(solenoidPin, HIGH);                //open the solenoid
    solenoid = 1;                                  
    timerClosed = 0;                                //resets the timer to 0 after the solenoid valve has been closed for the time set by the "timeClosed" variable.
  }

  if(timer >= time){                                     
    oil2 = oTemp;                                  //setting "2oil" = the oil temperature so i have a second reading to work out
    increase = oil2-oil1/(time/1000);              //how much the oil temperature is increasing per second
    i = 0;                                         //sets i back to 0 so that "1oil" will be set again to the oil temperature  
    timer = reset;                                 //resets timer so this if statment will set "2oil" when timer = time again
  }

  while(increase > mIncrease || oTemp > maxO) {       //if the increase in oil temperature is > the max increase then close the solenoid.
    digitalWrite(solenoidPin,LOW);                    //close solenoid    
    solenoid = 0;                                  
  }
  delay(5);                                       //im not sure if 5ms is long enough for the loop
}

i wrote this sketch with the idea in mind that the two temperatures (coming from oTempPin and dTempPin) would be readings from pressure transducers. That has changed and I will now be using a IR temperature sensor with this setup instead of a transducer for the oTempPin bildr Is it hot? Arduino + MLX90614 IR Thermometer - bildr
the code and library for using this with the arduino is on that link as well.
If someone with more experience than me could help me change my sketch so that oTempPin is replaced with the reading from the IR sensor.
also i dont know how much trouble it is to have both the temperatures relayed to my computer in real time using serial communications?

Any help or advice is appreciated. (massive understatement)

okay so I have edited the code myself and I think it should work fine. 30+ people read this and no replys so i assume i just suck at explaining things lol

#include <i2cmaster.h>

const double  maxO = 65.0;                //maximum oil temperature before solenoid remains closed for set time
const double  maxD = 38.5;                //maximum discharge temperature
const double  mIncrease = 0.25;           //the maximum increase rate of the oil temperature before solenoid closes.
unsigned long time = 5;                   //the time between the 1st oil temp reading and the 2nd oil temp(seconds)
unsigned long timeClosed = 480000;        //how long the solenoid once open will remain open (milliseconds)
unsigned long timerClosed = 480000;       //how long the solenoid once open will remain open (milliseconds)

int           oValue = 0;           //oil temp pin value. analogRead values go from 0 to 1023
double        oTemp;                //oil temperature
const int     dTempPin = 4;         //digital pin used to read current discharge temperature
int           dValue = 0;           //discharge temp pin value. analogRead values go from 0 to 1023
double        dTemp;                //discharge temperature
const int     solenoidPin = A3;     //pin used to open solenoid
int           oil1;                 //1st timed reading of oil temperature (0s)
int           oil2;                 //2nd timed reading of oil temperature (delay time set by "double time")
double        increase;             //=oil temp at time(milliseconds) divided by oil temp at 0seconds(degrees per second)
boolean       solenoid = 0;         //shows if the solenoid is closed or open;
unsigned long reset = 0;

//
	float  celcius;
	float  fahrenheit;
        double tempData;
        int    a=0;
//

void setup() {
	Serial.begin(9600); 
	Serial.println("Setup...");
  
	i2c_init(); //Initialise the i2c bus
	PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups
	
	//  pinMode(oTempPin, INPUT);    //sets the pin used to moniter the oil temperature to an input (not needed for analog inputs)
	//  pinMode(dTempPin, INPUT);    //sets the pin used to moniter the discharge temperature to an input
	pinMode(solenoidPin, OUTPUT);    //sets the solenoid open/close pin to an output

}

void loop() {        
	if(a=0){
                a++
		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 off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
		tempData = (((data_high & 0x007F) << 8) + data_low);
		tempData = (tempData * tempFactor)-0.01;

                celcius = tempData - 273.15;
	        fahrenheit = (celcius*1.8) + 32;

		Serial.print("Celcius: ");
		Serial.println(celcius);

		Serial.print("Fahrenheit: ");
		Serial.println(fahrenheit);

		millis(100);
                a=0;
	}
	
	unsigned long timerOpen = millis();               //this variable is used to start a timer when the valve opens.  
	unsigned long timer = millis();                   //this timer will be used to time the difference between the 1st oil temp (1oil) reading and the 2nd oil temp(2oil) reading                                                           
	int i = 0;                                        //i used this to stop my first reading of the oil temp from refreshing everytime loop() runs.
	int j = 0;                                        //the solenoid needs to open when the compressor is first started so i used this variable in an if statement below

	oTemp = tempData;
	
        if(i==0) {
	        oil1 = oTemp;                                 //first reading of oil temp 
	}
	i=1;
  
	dValue = digitalRead(dTempPin);                   //read the value for discharge temperature
	dTemp = ((dValue*0.0049));                        //dont know yet what voltage == what temperature

	if(j == 0 & oTemp < maxO) {
		analogWrite(solenoidPin,255);                 //when the program first starts running open solenoid if the oil temperature is below the max oil temperature.
		j++;
	}

	if(solenoid == 0 & timerClosed >= timeClosed) {   //im not sure if i need to check for the solenoid being closed as well as checking the timer
		analogWrite(solenoidPin, 255);                //open the solenoid
		solenoid = 1;                                  
		timerClosed = 0;                              //resets the timer to 0 after the solenoid valve has been closed for the time set by the "timeClosed" variable.
	}

	if(timer >= time){                                     
		oil2 = oTemp;                                 //setting "2oil" = the oil temperature so i have a second reading to work out
		increase = oil2-oil1/(time/1000);             //how much the oil temperature is increasing per second
		i = 0;                                        //sets i back to 0 so that "1oil" will be set again to the oil temperature  
		timer = reset;                                //resets timer so this if statment will set "2oil" when timer = time again
	}

	while(increase > mIncrease || oTemp > maxO) {     //if the increase in oil temperature is > the max increase then close the solenoid.
		analogWrite(solenoidPin,0);                   //close solenoid    
		solenoid = 0;                                  
	}
	delay(50);
}

i2cmaster.h (5.34 KB)

keywords.txt (610 Bytes)

twimaster.cpp (5.88 KB)

	if(a=0){

Will always be false.

    a++

Needs more semicolon.

  millis(100);

?

The compiler already told you the last two were incorrect, so why didn't you fix those before posting?

              a++
		int dev = 0x5A<<1;

Does that even compile?

int a;
a++;
if(a=0)
millis(1000);
a=0;

obviously missed out some code in the middle to show you what i have done but why would you guys be confused by that code? have i missed something? i have to put that part of the code inside an if statement with a millis timer because if it was on the same timer as the loop the ir sensor wouldn't have time to process the temp before the program asks for it again. and if i was to use delay then it would block the rest of the code instead of running simultaneously.

no it doesn't compile because it cant find any of the i2c functions even though they are all declared in the header file and .cpp file. i dont know why though - i used the exact same setup as you can find on here http://bildr.org/2011/02/mlx90614-arduino/ only with a modified version of the MLX90614.ino file.

i know what i did now. i was using millis like it was the same as delay… stupid mistake

int a = 0;

if(a=0){
                a++;
		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 off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
		tempData = (((data_high & 0x007F) << 8) + data_low);
		tempData = (tempData * tempFactor)-0.01;

                celcius = tempData - 273.15;
	        fahrenheit = (celcius*1.8) + 32;

		Serial.print("Celcius: ");
		Serial.println(celcius);

		Serial.print("Fahrenheit: ");
		Serial.println(fahrenheit);
                unsigned long t = 100;
		unsigned long T = millis();
                if (T==t){ 
                         a=0;}
	}

fixed but still; cant get i2c functions to work

why would you guys be confused by that code?

I don't think I'm confused.

if(a=0)
millis(1000);

I think you are.
"millis", like me, doesn't take any arguments.
"if (a=0)" is always false.

ok, so instead of a=0 it should be if a==o? i appreciate you taking the time to tell me where iv gone wrong but could you also help me solve the problems too? :slight_smile: and before I posted the first code I didn't compile it because i edited the program at work without the sdk so i did it on notepad++.

ok, so instead of a=0 it should be if a==o?

No, it should be if (a == 0)

but could you also help me solve the problems too?

We're working towards that, but until the conditional code actually gets executed, it is pointless speculating about whether or not it works.

ok with all the stupid mistakes out the way (hopefully), could anybody help me with the fact that when I try to compile the compiler tells me that all the i2c variables are not declared. I downloaded the program for the ir sensor from the website and just moved the downloaded file into the library’s folder. Im not at home just now so I cant try this but what if I move all the files within the downloaded folder out of that folder and into the library folder by themselves without their original sub folder?

Although I would have thought that the compiler would have pointed out that it cant find the included header file?

#include <i2cmaster.h>

Although I would have thought that the compiler would have pointed out that it cant find the included header file?

If you scrolled back far enough, it probably did.

#include <foobar.h>
void setup () {}
void loop () {}
sketch_aug20a.cpp:1:23: error: foobar.h: No such file or directory

AwesomeGauge:
Although I would have thought that the compiler would have pointed out that it cant find the included header file?

#include <i2cmaster.h>

For some obscure reason the IDE hides that warning message. Probably because it’s a warning.

sketch_aug20b.ino:1:27: warning: i2cmaster.h: No such file or directory

Turn on verbose compiling to see warnings.

well i get this

OperationWaterman.ino: In function 'void setup()':
OperationWaterman:33: error: 'i2c_init' was not declared in this scope
OperationWaterman.ino: In function 'void loop()':
OperationWaterman:52: error: 'I2C_WRITE' was not declared in this scope
OperationWaterman:52: error: 'i2c_start_wait' was not declared in this scope
OperationWaterman:53: error: 'i2c_write' was not declared in this scope
OperationWaterman:56: error: 'I2C_READ' was not declared in this scope
OperationWaterman:56: error: 'i2c_rep_start' was not declared in this scope
OperationWaterman:57: error: 'i2c_readAck' was not declared in this scope
OperationWaterman:59: error: 'i2c_readNak' was not declared in this scope
OperationWaterman:60: error: 'i2c_stop' was not declared in this scope

does it make a difference to the compiler if the header files path is like so
C:\Users\Administrator\Documents\Arduino\libraries\HeaderFile
or like
C:\Users\Administrator\Documents\Arduino\libraries\RandomFolder\HeaderFile

i have tried both and either way i get these errors but would be nice to eliminate that as another problem.

any idea why the compiler cant find the header file?

AwesomeGauge:
does it make a difference to the compiler if the header files path is like so
C:\Users\Administrator\Documents\Arduino\libraries\HeaderFile
or like
C:\Users\Administrator\Documents\Arduino\libraries\RandomFolder\HeaderFile

i have tried both and either way i get these errors but would be nice to eliminate that as another problem.

Neither of those.

It (they) should be in /libraries/i2cmaster/

Like this:

Then once you have done that close the IDE and open it again, for it to detect it.

ok i have it the way its supposed to be now but it still doesn't compile. Its giving me the same error. also i bought an annikken andee (Annikken Andee-An Easy Link between Arduino and Android. | Indiegogo) and when i try to upload one of the example sketches to it, the ide doesn't find the header file, the same as with the i2cmaster header file.

hmm. was getting annoyed so i deleted the arduino ide and re-installed it. now it works... a lot of wasted hours :frowning: and very strange but at least now it will compile.
Now i got it working i got a chance to study my code again and i have a quick question - all the code i have inside the "if (a == 0)" is there so that it can refresh the temperature at a different speed (slower) from the pressure transducer. will this even work? essentially i want to replicate having two loops running simultaneously.

the loop inside "if (a == 0)" i want this to run every time the "millis" timer reaches 100ms. and the rest of my code needs to refresh every 50ms.

void setup(){

int a = 0;
}
void loop(){

if (a == 0){
		a++;
		//run some code
		
		unsigned long t = 100;
		unsigned long T = millis();
		
        if (T => t){ 
               a=0;
		}
	}
	
//run some other code here

delay(50);

}

what happens if "delay(50)" happens to be counting down when the "millis()" timer reaches 100, does the "if(a == 0)" loop not run until the 50 is finished counting. if so can i use another "millis()" timer instead of "delay(50)"

Don't use delay, is the short answer.

well that answers that. :slight_smile: thanks

The late Peter Anderson has an example for the Arduino.

http://www.phanderson.com/picaxe/mlx90614.html
Scroll down past the Picaxe BASIC example to the Arduino ... It may require a little work for Arduino 1.0.5

Ray