Go Down

Topic: Case does not follow number call up (Read 308 times) previous topic - next topic

elmo2002

That's what I meant. The default case executes any time there is not a matching case above. If commandState got to be a value of 12, then default would execute.

You don't need #define default 6. Can you remove it and see if the serial output changes.

Based on the serial output the FillHeat case doesn't execute a single time. Furthermore it appears that no case is executing. I can't wait to find out what stupid little thing has been overlooked.

Thanks, I now understand what the default would do.
I have removed the #define default 6, also realised that I had to remove case from case default. I ran the code again and the serial monitor comes back the same.

That was my feeling that for some reason the FillHeat case doesn't execute at all. I have tried changing the commandstate at the end of Fill to complete and relay and the same still happens.

On an irrelevant note, why do you alternate between lcd.setCursor(0,0) and selectLineOne (or 0,1 and LineTwo)?

I thought it may be an easier way to select the lines on the lcd screen that way, I just ran into this problem before changing the whole script. its sloppy sorry

elmo2002

Also thank you for your suggestions so far.

adwsystems

The next suggestion I would have is to either

(a) change #define to int

or

(b) change all of the state names to hard coded numbers

at least to see what happens.

I'm still hoping it is something tiny we have missed (I'm sure it is but can't see it yet).

DKWatson

so would I be better off making pulseCount a global variable so that it will be incremented/changed in any case that I wish to reference it in?
That would be my suggestion. It doesn't discount the fact though, that pulseCount is never updated anywhere outside from the Fill case. Testing to be > (stopCount/2) to switch state from Fill to FillHeat means that when entering FillHeat the value of pulseCount is (stopCount/2) + 1. Without further change it will never be > stopCount therefore it will never enter the code segment that will change state to Complete.
Live as if you were to die tomorrow. Learn as if you were to live forever. - Mahatma Gandhi

adwsystems

#19
Sep 26, 2018, 02:52 am Last Edit: Sep 26, 2018, 03:00 am by adwsystems
That would be my suggestion. It doesn't discount the fact though, that pulseCount is never updated anywhere outside from the Fill case. Testing to be > (stopCount/2) to switch state from Fill to FillHeat means that when entering FillHeat the value of pulseCount is (stopCount/2) + 1. Without further change it will never be > stopCount therefore it will never enter the code segment that will change state to Complete.
That's after the fact that it does not even execute the first line of the FillHeat case. Notice from the serial output posted, there should be a final '3' printed from the first step of FillHeat. FillHeat case doesn't execute, let alone end.

cattledog

Quote
That's after the fact that it does not even execute the first line of the FillHeat case. Notice from the serial output posted, there should be a final '3' printed from the first step of FillHeat. FillHeat case doesn't execute, let alone end.
I can't confirm that from the latest posted code. I have set the pulseCount values to levels which will advance the case and added some delays to see what was going on.The code below advances through the states and shows it on both the lcd and serial monitor.

I have used a different display library for the lcd.

Code: [Select]
//----Libraries------
//#include <LiquidCrystal_I2C.h>


#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header

hd44780_I2Cexp lcd;
//-----Defines-----
#define I2C_ADDR    0x3F
#define BACKLIGHT_PIN 3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7


//Define all the command states
#define ON 0
#define Ready 1
#define Fill 2
#define FillHeat 3
#define Complete 4
#define Relay 5
#define default 6


//LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);   //Name lcd pins



//-----CONSTANTS----- (wont change)
const int Startswitch = 3;
const int waterInRelay = 4;
const int heaterRelay = 5;
const int mixPumpRelay = 6;
const int R1 = waterInRelay;
const int R2 = heaterRelay;
const int R3 = mixPumpRelay;

//-----VARIABLES----- (will change)
int commandState = ON; //0=ON, 1=Ready, 2=Fill, 3=Fill/Heat, 4=Complete, 5=Relay, 6=default


//-----Intrupt counter-----
volatile unsigned long isrCounter;
unsigned long pulseCount;
unsigned long pulseCount2;
// Flow sensor FL-S402B = 600 pulses/l
// Flow sensor YF-S201 = 450 pulses/l
int calFactor = 600;
// convert pulses to litres
unsigned long waterVol = (pulseCount+pulseCount2)/calFactor;
// Set volume to stop at = required volume in ltr x calFactor
unsigned long stopCount = 600;//**** SET FOR 1Ltr****

void setup() {

  Serial.begin(9600);

  pinMode(Startswitch, INPUT_PULLUP);   //configure pin 2 as an input and enable the internal pull-up resistor

  //configure outputs
  pinMode(R1, OUTPUT);
  digitalWrite (R1, HIGH);

  // Set LCD
  lcd.begin (16, 2);
  //lcd.setBacklightPin(BACKLIGHT_PIN, POSITIVE);
  //lcd.setBacklight(HIGH);
  lcd.home ();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print ("Flow counter");     // signal initalization done
  lcd.setCursor(0, 1);
  lcd.print ("starting");
  delay (3000);
  lcd.clear();

 
  attachInterrupt(0, countP, RISING);

}  // End of setup


void loop() {
  bool Startbuttonstate = digitalRead(Startswitch);
  //Serial.println(Startbuttonstate);                      //print out the value of the pushbutton
 
  switch (commandState) {

    //----------------------
    case ON:
      Serial.println("Running ON case");
      Serial.println(commandState);
     
      clearLCD();
      for (int ONi = 3; ONi > 0; ONi--) {  //count down from 3
        selectLineOne();
        lcd.print("Elmo Industries");
        selectLineTwo();
        lcd.print("   Hello Dave");
        delay (1000);
      }

      commandState = Ready;
      Serial.println("commandState = ready");
      delay(500);


      break;
    //---------------------
   
    case Ready:
      Serial.println("Ready case running");
      Serial.println(commandState);

      clearLCD();
      selectLineOne();
      //delay(100);
      lcd.print("Push button");     //Notify user that the system is ready
      selectLineTwo();
      lcd.print("to start");

      //if (Levelsensorstate) {   //(Levelsensorstate == HIGH) {   //check to make sure container is not already filled
      //LevelActivated();
      //delay(500);                      //blanked out as seems to be tripping even tho switch not made
      if (Startbuttonstate) {    //(Startbuttonstate == HIGH) {    //Wait for start button to be pressed
        Serial.println("waiting for button press");
        commandState = Ready;
        delay(500);

      } else { //if start button is pressed start fill.

        Serial.println("button pressed");
        clearLCD();
        selectLineOne();
        delay(100);
        lcd.print("   Starting");
        delay(2000);
        clearLCD();
        commandState = Fill; //Start flush countdown
        Serial.println("commandState = Fill");
      }

      break;
    //-------------------------
   
    case Fill:
      Serial.println("Running Fill case");
      Serial.println(commandState);
      digitalWrite (R1, LOW);             //water in relay on, solenoid open
      delay(100);
      noInterrupts();
      //long pulseCount = isrCounter;
      pulseCount = isrCounter;
      interrupts();
      pulseCount =400;
      lcd.setCursor(0,0);
      lcd.print("Total Vol");
      lcd.print (pulseCount);
      lcd.setCursor(0,1);
      lcd.print(waterVol);
      lcd.print(" Ltrs");
      delay(3000);
      if (pulseCount > (stopCount/2))
      {
        lcd.clear();
        selectLineOne();
        lcd.print("Starting Heat");
        selectLineTwo();
        lcd.print("and Mix");
        delay(3000);
        Serial.println("start heat mix");
        commandState = FillHeat; //set command state to fill and heat
        Serial.println(commandState);
        Serial.println("command state changed fill heat");
      }

      break;
      //----------------------

      case FillHeat:
      Serial.print("Entering Fill Heat");
      Serial.println(commandState);
      digitalWrite (R1, LOW);             //water in relay on, solenoid open
      digitalWrite (R2, LOW);             //water heater on, solenoid open
      digitalWrite (R3, LOW);             //mixing pump on, solinoid open
      delay(100);
      noInterrupts();
      //long pulseCount2 = isrCounter;
      pulseCount2 = isrCounter;
      interrupts();
      pulseCount2 = 700;
      lcd.setCursor(0,0);
      lcd.print("Total Vol");
      lcd.print (pulseCount2);
      lcd.setCursor(0,1);
      lcd.print(waterVol);
      lcd.print(" Ltrs,Heat on");
      delay(3000);
      if (pulseCount2 > stopCount)
      {
        digitalWrite (R1, HIGH);
        lcd.clear();
        selectLineOne();
        lcd.print("Fill stopped");
        selectLineTwo();
        lcd.print(waterVol);
        lcd.print(" Litres");
        delay(3000);
        Serial.println("complete fill");
        commandState = Complete; //set command state to complete
        Serial.println("state switched");
        Serial.println(commandState);
      }

      break;
      //----------------------
     
    case Complete:
      clearLCD();
      selectLineOne();
      delay(500);
      lcd.print("  Water fill");
      selectLineTwo();
      lcd.print("  completed!");
      delay (2000);
      commandState = Ready;

      break;
      //------------------------------

   case Relay:
      Serial.println(commandState);
      digitalWrite (R1, LOW);
      delay (1000);
      digitalWrite (R1, HIGH);
      delay (1000);

      break;
      //-----------------------------
     
    case default:
   
    Serial.println("Default Case Error");
   
    break;
  }

}  // end of loop

void countP()
{
  isrCounter++;
}

void clearLCD() {
  lcd.setCursor(0, 0);
  lcd.clear();
}

void selectLineOne() { //puts the cursor at line 0 char 0.
  lcd.setCursor(0,0); //position
}
void selectLineTwo() { //puts the cursor at line 0 char 0.
  lcd.setCursor(0,1); //position
}

adwsystems

@cattledog, can you post your serial monitor output so all can see the difference. Thx.

cattledog

Quote
@cattledog, can you post your serial monitor output so all can see the difference. Thx.
Serial Monitor output from code posted

Code: [Select]
Running ON case
0
commandState = ready
Ready case running
1
waiting for button press

button pressed
commandState = Fill
Running Fill case
2
start heat mix
3
command state changed fill heat
Entering Fill Heat3
complete fill
state switched
4
Ready case running
1
waiting for button press

adwsystems

#23
Sep 26, 2018, 07:15 pm Last Edit: Sep 26, 2018, 07:17 pm by adwsystems
elmo2002 doesn't show any of the following
Code: [Select]
Entering Fill Heat3
complete fill
state switched
4
Ready case running
1
waiting for button press


The final output is "command state changed fill heat", we never see any of the above. There should be at least a 3 printed (the output "Entering Fill Heat" was added by @cattledog) to indicate the execution of the FillHeat case. A lot was changed to allow @cattledog to run it, do we think a problem was fixed by accident?

@elmo2002, can you change cattledog's code back to use your lcd library. Don't make any other changes than to the lcd, don't worry about your sensor or counter, just make the lcd changes and see what happens?

Go Up