HackerBox Basics Workshop

Introduction: HackerBox Basics Workshop

The HackerBox Basics Workshop provides an enlightening introduction to electronics suitable for ages 10-110. No soldering required. The electronic components and modules were carefully selected to work along with the included solderless breadboard using jumper wire connections. The HackerBox Basics Workshop is perfect for self-study or classroom use in schools, business, scouts, makerspaces, or other training scenarios. Accordingly, the workshop is available for purchase here in single units or class packs of ten.


This material will evolve over the coming weeks to ultimately cover introductory electronics in fifty topics and hands-on experiments. This journey, which we call Electrons to A.I., starts with fundamental electricity, visits semiconductor transistors, digital logic, data storage, sensors, controllers, computer programs, and arrives at embedded computing devices capable of machine learning and artificial intelligence. The Electrons to A.I. educational programming spans the following subject matter:

  1. Solderless Breadboards
  2. Electron Flow
  3. Control Electron Flow with a Switch
  4. Control Electron Flow with a Pushbutton
  5. Microcontrollers
  6. Set Up The Arduino Nano
  7. Control Electron Flow with Program Code
  8. Looping and Timers
  9. Program Output to Serial Monitor
  10. Program Input from a Pushbutton
  11. Digital Versus Analog
  12. Analog Input from a Potentiometer
  13. Measuring Voltage
  14. Voltage Dividers
  15. Resistor Structures
  16. Ohm's Law
  17. Adjusting Light Brightness
  18. Light Sensors
  19. Temperature Sensors
  20. Program Control Flow
  21. Storing Data in Arrays
  22. Generating Sound
  23. Measure Distance
  24. Electromechanical Motion
  25. Controlling Servo Motors
  26. Displaying Graphics and Text
  27. Full Color LEDs 
  28. Serial Addressable LEDs
  29. Measuring Capacitance
  30. Capacitor Structures
  31. Electron Flow through Diodes
  32. Bipolar Junction Transistors
  33. Transistors as Switches
  34. Digital Logic
  35. Logic Gates from Transistors
  36. Integrated Logic Chips
  37. XOR Gates from NAND Gates
  38. Combining Logic Gates
  39. Four-Bit Adder from Logic Gates
  40. Storing Information
  41. NAND Gate Flip-Flops
  42. Latches
  43. Counters
  44. Microcontroller Arithmetic
  45. Four-Bit Adder in Assembly Language
  46. Four-Bit Adder in C Language
  47. Algorithms
  48. Artificial Intelligence 
  49. Machine Learning
  50. Neural Networks

Step 1: Solderless Breadboards

Solderless breadboards are the fastest and easiest way to prototype and experiment with electronic circuits and systems.

The drawing illustrates the four areas of the typical solderless breadboard.

Areas A and D are "power rails" generally used to conduct the plus and minus voltages for your power supply across the entire length of the board. For example, the blue lines might be grounded (ZERO VOLTS) and the red lines might be connected to the +5V power supply line.

Areas B and C are "terminal strips" generally used to connect the pins of various circuit components. Each vertical column of five pins are connected together in the same way that the long horizontal rows of the power rails are connected together. Note that Area B is separated from Area C by a gap of exactly the distance between the two rows of pins on a standard DIP Chip. Accordingly, the terminal strips of Area B and those of Area C are not connected to one another.

Jumper Wires having pins or stripped wires on each end may be used to connect between the terminal strips as needed. The jumpers may also be used to connect the power rails into the terminal strip areas where needed.

For additional background on solderless breadboards, have a look at this tutorial from Sparkfun.

Step 2: Electron Flow

The Arduino Nano module is a microcontroller device with a USB-C connector. There is a lot of interesting circuitry on the Arduino Nano, which we will get to in due time. For now, we are only using the Arduino Nano as a mechanism for connecting 5V power from USB to our breadboard.

Once the Arduino Nano is inserted into the solderless breadboard as shown, the white USB-C to USB-C cable can be connected to the Arduino Nano. The other end of the cable can be connected to your PC (or USB hub) assuming there is an open USB-C port. If instead there is only a USB-A port available, there is a black/silver USB-C to USB-A adapter inside the plastic box of components.

Once power, a tiny red LED on the Arduino Nano will flash. We can ignore that for now.

Disconnect the USB power cable while assembling the circuit shown.

Let's examine the components and connections of the circuit...

The red "+" power rail across the top of the breadboard is connected to the +5V pin of the Arduino Nano by the longer red jumper wire.

The blue "-" power rail across the bottoms of the breadboard is connected to a GND pin of the Arduino Nano by the short black jumper wire.

The shorter red jumper wire connects the +5V power rail to the green LED. Note that the LED has a long pin and a short pin. The long pin must connect to the +5V power rail.

The short pin of the green led is connected to a 1K Ohm resistor.

The other end of the resistor is connected to the GND power rail.

These connections implement the circuit shown in the schematic to the right of the solderless breadboard.

One pin of the green LED is connected to the +5V power rail. The other pin of the green LED is connected (via the 1K resistor) to the GND power rail. Accordingly, there will be a potential difference between +5V rail and the GND rail across the LED. This difference will attract electrons from the GND rail to the +5V rail. Opposites attract, so the negative electrons (all electrons are negatively charged) are pulled towards the +5V direction.

Why exactly are we talking about electrons? Atoms make up everything and those atoms have electrons floating around them. Some of those electrons can be made to move. The electrons move more easily from metal atoms than from atoms of insulating material. Thus metals can conduct electricity (electrons). What that means is when a voltage (also called a potential difference) is applied across a conductor (like metal wire), some electrons in the conductor are drawn from the negative side of the voltage to the positive side of the voltage.

Electrons get sucked from the ground power rail, through the green LED, and towards the +5V rail. When the electrons flow through the LED, it glows with light.

Current Affairs

It is worth committing to memory that while electric current is the flow of electrons, the convention for specifying the direction of current flow is in the opposite direction of the flow of the electrons. Electrons flow negative to positive but "Conventional Current" flows positive to negative. Just accept it, or read under the heading "conventions" on the Wikipedia page for electric current to learn more.

Identifying Resistors

The Basics Workshop includes 1K and 10K resistors. How can we tell them apart?

The 1K resistors can be:

  1. Beige with stripes colored: brown, black, red (1_0_00 = 1K Ohms), or
  2. Blue with stripes colored: brown, black, black, brown (1_0_0_0 = 1K ohms)

The 10K resistors can be:

  1. Beige with stripes colored: brown, black, orange (1_0_000 = 10K Ohms), or
  2. Blue with stripes colored: brown, black, black, red (1_0_0_00 = 10K ohms)

Resistor color code calculator.

Step 3: Control Electron Flow With a Switch

Our circuit can be updated with the addition of an ON-OFF slide switch. The switch can turn the flow of electrons on and off so that the LED is illuminated or not illuminated.

Step 4: Control Electron Flow With a Pushbutton

Replacing the slide switch with a momentary pushbutton allow the flow of electronics to occur when the pushbutton is pressed. The flow of electronics is blocked when the button is released opening the circuit.

Step 5: Microcontrollers

A microcontroller or microcontroller unit (MCU) is a small computer on a single integrated circuit (IC) chip. A microcontroller contains one or more CPUs (processor cores) along with memory and programmable input/output peripherals. Program memory in the form of flash memory and/or ROM is also often included on chip, as well as a small amount of RAM. Microcontrollers are designed for embedded applications, in contrast to the microprocessors used in personal computers or other general purpose applications consisting of various discrete chips. Modern MCUs often integrate one or more advanced peripheral blocks such as graphics processing units (GPU), Wi-Fi modules, or coprocessors. (wikipedia)

Step 6: Set Up the Arduino Nano

The microcontroller we'll be working with here is the ATmega328P, which is part of the Arduino Nano module that we've already placed on the solderless breadboard.

The software we will use to program and interface with the Arduino Nano is called the Arduino IDE. Let's download and install it now.

  1. Connect the Arduino Nano to a USB port of your computer
  2. Run the Arduino IDE
  3. In the IDE, select Tools > Board > Arduino Nano
  4. Also select Tools > Processor > ATmega328P (Old Bootloader)
  5. Also select Tools > Port > (the USB port connected to the Nano)


If there are multiple USB ports to select from, you can do a little test. One of the ports will disappear from the list when you unplug the USB cable from the Nano and then navigate back into the Tools dropdown menu again. That one that disappears is the port connected to the Nano.

If there are no USB ports to select (or at least there is no port that disappears when unplugged), you may need to install a driver for the USB chip on the Nano module. This chip is the CH340 which have a driver included in most modern operating systems, but there is more information here if you need it.

Step 7: Control Electron Flow With Program Code

Disconnect the power from the Arduino Nano (unplug the USB cable) and wire up the circuit shown here. This circuit is exactly like the one used in Step 2 with one important distinction. The wire connecting to the long pin of the green LED connects to the MCU I/O pin D2 instead of connecting to +5V.

Pin D2 is an INPUT/OUTPUT (I/O) pin which means that the MCU can input or output signals through it. In order to operate the LED, the pin will be used as an output. More specifically, a digital output. A digital output can only be set to HIGH (5V) or LOW (GND).

You can probably guess that when Pin D2 is set to HIGH (5V) the green LED will be illuminated as it was in Step 2. When Pin D2 is set to LOW (GND) the green LED will not be illuminated. This is a lot like using a switch but instead of having to flip the switch on or off, the LED will now be under program control.

So let's write a program. Select File > New in the IDE. In a new, empty sketch there are two empty functions: setup() and loop().

Inside setup() type:

pinMode(2, OUTPUT);

This tells the chip that we will use ARDUINO PIN 2 as an output from the chip.

Inside loop() type:

digitalWrite(2, HIGH);

This tells the chip to output a HIGH value (5V) to ARDUINO PIN 2.

Click the arrow above the code window to compile the code and upload the program into the Arduino Nano board. The first time you compile a new program, the IDE will ask you to select the folder you want it saved to and also to give it a file name.

During download, the small LEDs on the Arduino Nano module will flicker briefly. Finally the green LED, which you have wired to the D2 pin will light up and glow steady. Congratulations! You just wrote and uploaded your first microcontroller program.

You may have noticed that the tiny red LED on the Arduino Nano has stopped flashing. That is because the program that was flashing the LED has been replaced with your new program that turns on pin D2 and lights up the LED attached thereto.

Change the word HIGH in your program to LOW and then upload the program again. As may seem obvious, this will turn the LED off.

Step 8: Looping and Timers

Let's try a more complicated program. Clean up the program from the last step to look exactly like the one in the image here.

First, we'll define a macro ledPin as 2 to represent the I/O pin 2 (aka D2) that the green LED is wired up to.

The loop() function loops around forever and ever. In each pass, the LED is turned on, we wait for a delay of 1s (1,000 milliseconds), the LED is turned off, we wait for a delay of 1s, and then we loop around and do it again.

Once you test out this code on the Nano, play around with changing the delay parameters from 1,000 to 100, or 500, or 2,000. Remember these delays are a number of milliseconds.

Note that the two delay numbers do not need to be the same. Try setting the LED on for 200 and then off for 2,000. Does the LED flash pattern match what you expect from your program.

Change both delays back to 1,000 and then also change the ledPin value from 2 to 13. The tiny red LED on the Arduino that was originally flashing when we first powered the module is attached to pin D13, so this final change returns the Arduino Nano to how we found it - with the tiny red LED slowly flashing on and off.

Step 9: Program Output to Serial Monitor

Update the code to reflect what is shown in the image. Note that the setup and LED state change are now also output to the serial port. Program the Nano and then open Tools > Serial Monitor to see the output over the MCU's serial port. Printing output to the serial port can be useful for simple program debugging.

Step 10: Read Program Input From a Pushbutton

Wire the button and a 10K resistor to the Nano as shown. Download the attached ReadButton.ino sketch file and program it to the Arduino Nano. Again open the Serial Monitor to view the output printed over the Nano's serial port.

Step 11: Digital Vs. Analog

On and off signals - switch on and off - button pressed or not - LED on or off are DIGITAL they are only on or off - one or zero.

Analog signals (like the state of a light dimmer knob) can take on many values besides simply on and off - one and zero. Of course, values in a computer are only digital (ones ad zeros) so analog values from the real world are still stored and processed within a computer as digital numbers. Those numbers just have a wider range of values other than just high and low (one and zero).

Step 12: Reading Analog Input From a Potentiometer

Wire the potentiometer (viable resistor) to the Nano as shown. Download the attached ReadAnalog.ino sketch file and program it to the Arduino Nano.

Open Tools > Serial Monitor

Slowly turn the potentiometer to see the values change in the serial monitor

Close the serial monitor

Open Tools > Serial Plotter

Slowly turn the potentiometer to see the plot trace change in the serial plotter

Step 13: Measuring Voltage

Reading analog values is quite interesting because it is how we get real world data into the MCU. Reading when a button is open or closed (one or zero) is one thing, but reading a range of different values allows our program to "know" much more interesting signals than simply on and off. For example, these interesting signals may represent sounds, light, images, radio, and so forth.

Note that the values from the previous ReadAnalog.ino sketch range from 0 at one end of the potentiometer to 1023 when the potentiometer is turned all the way to the other end. What do these values mean?

The analog values from the potentiometer enter the MCU through an analog-to-digital converter (ADC). The ADC is actually reading the voltage at the input pin. The ADC represents the voltage using ten bits. Ten bits can hold two to the power of ten (1024) different values. Accordingly, the ADC represents the input voltage as a number between 0 and 1023.

The ADC value 0 (lowest value) represents 0 volts at the input pin. The ADC value 1023 (highest value) represents 5V at the input pin. Generalizing this conversion scale to any ADC value, we can see that the ADC value may be multiplied by (5/1023) to convert the ADC value to voltage. That scaling factor of (5/1023) maps the 0-1023 input values to 0-5 volts.

Download the attached ReadVoltage.ino sketch file and program it to the Arduino Nano.

Open Tools > Serial Monitor

Slowly turn the potentiometer to see the values change in the serial monitor. Note that the range of displayed values is now 0.00 to 5.00 volts.

Let's look more closely at the sketch. It is very close to our last sketch with a couple of interesting changes...

The variable analogValue is still declared as type int, or an integer number. It will only take on values of whole numbers between 0 and 1023. In other words, analogValue will never be 1.5 or 2.7.

In contrast, the variable voltage is declared as type float, or a floating point number. It can take on decimal values. This is important because the integer read into the analogValue variable will not necessarily remain a whole number once it is multiplied by the scaling factor of (5/1023).

Look at the function call to output the numerical value voltage to the serial monitor. It is not println (print a line) like last time. Instead it is print (print a string). Then, the following line Serial.println(" volts") is used to append a space and the word volts after the number. Since the number output did not end the line (it was print, not println) the space and the word volts will be on the same line as the number. However, since the function call to println to outputs the space-volts string, it does end the line. This allows the next number printed to begin on its own new line.  

The subtleties of output formatting in computer programs are simple but complicated. They show us the multitude of actions that we take for granted when writing or typing. Our brains have just learned to do many things automatically, such as moving the pencil to the next line or hitting return at the end of a line. We must be more explicit about such things when writing computer programs.

Step 14: Voltage Dividers

The potentiometer we've been using has a total resistance of 10K ohms (10,000 ohms). As the schematic symbol implies, the potentiometer is actually a long 10K resistor connected between the two outer pins of the potentiometer. The center pin of the potentiometer connects to a wiper that sweeps across the length of the resistor as the shaft is rotated. The wiper effectively splits the resistor into two resistor portions that are connected in the middle at the center pin such that R1 + R2 = 10K. The allocation of the total 10K resistance between R1 and R2 is changed by rotating the shaft of the potentiometer.

If the potentiometer shaft is adjusted to its center point, R1 = R2 = 5K. This will equally divide the total voltage. The total 5V will be divided in half and the ADC will see 2.5V at the input pin. 

This structure of two resistances with an output tapped between the resistances is common and very useful. It even has a special name: voltage divider. The two resistances of a voltage divider can be the two portions of a potentiometer, two separate resistor components, or various other resistive loads. An example voltage divider we will use later will have one resistor and one sensor that changes its resistance based on whatever it is sensing. 

The formula shown in the image illustrates how the values of the two resistances R1 and R2 determine how the total voltage (5V in this case) gets "divided" to create the output voltage being measured. Don't worry too much about all of the math for now, you will encounter this structure again and again and it will eventually click into place. 

Useful trick: The value of an unknown resistor can be determined by creating a voltage divider including the unknown resistor and a known resistor. The ADC is then used to measure the voltage output from the voltage divider. The measured voltage is plugged into the formula allowing us to calculate the unknown resistance.  

Step 15: Resistor Structures

Case A: If we remove the potentiometer and replace it with two equal 1K resistors R1 and R2, the division of total voltage will be exactly half (2.5V) just as when we set the potentiometer to its midpoint creating two equal R1 and R2 resistive portions. Set this up on the breadboard and try it out. The ReadVoltage.ino sketch file is still useful for this experiment.

Case B: Replace the 1K resistor R1 from Case A (that's the resistor between A0 and 5V) with a 2K resistor to establish the illustrated voltage divider ratio. But wait, we don't have a 2K resistor! Luckily, resistances add up in series, so two 1K resistors placed in series are equivalent to one 2K resistor. Set this up on the breadboard and try it out.

Case C: Replace the 1K resistor R1 from Case A (that's the resistor between A0 and 5V) with a 0.5K (500 ohm) resistor to establish the illustrated voltage divider ratio. But wait, we don't have a 500 ohm resistor! Luckily, two equal resistors become half of the original resistance when arranged in parallel. Two 1K resistors placed in parallel are equivalent to one 500 ohm resistor. This "parallel halving" can be conceptualized as twice the current passing through two parallel pipes (or resistors) than would pass through only one of them. The effective doubling of pipe width in the parallel structure cuts the resistance in half.

Techniques using various resistor configurations (also called resistor networks) are useful to modify voltage levels and bend electricity to our will.

Some questions to ponder:

What is the equivalent resistance of THREE parallel 1K resistors?

What is the equivalent resistance of a 1M (one million) resistor in series with a 0.1 ohm resistor? Are both resistors really necessary? Would such a structure ever be found in a commercial product?

What is the equivalent resistance of a 1K resistor in parallel with a 10K resistor? Warning: This one is tricky. It will probably require a little research if you want to attempt the challenge, but the payoff is that you will also discover the theory behind why the two parallel 1K resistors in Case C above combine to form a 500 ohm resistor.

Step 16: Ohm's Law

A lot of attention is paid to voltage, current, and resistance because the three quantities are related in a simple, reliable way. Let's dig deeper...

Voltage (V) is the difference in electric potential energy between two points. To make an analogy, when talking about mass, gravitational potential can be thought of as how high something has been raised off the ground and thus how much energy it has to release when it falls to the ground. Similarly, a charge at 5V potential has more energy to expend getting to 0V (ground) than does a charge at only 2V. Voltage is sometimes called "electrical pressure" because it is a bit like water pressure. To give the tap water in your house pressure as it flows out of the faucet, water is often pumped uphill to a water tower. The higher the tower (gravitational potential above the ground), the more pressure or the harder water can push through the pipe. Similarly, the more voltage (electrical potential raised above ground), the harder the electrons can push through the wires.

Electrical Current (I) is very similar to the notion of water current in a river or a pipe. Current is how much stuff (electrons in this case) flow through per unit time. For example, gallons-per-minute of water or charges-per-second of electricity.

Resistance (R) can be thought of as the “tightness” of the pipe. The narrower the pipe is (higher resistance), the less current flows through for a given potential (voltage). You can make more current flow through a pipe by pushing it harder (higher voltage) or opening the pipe up (less resistance).

The relationship between these three qualities is formalized as Ohm's Law:

V = I x R

where voltage (V in volts) equals current (I in amperes) times resistance (R in ohms).

If you are not a fan of algebra, a useful mnemonic tool is illustrated here. Starting with the "V over IR" expression in the orange circle, we can simply over the parameter we'd like to know and the remaining two parameters display the necessary calculation to find the desired parameter.

How much current flowed through our 10K potentiometer when it was connected between 5V and Ground?

5V = Current x 10,000 ohms

Current (I) = 5 / 10,000 = 0.0005 A = 0.5 mA

This may seem very small, but keep in mind that the pins of a digital silicon chip (like our MCU) really do not like to supply (or sink) a lot of current. This is part of why we've been placing a "current limiting resistor" in series whenever connecting an LED to the MCU.

Note that the same amount of current flowing through the long 10K resistor of the potentiometer also flows through each of the potentiometer's resistive portions R1 and R2. This is due to a generalization of the law of conservation of charge: "current in" generally equals "current out". The more water you drink, the more you will probably need to visit the restroom.

Step 17: Adjusting Light Brightness

Build this circuit. It's the same one we used in Steps 7, 8, and 9 with one important difference. The MCU output is now set to pin number 3 instead of pin number 2. Why is that? Pin 2 does not support PWM but pin 3 does. We'll get to why that's important for this experiment.

You might think that we can just dim a light (or other wise adjust its brightness) but changing the voltage on it. Well, that might by true in some cases, but LEDs conduct exponentially, so we can think of them as only being "all on" or "all off". Furthermore, our simple MCU does not have a DAC (digital to analog converter). Many MCUs do have DACs, but this one does not. Without a DAC, the MCU cannot actually make an analog value, but only on (5V) and off (0V).

If you download the LEDdimmer.ino sketch and have a look, you will notice the use of a function called analogWrite() even though there is no analog output on this MCU.

What is going on when we call analogWrite() is actually a trick that involves pulsing the output pin rapidly on and off. The duty cycle of this pulsing is what is adjusted to create what seems sort of like an analog signal. The output signal is only ever 0V or 5V (never actually analog) but the duty cycle specifies what percentage of time that the pulsing signal is high versus low. This technique is called PWM (pulse width modulation). Example PWM waveforms are illustrated in the image.

The analogWrite() function can be called with the value 0 (pulsing always low or 0V), the value 255 (pulsing always high or 5V), or any value between to specify what amount of the time the pulsing is high. The LEDdimmer.ino code uses the values 50, 150, and 250 to generate three different levels of brightness for our green LED. Even though we cannot see it, the PWM is actually pulsing the LED on and off very rapidly.

Feel free to try out other values or patterns or values. How about wiring up the potentiometer, reading the potentiometer from pin A0, scaling the value read to the range of 0-255, and then using that scaled value to drive the LED IO pin 3. Go ahead and give it a shot!

Step 18: Light Sensors

A common light sensor is a Photo Resistor, which is also known as a Photo Cell or Light Dependent Resistor (LDR). An LDR is a resistor with a resistance that decreases when brighter light shines upon is photosensitive surface. 

Wire up the Photo Resistor and a 10K Ohm Resistor in a Voltage Divider structure as shown. Connect the output of the Voltage Divider to pin A0 of the Nano as shown. Use the ReadVoltage.ino sketch to read and display the output of the voltage divider. Open the Serial Monitor to view the output printed through the Nano's serial port. Notice now the voltage changes when the Photo Resistor is shielded from ambient light or when a brighter light shines upon it.

Can you figure out what will happen if you swap the LDR and the 10K resistor around so they are on different sides of the voltage divider? Give it a ponder and then try it out to test your theory.

Step 19: Temperature Sensors

Wire up the TMP36GT9Z Temperature Sensor (datasheet) to the Nano as shown. Be careful to identify the correct component from the part number on the flat surface of the body. Also be careful to correctly orient the component according the flat surface of the body.

Download the attached ReadTemp.ino sketch file and program it to the Arduino Nano. Open the Serial Monitor to view the output printed over the Nano's serial port. You may notice that the measured temperature is close but not correct. Any variation is often due to the USB power supply voltage not being exactly 5.00V. Calibrating sensors against noise, power fluctuations, etc. is a common matter for careful attention in electronic design. For this education purpose, we will just accept that it is not perfect.

Identifying the TMP36 Component: Your parts kit includes SIX components that look like the one in the image. That "look" is called a TO-92 package component. TO-92 components generally have a small black body with one flat side and three leads extending from one end. TO-92 components are often automatically identified as transistors. While some TO-92 packaged devices certainly may be transistors, not all of them are.

Of the SIX TO-92 components in the parts kit, ONE of them is the TMP36 Temperature Sensor and FIVE of them are 2N2222A Bipolar Transistors. Examining the flat surface of the component's body (perhaps with a magnifying lens) will reveal some very tiny printing that will indicate the difference between the TMP36 and 2N2222 devices.

Step 20: Program Control Flow

Most of the program code we've looked at so far has simply used the setup() and loop() functions to control the flow of the program. Whatever we put in setup() happens once when the program starts. Whatever we put in loop() literally loops around and keeps happen for ever.  

Looking at the ReadButton.ino sketch that we used earlier, you will see an if-else block. This is illustrated in the image above: If A is true, then do B. Otherwise (else) do C.  Examine how that structure is used in the ReadButton.ino sketch to do different things when the button is pushed versus when the button is not pushed.

Sometimes we need more control. Let's consider some examples...

  • sit and do nothing until an input is received
  • keep doing something periodically until an input is received
  • do something 10 times
  • do something 10 times but stop if an input is received
  • do something 10 times where each of those does something else four times
  • receive a keyboard input and do different things based on which key was pressed

Download and run the ControlFlow.ino sketch attached here. The sketch demonstrates simple examples of the four most commonly used program control flow mechanisms: if, else, for, while. Carefully examine how they are used in the sketch.

More information on these four along with the other available control mechanisms (do...while, switch...case, return, break, continue, goto) can be studied in the Arduino Documentation under Control Structure. Over time, you will encounter examples of these various forms. You will develop a feeling for which ones you like using for certain types of tasks. Many tasks can be accomplished just as well using two or three different control mechanisms, but some tasks lend themselves more to one specific type of control mechanism.

Program Comments (also called inline documentation) are important notes placed inside a program while writing it. They can tell others what the programmer was thinking when they wrote the program. They can also remind the programmer what as going on when they look at the code again later. Notice the comment block at the top of the ControlFlow.ino sketch demonstrating the use of // and /*...*/ structures for commenting your code. Commenting your code is more important than you might realize right now. Trust us... learn it, love it, do it.

Step 21: Storing Data in Arrays

So far, we have used variables to store information. Variables have types like integer (int), character (char), or floating point (float).

Multiple pieces of related data can be stored in a collection called an array.

Each piece of data in the array is called an element and an index number is used to select the various elements. Just like a variable has a type, the elements of an array have types. In fact, all of the elements have the same type. So we say that it is an array of integers, or an array of characters, etc.

Download and run the DataArrays.ino sketch attached here. The sketch demonstrates a couple of examples of creating and using arrays. Carefully examine how they are used in the sketch.

First, an array of five integers is created (declared) and initialized:

int myArray[5] = {3, 4, 5, 6, 7};

Initializing means starting the array with its initial values preset.  An array can also be created without initializing its values.

Examine how the for loop is used to index through the array named myArray. The index variable c counts from 0 to 4 to access each element of the array.

The second example shows how an array of characters can be used to store words. An array of characters is also called a string, text string, or a string of characters.

Look at the last line of the loop() function:

while(1); //just wait forever

Since "1" is always true, this while() conditional will execute its contents forever. However, its contents are empty. There aren't even curly braces, just a semicolon. So "executing the contents of the while loop" really means "do nothing". Since "1" is always true, this simple line "does nothing" forever. Execution is just stuck right there (forever) so this line of code accomplishes "halting" the loop() function so that it doesn't keep looping. This is a simple trick that is worth remembering. 

Step 22: Generating Sound

Piezoelectric speakers (also known as piezo buzzers) generate sound using the piezoelectric effect. This is in contrast to the electromagnetic coils used to generate motion (vibrations) in a traditional speaker. Piezoelectric crystals physically deform slightly (compress or expand) when electricity is applied. Likewise, the crystals also build up electric charge in response to mechanical stress such as bending or squeezing.

The electrical deforming property of piezo crystals can be used to generate sound (vibrations). While that sounds is not high fidelity, it is very efficient. A piezo buzzer can be driven directly from an I/O pin without any amplifier circuitry.

Wire up the Piezo Buzzer to the Nano as shown. Since the pins of the buzzer do not have spacing that matches the solderless breadboard it is helpful to insert the buzzer at an angle as illustrated.

Download and run the Sounds.ino sketch attached here. The sketch demonstrates using the tone() command to generate sounds. The tone() can take three parameters:

tone(pin, frequency, duration)

The first parameter pin specifies which I/O pin the buzzer is connected to. The second parameter frequency specifies the frequency of the tone to generate, and the third parameter specifies for how lone to generate it (in milliseconds).

After the five notes are played, there is a delay of four seconds before looping around to play the notes again.

Using #define Preprocessor Directives

A #define is handled by as a preprocess before a program is even compiled. It simply replaces any instance of the first portion with the second portion. While it might seem like a variable, it is not. We cannot store anything in it or modify it at runtime. It doesn't even exist in the view of the compiler because it is handled as a preprocess. It is just a simple text replacement to make code easier to read and fixed values (such as constants and I/O pin numbers) easy to globally modify from one place.

In the current example. five #define lines provide the frequencies (in Hz) for the notes to play:

#define NOTE_D7 2349
#define NOTE_E7 2637
#define NOTE_C7 2093
#define NOTE_C6 1047
#define NOTE_G6 1568

A few more #define lines specify the duration (in ms) for each note and the pause time that includes the note duration plus a little more to provide space between the notes. There is also a #define to represent the I/O where the buzzer is connected:

#define noteDuration 800
#define notePause 900
#define buzzerPin 8

Step 23: Measuring Distance

The HC-SR04 ultrasonic sensor module is like a bat. It includes a transmitter for radiating ultrasonic waves at 40kHz (40,000 Hz). The upper frequency limit of human hearing is around 20kHz so frequencies higher than that are called ultrasonic. The HC-SR04 module also includes a receiver to detect any ultrasonic waves that bounce back to it. The radiated ultrasonic waves propagate through the air and reflect off any surfaces they encounter. Some of the reflected waves bounce back to the module. 

The microcontroller can measure the time between transmitting the waves and receiving the reflections. Comparing this echo time to the known speed of sound through air allows the microcontroller to calculate the distance from the sensor to the reflecting object.

Wire up the HC-SR04 ultrasonic sensor module to the Arduino Nano as shown. The trigger (trig) pin is used to tell the module to transmit its ultrasonic waves. The echo pin allows the module to tell the microcontroller when it detects the reflected (echo) of the ultrasonic waves.

Download and run the Ultasound.ino sketch attached here. The sketch triggers a short pulse from the ultrasonic transmitter and then measures the amount of time for a reflected pulse to be detected at the ultrasonic receiver. Since that echo time is round-trip, it is divided by two to find the one-way trip duration. Finally, the one-way time is multiplied by the speed of sound to find the distance of the echo in centimeters. The distance is displayed on the serial monitor.

Step 24: Electromechanical Motion

Electromagnets serve as the nexus between electricity and physical motion or movement.

An electromagnet is a type of magnet in which the magnetic field is produced by an electric current. Electromagnets generally have a wire wound into a coil around a core. When electrical current flows through the wire, such as from a battery, a magnetic field is created allowing the core to act much like a permanent magnet. However, the magnetic field disappears when the electrical current is not flowing through the wire.

The magnetic field can be turned on, off, or reversed using electricity. The magnetic field can be used to move (attract or repel) other physical objects or structures. Accordingly, physical motion can be generated, stopped, and reversed under electrical control.

Direct current motors (DC motors) are rotary motors that can be found in toys, tools, and appliances. The small, silver DC motor in the illustration is shown on its own and as part of a yellow gearbox with an attached wheel. Such motors are often used in toys and hobby projects.

DC motors have an arrangement of coils (electromagnets) and permanent magnets that can convert electrical current into rotational motion. DC motors have structures that periodically change the direction of current in part of the motor thereby allowing the motion to spin around in a circle as the current changes.

The diagram of a simple DC motor shows a stationary set of magnets around the outside called the stator. The diagram also shows windings of wire in the center forming electromagnets. This center can rotate and is called the rotor. The connections in front of the rotor cause the current flow to change as the motor spins and forms a structure called the commutator.

Servo motors are simple motors coupled to closed loop control mechanisms that are often built into each motor. The control mechanism includes a controller and a sensor for position feedback. A servo motor can usually turn automatically to any angle instructed by the controller. Servo motors are used in applications such as robotics, model planes, and CNC (computer numerical control) machinery common in manufacturing.

Stepper motors have multiple notched or toothed electromagnets arranged as a stator around a central rotor. Each full rotation of motion is divided into a number of equal steps related to the spacing of the notches or teeth in the electromagnets. The motor position can be commanded to move to one of these steps. The electromagnets are energized by a control circuit that is usually external to the stepper motor.

Unlike servo motors, stepper motors generally employ open-loop control. The motor itself does not incorporate a position sensor for feedback, so the motor does not "know" where it is. This state information must instead be collected and maintained by the control electronics connected to the stepper motor. Stepper motors in your scanner or printer usually have to move to one end of their motion range to reset their position every time the system is powered up. You are probably accustomed to hearing this startup process occur and now you know why.

Step 25: Controlling Servo Motors

The Arduino IDE includes a built-in Servo Library capable of controlling multiple servo motors making careful use of timing mechanism within the microcontroller. The library can control 12 different servos using only only timer.

Wire up the servo motor to the Arduino Nano as shown using the wire harness built into the servo and three male-to-male jumper wires. The servo wiring harness has three color-coded lines: 5V, Ground, and Signal. As shown, the Signal line connects to I/O pin 9 of the Arduino Nano. Pulses on the Signal line instruct circuitry within the servo to move the motor shaft to different angular settings.

It is useful to push one of the included servo attachments onto the output gear of the servo to make movements of the servo easier to see.

Open the sketch:

File > Examples > Servo > Sweep

Download and run the sketch on the microcontroller. As you can probably guess from looking at the sketch code, it will sweep the shaft of the servo motor from 0 to 180 degrees and then back again.

What do you expect if you change the loop() function to contain only:


How could this be used to replace rolling dice or using a "spinner" on a board game? 

Step 26: Displaying Graphics and Text

The OLED display module measures a tiny 0.96 inch but has a resolution of 128 X 64 pixels.

In addition to the pins for 5V Power (VDD) and GND, there are two pins for the IIC (inter-integrated circuit) bus. The IIC bus is also known as the I2S bus. The two I2C bus pins are SCK (Serial Clock) and SDA (Serial Data). The four pins for the display should be wired to the Arduino Nano as shown.

In the last step, we used a built-in library for servos. Now it is time to pull in an external library. External libraries are extremely useful for adding additional functionality to the Arduino IDE and sketches that we build within the IDE.

The external library that we will install is the Adafruit SSD1306 Library. The driver chip inside the OLED display module is an SSD1306 so this library is designed to allow your Arduino sketch to communicate with this driver chip.

In the Arduino IDE, navigate to Tools > Manage Libraries

In the window that pops up, enter SSD1306 in the search box. A few different libraries will come up in the search, so be sure to hit install under the entry for Adafruit SSD1306.

The installation process will ask if it should also install the dependency Adafruit GFX Library. Be sore to click to allow that Adafruit GFX dependency to also be installed. After this, your two new libraries will be installed into the Arduino IDE and ready to use.

Download and run the OLEDtext.ino sketch attached here. Notice that the sketch uses #include to invoke the new GFX and SDD1306 libraries through the Arduino IDE. Once the sketch runs as provided, try changing the settings for TextSize, cursor position, and the string being "printed" to the display.

Libraries usually come with example programs for demonstrating use of the library. Give this one a try:

File > Examples > Adafruit SSD1306 > SSD1306_128x64_I2C

Once the sketch opens up, change the value in #define SCREEN_ADDRESS from 0x3D to 0x3C

Run the sketch to see a nice variety of graphics and text display examples.

Step 27: Full Color LEDs

The Common Cathode RGB LED is actually three LEDs inside of one package. The RGB stands for red, green, and blue. These are the colors of each of the three LEDs.

Recall from our earlier LED work that each LED (or any diode for that matter) has an anode terminal and a cathode terminal. The LED is forward biased, and can light up, when the higher voltage (for example +5V) is applied to the anode, and the lower voltage (for example GND) is applied to the cathode. For this reason, the anode and the cathode and often referred to as the positive and negative terminals respectively.

The three LEDs inside this one LED package have their cathode terminals connected together, which is why it is referred to as a "common cathode" arrangement. We will call this one shared cathode terminal the ground terminal for our purposes here.

The three separate anodes for the different colored internal LEDs can be driven with 5V to light up the individual LEDs as desired. Just as with the signal LEDs used earlier, a 1K resister is placed inline with each of the three colored LEDs to limit the total current flowing through the LED.

Wire up the Common Cathode RGB LED and three 1K Resistors to the Arduino Nano as shown.

Download and run the CommonCathodeRGB.ino sketch attached here. The sketch uses PWM to achieve the desired brightness from each of the red, green, and blue LEDs allowing the three colors to mix together to create other colors as shown with in the sketch.

Features of I/O Pins

Recall that PWM outputs are generated by the Arduino Nano using the analogWrite() function. As shown in the function's documentation, only pins 3, 5, 6, 9, 10, and 11 of the Arduino Nano can be used for PWM. That is why pins 3, 5, and 6 are used in this experiment and pin 4 is not. It is important to check the features of specific I/O pins on an MCU when selecting which pins you will use for which purpose. You will learn that for different MCUs, certain pins may be I/O (both input and output) while some are input only and some are output only. Some pins may have specific I/O characteristics or bus applications. Some pins was be able to trigger interrupts while some may not. Some pins may have optional pull-up resistors, pull-down resistors, both, or neither. There are many options to check up on when it comes to micro controller I/O pins. Note that I/O pins are also sometimes called GPIO (general purpose I/O) pins.

Quantity of I/O Pins

Since only pins 3, 5, 6, 9, 10, and 11 of the Arduino Nano can be used for PWM and the common cathode LED requires three of those to display full colors, only two such RGB LEDs can be driven by the Arduino Nano. In additional to what specific functionality each I/O pin may have, we also have to pay close attention to how many I/O pins there are in total and how we allocate them in our project. This often forces us to figure out tricks to get additional functionality from the MCU. For example, you probably see projects with far more than two RGB LEDs all the time. Next we will look at one of the more popular ways to get there.

Step 28: Serial Addressable LEDs

One of the easiest techniques for controlling multiple RGB LEDs with one microcontroller involves serial, addressable LEDs. Certain examples of these are commonly referred to as NeoPixels or RGB Pixels.

While such a device is often called "an LED", each one actually contains 3 LEDs (one red, one blue, and one green) along with an embedded, or integrated, control circuit.

The control circuit of each device can be feed control information through one pin (data in or Din) and thus only requires one I/O pin from the microcontroller. The control information is sent from the microcontroller to the first addressable LED in a serial fashion, meaning one bit at a time - in a series. First, eight bits are sent defining the amount of green light to be emitted, then eight bits defining the amount of red light, and finally eight bits defining the amount of blue light. Those 24 bits are grabbed, or "latched", into the controller. Those 24 bits define a possible total of 16,777,216 (2 to the power of 24) different colors.

In addition to its data in pin, each RGB pixel also has a data out (or Dout) pin. The first pixel's Dout pin is daisy chained to the second pixels Din pin, and so forth until all of the pixels are connected in a single chain.  This structure allows the entire chain to be fed from a single I/O pin of the microcontroller. Once each RGB pixel latches the first 24 bits it receives, the control circuit outputs any additional bits on its Dout pin. From the Dout pin, the additional bits are sent along to next RGB pixel in the chain.

Wire up the Eight-Pixel Addressable RGB LED Module as shown

The module includes eight daisy-chained WS2812Bs devices. You can read the ES2812B datasheet from the manufacturer if you wish.

Install the FastLED Library

In the Arduino IDE, navigate to Tools > Manage Libraries

In the window that pops up, enter FastLED in the search box. A few different libraries will come up in the search, so be sure to hit install under the entry for FastLED by Daniel Garcia.

The FastLED library comes with some nice example programs. Load this one for now:

File > Examples > FastLED > DemoReel100

Once the sketch opens, change two defines to match these:

#define LED_TYPE  WS2812B
#define NUM_LEDS  8

Run the sketch. After enjoying the results, play around with the sketch to see what fun can be had with these serial, addressable LEDs. As you can see, they are extremely versatile.

Step 29: Measuring Capacitance

A capacitor is a two terminal device capable of storing energy in an electric field. A capacitor can be thought of as a very fast rechargeable battery where energy is stored in an electric field instead of as chemical energy. Since an electric field can be generated an discharged rapidly, the capacitor operates on a much faster time scale than a chemical battery.

The simplest structure for a capacitor is two parallel conductive plates. Between the plates, there is usually a nonconducting dielectric such as ceramic, glass, plastic, paper, mica, or air. Alluding to that parallel plate structure, the schematic symbol for a capacitor is two parallels lines. 

The effect of a capacitor is known as capacitance and is measured in the unit Farads. One Farad is huge, so practical capacitors are usually measured in pico Farads (10 to the power of -12 Farads), nano Farads (10 to the power of -9 Farads), or micro Farads (10 to the power of -6 Farads).  

We will measure a ceramic capacitor with marking "106" which equals a capacitance value of 10μF. The marking represents a value in picofarads starting with two digits "10" followed by the multiplier factor 6 (ten to the power of six) or 1,000,000. Giving us the value of 10 * 1,000,000pF or 10μF.

When a voltage is applied across a capacitor, the electric field within the capacitor is charged up and energy is stored with the capacitor. This energy can then be discharged (used up) out of the capacitor. How rapidly the capacitor charges or discharges can be used to calculate the value of the capacitor.

Microcontroller code can measure the time required for charging or discharging the capacitor to calculate the capacitance between two pins. Wire the 10uF ceramic capacitor between pins A0 and A2 of the Nano as shown.

Download the attached Capacitance.ino sketch file and program it to the Arduino Nano. Open the Serial Monitor to view the output printed over the Nano's serial port. Notice how the capacitors marked as 10uF capacitors will have measurements varying from about 8 to 11 uF. This is normal for the type of capacitor we are working with.

How does this timing work? According to basic physics, it requires one time constant to charge a capacitor from zero up to 63.2% of the applied voltage. In this case, that would be 63.2% of 5V. But what is the time constant? It is just R*C, where R is the resistance of the circuit (in Ohms) and C is the capacitance (in Farads). It may look like there is no resistor in the circuit, but in fact the microcontroller's internal pullup resistor (having approximately 34.8 Ohms) is used to charge up the external capacitor. The code in the sketch is a little complicated, but you can certainly explore how the RC time constant and the known pullup resistance of the microcontroller are used to make the measurement calculations.

Step 30: Capacitor Structures

Modify the previous capacitor circuit by combining two 10uF capacitors in parallel and then in series as shown here. In each instance, observe the output of the serial monitor to measure the equivalent capacitance of the combined capacitors. Remember that the capacitors are not exactly 10uF even though that is how they are marked.

Revisit the results found in Step 15: Resistor Structures. Notice how resistors and capacitors combine in similar, but opposite, fashions. Serial resistors add together while parallel capacitors add together. The equivalent resistance of parallel resistors is the inverse of the sum of the inverse of the individual resistors. Similarly, the equivalent capacitance of series capacitors is the inverse of the sum of the inverse of the individual capacitors.

Consider delving deeper into capacitor structures by combining all three of the 10uF capacitors in different ways.

For an advanced exercise, measure the capacitance of each capacitor alone and then plug those actual individual capacitances into the parallel and serial equivalence formulas to see how close the combined measurements are to theory.

Step 31: Electron Flow Through Diodes

Semiconductor diodes are like one-way valves. They only allow current to flow in one direction, and not in the opposite direction. This is true for all types of Diodes, including LEDs (Light Emitting Diodes).

Wire up two 1K resistors and an LED as shown in the diagram.

Download the attached DiodeTest.ino sketch file and program it to the Arduino Nano. Open the Serial Monitor to view the output printed over the Nano's serial port.

With the LED wired as shown (long pin to A1 and short pin to A2), the serial monitor will indicate that current flows from A1 to A2 but current cannot flow from A2 to A1.

With the direction of the LED swapped, current will flow from A2 to A1, but not from A1 to A2.

With the LED removed, current will not flow in either direction.

With A1 connected directly to A2, current will flow in both directions.

Carefully examining the sketch code will reveal how two additional pins (A0 and A3) are used to control 1K resistors connected (respectively) to A1 and A2. The first test in the code sets A3 to ground which means the 1K resistor connected to A2 is grounded (pulling low). Then the code configures A0 as an input meaning that A0 is not driving high or low, but instead is floating. With A0 floating, the resistor connected to A1 will not be pulled high or low. Pin A1 is however connected directly to 5V. So one side (A1) of the DUT (device under test) is set to 5V and the other side (A2) of the DUT has a 1K resistor to ground and can also be read as an analog input to the microcontroller.

Depending upon what is between A1 and A2, current will either not flow (keeping the original 5V difference between A1 and A2). However, if current is flowing through the DUT, it will also flow through the 1K resistor since they are in series. The voltage drop in the 1K resistor will make the difference between A1 and A2 less than 5V. Sensing this lower voltage difference allows the code to identify that current is flowing. This trickery probably starts out sounding a lot more complicated than it really is. Stepping through the measurement process several times or until everything clicks is a worthwhile undertaking if you're up for it.

Step 32: Live the HACK LIFE

We hope you are enjoying the HackerBox Basics Workshop. To continue your adventure into electronics, computer technology, and hacker culture, visit HackerBoxes.com where you can find the HackerBox Soldering Workshop, and HackerBox Core Workshop. This suggested workshop progression builds towards increasingly advanced electronics projects, such as those found in the monthly HackerBox subscription boxes.

As you work through the HackerBox Basics Workshop, be sure to wear your iron-on electronics achievement patch with pride!

If you are a scout, please note that the included patch is not an official merit badge and should not be worn on your uniform. Of course, it can be applied to other gear such as a hat, backpack, or jacket. Talk to your Scoutmaster about earning your official electronics badge.

Be the First to Share


    • Make It Bridge

      Make It Bridge
    • Game Design: Student Design Challenge

      Game Design: Student Design Challenge
    • For the Home Contest

      For the Home Contest



    Question 2 months ago

    Just getting started with this but can't seem to get the initial program to load to the Arduino board. Any tips? Thanks!

    The error message reads as follows: "Uploading Error Exit Status 1" and the log reads as follows:

    Sketch uses 724 bytes (2%) of program storage space. Maximum is 30720 bytes.
    Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x57
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x57
    Failed uploading: uploading error: exit status 1


    Answer 2 months ago

    I got this yesterday after trying to connect to RPi 4 running Ubuntu. Had to install the Legacy Arduino IDE software since there seems to be a lack of support for ARM architecture on the newer one. Took me forever to get software being able to recognize the arduino. I had to do 2 things. Can't remember if step 1 fixed this error or not, so maybe try that first.

    1. Don't use the old bootloader processor but the other one. Get board Info should work hopefully
    2. Usb isn't recognized on Ubuntu, remove brltty: sudo apt remove brltty


    Reply 2 months ago

    Thanks - we tried on a different computer earlier today (also Windows 10) and were given the option to download some updates and patches to the Arduino IDE. Those made all of the difference and we were back on track. I'll give it another whirl on my desktop machine and see if I can get the patches to load. Onwards and upwards!


    2 months ago on Step 1

    The breadboard mine came with doesn't work with the arduino. I wasn't able to attach the arduino and had to grab a different one I had on hand. Also had imaging/comnection issues with the arduino software. Spent hours debugging and almost thought I had a defective arduino. Other than that, this kit was pretty neat. Will try the spldering one next, whenever its in stock


    4 months ago

    Yes, the Basics Workshop is still active. Since this Spring when several experiments were released, there have been some delays. Updated experiments (capacitors and diodes) were released last week and additional experiments will be published as they become available. Thank you for your patience.


    Question 6 months ago on Introduction

    Hi! I was wondering if there would be more after 28 sections? I saw the beginning had up to 50, but I didn't see any past 28. Thank you!


    Answer 6 months ago

    Yes, there should be more sections. Keep an eye out for the others. We'll try to get them uploaded as soon as possible.


    Reply 5 months ago

    Agreed - can you please upload the second half of the sections? The material you've got posted so far is great. Thank you!


    Reply 4 months ago

    When do you intend to upload the additional material? It's been 10 months since the first piece was uploaded. Has HackerBoxes abandoned this project?