Help with Multitasking

Hi

I am trying to perform a few tasks with 5V pro mini, listed below:

a) Update display on LCD
b) Read values of 2 x 5K potentiometers (Sets time limit for Filling and Sealing)
c) Read values of 3 buttons (1 for Filling Job and 2 for Sealing Job)
d) Switch on the solenoids (1 for Filling Job and 2 for Sealing Job)
e) When Sealing Job is done increase the counter "totalSealed"

The issues I am facing are:

a) Either of the POTs are not setting correct time limit.
b) The LCD updates only once. The "totalSealed" value is not updated.

Here is the sketch:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4); 

//const byte lcdSense = 2;
//const byte lcdWrite = 3;
const byte npn1Seal = 4; 
const byte npnFill = 9; 
//const byte heaterReady = 10;
const byte sealButton1 = 11; 
const byte sealButton2 = 12; 
const byte fillPot = A0; 
const byte sealPot= A1; 
const byte npn2Seal = 16; 
const byte fillButton = 17;

// #####################   Variables for Debouncing  #################
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
int reading = HIGH; // Temporary variable for button read value
//int fillButtonVal;
//int sealButton1Val;
//int sealButton2Val;
int fillPotVal;
int sealPotVal;
int totalSealed = 0;
unsigned long startTimeFill;
unsigned long startTimeSeal1;
unsigned long startTimeSeal2;

void setup() 
{
  pinMode(fillButton,  INPUT_PULLUP);
  pinMode(sealButton1, INPUT_PULLUP);
  pinMode(sealButton2, INPUT_PULLUP);
 // pinMode(lcdSense,          OUTPUT);
 // digitalWrite(lcdSense,       HIGH);
 // pinMode(lcdSense,           INPUT);
 // pinMode(lcdWrite,          OUTPUT);
  pinMode(npnFill,           OUTPUT);
  pinMode(npn1Seal,          OUTPUT);
  pinMode(npn2Seal,          OUTPUT);
  pinMode(heaterReady,        INPUT);

 // while(lcdSense == HIGH);
 // {}
  digitalWrite(lcdWrite, HIGH);
  lcd.init();       
  lcd.backlight();  
  
  lcd.setCursor(0,1);
  lcd.print("Fill Time:      sec");
  lcd.setCursor(0,2);
  lcd.print("Seal Time:      sec");
  lcd.setCursor(0,3);
  lcd.print("Total Sealed:");
  digitalWrite(lcdWrite, LOW);

}

void loop()
{
  fillPotVal = map(analogRead(A0),0,1023,100,500);   //100-500
  sealPotVal = map(analogRead(A1),0,1023,500,1500);  //500-1500
  
  updateDisplay();
// while (digitalRead(heaterReady) == HIGH)
// {
//------------------Reading Buttons ---------------
    reading = digitalRead(fillButton); 
    debounceCheck();
    fillButtonVal = reading;
    
    reading = digitalRead(sealButton1); 
    debounceCheck();
    sealButton1Val = reading;
    
    reading = digitalRead(sealButton2); 
    debounceCheck();
    sealButton2Val = reading;

//--------------- Assigning Tasks ----------------
    if (fillButtonVal == LOW)
    {
      digitalWrite(npnFill, HIGH); // Switch ON solenoid A thru NPN
      startTimeFill = millis();
      fillButtonVal = HIGH;
    }

    if (sealButton1Val == LOW)
    {
      digitalWrite(npn1Seal, HIGH); // Switch ON solenoid B thru NPN
      startTimeSeal1 = millis();
      sealButton1Val = HIGH;
    }

    if (sealButton2Val == LOW)
    {
      digitalWrite(npn2Seal, HIGH); // Switch ON solenoid C thru NPN
      startTimeSeal2 = millis();
      sealButton2Val = HIGH;
    }

//---------------- Checking Timer for each Task ----------------
    if (millis() - startTimeFill >= fillPotVal)
    {
      digitalWrite(npnFill, LOW); //Switch OFF filling solenoid thru NPN
    }

    if (millis() - startTimeSeal1 >= sealPotVal)
    {
      digitalWrite(npn1Seal, LOW); //Switch OFF sealing solenoid thru NPN
      totalSealed = +1;
    }

    if (millis() - startTimeSeal2 >= sealPotVal)
    {
      digitalWrite(npn2Seal, LOW); //Switch OFF sealing solenoid 2 thru NPN
      totalSealed = +1;
    }
//  }
   
}

void updateDisplay()
{
  //while (lcdSense == HIGH)
  //{}
  //digitalWrite(lcdWrite, HIGH);
  lcd.setCursor(11,1);
  lcd.print(fillPotVal/1000);
  lcd.setCursor(11,2);
  lcd.print(sealPotVal/1000);
  lcd.setCursor(14,3);
  lcd.print(totalSealed);
//  digitalWrite(lcdWrite, LOW);
}

// ##################### Debounce ##############
void debounceCheck()
{
  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  if (reading != lastButtonState) // if Switch status changed pressed or noise
  {
    lastDebounceTime = millis(); // reset the debouncing timer
  }

  // if Longer than the debounce delay, switch really pressed
  if ((millis() - lastDebounceTime) > debounceDelay) 
  {
    if (reading != buttonState) 
    {
      buttonState = reading;
    }
  }

  lastButtonState = reading;
}

Did you mean

totalSealed += 1;

Hint: an integer less than 1000, divided by 1000 will always be zero.

You need some Serial.print() statements in your program so you can check the values and the parts of the code that are being activated.

...R

Hi,

const byte npn2Seal = 16;
const byte fillButton = 17;

Where are these pins, you need to use the Arduino IDE I/O numbers.
They are printed on the PCB.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :slight_smile:

Hi,
In your display function, you are overwriting old data, if you have a two digit number displayed then over write it with a single digit, the second digit of the old data will still be displayed.
So if you had "99" then next update wanted to display "1", you would actually display "19".
The trick is to display and number of blank places over the old data just before adding the new.

void updateDisplay()
{
  //while (lcdSense == HIGH)
  //{}
  //digitalWrite(lcdWrite, HIGH);
  lcd.setCursor(11,1);
  lcd.print(fillPotVal/1000);
  lcd.setCursor(11,2);
  lcd.print(sealPotVal/1000);
  lcd.setCursor(14,3);
  lcd.print(totalSealed);
//  digitalWrite(lcdWrite, LOW);
}

So,

void updateDisplay()
{
  //while (lcdSense == HIGH)
  //{}
  //digitalWrite(lcdWrite, HIGH);
  lcd.setCursor(11, 1);
  lcd.print("    ");
  lcd.setCursor(11, 1);
  lcd.print(fillPotVal / 1000);
  lcd.setCursor(11, 2);
  lcd.print("    ");
  lcd.setCursor(11, 2);
  lcd.print(sealPotVal / 1000);
  lcd.setCursor(14, 3);
  lcd.print("    ");
  lcd.setCursor(14, 3);
  lcd.print(totalSealed);
  //  digitalWrite(lcdWrite, LOW);
}

This may be why your pot values look in error.

Tom... :slight_smile:

But zero overwritten with zero always looks the same, as does one, overwritten with one. :wink:

TheMemberFormerlyKnownAsAWOL:
Did you mean

totalSealed += 1;

If I use

totalSealed += 1;

or

totalSealed++;

or

totalSealed = totalSealed + 1;

the display would keep on increasing the value, even not a single button is pressed.

TomGeorge:
Hi,

const byte npn2Seal = 16;

const byte fillButton = 17;



Where are these pins, you need to use the Arduino IDE I/O numbers.
They are printed on the PCB.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :)

Pin A0 can also be used as digital pin 14, A1 as 15, A2 as 16, A3 as 17, A4 as 18 and A5 as 19.

TomGeorge:
Hi,
In your display function, you are overwriting old data, if you have a two digit number displayed then over write it with a single digit, the second digit of the old data will still be displayed.
So if you had "99" then next update wanted to display "1", you would actually display "19".
The trick is to display and number of blank places over the old data just before adding the new.

void updateDisplay()

{
  //while (lcdSense == HIGH)
  //{}
  //digitalWrite(lcdWrite, HIGH);
  lcd.setCursor(11,1);
  lcd.print(fillPotVal/1000);
  lcd.setCursor(11,2);
  lcd.print(sealPotVal/1000);
  lcd.setCursor(14,3);
  lcd.print(totalSealed);
//  digitalWrite(lcdWrite, LOW);
}



So,


void updateDisplay()
{
  //while (lcdSense == HIGH)
  //{}
  //digitalWrite(lcdWrite, HIGH);
  lcd.setCursor(11, 1);
  lcd.print("    ");
  lcd.setCursor(11, 1);
  lcd.print(fillPotVal / 1000);
  lcd.setCursor(11, 2);
  lcd.print("    ");
  lcd.setCursor(11, 2);
  lcd.print(sealPotVal / 1000);
  lcd.setCursor(14, 3);
  lcd.print("    ");
  lcd.setCursor(14, 3);
  lcd.print(totalSealed);
  //  digitalWrite(lcdWrite, LOW);
}





This may be why your pot values look in error.


Tom... :)

Thanks for the tip however, formatting the output on the LCD is a secondary issue.
What I am experiencing is that the POTs are assigning the maximum mapped values as the time limit, irrespective of the position of the wipers.

abuhafss:
Thanks for the tip however, formatting the output on the LCD is a secondary issue.
What I am experiencing is that the POTs are assigning the maximum mapped values as the time limit, irrespective of the position of the wipers.

You need to post a picture, or a diagram, of the circuit. If the analogRead of A0 and A1 produce 1024 every time, then they're getting a fixed voltage and not varying.

As someone else stated, you can enable serial monitoring, and place some serial.Println statements in at strategic places in your code, so you can see what values are being read at specific times during the run.

Hi,
There is a debounce library that might be easier to use.
[iur]https://www.arduinolibraries.info/libraries/bounce2[/iurl]

Did you write this code in stages, getting each stage to work before going onto the next, then putting them together one at a time.

You should have some code that JUST reads the pots and prints the result to serial monitor to verify your code and circuit construction.

If not, then write one and verify your pot operation.
Do you have a DMM to confirm t he changing voltage at the analog inputs to the ProMini?

Tom.. :slight_smile:

abuhafss:
If I use

totalSealed += 1;

or

totalSealed++;

or

totalSealed = totalSealed + 1;

the display would keep on increasing the value, even not a single button is pressed.

So, can you confirm that you're happy with totalSealed being assigned the value +1 repeatedly?

TheMemberFormerlyKnownAsAWOL:
So, can you confirm that you're happy with totalSealed being assigned the value +1 repeatedly?

Of course not.

Stoopalini:
You need to post a picture, or a diagram, of the circuit. If the analogRead of A0 and A1 produce 1024 every time, then they're getting a fixed voltage and not varying.

Here you go with the schematic.

Stoopalini:
If the analogRead of A0 and A1 produce 1024 every time, then

...you've got really big problems.

abuhafss:
Of course not.

So what should happen?

Please try to be more forthcoming - don't make us extract information from you.

It looks like your potentiometers are wired ok ... tough to tell without the entire diagram though.

These statements will continually be true, since nothing is causing them to become untrue. Basicaly, you're saying: "if current time, minus time stored in Seal variables, is greater than or equal to sealPotVal then ..."

    if (millis() - startTimeSeal1 >= sealPotVal)
    {
      digitalWrite(npn1Seal, LOW); //Switch OFF sealing solenoid thru NPN
      totalSealed = +1;
    }

    if (millis() - startTimeSeal2 >= sealPotVal)
    {
      digitalWrite(npn2Seal, LOW); //Switch OFF sealing solenoid 2 thru NPN
      totalSealed = +1;
    }

After those becomes true, and the current time is increasing ... the time store in starTimeSeal1 (and 2) stays fixed until the button is pressed again. So both statements will continue to be true, and the totalSealed value will keep incrementing (assuming you fix the statement to be += or ++, etc ...)

Hi,
Can you post a picture of your project please, so we can see your component layout.

With a DMM, measure the voltage at the 3 terminals of the potentiometer and tell us what you get with the pot turned fully clockwise then fully anti-clockwise.

Thanks.. Tom... :slight_smile:

Hi,
Can you try this code on your project please
Open the IDE Serial Monitor and set the baud rate to 115200.
What is displayed as you adjust the potentiometers?

int fillPin = A0;
int sealPin = A1;
int fillVar = 0;
int sealVar = 0;


void setup()
{
  Serial.begin(115200);
}


void loop()
{
  fillVar = analogRead(fillPin);
  sealVar = analogRead(sealPin);
  Serial.print("Fill Pot ");
  Serial.print(fillVar);
  Serial.print("\tSeal Pot ");
  Serial.println(sealVar);
  delay(500);
}

Thanks.. Tom... :slight_smile:

TheMemberFormerlyKnownAsAWOL:
So what should happen?

Please try to be more forthcoming - don't make us extract information from you.

I am sorry for that.