mode switch problems

Building a coil winder and having problem with the mode switch that I want to change from setup to run mode.

Code, details and circuit layout attached.
Tried to write more detail here but the editor spat it out. So detail is in the txt file.

/*Arduino pro mini code to run a menu for the ignition coil winder started April 11 2020.....this version 30_4_2020
   Setup in this version uses a 20*4 LCD Display...simpler than using a 16*2 and a menu system
   Uses a 4x4 matrix keypad (3 x 3 used) to change the values of bobbin width, wire size and total turns.
   Keypad as per.... press "0-9" ....input number (10's 100's and 1000's selected in code)
                     press "#" ......ENTER
                     press "*" ......Cancel or Delete

   At this stage the primary winding will be around 364 turns of 28awg (0.0126" diameter)on a bobbin of 0.35" inside diameter.
   End plates are at 0.95" diameter which should be sufficient.
   Length of the bobbin inside 1.15"
   ************************************************************
   On 1 particular coil
   The latter allows for 1.15"/28awg wire (0.0126") = 91 turns each layer for total 364 turns.
   The secondary wire is 2 thou 44awg so 1.15/0.002" =  575 turns per layer for total of 12,075 turns.
   ************************************************************

   For others, setting up will require
                      (1) Manual or Auto.... manual runs just bobbin motor
       DISPLAY No.1 = (2) Bobbin inside width ...in conjunction with wire size determines turns per layer
       DISPLAY No.1 = (3) Wire size (diameter)
       DISPLAY No.1 = (4) Total secondary turns
                  *********************************************************************
                    Perhaps a switch will be necessary to isolate any setting up values
                    from being changed when the program runs (Setting/Running)
                  *********************************************************************
   Variables required for ..........
                          Turns per Layer (layerTurns)
                          Number of Layers (numLayers)
                          Stepper Speed for Bobbin motor via foot switch (use accel library with extra speed control pot)
                          Stepper speed for the feed motor ...this would be calculated from above speed and wire size

                          Number for both the Bobbin width and the wire size will be whole numbers
                          Idea is to display whole number for Bobbin width then display /100
                          Then display a float number after that e.g. 115/100 = 1.15in
                          So take the array number and change to a float variable
                          bW for bobbin width
                          wS for wire size

*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // for the displays
LiquidCrystal_I2C lcd1 (0x27, 20, 4); //for 2 LCD setup parameters screen
LiquidCrystal_I2C lcd2 (0x25, 16, 2); //for 2 LCD running screen ...probably just for Total turns

#include <Keypad_I2C.h> // for the keypad ...used a 4*4 but only using 4*3
#define keypad_addr 0x20 // keypad expander module (A0, A1, A2 DIP switches set to OFF)PCF_8574T
const byte ROWS = 4; // keypad has 4 rows
const byte COLS = 3; // keypad has 3 columns

//define the keys of the keypad
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'} // * is the delete or clear screen and # is the ENTER value key
};
//keypad pins connected to the I2C_Expander unit pins P0-P6
byte rowPins[ROWS] = {0, 1, 2, 3}; // connect P0-P3 to the row R1,R2,R3,R4 pinouts of the keypad
byte colPins[COLS] = {4, 5, 6}; // connect P4-P6 to columns C1,C2,C3 pinouts of the keypad
//create instance of the keypad name I2C_Keypad and using the PCF8574 chip
Keypad_I2C I2C_Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS, keypad_addr, PCF8574);

//*************************************************
//END of Keypad stuff
//*************************************************

// Arduino pro mini I2C pins A4 to SDA, A5 to SCL for both LCD's and the PCF8574
float bW = 0; //bobbin width in 2 decimal places in inches
float wS = 0; // wire size in thou inch
int totalTurns = 0;// total number of turns to be wound

//Switches and/or pushbuttons
const int modeSw = 10;//pin 10 on Arduino
int modeSwState; //current set run switch state
int lastmodeSwState;//previous set run switch state

void setup() {
  I2C_Keypad.begin(); // initiate keypad
  Serial.begin(9600); // for testing
  pinMode(modeSw, INPUT_PULLUP); // for set run switch
  lcd1.init(); // initiate lcd 1
  lcd2.init(); // initiate lcd 2
  lcd1.backlight(); //same
  lcd2.backlight(); // same
  updateDisplay_1(); // attempt to only write when needed




}

void loop() {
  modeSwState = digitalRead(modeSw); //read the mode switch state
  Serial.print("mode switch state =");
  Serial.println (modeSwState);
  delay(1000);
  Serial.print("last mode switch state was = ");
  Serial.println(lastmodeSwState);
  delay(1000);
  //now compare the current state with the last state
  if (modeSwState != lastmodeSwState) {
    if (modeSwState == HIGH) {
      lcd2.clear();
      Serial.println("MODE SWITCH IN SETUP");


      keySet();
    }

    delay(1000);

  }

  if (modeSwState == lastmodeSwState) {
    if (modeSwState == LOW) {
      Serial.println("MODE SWITCH NOW IN RUN MODE");
      lcd2.setCursor(0, 0);
      lcd2.print("MODE SW IN RUN");
      lcd2.setCursor(0, 1);
      lcd2.print("CHANGE MODE SW");
    }
  }
  lastmodeSwState = modeSwState;
}


void keySet() {
  for (int i = 0; i < 4; i++) { //go through the key and if more than 3, revert back to bW
    bW = GetNumber();
    Serial.print("bW = ");
    bW = bW / 100; // need a fraction such as number input 115, this will equal 1.15
    Serial.println (bW); //check
    lcd1.setCursor(15, 0);// set the cursor 1st line at position past == sign
    lcd1.print(bW);  // print the value there
    wS = GetNumber(); // same for wire size
    Serial.print("wS = ");//check
    wS = wS / 1000;// wire size input becomes thou of an inch
    Serial.println(wS, 3);// check
    lcd1.setCursor(12, 1);// same as above for value to be printed past the equal on 2nd line of display
    lcd1.print(wS, 3); // print 3 decimal places on display
    totalTurns = GetNumber(); // now for required turns
    Serial.print ("TURNS = "); //check
    Serial.println(totalTurns);//check
    lcd1.setCursor(13, 2); // now print a set of spaces to the turns position in case a second input
    lcd1.print("       "); // of numbers...say 12000 now becomes 500..this wipes out the previous zeros
    lcd1.setCursor(13, 2); // set back to same place
    lcd1.print(totalTurns);// now input the total turns required


    Serial.println("ALL INPUTS FINISHED");
    lcd2.print("ALL INPUTS DONE ");

    if (digitalRead(modeSw) == LOW) {
      Serial.println("Mode sw now LOW = RUN POSITION");
      runMode();
    }
    Serial.println("ARRIVED HERE");
  }


}

int GetNumber() //get the number from the key press
{
  lcd2.print("ENTER No.= ");
  int num = 0;
  char key = I2C_Keypad.getKey();
  while (key != '#')// while the ENTER key is not pressed
  {
    switch (key)
    {
      case NO_KEY:
        break;

      case '0': case '1': case '2': case '3': case '4':// go through the list of cases
      case '5': case '6': case '7': case '8': case '9':// and find which key was pressed
        lcd2.print(key);
        num = num * 10 + (key - '0'); // take 48 from the char to give correct value
        break;                        // e.g. press 1 gives 49 so -'0' value (48) = 1

      case '*': // delete buton and start input again
        num = 0;
        lcd1.clear();
        updateDisplay_1();// rewrite the screen on lcd 1
        keySet();// go back to the key inputs
    }
    key = I2C_Keypad.getKey();
  }
  if (key == '#') {
    lcd2.clear(); // if the ENTER key is pressed, the input numbers displayed on lcd 2 are now cleared
  }
  return num;
}

void updateDisplay_1() {
  lcd1.print("BOBBIN WIDTH = ");
  lcd1.setCursor(0, 1);
  lcd1.print("WIRE SIZE = ");
  lcd1.setCursor(0, 2);
  lcd1.print("TOTALTURNS = ");
}

void runMode() {
  lcd2.clear();
  lcd2.print("Back in RUN MODE");
}

Winder query.txt (1.36 KB)

“Having a problem” is not a good description of your problem.

  1. What did you try?
  2. What did you expect to see (voltages, debug output)?
  3. What did you actually see (Voltages, debug output)?
  4. How did you test this?
    Edit, okay I see you included some details in the text file, sorry.
    Could you post the entire debug output please?

Your code looks unbalanced to me. Why is this code...

if (modeSwState == lastmodeSwState) {
    if (modeSwState == LOW) {
      Serial.println("MODE SWITCH NOW IN RUN MODE");
      lcd2.setCursor(0, 0);
      lcd2.print("MODE SW IN RUN");
      lcd2.setCursor(0, 1);
      lcd2.print("CHANGE MODE SW");
    }
  }

Checking for modeSwState == lastmodeSwState when the previous code checks for modeSwState != lastmodeSwState?
It may work, but it’s not great idea to go updating the LCD when nothing has changed.

pcbbc:
Edit, okay I see you included some details in the text file, sorry.
Could you post the entire debug output please?

Your code looks unbalanced to me. Why is this code...

if (modeSwState == lastmodeSwState) {

if (modeSwState == LOW) {
      Serial.println("MODE SWITCH NOW IN RUN MODE");
      lcd2.setCursor(0, 0);
      lcd2.print("MODE SW IN RUN");
      lcd2.setCursor(0, 1);
      lcd2.print("CHANGE MODE SW");
    }
  }



Checking for modeSwState == lastmodeSwState when the previous code checks for modeSwState != lastmodeSwState?
It may work, but it’s not great idea to go updating the LCD when nothing has changed.

What do you mean by the entire debug ...all of the serial prints..??
Does not seem to be any way to copy it.
Anyhow, all the details of the readout are in the txt file.

The quoting of the extra code for the mode state was to see how far the program was advancing and to see if the mode switch change was being detected.

Use Ctrl-C to copy the highlighted text to the clipboard.

All the details are not there because we don’t know if it prints...
Serial.println("Mode sw now LOW = RUN POSITION");
And/or then:
Serial.println("ARRIVED HERE");

It must do one of those two things.

Or indeed what the main loop is doing.

Here’s one problem...
Loop calls keyset...
keyset calls GetNumber...
GetNumber calls keyset...

 keySet();// go back to the key inputs

Your comment there seems to imply a fundamental misunderstanding about what calling the same function you just came from actually does.
Hint: It does NOT go back. It creates a nested call.
The correct way to “go back” is use the return statement.

Well it is assembled as many project are, from existing code pieced together.
Original code for the keypad was just that, just the keypad which entered numbers into the display, nothing else.

So sort of assumed it had to be associated with the way that was written.Poked serial prints all over the place and wrote to the LCD's in just as many to try to see where it was but no luck.

Question is how to change it so it escapes the key input, because at present, the whole idea of disabling the keypad input after it has the required 3 variables is not working that way.

Yes, tried that Ctrl_C but it doesn't work quite a few times. Then I read where sometimes Ctrl_A first and then Crtl_C with autoscroll disabled...... then suddenly I was able to highlight part with the mouse and then hit Ctrl-C and that worked...some bug in the IDE I read.
Anyhow....managed to get the readout below.
Ahhh..crap...only accepts certain file types not rtf.
Try this......

Debug.txt (591 Bytes)

It's because your keySet routine loops 4 times...

for (int i = 0; i < 4; i++)

So it's just going back around the loop again.

if you want out after the switch is low, you need a return or break statement where I have indicated...

   if (digitalRead(modeSw) == LOW) {
      Serial.println("Mode sw now LOW = RUN POSITION");
      runMode();
      // return; or break; here
    }

pcbbc:
It's because your keySet routine loops 4 times...

for (int i = 0; i < 4; i++)

So it's just going back around the loop again.

if you want out after the switch is low, you need a return or break statement where I have indicated...

   if (digitalRead(modeSw) == LOW) {

Serial.println("Mode sw now LOW = RUN POSITION");
      runMode();
      // return; or break; here
    }

Yes, I put the 3 times around there for a good reason, to fill in 3 variables.

Pretty certain I tried an escape like you suggested but i'll have another look.

pcbbc:
if you want out after the switch is low, you need a return or break statement where I have indicated...

   if (digitalRead(modeSw) == LOW) {

Serial.println("Mode sw now LOW = RUN POSITION");
      runMode();
      // return; or break; here
    }

No, that didn't work.