Storing and comparing values for later use

Hi there,

I'm doing a project whereby I have some solenoids and want to open/close them in correspondence to temperature sensor readings. I'm having trouble getting my head around how this should work. I know I'm close but I have a limited knowledge and would really appreciate some help! The general flow of how it should work is as follows:

Temperature range is to be mapped and constrained from 20-30C for now.

I want to allow the solenoids to let air into a balloon for 1 second for increase in degree, and let it out for 1 second per decrease in degree, again, mapped between 20 and 30C.

  1. Start up
  2. Let air in to a certain 'base' point, lets call it 0. (which will be mapped to 20C, and anything below that will be constrained to 20C)
  3. Get the temp from sensor
  4. Check if sensor temp is higher than 20, if not do nothing, if so how much higher than 20? (for arguments sake lets say it went up to 23C)
  5. Let air in for 1 second per each degree above 20 (so 3 seconds)
  6. Check temp sensor again, if BELOW what it previously was, let air OUT for 1 second per difference in degree. (for arguments sake lets say it went to 22, so 1 second difference)
  7. if ABOVE what it previously was, let air IN for 1 second per difference in degree.

......and so on and so forth.....

I have two solenoids for each balloon and I have 2 balloons.

My code currently is:

#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS_PIN 3
#define SENSOR_RESOLUTION 12

OneWire oneWire(ONE_WIRE_BUS_PIN);  // Setup a oneWire instance to communicate with any OneWire devices

DallasTemperature sensors(&oneWire);

DeviceAddress HS1 = {0x28, 0xFF, 0xDF, 0x1C, 0xA4, 0x16, 0x03, 0x9F};
DeviceAddress HS4 = {0x28, 0xFF, 0x04, 0x19, 0xA5, 0x16, 0x03, 0x9B};

float HSA [2];

int solIn1 = 9;
int solOut1 = 10;

int solIn2 = 7;
int solOut2 = 8;

//-------------------------------------------------------//////////////////////------------------------------------------------------//

void setup() {
  // put your setup code here, to run once:

pinMode(solIn1, OUTPUT);
pinMode(solOut1, OUTPUT);
pinMode(solIn2, OUTPUT);
pinMode(solOut2, OUTPUT);

 Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  sensors.begin();
}

//-------------------------------------------------------//////////////////////------------------------------------------------------//

void printTemperature(DeviceAddress deviceAddress) {
  
  float tempC = sensors.getTempC(deviceAddress);

  if (tempC == -127.00)
  {
    Serial.print("Error getting temperature  ");
  }
  else
  {
    Serial.print("C: ");
    Serial.print(tempC);
    Serial.print(" F: ");
    Serial.print(DallasTemperature::toFahrenheit(tempC));
}

}
  
//-------------------------------------------------------//////////////////////------------------------------------------------------//

void loop() {
  // put your main code here, to run repeatedly:

  float HS1Temp = sensors.getTempC(HS1);
  float HS4Temp = sensors.getTempC(HS4);

  HSA [0] = HS1Temp;
  HSA [1] = HS4Temp;

  Serial.println();
  Serial.print("Number of Devices found on bus = ");
  Serial.println(sensors.getDeviceCount());
  Serial.print("Getting temperatures... ");
  Serial.println();

  sensors.requestTemperatures();

  Serial.print("HS0 temperature is:   ");
  printTemperature(HS1);
  Serial.println();
  Serial.print("HS0 array value is:   ");
  Serial.println(HSA [0], DEC);

  Serial.print("HS1 temperature is:   ");
  printTemperature(HS4);
  Serial.println();
  Serial.print("HS1 array value is:   ");
  Serial.println(HSA [1], DEC);

}

Note, I haven't put any code to deal with comparing the values yet as I'm just stumped.... so far I can only think to have some variables like such:

int blowCount = 0
int tempDiff = HS1Temp - OldTemp
delay(blowcount * 1000);

Also, to control my solenoids I am using two, one that lets air in and one out, I made a table which describes the necessary combination of HIGH/LOW signals to let air in and out. they are as follows.

//Let air in to balloon
(solIn1, HIGH);
(solOut1, LOW); 

//Let air out of balloon 
(solIn1, LOW);
(solOut1, HIGH);

//Hold air in balloon and do nothing
(solIn1, Low);
(solOut1, Low); 

//Let air in to balloon 
(solIn1, HIGH);
(solOut1, HIGH);

Long message I know.... sorry, I wanted to give all the info. I'm pretty sure it's not that hard an issue to solve, I'm just not that clued up on programming. Any help would be greatly appreciated! Thanks.

Edit: Oh, I should also say, I did have a long look through various other threads, and many similar problems existed, but none that lined up exactly with how I need to control and compare values that I could find.... I had trouble tailoring it to my code with my current skill level anyway.

I have tried to accommodate your project idea in the following Block Diagram and Flow Chart. These may be helpful to tailor/align the program codes that you have posted in this thread.

Figure-1: Block Diagram


Figure-2: Flow Chart for the Control Program

Program Codes for the Flow Chart of Fig-2: (untested)
You may pick up codes from your program that you have posted in this thread and place them at the appropriate section of the following programming template. Let us write programming codes at the level of our understandings and skills.

//Global space for the global variables
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3  //3 is DPin-3 of UNO at which sensor's output is connected

OneWire oneWire(ONE_WIRE_BUS);         
DallasTemperature sensors(&oneWire);   //sensors is the object created from the class -- DallasTemp..
unsigned int dsTemp1, dsTemp2;               

void setup() //enter codes for those tasks that will be executed only once or for a number of times

{
    Serial.begin(9600);   //initialize Serial Monitor
    sensors.begin();      //initialize One-Wire Sensor -- DS18B20 
    
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
   
}

void loop() //enter codes for those tasks that will be executed again and again
{
   acquireTemp();     //acquire Temp from Sensor-1/Sensor-2 and save them in dsTemp1, dsTemp2

   ballon1Control();   //control ballon1 based on Sensor-1's temperature
   ballon2Control();   //control ballon2 based on Sensor-2's temperature

   delay(2000);         //wait for stablizatipon
}

void acquireTemp()
{
     sensors.requestTemperatures();  // Temp conversion command; waiting here until comversion is done
     dsTemp1 = sensors.getTempCByIndex(0);  //read temp data from Sensor-1 and save in dTemp1
     dsTemp2 = sensors.getTempCByIndex(1);  //read temp data from Sensor-2 and save in dsTemp2

}

void balolon1Control()
{

}

void ballon2Control()
{

}

Thanks very much GolamMostafa!

Since I posted I've been playing around with it a bit and come up with the following:

//________________________________Libraries________________________________//

#include <AccelStepper.h>
#include <OneWire.h>
#include <DallasTemperature.h>

//________________________________Pin Assign_______________________________//

// Define two steppers and the pins they will use
AccelStepper stepper1(AccelStepper::DRIVER, 9, 5);
//AccelStepper stepper2(AccelStepper::DRIVER, 7, 6);

#define ONE_WIRE_BUS_PIN 3
#define SENSOR_RESOLUTION 12

OneWire oneWire(ONE_WIRE_BUS_PIN);  // Setup a oneWire instance to communicate with any OneWire devices

DallasTemperature sensors(&oneWire);

//_____________________________Sensor Addresses____________________________//

DeviceAddress HS0 = {0x28, 0xFF, 0xDF, 0x1C, 0xA4, 0x16, 0x03, 0x9F};
DeviceAddress HS1 = {0x28, 0xFF, 0x1C, 0x0D, 0xA4, 0x16, 0x03, 0x44};
DeviceAddress HS2 = {0x28, 0xFF, 0xA1, 0x36, 0xA4, 0x16, 0x03, 0x3B};
DeviceAddress HS3 = {0x28, 0xFF, 0x04, 0x19, 0xA5, 0x16, 0x03, 0x9B};
DeviceAddress HS4 = {0x28, 0xFF, 0x7B, 0x18, 0xA5, 0x16, 0x03, 0x16};
DeviceAddress HS5 = {0x28, 0xFF, 0x07, 0xD0, 0x71, 0x16, 0x03, 0xF8};

//_____________________________Integers/Arrays_____________________________//

float HSA [6];
int solIn1 = 9;
int solOut1 = 10;
int solIn2 = 7;
int solOut2 = 8;
int curTemp0 = 0;
int curTemp1 = 0;
int prevTemp0 = 0;
int prevTemp1 = 0;

//___________________________________Setup________________________________//

void setup() {

 Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  sensors.begin();

Serial.print("Inflating balloons to 0 point...");


}

//__________________________TempPrint Function_____________________________//

void printTemperature(DeviceAddress deviceAddress) {
  
  float tempC = sensors.getTempC(deviceAddress);

  if (tempC == -127.00)
  {
    Serial.print("Error getting temperature  ");
  }
  else
  {
    Serial.print("C: ");
    Serial.print(tempC);
    Serial.print(" F: ");
    Serial.print(DallasTemperature::toFahrenheit(tempC));
  }
}

//________________________________sol1AirIn/Out Functions___________________________________//
 
  void decideSol1AirFlow () {
  if (curTemp0 > prevTemp0){
    digitalWrite(solIn1, LOW);
    digitalWrite(solOut1, HIGH);
    delay(prevTemp0 - curTemp0 * 1000); 
    digitalWrite(solIn1, LOW);
    digitalWrite(solOut1, LOW);
  }
    else if (curTemp0 < prevTemp0) {
      digitalWrite(solIn1, HIGH);
      digitalWrite(solOut1, LOW); 
      delay(curTemp0 - prevTemp0 * 1000);
      digitalWrite(solIn1, LOW); 
      digitalWrite(solOut1, LOW); 
    }

      else if (curTemp0 = prevTemp0) {
         digitalWrite(solIn1, LOW); 
         digitalWrite(solOut1, LOW); 
      }}

//________________________________sol2AirIn/Out Functions___________________________________//

 void decideSol2AirFlow () {
  if (curTemp1 > prevTemp1){
    digitalWrite(solIn2, LOW);
    digitalWrite(solOut2, HIGH);
    delay(prevTemp1 - curTemp1 * 1000); 
    digitalWrite(solIn2, LOW);
    digitalWrite(solOut2, LOW);
  }
    else if (curTemp1 < prevTemp1) {
      digitalWrite(solIn2, HIGH);
      digitalWrite(solOut2, LOW); 
      delay(curTemp1 - prevTemp1 * 1000);
      digitalWrite(solIn2, LOW); 
      digitalWrite(solOut2, LOW); 
    }

      else if (curTemp1 = prevTemp1) {
         digitalWrite(solIn2, LOW); 
         digitalWrite(solOut2, LOW); 
      }}
      
//________________________________Loop___________________________________//

void loop() {

int curTemp0 = sensors.getTempC(HS0);
int curTemp1 = sensors.getTempC(HS1);

  float HS0Temp = sensors.getTempC(HS0);
  float HS1Temp = sensors.getTempC(HS1);
  float HS2Temp = sensors.getTempC(HS2);
  float HS3Temp = sensors.getTempC(HS3);
  float HS4Temp = sensors.getTempC(HS4);
  float HS5Temp = sensors.getTempC(HS5);

  HSA [0] = HS0Temp;
  HSA [1] = HS1Temp;
  HSA [2] = HS2Temp;
  HSA [3] = HS3Temp;
  HSA [4] = HS4Temp;
  HSA [5] = HS5Temp;

  Serial.println();
  Serial.print("Number of Devices found on bus = ");
  Serial.println(sensors.getDeviceCount());
  Serial.print("Getting temperatures... ");
  Serial.println();

  // Command all devices on bus to read temperature
  sensors.requestTemperatures();

  Serial.print("HS0 temperature is:   ");
  printTemperature(HS0);
  Serial.println();
  Serial.print("HS0 array value is:   ");
  Serial.println(HSA [0], DEC);
  decideSol1AirFlow ();

  Serial.print("HS3 temperature is:   ");
  printTemperature(HS3);
  Serial.println();
  Serial.print("HS3 array value is:   ");
  Serial.println(HSA [3], DEC);
  decideSol2AirFlow ();
  
prevTemp0 = curTemp0;
prevTemp1 = curTemp1;

}

I haven't had a chance to try it yet but will upload in a few hours to my Arduino and see how it goes.

I have assigned temperature values from the sensors to curTemp and prevTemp in the loop. This should work.....?

I am still wondering how and where I might fit in the map and constrain functions (similar to the below code taken from an old stepper controlling code I wrote) to 20-30C. Any ideas?

int theTemp = HSA [3] * 10;
int newPosition = map(theTemp, 200, 300, 0, 4500);
newPosition = constrain(newPosition, 0, 4500);

How many temperature sensors are there in your system?

Do you need to declare the ROM Codes of the sensors when you are using DallasTemperature.h Library?

What type of motors are you using? Are they steppers or servos?

This is what your outline says to do:

#include <OneWire.h>
#include <DallasTemperature.h>


const byte SensorCount = 2;


#define ONE_WIRE_BUS_PIN 3
#define SENSOR_RESOLUTION 12


OneWire oneWire(ONE_WIRE_BUS_PIN);  // Setup a oneWire instance to communicate with any OneWire devices


DallasTemperature sensors(&oneWire);


DeviceAddress HSAddresses[SensorCount] =
{
  {0x28, 0xFF, 0xDF, 0x1C, 0xA4, 0x16, 0x03, 0x9F},
  {0x28, 0xFF, 0x04, 0x19, 0xA5, 0x16, 0x03, 0x9B}
};


float HSTemp[SensorCount];
const byte SolenoidInPins[SensorCount] = {9, 7};
const byte SolenoidOutPins[SensorCount] = {10, 8};




//-------------------------------------------------------//////////////////////------------------------------------------------------//


void setup()
{




  Serial.begin(9600);
  Serial.print("Initializing Temperature Control Library Version ");
  Serial.println(DALLASTEMPLIBVERSION);
  sensors.begin();


  for (int i = 0; i < SensorCount; i++)
  {
    AirStop(i);
    pinMode(SolenoidInPins[i], OUTPUT);
    pinMode(SolenoidOutPins[i], OUTPUT);
    HSTemp[i] = 20.0;  // Initial load represents 20°C
  }


  // 1. Start up
  // 2. Let air in to a certain 'base' point, lets call it 20C
  for (int i = 0; i < SensorCount; i++)
    AirIn(i);
    
  delay(5000);  // Initial air load.  Adjust time as needed.
  
  for (int i = 0; i < SensorCount; i++)
    AirStop(i);


}


//-------------------------------------------------------//////////////////////------------------------------------------------------//


void loop()
{
  sensors.requestTemperatures();


  for (int i = 0; i < SensorCount; i++)
  {
    // 3. Get the temp from sensor
    float newTemp = sensors.getTempC(HSAddresses[i]);


    // Constrain the temperature range
    if (newTemp < 20.0)
      newTemp = 20.0;
    if (newTemp > 30.0)
      newTemp = 30.0;


    // 4. Check if sensor temp is higher
    if (newTemp > HSTemp[i] && (newTemp - HSTemp[i]) > 0.5)
    {
      // 5. Let air in for 1 second per each degree
      // 8. if ABOVE what it previously was, let air IN for 1 second per difference in degree.


      // WARNING: if the air flow rate in each direction is not the same (and why would they be?)
      //  the balloon will eventually explode or become empty.  One way to work around the problem
      // to use differnt time values for inflate and deflate.      AirIn(i);


      AirIn(i);
      delay((newTemp - HSTemp[i]) * 1000);
      AirStop(i);
      
      HSTemp[i] = newTemp;
    }
    else if  (newTemp < HSTemp[i] && (HSTemp[i] - newTemp) > 0.5)
    {
      // 7. if BELOW what it previously was, let air OUT for 1 second per difference in degree.
 
      // WARNING: if the air flow rate in each direction is not the same (and why would they be?)
      //  the balloon will eventually explode or become empty.  One way to work around the problem
      // to use differnt time values for inflate and deflate.


      AirOut(i);
      delay((HSTemp[i] - newTemp) * 1000);
      AirStop(i);
      
      HSTemp[i] = newTemp;
    }
  }
}




void AirIn(int index)
{
  //Let air in to balloon
  digitalWrite(SolenoidInPins[index], HIGH);
  digitalWrite(SolenoidOutPins[index], LOW);
}


void AirOut(int index)
{
  // Let air out of balloon
  digitalWrite(SolenoidInPins[index], LOW);
  digitalWrite(SolenoidOutPins[index], HIGH);
}


void AirStop(int index)
{
  // Hold air in balloon
  digitalWrite(SolenoidInPins[index], LOW);
  digitalWrite(SolenoidOutPins[index], LOW);
}

This works perfectly it seems. I have wired everything up and the LEDs I have placed in circuit to indicate solenoid being sent a HIGH signal are responding as predicted. Thank you very very much!!!! I'll report back once I connect are dist. etc. and give it a whirl!

Again, thank you!