Arduino Code Assistance

Can someone please edit this entire code so that the heater my micro arduino is connected to will turn on for 5 seconds when the button is pressed and turn off again when you press the button? Can you also please ensure the thermistor will read the temperature of the heater and control it so it does not go above 100 deg C? Thank you!!!

// Proof of Concept Heating Mode

#include <Bounce2.h>
#include <PID_v1.h>

// I/O Definition

const int THERMISTOR_PIN = A1;       Does there need to be a thermistor implemented???

const int HEAT_PIN = 7;

const int BUTTON_PIN = 8;

//State variables
enum modes {
  HEAT,
  OFF
};
enum modes currentMode = OFF;

//Global vars
const int TEMP_MAX = 100; //Celsius   What max temp do we want the heater to be????
const int RANGE = 1; //Celsius

const int DELAY = 500; //ms - for LED flash
unsigned long pulseStart = 0; //ms-timer for LED flash

unsigned long tempPulseStart = 0; //ms timer for ADC
const int ADC_DELAY = 50; //ms
double rollingAvgTemp = 25.0; //Celsius

double pidHotOutput = 0; //global for PID output (hot mode)
double pidHotTarget = double(TEMP_MAX); //Celsius
PID pidHotController(&rollingAvgTemp, &pidHotOutput, &pidHotTarget,2000, 20, 0, DIRECT);

//Debouncer setup
Bounce debouncer = Bounce();

void setup(){
  //set up code here to run once
  pinMode(HEAT_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLDOWN);

  analogReference(DEFAULT); // use default 5V ref

  debouncer.attach(BUTTON_PIN, INPUT_PULLDOWN);
  debouncer.interval(50);                                                          // why 50???

  pidHotController.SetOutputLimits(0, pidWindow); //PID outputs how long we should be on this cycle

  Serial.begin(9600);                                                        // why 9600???
}

void loop () {
  //main code here to run repeatadly 

  debouncer.update();

  if(debouncer.fell() ){
    isRunning = !isRunning;
    Serial.println("mode toggle");
  }

  if (isRunning){
    run_system();
  }
else {
  digitalWrite(HEAT_PIN, LOW); // heating element off
}

delay(50);

}

/////////////////////////////////////////////////////////////////////////
// run_system
//
// run the control system 
// basic on/off control system with hysteresis 
////////////////////////////////////////////////////////////////////////
void run_system(){
  
  read_thermistor();

  //very crude two-level hi-low-off control
  if (rollingAvgTemp > TEMP_MAX){
    analogWrite(HEAT_PIN, 0); //off if exceeds set temperature
    Serial.println("Power: 0");
  }
   else if ((rollingAvgTemp >= (TEMP_MAX - RANGE)) & (rollingAvgTemp <= TEMP_MAX)){
    analogWrite(HEAT_PIN, 25); //10% power when in the set temp range
    Serial.println("Power: 25");
  }
  else if (rollingAvgTemp < (TEMP_MAX-RANGE)){
    analogWrite(HEAT_PIN, 255); //full power
    Serial.println("Power: 255");
  }
  else {
    analogWrite(HEAT_PIN, 0); //catch all - turn off if in weird state
  }

  Serial.print(" Temp: ");
  Serial.print(rollingAvgTemp);
  Serial.print("\n");
}


///////////////////////////////////////////////////////////////////////////
// read_thermistor
//
// Reads the value of the thermistor and converts to degrees C
// ADC reads are rate limited using non-blocking timers
// Returns a running average to minimize noise
//////////////////////////////////////////////////////////////////////////
void read_thermistor(){
  // ____________ (MF52C1103F3380) Thermistor 
  static const float T0 = 298.15; //T0 in K (per datasheet)
  static const float B = 3380.0; //B in K (per datasheet)
  static const float R0 = 10000.0; //Thermistor resistance at 25C
  static const float R1 = 9807.00; //R used in voltage divider
  float temp_C = 0.0;
  float temp_C_avg = 0.0;

  if((millis() - tempPulseStart) > ADC_DELAY){
    //calculate temperature reading
    float raw_value = analogRead(THERMISTOR_PIN);
    float resistance = ((R1 * (1023.00 - raw_value)) / raw_value);
    
  }
}

Please post your code using code tags

2 Likes

What part isn't finished?

1 Like

I need help in writing code for the heater to be on for a certain amount of time, 5 seconds. I would also like if someone could proofread the code so that it will work.

You need to post your cade using code tags

2 Likes

You will get faster and better help if you post all your code as requested by the forum guidelines.
Please go back and fix your original post.

1 Like

Sorry I cannot read the code, or follow your shcematic. Read the forum guidelines and post your code accordingly to them. When you entered your code there is a butten marked , click that pand post inbetween the lines.

Is this a school project?

1 Like

The number one test is to use the code, let it run. Note what differs from the wanted action. Dry reading code is a very time consuming task, not offered by every helper.

1 Like

This function does not "return[] a running average".

// read_thermistor
//
// Reads the value of the thermistor and converts to degrees C
// ADC reads are rate limited using non-blocking timers
// Returns a running average to minimize noise
//////////////////////////////////////////////////////////////////////////
void read_thermistor(){

HTH

a7

Hi, @m11s
Welcome to the forum.

This link will show you how to post code so it appears in its own scrolling window.
TIP. Before posting your code press [ CTRL ] [ T ], it will auto format your code with indentations at appropriate statements.

What model Arduino are you using?

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Not a Fritzy copy and paste!!

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

2 Likes

What Arduino board are you compiling for?

Your sketch as published does not compile. You have no PID library, so there's no chance the PID stuff compiles.

You use INPUT_PULLDOWN as a mode. This must be for a board I am not using to test the code.

As I pointed out, the read_thermistor() function does not.


I replaced your constants with the numbers they are set to.

This

  if (rollingAvgTemp > 100){
    analogWrite(HEAT_PIN, 0); //off if exceeds set temperature
    Serial.println("Power: 0");
  }
   else if ((rollingAvgTemp >= 99) & (rollingAvgTemp <= 100)){
    analogWrite(HEAT_PIN, 25); //10% power when in the set temp range
    Serial.println("Power: 25");
  }
  else if (rollingAvgTemp < 99){
    analogWrite(HEAT_PIN, 255); //full power
    Serial.println("Power: 255");
  }
  else {
    analogWrite(HEAT_PIN, 0); //catch all - turn off if in weird state
  }

Is that correct? Using a proxy for the average temperature, that logic works fine. I just wanna make sure you are talking about 25 percent heating for the single degree between 99 and 101.


Printing is good, essemntial even. But you can make better printing, viz:
  if (debouncer.fell()) {
    isRunning = !isRunning;
    Serial.print("mode toggle to ");
    Serial.println(isRunning ? "RUNNING" : "NOT RUNNING");
  }

You did not declare isRunning, BTW. I assume it is of type bool or unsigned char. Either does.

Also, just noticed, you want &&, logical, not &, bitwise and. In this case it makes no difference, but something to pay attention to for when it might.


  Serial.begin(9600);                                                        // why 9600???

Because your grandfather is helping? You can use 115200 and move closer to the 21st century. If you mean where do those magic numbers come from, there are standard baud rates that show up. That's one of them. It's twice 4800. which is twice 2400. Which is twice 1200. Which is four times 300, which was once fast. :expressionless:

a7

1 Like

tempPulseStart will never renewed.
every results from read_thermistor() is not used and will be lost.
run_system() used no PID adjustment.
no PID library included.
Debounce lib for one single button press?
enum modes used nowhere.
double rollingAvgTemp = 25.0; //Celsius really? eight bytes for storing of '25'?

the sketch is a mess, dump it and make one from scratch.

The temperature reading function seems to have started a more ambitious life, to end up as

void read_thermistor(){
  // ____________ (MF52C1103F3380) Thermistor 

  static const float R1 = 9807.00; //R used in voltage divider
  
  if((millis() - tempPulseStart) > ADC_DELAY) {
    //calculate temperature reading
    float raw_value = analogRead(THERMISTOR_PIN);
    float resistance = ((R1 * (1023.00 - raw_value)) / raw_value);    
  }
}

If you want a smoothed but representative measurement, you could use a low pass filter, viz:

  // ____________ (MF52C1103F3380) Thermistor 

float read_thermistor()
{
  static float averageTemperature;

// I don't know why you don't just read the temp every time?
  if ((millis() - tempPulseStart) < ADC_DELAY) return averageTemperature;

// do whatever it takes to get the current thermistor temperature reading:

  float newReading = whatever the equation and analogRead comes up with... 

// now use the new reading to adjust the average reading, feed it to the low pass filter:

  averageTemperature = 0.9 * averageTemperature + 0.1 * newReading;

// finally fulfill the promise you made to return that value to the caller:

  return averageTemperature;
}

I cannot test this from under the umbrella here. The idea of the low pass filter or "leaky integrator" is to make a new value out of most of the old value, 90 percent here, with a bit of the new reading mixed in, 10 percent. 0.9 and 0.1.

You can use any numbers that add up to 1.0 in the equation. You will move faster to a new value by being more aggressive, say 0.70 and 0.30 and it will get there faster, but will also be potentially less smooth.

A way to decide is to run your thermistor with the right equation and constants, and simply watch the printed values that read_thermistor() calculates. And maybe now that function needs a different name, as it is not returning the reading, it is returning the filter average reading since time 0.

HTH can't miss an opportunity to talk hysteresis and leaky integration.

a7

Did you mean to start another thread?
https://forum.arduino.cc/t/connecting-arduino-to-correctly-work-with-heater/1158876/2

Can someone please rewrite this code so that the button on the breadboard connected to the micro Arduino can be pressed and the code turns a heater on for a specific amount of time, 5 seconds, and then either turns off or the button is pressed and it turns off?

// Proof of Concept Heating Mode

#include <Bounce2.h>
#include <PID_v1.h>

// I/O Definition

const int THERMISTOR_PIN = A1;       Does there need to be a thermistor implemented???

const int HEAT_PIN = 7;

const int BUTTON_PIN = 8;

//State variables
enum modes {
  HEAT,
  OFF
};
enum modes currentMode = OFF;

//Global vars
const int TEMP_MAX = 100; //Celsius   What max temp do we want the heater to be????
const int RANGE = 1; //Celsius

const int DELAY = 500; //ms - for LED flash
unsigned long pulseStart = 0; //ms-timer for LED flash

unsigned long tempPulseStart = 0; //ms timer for ADC
const int ADC_DELAY = 50; //ms
double rollingAvgTemp = 25.0; //Celsius

double pidHotOutput = 0; //global for PID output (hot mode)
double pidHotTarget = double(TEMP_MAX); //Celsius
PID pidHotController(&rollingAvgTemp, &pidHotOutput, &pidHotTarget,2000, 20, 0, DIRECT);

//Debouncer setup
Bounce debouncer = Bounce();

void setup(){
  //set up code here to run once
  pinMode(HEAT_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLDOWN);

  analogReference(DEFAULT); // use default 5V ref

  debouncer.attach(BUTTON_PIN, INPUT_PULLDOWN);
  debouncer.interval(50);                                                          // why 50???

  pidHotController.SetOutputLimits(0, pidWindow); //PID outputs how long we should be on this cycle

  Serial.begin(9600);                                                        // why 9600???
}

void loop () {
  //main code here to run repeatadly 

  debouncer.update();

  if(debouncer.fell() ){
    isRunning = !isRunning;
    Serial.println("mode toggle to ");
    Serial.println(isRunning ? "RUNNING" : "NOT RUNNING");
  }

  if (isRunning){
    run_system();
  }
else {
  digitalWrite(HEAT_PIN, LOW); // heating element off
}

delay(50);

}

/////////////////////////////////////////////////////////////////////////
// run_system
//
// run the control system 
// basic on/off control system with hysteresis 
////////////////////////////////////////////////////////////////////////
void run_system(){
  
  read_thermistor();

  //very crude two-level hi-low-off control
  if (rollingAvgTemp > TEMP_MAX){
    analogWrite(HEAT_PIN, 0); //off if exceeds set temperature
    Serial.println("Power: 0");
  }
   else if ((rollingAvgTemp >= (TEMP_MAX - RANGE)) & (rollingAvgTemp <= TEMP_MAX)){
    analogWrite(HEAT_PIN, 25); //10% power when in the set temp range
    Serial.println("Power: 25");
  }
  else if (rollingAvgTemp < (TEMP_MAX-RANGE)){
    analogWrite(HEAT_PIN, 255); //full power
    Serial.println("Power: 255");
  }
  else {
    analogWrite(HEAT_PIN, 0); //catch all - turn off if in weird state
  }

  Serial.print(" Temp: ");
  Serial.print(rollingAvgTemp);
  Serial.print("\n");
}


///////////////////////////////////////////////////////////////////////////
// read_thermistor
//
// Reads the value of the thermistor and converts to degrees C
// ADC reads are rate limited using non-blocking timers
// Returns a running average to minimize noise
//////////////////////////////////////////////////////////////////////////
void read_thermistor(){
  // ____________ (MF52C1103F3380) Thermistor 
  static const float T0 = 298.15; //T0 in K (per datasheet)
  static const float B = 3380.0; //B in K (per datasheet)
  static const float R0 = 10000.0; //Thermistor resistance at 25C
  static const float R1 = 9807.00; //R used in voltage divider
  float temp_C = 0.0;
  float temp_C_avg = 0.0;

  if((millis() - tempPulseStart) > ADC_DELAY){
    //calculate temperature reading
    float raw_value = analogRead(THERMISTOR_PIN);
    float resistance = ((R1 * (1023.00 - raw_value)) / raw_value);
    
  }
}


1 Like

Is this the same subject as your other post?

Yes I made a new post because I figured out the errors pointed in the last.

Did you write that code? If not, from where does it come?

That code will not compile. You should mention that in the post and post the errors. Can we get it to compile, then add the features that you want?

It is unlikely that anyone will fix your code for you for free. If you want to pay someone to fix the code, try the About the Jobs and Paid Consultancy category.

I am not aware of any internal pull down resistors in the Micro processor.
And I find no mention of pull down resistors in the 32U4 data sheet or the Bounce library.

The breadboard photo may be useful, but a schematic would be much more valuable. Hand drawn, photographed and posted is fine. Include all pin names/numbers, components, their part numbers and/or values and power supplies.

EDIT: So my effort was wasted, replying to a cross post. That is irritating. I am done with this poster.

1 Like

And repeat them. Please flag your own post and ask that this be moved to the thread you have already.

a7

@m11s,

Your two or more topics on the same or similar subject have been merged.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.