Bluetooth + Nano temperature controller (yes another one)

Using HC05 with nano, Android OS

I’ve searched for similar projects but somehow mine is different. Basically I want my system to work all on its own and the blynk interface is for monitoring and overwritting of default values.

My problem is coming in that I have a button, which when pressed, allows for overwriting of values for temperature hysteresis, delays etc.
In the code I have it write the value of the overwrite button to a var for “Override”
It’s setup to ignore changes to temperature etc unless the override var is HIGH, however, even if I don’t touch the overidde button, it will somehow set Override to HIGH all on its own if I move the sliders… this obviously ruins the whole point of the override button.

Additionally, I constantly get errors about the packets being too big and I have no idea why that is…

Any ideas why the override var sets itself to HIGH even if I don’t touch the override button?

The section in question:

BLYNK_WRITE(V6) // This runs when blynk runs - it basically checks if V6 is set to on or off and sets variable accordingly
{ 
  SettingsOverride = param.asInt();  // Get status of V6.
  Serial.print(" Settings Override = ");
  Serial.println(SettingsOverride);
}

BLYNK_WRITE(V5) // This runs when blynk runs - it basically checks if V6 is set to on or off and sets variable accordingly
{ 
  if (SettingsOverride = HIGH) {
    SetTemp = param.asInt();
    Serial.print("Set Temp Overwritten by Blynk, new set temp =");
    Serial.println(SetTemp);
  } else {
      Blynk.virtualWrite(V5,SetTemp);
  }

}

Full code below:



/*********************** BLYNK STUFF *******************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#define BLYNK_DEBUG  //USE ONLY FOR DEBUGGING - remove this when you are done debugging

#include <SoftwareSerial.h>  //used to setup Bluetooth module
SoftwareSerial SwSerial(8, 9); // RX, TX Sets up SW serial to be thru using the library
    
#include <BlynkSimpleSerialBLE.h>
#include <SoftwareSerial.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "e2e2bb7420574c8bad75e3418abf11e5";

SoftwareSerial SerialBLE(8, 9); // RX, TX - No Idea why I need this? Was in example code for BLE via BLYNK


/****************** Temp Sensor Crap ************************/

// First we include the libraries for temp sensor
#include <OneWire.h>  //for communication over a single wire
#include <DallasTemperature.h>  //for communication protocol specifically for the temp sensor

// Data wire is plugged into pin 11 on the Arduino 
#define ONE_WIRE_BUS 11 


// Setup a oneWire instance to communicate with any OneWire devices  
// (not just Maxim/Dallas temperature ICs) 
OneWire oneWire(ONE_WIRE_BUS); 


// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);




/*************************** Fridge Control and Inverter Control***************/
const byte fridge_pwr_relay_pin = 5; //pin used to control power relay on fridge compressor
const byte inverter_power_feedback_pin = 3; //pin used to detect whether the inverter is on or off
const byte inverter_power_cycle_pin = 2; //pin used to turn the inverter on or off
const byte temp_sens_pwr_pin = 12;      // Pin used to provide power to temp sensor


/*************************  Control System States *************/
//The idea here is that we will setup states that the controller can be in 

// States
#define S_Monitor 0 //State Monitor -used to check the temperature reading every minute
#define S_Sleep 1  //State Sleep /cooldown - used to turn off all system control except temp check for X minutes
#define S_Cooling 2 //state for actively cooling the fridge

byte state = S_Sleep; // Initial state so the thing doesn't cycle or start for minumum of X minutes after power on


// Vars

unsigned long SleepLength = 900000; // How long we wait before we try to cool the fridge again

int SetTemp = 85; // Default temperature for controller (link with Blynk to make adjustable)
byte Hysteresis = 5; // Default Hysteresis to use so that it doesn't short cycle compressor (on then off then on then off etc)
float Temp = 0; //set the default automatically so low nothing will ever try to turn it on at startup

/********************   Blynk Control Pins and Vars ****************/
bool SettingsOverride = 0; //sets setting override to 0 so it doesn't try and read fake values from Blynk


void setup()
{
 // Debug console
  Serial.begin(9600);
  Serial.println("Setup Starting...");

  
 /**************** Temp Sensor Stuff ************/
  sensors.begin(); //initializes the temp sensor via dallas communication protocol
  pinMode(temp_sens_pwr_pin, OUTPUT); //sets the power pin for temp sensor to be an output 
  digitalWrite(temp_sens_pwr_pin, HIGH); //turn the power to the temp sensor on

 /***************** Fridge Control and Inverter Control ************/

   pinMode(fridge_pwr_relay_pin, OUTPUT); // sets the fridge relay pin to be an output
   pinMode(inverter_power_feedback_pin, INPUT); // sets the fridge relay pin to be an output
   pinMode(inverter_power_cycle_pin, OUTPUT); // sets the fridge relay pin to be an output
 
 
 
 /************* BLYNK Stuff***********/
  // Debug console
  Serial.begin(9600);
  Serial.println("Serial started, starting Serial BLE...");
  SerialBLE.begin(9600); //begin communication thru bluetooth module (serial)
 // Blynk.begin(SerialBLE, auth); //starts blynk session thru previously established serial channel^
  
  Serial.print(millis());
  Serial.println("Waiting for connections...");
  Blynk.config(SerialBLE, auth);  // No idea if this will work...
  Serial.print(millis());
  Serial.println("Past blynk.config, going to blynk.connect");
  Blynk.connect();
  Serial.print(millis());
  Serial.println("Past blynk.connect, starting timeout");
 int mytimeout = millis() / 1000;  //stores value of time so far elapsed in seconds, rounded to nearest second. OK to be an int since this is in setup and millis should be small still
while (Blynk.connect() == false) { 
  if((millis() / 1000) > mytimeout + 8){  // try for less than 9 seconds
    Serial.println("Timeout occured, exiting setup");
    break;
     }
    }
}

void loop()
{
  Serial.print("Current State is:");
  if(state == 0) {Serial.print(" Monitoring  aka =");}
  if(state == 1) {Serial.print(" Sleeping  aka =");}
  if(state == 2) {Serial.print(" Cooling  aka =");}
  Serial.println(state); // prints the current state
   Blynk.run();
  Serial.print("BLE Connection status =");
  Serial.println(Blynk.connected());
  if (Blynk.connected() == true){
  Blynk.run();
  } else {
    Serial.print("BLE Connection status =");
    Serial.println(Blynk.connected());
    }
  
  // You can inject your own code or combine it with other sketches.
  // Check other examples on how to communicate with Blynk. Remember
  // to avoid delay() function!
  if(state == S_Monitor) {
    F_Monitor();
    
  }
  if(state == S_Sleep) {
    F_Sleep();
    state = S_Monitor; //After sleeping, go back to monitoring
  }

  if(state == S_Cooling) {
    F_Cooling();
    state = S_Sleep; //After sleeping, go back to monitoring
  }
}

//Functions 
void F_Monitor () {   //Establishes Function_Monitor to just check the temp
  F_GetTemp();

  F_ShowTemp();

  if (Temp > SetTemp) {
    state = S_Cooling; } 

 Serial.print("Set Temp: " ); 
  Serial.println(SetTemp);
  Serial.print("Settings override =");
  Serial.println(SettingsOverride);



  F_ReadingDelay();
  }
 

void F_GetTemp() {
        //  Serial.println("--------------------------------");
        //  Serial.println("Starting Temp sensor reading");
  digitalWrite(temp_sens_pwr_pin, HIGH); //turn the power to the temp sensor on, will need 1 sec to stabilize
  sensors.requestTemperatures(); // Tell the sensor to record the temp to its memory
      //now we need to put in a delay of 750ms to resend command to get a real reading
       // Serial.println("Requested boot of temp sensor..");
      // Serial.println("Starting temp sensor boot timer");
  F_BlynkDelay(750); // needs a delay of 750ms for temp sensor to boot and give a good reading
 
        //  Serial.println("Temp Sensor Timer finished, getting reading"); //Lets user know timer is over
  sensors.requestTemperatures(); // Tell the sensor to record the temp to its memory
  Temp = sensors.getTempFByIndex(0); // Retrieve the temp from the sensor's memory and store it in a local var
  
  digitalWrite(temp_sens_pwr_pin, LOW); //turn off power to the sensor
      // Serial.println("Temp received, turned off pwr to temp sensor");
 
}

void F_ShowTemp(){
  Serial.print("Temp is: ");
  Serial.println(Temp); //Prints temp received from sensor
  if (Blynk.connected() == true){
  Blynk.virtualWrite(V4,Temp); //write the value stored in Temp (temperature) to virtual pin v4 for dispay in app
  } 
  
}

void F_ReadingDelay(){
  Serial.println("Post Temp reading delay between next reading");
  F_BlynkDelay(5000); //Sets a 5 second timer between readings so that the sensor isn't always powered up
}


void F_BlynkDelay(unsigned int ms) {              // ms: duration of delay in milliseconds
    unsigned long start = millis();           // start: timestamp
    while (millis() - start < ms) {  // as long as the time period defined in function call hasn't passed...
      if (Blynk.connected() == true){
           // Serial.println("Blynk connected, Running Blynk");
            Blynk.run();
            }
    }
// Serial.println("End of Blynk Safe Delay");
}

void F_Sleep(){
  Serial.println("----------------------------");
  Serial.println("Current state is sleep, will pause all actions");
  Serial.println("Starting BlynkDelay for the sleep timer");
  F_BlynkDelay(7000);
  Serial.println("Sleep cycle finished");
}

void F_Cooling(){
  Serial.println("----------------------------");
  Serial.println("Current state is Cooling, Will run compressor until past SetTemp + Hysteris");
  digitalWrite(fridge_pwr_relay_pin,HIGH);
  

  Serial.println("Starting BlynkDelay so minor temp fluctuations don't affect output");
  F_BlynkDelay(3000);
  Serial.println("Compressor startup temp fluctuation cycle completed, can now trust temp sensor output");
  Serial.print("Set Temp = "); Serial.println(SetTemp);
  while( Temp >= SetTemp - Hysteresis) {
    F_BlynkDelay(1000);
    F_GetTemp();
    F_ShowTemp();
  }
  digitalWrite(fridge_pwr_relay_pin,LOW);
  }

BLYNK_WRITE(V6) // This runs when blynk runs - it basically checks if V6 is set to on or off and sets variable accordingly
{ 
  SettingsOverride = param.asInt();  // Get status of V6.
  Serial.print(" Settings Override = ");
  Serial.println(SettingsOverride);
}

BLYNK_WRITE(V5) // This runs when blynk runs - it basically checks if V6 is set to on or off and sets variable accordingly
{ 
  if (SettingsOverride = HIGH) {
    SetTemp = param.asInt();
    Serial.print("Set Temp Overwritten by Blynk, new set temp =");
    Serial.println(SetTemp);
  } else {
      Blynk.virtualWrite(V5,SetTemp);
  }

}

I can’t speak for your override issue, but regardless of what you want to use Blynk for, you still need to follow the programming convention it requires… as in minimal content in the void loop() and no blocking commands like delays as they can cause issues with Blynk, even over a BT connection. All that is probably the root for your packet issues.

Also, when you do this, you need to follow up with sync command in-order to actually process the change… although the way you are doing it might cause a cyclic loop?.. hard to say just glancing at it.

And which ever one you need for the BLE you keep… and remove the other. Or whichever one is processed last may override or conflict with the first since they are both using the same pins.

Hi Gunner, Although I put some print statements into the main loop for debugging, I thought I was still following the clean void loop strategy. I have no delays in my code anywhere, just timers. Also, my timer function is set to run Blynk on repeat without doing anything else like sending data or reading data etc.
The main loop runs through once and points to a function, which runs separately, and basically all function calls take at least 750ms to run. And in those functions, basically it checks to see if blynk is connected. If so, in the timer function it runs Blynk, if not it just sits there until the timer runs out and moves onto the next block.

I didn’t use the sync command on purpose there - so if they don’t use the override, it won’t let them change the set point, and will instead write to the app (so they can manually change the value, but it’ll write the unmodified value to the app, so that I can’t change the set point without first setting it into override mode)

As for the SW Serial, I’ll try deleting one at a time and see if I can get it to work with just one. I’ve been piecing together Bluetooth code (some of it outdated probably) so I probably screwed that sucker up. Thanks!

It may not be as critical with BT, but any delay in the void loop(), including directly calling another function (potentially hundreds or thousands of times a second), that then takes up it’s own time, may cause issues.

Remember, Blynk is not just a GUI, it is designed as a full IoT system and thus generally requires constant server link when it needs to do something… even over BT (so far).

Best to let Blynk rule the clean void loop() and use timers for functions and connection management for the “run without server” needs.

Possibly then it will be easier to manage the rest of the logic flow for the way you want it to be.

Gosh I’m an idiot. Sorry everyone. Guess it took a good couple nights rest to realize my if statement was if(xxx = HIGH) and not if(xxx == HIGH), total noob mistake.

I went ahead and put in Blynk.syncall after I write to the app. That way, if override is set to HIGH, it will read the new value and set it as the temp, then syncall. Otherwise, it’ll write the old value to the app and then sync all so that the app updates the value appropriately.

1 Like

Gunner, I guess I thought it was good enough as-is, but I’ll try to trim it down even more per your guidance. Thank you for helping me out , I know it must be such a PITA to deal with the same problems over and over.

PS… I don’t use BT myself so I forgot… but sync requires the server connection… so not sure how well it will work with BT

I guess I figure someone might, just might, read one of my repetitive comments and it will save their soul :rofl: