30 Days Lost in Space: Week 2
Day 8: Adding some color to this dark place - 11/23/2025
Stuff we cover in today's adventure:
- Hardware
- RGB LEDs
- Pulse Width Modulation (PWM):
- Software
analogWrite().
RGB LED
An RGB LED, or Red Green Blue Light-Emitting Diode, allows us to make virtually any color.
Where with a regular LED you apply power and it emits a pre-programmed specific color, with an RGB LED you have the ability to control Red, Green, and Blue individually and in various combinations. By varying the intensity of each of these colors, we can create virtually any color we want.
analogWrite() and Pulse Width Modulation
analogWrite() is a function in Arduino that helps us produce Pulse Width Modulation (PWM) signals.
Pulse Width Modulation is a technique used to kind-of produce a fake analog effect through digital means. By rapidly switching a signal or power source on and off and changing the amounts of time it is on and off, we can vary the intensity of power that is received. This works in tandem with the RGB LED, allowing us to control the intensity of Red, Green, and Blue LEDs, letting us mix our colors.
We are going to use analogWrite() to send PWM signals to each of the Red, Green, and Blue LEDs. Duty cycle is the on time of the PWM.
displayColor()
We could set the Reg, Green, and Blue values individually, but instead we will write a function to streamline that for us:
void displayColor(byte red_intensity, byte green_intensity, byte blue_intensity) {analogWrite(red, red_intensity);analogWrite(green, green_intensity);analogWrite(blue, blue_intensity);}
Final code
Here's a sequence built on the solution code that produces a rainbow:
#include "Arduino.h"const byte RED_PIN = 11;const byte GREEN_PIN = 10;const byte BLUE_PIN = 9;const byte OFF = 0;const byte DIM = 64;const byte BRIGHTER = DIM + 64;const byte BRIGHT = BRIGHTER + 64;const byte BRIGHTEST = 255;const unsigned int COLOR_DELAY = 500;void setup() {pinMode(RED_PIN, OUTPUT);pinMode(GREEN_PIN, OUTPUT);pinMode(BLUE_PIN, OUTPUT);}void loop() {// REDdisplayColor(BRIGHTEST, OFF, OFF);delay(COLOR_DELAY);// ORANGEdisplayColor(BRIGHTEST, DIM, OFF);delay(COLOR_DELAY);// YELLOWdisplayColor(BRIGHTEST, BRIGHTEST, OFF);delay(COLOR_DELAY);// GREENdisplayColor(OFF, BRIGHTEST, OFF);delay(COLOR_DELAY);// BLUEdisplayColor(OFF, OFF, BRIGHTEST);delay(COLOR_DELAY);// INDIGOdisplayColor(DIM, OFF, BRIGHTER);delay(COLOR_DELAY);// VIOLETdisplayColor(BRIGHTEST, DIM, BRIGHT);delay(COLOR_DELAY);}void displayColor(byte red_intensity, byte green_intensity, byte blue_intensity) {analogWrite(RED_PIN, red_intensity);analogWrite(GREEN_PIN, green_intensity);analogWrite(BLUE_PIN, blue_intensity);}
This was a very fun exercise day. Probably the most difficult part was actually connecting all four of the RGB LED pins correctly to the breadboard.
Day 9: A better way to do things - 11/24/2025
The goal for today's lesson is to combine the exercise that uses a photoresistor to charge up our battery with our work yesterday to create a colorful indicator that reflects the battery charge amount. If the battery is low (0% to 24.9%), the RGB LED indicator will be a flashing red color. If the battery is medium-charged (25% to 49.9%), the RGB LED indicator will be a solid amber color. If the battery is mostly full to full (50% to 100%), the RGB LED indicator will be a solid green color.
When we run the program, the battery will always start at 0%, and will fill up at a rate based on the amount of light that hits the photoresistor. The more light hits it, the faster the battery charges up. The less light hits it, the slower the battery charges up.
Hardware-wise, this is basically combining the last three or four lessons, so nothing new. We mostly reconfigure Day 8's breadboard to add the photoresistor back and to utilize a common ground bus.
Software-wise, we get a few new concepts. First, some flow control:
else/if- Comparison operators:
>=><=<
- Logical operators:
&&||
And second, type conversion to convert integers to floats.
Here's the completed code for today's lesson:
#include "Arduino.h"const byte PHOTORESISTOR_PIN = A0;const byte RED_PIN = 11;const byte GREEN_PIN = 10;const byte BLUE_PIN = 9;const unsigned int BATTERY_CAPACITY = 50000;void displayColor(byte red_intensity, byte green_intensity, byte blue_intensity) {analogWrite(RED_PIN, red_intensity);analogWrite(GREEN_PIN, green_intensity);analogWrite(BLUE_PIN, blue_intensity);}void setup() {pinMode(RED_PIN, OUTPUT);pinMode(GREEN_PIN, OUTPUT);pinMode(BLUE_PIN, OUTPUT);pinMode(PHOTORESISTOR_PIN, INPUT);Serial.begin(9600);}void loop() {static unsigned long battery_level = 0;battery_level += analogRead(PHOTORESISTOR_PIN);if (battery_level > BATTERY_CAPACITY) {battery_level = BATTERY_CAPACITY;}float percentage = ((float)battery_level / (float)BATTERY_CAPACITY) * 100;if (percentage >= 50.0) {displayColor(0, 128, 0);} else if (percentage >= 25.0 && percentage < 50.0) {displayColor(128, 80, 0);} else {displayColor(0, 0, 0);delay(20);displayColor(128, 0, 0);}Serial.print(percentage);Serial.println("%");delay(100);}
Day 10: Creative day #2 - 11/25/2025
- Easy project: Create a night light using the photoresistor; when it gets dark, the LED should turn on, when it's light, the LED should turn off.
- Hard project: Do the easy project, but add in a DIP switch override
Easy project:
#include "Arduino.h"const byte PHOTORESISTOR_PIN = A0;const byte RED_PIN = 11;const byte GREEN_PIN = 10;const byte BLUE_PIN = 9;void displayColor(byte red_intensity, byte green_intensity, byte blue_intensity) {analogWrite(RED_PIN, red_intensity);analogWrite(GREEN_PIN, green_intensity);analogWrite(BLUE_PIN, blue_intensity);}void setup() {pinMode(RED_PIN, OUTPUT);pinMode(GREEN_PIN, OUTPUT);pinMode(BLUE_PIN, OUTPUT);pinMode(PHOTORESISTOR_PIN, INPUT);Serial.begin(9600);}void loop() {static unsigned long light_level = 0;light_level = analogRead(PHOTORESISTOR_PIN);Serial.print(light_level);Serial.println();if (light_level >= 800) {displayColor(0, 0, 0);} else if (light_level >= 625 && light_level <= 700) {displayColor(0, 0, 128);} else {displayColor(0, 128, 0);}}
Hard project:
#include "Arduino.h"const byte PHOTORESISTOR_PIN = A0;const byte RED_PIN = 11;const byte GREEN_PIN = 10;const byte BLUE_PIN = 9;const byte LIGHT_SWITCH_PIN = 2;void displayColor(byte red_intensity, byte green_intensity, byte blue_intensity) {analogWrite(RED_PIN, red_intensity);analogWrite(GREEN_PIN, green_intensity);analogWrite(BLUE_PIN, blue_intensity);}void setup() {pinMode(RED_PIN, OUTPUT);pinMode(GREEN_PIN, OUTPUT);pinMode(BLUE_PIN, OUTPUT);pinMode(PHOTORESISTOR_PIN, INPUT);pinMode(LIGHT_SWITCH_PIN, INPUT);Serial.begin(9600);}void loop() {if (digitalRead(LIGHT_SWITCH_PIN) == LOW) {displayColor(0, 0, 0);} else {static unsigned long light_level = 0;light_level = analogRead(PHOTORESISTOR_PIN);Serial.print(light_level);Serial.println();if (light_level >= 800) {displayColor(0, 0, 0);} else if (light_level >= 625 && light_level <= 700) {displayColor(0, 0, 128);} else {displayColor(0, 128, 0);}}}
Day 11: Starting your control panel - 11/26/2025
We start a new five-day week today, and we scrap just about everything we've done to start exploring keypads. Here's what we cover in this lesson:
- Hardware:
- 4 * 4 keypad
- Software:
- Libraries, specifically the keypad library
Hardware
- No breadboard today!
- 4 * 4 keypad
- Each button, when pressed, closes a circuit and sends a signal that we can detect and utilize
- Used in contexts where manual input is required
- The only wiring is connecting the keypad's pins to 8 input pins on the hero board
Software
- Libraries: a prepackaged set of functionality
- Keypad library: a custom library designed for working with keypads of various sizes, like a 4*4 keypad. Functionality may include:
- When keys are pressed
- Which keys are pressed
- "Multi-key" detection
- Keypad library: a custom library designed for working with keypads of various sizes, like a 4*4 keypad. Functionality may include:
In order for the keypad library to work we need to tell it:
- how many rows are on our keypad
- how many columns are on our keypad
- column pins used on the microcontroller
- row pins used on the microcontroller
- keymap: the values corresponding to each key on the keypad
To make the keymap, we will utilize arrays. An array is a data structure that allows storage of multiple values. Here are our column pins and row pins in two arrays:
const byte ROW_PINS[ROWS] = { 5, 4, 3, 2 };const byte COL_PINS[COLS] = { 6, 7, 8, 9 };
A two-dimensional array is a grid of data. Here is our two-dimensional array of the values we want to map to the buttons on the keypad:
const char BUTTONS[ROWS][COLS] = {{ '1', '2', '3', 'A' },{ '4', '5', '6', 'B' },{ '7', '8', '9', 'C' },{ '*', '0', '#', 'D' },};
We will construct the keymap as follows:
Keypad heroKeypad = Keypad(makeKeymap(BUTTONS), ROW_PINS, COL_PINS, ROWS, COLS);
Here is the completed code for today's lesson:
#include "Arduino.h"#include <Keypad.h>const byte ROWS = 4;const byte COLS = 4;const byte ROW_PINS[ROWS] = { 5, 4, 3, 2 };const byte COL_PINS[COLS] = { 6, 7, 8, 9 };const char BUTTONS[ROWS][COLS] = {{ '1', '2', '3', 'A' },{ '4', '5', '6', 'B' },{ '7', '8', '9', 'C' },{ '*', '0', '#', 'D' },};Keypad heroKeypad = Keypad(makeKeymap(BUTTONS), ROW_PINS, COL_PINS, ROWS, COLS);void setup() {Serial.begin(9600);}void loop() {char pressedButton = heroKeypad.waitForKey();Serial.println(pressedButton);}
Day 12: Can you hear us? - 11/27/2025
Today we are turning our 4 * 4 keyboard into an 8-bit synth. This aligns just about perfectly with my interests. I love today's lesson.
Hardware
- Passive buzzer: a small speaker that can play different frequencies
- A piezo-electric device. When an oscillating electric signal is applied to its terminus, it vibrates. We can control the frequency of this oscillation, which translates to the pitch at which it vibrates.
- For more capabilities than we are getting into in this lesson, check out the tone-h library
tone()takes in two parameters:- pin
- frequency we want to send
- left-hand side has a minus sign (
-) for negative, and the right-hand lead has an S (s) for signal.
We're basically using pulse width modulation from the keypad to send frequency values to the passive buzzer.
Software
forLoop- executes a block of code for a certain, known, number of times
whileLoop- executes a block of code repeatedly until a condition is met; typically used when we don't know how many times it should loop
Here is the code for today's lesson:
#include "Arduino.h"#include <Keypad.h>const byte ROWS = 4;const byte COLS = 4;const byte ROW_PINS[ROWS] = { 5, 4, 3, 2 };const byte COL_PINS[COLS] = { 6, 7, 8, 9 };const char BUTTONS[ROWS][COLS] = {{ '1', '2', '3', 'A' },{ '4', '5', '6', 'B' },{ '7', '8', '9', 'C' },{ '*', '0', '#', 'D' },};Keypad heroKeypad = Keypad(makeKeymap(BUTTONS), ROW_PINS, COL_PINS, ROWS, COLS);// 31hz to 3729hzconst unsigned int TONES[ROWS][COLS] = {{ 31, 93, 147, 208 },{ 247, 311, 370, 440 },{ 523, 587, 698, 880 },{ 1397, 2637, 3729, 0 }};const byte BUZZER_PIN = 10;void setup() {Serial.begin(9600);}void loop() {char button_character = heroKeypad.waitForKey();unsigned int tone_frequency = 0;for (byte i = 0; i < ROWS; i++) {for (byte j = 0; j < COLS; j++) {if (button_character == BUTTONS[i][j]) {tone_frequency = TONES[i][j];}}}Serial.print("Key: ");Serial.print(button_character);Serial.print(" Freq: ");Serial.println(tone_frequency);if (tone_frequency > 0) {tone(BUZZER_PIN, tone_frequency);} else {Serial.println("Stop tone");noTone(BUZZER_PIN);}}
The thing I didn't understand from this lesson were:
- Where do the
tone()andnoTone()functions come from?- These functions are part of the core Arduino software.
- Why didn't we specify
pinMode(BUZZER_PIN, OUTPUT)? We've had to specify almost all of the other pins so far (at least before using the keypad library).- The
tone()functionality automatically handles pin configuration for us internally.
- The
Day 13: HERO Security 101 - 11/28/2025
In this lesson, we're going to use the 4 * 4 keypad to input a PIN for some basic authorization in our spaceship's control panel. This is pretty much purely a software lesson.
The user flow:
- Press the
*to change the PIN. - Press the
#to begin authorizing. - After pressing
#, enter the PIN. - If the correct PIN is entered, we can access the control panel.
- If the incorrect PIN is entered, an error message is shown.
The software concepts we cover in this lesson:
- return: used when a function returns a value. When a function gets called, it returns the specified value to the place where that function is called.
- boolean: a true or a false
Here's the code for today's lesson:
#include "Arduino.h"#include <Keypad.h>const byte ROWS = 4;const byte COLS = 4;const byte PIN_LENGTH = 4;char current_pin[PIN_LENGTH] = { '0', '0', '0', '0' };const char BUTTONS[ROWS][COLS] = {{ '1', '2', '3', 'A' },{ '4', '5', '6', 'B' },{ '7', '8', '9', 'C' },{ '*', '0', '#', 'D' }};const byte ROW_PINS[ROWS] = { 5, 4, 3, 2 };const byte COL_PINS[COLS] = { 6, 7, 8, 9 };Keypad heroKeypad = Keypad(makeKeymap(BUTTONS), ROW_PINS, COL_PINS, ROWS, COLS);const byte BUZZER_PIN = 10;void setup() {pinMode(BUZZER_PIN, OUTPUT);Serial.begin(9600);delay(200);Serial.println("Press * to enter a new PIN or # to access the system.");}void loop() {char button_character = heroKeypad.waitForKey();tone(BUZZER_PIN, 880, 100);if (button_character == '#') {bool access_allowed = validatePIN();if (access_allowed) {Serial.println("Welcome, authorized user. You may now begin using the system.");} else {Serial.println("Access denied.");Serial.println("\nPress * to enter new PIN or # to access the system.");}}if (button_character == '*') {bool access_allowed = validatePIN();if (access_allowed) {Serial.println("Welcome, authorized user. Please enter a new PIN: ");for (int i = 0; i < PIN_LENGTH; i++) {button_character = heroKeypad.waitForKey();tone(BUZZER_PIN, 880, 100);current_pin[i] = button_character;Serial.print("*");}Serial.println();Serial.println("PIN successfully changed.");} else {Serial.println("Access denied. Cannot change PIN without the old or default.");Serial.println("\nPress * to enter a new PIN or # to access the system.");}}}bool validatePIN() {Serial.println("Enter PIN to continue.");for (int i = 0; i < PIN_LENGTH; i++) {char button_character = heroKeypad.waitForKey();tone(BUZZER_PIN, 880, 100);if (current_pin[i] != button_character) {Serial.println();Serial.print("Wrong PIN digit: ");Serial.println(button_character);return false;}Serial.print("*");}Serial.println();Serial.println("Device successfully unlocked.");return true;}
Pretty chill lesson today, and fun to pair some audio feedback with user interactions.
Day 14: Advanced security panel - 11/29/2025
Today's lesson builds on the basic security panel from yesterday, pairing it with the RGB LED and some new sounds to offer improved feedback for successful or unsuccessful authentication. No new hardware this time around, but we do have to rewire our microcontroller to free up the PWM pins that the RGB LED needs.
User flow:
- When a button is pressed:
- The buzzer should still beep with each button input; and
- A sound should play.
- When the correct PIN is entered:
- The RGB LED should glow green; and
- A "success" melody should sound.
- When an incorrect PIN is entered:
- The RGB LED should glow red; and
- A "failure" melody should sound.
Not a lot to actually write about today as hardware is just moving some pins around and adding the RGB LED back. On the software side of things, we update some consts to reflect new pins and use the PWM pins for the RGB LED. The other newish thing is setting up some input, success, and failure functions that control the sound and light feedback states.
Code for today:
#include "Arduino.h"#include <Keypad.h>const byte ROWS = 4;const byte COLS = 4;const byte PIN_LENGTH = 4;char password[PIN_LENGTH] = { '0', '0', '0', '0' };const char BUTTONS[ROWS][COLS] = {{ '1', '2', '3', 'A' },{ '4', '5', '6', 'B' },{ '7', '8', '9', 'C' },{ '*', '0', '#', 'D' }};const byte ROW_PINS[ROWS] = { 5, 4, 3, 2 };const byte COL_PINS[COLS] = { 6, 7, 8, 13 };Keypad heroKeypad = Keypad(makeKeymap(BUTTONS), ROW_PINS, COL_PINS, ROWS, COLS);const byte BUZZER_PIN = 12;const byte RED_PIN = 11;const byte GREEN_PIN = 10;const byte BLUE_PIN = 9;void setup() {pinMode(RED_PIN, OUTPUT);pinMode(GREEN_PIN, OUTPUT);pinMode(BLUE_PIN, OUTPUT);displayColor(128, 0, 0);Serial.begin(9600);Serial.println("Press * to set new password or # to access the system.");}void loop() {char button_character = heroKeypad.getKey();if (button_character == '#') {giveInputFeedback();bool access_allowed = validatePIN();if (access_allowed) {Serial.println("Welcome, authorized user. You may now begin using the system.");} else {Serial.println("Access denied.");Serial.println("\nPress * to enter new PIN or # to access the system.");}}if (button_character == '*') {giveInputFeedback();bool access_allowed = validatePIN();if (access_allowed) {displayColor(128, 80, 0);Serial.println("Welcome, authorized user. Please enter a new password: ");for (int i = 0; i < PIN_LENGTH; i++) {password[i] = heroKeypad.waitForKey();if (i < (PIN_LENGTH - 1)) {giveInputFeedback();displayColor(128, 80, 0);}Serial.print("*");}Serial.println();Serial.println("PIN successfully changed.");giveSuccessFeedback();} else {Serial.println("Access denied. Cannot change PIN without entering current PIN first.");Serial.println("\nPress * to enter new PIN or # to access the system.");}}}bool validatePIN() {Serial.println("Enter PIN to continue");for (int i = 0; i < PIN_LENGTH; i++) {char button_character = heroKeypad.waitForKey();if (password[i] != button_character) {giveErrorFeedback();Serial.println();Serial.print("Wrong PIN digit: ");Serial.println(button_character);return false;}if (i < (PIN_LENGTH - 1)) {giveInputFeedback();}Serial.print("*");}giveSuccessFeedback();Serial.println();Serial.println("Device successfully unlocked.");return true;}void displayColor(byte red_intensity, byte green_intensity, byte blue_intensity) {analogWrite(RED_PIN, red_intensity);analogWrite(GREEN_PIN, green_intensity);analogWrite(BLUE_PIN, blue_intensity);}void giveInputFeedback() {displayColor(0, 0, 0);tone(BUZZER_PIN, 880, 200);delay(200);displayColor(0, 0, 128);}void giveSuccessFeedback() {displayColor(0, 0, 0);tone(BUZZER_PIN, 300, 200);delay(200);tone(BUZZER_PIN, 500, 500);delay(500);displayColor(0, 128, 0);}void giveErrorFeedback() {displayColor(0, 0, 0);tone(BUZZER_PIN, 300, 200);delay(200);tone(BUZZER_PIN, 200, 500);delay(500);displayColor(128, 0, 0);}
One interesting thing is the slight delay between the tone() and displayColor functions in, for example, giveInputFeedback():
void giveInputFeedback() {displayColor(0, 0, 0);tone(BUZZER_PIN, 880, 200);delay(200);displayColor(0, 0, 128);}
During the hardware portion of the lesson, the instructor explains that the tone() and PWM functions will actually use the same resources from the Hero board, and issues can arise when we try to run both of the functions at the same time. To accommodate that, we turn the color off first before playing the tone, then delaying, then displaying the color.
Day 15: Creative day #3
Only one suggested project today: to make our PIN a little less brute force-able, we should change the code so that the error notification appears only after all four digits are entered, instead of immediately bailing out like it currently does.
Here's my solution:
#include "Arduino.h"#include <Keypad.h>const byte ROWS = 4;const byte COLS = 4;const byte PIN_LENGTH = 4;char password[PIN_LENGTH] = { '0', '0', '0', '0' };const char BUTTONS[ROWS][COLS] = {{ '1', '2', '3', 'A' },{ '4', '5', '6', 'B' },{ '7', '8', '9', 'C' },{ '*', '0', '#', 'D' }};const byte ROW_PINS[ROWS] = { 5, 4, 3, 2 };const byte COL_PINS[COLS] = { 6, 7, 8, 13 };Keypad heroKeypad = Keypad(makeKeymap(BUTTONS), ROW_PINS, COL_PINS, ROWS, COLS);const byte BUZZER_PIN = 12;const byte RED_PIN = 11;const byte GREEN_PIN = 10;const byte BLUE_PIN = 9;void setup() {pinMode(RED_PIN, OUTPUT);pinMode(GREEN_PIN, OUTPUT);pinMode(BLUE_PIN, OUTPUT);displayColor(128, 0, 0);Serial.begin(9600);Serial.println("Press * to set new password or # to access the system.");}void loop() {char button_character = heroKeypad.getKey();if (button_character == '#') {giveInputFeedback();bool access_allowed = validatePIN();if (access_allowed) {Serial.println("Welcome, authorized user. You may now begin using the system.");} else {Serial.println("Access denied.");Serial.println("\nPress * to enter new PIN or # to access the system.");}}if (button_character == '*') {giveInputFeedback();bool access_allowed = validatePIN();if (access_allowed) {displayColor(128, 80, 0);Serial.println("Welcome, authorized user. Please enter a new password: ");for (int i = 0; i < PIN_LENGTH; i++) {password[i] = heroKeypad.waitForKey();if (i < (PIN_LENGTH - 1)) {giveInputFeedback();displayColor(128, 80, 0);}Serial.print("*");}Serial.println();Serial.println("PIN successfully changed.");giveSuccessFeedback();} else {Serial.println("Access denied. Cannot change PIN without entering current PIN first.");Serial.println("\nPress * to enter new PIN or # to access the system.");}}}bool validatePIN() {Serial.println("Enter PIN to continue");bool passwordCheck = true;for (int i = 0; i < PIN_LENGTH; i++) {char button_character = heroKeypad.waitForKey();if (password[i] != button_character) {passwordCheck = false;}if (i < (PIN_LENGTH - 1)) {giveInputFeedback();}Serial.print("*");}giveSubmitFeedback(passwordCheck);Serial.println();return passwordCheck;}void displayColor(byte red_intensity, byte green_intensity, byte blue_intensity) {analogWrite(RED_PIN, red_intensity);analogWrite(GREEN_PIN, green_intensity);analogWrite(BLUE_PIN, blue_intensity);}void giveSubmitFeedback(bool authenticated) {if (!authenticated) {giveErrorFeedback();} else {giveSuccessFeedback();}}void giveInputFeedback() {displayColor(0, 0, 0);tone(BUZZER_PIN, 880, 200);delay(200);displayColor(0, 0, 128);}void giveSuccessFeedback() {displayColor(0, 0, 0);tone(BUZZER_PIN, 300, 200);delay(200);tone(BUZZER_PIN, 500, 500);delay(500);displayColor(0, 128, 0);}void giveErrorFeedback() {displayColor(0, 0, 0);tone(BUZZER_PIN, 300, 200);delay(200);tone(BUZZER_PIN, 200, 500);delay(500);displayColor(128, 0, 0);}
In validatePin() I have a new boolean variable, passwordCheck, which is initialized to true. As the for Loop runs while the user is inputting a PIN, if an incorrect character is provided, instead of throwing an error immediately, passwordCheck flips to false and the loop continues to run. At the end of the for Loop, a new function, getSubmitFeedback() is called with whatever the value of passwordCheck is, and all that function does is call giveSuccessFeedback() or giveErrorFeedback() if passwordCheck is false or true. validatePin() then returns passwordCheck.
I ran my solution past the course's AI assistant and it made two recommendations:
First, instead of this:
if (password[i] != button_character) {passwordCheck = false;}
use a logical &= assignment operator:
passwordCheck &= (password[i] == button_character);
This is the C++ equivalent of JavaScript's Logical And Assignment Operator.
The second recommendation is instead of this:
if (!authenticated) {giveErrorFeedback();} else {giveSuccessFeedback();}
to use a ternary operator:
(authenticated) ? giveSuccessFeedback() : giveErrorFeedback();
Anyway, I'm feeling pretty good about today's exercise.
Summary
So that's the end of week two of the 30 Days Lost in Space kit. I had far fewer struggles this week with the hardware, which focused on an RGB LED light, a 4 * 4 keypad, and a passive buzzer. One of the creative days did bring back the DIP switch, which is still a little bit squirrely for me, but overall I made it work.
It was a lot of fun adjusting the colors of the RGB LED and offering some visual and audio feedback to the tactile pressing of the keypad buttons. And as always, it feels so powerful combining code with hardware to accomplish something, even if it's as small as basic authentication and changing a light color or brightness.