Go Down

Topic: Incorporating ADXL345 to turn on heating coils and thermistor to control temp. (Read 250 times) previous topic - next topic

mzulen1

Hey everyone,

I am quite new to Arduino world. I have a project that requires Accelerometer ADXL345 and Nano Arduino to turn heating coils when the ADXL345 experiences abrupt stop or sudden stop due to a blockage of stationary object in X-direction. After it hits the stationary object and experiences abrupt stop, the acceleration gets to 3g really quick and return back to zero. I utilized boolean statement to allow the heating coils to be turned on for 300 seconds as soon as the condition becomes true or the adxl345 experiences 3g. I also use thermistor to measure the temperature of heating coils so that it will not get to higher than lower than 1.75 V which is approximately equal to 70 DEG Celcius). This is the code that I have written:

Code: [Select]

#include <Wire.h> //Wire library used for I2C communication

int ADXL345 = 0x53; //The ADXL345 sensor I2C address

int TempVolt = A7; // Assigning TempVolt to A7
int MOSFETout = 9; // Setting digital pin 9 (pin to mosfet to heating coils)
int sensorValue; //Delcaring our sensorValue Variable
float Voltage; //Declare our Voltage Variable
float Xa, Ya, Za; //Outputs at each 3-axis directions
boolean heaterTiming = false; //setup of boolean statement for turning on/off heating coils for certain period of time when ADXL345 reaches abrupt stop for a short time
unsigned long startTime;

int flag = 0;

void setup() {
  Serial.begin(9600); //Initiate serial communication for printing the result on the serial
  pinMode(TempVolt,INPUT); // Declare TempVolt an input
  pinMode(MOSFETout, OUTPUT);
  Wire.begin(); //Initiate the Wire library
  //These lines below is to set ADXL in measuring mode
  Wire.beginTransmission(ADXL345);
  Wire.write(0x2C);
  Wire.write(0x0A);
  Wire.endTransmission();
  Wire.beginTransmission(ADXL345); //Start communicating with the device
  Wire.write(0x2D); //Access or talk to POWER?CTL Register - 0x2D
  Wire.write(8); //Enable measurement //(8decimal -> 0000 1000 binary) Bit D3 High for measuring enable
  Wire.endTransmission();
  Wire.beginTransmission(ADXL345);
  Wire.write(0x31);// Select data format register to start range setting option
  Wire.write(0x12); //Full resolution, Range = +/- 8g
  Wire.endTransmission();
  delay(10);

  //This is to be activated when the ADXL345 needs to be calibrated
  //Off-set Calibration
  //X-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1E); //From datasheet
  Wire.write(0); //"1" is arbitrary, it depends on the error of the measurement
  //Let's say Xa = 240, then the error: 240-256 = -16, Xoffset = Round(27/4)= 4 LSB
  //Let's say Ya = 264, then the error: 264-256 = 8,Yoffset = -Round(8/4) = -2 LSB
  Wire.endTransmission();
  delay(10);
  //Y-axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x1F);
  Wire.write(2); //this comment has nothing to do with the offset in Yaxis
  Wire.endTransmission();
  delay(10);
  //Z-Axis
  Wire.beginTransmission(ADXL345);
  Wire.write(0x20);
  Wire.write(4);
  Wire.endTransmission();
  delay(10);
}

void loop() {
  //Read accelerometer data
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); //Start with register 0x32 (ACCEL_XA_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); //Read 6 registers total, each axis is stored in 2 registers
  Xa = ( Wire.read() | Wire.read() << 8); //X-axis value
  Xa = Xa / 64; //For a range of +/-8g, we need to divide the raw values by 64 according to the datasheet
  Ya = ( Wire.read() | Wire.read() << 8); //Y-axis value
  Ya = Ya / 64;
  Za = ( Wire.read() | Wire.read() << 8); //Z-axis value
  Za = Za / 64;

  Serial.print("Xa= ");
  Serial.println(Xa);
  Serial.print("   Ya= ");
  Serial.println(Ya);
  Serial.print("      Za= ");
  Serial.println(Za);

  //Activate heating coils when pig experiences sudden stop
  //Xa value is to be determined after accelerometer test
  if (Xa >= 3 && !heaterTiming) {
          digitalWrite(MOSFETout, HIGH);
          heaterTiming = true;
          startTime = millis();} //heating coils turn on for 60 s
  else if (heaterTiming && millis() - startTime >= 60000UL)
          {
            digitalWrite(MOSFETout, LOW);
            heaterTiming = false;
          }
         
  //Thermistor code takes place, reading temp. in terms of volt
  if ( Xa >= 3 || flag == 1){
  sensorValue = analogRead(TempVolt); // Read TempVolt and put value in readValue
  Voltage = (5./1023.)*sensorValue; // Calculating the real world voltage
  Serial.println(Voltage);        // Print out the real world voltage
 // delay(500); // Delay 500ms
   if(Voltage <= 1.75) {
    digitalWrite(MOSFETout, LOW); // V = 1.75 approximately is areound 70 DEG Celcius
    delay(250);
    }
   if(Voltage >= 1.77) {
    digitalWrite(MOSFETout, HIGH);
    delay(250);
    }
   if(Voltage == 1.55) {
    digitalWrite(MOSFETout,LOW);
    delay(60000);
    }
   if(Voltage == 1.45) {
    digitalWrite(MOSFETout, LOW);
    delay(1200000);
    }
  }
  flag = 1;
}


This is the part where the heating coils gets turned on after the acceleration gets to 3g:
Code: [Select]

//Activate heating coils when pig experiences sudden stop
  //Xa value is to be determined after accelerometer test
  if (Xa >= 3 && !heaterTiming) {
          digitalWrite(MOSFETout, HIGH);
          heaterTiming = true;
          startTime = millis();} //heating coils turn on for 300 s
  else if (heaterTiming && millis() - startTime >= 300000UL)
          {
            digitalWrite(MOSFETout, LOW);
            heaterTiming = false;
          }


This is the part where the thermistor is utiized to control the temperature within desired range:
Code: [Select]

  //Thermistor code takes place, reading temp. in terms of volt
  if ( Xa >= 3 || flag == 1){
  sensorValue = analogRead(TempVolt); // Read TempVolt and put value in readValue
  Voltage = (5./1023.)*sensorValue; // Calculating the real world voltage
  Serial.println(Voltage);        // Print out the real world voltage
 // delay(500); // Delay 500ms
   if(Voltage <= 1.75) {
    digitalWrite(MOSFETout, LOW); // V = 1.75 approximately is areound 70 DEG Celcius
    delay(250);
    }
   if(Voltage >= 1.77) {
    digitalWrite(MOSFETout, HIGH);
    delay(250);
    }
   if(Voltage == 1.55) {
    digitalWrite(MOSFETout, LOW);
    delay(60000);
    }
   if(Voltage == 1.45) {
    digitalWrite(MOSFETout, LOW);
    delay(1200000);
    }
  }
  flag = 1;


I have this code being uploaded to arduino nano. After the acceleration gets to 3g, the heating coils was on as the voltage measured by the thermistor kept dropping which means the temperature was increasing. However, the heating coils is not turned off after 300 s. the temperature kept increasing until it gets to 1.75 V where the heating coils was off and its turned on again at more than or equal to 1.77 V.
I have no clue how to incorporate these two part of the program so that the heating coils will be turned off after 300 s, but at the same time it will still also control the temperature of the heating coils at 1.75-.177 V.

groundFungus

If heaterTiming is true and millis() - startTime less than 300000, monitor temperature.  And get rid of those delays.

mzulen1

Hey Groundfungus,

Thank you for replying to my post. I don't understand what you mean by monitor temperature. Could you please elaborate it more to me?

groundFungus

I meant put the code that measures temperature (second posted code) in that new section of code.    Why are you using delays in that code?

mzulen1

That code that measures temperature has if statements as well. How do you put if statements inside an if statement?

groundFungus

Quote
How do you put if statements inside an if statement?
It is quite common to have if blocks inside of if blocks. 

Here is your code from the original post modified to illustrate what I meant.  I don't know if it will work the way that you want, but the code does compile.  I commented the delays cause they do not seem necessary and you still have not explained their use.  I also put the voltage measurement in a timer so that voltage is sampled every 20 milliseconds (instead of every time through loop).

Code: [Select]
if (Voltage == 1.55)
Using equality with float data type is a recipe for frustration.  As the comments in the code say, it is very very unlikely that they will ever be exactly on the number.

Code: [Select]

#include <Wire.h> //Wire library used for I2C communication

int ADXL345 = 0x53; //The ADXL345 sensor I2C address

int TempVolt = A7; // Assigning TempVolt to A7
int MOSFETout = 9; // Setting digital pin 9 (pin to mosfet to heating coils)
int sensorValue; //Delcaring our sensorValue Variable
float Voltage; //Declare our Voltage Variable
float Xa, Ya, Za; //Outputs at each 3-axis directions
boolean heaterTiming = false; //setup of boolean statement for turning on/off heating coils for certain period of time when ADXL345 reaches abrupt stop for a short time
unsigned long startTime;

int flag = 0;

void setup()
{
   Serial.begin(9600); //Initiate serial communication for printing the result on the serial
   pinMode(TempVolt, INPUT); // Declare TempVolt an input
   pinMode(MOSFETout, OUTPUT);
   Wire.begin(); //Initiate the Wire library
   //These lines below is to set ADXL in measuring mode
   Wire.beginTransmission(ADXL345);
   Wire.write(0x2C);
   Wire.write(0x0A);
   Wire.endTransmission();
   Wire.beginTransmission(ADXL345); //Start communicating with the device
   Wire.write(0x2D); //Access or talk to POWER?CTL Register - 0x2D
   Wire.write(8); //Enable measurement //(8decimal -> 0000 1000 binary) Bit D3 High for measuring enable
   Wire.endTransmission();
   Wire.beginTransmission(ADXL345);
   Wire.write(0x31);// Select data format register to start range setting option
   Wire.write(0x12); //Full resolution, Range = +/- 8g
   Wire.endTransmission();
   delay(10);

   //This is to be activated when the ADXL345 needs to be calibrated
   //Off-set Calibration
   //X-axis
   Wire.beginTransmission(ADXL345);
   Wire.write(0x1E); //From datasheet
   Wire.write(0); //"1" is arbitrary, it depends on the error of the measurement
   //Let's say Xa = 240, then the error: 240-256 = -16, Xoffset = Round(27/4)= 4 LSB
   //Let's say Ya = 264, then the error: 264-256 = 8,Yoffset = -Round(8/4) = -2 LSB
   Wire.endTransmission();
   delay(10);
   //Y-axis
   Wire.beginTransmission(ADXL345);
   Wire.write(0x1F);
   Wire.write(2); //this comment has nothing to do with the offset in Yaxis
   Wire.endTransmission();
   delay(10);
   //Z-Axis
   Wire.beginTransmission(ADXL345);
   Wire.write(0x20);
   Wire.write(4);
   Wire.endTransmission();
   delay(10);
}

void loop()
{
   //Read accelerometer data
   Wire.beginTransmission(ADXL345);
   Wire.write(0x32); //Start with register 0x32 (ACCEL_XA_H)
   Wire.endTransmission(false);
   Wire.requestFrom(ADXL345, 6, true); //Read 6 registers total, each axis is stored in 2 registers
   Xa = ( Wire.read() | Wire.read() << 8); //X-axis value
   Xa = Xa / 64; //For a range of +/-8g, we need to divide the raw values by 64 according to the datasheet
   Ya = ( Wire.read() | Wire.read() << 8); //Y-axis value
   Ya = Ya / 64;
   Za = ( Wire.read() | Wire.read() << 8); //Z-axis value
   Za = Za / 64;

   Serial.print("Xa= ");
   Serial.println(Xa);
   Serial.print("   Ya= ");
   Serial.println(Ya);
   Serial.print("      Za= ");
   Serial.println(Za);

   //Activate heating coils when pig experiences sudden stop
   //Xa value is to be determined after accelerometer test
   if (Xa >= 3 && !heaterTiming)
   {
      digitalWrite(MOSFETout, HIGH);
      heaterTiming = true;
      startTime = millis();
   } //heating coils turn on for 60 s
   else if (heaterTiming && millis() - startTime >= 60000UL)
   {
      digitalWrite(MOSFETout, LOW);
      heaterTiming = false;
   }

   //Thermistor code takes place, reading temp. in terms of volt
   //   if ( Xa >= 3 || flag == 1)

   // added this timer so that temperature is measured during the 60 seconds
   else if (millis() - startTime < 60000UL && heaterTiming == true)
   {
      static unsigned long voltTimer = 0;
      unsigned long voltInterval = 20;  // measure voltage every 20 milliseconds
      if (millis() - voltTimer >= voltInterval)
      {
         voltTimer = millis();
         sensorValue = analogRead(TempVolt); // Read TempVolt and put value in readValue
         Voltage = (5. / 1023.) * sensorValue; // Calculating the real world voltage
         Serial.println(Voltage);        // Print out the real world voltage
         // delay(500); // Delay 500ms
         if (Voltage <= 1.75)
         {
            digitalWrite(MOSFETout, LOW); // V = 1.75 approximately is areound 70 DEG Celcius
            //delay(250);
         }
         if (Voltage >= 1.77)
         {
            digitalWrite(MOSFETout, HIGH);
            //delay(250);
         }
         if (Voltage == 1.55)  // very very unlikely to ever be exactly 1.55
         {
            digitalWrite(MOSFETout, LOW);
            //delay(60000);
         }
         if (Voltage == 1.45)  // very very unlikely to ever be exactly 1.45
         {
            digitalWrite(MOSFETout, LOW);
            //delay(1200000);
         }
      }
      flag = 1;
   }
}

mzulen1

HeyGroundFungus,

I am going to test the code as we speak. I'll let you know the result.

Thank you for helping me out with the code.

Go Up