Elecrow All-in-One Arduino Starter Kit Review - 20 Projects & 16 Modules
This Elecrow Starter Kit saves time, eliminates wiring problems, and makes learning electronics both simple and enjoyable.
This time I will describe a simple and practical way to enter the world of microcontrollers, specifically Arduino. Arduino is an open-source electronics platform that combines simple hardware (microcontroller boards) and software (Arduino IDE) to let anyone build interactive projects like robots, sensors, or smart devices. It’s widely used by beginners, hobbyists, and professionals because it’s affordable, easy to learn, and supported by a huge global community.
Namely, during the school year I conduct practical training for students from a local vocational school. In the practical exercises I used a standard breadboard on which the components were connected with wires.

However, it often happened that the device did not function even though it was connected exactly according to the scheme, and the reason for this was poor contacts and parasitic oscillations that occur due to the proximity of large metal surfaces in the breadboard. The kit I will present to you is a solution to all these problems and is very practical for both beginners and advanced users.

The kit is in the form of a plastic tool box with a handle that contains all the necessary elements and is ready to work immediately after opening. This saves valuable time, especially when developing a software project. Let's see what's inside the box.

Besides the necessary cables, there is also a moisture sensor, an infrared remote controller, and accessories for the servo motor. There is also the microcontroller board that needs to be mounted on the appropriate base.
Now the main part: the lower half of the case is actually a large PCB on which, in addition to the MCU, all the other components are mounted. These are mainly various sensors, then displays, servo motors, LEDs, relays and linear potentiometers. All these components are connected to the corresponding pins of the Arduino board that are marked next to the sensor. For example, the servo is connected to pin D9, and the relay to D4.

So all these sensors and components are connected to a specific pin on the microcontroller via the PCB lines. This means that there is no need for any wiring or soldering.
On the Elecrow Wiki page you can download a PDF manual of over 170 pages, which describes in great detail with pictures how to install Arduino IDE with proper support for Arduino Nano R4, and install the necessary libraries.
Then, more than 20 hardware and software projects that use these sensors are also described in detail. You can download the complete codes for these projects on the given GitHub page.

In this way, creating any of the proposed projects is extremely simple. It is enough to just upload the desired code and the project is ready. In the manual, each line of the code is described very extensively and step by step.
Now I will practically present you the creation of one of the given projects. For example, let it be "Servo Example". We start the Arduino IDE and select the Arduino Nano R4 board.

Now we copy the code from GitHub and paste it into the IDE. Previously, I copied all the given libraries into the Documents-Arduino-libraries folder. Then I connect the USB cable and select the appropriate COM port, in this case COM15 and press Upload. In a short time, the uploading is completed and the project is ready.

As I mentioned at the beginning, the kit is adapted for both absolute beginners and more advanced users. For example, we can expand the given codes with additional functions, but also create and test completely new code that would use one of the given sensors. And that's not all: There are two I/O connectors on the PCB, one for serial communication and the other with analog inputs, to which we can also connect one of the many external ElekroW sensors without soldering.
Now I will present you a test of one of my previous projects (Spectrum Analyzer) where the code was adapted specifically for this device.

And finally a short Conclusion. Whether you're just starting with Arduino or looking for a fast and reliable prototyping platform, this Elecrow Starter Kit is an excellent choice. It saves time, eliminates wiring problems, and makes learning electronics both simple and enjoyable.
/*
16x2 LCD Spectrum Analyzer
Adapted for:
Elecrow All-in-One Starter Kit for Arduino Nano R4
Hardware connections on the kit:
--------------------------------
Microphone / Sound sensor : A1
Three buttons : A3
LCD SDA : A4
LCD SCL : A5
LCD I2C address : 0x27
K1 changes the spectrum display style.
by mircemk July 2026
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <arduinoFFT.h>
// =====================================================
// ELECROW KIT PINS
// =====================================================
#define AUDIO_PIN A1
#define BUTTON_PIN A3
// =====================================================
// LCD CONFIGURATION
// Same configuration as the official Elecrow LCD code
// =====================================================
#define LCD_COLUMNS 16
#define LCD_ROWS 2
LiquidCrystal_I2C lcd(
PCF8574_ADDR_A21_A11_A01,
4, 5, 6, 16, 11, 12, 13, 14,
POSITIVE
);
// =====================================================
// FFT CONFIGURATION
// =====================================================
const uint16_t SAMPLES = 256;
// 8000 Hz gives a maximum detectable frequency of 4000 Hz.
const double SAMPLING_FREQUENCY = 8000.0;
double vReal[SAMPLES];
double vImag[SAMPLES];
ArduinoFFT<double> FFT =
ArduinoFFT<double>(
vReal,
vImag,
SAMPLES,
SAMPLING_FREQUENCY
);
// FFT bins used for the 16 LCD columns.
// With 8000 Hz / 256 samples:
// one FFT bin is approximately 31.25 Hz.
const uint8_t spectrumBins[16] = {
2, 3, 4, 6,
8, 10, 12, 14,
16, 18, 20, 22,
24, 26, 28, 30
};
// =====================================================
// SPECTRUM SETTINGS
// =====================================================
// Increase this if the display reacts to background noise.
// Decrease it if the spectrum reacts too weakly.
const double NOISE_FLOOR_DB = 20.0;
// Minimum dynamic range above the noise floor.
const double MIN_DYNAMIC_RANGE_DB = 8.0;
// Additional space above the strongest peak.
const double PEAK_HEADROOM_DB = 4.0;
// Spectrum movement smoothing.
// Higher value = faster movement.
// Lower value = smoother movement.
const float BAR_ATTACK = 0.95;
const float BAR_RELEASE = 0.55;
// Automatic gain smoothing.
const float AUTO_GAIN_SPEED = 0.12;
// Displayed bar levels: 0 to 15.
float displayedLevel[16];
// Automatically adjusted upper spectrum limit.
double autoGainTopDB = 55.0;
// =====================================================
// DISPLAY MODES
// =====================================================
// Six pixel patterns from the original project.
const uint8_t modePattern[6] = {
4, // 00100
14, // 01110
10, // 01010
27, // 11011
31, // 11111
21 // 10101
};
uint8_t spectrumMode = 0;
// Button debounce / release detection.
bool buttonWasPressed = false;
unsigned long lastButtonTime = 0;
// =====================================================
// FUNCTION PROTOTYPES
// =====================================================
void createSpectrumCharacters();
void readModeButton();
bool isK1Pressed();
void collectAudioSamples();
void calculateSpectrum();
void drawSpectrum();
double magnitudeToDb(double magnitude);
// =====================================================
// SETUP
// =====================================================
void setup() {
Serial.begin(115200);
pinMode(AUDIO_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT);
// Default analogRead resolution used by the official
// Elecrow button example is 10 bits: 0 to 1023.
analogReadResolution(10);
Wire.begin();
lcd.begin(LCD_COLUMNS, LCD_ROWS, LCD_5x8DOTS);
lcd.clear();
lcd.backlight();
createSpectrumCharacters();
lcd.setCursor(0, 0);
lcd.print("Spectrum");
lcd.setCursor(0, 1);
lcd.print("Analyzer Nano R4");
delay(1200);
lcd.clear();
// Initial ADC read after selecting A1.
// This helps the ADC input settle.
analogRead(AUDIO_PIN);
}
// =====================================================
// MAIN LOOP
// =====================================================
void loop() {
readModeButton();
collectAudioSamples();
calculateSpectrum();
drawSpectrum();
}
// =====================================================
// READ K1 BUTTON ON A3
// =====================================================
void readModeButton() {
bool pressed = isK1Pressed();
if (pressed && !buttonWasPressed) {
if (millis() - lastButtonTime > 250) {
spectrumMode++;
if (spectrumMode > 5) {
spectrumMode = 0;
}
createSpectrumCharacters();
lastButtonTime = millis();
}
buttonWasPressed = true;
}
if (!pressed) {
buttonWasPressed = false;
}
}
bool isK1Pressed() {
/*
Read twice because the ADC was previously reading A1.
The first read allows the ADC multiplexer to settle.
*/
analogRead(BUTTON_PIN);
int buttonValue = analogRead(BUTTON_PIN);
/*
Official Elecrow values:
K1 approximately 500-520
K2 approximately 680-690
K3 approximately 845-860
A slightly wider range is used for tolerance.
*/
if (buttonValue >= 470 && buttonValue <= 550) {
return true;
}
return false;
}
// =====================================================
// CREATE THE 8 CUSTOM LCD BAR CHARACTERS
// =====================================================
void createSpectrumCharacters() {
uint8_t pixelPattern = modePattern[spectrumMode];
for (uint8_t characterNumber = 0;
characterNumber < 8;
characterNumber++) {
uint8_t customCharacter[8];
/*
Character 0 has one active row.
Character 7 has all eight rows active.
*/
for (uint8_t row = 0; row < 8; row++) {
if (row >= (7 - characterNumber)) {
customCharacter[row] = pixelPattern;
} else {
customCharacter[row] = 0;
}
}
lcd.createChar(characterNumber, customCharacter);
}
}
// =====================================================
// AUDIO SAMPLING
// =====================================================
void collectAudioSamples() {
const uint32_t samplingPeriodMicroseconds =
1000000UL / SAMPLING_FREQUENCY;
// Allow ADC multiplexer to settle after reading A3.
analogRead(AUDIO_PIN);
for (uint16_t i = 0; i < SAMPLES; i++) {
uint32_t sampleStart = micros();
vReal[i] = analogRead(AUDIO_PIN);
vImag[i] = 0.0;
while ((micros() - sampleStart) <
samplingPeriodMicroseconds) {
// Wait for the next sample time.
}
}
}
// =====================================================
// FFT CALCULATION
// =====================================================
void calculateSpectrum() {
// Remove microphone DC offset.
FFT.dcRemoval();
// Apply Hamming window.
FFT.windowing(
FFTWindow::Hamming,
FFTDirection::Forward
);
// Calculate FFT.
FFT.compute(FFTDirection::Forward);
// Convert complex values into magnitudes.
FFT.complexToMagnitude();
double frameMaximumDB = NOISE_FLOOR_DB;
// Find strongest displayed frequency bin.
for (uint8_t column = 0; column < 16; column++) {
uint8_t bin = spectrumBins[column];
double levelDB = magnitudeToDb(vReal[bin]);
if (levelDB > frameMaximumDB) {
frameMaximumDB = levelDB;
}
}
// Calculate target upper gain limit.
double targetTopDB = frameMaximumDB + PEAK_HEADROOM_DB;
if (targetTopDB <
NOISE_FLOOR_DB + MIN_DYNAMIC_RANGE_DB) {
targetTopDB =
NOISE_FLOOR_DB + MIN_DYNAMIC_RANGE_DB;
}
// Smooth automatic gain.
autoGainTopDB =
autoGainTopDB * (1.0 - AUTO_GAIN_SPEED) +
targetTopDB * AUTO_GAIN_SPEED;
// Calculate 16 display levels.
for (uint8_t column = 0; column < 16; column++) {
uint8_t bin = spectrumBins[column];
double levelDB = magnitudeToDb(vReal[bin]);
double normalized =
(levelDB - NOISE_FLOOR_DB) /
(autoGainTopDB - NOISE_FLOOR_DB);
if (normalized < 0.0) {
normalized = 0.0;
}
if (normalized > 1.0) {
normalized = 1.0;
}
float targetLevel = normalized * 15.0;
// Faster rise, slower fall.
if (targetLevel > displayedLevel[column]) {
displayedLevel[column] =
displayedLevel[column] * (1.0 - BAR_ATTACK) +
targetLevel * BAR_ATTACK;
} else {
displayedLevel[column] =
displayedLevel[column] * (1.0 - BAR_RELEASE) +
targetLevel * BAR_RELEASE;
}
}
}
// =====================================================
// CONVERT FFT MAGNITUDE TO DECIBEL-LIKE VALUE
// =====================================================
double magnitudeToDb(double magnitude) {
return 20.0 * log10(magnitude + 1.0);
}
// =====================================================
// DRAW 16 SPECTRUM BARS
// =====================================================
void drawSpectrum() {
for (uint8_t column = 0; column < 16; column++) {
int level = round(displayedLevel[column]);
level = constrain(level, 0, 15);
if (level == 0) {
lcd.setCursor(column, 0);
lcd.print(' ');
lcd.setCursor(column, 1);
lcd.print(' ');
}
else if (level <= 8) {
lcd.setCursor(column, 0);
lcd.print(' ');
lcd.setCursor(column, 1);
lcd.write((uint8_t)(level - 1));
}
else {
lcd.setCursor(column, 0);
lcd.write((uint8_t)(level - 9));
lcd.setCursor(column, 1);
lcd.write((uint8_t)7);
}
}
}









