TEMP sensor to control a MOTOR and display info on LCD

Hi, another newbie here!

I’m helping a friend with a university project (she’s a landscape architect, so I’m not exactly doing her homework). The more important bit is her design but it also needs to be ‘smart’, and I’m trying to do
the ‘smart’ bit. Hence I’m here crying for help…oh, the irony…
Anyway, I quite enjoy messing around with it, but the deadline is approaching.

Here’s what needs to happen:

There is a temperature sensor that needs to drive a stepper after reaching certain threshold.
Said threshold needs to be user adjustable (via buttons). Current temperature and current threshold need to be displayed on an LCD as well as state of motor - “going up” or “going down” for example.
Also, there should be a switch for when she needs to force the motor instead of wait for the sensor,
that needs another set of buttons and indication.

This is what would be really nice to have, however I’ll probably end up with a more simplified version of it.

Here’s where I’m at the moment:

I have the sensor (LM35) which turns on an LED after reaching a pre-set threshold.
Current temp and state are displayed on an LCD (Qapass 1602).

This is the code that works so far:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int inPin = 0; //sensor input
const int outPin = 8; // LED pin
const int treshold = 25; // temp treshold



void setup()
{
  lcd.begin(16, 2);
  Serial.begin(9600);
  pinMode(outPin, OUTPUT);
}

void loop()
{
  int value = analogRead(inPin);
  long celsius = (value * 500L) / 1024; //10mV per C
  Serial.print(celsius);
  Serial.print(" Temp, C: ");
  lcd.print(celsius);

  lcd.setCursor(0, 1);
  if (celsius > treshold) // if temp is higher than tresh elevate LED pin
  {
    digitalWrite(outPin, HIGH);
    lcd.write("sh*t is hot");
  }
  else
  {
    digitalWrite(outPin, LOW);
    lcd.write("it's cool");

  }
  
  delay(500); lcd.clear();

}

Here’s what I’m struggling with:

  1. I’m having troubles adjusting the threshold via button press. How do I set this up?
  2. Formatting the LCD, how to properly display all four bits of data, a link to tutorial would be ok.
  3. Servo isn’t working, it’s glitch-y, only moves a bit at the start, tried a few ways, gave up on it.
  4. Motor is going to be a pain, but I’m not there yet (but I tried a few simple schemes and it works).

So yeah, the question is a bit broad at the the moment,
I guess I just have to read a book perhaps and try lots of stuff until I figure how
everything comes together, but it would be nice if you could give me a few pointers!

Cheers,
Milko

  1. assign a variable to record button presses increment(+1) or decrement(-1) the variable each time the button is pressed.

  2. sorry I haven’t played with these yet.

  3. you need to use the servo library it comes with the IDE.

  4. motors are easy just need a relay maybe one that’s opto-isolated like this
    just make sure to get one that can handle your power requirements .

EDIT: OK well some motors are easy But I should of asked what type of motor you are dealing with and what you need it to do.

Thanks,
I'll look at it today, see if I can improve it and come up with more specific problems.

I found a chapter in one book on 'using switches'. They use digitalRead to track the state of the
input pins where buttons are connected.
Perhaps I could do 5V---[button]---[PIN]---GND ?

The motor is either a stepper or servo (I have both), it would be best if I could make the servo work,
I'll give it another go tonight.

Cheers,
Milko

Hi,

I managed to make the buttons work.
Perhaps not the most elegant solution but it works.

Here’s a Fritz of the wiring:
LED_ON_on_Temp_treshold_LCDv2-02_adjust_v2.jpg

And here’s the code, few typos and clearer commenting added:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int sensorPin = 0; //sensor input
const int ledPin = 8; // LED pin
int threshold = 25; // temp threshold
const int threshAddPin = 6; //increment threshold button
const int threshSubPin = 7; //decrement threshold button


void setup()
{
  lcd.begin(16, 2);
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(threshAddPin, INPUT);
  pinMode(threshSubPin, INPUT);
}

void loop()
{
  int threshAddState = digitalRead(threshAddPin);
  int threshSubState = digitalRead(threshSubPin);

  if (threshAddState == HIGH)
  {
    threshold++ ;
  }
  else {}

if (threshSubState == HIGH)
  {
    threshold-- ;
  }
  else {}

  Serial.println(threshold);


  int value = analogRead(sensorPin);
  long sensorTemp = (value * 500L) / 1024; //10mV per C
  Serial.print(sensorTemp);
  Serial.print(" Temp, C: ");
  lcd.print(sensorTemp);

  lcd.setCursor(0, 1);
  if (sensorTemp > threshold) // if temp is higher than thresh elevate LED pin
  {
    digitalWrite(ledPin, HIGH);
    lcd.write("sh*t is hot");
  }
  else
  {
    digitalWrite(ledPin, LOW);
    lcd.write("it's cool");

  }

  delay(500); lcd.clear();

}

Could someone help me display the Threshold and Temperature and State in a cleaner way, please?

Something like that would do:
25T : 22C
It’s cool.

Other improvements are welcome as well.
I’m onto the motor now.

Cheers,
Milko

This Tutorial answer's your questions plus a few you didn't ask.

LCD Tutorial

Also if statements do not require an else statement.
and delay is bad, you cant read your button or do anything else during a delay.
at a half second it's pretty safe to say you are spending more time delaying your sketch
then your are running it.

Blink without delay

.

Thanks for that, it was very helpful!
I’m slowly starting to get the idea, won’t have time to make it perfect - deadline is tomorrow :confused:

Here’s some progress:

#include <Servo.h>
#include <LiquidCrystal.h>

Servo servoM; //servo object
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int sensorPin = 0;                //sensor input
const int ledPin = 8;                   // LED pin

int ServoPos = 0;                       // servo start position

int threshold = 23;                     // temp threshold
const int threshAddPin = 6;             //increment threshold button
const int threshSubPin = 7;             //decrement threshold button

unsigned long lastServoCheck = 0;       //last time servo was updated
long servoSweepTime = 5000;             //servo sweep duration wait

unsigned long lastBtnCheck = 0;         //last time button was updated
long btnWaitTime = 500;                 //button wait duration


void setup()
{

  servoM.attach(9);
  servoM.write(0);
  lcd.begin(16, 2);
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(threshAddPin, INPUT);
  pinMode(threshSubPin, INPUT);
}

void loop()
{
  unsigned long currentServoCheck = millis();
  unsigned long currentBtnCheck = millis();


  int threshAddState = digitalRead(threshAddPin);
  int threshSubState = digitalRead(threshSubPin);

  if ((threshAddState == HIGH) && (currentBtnCheck - lastBtnCheck >= btnWaitTime))
  {
    threshold++ ;
    lastBtnCheck = currentBtnCheck; //update button check time
  }
  else {}
  if ((threshSubState == HIGH) && (currentBtnCheck - lastBtnCheck >= btnWaitTime))
  {
    threshold-- ;
    lastBtnCheck = currentBtnCheck; //update button check time
  }
  else {}

  Serial.println(threshold);
  Serial.print("C");

  int value = analogRead(sensorPin);
  long sensorTemp = (value * 500L) / 1024; //10mV per C
  Serial.print(sensorTemp);
  Serial.print("Thresh");

  lcd.setCursor(0, 0);
  lcd.print(sensorTemp);
  lcd.print(" C");
  lcd.setCursor(11, 0);
  lcd.print(threshold);
  lcd.print(" T");
  lcd.setCursor(0, 1);
  lcd.print("Lilly_Stoeva");
  lcd.setCursor(12, 1);


  if (sensorTemp > threshold) // if temp is higher than thresh elevate LED pin
  {
    digitalWrite(ledPin, HIGH);
    lcd.write("  >");
  }
  else
  {
    digitalWrite(ledPin, LOW);
    lcd.write("  <");
  }

  if ((sensorTemp > threshold) && (currentServoCheck - lastServoCheck >= servoSweepTime))  // if thresh is valid, servoTime is valid and last sweep is complete do sweep
  {
    lastServoCheck = currentServoCheck;
    servoM.write(161);
    delay(100);
  }

  if ((sensorTemp < threshold) && (currentServoCheck - lastServoCheck >= servoSweepTime))
  {
    lastServoCheck = currentServoCheck;
    servoM.write(0);
    delay(100);
  }

  lcd.clear();

}

Ah, just re read your last reply, forgot about the else’s…
Still needs cleaning up, credits etc.

I saw a nice breakdown of oop/states here , I’d love to do it that way, but I’m afraid it will take me too long to convert and understand.

Anyway, my biggest problem right now is that there’s lots if interference in the system,
the threshold jumps on its own or when I touch the board.
I’ve got 10K pull downs, should I double them or could the problem be somewhere else?
The thing is, sometimes it’s quite stable…any thoughts? Ignore that, someone wired the buttons wrong :blush:

Also, I’d like to add a delay in the LCD update, as the right side of it is very faint at the moment,
what’s the popper way of doing it, with millis again?

Here’s what it looks like soldered, not pretty at all:
I had to improvise due to lack of materials, lack of open shops on Sunday, hah, and box requirements:

LED_SERVO_ON_TEMP_LCD_THRESH_ADJ_v1-06.JPG

Buttons are wired wrong on the pic above ^

Also, I'd like to add a delay in the LCD update, as the right side of it is very faint at the moment,
what's the popper way of doing it, with millis again?

Write a function update_display() to print what you want to the lcd. Follow the example of "Blink without Delay" with interval = 1000 for an update every second. Unchanging elements of the display can be written once in setup.

if(currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;   
    update_display();
  }