[SOLVED] Does photon support the toint() function?

I have a function that needs an integer, but I’m inputting a string, I’ve been using an arduino function tonint(), but that doesn’t seem to be working

else if (time_selected.toInt() > 0 && temp_selected.toInt() > 0) {
   prev_time_remaining = time_selected.toInt(); //convert to number
   temp_setpoint = temp_selected.toInt();
   run_type = 3;
}

time_selected and temp_selected are string vars and time_remaining and temp_setpoint are integer vars.
The output looks like

time=805, currentMode=stop_mode, inside_temp=78.80, inside_moisture=43.00, average= 38, time_selected=90, time_remaining=0, temp_selected=150, temp_setpoint=0, heater on?=0, motor on?=0, button pressed?=1, heater timeout?=1, cooldown start=436

So, obviously temp_setpoint is not being set equal to temp_selected.

Hi @jrubins

The toInt() method of String bails out and returns zero if it encounters a non-numeric character.

Could that explain what you are seeing?

Thanks @bko, I don’t think so, because the characters going in are 90 for the time and 150 for the temperature.

this is one section defining the time_selected

 if (clicked_buttons & BUTTON_SELECT) {
    time_selected = "90";
    lcd.clear();
    lcd.print("90 Minutes");
    delay(1000);
    lcd.clear();
    menu =1;
  }
  break;

I can post my whole code, but it’s long :slight_smile:

To make sure what your String actually contains try to Serial.print() the contents like this

  Serial.print(">");
  Serial.print(yourString);
  Serial.print("<");
  Serial.println();

to ensure you even see white-space characters.

Serial.print("time_selected=");
Serial.print(time_selected);
Serial.print(", ");
Serial.print("time_remaining=");
Serial.print(time_remaining);
Serial.print(", ");
Serial.print("temp_selected=");
Serial.print(temp_selected);
Serial.print(", ");
Serial.print("temp_setpoint=");
Serial.print(temp_setpoint);
Serial.print(", ");
...

This is my print statement block. I think that any whitespace would show up, no?

1 Like

Here’s the entirety of my code. I’m sure there are lots of bugs, just trying to work through them one-by-one :slight_smile:

// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_RGBLCDShield/Adafruit_RGBLCDShield.h"
#include "Adafruit_RGBLCDShield/Adafruit_MCP23017.h"

//dryer v3 uses the adafruit dht library since the pietteTech lib seems to have stopped working? -it just reads -5.00 all the time
//I've also updated the rgblcdshield lib, but no improvement

// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_DHT/Adafruit_DHT.h"

// This #include statement was automatically added by the Particle IDE.
//#include "PietteTech_DHT/PietteTech_DHT.h"

// This #include statement was automatically added by the Particle IDE.


#include "math.h" 

// Uncomment whatever type you're using!
#define DHTTYPE DHT11       // Sensor type DHT11/21/22/AM2301/AM2302

//includes
//define pins
#define DHTPIN 3     // what pin we're connected to
#define ON 0x7
#define OFF 0x0
//inititalize dht temp sensor and lcd shield
//void dht_wrapper(); // must be declared before the lib initialization
// Lib instantiate
//PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
DHT dht(DHTPIN, DHTTYPE); //adafruit dht init
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
//initialize icons
byte icons[3][7] = {{ 0x0, 0x4, 0x6, 0x1f, 0x6, 0x4, 0x0},
  {0x0, 0xe, 0x15, 0x17, 0x11, 0xe, 0x0},
  {0x4, 0xe, 0xe, 0x1e, 0x1b, 0xb, 0x6}
};
//! Index into the bitmap array for the  icons.
const int ARROW_ICON_IDX = 0;
const int CLOCK_ICON_IDX = 1;
const int FLAME_ICON_IDX = 2;

//constants
const long meas_interval = 3000;
const int motorPin = 7;
const int heaterPin = A5;
const long heater_timeout_interval = 120000; //2 minute lockout
const long time_interval = 3000; //check how much time left every 3 seconds
const long temp_interval = 3000; //check what to set temp to every 3 seconds

//variables
uint8_t clicked_buttons;
int menu = 0;
unsigned long previous_print_millis;
const unsigned long printInterval = 3000;
unsigned long heater_last_used_millis;
int motorState = LOW;
int heaterState = LOW;
boolean heater_timeout = false;
unsigned long previous_meas_millis = 0;
String currentMode;
unsigned long previous_time_millis = 0;
unsigned long previous_temp_millis = 0;
float inside_temp;
float inside_moisture;
int time_remaining = 60;
int temp_setpoint = 101;
unsigned long currentMillis;
unsigned long cooldown_start_millis = 0;
unsigned long cooldown_interval = 300000;

//button variables
int buttonPin = 6;         // the number of the input pin
int reading;           // the current reading from the input pin
int buttonPrevious = LOW;

//variables and constants for moving average of moisture
const int numReadings = 10;
int readings[numReadings];      // the readings from the analog input
int reading_idx = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average_moisture = 0;                // the average

//variables for time and temp selections
String run_selected;
String temp_selected;
String time_selected;
int run_type = 0;
int prev_time_remaining = 0;
unsigned long previous_run_millis = 0;
unsigned long time_elapsed = 0;


/*--- *****setup****** ---*/
void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.createChar(ARROW_ICON_IDX, icons[ARROW_ICON_IDX]);
  lcd.createChar(CLOCK_ICON_IDX, icons[CLOCK_ICON_IDX]);
  lcd.createChar(FLAME_ICON_IDX, icons[FLAME_ICON_IDX]);
  pinMode(motorPin, OUTPUT);
  pinMode(heaterPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  dht.begin(); //adafruit dht start
  for (int thisReading = 0; thisReading < numReadings; thisReading++) //initialize counter for moving average of moisture
    readings[thisReading] = 0;
  lcd.setCursor(0, 0);
  lcd.write(FLAME_ICON_IDX);
  lcd.write(CLOCK_ICON_IDX);
  lcd.print(" Welcome to ");
  lcd.write(CLOCK_ICON_IDX);
  lcd.write(FLAME_ICON_IDX);
  lcd.setCursor(2, 1);
  lcd.print("Dryerbot9000");
  delay(2000);
  lcd.clear();
  menu_fun();
}

//void dht_wrapper() {
//    DHT.isrCallback();
//}
float read_inside_temp() {
  //float t = dht.readTemperature();
  // Read temperature as farenheit
  inside_temp = dht.getTempFarenheit();

  // Check if any reads failed and exit early (to try again).
  if (isnan(inside_temp)) {
    //lcd.print("Failed to read from DHT sensor!");
    Serial.println("Failed to read from DHT sensor!");
  }
  return inside_temp; //?? this was commented out, why? 
}

float read_inside_moisture() {
  inside_moisture = dht.getHumidity();
  if (isnan(inside_moisture)) {
    //lcd.print("Failed to read from DHT sensor!");
    Serial.println("Failed to read from DHT sensor!");
  }
  return inside_moisture;
}


int auto_heat() {
  if (average_moisture >= 52) {
    temp_setpoint = 160;
  }

  else if ( average_moisture < 52 && average_moisture >= 50) {
    temp_setpoint = 150;
  }
  else if (average_moisture < 50 && average_moisture >= 47) {
    temp_setpoint = 140;
  }
  else if (average_moisture < 47 && average_moisture >= 44) {
    temp_setpoint = 130;
  }
  else if (average_moisture < 44 && average_moisture >= 41) {
    temp_setpoint = 120;
  }
  else if (average_moisture < 41 && average_moisture >= 38) {
    temp_setpoint = 110;
  }
  else if (average_moisture < 38 && average_moisture >= 35) {
    temp_setpoint = 100;
  }
  else if (average_moisture < 35) {
    temp_setpoint = 0;
  }
  else {
    temp_setpoint = 0;
  }
  return temp_setpoint;
}

int auto_time() {

  if (average_moisture >= 53) {
    time_remaining = 60;
  }
  else if (average_moisture < 53 && average_moisture >= 50) {
    time_remaining = 50;
  }
  else if (average_moisture < 50 && average_moisture >= 47) {
    time_remaining = 40;
  }
  else if (average_moisture < 47 && average_moisture >= 44) {
    time_remaining = 30;
  }

  else if (average_moisture < 44 && average_moisture >= 41) {
    time_remaining = 20;
  }

  else if (average_moisture < 41 && average_moisture >= 38) {
    time_remaining = 10;
  }

  else if (average_moisture < 38 && average_moisture >= 35) {
    time_remaining = 5;
  }

  else if (average_moisture < 35) {
    time_remaining = 0;
  }

  else {
    time_remaining = 60;
  }

  return time_remaining;
}

boolean heater_timeout_check() {
  //heaterState = digitalRead(heaterPin);
  if (heaterState == HIGH) {
    heater_last_used_millis = currentMillis;
    heater_timeout = false;
  }

  else if (heaterState == LOW && (currentMillis - heater_last_used_millis >= heater_timeout_interval)) {
    heater_timeout = false;
  }
  else {
    heater_timeout = true;
  }
  return heater_timeout;
}


String run_mode() {
  //digitalWrite(motorPin, HIGH);
  cooldown_start_millis = currentMillis;
  if (time_selected == "auto" && temp_selected == "auto") {
    run_type = 0;
  }
  else if (time_selected == "auto" && temp_selected.toInt() > 0) {
    temp_setpoint = temp_selected.toInt();
    run_type = 1;
  }
  else if (time_selected.toInt() > 0 && temp_selected == "auto") {
    prev_time_remaining = time_selected.toInt(); //convert to number
    run_type = 2;
  }
  else if (time_selected.toInt() > 0 && temp_selected.toInt() > 0) {
    prev_time_remaining = time_selected.toInt(); //convert to number
    temp_setpoint = temp_selected.toInt();
    run_type = 3;
  }
  else {
    run_type = 0;
  }


  switch (run_type) {
    case 0: //auto time auto heat
      if (currentMillis - previous_time_millis >= time_interval) {
        previous_time_millis = currentMillis;
        auto_time();
      }
      if (currentMillis - previous_temp_millis >= temp_interval) {
        previous_temp_millis = currentMillis;
        auto_heat();
      }
      break;

    case 1:  //auto time set heat
      if (currentMillis - previous_time_millis >= time_interval) {
        previous_time_millis = currentMillis;
        auto_time();
      }
      break;

    case 2: //set time auto heat
      if (currentMillis - previous_temp_millis >= temp_interval) {
        previous_temp_millis = currentMillis;
        auto_heat();
      }

      time_remaining = prev_time_remaining - ((currentMillis - previous_run_millis) * 60000);
      previous_run_millis = currentMillis;
      break;

    case 3: //set time set heat
      time_remaining = prev_time_remaining - ((currentMillis - previous_run_millis) * 60000);
      previous_run_millis = currentMillis;
      break;
  }




  motorState = HIGH;
  heater_timeout_check();
  //motorState = digitalRead(motorPin);
  if (inside_temp <= temp_setpoint && heater_timeout == false) {
    //digitalWrite(heaterPin, HIGH);
    heaterState = HIGH;
  }
  else {
    //digitalWrite(heaterPin, LOW);
    heaterState = LOW;
  }
  currentMode = "run_mode";
  menu = 999;
  //}
  //else {
  // cooldown_mode();
  // }
  return currentMode;
}

String cooldown_mode() {
  //if (currentMillis - cooldown_start_millis <= cooldown_interval) {
  // digitalWrite(motorPin, HIGH);
  // digitalWrite(heaterPin,LOW);

  motorState = HIGH;
  heaterState = LOW;
  currentMode = "cooldown_mode";
  // }
  //else if (temp_setpoint != 0 && time_remaining != 0) {
  // run_mode();
  //}

  // else {
  //  stop_mode();
  //}
  return currentMode;
}

String stop_mode() {
  // digitalWrite(heaterPin, LOW);
  //digitalWrite(motorPin, LOW);
  //cooldown_start_millis = currentMillis;

  heaterState = LOW;
  motorState = LOW;
  time_remaining = 0;
  temp_setpoint = 0;
  currentMode = "stop_mode";
  return currentMode;
}

void read_button_clicks() {
  static uint8_t last_buttons = 0;
  uint8_t buttons = lcd.readButtons();
  clicked_buttons = (last_buttons ^ buttons) & (~buttons);
  last_buttons = buttons;
  /*if (clicked_buttons) {
    menu_fun();
  }*/

}
int prev_menu=-1;

int menu_fun() {
  if (clicked_buttons & BUTTON_RIGHT) {
    menu++;
  }
  if (clicked_buttons & BUTTON_LEFT) {
    menu--;
  }
  if (menu > 2 && menu < 100) {
    menu = 0;
  }
  if (menu < 0) {
    menu = 2;
  }
  if (menu > 106 && menu < 200) {
    menu = 101;
  }
  if (menu < 101 && menu > 99) {
    menu = 106;
  }
  if (menu > 205 && menu < 300) {
    menu = 201;
  }
  if (menu < 201 && menu > 199) {
    menu = 205;
  }
  switch (menu) {
    case 0: //time
      //lcd.clear();
      lcd.setCursor(0,0);
      lcd.write(ARROW_ICON_IDX);
      lcd.print("time ");
      lcd.print("heat         ");
      //if (time_selected && temp_selected){
      lcd.setCursor(0,1);
      lcd.print("time:");
      lcd.print(time_selected);
      lcd.print(" temp:");
      lcd.print(temp_selected);//}
      if (clicked_buttons & (BUTTON_SELECT | BUTTON_DOWN)) {
        lcd.clear();
        menu=101;
      }
      break;
    case 1: //heat
    lcd.setCursor(0,0);
      lcd.print(" time");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("heat        ");
      //if (time_selected && temp_selected){
      lcd.setCursor(0,1);
      lcd.print("time:");
      lcd.print(time_selected);
      lcd.print(" temp:");
      lcd.print(temp_selected);//}
      if (clicked_buttons & (BUTTON_SELECT | BUTTON_DOWN)) {
        lcd.clear();
        menu = 201;
      }
      //prev_menu = 1;
      break;
    case 101: //time auto
      lcd.setCursor(0,0);
      lcd.write(CLOCK_ICON_IDX);
      lcd.print("time           ");
      lcd.setCursor(0, 1);
      lcd.write(ARROW_ICON_IDX);
      lcd.print("Auto 90 60 45 30 15");
      
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        time_selected = "auto";
        lcd.clear();
        lcd.print("Auto Time");
        delay(1000);
        lcd.clear();
        menu =1;
      }
      break;
    case 102: //time 90
      lcd.setCursor(0,0);
      lcd.write(CLOCK_ICON_IDX);
      lcd.print("time           ");
      lcd.setCursor(0, 1);
      lcd.print(" Auto");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("90 60 45 30 15");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        time_selected = "90";
        lcd.clear();
        lcd.print("90 Minutes");
        delay(1000);
        lcd.clear();
        menu =1;
      }
      break;
    case 103: //time 60
      lcd.setCursor(0,0);
      lcd.write(CLOCK_ICON_IDX);
      lcd.print("time           ");
      lcd.setCursor(0, 1);
      lcd.print(" Auto 90");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("60 45 30 15");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        time_selected = "60";
        lcd.clear();
        lcd.print("60 Minutes");
        delay(1000);
        lcd.clear();
        menu = 1;
      }
      break;
    case 104: //time 45
      lcd.setCursor(0,0);
      lcd.write(CLOCK_ICON_IDX);
      lcd.print("time           ");
      lcd.setCursor(0, 1);
      lcd.print(" Auto 90 60");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("45 30 15");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        time_selected = "45";
        lcd.clear();
        lcd.print("45 Minutes");
        delay(1000);
        lcd.clear();
        menu =1;
      }
      break;
    case 105: //time30
      lcd.setCursor(0,0);
      lcd.write(CLOCK_ICON_IDX);
      lcd.print("time           ");
      lcd.setCursor(0, 1);
      lcd.print("90 60 45");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("30 15  ");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        time_selected = "30";
        lcd.clear();
        lcd.print("30 Minutes");
        delay(1000);
        lcd.clear();
        menu =1;
      }
      break;
    case 106:  //time 15
      lcd.setCursor(0,0);
      lcd.write(CLOCK_ICON_IDX);
      lcd.print("time           ");
      lcd.setCursor(0, 1);
      lcd.print("90 60 45 30");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("15  ");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        time_selected = "15";
        lcd.clear();
        lcd.print("15 Minutes");
        delay(1000);
        lcd.clear();
        menu =1;
      }
      break;
    case 201: //heat auto
      lcd.setCursor(0,0);
      lcd.write(FLAME_ICON_IDX);
      lcd.print("heat           ");
      lcd.setCursor(0, 1);
      lcd.write(ARROW_ICON_IDX);
      lcd.print("Auto Hi Med Low Off");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        temp_selected = "auto";
        lcd.clear();
        lcd.print("Auto heat");
        delay(1000);
        lcd.clear();
        menu =0;
      }

      break;
    case 202:  //heat hi
      lcd.setCursor(0,0);
      lcd.write(FLAME_ICON_IDX);
      lcd.print("heat           ");
      lcd.setCursor(0, 1);
      lcd.print(" Auto");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("Hi Med Low Off");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        temp_selected = "150";
        lcd.clear();
        lcd.print("High heat");
        delay(1000);
        lcd.clear();
        menu = 0;
      }
      break;
    case 203: //heat med
      lcd.setCursor(0,0);
      lcd.write(FLAME_ICON_IDX);
      lcd.print("heat           ");
      lcd.setCursor(0, 1);
      lcd.print(" Auto Hi");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("Med Low Off");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        temp_selected = "130";
        lcd.clear();
        lcd.print("Medium heat");
        delay(1000);
        lcd.clear();
        menu = 0;
      }
      break;
    case 204:  //heat low
      lcd.setCursor(0,0);
      lcd.write(FLAME_ICON_IDX);
      lcd.print("heat           ");
      lcd.setCursor(0, 1);
      lcd.print("Hi Med");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("Low Off  ");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        temp_selected = "110";
        lcd.clear();
        lcd.print("Low heat");
        delay(1000);
        lcd.clear();
        menu = 0;
        
      }
      break;
    case 205: //heat off
      lcd.setCursor(0,0);
      lcd.write(FLAME_ICON_IDX);
      lcd.print("heat           ");
      lcd.setCursor(0, 1);
      lcd.print("Hi Med Low");
      lcd.write(ARROW_ICON_IDX);
      lcd.print("Off  ");
      if (clicked_buttons & BUTTON_UP) {
        lcd.clear();
        menu = 0;
      }
      if (clicked_buttons & BUTTON_SELECT) {
        temp_selected = "32";
        lcd.clear();
        lcd.print("Heat Off");
        delay(1000);
        lcd.clear();
        menu = 0;
      }
      break;
      
    case 999: //display in run mode
     lcd.setCursor(0,0);
     lcd.write(CLOCK_ICON_IDX);
      lcd.print(":");
      lcd.print(time_remaining);
      lcd.print(" dry:");
      lcd.print(map(average_moisture,35,100,100,0));
      lcd.print(" ");
      lcd.print(currentMode);
      //if (time_selected && temp_selected){
      lcd.setCursor(0,1);
      lcd.print("time:");
      lcd.print(time_selected);
      lcd.print(" temp:");
      lcd.print(temp_selected);//}
      if (clicked_buttons) {
        lcd.clear();
        menu=0;
      }
      break;
  }
}

/* --- ******* Loop ****** --- */
void loop() {
  delay(10);
  lcd.setBacklight(ON);
  read_button_clicks();
  menu_fun();
  currentMillis = millis();
  digitalWrite(motorPin, motorState);
  digitalWrite(heaterPin, heaterState);
  reading = digitalRead(buttonPin);

  total = total - readings[reading_idx];

  if (currentMillis - previous_meas_millis >= meas_interval) {
    previous_meas_millis = currentMillis;
   // DHT.acquire();//?? do I need this? 
    readings[reading_idx] = read_inside_moisture();
    read_inside_temp();
  }
  total = total + readings[reading_idx];
  reading_idx = reading_idx + 1;
  if (reading_idx >= numReadings)
    reading_idx = 0;
  average_moisture = total / numReadings;

  //probably need to move these to the run function
  //calculate time remaining
  /*
  if (currentMillis - previous_time_millis >= time_interval) {
    previous_time_millis = currentMillis;
    auto_time();

  }

  if (currentMillis - previous_temp_millis >= temp_interval) {
    previous_temp_millis = currentMillis;
    auto_heat();
  }*/
  //////////
  if (reading == HIGH && time_remaining > 0 && temp_setpoint > 0) {
    run_mode();
  }
  else if (reading == HIGH && (time_remaining == 0 || temp_setpoint == 0) && (currentMillis - cooldown_start_millis <= cooldown_interval)) {
    cooldown_mode();
  }

  else if (reading == HIGH && currentMode == "cooldown_mode" && (currentMillis - cooldown_start_millis > cooldown_interval)) {
    stop_mode();
  }

  else if (reading == LOW) {
    cooldown_start_millis = currentMillis;
    stop_mode();
  }

  else {
    stop_mode();
  }




  if (currentMillis - previous_print_millis >= printInterval) {
    previous_print_millis = currentMillis;

    Serial.print("time=");
    Serial.print(currentMillis / 1000);
    Serial.print(", ");
    Serial.print("currentMode=");
    Serial.print(currentMode);
    Serial.print(", ");
    Serial.print("inside_temp=");
    Serial.print(inside_temp);
    Serial.print(", ");
    Serial.print("inside_moisture=");
    Serial.print(inside_moisture);
    Serial.print(", average= ");
    Serial.print(average_moisture);
    Serial.print(", ");
    Serial.print("time_selected=");
    Serial.print(time_selected);
    Serial.print(", ");
    Serial.print("time_remaining=");
    Serial.print(time_remaining);
    Serial.print(", ");
    Serial.print("temp_selected=");
    Serial.print(temp_selected);
    Serial.print(", ");
    Serial.print("temp_setpoint=");
    Serial.print(temp_setpoint);
    Serial.print(", ");
    Serial.print("heater on?=");
    Serial.print(heaterState);
    Serial.print(", ");
    Serial.print("motor on?=");
    Serial.print(motorState);
    Serial.print(", ");
    Serial.print("button pressed?=");
    Serial.print(reading);
    Serial.print(", ");
    Serial.print("heater timeout?=");
    Serial.print(heater_timeout);
    Serial.print(", cooldown start=");
    Serial.println(cooldown_start_millis / 1000);
    /*
    lcd.clear();
      lcd.setCursor(0, 0);
    lcd.print("tr=");
    lcd.print(time_remaining);
    lcd.print(" ");
    lcd.print("h=");
    lcd.print(heaterState);
    lcd.print("ts=");
    lcd.print(temp_setpoint);
        lcd.setCursor(0, 1);
    lcd.print("temp=");
    lcd.print(inside_temp);
    lcd.print(" ");
    lcd.print("moist=");
    lcd.print(inside_moisture);
    */
  }

}

Hi @jrubins

I read your code and I am still not sure what is happening.

Can you add Serial.print()'s to the run_mode/stop_mode logic? Another way you could end up with both of the values 0 is by running stop_mode().

I gave this a very quick read, but this approach may be an issue:

time_selected = "auto";

in places like this:

else if (time_selected.toInt() > 0 && temp_selected == "auto") {

why use Strings at all for what look like numeric inputs?

Perhaps you need STATES and SETPOINTS...

my only other advice would be to modularize this into chunks of code that you can debug and leave be while you work on the next chunk:

void loop() {
  delay(10);
  lcd.setBacklight(ON);
  read_button_clicks();
  menu_fun();
  currentMillis = millis();
  digitalWrite(motorPin, motorState);
  digitalWrite(heaterPin, heaterState);
  // and so on...

hard to understand what you are trying to do in loop()

I gave this a very quick read, but this approach may be an issue:

time_selected = "auto";

in places like this:

else if (time_selected.toInt() > 0 && temp_selected == "auto") {

why use Strings at all for what look like numeric inputs?

IDK, I just want to have "auto" actually be a meaningful value, rather than say "-99" but I may try that.

Perhaps you need STATES and SETPOINTS...

I don't know about this setpoint business, but I have many switch(case) statements. Is that what you mean by 'states'?

which likely could be simplified...

your:

int auto_heat() {
  if (average_moisture >= 52) {
    temp_setpoint = 160;
  }

  else if ( average_moisture < 52 && average_moisture >= 50) {
    temp_setpoint = 150;
  }
  else if (average_moisture < 50 && average_moisture >= 47) {
    temp_setpoint = 140;
  }
  else if (average_moisture < 47 && average_moisture >= 44) {
    temp_setpoint = 130;
  }
  else if (average_moisture < 44 && average_moisture >= 41) {
    temp_setpoint = 120;
  }
  else if (average_moisture < 41 && average_moisture >= 38) {
    temp_setpoint = 110;
  }
  else if (average_moisture < 38 && average_moisture >= 35) {
    temp_setpoint = 100;
  }
  else if (average_moisture < 35) {
    temp_setpoint = 0;
  }
  else {
    temp_setpoint = 0;
  }
  return temp_setpoint;
}

may be as simple as:

int auto_heat() 
{
  if (average_moisture < 35)
  {
    tempSetpoint = 0;
  }
  else
  {
    temp_setpoint = 10 * (constrain(map(average_moisture, 35, 52, 100, 160), 100, 160) / 10);
  }
  return temp_setpoint;
}

your code is very complex and could likely be simplified... a lot. :wink:

3 Likes

Any suggestions are likely to be accepted, particularly if they are as good as this one :smiley:

Did you check to see if stop_mode() is being called yet? That should be easy.

All @BulldogLowell is pointing out is that your code will be easier to debug if you separate the notions of modes (or states) and the control logic for these from the actual values that used as settings.

You are mixing these up by using Strings to hold both "auto" and "98.6" which seems easier on the surface but makes the logic harder to debug than if you had a boolean autoMode = true and a float setPoint = 98.6.

As it stands now, every part of your program that wants a numeric value needs to validate that the String is not "auto" first.

1 Like

The snippet of output I posted is stop_mode, but it does the same in cooldown_mode, which is to say, when I start the app it goes straight into cooldown mode because it doesn’t see the settings as anything other than 0.
e.g.

time=569, currentMode=cooldown_mode, inside_temp=78.80, inside_moisture=43.00, average= 43, time_selected=auto, time_remaining=0, temp_selected=auto, temp_setpoint=0, heater on?=0, motor on?=1, button pressed?=1, heater timeout?=1, cooldown start=436

time=212, currentMode=cooldown_mode, inside_temp=77.00, inside_moisture=43.00, average= 25, time_selected=90, time_remaining=0, temp_selected=150, temp_setpoint=0, heater on?=0, motor on?=1, button pressed?=1, heater timeout?=1, cooldown start=5

Because the Photon never sees that the time_remaining and temp_setpoint !=0, it will only ever go into cooldown and stop mode.

Hi @jrubins

When I was looking at your code, I looked for all the places that changed the values of temp_setpoint and time_remaining, and stop_mode() set both to zero. If fact other than the toInt() call there are no other places where these could become zero, so either toInt() is returning zero or stop_mode() is getting called.

2 Likes

try forcing it to startup in a particular mode, then based on the conditions of the sensors, change modes.

Something like this:

enum OperatingMode{
  STANDBY_MODE,
  HEAT_MODE,
  COOL_MODE,
  STOP_MODE
};

OperatingMode currentMode = STANDBY_MODE;
OperatingMode lastMode = STANDBY_MODE;


void setup() 
{


}

void loop() 
{
  evaluateSensors();  //force a state change on evaluation of your sensor data, you can even do this at an interval

  if (lastMode != currentMode)
  {
    //doSomething ?
    lastMode = currentMode;
  }
  switch(currentMode){
    case (STANDBY_MODE):
      //do STANDBY_MODE stuff
      break;
    case (HEAT_MODE):
      //do HEAT_MODE stuff
      break;
    case (COOL_MODE):
      // do COOL_MODE stuff
      break;
    case (STOP_MODE):
      // do STOP_MODE stuff
      break;
  } 
}

void evaluateSensors()
{
  //if(this)
  //currentMode = STANDBY_MODE;
  //if(that)
  //currentMode = HEAT_MODE;
  //etc...
}
2 Likes

Right, but it shows 0 for cooldown_mode too, meaning that toInt() is probably returning a 0, hence my question about toInt(). Seems like it may be choking though because it doesn’t recognize “150” as being an integer after conversion. I don’t have the Photon in front of me, so I can’t check. If only there were some way to remotely monitor the serial output, that would be neat.

Thanks!
JR

Seems like a good idea, thanks @BulldogLowell. Keep the suggestions coming! :smiley:

So, try to integrate some of what @bko and I have offered up…

I think you now know that toInt() works, so let’s mark this [SOLVED] and you can still post your code for help from the forum. I’m sure that you can solicit a lot of very competent guidance here (particularly from the Elites).

have fun!

1 Like

Yep. Will do.

Thanks!