Moving oft used code to a library

Good Morning Keyboard Warriors
I have managed to read too much and now I'm so confused that I need some direction or a good tutorial that explains what is what better.

I am attempting to take an often used piece(s) of code(s) and make libraries out of them. I have read several tutorials and the separation of the code from a working version in the IDE to a library is my sticking point. What is supposed to go where.

What I have done so far:
Below is an example piece of code that I used for the 4x4 keypads. When the button is pressed the variable "button" is changed to the button value.
What I am looking to do is to take the large block of scan code that is in the loop area and move it to the library. This would mean that I would need some function identifier to trigger the scan. I have selected "scanKeypad" as that marker. I would put that at the top of the loop cycle and just below it "if (button !=0){action();} This would look like:

void loop()
{

scanKeypad();
if (button !=0){action();}

}//end of loop

The action function is where a reaction to the button press would happen and would not be part of the library.

I have created a keypad.h file and a keypad.cpp file but all I have are the headers to place the instructions between. The part I have muddled is how the function identifier (scanKeypad) would be defined, which of the files it would go in and how to basicly construct the assembly. See below for the example code. (yes I know there is already a library for this)

/*
 * first attempt at taking oft used code and creating a library
 * this version to use a 4x4 keypad
 * the scanKeypad function is the part I wish to export to a library
 * upon press, the 1-9 buttons output 1-9, 0button=10, *button=11, #button=12, Abutton=13, Bbutton=14, Cbutton=15, Dbutton=16
 */
//rows and collums of the keypad
const int col1=2;
const int col2=3;
const int col3=4;
const int col4=5;
const int row1=6;
const int row2=7;
const int row3=8;
const int row4=9;
int button=0; //used to recieve the number of the button that is pressed

void setup() {
  
  pinMode (row1, OUTPUT); //rows and collums of the keypad setup for scan
  pinMode (row2, OUTPUT);
  pinMode (row3, OUTPUT);
  pinMode (row4, OUTPUT);
  pinMode (col1, INPUT_PULLUP);
  pinMode (col2, INPUT_PULLUP);
  pinMode (col3, INPUT_PULLUP);
  pinMode (col4, INPUT_PULLUP);

}

void loop() {

  //scan keypad for button press
  digitalWrite(row1, LOW); //set row 1 to be scanned
  digitalWrite(row2, HIGH);
  digitalWrite(row3, HIGH);
  digitalWrite(row4, HIGH);
  if (digitalRead(col1) == LOW) //scan 1 button for press
  {
    delay(15);
    while (digitalRead(col1) == LOW)
    {
      button = 1;
    }
  }
  if (digitalRead(col2) == LOW)//scan 2 button for press
  {
    delay(15);
    while (digitalRead(col2) == LOW)
    {
      button = 2;
    }
  }
  if (digitalRead(col3) == LOW)//scan 3 button for press
  {
    delay(15);
    while (digitalRead(col3) == LOW)
    {
      button = 3;
    }
  }
  if (digitalRead(col4) == LOW)//scan 13 button for press
  {
    delay(15);  //A button
    while (digitalRead(col4) == LOW)
    {
      button = 13;
    }
  }

  digitalWrite(row1, HIGH);
  digitalWrite(row2, LOW); //set row 2 to be scanned
  digitalWrite(row3, HIGH);
  digitalWrite(row4, HIGH);

  if (digitalRead(col1) == LOW)// scan 4 button for press
  {
    delay(15);
    while (digitalRead(col1) == LOW)
    {
      button = 4;
    }
  }
  if (digitalRead(col2) == LOW)// scan 5 button for press
  {
    delay(15);
    while (digitalRead(col2) == LOW)
    {
      button = 5;
    }
  }
  if (digitalRead(col3) == LOW)//scan 6 button for press
  {
    delay(15);
    while (digitalRead(col3) == LOW)
    {
      button = 6;
    }
  }
  if (digitalRead(col4) == LOW)//scan 14 button for press
  {
    delay(15);  //B button
    while (digitalRead(col4) == LOW)
    {
      button = 14;
    }
  }

  digitalWrite(row1, HIGH);
  digitalWrite(row2, HIGH);
  digitalWrite(row3, LOW); //set row 3 for scan
  digitalWrite(row4, HIGH);

  if (digitalRead(col1) == LOW)// scan 7 button for press
  {
    delay(15);
    while (digitalRead(col1) == LOW)
    {
      button = 7;
    }
  }

  if (digitalRead(col2) == LOW)// scan 8 button for press
  {
    delay(15);
    while (digitalRead(col2) == LOW)
    {
      button = 8;
    }
  }

  if (digitalRead(col3) == LOW)//scan 9 button for press
  {
    delay(15);
    while (digitalRead(col3) == LOW)
    {
      button = 9;
    }
  }

  if (digitalRead(col4) == LOW)//scan 15 button for press
  {
    delay(15);  //C button
    while (digitalRead(col4) == LOW)
    {
      button = 15;
    }
  }

  digitalWrite(row1, HIGH);
  digitalWrite(row2, HIGH);
  digitalWrite(row3, HIGH);
  digitalWrite(row4, LOW); //set row 4 for scan

  if (digitalRead(col1) == LOW)//scan 11 button for press
  {
    delay(15);
    while (digitalRead(col1) == LOW)
    {
      button = 11;
    }//*button
  }

  if (digitalRead(col2) == LOW)//scan 10 button for press
  {
    delay(15); while (digitalRead(col2) == LOW)
    {
      button = 10;
    }//0button
  }
  if (digitalRead(col3) == LOW)//scan 12 button for press
  {
    delay(15); while (digitalRead(col3) == LOW)
    {
      button = 12;
    }//#button
  }
  if (digitalRead(col4) == LOW)//scan 16 button for press 
  {
    delay(15); while (digitalRead(col4) == LOW)
     {
      button = 16;
    }//D button
  }
//decide where to send the program

if (button!=0)
{
Serial.print(button);
action();
button=0; //clear button back to 0
}

}//end of loop

void action()
{
  if (button==1){/* do 1 button stuff */}
  if (button==2){/* do 2 button stuff */}
  if (button==3){/* do 3 button stuff */}
  if (button==4){/* do 4 button stuff */}
  if (button==5){/* do 5 button stuff */}
  if (button==6){/* do 6 button stuff */}
  if (button==7){/* do 7 button stuff */}
  if (button==8){/* do 8 button stuff */}
  if (button==9){/* do 9 button stuff */}
  if (button==10){/* do 10 button stuff */}
  if (button==11){/* do 11 button stuff */}
  if (button==12){/* do 12 button stuff */}
  if (button==13){/* do 13 button stuff */}
  if (button==14){/* do 14 button stuff */}
  if (button==15){/* do 15 button stuff */}
  if (button==16){/* do 16 button stuff */}

  
} //end of action

Here is what I have so far in the keypad.h file.

#ifndef KEYPAD_H
#define KEYPAD_H
#include <Arduino.h>


#endif

Here is what I have so far in the keypad.cpp file

#include "keypad.h"


I feel like I could make a separate function out of that section of code in the regular IDE and call it from the loop then I should be able to just be able to move it to a library and it will act the same way as if I was calling it from the loop. Yes?

this would look like:

void loop()
{
scanKeypad();
if (button!=0) {action();}
}//end of loop

void scanKeypad()
{
  //scan keypad for button press
  digitalWrite(row1, LOW); //set row 1 to be scanned
  digitalWrite(row2, HIGH);
  digitalWrite(row3, HIGH);
  digitalWrite(row4, HIGH);
  if (digitalRead(col1) == LOW) //scan 1 button for press
  {
    delay(15);
    while (digitalRead(col1) == LOW)
    {
      button = 1;
    }
  }
  if (digitalRead(col2) == LOW)//scan 2 button for press
  {
    delay(15);
    while (digitalRead(col2) == LOW)
    {
      button = 2;
    }
  }
  if (digitalRead(col3) == LOW)//scan 3 button for press
  {
    delay(15);
    while (digitalRead(col3) == LOW)
    {
      button = 3;
    }
  }
  if (digitalRead(col4) == LOW)//scan 13 button for press
  {
    delay(15);  //A button
    while (digitalRead(col4) == LOW)
    {
      button = 13;
    }
  }

  digitalWrite(row1, HIGH);
  digitalWrite(row2, LOW); //set row 2 to be scanned
  digitalWrite(row3, HIGH);
  digitalWrite(row4, HIGH);

  if (digitalRead(col1) == LOW)// scan 4 button for press
  {
    delay(15);
    while (digitalRead(col1) == LOW)
    {
      button = 4;
    }
  }
  if (digitalRead(col2) == LOW)// scan 5 button for press
  {
    delay(15);
    while (digitalRead(col2) == LOW)
    {
      button = 5;
    }
  }
  if (digitalRead(col3) == LOW)//scan 6 button for press
  {
    delay(15);
    while (digitalRead(col3) == LOW)
    {
      button = 6;
    }
  }
  if (digitalRead(col4) == LOW)//scan 14 button for press
  {
    delay(15);  //B button
    while (digitalRead(col4) == LOW)
    {
      button = 14;
    }
  }

  digitalWrite(row1, HIGH);
  digitalWrite(row2, HIGH);
  digitalWrite(row3, LOW); //set row 3 for scan
  digitalWrite(row4, HIGH);

  if (digitalRead(col1) == LOW)// scan 7 button for press
  {
    delay(15);
    while (digitalRead(col1) == LOW)
    {
      button = 7;
    }
  }

  if (digitalRead(col2) == LOW)// scan 8 button for press
  {
    delay(15);
    while (digitalRead(col2) == LOW)
    {
      button = 8;
    }
  }

  if (digitalRead(col3) == LOW)//scan 9 button for press
  {
    delay(15);
    while (digitalRead(col3) == LOW)
    {
      button = 9;
    }
  }

  if (digitalRead(col4) == LOW)//scan 15 button for press
  {
    delay(15);  //C button
    while (digitalRead(col4) == LOW)
    {
      button = 15;
    }
  }

  digitalWrite(row1, HIGH);
  digitalWrite(row2, HIGH);
  digitalWrite(row3, HIGH);
  digitalWrite(row4, LOW); //set row 4 for scan

  if (digitalRead(col1) == LOW)//scan 11 button for press
  {
    delay(15);
    while (digitalRead(col1) == LOW)
    {
      button = 11;
    }//*button
  }

  if (digitalRead(col2) == LOW)//scan 10 button for press
  {
    delay(15); while (digitalRead(col2) == LOW)
    {
      button = 10;
    }//0button
  }
  if (digitalRead(col3) == LOW)//scan 12 button for press
  {
    delay(15); while (digitalRead(col3) == LOW)
    {
      button = 12;
    }//#button
  }
  if (digitalRead(col4) == LOW)//scan 16 button for press 
  {
    delay(15); while (digitalRead(col4) == LOW)
     {
      button = 16;
    }//D button
  }

//return to loop with the button variable adjusted to the current button being pressed if any
}

void action()
{
  if (button==1){/* do 1 button stuff */}
  if (button==2){/* do 2 button stuff */}
  if (button==3){/* do 3 button stuff */}
  if (button==4){/* do 4 button stuff */}
  if (button==5){/* do 5 button stuff */}
  if (button==6){/* do 6 button stuff */}
  if (button==7){/* do 7 button stuff */}
  if (button==8){/* do 8 button stuff */}
  if (button==9){/* do 9 button stuff */}
  if (button==10){/* do 10 button stuff */}
  if (button==11){/* do 11 button stuff */}
  if (button==12){/* do 12 button stuff */}
  if (button==13){/* do 13 button stuff */}
  if (button==14){/* do 14 button stuff */}
  if (button==15){/* do 15 button stuff */}
  if (button==16){/* do 16 button stuff */}

  
} //end of action

Now the question is what goes where? Am I on the right track?
Your education in this would be very much appreciated
amachinetech

Have you seen and understood this https://docs.arduino.cc/learn/contributions/arduino-creating-library-guide

You know what frustrating. I searched the Arduino site for "how to make a library", "creating a library" , "library creation" etc and that never showed up. I'll have a read and see if this clears the water.
Thanks
amachinetech

@amachinetech , before starting the library it would be best to completely rewrite the program to throw out numerous repeating blocks the code. Read something about using arrays and functions.

I would say you are not... you have variables inside your code (button, row1, row2, ...) that end up being shared with the library... This is not a good separation, a good library should be standalone and have a clean API.

have a look at the keypad library and how they let the user declare the configuration

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad

and then pass that configuration to the library

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

so that at run time the API to know if something was pressed is a simple call keypad.getKey() which returns if something was pressed (and in that case the associated key) or not (then returns NO_KEY)

@amachinetech got another example to ponder..

Arduino stuff..

2 folders there, AsyncMorse and AsyncMorseLib..

first step is creating common functions that can be moved into a lib..

good luck.. ~q

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