You are on page 1of 29

Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Report on small creative project


Disclaimer: This report has humorous notes included (besides the technical explanation ofc) but no module was offended in the process.
Please enjoy the lecture!

Start date: 29.01.2021

Focus and goals: Implement as many projects from Elegoo The Most
Complete Starter Kit for UNO folder Multimodule Combination Course

Part1: Thermometer (LCD + Thermistor)

Step1: The LCD Display Module(miniproject)

I decided to take a granular approach to each of the components, thus for this project I started with
the LCD. So, first thing I did? Well, I went to the LCD module and I checked how you implement Hello
world on the LCD.

What I needed to know to do that?

Well first the Hardware

• The Elegoo Uno Board board.


• The breadboard
• The male-to-male cables
• The LCD Screen
• The potentiometer
• The 220 Ohm Resistor
• The USB cables

And the Software

• The Liquid Crystal Library


• The Sketch
• Arduino IDE

The Hardware side


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

The Elegoo Uno R3 Board board

Basically is an almost perfect copy of the Arduino Uno R3 board(whose schematics are opensource
which means any company can basically copy the board and make their own) exactly what
happened. Elegoo, the company provided and Elegoo Uno R3 was born, which is “100% compatible
with Arduino UNO R3”.

The board is provided with lots of I/O ports(where you can plug different pins and cables):

• 1 x USB port which is used to connect to the computer via USB and also provide the board
with power
• 1 x Aux power port if you want to connect an external battery or similar to the bord for
power
• 3 x GND slots short for Ground to ground you circuit (-)
• 1 x 5V is one of the 2 power slots where you can basically power up your circuit with 5 Volts
(+)
• 1 x 3.3V basically the same as above but with 3.3 Volts (+)
• 1 x Reset port
• 1 x IOREF port
• 1 x AREF port
• 1 x VIN port
• 14 x Digital Ports
• 6 x Analog Ports
• 1 x ICSP port
• 1 x similar to ICSP port
• 1 x unlabeled port near IOREF

The Analog Pins

A0 to A5 are analog pins, which can read data from analog sensors, for example the our thermistor
(soon to be discussed). Cool thing about them is that you can use them as digital pins if you run out,
what I also did. You can convert them to digital by assigning them pinMode(A0, OUTPUT); or 14
instead of A0. Then you can just use them either as I/O pins with digitalRead or digitalWrite.

The Digital Pins

0 to 13 are I/O digital pins that can be used for either of the functions by assigning a pinMode. They
cannot be used as analog tho(if not ~).
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Special Digital Pins:

• RX
• TX
• PWM~

RX and TX are used for serial TTL communication with another computer or another board so you
basically shouldn’t use them as digital pins u can fry your board(they operate at +/- 12V) if you do
sample projects and u already use the USB pin that does almost the same.

PWM~ Pulse Width Modulation is a technique for getting analog results with digital means.

Except from pins and ports and any other naming for that the board is also provided with:

• Leds: TX, RX, On, L; transmit and receive Leds, Power On leds and another Led for processing
and errors
• Reset Button it does what it is named for
• Main IC basically the brain of the board.
• Voltage Regulator basically does what it is called, but u cannot interact with it. It is limited
to 20 Volts, If you don’t want to cook Arduino/Elegoo boards.

Fig1. The Elegoo R3 board


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Next to the Arduino another big friend of ours the Breadboard helps us put every more complex
external stuff together with the board. It is split into 6 main things.

• 2 (+) lines on each sides, each one being interconnected (all the pins of the line are
connected), which u can distribute power from the board to more things that need it
• 2 (-) lines on each sides, basically just like the (+) ones from above
• 2 matrices with rows and columns of pins. The breadboard is split in the middle so the
connection don’t go from the matrix 1 to matrix 2 on a column level. The columns (named
by numbers) in each matrix are individually connected, for example column 40 and row a pin
is connected with column 40 and row b, c, d, e pins. Same for the matrix number 2.

Cool thing about the breadboard is that the better you organize and manage it the more space you
have for your project and the simpler is to understand it.

Fig2 The breadboard.

The Resistor in our case 220 Ohm one is used to reduce the current flow for the LCD power input so
that we protect it and not fry it. You can calculate the Ohm number for a resistor based on the color
circles drawn on it, which in fact mean the chemical elements used for creating the resistor each
having its own higher or lower electric resistance properties.
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Fig3. The 220 Ohm resistor

The male-to-male cables perfect for plugging in pins on the board or breadboard or other female
pins to connect components.

The potentiometer is a three-terminal resistor with a sliding or rotating contact that forms an
adjustable voltage divider. After the formal wiki definition in our case we use it to regulate contrast
on the LCD display by allowing a higher or a lower voltage to reach its V0 Pin. It has a 10k Ohm
resistance.

Fig4. The potentiometer(at least one picture I found) the point is you can see the 3 pins from it
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

The LCD1602 is the second most complex thing in our circuit. It has an astounding number of 16
PINS.

LCD meaning Liquid Crystal Display (a dot matrix to show characters) the model name 1602 can be
translated to 16 columns and 02 rows (16 characters per 2 rows).

It has the following ports:

• VSS for connecting to GND


• VDD is for 5V power supply
• V0 as described with the potentiometer is used to adjust contrast based on the voltage
allowed to flow through the potentiometer
• RS this pin controls where in the LCD’s memory (in what register you select) to write data to.
The LCD has 2 options for that. The data register where it is stored what is shown on the
screen and the instruction register where it is decided what the Display is going to do next.
• The E(nabling) pin is used to run instructions from the data register when the signal is changed
from High(1) to Low(0)
• D0-D7 pins to read and write data(I like to call them I/O pins)
• A controls the LCD backlight and is connected to a power source. I connected it to 5V but
reduced the current flow with the 220 Ohm resistor to protect the LCD.
• K controls the LCD backlight and is connected to the ground

Fig5 the LCD1602 u can see all its pins in the picture
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

The Software side.

The Arduino IDE…is basically an IDE just like Visual Studio, Visual Studio Code, Intellij etc. but made
for ARDUINO as the name says. The files u create here have a .ino extension and can be uploaded on
the board. They are called sketches and the IDE provides multiple features to interact with them,
with the board or the computer. Just be sure u have the correct board selected under the menu
Tools>Board and the correct port selected Tools>Port and after saving and checking your sketch u
can just upload it on the board and see how everything can go wrong. Or NOT(fingers crossed and
hold your breath like this guy at min 10:45 see reference [1]).

The Liquid Crystal Library is a library written to allow the Arduino board to control the guess what
Liquid Crystal Displays. It is basically a source of code in C(library) which is broadly used so the guys
from Arduino decided to make it official and create one for generic use. It has a header file where
basically everything is declared and a implementation file where the declarations are actually
implemented (can you believe that). This library defines and implements a class called Liquid Crystal
and multiple constants as flags. The class has multiple methods and each of them serve a role for 1
of the functions of the LCD component.

Before we use the class of the LCD, we need to instantiate it with the pins that are connected to the
board. In our case LiquidCrystal lcd(7, 8, 9, 10, 11, 12); pin 7 for the RS and pin 8 for E, the other
ones for D4 to D7 on the LCS component.

Most used functions of the LCD component/or from the class are the following ones:

• lcd.clear() the command clears the LCD screen and puts the cursor for the first column on
the first line
• lcd.beginn(16,2) the command initializes the LCD with 16 columns and 2 lines, it can have an
extra parameter to specify dot size, it needs to be run before any of the other commands to
setup the LCD
• lcd.print(“Message”) prints the string at the position where the cursor of the LCD is set
• lcd.setCursor(0,1) sets the cursor where at the column 0 and line 1 and the next printed
string will start from there

Step 2: Adding the Thermistor

The thermistor is a type of resistor whose resistance is strongly dependent on temperature, more so
than in standard resistors. The word is a combination of thermal and resistor and u can use it to
output current temperature. There are PTC and NTC types, where P and N come from positive and
negative, which means Thermistors are of two types for Negative where resistance decreases as
temperature rises and for Positive where resistance increases as temperature rises.
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

As the resistor you have to put them in a circuit so one side will be connected to the power(5V) in
our case and on the other side will be connected to the ground (GND) to close the circuit. To read
the data we cand plug a cable and read the output power after the resistance of the thermistor
with a cable to an analog pin before it reaches the GND and calculate the resistance on the board
and translate it to Kelvin and then Celsius or Fahrenheit degrees.

To calculate the temperature to Kelvin…well there are some formulas…I don’t think its relevant to
cover those. They are provided directly as code by the Elegoo kit book. (that’s why it’s the most
complete kit…u get it?)

Fig6 the thermistor

Ok so far we basically have exactly the same project as in the lesson 3.1 form the third folder of the
book. The sketch is the identic one and the schema is exactly the same. I will post the schema below.

Fig7 The schema so far, lcd the thermistor and the board.

I will not comment the code from this sketch as I do not think it is relevant. It suffered a lot of
changes to be adapted to the end project and I will cover what is relevant from it later!!!!!!!!!!!!!!!!
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

float toCelsius(int analogTemp) {

printf("toCelsius(analogTemp = %d) begin\n", analogTemp); //debug statements

double tempK = log(10000.0 * ((1024.0 / analogTemp - 1))); //calculates kelvin

tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK )) * tempK ); // Temp


Kelvin

return tempK - 273.15; // Convert Kelvin to Celcius

printf("toCelsius(analogTemp = %d) begin\n", analogTemp);

For the thermometer function we have the functions toCelsius and toFahrenheit which basically
transform the value obtained from the analog pin A0 which has performed the following instruction
wherever we need to get the value of the thermistor resistance to calculate the current temperature
Int tempReading = analogRead(tempPin);

After that we just call the function like this

toCelsius(tempReading); or

toFahrenheit(tempReading);

in comparison to toCelsius, toFahrenheit has the following instruction to converts the Celsius value to
Fahrenheit
return (toCelsius(analogTemp) * 9.0) / 5.0 + 32.0;

To change from Celsius to Fahrenheit we have a switch


//function that sets the global temperature index between Celsius or Fahrenheit

void setTemp() {

printf("setTemp() begin\n"); //debug

celsius = !celsius; //negates the current value of the Boolean celsius to differentiate it from
fahrenheit

printf("setTemp() end\n"); //debug

We also have a function that constructs a string from the temperature from the functions debated
before:
//function that returns the current temperature as a string in either Celsius or Fahrenheit degrees depending on the global
flag

String getTemp() {

printf("getTemp() begin\n"); //debug


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

tempReading = analogRead(tempPin); //read current temperature

float c; //prepare variables for celsius

float f; //prepare variable for fahrenheit

if (celsius) { //if the themperature flag is set to celsius

c = toCelsius(tempReading); //call the toCelsius function on the value from the analog pin A0

String celsiusDegreez = String(c) + " C"; //create a string from the result of the brevious call and C from
celsius

return celsiusDegreez; //return Celsius string and exit function

f = toFahrenheit(tempReading); //if flag is set to false it means fahrenheit

String fahrenheitDegreez = String(f) + " F"; //the process repeats but for fahrenheit

return fahrenheitDegreez; //and the string returned contains Fahrenheit number and
symbol

printf("getTemp() end\n"); //debug

To improve the functionality even more we have

//a function that holds the temperature on the screen and keeps it updated live until a key is pressed
void currentTemp() {

printf("currentTemp() begin"); //debug

lcd.clear(); //first clear display

lcd.setCursor(0, 0); //second set cursor to first row and column

lcd.print(getTemp()); //call the function explained above

lcd.setCursor(0, 1); //set cursor to second row first column

lcd.print("Press any key to exit"); //display instruction on how to exit

bool ok = true; //instantiate ok handle for stopping at keypress

char customKey1 = customKeypad.getKey(); //requesting a new key input

while (ok) { //loop until ok is false

lcd.setCursor(0, 0); //this is to keep the temperature updated even if the number
changes
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

delay(200); //delay to slow things down for human eye

lcd.print(getTemp()); //request the temperature string again

customKey1 = customKeypad.getKey(); //ask for a new key

if (customKey1 != NO_KEY) ok = false; //if key has a value set ok to false

beep(); //beep and finish function

printf("currentTemp() end"); //debug

Part2: From more projects to 1 creative project where u put more


components together for glory

Step1: The glory days of having no touchscreen: Nokia and the Keypad

Chapter1: Hacking the hardware

After remembering that keypads were cool one day, I saw we have one in the kit and said…that
would be absolutely awesome to have in our multicomponent project.

Then a new problem arose. The greedy LCD deployment just used 6 out of the 12 usable digital pins
I had on my Elegoo board and the membrane keypad I had in the kit was going to use 8 pins. So, we
had to think about a solution and we found our perfectly balanced and not broken component
provided by the kit, THE SHIFT REGISTER 74HC595 IC, which basically allow us to hack 6 pins used
between the board and the LCD to just 3 pins, oh yes. (insert stonks meme here [2]).

This is definitely balanced hardware to software exploit. (I need to buy more of these, I wonder how
many shift registers and other components will handle the poor limited space breadboard now.)

So basically, now we have 1 new hardware components to introduce:

• the shift register 74HC595

On the software side we have 2 new libraries to use:

• the SPI library


• the custom made ShiftedLCD library with actually combines the library Liquid Crystal with
the SPI library
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

The shift register 74HC595

The pins of the register are the following ones:

On the LCD side we can see 8 Pins:

• Q1 to Q7 from where Q1 is connected to the RS pin of the LCD for selectin the register of the
LCD we write data too, Q2 is not used, Q3 is connected to the E pin of the LCD to enable(set 1
or 0) it to use the instructions memorized in the instructions register, and Q4 to Q7 ar
connected to the LCD D4 to D7 to send the input data for the LCD
• GND which is supposed to be connected to the ground

On the board side we also see 8 Pins:

• The VCC pin which is used to supply the register with power(5V) in our case
• The Q0 which in our case is not used
• The DS pin is used to feed data in the shift register a bit at a time from the board digital pin
number 11
• The OE pin is connected to the GND , when set to High Voltage the Output pins (Q) are
disabled or set to high impedance state and don’t allow current flow. When it gets Low
Voltage the output pins are set to normal
• The ST_CP pin is the clock latch pin. When it is HIGH we copy the contents of the shift
register to the latch register; which ultimately shows up at the output. So the latch pin can
be seen as like the final step in the process to seeing our results at the output, which in this
case are LEDs. It is connected to pin 10 on our board.
• The SH_CP pin is the clock pin for the 74hc595. We need to set it High in order to shift bits. It
is connected to pin 13 to our board.
• The MR pin allows us to reset the entire Shift Register, set all bits 0. We need to set it to
LOW to reset it. If we don’t need to reset it we will always have it high so we just connected
the MR pin to the 5V power source.
• The second Q7 pin, not used in our case.

How does the 74HC595 IC work?

Well the IC has 2 registers(memory containers) and each one of them has 8 bits of data. The first
one is the shift register and the second one is storage or latch register.
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

When there is a clock pulse applied to it the bits in the shift register move one bit to the left and the
bit 0 takes the current value on the data pin and if the data is high at the rising edge of the pulse
then a 1 is pushed in the shift register, else a 0. On the latch pin the bits are copied to the latch
register from the shift register and each pin from the latch register is connected to one of the Q0-Q7
output pins.

Fig8 74HC595 IC

The SPI library

The SPI is synchronous serial data protocol and is used by the board to communicate fast with one or
more components very quick on short distances. There is always a master component which is the
microcontroller in our case.

The following concepts are common for both the controller and the other components:

• MISO Master In Slave Out meaning the master receives data from slave
• MOSI Master Out Slave In meaning exactly the opposite from the above one
• SCK Serial Clock The clock pulses which synchronize data transmission generated by the
master

And the one that is specific:

• SS (Slave Select) - the pin on each device that the master can use to enable and disable
specific devices.

The ShiftedLCD library


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

The ShiftedLCD library is basically an extension of the Liquid Crystal Library combined with the SPI
Library. It inherits both the methods from Liquid Crystal Library as well as methods from the SPI
Library to help with the shift register. It is a custom-made library; I included the reference to the
YouTube video where I discovered it down at sources. What is overwritten for the Liquid Crystal
class of this library is the constructor which instead of taking all the pins required for the LCD as
parameters it only takes as parameter the SS pin for the SPI part of the library.

Fig9 The schema after the addition of 74HC595 IC

The biggest change after the addition of the 74HC595 IC in the sketch are the pins required in the
constructor for the Liquid Crystal library. First we had the following line:
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

//which was basically preparing the software handles for the pins 7 8 9 10 11 12 in the Liquid Crystal
constructor

And this was translated to our


LiquidCrystal lcd(10);

//because we now used the SPI.h and the ShiftedLCD library and we only needed to pass the ssPin
and as we used SPI and the MOSI as well as the SCK pin of the board this will be automatically
handled by the SPI library to work with our shift register

Chapter 2: The keypad

Now that we freed up space for more digital pins, we can finally add a keypad to our project. To use
it we will also need the hardware and software parts. The membrane switch is the hardware part.
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

The Membrane Switch

The Membrane switch is provided with 8 PINS for output so we will need 8 Digital Input pins for the
microcontroller. Which is a huuuge number and is using a lot of our Digital pins. For this I used D2 to
D9 on the board. Why are they 8 PINS? Well, we have a 4x4 Matrix as our Keypad…and we have 4
Rows and 4 Columns. To identify which button was pressed on the Keypad we have the first 4 pins
to use them for the rows and the other 4 ones for the columns. Initially the row pins will be set to 0
and the column pins to 1. If a button is pressed the 2 conductors are connected and the column will
go to 0. Now we know the column on which is the button pressed is, so to find out the row, all the
columns are set to 0 and each row is individually scanned by setting it individually to 1, one at a
time and if the button is depressed the column will go to 1. So, now we will know which row it was
and which column, information that are sent to the microcontroller and interpreted using the
Keypad Library, which we will use to process the inputs coming from our hardware. Based on the
way the membrane switch works u can only get one key at a time, u cannot get 2 in parallel.

Fig10 The 4x4 membrane switch component


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Fig11 updated schema including both the membrane as well as the LCD with 74HC595 and the
thermistor

The Keypad Library

Basically, the Keypad Library is providing the definition and implementation of a class Keypad,
which contains all the necessary methods to handle the user inputs on the membrane switch. With
the help of the constructor the Keypad object is instantiated with a mapped matrix 1:1 with the real
physical keypad, with the array of pins corresponding to the rows, with the array of pins
corresponding to the columns, the number of row Pins and the number of column Pins. The most
used method of the library is the getKey() which is returning the key.
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

const byte ROWS = 4; //four rows

const byte COLS = 4; //four columns

char hexaKeys[ROWS][COLS] = {

{'1', '2', '3', 'A'},

{'4', '5', '6', 'B'},

{'7', '8', '9', 'C'},

{'*', '0', '#', 'D'}

};

byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad

byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

This is the code for setting up the Keypad class used for the connection with the membrane switch
to process the inputs.

ROWS and COLS are the numbers to check if the Membrane is 4x4 or 4x3

The matrix hexaKeys are going to be mapped as the buttons on the component and the rowPins and
ColPins are the distribution of the pins of the membrane as 4 need to be rows and 4 need to be
columns to identify the button pressed as explained before.

Then the constructor is instantiated with all these values and you can use the main methods of the
Keypad class.

The most used function in my project is

char key = keypad.getKey(); // which basically returns a single key. We allow this
functions to run as long as we need user input...like for the PIN unlock function listed below
void unlock() {

printf("unlock() begin\n");

setLocked(); //what the setLocked() function defined by me does it displays on the LCD the message Enter
pin and sets the flag to check pass to true to allow us to have another go

bool ok = true;

while (ok) {

delay(100);

char customKey = customKeypad.getKey(); //our getKey function will run until ok will be false meaning we
obtained a 4 digits from the Membrane which are corresponding to the 4 digits of the set password

if (customKey != NO_KEY) { // we check if the key returned by the function above is not the NO_KEY
which is also defined in the Keypad Library as no key can be returned
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

beep(); //we beep as a NOKIA

lcd.setCursor(i, 1); //we set the cursor on the second row on column I to keep it on the next column
after write

lcd.print('*'); //we print * as we are used to with hidden passwords

if (customKey != password[i]) //we check if one digit matches with the corresponding digit of the set
password

checkPass = false; //if it is different checkPass is false

i++; //increment digit counter i

if (i == 4) // we check if we reached the 4 digits password inputed

if (checkPass) //if we reached this step it means our password is 4 digits and now we check if the inputed
password is identical to our set password

beepRegulator(2); //we call the 3 beeps success sound

ok = false; //we set the oke to false to stop the KEY input loop

else {

beepRegulator(1); //if we inputed 4 wrong DIGITS not corresponding to the set pass

setLocked(); //we set up the unlock function again and run it again

printf("unlock() end\n"); //debug

//function that sets the lock mechanism and aferent message on lcd

void setLocked() {

printf("setLocked() begin\n"); //debugg

i = 0; //reset digit counter for unlock function

firstLineMSG("Enter Pin:"); //print message on first line of lcd

checkPass = true; //set digit pass check to true

printf("setLocked() end\n");} //debugg


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Step 2: Tools and beeps.

Chapter 1: Clean code, debugging and improved security.

After writing most of the stuff described above thinks started to get dirty. I started getting lost in my
own code and debugging problems here and there was a nightmare. I decided to start rewriting
most of my code and using functions as much as possible to not use duplicate code. The biggest
problem was when I started implementing the PIN LOCK functionality and I wanted to see if certain
statements were reached. So, I was forced to start using the Serial Monitor more and more. The
problem with the Serial Monitor is that it has only the 2 very primitive print and println methods
which do not help me enough to improve my debugging mechanisms. I started googling for a printf
similar function library. I found ardprintf custom Library and started to use it as it was an extension
of the Serial Monitor, and it added the new ardprintf method which was working exactly like the
printf in C++.

So for this we have now the function based on the library LibPrintf.h

//printf function just like in C++ which also supports


printf("beep(parameter = %s) begin\n", s);
additional parameter that are included in the first string

printf("beep() end\n"); // I used it for debugging purposes at each function at beginning and
at the end to see where in our loops we get out and how our parameters look

That was helping a lot now that I can test each function or loop, it was started or finished and with
what parameters at what time. Now I was able to implement a pin lock function that was expecting
the user to type on the keypad a pin made of 4 digits to unlock it. It is described above

The lock function implementation was explained above. Just before this chapter.
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Fig12 The log of our printf() debug solution in the Serial Monitor
// function that prints a temporary message on the screen and deletes it after 2000ms

void tempPrint(String msg) {

printf("tempPrint( msg = %s ) begin\n", msg);

lcd.clear(); //first it clears last message displayed on lcd

lcd.setCursor(0, 0); //sets cursor for first row first column

lcd.print(msg); //prints the message

delay(2000); // waits 2000ms

lcd.clear(); //clears the display

printf("tempPrint( msg = %s ) end\n", msg);

Chapter 2: Nokia used to beep.

Well, if the project reminds me of a Nokia, I remember my Nokia used to beep when you touched
the keys, or when u unlocked it or others, so I decided to add an active buzzer for ease-of-use ofc.
The active buzzer we used has an integrated oscillator and if you power it up you will gain sound
instantly.

To keep things even more simple I used the tone(pin, freq, dur*) function provided by Arduino. That
generates a square wave of frequency until the end of the duration parameter if it is specified, else it
will stop at the next noTone() function call. What it basically does is digitalWrite high on the output
pin to the active buzzer.

void beep() {

printf("beep() begin\n"); //debug printfs

if (!silent) //this flag is used to set the whole system in silent mode and disable beeps

tone( buzzer, 1500, 100); //the tone function provided by Arduino…explained above

delay(120); //so by checking the frequency and duration I managed to get the bes acoustic version of the
beep by seting a delay of 120 which overlaps with the duration

printf("beep() end\n"); //debug printfs


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Fig 13 Active buzzer


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Fig14 The system after the addition of the buzzer on the right. You the complexity rise.
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

Step 3: Putting it all together.

Now that every component so far was covered so far, software as well as hardware. We had to put
everything together. So, as we discussed before as clean code and debugging everything is
structured in functions to keep it organized and clean. The functions are tested in the serial monitor
if they start with the expected values as parameters.

We have 2 functions used for the change PIN procedure:


// function that reads 4 digits as a new pin

String newPinProcedure() { //this function is a reusable one, it returns a new pin input

printf("newPinProcedure() begin\n"); //debugg

int k = 0; //instantiate pin length

String pinx = ""; //instantiate pin string

while (k < 4) { //loop until we have 4 digits

delay(100); //delay for keyboard typing experience

char customKey2 = customKeypad.getKey(); //read new key input

if (customKey2 != NO_KEY) { //check if key different than NO_KEY char, if yes do following

beep(); //beep the key touch

pinx.concat(customKey2); //build the string to be returned as the new pin

lcd.setCursor(k, 1); //set cursor to next position on row for tiping

lcd.print(customKey2); //print key inputed

delay(400); //delay for experience reasons

lcd.setCursor(k, 1); //set cursor on same position as before

lcd.print('*'); //and override the input key for security reasons

k++; //increment digit counter

printf("newPinProcedure() end\n"); //debugg

return pinx; //return final result after the loop stops

// function that checks if the pin and the retyped pin are the same and if so assigns it to the global password

void resetPin() {

printf("resetPin() begin\n"); //debugg


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

String pin1 = ""; //init first pin

String pin2 = ""; //init second pin

bool ok = false; //we need to loop until pins are equal

while (pin1.length() != 4 && pin2.length() != 4 && ok == false) { //loop until both pins are equal and have 4
digits

firstLineMSG("Type new pin(4)"); //type new pin lcd display

pin1 = newPinProcedure(); //use the previous function to obtain new


pin1

lcd.clear(); //clear screen

firstLineMSG("Type pin again!"); //retype pin message display on lcd

pin2 = newPinProcedure(); //use the previous function for second pin

if (pin1 == pin2) { //check if both pins are same

ok = true; //set ok to true

beepRegulator(2); //beep trice for success

} else {

beepRegulator(1); //beep twice for error

tempPrint("PIN1 != PIN2"); //temporary display error message

tempPrint("New PIN saved!"); //when loop ends we succesfully changed pin

password = pin1; //set pin value as the new global password

printf("resetPin() end\n"); //debugg

I tryied to put as much reusable code as possible:

// function that prints a message on the first line


void firstLineMSG(char* msg) {

printf("firstLineMSG( msg = %s ) begin\n", msg); //debug prints with msg

lcd.clear(); //clear lcd first with LiquidCrystal clear


method

lcd.print(msg); //prints message on LCD screen


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

lcd.setCursor(0, 1); //sets cursor for the next use on second row

printf("firstLineMSG( msg = %s ) end\n", msg); //debug prints with msg

//function sets the silent flag to its negation prints silent mode on if true or off if false
void setSilent() {

printf("setSilent() begin\n"); //debug prints

silent = !silent; //change state of flag

if (silent) tempPrint("Silent mode on"); //temporary display on

else tempPrint("Silent mode off"); //temporary display off

printf("setSilent() end\n"); //debug prints

UX
Well I also implemented a menu displayed on the lcd display and handled with the keypad. Below
are the explanations and the code.
//function that displays the menu options!

void showMenu() {

printf("showMenu() begin\n"); //debugg

lcd.clear(); //clear lcd display

lcd.setCursor(0, 0); //set cursor to first line first column

lcd.print("Select options: "); //print first line message

lcd.setCursor(0, 1); //set cursor to second line first column

lcd.print("1,2,3,4,0,#,*"); //display second line message the options

printf("showMenu() end\n"); //debugg

Next we have the comprehensive menu function:


//function that handles menu options as keypad inputs

void menu() {

printf("menu() begin\n"); //debugg

tempPrint(String("Welcome!")); //temporary print welcome mesage


Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

showMenu(); //call show menu function

bool ok = false; //set loop handle to ok = false

while (ok == false) //the menu loop will end when selected option is lock “#”

char customKey = customKeypad.getKey(); //get new key

if (customKey != NO_KEY) { //check key if not null

beep(); //beep if key is true

if (customKey == '0') // if the key is “0” we toggle the silent mode on or off

setSilent();

showMenu();

else if (customKey == '1') //if the key is “1” we temporary show the temperature in Celsius

{ //or Fahrenheit depending on what is currently set on the flag

tempPrint(getTemp());

showMenu();

else if (customKey == '2') //if key is “2” we print and hold until input the live temperature

currentTemp();

showMenu();

else if (customKey == '3') //if key is “3” we toggle the Celsius or Fahrenheit and temprint

setTemp();

if (celsius)

tempPrint("To Celsius");

else tempPrint("To Fahrenheit");

showMenu();

else if (customKey == '4') //if key is “4” we call the playSong function from the Song library

{
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

playSong(buzzer);

showMenu();

else if (customKey == '#') //if “#” we print welcome, 3 beep sound and lock

beepRegulator(3);

tempPrint("Bye!");

ok = true;

else if (customKey == '*') //if “*”

unlock(); // we lock to for security reasons

resetPin(); //we do the reset pin procedure if successfull

showMenu(); //we show menu

else {

beep(); //we beep if key has no func registered

tempPrint("No such function"); //we display no function on this key

showMenu(); //we show menu

printf("menu() end\n"); //debugg

The main functionalities are the following:

• Locking on “#”
• Change PIN on “*”
• Locking with PIN
• Keypress beep
• Silent mode on “0”
• Error signal with double beep
• Success signal with triple beep
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

• Show current temperature on “1”


• Display current temperature(changing) until key press on key “2”
• Switch between Celsius/Fahrenheit on “3”
• Song function on “4”
• Temporary messages (ex “Welcomes!”)

Sources
• [1]: https://youtu.be/tuRAvlVBEl0?t=645
• [2]:
https://www.google.com/imgres?imgurl=https%3A%2F%2Fwww.elcarteldelgaming.com%2F
wp-
content%2Fuploads%2F2019%2F10%2Fnau.jpg&imgrefurl=https%3A%2F%2Fwww.elcarteld
elgaming.com%2F2019%2F10%2Fnotizie%2Fstonks-da-dove-arriva-il-meme-migliore-del-
2019%2F&tbnid=BMEt6gpbx3nlCM&vet=12ahUKEwiG-
5_VusfuAhWGkKQKHfgFCPMQMygAegUIARCvAQ..i&docid=ReoMzaIF3x81PM&w=1280&h=7
20&q=stonks%20meme&ved=2ahUKEwiG-5_VusfuAhWGkKQKHfgFCPMQMygAegUIARCvAQ
• https://lastminuteengineers.com/74hc595-shift-register-arduino-tutorial/
• https://forum.arduino.cc/index.php?topic=681957.0
• https://en.wikipedia.org/wiki/Thermistor
• https://www.arduino.cc/en/Reference/LiquidCrystalSetCursor
• https://www.arduino.cc/en/Reference/LiquidCrystal
• https://www.arduino.cc/en/Reference/LiquidCrystalPrint
• https://www.arduino.cc/en/Reference/LiquidCrystalBegin
• https://www.arduino.cc/en/Reference/LiquidCrystalClear
• https://www.youtube.com/watch?v=tuRAvlVBEl0&ab_channel=PaulMcWhorter
• https://www.youtube.com/watch?v=GteMrHri6r8&ab_channel=MERTArduino%26Tech
• https://en.wikipedia.org/wiki/Potentiometer
• https://en.wikipedia.org/wiki/Resistor
• https://www.arduino.cc/en/Tutorial/Foundations/PWM
• https://www.arduino.cc/en/pmwiki.php?n=Reference/serial
• https://www.arduino.cc/reference/en/language/functions/communication/serial/
• https://www.arduino.cc/en/Tutorial/Foundations/DigitalPins
• https://www.arduino.cc/en/Tutorial/Foundations/AnalogInputPins
• https://arduino.stackexchange.com/questions/132/what-are-the-aref-ioref-and-the-
unlabeled-pin-next-to-ioref-on-the-uno-r3
• https://learn.sparkfun.com/tutorials/what-is-an-arduino/whats-on-the-board
• http://wiki.sunfounder.cc/index.php?title=LCD1602_Module
• https://www.arduino.cc/en/Hacking/libraryTutorial
• https://www.youtube.com/watch?v=fE3Dw0slhIc&ab_channel=RalphSBacon
Author: Alex-George Rusu

Coordinating professor: Prof.


Francesco Longo

• https://arduino.stackexchange.com/questions/176/how-do-i-print-multiple-variables-in-a-
string
• https://www.youtube.com/results?search_query=create+arduino+library
• https://github.com/embeddedartistry/arduino-printf
• https://embeddedartistry.com/blog/2019/11/25/arduino-printf-library/
• https://arduino.stackexchange.com/questions/176/how-do-i-print-multiple-variables-in-a-
string
• https://www.arduino.cc/reference/en/language/functions/communication/serial/println/
• https://www.arduino.cc/reference/en/language/functions/advanced-io/notone/
• https://www.arduino.cc/reference/en/libraries/buzzer/
• https://stackoverflow.com/questions/10279718/append-char-to-string-in-c
• http://www.cplusplus.com/reference/cstring/strncat/
• https://forum.arduino.cc/index.php?topic=616670.0
• https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/
• https://forum.arduino.cc/index.php?topic=595897.0
• https://www.quora.com/Can-I-make-a-buzzer-work-using-analogue-pins-in-Arduino
• https://stackoverflow.com/questions/26199481/concatenate-characters-to-an-empty-string
• https://www.programmingelectronics.com/an-easy-way-to-make-noise-with-arduino-using-
tone/
• https://www.youtube.com/watch?v=jW1sLboXgDc
• https://www.youtube.com/watch?v=zl1o-t_17oQ
• https://forum.arduino.cc/index.php?topic=311828.0
• https://www.youtube.com/watch?v=-RV6J4oAtEE
• https://www.youtube.com/watch?v=ameNT2MKDyE
• https://www.youtube.com/watch?v=Mr9FQKcrGpA
• https://www.youtube.com/watch?v=GyprsoB887Y
• https://www.youtube.com/watch?v=tJvN-2GLMjs
• https://www.youtube.com/watch?v=vl1-R6NsejM&ab_channel=DroneBotWorkshop
• And of course, the most used of them all was Elegoo the complete kit with the sketches and
the instructions provided there.

You might also like