Using Keypad to name file?

I tried searching various approaches to this and got nothing. I assume it can be done with a long series of "if" statements, but I don't want to push through it all to find out I can't.

I also can't believe this isn't a more common question. But hey, that's my curse when attempting projects, I guess.

So I want to input 5 or so characters as the datalogger file name when starting up the program. All the test examples of keypad coding is in the loop. I know I need to "create" the string of digits to act as the file name before the code can create it and reference it.

I also plan on using the keypad to set parameters for the loop, but I'm trying to attack this whole project one step at a time. I keep having component failures and I'm pulling my hair out with all these road blocks. I couldn't fathom this would be an issue, but again, here I am.

Thank y'all for the input. I was excited to start this project and have learned a lot so far.

You can keep a flag in loop() that checks if you already entered a filename; something like

void loop()
{
  static bool firstRun = true;


  if (firstRun == true)
  {
    get thefilename

    firstRun = false;
  }
1 Like

This should do it:

#include <Keypad.h>

const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};

uint8_t colPins[COLS] = { 5, 4, 3, 2 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 9, 8, 7, 6 }; // Pins connected to R1, R2, R3, R4

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

String Filename = "";
boolean FilenameComplete = false;
const byte maxFilenameLength = 8;

void setup() {
  Serial.begin(9600);
  Serial.println("Press * to start input of filename or reset the input");
  Serial.println("Press # to stop input of filename");
}

void loop() {
  ReadFileName();
  if (FilenameComplete) {
    Serial.print("The Filename is:\t");
    Serial.println(Filename);
    FilenameComplete = false;
  }
}

void ReadFileName(){
  static boolean GetFileName = false;
  char key = keypad.getKey();
  if (key == '*') { 
    GetFileName = true;
    Filename = "";
    key = NO_KEY;
    Serial.println("\nStart of Input");
  } 
  if (GetFileName) {
    if (key == '#' || Filename.length() >= maxFilenameLength) {
      GetFileName = false;
      if (Filename.length() > 0) FilenameComplete = true;
                            else FilenameComplete = false;
      key = NO_KEY;
      Serial.println("\nEnd of Input");
      }
    if (key != NO_KEY){
      Filename += key;
      Serial.print(key);
    }
  }  
}

If you like to test it, you can do that on Wokwi:

https://wokwi.com/projects/331913021697819219

Good luck :wink:

1 Like

So if I'm thinking about this correctly, I can use that to sort of containerize the typing of the name and incorporate an
"if #acting as enter in this case then firstrun = false."
to then trigger then next run. Which, now that I think about it, could be another static bool as "second run" that gets switched on to ask the next question, etc.

Alright, cool. I think I can work with that.

If you want to be able to input Filename all the time while your Arduino is running you can use the sketch from my post #3.

If you want to do it only once every time you startup the controller, your sketch could be like this:

#include <Keypad.h>

const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};

uint8_t colPins[COLS] = { 5, 4, 3, 2 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 9, 8, 7, 6 }; // Pins connected to R1, R2, R3, R4

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

String Filename = "";
boolean FilenameComplete = false;
const byte maxFilenameLength = 8;

void setup() {
  Serial.begin(9600);
  Serial.println("Press * to start input of filename or reset the input");
  Serial.println("Press # to stop input of filename");
  while (!FilenameComplete){
    ReadFileName();
  }
  Serial.print("The Filename is:\t");
  Serial.println(Filename);
  Serial.println("Starting the loop() ...");
}

void loop() {
}

void ReadFileName(){
  static boolean GetFileName = false;
  char key = keypad.getKey();
  if (key == '*') { 
    GetFileName = true;
    Filename = "";
    key = NO_KEY;
    Serial.println("\nStart of Input");
  } 
  if (GetFileName) {
    if (key == '#' || Filename.length() >= maxFilenameLength) {
      GetFileName = false;
      if (Filename.length() > 0) FilenameComplete = true;
                            else FilenameComplete = false;
      key = NO_KEY;
      Serial.println("\nEnd of Input");
      }
    if (key != NO_KEY){
      Filename += key;
      Serial.print(key);
    }
  }  
}

Again on Wokwi: https://wokwi.com/projects/331913710750663251

The maximum length is set to 8, you can easily change this by adjusting the line

const byte maxFilenameLength = 8;

to 5 or whatever you want ...

1 Like

Thank you, ec2021. I guess it didn't update to show your first post.

This puts it all in context, which is much easier for me to read. Yes, the plan is to name the file once and only once per power cycle.

This is to test compressors. The general idea is to hook everything up, plug it all in, name the file, set number of cycles for the compressor to run, and then record data as it runs the selected number of cycles.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.