(SOLVED) Problem with temperature controlled motor

Hello, I'm having trouble controlling a motor with if() statements from thermocouple output. Thermocouple takes a reading and is supposed to spin opposite directions based on high or low temperature. If temp is within a range the motor is off, spin is opposite depending on whether temp is above max or below minimum.

For some reason, the motor always spins, and always at max speed. I have changed speed and temp conditions and it doesn't affect whether it runs or not. I added Serial.print() to see if condition was being tested and it appears to work, but motor still doesn't behave as expected:

MAX6675 warmup
#1= 21.00
Butterzone - OFF
#1= 20.75
Butterzone - OFF
#1= 29.25
Hot - CW
#1= 28.75
Hot - CW
#1= 28.00
Hot - CW
#1= 27.25
Butterzone - OFF
/* Functions defined:
    setupArdumoto() -- Setup the Ardumoto Shield pins
    driveArdumoto([motor], [direction], [speed]) -- Drive [motor] 
      (0 for A, 1 for B) in [direction] (0 or 1) at a [speed]
      between 0 and 255. It will spin until told to stop.
    stopArdumoto([motor]) -- Stop driving [motor] (0 or 1).

  setupArdumoto() is called in the setup().
*/

//Thermocouple reads temperature and reports it to LCD
//and serial

#include "max6675.h" //thermocouple library
#include "Wire.h"  //LCD screen library
//#include "LiquidCrystal.h"  //LCD screen library
#include "Adafruit_LiquidCrystal.h"
#include <SD.h>  // SD card library

int DO = 22;
int CS = 23;
int CLK = 24;

MAX6675 thermocouple(CLK, CS, DO);
int CS1 = 3;

float tempA = 0;
float tempA1 = 0;
float tempMin = 20;
float tempMax = 28;

int serialTab = 0;

//identify LCD screen address
Adafruit_LiquidCrystal lcd(0);

// make a degree symbol
uint8_t degree[8]  = {140,146,146,140,128,128,128,128};

// Clockwise and counter-clockwise definitions.
// Depending on how you wired your motors, you may need to swap.
#define CW  0
#define CCW 1

// Motor definitions to make life easier:
#define MOTOR_A 0
#define MOTOR_B 1

// Pin Assignments //
// Don't change these! These pins are statically defined by shield layout
const byte PWMA = 3;  // PWM control (speed) for motor A
const byte PWMB = 11; // PWM control (speed) for motor B
const byte DIRA = 12; // Direction control for motor A
const byte DIRB = 13; // Direction control for motor B

void setup()
{
  setupArdumoto(); // Set all pins as outputs

  //start computer communications  
  Serial.begin(9600);

  // start thermocouple communications
  pinMode(CS1, OUTPUT); 

  Serial.println("MAX6675 warmup\n");

  digitalWrite(CS1, HIGH);
  delay(500);
  digitalWrite(CS1, LOW);
  delay(500);

// get LCD screen going 
  lcd.begin(16, 2);
  lcd.createChar(0, degree);
  
// Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("please wait");
  delay (1000);
  lcd.setCursor(0, 1);
  lcd.print("checking things");
  delay (1000);
  lcd.clear();
}

void loop()
{
  // read temperatures  
  digitalWrite(CS1, HIGH);
  // read temp delay in ms
  delay(2000);

  tempA = thermocouple.readCelsius();
    digitalWrite(CS1, LOW);

  tempA1 = tempA - 3.5;

  // print results to computer  
   Serial.print("#1= "); 
   Serial.print(tempA1);

  // results in single column
   Serial.print("\n");
   
  // print results to LCD screen  
  lcd.setCursor(0, 0);
  lcd.print("Temp = ");
  lcd.print(tempA1);
  lcd.print("C");

  //run motors based on temp condition
  if(tempA1 <= tempMin)
  {
    driveArdumoto(MOTOR_A, CCW, 75); // Set motor A to CCW
    Serial.print("Cold - CCW");
    Serial.print("\n");
  }
  if(tempA1 >= tempMax)
  {
    driveArdumoto(MOTOR_A, CW, 75);  // Set motor A to CW
    Serial.print("Hot - CW");
    Serial.print("\n");
  }
  if((tempA1 > tempMin) && (tempA1 < tempMax))
  {
    stopArdumoto(MOTOR_A);  // STOP motor A 
    Serial.print("Butterzone - OFF");
    Serial.print("\n");
  }
  
/*
  // Drive motor B (and only motor B) at various speeds, then stop.
  driveArdumoto(MOTOR_B, CCW, 255); // Set motor B to CCW at max
  delay(1000);  // Motor B will spin as set for 1 second
  driveArdumoto(MOTOR_B, CW, 127);  // Set motor B to CW at half
  delay(1000);  // Motor B will keep trucking for 1 second
  stopArdumoto(MOTOR_B);  // STOP motor B 

  // Now spin both!
  driveArdumoto(MOTOR_A, CW, 255);  // Motor A at max speed.
  driveArdumoto(MOTOR_B, CW, 255);  // Motor B at max speed.
  delay(1000);  // Drive forward for a second
  // Now go backwards at half that speed:
  driveArdumoto(MOTOR_A, CCW, 127);  // Motor A at max speed.
  driveArdumoto(MOTOR_B, CCW, 127);  // Motor B at max speed.
*/
}

// driveArdumoto drives 'motor' in 'dir' direction at 'spd' speed
void driveArdumoto(byte motor, byte dir, byte spd)
{
  if (motor == MOTOR_A)
  {
    digitalWrite(DIRA, dir);
    analogWrite(PWMA, spd);
  }
  else if (motor == MOTOR_B)
  {
    digitalWrite(DIRB, dir);
    analogWrite(PWMB, spd);
  }  
}

// stopArdumoto makes a motor stop
void stopArdumoto(byte motor)
{
  driveArdumoto(motor, 0, 0);
}

// setupArdumoto initialize all pins
void setupArdumoto()
{
  // All pins should be setup as outputs:
  pinMode(PWMA, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(DIRA, OUTPUT);
  pinMode(DIRB, OUTPUT);

  // Initialize all pins as low:
  digitalWrite(PWMA, LOW);
  digitalWrite(PWMB, LOW);
  digitalWrite(DIRA, LOW);
  digitalWrite(DIRB, LOW);
}

ThatTrashPanda:
Hello, I'm having trouble controlling a motor with if() statements from thermocouple output. Thermocouple takes a reading and is supposed to spin opposite directions based on high or low temperature. If temp is within a range the motor is off, spin is opposite depending on whether temp is above max or below minimum.

For some reason, the motor always spins, and always at max speed. I have changed speed and temp conditions and it doesn't affect whether it runs or not. I added Serial.print() to see if condition was being tested and it appears to work, but motor still doesn't behave as expected:

MAX6675 warmup

#1= 21.00
Butterzone - OFF
#1= 20.75
Butterzone - OFF
#1= 29.25
Hot - CW
#1= 28.75
Hot - CW
#1= 28.00
Hot - CW
#1= 27.25
Butterzone - OFF






/* Functions defined:
   setupArdumoto() -- Setup the Ardumoto Shield pins
   driveArdumoto([motor], [direction], [speed]) -- Drive [motor]
     (0 for A, 1 for B) in [direction] (0 or 1) at a [speed]
     between 0 and 255. It will spin until told to stop.
   stopArdumoto([motor]) -- Stop driving [motor] (0 or 1).

setupArdumoto() is called in the setup().
*/

//Thermocouple reads temperature and reports it to LCD
//and serial

#include "max6675.h" //thermocouple library
#include "Wire.h"  //LCD screen library
//#include "LiquidCrystal.h"  //LCD screen library
#include "Adafruit_LiquidCrystal.h"
#include <SD.h>  // SD card library

int DO = 22;
int CS = 23;
int CLK = 24;

MAX6675 thermocouple(CLK, CS, DO);
int CS1 = 3;

float tempA = 0;
float tempA1 = 0;
float tempMin = 20;
float tempMax = 28;

int serialTab = 0;

//identify LCD screen address
Adafruit_LiquidCrystal lcd(0);

// make a degree symbol
uint8_t degree[8]  = {140,146,146,140,128,128,128,128};

// Clockwise and counter-clockwise definitions.
// Depending on how you wired your motors, you may need to swap.
#define CW  0
#define CCW 1

// Motor definitions to make life easier:
#define MOTOR_A 0
#define MOTOR_B 1

// Pin Assignments //
// Don't change these! These pins are statically defined by shield layout
const byte PWMA = 3;  // PWM control (speed) for motor A
const byte PWMB = 11; // PWM control (speed) for motor B
const byte DIRA = 12; // Direction control for motor A
const byte DIRB = 13; // Direction control for motor B

void setup()
{
 setupArdumoto(); // Set all pins as outputs

//start computer communications  
 Serial.begin(9600);

// start thermocouple communications
 pinMode(CS1, OUTPUT);

Serial.println("MAX6675 warmup\n");

digitalWrite(CS1, HIGH);
 delay(500);
 digitalWrite(CS1, LOW);
 delay(500);

// get LCD screen going
 lcd.begin(16, 2);
 lcd.createChar(0, degree);
 
// Print a message to the LCD.
 lcd.setCursor(0, 0);
 lcd.print("please wait");
 delay (1000);
 lcd.setCursor(0, 1);
 lcd.print("checking things");
 delay (1000);
 lcd.clear();
}

void loop()
{
 // read temperatures  
 digitalWrite(CS1, HIGH);
 // read temp delay in ms
 delay(2000);

tempA = thermocouple.readCelsius();
   digitalWrite(CS1, LOW);

tempA1 = tempA - 3.5;

// print results to computer  
  Serial.print("#1= ");
  Serial.print(tempA1);

// results in single column
  Serial.print("\n");
 
 // print results to LCD screen  
 lcd.setCursor(0, 0);
 lcd.print("Temp = ");
 lcd.print(tempA1);
 lcd.print("C");

//run motors based on temp condition
 if(tempA1 <= tempMin)
 {
   driveArdumoto(MOTOR_A, CCW, 75); // Set motor A to CCW
   Serial.print("Cold - CCW");
   Serial.print("\n");
 }
 if(tempA1 >= tempMax)
 {
   driveArdumoto(MOTOR_A, CW, 75);  // Set motor A to CW
   Serial.print("Hot - CW");
   Serial.print("\n");
 }
 if((tempA1 > tempMin) && (tempA1 < tempMax))
 {
   stopArdumoto(MOTOR_A);  // STOP motor A
   Serial.print("Butterzone - OFF");
   Serial.print("\n");
 }
 
/*
 // Drive motor B (and only motor B) at various speeds, then stop.
 driveArdumoto(MOTOR_B, CCW, 255); // Set motor B to CCW at max
 delay(1000);  // Motor B will spin as set for 1 second
 driveArdumoto(MOTOR_B, CW, 127);  // Set motor B to CW at half
 delay(1000);  // Motor B will keep trucking for 1 second
 stopArdumoto(MOTOR_B);  // STOP motor B

// Now spin both!
 driveArdumoto(MOTOR_A, CW, 255);  // Motor A at max speed.
 driveArdumoto(MOTOR_B, CW, 255);  // Motor B at max speed.
 delay(1000);  // Drive forward for a second
 // Now go backwards at half that speed:
 driveArdumoto(MOTOR_A, CCW, 127);  // Motor A at max speed.
 driveArdumoto(MOTOR_B, CCW, 127);  // Motor B at max speed.
*/
}

// driveArdumoto drives 'motor' in 'dir' direction at 'spd' speed
void driveArdumoto(byte motor, byte dir, byte spd)
{
 if (motor == MOTOR_A)
 {
   digitalWrite(DIRA, dir);
   analogWrite(PWMA, spd);
 }
 else if (motor == MOTOR_B)
 {
   digitalWrite(DIRB, dir);
   analogWrite(PWMB, spd);
 }  
}

// stopArdumoto makes a motor stop
void stopArdumoto(byte motor)
{
 driveArdumoto(motor, 0, 0);
}

// setupArdumoto initialize all pins
void setupArdumoto()
{
 // All pins should be setup as outputs:
 pinMode(PWMA, OUTPUT);
 pinMode(PWMB, OUTPUT);
 pinMode(DIRA, OUTPUT);
 pinMode(DIRB, OUTPUT);

// Initialize all pins as low:
 digitalWrite(PWMA, LOW);
 digitalWrite(PWMB, LOW);
 digitalWrite(DIRA, LOW);
 digitalWrite(DIRB, LOW);
}

Based on your definitions (ifs), the output is correct.

If the motor is not operating as expected I would concentrate on testing your driveMotor(), stopMotor(), and your setupMotor().

Chuck.
p.s.
I would use a little different IF structure:

if(temp>hotLimit){ //Start motor for Cooling Operation
  }
else if(temp<coldLimit){ // start motor for Heating Operation
  }
else {// shutdown motor, temp is between Hot and Cold.
  }

Hi,
Welcome to the forum.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
(Please no Fritzy diagrams)

Thanks.. Tom.. :slight_smile:

When I use the code that runs the motors in the example the speed and direction control work fine. When I change the speed number, it behaves as expected:

void loop() 
{
  // Drive motor A (and only motor A) at various speeds, then stop.
  driveArdumoto(MOTOR_A, CCW, 255); // Set motor A to CCW at max
  delay(5000);  // Motor A will spin as set for 1 second
  driveArdumoto(MOTOR_A, CW, 255);  // Set motor A to CW at half
  delay(5000);  // Motor A will keep trucking for 1 second 
  stopArdumoto(MOTOR_A);  // STOP motor A 

}

...but when I change to the if() statements based on temp reading it behaves as I described above.

Here's my circuit - pretty simple:

When I use the code that runs the motors in the example the speed and direction control work fine. When I change the speed number, it behaves as expected:

void loop() 
{
  // Drive motor A (and only motor A) at various speeds, then stop.
  driveArdumoto(MOTOR_A, CCW, 255); // Set motor A to CCW at max
  delay(5000);  // Motor A will spin as set for 1 second
  driveArdumoto(MOTOR_A, CW, 255);  // Set motor A to CW at half
  delay(5000);  // Motor A will keep trucking for 1 second 
  stopArdumoto(MOTOR_A);  // STOP motor A 

}

...but when I change to the if() statements based on temp reading it behaves as I described above.

Here's my circuit - pretty simple:

uploading images

I figured it out.

CS1 for the thermocouple is set to pin 3. Motor speed is hardwired to pin 3. When the thermocouple takes a reading sets pin 3 to HIGH right before the if() statements.

The code is copied from a previous build with just a handful of thermocouples and no motor shield. CS1 wasn't even correctly assigned (to pin 23) and my thermocouple was still working correctly...changed this value to 23 and the motor shield now has pin 3 back.

Woo!