Record 005 / Hardware and PCB
RP2040 interface PCB
PCB designAn RP2040 interface board combines controller connections, power and signal interfaces. Routing and assembly views document the component layout and connector placement.
Project detailsEngineering archive
98 engineering records across six areas, including board designs, firmware modules, prototypes and studies. Each record identifies its scope and development stage.
Search by application or technology. Selected records include source-code excerpts, flow diagrams and technical notes.
98 records · All six areas
Open a record for technical notes and supporting material.
Record 005 / Hardware and PCB
An RP2040 interface board combines controller connections, power and signal interfaces. Routing and assembly views document the component layout and connector placement.
Project detailsRecord 029 / Hardware and PCB
A six-layer controller board for six actuators, sensor inputs, ESP32 control and battery management.
Record 042 / Hardware and PCB
Four-channel Hall PCB design, with related firmware showing how two magnetic inputs control an FM tuning offset.

Firmware flow
Related two-input magnetic-knob firmware, not proven firmware for the four-channel PCB.
Compare the previous and current two-input states. Accept only a forward or reverse transition, optionally reverse its sign and accumulate it. Always remember the new state.
The selected variant has no timed Hall debounce or calibration. Accepted transitions contribute directly; they are not divided by four.
Selected source excerpt · selected source lines 156–169. Source inspection is not a hardware test.
static inline void handleQuadEdge() {
uint8_t sNew = readAB_normalized();
uint8_t idx = (prevState << 2) | sNew;
int8_t step = QEM[idx];
if (step == 1 || step == -1) {
if (REVERSE_DIR) step = -step;
pending += step;
}
// ignore 0 or 2
prevState = sNew;
currState = sNew;
}Open the exact source-level diagramFirmware flow
Related two-input magnetic-knob frequency routine, not verified integration with the four-channel PCB.
Collect pending movement, update the offset and calculate a target frequency. If the result is beyond a band edge, wrap to the opposite boundary before requesting the tune.
The excerpt demonstrates the requested frequency calculation and boundary wrapping, not calibrated tuning accuracy or PCB operation.
Selected source excerpt · selected source lines 236–257. Source inspection is not a hardware test.
noInterrupts();
int8_t d = pending;
pending = 0;
uint8_t s = currState;
interrupts();
if (d != 0) {
totalSteps += d;
}
// 3) Compute target with wrap-around
float target = baseMHz + totalSteps * STEP_MHZ;
if (target > FM_MAX_MHZ + 1e-6f) {
target = FM_MIN_MHZ;
totalSteps = (int32_t) roundf((target - baseMHz) / STEP_MHZ);
} else if (target < FM_MIN_MHZ - 1e-6f) {
target = FM_MAX_MHZ;
totalSteps = (int32_t) roundf((target - baseMHz) / STEP_MHZ);
}
tuneTo(target);Open the exact source-level diagramThe reviewed two-input version samples the A/B state when either input changes. It combines the previous and current states into a lookup-table index. Only +1 or −1 results change the pending count; unchanged states and invalid jumps are ignored. Direction can be reversed in configuration.
The main loop copies and clears the pending count with interrupts temporarily disabled. It adds that signed count to totalSteps, then requests baseMHz + totalSteps × 0.2 MHz. An out-of-band request wraps between 88 and 108 MHz. The code counts each accepted transition directly; it does not divide four transitions into one detent.
The potentiometer uses an exponential moving average with alpha 0.15. Its base frequency changes only after a 0.05 MHz difference. This selected Hall decoder has no timed debounce gate. Other supplied variants use different decoding methods; their filename suffixes do not establish which was the final hardware version.
The original project record establishes a four-channel PCB design. The supplied tuning example uses two digital Hall inputs, so it is shown as related magnetic-knob firmware. The inspected files do not prove that this version runs on the pictured four-channel board.


Record 043 / Hardware and PCB
A dual motor driver circuit based on the DRV8833, with the associated control and power connections.
The circuit brings motor-load current and controller signals into the same design.
The DRV8833 circuit defines the motor, power and control connections around the driver.
The circuit defines the electrical interface between controller commands and motor drive.
Record 059 / Hardware and PCB
A two-board control system separates the operator’s keypad from the relay outputs. The handheld unit sends key events over CAN; the receiver maps each event to the corresponding relay.
Project details
System flow
The handheld side scans a keypad and translates user actions into CAN frames. This lets the control interface occupy a different physical location from the board connected to external actuators.
The receiver decodes the commands and applies a defined relay mapping. The layout image shows the output board's routing and relay connections, connecting the firmware task with the physical electrical interfaces.
Key release is part of the command handling. A useful control interface must describe both the start of a requested action and the change when the operator releases the key.
Record 064 / Hardware and PCB
A circuit and schematic package documenting an embedded system and its electrical interfaces.

The schematic brings the controller, driver and power connections into a common view. The drawing identifies the boundary between the Arduino's control signals and the motor driver's connections.
A start program push button, power switch and potentiometer are visible in the circuit. These connect user actions to the electronic control arrangement instead of leaving them as separate assembly assumptions.
The package documents electrical intent and connection points. Its role is schematic definition and review, with the drawing serving as a reference for later hardware work.
Record 082 / Hardware and PCB
A wiring package for a CNC controller, covering motor interfaces and limit or safety input connections.

The drawing groups motor connections by axis. X and Z have their own sections, while the Y-axis section contains two stepper connections, making the machine’s motion wiring easier to follow.
Limit switches and an emergency-stop connection are shown alongside the controller. Their placement in the same package makes these inputs part of the overall wiring discussion, rather than a separate installation note.
Power, ground and control connections share the same drawing. For assembly and troubleshooting, the useful detail is the ability to trace a connection from the controller to the relevant driver, motor or input.
Record 088 / Hardware and PCB
A multi sheet schematic package organising embedded interfaces and power domains.

The schematic labels the transmitter-side generator and Gray encoder separately from the receiver sampling and decoder. These groups give the reader an entry point into the circuit’s signal flow.
Named nets connect the logic groups with channel sections. Keeping those relationships visible matters when a signal passes through several functional blocks before returning to a decoded output.
The drawing includes test-point groups and channel monitoring connections. Their presence makes intended observation locations part of the design documentation, alongside the circuit connections themselves.
Record 098 / Hardware and PCB
A restored car radio needs modern amplifier electronics within a fixed board outline. The design brings audio inputs, front and rear speaker connections, control signals and a vehicle supply into a 50 × 50 mm footprint.
Project details
The fixed board outline determines where the connectors, amplifier stages and supporting components can sit. Power enters near one corner, while the audio and speaker connections occupy the board edges. Placement has to make those connections practical within the existing radio assembly.
The design review covers component choice, supply protection, local decoupling and the return paths around the amplifier stages. Copper areas, track routing and via placement are considered together because the board carries both switched power and audio signals in a small space.
The three views expose different parts of the same board: component placement, routing and copper coverage. The design is being refined through schematic, component and layout review.
Record 002 / Firmware and control
A MIDI control interface using an Arduino Nano and physical controls. The work covers control input handling and MIDI event generation.
Keypad input identifies a selected key; encoder input supplies an increment or decrement. Both are processed before a MIDI event is generated.
Scaling maps control values to the intended MIDI range. Debouncing prevents contact chatter from becoming repeated actions.
MIDI event generation is separate from physical input processing, allowing the control arrangement and event formatting to be handled independently.
Record 003 / Firmware and control
Audio playback control built around a Teensy, with peripheral interfaces and storage integration.
Playback control uses an operating state to distinguish new commands, repeated inputs and actions that are not currently relevant.
The controller work spans I2C, SPI and UART peripheral connections, with each interface linked to its component or communication path.
Storage integration and SD-related logging are handled separately from playback commands and local user control.
Record 004 / Firmware and control
Configuration work for an embedded display interface using LVGL. Scope includes display setup and application interface organisation.
Configuration connects the graphics library with the display and input paths before application screens are developed.
Touch events need an application meaning, such as choosing a screen or changing a setting. Organising those responsibilities helps prevent display setup from becoming mixed with application logic.
The package spans LVGL graphics, SPI peripherals and HTTP or REST interfaces within the embedded application.
Record 007 / Firmware and control
Configurable stepper movement with control of motion timing and direction.
Timing controls the rate of commanded steps; direction controls their sense. Both are configurable motion settings.
The script controls the stepper driver, which provides the electrical interface to the motor.
A repeatable command needs a clear start, progression and end. These are useful review points for configurable motion, before considering mechanical loading and motor response.
Record 009 / Firmware and control
MIDI control input processing for a joystick and faders. Moving average and low pass filtering routines support signal conditioning.

applyMovingAverage() and applyLowPassFilter() condition input data using different forms of smoothing.
Smoothing and response must be considered together. A value that barely moves may look stable but feel slow, while an unfiltered input may send unwanted changes.
Conditioned input values are converted to MIDI events, with input processing kept separate from event generation.
Record 010 / Firmware and control
Control logic for a motorised FM radio sweep system, including button input and sweep speed adjustment.
handleButtons() processes local button input before it changes the sweep.
adjustSweepSpeed() handles the sweep-speed setting within the motor control firmware.
updateLCD() handles local display updates so the operator can see the setting being adjusted.
Record 012 / Firmware and control
An access control interface combining fingerprint input, keypad entry and local feedback.
Firmware flow
Selected keypad input and backspace branch.
A press is remembered. After release, a valid key is mapped and the timeout restarts. In the shown backspace branch, the final character is removed only when the input is not empty.
This is only part of the password-entry routine. It does not show password comparison, fingerprint verification or door control.
getPasswordFromKeypad excerpt · selected source lines 110–130. Source inspection is not a hardware test.
uint8_t currentKey = keypad.getKey();
lcd.setCursor(0, 0);
lcd.print("Enter Password:");
if (currentKey != I2C_KEYPAD_NOKEY) {
lastKey = currentKey;
wasPressed = true;
} else if (wasPressed) {
wasPressed = false;
if (lastKey < 16) {
char key = keymap[lastKey];
startTime = millis(); // 🔄 Reset timeout on key press
switch (key) {
case 'D': // Backspace
if (inputBuffer.length() > 0) {
inputBuffer.remove(inputBuffer.length() - 1);
Serial.println("Deleted last character");
}
break;Open the exact source-level diagramhandleKeypadInput() handles keypad entry; addFingerprint() handles fingerprint enrolment.
stepperMove() handles motion separately from input parsing.
The local display and serial interfaces provide feedback during device interaction.
Record 013 / Firmware and control
Stepper control using an encoder reference to relate commanded movement to position input.
The controller relates movement commands to position information from the encoder.
generateSteps() handles step generation separately from command and reference interpretation.
UART communication, stepper control and the motor driver form distinct interfaces in the movement-control path.
Record 019 / Firmware and control
Motor and servo operations scheduled using a real time clock.

A scheduled event answers when an action should begin. Motor control answers what happens during that action. Keeping those decisions separate makes the overall sequence easier to follow.
moveMotor() and stopMotor() define the start and end of a motor action.
The controller brings together servo control, motor drive, I2C and UART. Their integration supports scheduled operation without requiring the clock interface to contain the actuation logic.
Record 020 / Firmware and control
Firmware for enrolling fingerprints and checking subsequent reads against stored records.
Firmware flow
Fingerprint verification routine.
Wait for an image, convert it to a fingerprint template and search stored records. A conversion error stops the routine; the search reports either a matching ID and confidence or a no-match error.
The function waits for an image without a timeout in the supplied code. It reports search results, not an independently measured recognition rate.
verifyReload · selected source lines 260–280. Source inspection is not a hardware test.
void verifyReload() {
Serial.println(F("❓ Verify: place the same finger…"));
// 1) wait for finger
while (finger.getImage() != FINGERPRINT_OK) delay(50);
if (finger.image2Tz(1) != FINGERPRINT_OK) {
Serial.println(F("⚠️ image2Tz fail"));
return;
}
// 2) search the buffer 1 template against slot 1
uint8_t res = finger.fingerFastSearch();
if (res == FINGERPRINT_OK) {
Serial.print(F("✅ Match! ID="));
Serial.print(finger.fingerID);
Serial.print(F(" Confidence="));
Serial.println(finger.confidence);
} else {
Serial.print(F("❌ No match (err 0x"));
Serial.print(res, HEX);
Serial.println(F(")"));
}
}Open the exact source-level diagramsensorSerialBegin() provides a communication setup step separate from fingerprint enrolment and verification. This keeps transport handling identifiable.
enrollFingerprint() handles registration separately from later fingerprint checks.
downloadModelToString() and reloadFingerprint() handle model representation and reloading separately from matching a presented fingerprint.
Record 021 / Firmware and control
An embedded interface coordinating text input with tactile and spoken output.
sayLetter(), sayKnownWord() and speakLine() distinguish character, word and line operations. The separate routines make each level of speech output explicit in the implementation.
pushToShiftRegs() sends tactile output through shift registers, separately from text interpretation.
BLE, SPI and USB interface work supports the coordination of text processing with spoken and tactile output.
Record 024 / Firmware and control
Motion triggered wearable firmware with lighting control and sleep or wake routines. The source includes vibration wake handling.
applyColor() and ledsOff() define the active lighting effect and the inactive output.
enableVibrationPCINT() and enterPowerDownUntilVibration() define the vibration-based wake path and the event that resumes operation.
Going idle and returning to active operation are connected decisions. The firmware work addresses that transition, while actual battery life still depends on the complete hardware and its measured consumption.
Record 026 / Firmware and control
A motor controller combining BLE commands with encoder based input or feedback.
BLE commands and encoder events provide distinct inputs to the motor application.
An encoder interrupt routine captures events alongside communication and motor control.
The firmware integrates the wireless command path, encoder events and motor output handling.
Record 027 / Firmware and control
Control logic for sequencing relay outputs according to defined operating states.
Operating states define where each relay output belongs in the switching sequence.
The firmware scope combines relay or solenoid control, I2C interfaces and embedded C/C++.
The sequence identifies the active state, its associated output and the condition for the next transition.
Record 028 / Firmware and control
An ESP32 control application combining audio playback and motor outputs.

A dedicated routine sends MP3 playback commands.
Motor actions and audio playback are part of the same control application.
Serial playback and motor control retain separate output handling within the application.
Record 045 / Firmware and control
Control work coordinating smoke, motor and LED outputs in a themed prop.

The application coordinates motor control, addressable lighting and a smoke relay.
Routines handle button presses, active-high output configuration, smoke-relay writes and LED indexing.
LED updates and relay commands have separate handling within the prop’s output sequence.
Record 046 / Firmware and control
Motion input used to trigger coordinated lighting and sound output.
A tilt-trigger routine converts movement into an event for the effect logic.
Routines show blue, turn outputs off and fade a white element. These lighting actions can form part of the prop's response to movement.
Motion input coordinates lighting and sound within the same application.
Record 056 / Firmware and control
USB descriptor configuration and callback handling for a LUFA based device.
USB descriptors identify the device and its interfaces to the host.
CALLBACK_USB_GetDescriptor() handles host descriptor requests in the LUFA firmware.
The package defines descriptor data and request handling for the intended USB interface.
Record 057 / Firmware and control
An ESP32 application implementing a Bluetooth keyboard control interface.
Firmware flow
Selected horizontal-axis Bluetooth keyboard handling.
When Bluetooth is connected, read the joystick and ignore small horizontal movement. A larger movement sends the matching arrow key, waits 150 ms and releases the keys.
The snippet reads both axes but only shows horizontal key handling. It does not establish behaviour after disconnection or the complete keyboard mapping.
loop excerpt · selected source lines 40–58. Source inspection is not a hardware test.
void loop() {
// Ensure BLE keyboard is connected
if (bleKeyboard.isConnected()) {
// Read joystick values
int joystickX = analogRead(JOYSTICK_X) - 2048; // Adjust for ESP32 ADC range
int joystickY = analogRead(JOYSTICK_Y) - 2048;
// Handle joystick movements
if (abs(joystickX) > DEADZONE) {
if (joystickX > 0) {
bleKeyboard.press(KEY_RIGHT_ARROW); // Joystick moved RIGHT
Serial.println("Joystick RIGHT");
} else {
bleKeyboard.press(KEY_LEFT_ARROW); // Joystick moved LEFT
Serial.println("Joystick LEFT");
}
delay(150);
bleKeyboard.releaseAll(); // Release after press
}Open the exact source-level diagramThe firmware translates local control actions into keyboard input for the host.
BLE carries keyboard input between the ESP32 and its host.
The module provides an embedded keyboard interface for custom controls used with applications that accept keyboard input.
Record 058 / Firmware and control
Control logic combining IMU input with motor and servo outputs.
The control scope relates IMU motion or orientation readings to actuator commands.
Motor drive and servo control have separate output handling within the application.
The control decision translates sensed motion or orientation into a movement command. Keeping this step distinct clarifies the relationship between the sensor and each actuator during development.
Record 060 / Firmware and control
One remote button selects lighting actions by press duration. An ESP-NOW receiver keeps the colour and effect state locally.

Firmware flow
Selected mode-to-hue helper.
Use the requested hue entry for mode numbers zero through four. For any other value, return the first entry.
This helper selects a value only. It does not prove the complete receiver works, identify the actual hue constants or provide a link-loss failsafe.
getColorForMode · selected source lines 196–205. Source inspection is not a hardware test.
uint32_t getColorForMode(int mode) {
uint32_t startingHues[] = { hueb, huer, huey, hueg, huev };
if (mode >= 0 && mode < sizeof(startingHues) / sizeof(startingHues[0])) {
return startingHues[mode];
} else {
// Default to Reddish for unknown modes
return startingHues[0];
}
}Open the exact source-level diagramFirmware flow
Selected ESP-NOW transmitter release-duration branches.
On a LOW-to-HIGH release, select a command from the duration bands and send it over ESP-NOW. A release in the 2500–2999 ms gap sends no command. Afterwards clear the payload locally and remember the input state.
A release lasting 2500–2999 ms matches no command. The zero reset is local and is not transmitted. No receiver failsafe, delivery acknowledgement or hardware retest is established.
loop() selected body · selected source lines 67–94. Source inspection is not a hardware test.
if ((newState == HIGH) && (oldState == LOW) && (millis() - lowSignalStartTime < 500)) {
myData.a = 1;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}else if ((newState == HIGH) && (oldState == LOW) && (millis() - lowSignalStartTime >= 500) && (millis() - lowSignalStartTime < 1000)) {
myData.a = 2;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}else if ((newState == HIGH) && (oldState == LOW) && (millis() - lowSignalStartTime >= 1000) && (millis() - lowSignalStartTime < 1500)) {
myData.a = 3;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}else if ((newState == HIGH) && (oldState == LOW) && (millis() - lowSignalStartTime >= 1500) && (millis() - lowSignalStartTime < 2000)) {
myData.a = 4;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}else if ((newState == HIGH) && (oldState == LOW) && (millis() - lowSignalStartTime >= 2000) && (millis() - lowSignalStartTime < 2500)) {
myData.a = 5;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}else if ((newState == HIGH) && (oldState == LOW) && (millis() - lowSignalStartTime >= 3000)) {
myData.a = 6;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}
myData.a=0;
oldState = newState;
}Open the exact source-level diagramFirmware flow
Selected ESP-01S / ESP8266 receiver command dispatch.
Choose the first matching local or remote command. It may initialise the LEDs and change colour, call the strobe routine, change the effect flags or lower the output pin. Clear the remote selector after the branch.
The receiver snapshot is incomplete for standalone compilation. Local release conditions can take precedence over remote selectors because this is a first-match chain. No link-loss failsafe or tested output behaviour is established.
loop() selected body · selected source lines 95–131. Source inspection is not a hardware test.
if ((newState == HIGH) && (oldState == LOW) && (millis() - lowSignalStartTime < 500) || sel == 1) { // FIXME: color change delay
if (!ledInitialized) {
for(int i=0; i<=NUM_LEDS; i++){
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(huewa, 255, 255))); // Set initial color
strip.begin();
strip.show();}
digitalWrite(1, HIGH);
ledInitialized = true; // Set the flag to true
}
modeChange(); // Color Transition
} else if ((newState == HIGH) && (oldState == LOW) && (millis() - lowSignalStartTime >= 650) || sel == 2) { // FIXME: strobe effect trigger delay
beameffect(); // Trigger Strobe Effect
} else if (sel == 3) {
flash = true; // layermode
glittereffect = false; // glitter mode
} else if (sel == 4) {
glittereffect = true;
flash = false;
} else if (sel == 5) {
glittereffect = false; //all off
flash = false;
} else if (sel == 6) {
digitalWrite(1, LOW);
}
// Set the last-read button state to the old state.
sel = 0;
oldState = newState;Open the exact source-level diagramThe sender measures a button hold and sends one command when the button returns HIGH. The receiver keeps the effect state locally, so a packet selects an action rather than carrying every LED update.
The sender assigns commands 1–5 to successive ranges below 2500 ms, then command 6 at 3000 ms or more. The inspected version has no send branch for 2500–2999 ms. After the branch chain it clears the local payload, without transmitting a reset packet.
The first-match chain combines local button conditions with remote selectors. It can initialize the strip and raise GPIO1, advance the hue mode, call the strobe routine, switch flash/glitter flags, or lower GPIO1. Command 5 clears two effect flags; it is not an all-output shutdown. Command 6 lowers GPIO1 without clearing the LED initialization flag.
The transmitter includes ESP8266WiFi.h and both files use the ESP8266-era ESP-NOW API, correcting the old ESP32 label. The receiver snapshot omits declarations needed to compile it alone. No link-loss timeout or fail-safe is established by these files, and no hardware retest is claimed.
Record 063 / Firmware and control
Motor movement arranged as an explicit sequence of timed steps.
Firmware flow
Selected motor step-pulse loop.
For each requested step, raise the step pin, wait for the pulse interval, lower it and wait for the configured low interval. Repeat until the requested count is reached.
There is no acceleration profile, position feedback or measured timing guarantee in this excerpt. The high-pulse delay and low-period delay are separate, so the total cycle includes both.
stepMove pulse-loop excerpt · selected source lines 36–42. Source inspection is not a hardware test.
for (long i = 0; i < steps; i++) {
digitalWrite(STEP_PIN, HIGH);
delayMicroseconds(STEP_PULSE_US);
digitalWrite(STEP_PIN, LOW);
// Keep overall step rate controlled:
delayMicroseconds(STEP_PERIOD_US);
}Open the exact source-level diagramRecord 066 / Firmware and control
Relay and motor control firmware with current measurement input.
Relay and motor commands describe what the controller asks the hardware to do. Current information describes another aspect of the system, helping distinguish an output request from the load's electrical state.
updateButtons() handles local input alongside switched outputs and current measurement.
The firmware integrates operator input, motor control, relay operation and current measurement.
Record 068 / Firmware and control
A stepper platform control application using IMU feedback.
Firmware flow
Complete selected stabilisation routine.
Read the current angle, subtract it from the target, scale the error using the step settings and pass that value to the stepper speed function.
The computed value is passed to a speed setter, not to a position-move command. The excerpt does not establish closed-loop stability, tuning or a tested accuracy.
stabilizeMotor · selected source lines 149–155. Source inspection is not a hardware test.
void stabilizeMotor() {
float currentAngle = getMPUAngle();
float angleError = mpuTargetAngle - currentAngle;
float stepsToMove = angleError * (stepsPerRevolution * microstepSetting / 360.0); // Map angle to steps
stepper.setSpeed(stepsToMove);
stepper.runSpeed();
}Open the exact source-level diagrammoveLeft() and moveRight() provide explicit direction-control operations.
toggleSweep() and sweepMotor() distinguish selecting a sweep mode from executing it. That separation gives a movement pattern its own ongoing state.
The development work connects IMU orientation feedback with the stepper platform’s movement commands.
Record 069 / Firmware and control
ESP32 firmware for motor commands and power stage control.
The power stage reference distinguishes motor phase and supply connections from its low voltage control connections. That separation explains where the ESP32's firmware responsibilities meet the power hardware.
The driver reference identifies speed, direction, brake and stop connections.
ESP32 firmware handles motor and power-stage commands through the connections defined by the driver reference.
Record 074 / Firmware and control
Firmware for running a defined sequence across multiple servo outputs.
runServoSequence() provides the entry point for the coordinated servo movement.
A multi-servo sequence depends on the timing of each action relative to the others. A defined sequence records those relationships in the program.
UART communication is integrated with the control application, separately from the servo sequence routine.
Record 075 / Firmware and control
An embedded control module covering device states and hardware interfacing.
Embedded C++ state-based control relates the current device state to its hardware-facing actions.
The module covers input handling, control decisions and hardware outputs.
The central task is translating the device's intended operation into explicit firmware responsibilities at the hardware interface.
Record 076 / Firmware and control
Alarm logic with keypad entry, PIN checking and multiple monitored zones.
Keypad entry and monitored zones provide different inputs to the alarm logic, with PIN verification handled separately.
checkPincode() and comparePincode() handle credential checks separately from zone monitoring.
A local display shows feedback on entered commands and the alarm’s current condition.
Record 078 / Firmware and control
A multi channel servo interface built around the PCA9685 driver.

The PCA9685 forms the centre of the servo interface. A shared control connection lets the firmware address multiple outputs through a dedicated driver rather than treating each servo as a separate software interface.
The wiring illustration identifies the servo's signal, supply and ground connections beside an ESP32 pinout. This connects the software-facing interface to the wiring required at the actuator.
Servo command handling and actuator power are related but separate concerns. Wiring documentation makes that distinction clear before assessing movement on the bench.
Record 081 / Firmware and control
Relay output control through a BLE interface.
BLE commands provide the input to the relay-control module.
Firmware links received commands to relay output handling; the control scope also includes an interrupt routine.
Relay control converts the requested software state into a physical switching action.
Record 084 / Firmware and control
An ESP32 BLE interface translating physical input into game controller actions, with timed button press and release handling.
Firmware flow
Two separate press and release helpers.
When the press helper is called
When the release helper is called
The press helper sends one button press and records its start time when the button is not already held. A separately called release helper releases it once the configured hold time has elapsed.
The caller decides when each helper runs. This overview does not imply a blocking wait or prove the complete input mapping.
press/release functions · selected source lines 94–107. Source inspection is not a hardware test.
void tapButtonIfNeeded(int btn, bool &pressedFlag, uint32_t &startedFlag) {
if (!pressedFlag) {
bleGamepad.press(btn);
pressedFlag = true;
startedFlag = millis();
}
}
void releaseIfElapsed(int btn, bool &pressedFlag, uint32_t &startedFlag) {
if (pressedFlag && (millis() - startedFlag >= (uint32_t)PRESS_MS)) {
bleGamepad.release(btn);
pressedFlag = false;
}
}Open the exact source-level diagramsetupEncoder() handles physical input for translation into game-controller actions.
tapButtonIfNeeded() handles button activation, with timing separate from the duration of the physical input.
releaseIfElapsed() handles timed release to complete a button tap over the BLE interface.
Record 089 / Firmware and control
A collection of embedded control work covering an accident alert interface, greenhouse functions and BLDC control.
The alert work includes button handling, output control, buzzer pulses and LED indication. Named routines such as debouncedPressed() and setAlertOutputs() identify those parts of the interaction.
Environmental control forms another part of the collection. Its engineering emphasis is the relationship between conditions being monitored and the control actions associated with them.
Motor control introduces a different output responsibility. Bringing it into the collection shows the range from discrete alert feedback to firmware concerned with controlling a motor interface.
Record 096 / Firmware and control
ATtiny84A firmware calibrates a replacement joystick for an N64 stick converter. The centre position and eight directional references define the usable travel and its mapping to the console’s expected output.
Project detailsConceptual workflow
The reported failure appeared after calibration: stick movement could produce zero output on both axes. The work focused on how calibration readings became usable coordinates, including the relationship between the neutral position and the outer reference points.
The firmware was revised and tested using captured output and practical stick movements. Logic analyser checks helped relate what the converter transmitted to the direction and position being applied. The corrected firmware was delivered with the project files.
Follow-up testing raised a different issue: the client reported that the console reset button affected calibration even though a full power cycle did not. The ongoing work checks calibration storage and startup behaviour across those two events.
Record 017 / Connected systems
A low level NFC interface with byte exchange and diagnostic output routines for tag communication.
sendFrame() and readFrame() handle outgoing requests and incoming data.
readByteWait() handles byte reception separately from interpretation of a complete tag response.
dumpHex() exposes the exchanged data in hexadecimal form for protocol inspection.
Record 023 / Connected systems
An NFC terminal linked to a web workflow. Project material covers tag operations and device or browser status handling.
Firmware flow
Four-byte NFC page-writing routine.
Split the payload into four-byte pages, stopping if a payload-page write fails. Pause between pages. Once all payload bytes are written, write a zero-filled page and return success without checking that final write.
Payload-page failures are checked, but the final zero-filled page write is not checked before success is returned. This does not verify the browser workflow or a successful physical tag write.
writePagesPaced · selected source lines 69–82. Source inspection is not a hardware test.
bool writePagesPaced(const uint8_t* data, size_t len, uint8_t startPage=4) {
uint8_t pageBuf[4]; size_t idx=0; uint8_t page=startPage;
while(idx<len){
memset(pageBuf,0x00,4);
for(uint8_t k=0;k<4 && idx<len;k++) pageBuf[k]=data[idx++];
if(!nfc.mifareultralight_WritePage(page,pageBuf)) return false;
delay(12); // more conservative commit time
page++;
}
memset(pageBuf,0x00,4);
nfc.mifareultralight_WritePage(page,pageBuf);
delay(12);
return true;
}Open the exact source-level diagramThe NFC or PN532-related interface handles physical tag operations at the terminal.
Device and browser status handling connects local tag operations with the information shown in the web interface.
The terminal provides the physical tag interaction; the web workflow supplies its application context.
Record 025 / Connected systems
Provide a local browser interface to release a toy car and measure its lap time.
The controller creates its own Wi Fi access point. The browser portal therefore works without an external router, keeping the control interface close to the track and reducing setup dependencies.
A portal command releases the servo gate. Lap timing and laser detection connect that physical action to a recorded result, bringing movement, sensing and browser interaction into one prototype.
The useful distinction is between the user command and the sensor event. The sensor supplies the finish event rather than relying on a person to stop the timer, connecting a physical crossing to the lap result.
Record 032 / Connected systems
Read field instrument values over a wired industrial interface and make them available through a connected logger.

Firmware flow
Selected Modbus flow-rate and accumulator readers.
Each reader requests its registers, returns an unavailable value on communication failure, and otherwise decodes the words into either instantaneous flow or an accumulated reading.
The two readers are separate functions, not a guaranteed call sequence. Register layout and hardware multiplier settings are assumed by the code; no instrument validation is shown.
regToFloat / readFlowRate / readPositiveAccum · selected source lines 31–52. Source inspection is not a hardware test.
float regToFloat(uint16_t hi, uint16_t lo) {
union { uint32_t U; float F; } u;
u.U = ((uint32_t)hi << 16) | lo;
return u.F;
}
// Read instantaneous flow (m³/h), then convert to L/s
float readFlowRate() {
if (node.readHoldingRegisters(0x0000, 2) != node.ku8MBSuccess) return NAN;
return regToFloat(node.getResponseBuffer(0), node.getResponseBuffer(1)) * 0.2778;
}
// Read positive accumulator (LONG + fraction)
float readPositiveAccum() {
// INTEGER part at reg 0009 -> offset 8, fraction at 0011 -> offset 10
if (node.readHoldingRegisters(0x0008, 4) != node.ku8MBSuccess) return NAN;
// lower two regs = integer, upper two = fraction
int32_t N = (int32_t)node.getResponseBuffer(0) << 16
| node.getResponseBuffer(1);
float Nf = regToFloat(node.getResponseBuffer(2), node.getResponseBuffer(3));
// multiplier n is handled in hardware (M33/M31), so assume direct (no extra 10ⁿ)
return N + Nf;
}Open the exact source-level diagramSeparate routines read flow rate and positive accumulation. Register conversion translates the raw device response into application values.
Wi Fi, WebSocket updates and a broadcast routine connect the instrument-facing code to the viewing interface.
Flow rate describes current activity; accumulated values describe a total. Both pass through the logger with their meanings kept distinct.
Record 034 / Connected systems
An interface between an ESP32 and a Teensy for exchanging LED control information.
The two controllers exchange LED control information through a defined communication interface.
I2C communication and a request-event routine handle information requests between the controllers.
The bridge handles controller-to-controller communication separately from the lighting effects that use its commands.
Record 035 / Connected systems
A DHT11 sensor supplies temperature and humidity readings to a Bluetooth serial link. The firmware checks the measurements before formatting them for an HC-05 receiver.
Project details
Firmware flow
Complete temperature and humidity transmission routine.
Read temperature and humidity. If either reading is invalid, send a sensor-read error and stop. Otherwise format the values and send them through the HC-05 serial interface.
This establishes the packet-building logic, not wireless range, delivery confirmation or sensor accuracy.
sendDHT11Data · selected source lines 187–206. Source inspection is not a hardware test.
void sendDHT11Data() {
float humidity = dht.readHumidity();
float temperatureC = dht.readTemperature();
if (isnan(humidity) || isnan(temperatureC)) {
Serial.println("DHT11 read failed.");
hc05.println("ERROR,DHT11_READ_FAILED");
return;
}
String dataPacket = "";
dataPacket += "TEMP_C=";
dataPacket += temperatureC;
dataPacket += ",HUMIDITY=";
dataPacket += humidity;
Serial.println(dataPacket);
hc05.println(dataPacket);
}Open the exact source-level diagramHC05 configuration and AT command routines set up the communication module.
A DHT11 reporting routine connects sensor acquisition with transmission through the Bluetooth interface.
Configuration commands and sensor readings have separate roles on the serial path.
Record 039 / Connected systems
I2C communication work connecting ESP32 and FRDM development platforms.
The two platforms exchange information over a shared bus, with platform-specific firmware on each side.
An I2C slave callback handles incoming bus events within the interface module.
The work is a communication module, not a complete product. It connects bus activity with the firmware that handles it.
Record 040 / Connected systems
A pool monitoring interface with device data retrieval and web diagnostics. The documented routines include response parsing and sampling sequence checks.
Data-request and response-reading routines parse information from the monitored device.
Cuvette-fill checks and a pause after refilling relate sampling readiness to measurement handling.
Web diagnostics expose the communication and sampling process for inspection during development.
Record 044 / Connected systems
An ESP32 camera workflow for moving image data into a calculator related interface.

Capturing an image is only one part of an interface task. The receiving environment also needs usable data and a defined way to start an operation and recognise whether it succeeded.
Command initiation, string handling and success or error states support the ESP32 image-transfer workflow over Wi Fi and HTTP.
Success and error states distinguish a completed transfer from an operation needing attention.
Record 047 / Connected systems
Firmware and a browser interface for a radio-based race-tracking system. The work covers position and status packets, a LoRa-to-web gateway, map updates and GPX route logging.
Project details
Documented system flow
Firmware flow
Complete GNSS sample-building routine.
Check that position and satellite data are valid with at least one satellite. Keep the coordinates when a fix is available; otherwise mark no fix and use zero placeholders. Add independently valid auxiliary readings, then update the latest fix, quality and satellite status.
The check is for reported field validity, not sample freshness or an accuracy threshold. Zero coordinates are placeholders when there is no fix. LoRa transmission, browser maps and GPX logging are outside this excerpt.
buildGpsSample · selected source lines 1040–1053. Source inspection is not a hardware test.
void buildGpsSample(GpsSample &out) {
out.fix = gps.location.isValid() && gps.satellites.isValid() && gps.satellites.value() > 0;
out.lat = out.fix ? gps.location.lat() : 0.0;
out.lon = out.fix ? gps.location.lng() : 0.0;
out.alt_m = gps.altitude.isValid() ? gps.altitude.meters() : 0.0;
out.spd_mph = gps.speed.isValid() ? gps.speed.mph() : 0.0;
out.heading_deg = gps.course.isValid() ? gps.course.deg() : 0.0;
out.hdop = gps.hdop.isValid() ? gps.hdop.hdop() : 0.0;
out.sats = gps.satellites.isValid() ? gps.satellites.value(): 0;
lastGpsFix = out.fix;
lastHdop = out.hdop;
lastSats = out.sats;
}Open the exact source-level diagramThe telemetry format carries position and status in compact packets. This gives the radio link a defined data representation rather than coupling the map directly to the GNSS device.
Gateway software bridges the radio side to WebSocket updates. That boundary connects the embedded communication path to browser software while keeping the radio packet and user interface responsibilities distinct.
Browser map development turns position information into a spatial view, while GPX logging provides a route record. Together they connect the incoming telemetry with two useful ways of examining a race tracking system.
Record 048 / Connected systems
An ESP32 and CAN interface for a controller split across two boards, including output setup and PWM handling.
CAN links the distributed control functions across two boards; local firmware handles each board’s outputs.
Routines assign PWM to pins, write PWM values, find the channel associated with a pin and set up outputs. These give the firmware a defined mapping between application outputs and hardware resources.
A command crossing the board boundary is different from a local PWM update. Keeping these responsibilities explicit helps the controller relate distributed communication to the output work performed on each board.
Record 051 / Connected systems
Pump and reagent control linked to a cloud interface, with output state handling and publication or retry logic.

A pump routine controls the output, while allOutputsOff() returns the outputs to an inactive state.
safePublish() and tryOrQueue() handle cloud publication and information waiting to be sent.
The scope covers both physical output state and the progress of network publication.

Record 052 / Connected systems
A telemetry node combining motion sensor information with MQTT and cellular communication.
setupMPU() initialises the IMU before its motion readings are used by the application.
Wi Fi station setup and routines such as sendHeader() and waitFor() handle connection preparation.
MQTT supplies remote reporting for the motion-sensor application.
Record 055 / Connected systems
A lighting interface using Art Net and UDP communication.
Firmware flow
Selected Art-Net frame handling code.
Check packet tracking, place the RGB values into the LED buffer and update the remembered packet length. Display the frame and reset tracking only when the frame-ready flag is set.
The excerpt begins after earlier callback setup. It does not show how the frame-ready flag is initially set or how missing packets are recovered.
onDmxFrame excerpt · selected source lines 72–94. Source inspection is not a hardware test.
// Check that all universes have been received
for (int i = 0; i < maxUniverses; i++) {
if (!universesReceived[i]) {
Serial.println("Something is broken...");
sendFrame = false;
break;
}
}
// Map the DMX data to the appropriate LED(s) on the strip.
for (int i = 0; i < length / 3; i++) {
int led = i + (universe - startUniverse) * (previousDataLength / 3);
if (led < numLeds)
leds.setPixelColor(led, data[i * 3], data[i * 3 + 1], data[i * 3 + 2]);
}
previousDataLength = length;
// Once all universes have been received, update the LED strip and reset the tracking array.
if (sendFrame) {
leds.show();
memset(universesReceived, 0, sizeof(universesReceived));
}
}Open the exact source-level diagramArt Net carries lighting data over UDP into the embedded application.
Network reception and local lighting output are separate parts of the interface.
The module connects incoming lighting-protocol data with the firmware that controls the output.
Record 061 / Connected systems
An ESP32 prototype exposing device information through an embedded web interface.
The embedded web interface exposes local device information for inspection.
The project covers the relationship between local device operation and its web representation. This defines which information the browser can show and how it relates to the device.
The prototype presents controller state through a browser-facing interface.
Record 071 / Connected systems
Firmware carrying serial data over a Wi Fi connection.
UART-to-Wi-Fi transport connects the serial interface with the wireless data path.
transmissionComplete() handles transfer completion within the firmware.
The module carries the surrounding device’s serial data over a wireless connection.
Record 072 / Connected systems
A motion interface linking hardware control functions to UDP communication, with PWM channel configuration and output updates.

Firmware flow
PWM timer and channel setup routine.
Allocate a timer for the requested frequency, configure the selected channel with zero initial duty, then keep the timer-to-channel mapping. Return failure if no timer is available or configuration fails.
This is setup code for one output channel. It does not show UDP transport, real-time timing performance or motor behaviour.
configure_pwm_channel excerpt · selected source lines 47–70. Source inspection is not a hardware test.
bool configure_pwm_channel(int ch, int gpio, int freq) {
ledc_timer_t timer = get_or_allocate_ledc_timer(freq);
if (timer == (ledc_timer_t)-1)
return false; // hiba: nincs szabad timer
ledc_channel_config_t chan_cfg = {
.gpio_num = gpio,
.speed_mode = LEDC_HIGH_SPEED_MODE,
.channel = (ledc_channel_t)ch,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = timer,
.duty = 0,
.hpoint = 0,
.sleep_mode = LEDC_SLEEP_MODE_NO_ALIVE_NO_PD,
.flags = {
.output_invert = 0
}
};
if (ledc_channel_config(&chan_cfg) != ESP_OK)
return false;
pwm_timer_map[ch] = timer;
return true;
}Open the exact source-level diagramThe reference drawings distinguish a LinuxCNC speed setpoint from the resulting motor speed, and show the relationship between step pulses and direction setup. These are different parts of the motion problem.
The firmware names configure_pwm_channel(), set_pwm_duty() and io_init(). This separates output preparation from later changes to the output value, making the hardware interface easier to follow.
UDP provides the communication side of the interface. The engineering work concerns how motion information reaches the hardware layer, without treating network message arrival as identical to a correctly timed motor signal.

Record 077 / Connected systems
An ESP32 camera interface providing image data through a web server.
The system uses an ESP32 camera interface with an embedded web server. Wi-Fi provides the network connection between the camera device and the browser-facing service.
Image annotation routines include rgb_print(), rgb_printf() and draw_face_boxes(). They place image annotation alongside the camera serving portion of the firmware.
Image handling and network service share the same embedded device. That makes buffer use and the division of processing responsibilities relevant when developing a camera interface on this platform.
Record 079 / Connected systems
A diagnostic interface for reading and sending frames across three CAN channels.
The interface is organised around three CAN channels. Channel identity matters because the same frame identifier can have a different meaning on a different connected bus.
Named routines include sendMessage(), readBus() and readMsgFromBuffer(). Together they describe the core operations involved in moving frames between the diagnostic application and its bus interfaces.
Receive and transmit functions distinguish observing CAN traffic from sending a frame onto the bus.
Record 083 / Connected systems
A gateway linking local data with MQTT over cellular or Wi Fi communication. Documented routines include connection management and state of charge publication.
Firmware flow
Complete state-of-charge publication selector.
Use Wi-Fi when it is enabled and connected. If that publication succeeds, stop; otherwise call the cellular publication routine.
The excerpt attempts cellular publication after unavailable or unsuccessful Wi-Fi. It does not show cellular success checking, retries or guaranteed delivery.
publication fallback excerpt · selected source lines 297–307. Source inspection is not a hardware test.
void sendSOC(int soc) {
bool sent=false;
if (wifiEnabled && wifiConnected) {
sent = publishSOC_WLAN(soc);
if (sent) return;
Serial.println("⚠️ WLAN failed → LTE fallback");
}
mqttPublishSOC_LTE(soc);
}Open the exact source-level diagramreadSOC() identifies state of charge as a data input for the gateway’s reporting task.
wifiConnectOnce() and wifiMqttEnsureConnected() separate the Wi-Fi connection from the MQTT connection. These are distinct stages between having local data and making it available to a remote subscriber.
wifiPublishSOC() names the publication step explicitly. The overall gateway scope considers cellular and Wi-Fi connectivity, while the Wi-Fi routines show the progression from network access to application-level reporting.
Record 086 / Connected systems
An ESP32 environmental logger combines local OLED feedback with cloud reporting. Configuration routines cover Wi Fi details and a spreadsheet logging endpoint.
Firmware flow
Selected sensor acquisition and state checks.
Read the motion input, update readings from sensors marked ready, and combine no-motion with valid numeric light or temperature values to set the two threshold flags.
The flags describe possible conditions, not measured energy savings. The excerpt does not clear old values when a sensor is unavailable or test reading freshness; cloud reporting is outside it.
sensor acquisition / state flags excerpt · selected source lines 413–430. Source inspection is not a hardware test.
int pirRaw = digitalRead(PIR_PIN);
bool motionDetected = (pirRaw == LOW);
bool noMotion = !motionDetected;
if (bmeOK) {
temperatureC = bme.readTemperature();
humidity = bme.readHumidity();
pressureHpa = bme.readPressure() / 100.0F;
}
if (tslOK) {
sensors_event_t event;
tsl.getEvent(&event);
lux = event.light;
}
bool emptyRoomLightOn = noMotion && !isnan(lux) && lux > LIGHT_ON_THRESHOLD_LUX;
bool possibleHeatingWaste = noMotion && !isnan(temperatureC) && temperatureC > HIGH_TEMP_THRESHOLD_C;Open the exact source-level diagramshowOLEDMessage() provides local display feedback alongside acquisition and remote logging.
wifiDetailsAdded() and sheetsUrlAdded() identify two setup responsibilities: connecting the logger to a network and assigning its spreadsheet endpoint. This makes the destination part of the device configuration.
The project includes a spreadsheet view with environmental columns and timestamped rows. This complements the local display: one presents device feedback, while the other organises reported data for later inspection.
Record 094 / Connected systems
A CAN controlled node for LED and other output commands.
CAN commands are interpreted by the node’s output-control firmware.
LED control is one of the output functions. The module also covers other output commands, linking the communication interface with local hardware control.
The module connects distributed CAN commands with the device’s local outputs.
Record 095 / Connected systems
Addressable LED control from CAN frames, with message transmission and received frame processing.
processCanData() identifies the received-frame portion of the implementation. This is the point where communication data meets the application logic that controls the LEDs.
WS2812 LEDs form the output side of the controller. CAN data and pixel colour data belong to different interfaces, with the application responsible for the relationship between them.
SendCanMessage() covers the transmitting side of the firmware. The module therefore includes CAN message handling in both directions alongside the addressable-light output path.
Record 097 / Connected systems
The machine-control path moves browser commands over MQTT to an ESP32, while the existing Firebase services continue to handle accounts, balances, payments and session records.
Project details
System flow
The migration retained Firebase for account and game records. Browser commands travel over MQTT and WebSocket through EMQX to the ESP32, which controls the machine's relay outputs. This let the control path change without rebuilding the surrounding application.
The command handling covers direction, grab and stop. It distinguishes a short press from a held control, stops movement on release, and includes protection against stale or duplicate commands. A watchdog and failsafe behaviour address interrupted control sessions.
Client testing confirmed responsive machine control. Camera integration is being refined alongside the working control path.
Record 001 / Lighting and interaction
LED game logic for player selection, matrix addressing and win detection. The project includes input debouncing and cell selection routines.

The debounce() routine addresses the first interaction problem: a mechanical press can create several electrical transitions. Input conditioning belongs before game logic, where duplicate events could otherwise become duplicate moves.
traverseMatrix() and selectLED() separate matrix navigation from LED cell selection.
checkWin() evaluates the game board separately from pixel updates.
Record 016 / Lighting and interaction
Firmware for addressable LED strip output and lighting sequences.
setStripColor() applies a colour to the strip separately from the lower-level pixel transmission.
clearStrip() provides a distinct operation for removing the current output.
WS2812 output has its own signalling requirements. The firmware scope considers responsive lighting and command timing, so lighting sequences and input handling need to be considered together.
Record 030 / Lighting and interaction
An ESP32 display application for animated photo booth feedback.
Firmware flow
Selected monochrome frame rendering code.
Read the stored monochrome pixels, expand them to the selected scale, centre the result and send the completed buffer to the display.
This excerpt shows decoding, scaling and display transfer. It does not show frame timing, buffer allocation or the complete photo-booth interaction.
drawFramephoto1 excerpt · selected source lines 185–205. Source inspection is not a hardware test.
for (uint16_t y = 0; y < FRAME_HEIGHT; y++) {
for (uint16_t x = 0; x < FRAME_WIDTH; x++) {
uint16_t byteIndex = y * FRAME_BYTE_WIDTH + (x / 8);
uint8_t bitIndex = 7 - (x % 8);
uint8_t b = pgm_read_byte(&photo1[frameIndex][byteIndex]);
bool pixelOn = (b >> bitIndex) & 0x01;
uint16_t color = pixelOn ? 0xFFFF : 0x0000;
for (uint16_t j = 0; j < SCALE_FACTOR; j++) {
for (uint16_t i = 0; i < SCALE_FACTOR; i++) {
uint16_t px = x * SCALE_FACTOR + i;
uint16_t py = y * SCALE_FACTOR + j;
spriteBuffer[py * spriteWidth + px] = color;
}
}
}
}
uint16_t posX = (TFT_WIDTH - spriteWidth) / 2;
uint16_t posY = (TFT_HEIGHT - spriteHeight) / 2;
lcd_PushColors(posX, posY, spriteWidth, spriteHeight, spriteBuffer);
free(spriteBuffer);Open the exact source-level diagramThe application uses animation for photo-booth feedback.
The application combines ESP32, Wi Fi and HTTP interfaces with display control, including text checks and grid data handling.
The development scope connects display logic with the photo booth’s user feedback.
Record 031 / Lighting and interaction
A PCB layout concept for a lighting controller, shown in a Fusion 360 routing view. The work concerns board connections, copper routing and the physical arrangement of the design.
The layout shows board connections and copper routing for the lighting controller.
The Fusion 360 routing view shows the proposed lighting-controller layout.
Record 033 / Lighting and interaction
A game controller combining keypad input, visual feedback and relay outputs.
Input routines wait for a key and interpret individual choices according to the game state.
Menu handling coordinates keypad choices with display feedback and relay actions.
Relay outputs give the game a physical response alongside its visual feedback.
Record 037 / Lighting and interaction
A visualisation prototype for addressable-lighting effects.
The visualiser shows how an effect occupies the lighting arrangement.
The visual prototype illustrates addressable-lighting effects.
Record 038 / Lighting and interaction
A memory game using input sequences and LED feedback, with game state and pattern handling.

Pattern generation and membership checks represent the game sequence independently of the current LED output.
Separate routines display the LED pattern and read the player’s response.
Game logic coordinates the stored pattern, LED presentation and player input.
Record 053 / Lighting and interaction
A simulation and control sketch for NeoPixel lighting sequences.

The simulation places the LED elements beside the control sketch, making it possible to relate the program to the colours and positions shown in the circuit view.
The circuit view shows power and signal wiring alongside the LED elements and their logical arrangement.
The simulation gives an early view of the lighting sequence and intended wiring. It supports review of the connections before the circuit moves to physical hardware.
Record 054 / Lighting and interaction
AbuLou SmartLED implements colour fades, stored scripts and motor patterns on an ATtiny85, controlled through a compact I2C command interface.
Project details
System flow
The interface uses BlinkM-style I2C commands. Packed command parsing links incoming instructions to RGB and HSV fades through a compact control interface.
EEPROM-backed scripts keep programmed sequences available between sessions. The command engine stores the scripts, so an external application does not have to resend every lighting step.
Animation and motor updates are organised without long blocking delays, so they do not occupy the controller at the expense of its command interface. Photographs show the small prototype modules illuminated in different colours.
Record 062 / Lighting and interaction
Animation control for WS2812 addressable LEDs.
setAll() applies a common output state across the LEDs.
Animation logic defines successive LED output states.
The module provides lighting routines that produce the successive states of an addressable LED animation.
Record 085 / Lighting and interaction
An addressable LED controller using stored scripts and local colour or animation selection routines.
EEPROM provides storage for the lighting scripts. Keeping saved sequences separate from the code that executes them gives the controller a clear way to organise its lighting effects.
The firmware includes ledCountMenu(), colorMenu() and colorCycle() routines. These connect user-facing choices, such as pixel count and colour, to the animation portion of the controller.
The output scope covers addressable LEDs, including WS2812 or NeoPixel-style control. Each saved or selected effect ultimately needs to be expressed as colour values across the configured pixels.
Record 093 / Lighting and interaction
An ESP32 controls a large bingo display using WS2812 pixels. Wireless game updates select number highlights, with a pixel map linking each number to its panel position.
Project details
System flow
Firmware flow
Selected number-to-pixel clearing routine.
Accept only numbers from 1 to 90, look up the stored pixel list for that number and set those pixels to black in the LED buffer.
The routine updates the pixel buffer. It does not include the command that displays that buffer or establish installation size or frame rate.
clearRows · selected source lines 156–167. Source inspection is not a hardware test.
// Clear rows for a specific number
void clearRows(int number) {
if (number < 1 || number > 90) return; // Ensure valid range STOP BLINK FOR MORE 90 !!!!!!
int index = number - 1; // Convert 1-based number to 0-based index
int pixelCount = pgm_read_word(&numberPixelCount[index]); // Read count from PROGMEM pgm_read_word (small) or pgm_read_byte (original big)
for (int i = 0; i < pixelCount; i++) {
int pixelIndex = pgm_read_word(&numberPixels[index][i]); // Read pixel index from PROGMEM
strip.SetPixelColor(pixelIndex, blackColor); // Turn off the pixel
}
}Open the exact source-level diagramIncoming wireless updates drive changes in the displayed numbers. The firmware translates the relevant game state into lighting updates across the panels.
The display is organised as a large physical matrix, rather than a short decorative strip. A pixel map connects individual game numbers with the correct regions of the installed panels.
The work includes ESP32 firmware, display-state logic and integration with the physical LED installation. The visible result is a large-format number display in which selected regions carry the game information.
Record 006 / Sensing and instrumentation
An IMU based approach to observing breathing related motion. The project material covers sensor acquisition and motion data review.

An IMU observes movement at its mounting point. Position and orientation therefore affect the signal being examined, which is an important consideration when relating motion to breathing.
I2C and UART support acquisition and data review, with the communication path kept distinct from the motion signal.
The project concerns motion observation and analysis. Understanding that signal is a different task from establishing medical accuracy or diagnosing a condition; this work is an engineering exploration of movement.
Record 015 / Sensing and instrumentation
Environmental monitoring logic with threshold alarms and a local LCD interface.
Environmental input acquisition is separate from the threshold decisions that control the alarm.
A threshold defines when the response should change. Making that rule explicit helps keep the displayed information and alarm response grounded in the same reading.
updateLCD() handles display refresh separately from the alarm decision logic.
Record 022 / Sensing and instrumentation
A cable testing interface presenting continuity information on a compact OLED display.
The continuity check relates the cable path being tested to the observed result.
The OLED is the instrument’s local display for continuity results.
I2C, UART and local controls support the test interface, separately from the continuity decision.
Record 036 / Sensing and instrumentation
Capacitive sensor input translated into MIDI control information.
Input processing translates capacitive sensor readings into MIDI control events.
The firmware scope includes MIDI message generation, UART communication and embedded C/C++.
The scope connects capacitive input processing with MIDI output.
Record 049 / Sensing and instrumentation
A compass interface library with magnetometer setup and heading readout routines.
I2C connects the magnetic sensor with dedicated initialisation and heading-access routines.
setupHMC5883L(), getHeading() and Output() separate sensor setup, heading acquisition and output.
A compass reading needs context: sensor orientation and the surrounding magnetic environment affect its meaning. Keeping acquisition separate from presentation gives the wider controller a clear place to apply its own operating conventions.
Record 050 / Sensing and instrumentation
Signal counting using interrupt driven input handling.
A polling loop only sees an input when execution reaches the read operation. Interrupt driven counting gives the input event its own response path instead of tying observation to the loop schedule.
The module accumulates incoming signal events into a count used by the application.
The useful distinction is between capturing an event and reporting the result. Output or communication activity should not determine when the system notices the next input transition.
Record 065 / Sensing and instrumentation
LiDAR measurements used in start and finish timing modules, with local timing and interface routines.
LiDAR range information provides the input for start and finish event handling.
drawApp(), drawMenu() and events() connect application views and menus with timing-event handling.
getTime() handles the timing operation alongside detection, event handling and presentation.
Record 067 / Sensing and instrumentation
A prototype combining load cell measurement, compass data and a BLE interface.
A load cell and a magnetometer provide different information and require different interpretation. The prototype brings both into one application without treating their readings as interchangeable sensor values.
writeRegister(), readRegister(), readMagnetometerData() and softReset() provide low-level sensor access.
The development view identifies a Seeed XIAO BLE Sense nRF52840 target. BLE provides the wireless interface around the sensor work, while local diagnostics support inspection of the acquired data during development.
Record 087 / Sensing and instrumentation
A handheld target-alignment prototype combines IMU orientation with LiDAR range measurements. The firmware brings the two inputs into a consistent update sequence before producing feedback.
Project details
System flow
Firmware flow
Selected orientation and range alignment logic.
Compare orientation with its tolerances and compare range only when both distance values exist. Choose target-reached, orientation-aligned or misaligned feedback, then update the LED and buzzer.
This classifies the readings against configured tolerances. It does not establish physical accuracy, safety performance or a tested acquisition range.
alignment feedback excerpt · selected source lines 423–445. Source inspection is not a hardware test.
bool angAligned =
(fabsf(errRoll) <= ALIGN_ROLL_DEG) &&
(fabsf(errPitch) <= ALIGN_PITCH_DEG) &&
(fabsf(errYaw) <= ALIGN_YAW_DEG);
bool distAligned = false;
if (tfHasData && targetHasDist) {
int32_t diff = (int32_t)tfDistCm - (int32_t)targetDistCm;
if (diff < 0) diff = -diff;
distAligned = (diff <= TARGET_DIST_TOL_CM);
}
if (angAligned && distAligned && tfHasData && targetHasDist) {
trackState = TRACK_TARGET_REACHED;
} else if (angAligned) {
trackState = TRACK_LOCKED_ALIGNED;
} else {
trackState = TRACK_LOCKED_MISALIGNED;
}
updateLedForState();
updateBuzzerForState();
}Open the exact source-level diagramOrientation and range answer different questions about alignment. The IMU contributes the direction-related information, while the LiDAR contributes distance, giving the guidance application two complementary inputs to work with.
The firmware keeps inertial and range data within a consistent update sequence. The engineering concern is the relationship between those measurements when the handheld assembly changes position or orientation.
Filtering and bias handling form part of the acquisition path. This adds a processing stage between raw sensor values and the feedback used by the target-alignment application.
Record 090 / Sensing and instrumentation
Firmware for acquiring readings from a blood oxygen sensor interface. Scope is sensor communication and data acquisition.
I2C forms the communication link between the ESP32 and the sensor interface. The work concerns the firmware at that hardware boundary.
The module focuses on obtaining sensor readings for further processing or reporting within the embedded application.
This is sensor communication work: the acquisition layer that connects a peripheral device with the controller’s application logic.
Record 091 / Sensing and instrumentation
A measurement controller for two load cell inputs, including channel handling and measurement processing.

The controller’s scope includes two load-cell inputs. Keeping channel identity attached to a reading is a basic requirement for making sense of the measurements together.
Firmware handles the measurements after acquisition through the load-cell interface. This is the application layer between incoming conversion data and the values used by the controller.
The accompanying controller material includes an ESP32 module schematic and a board view. These place the measurement firmware within a broader embedded hardware context.
Record 092 / Sensing and instrumentation
An HX711 interface with channel selection and separate tare routines for two load cell channels.

selectChannelA() and selectChannelB() make input selection explicit in the source. This connects the firmware’s choice of channel to the measurement being requested from the interface.
tareChannelA() and tareChannelB() provide separate tare operations. A tare action establishes a reference for its selected input, so the firmware must preserve the distinction between the two channels.
The wiring illustration brings two load cells, the interface board and a controller into one view. It complements the firmware by showing the physical inputs behind the channel operations.
Record 008 / Engineering studies
A user interface concept for a round touchscreen, covering screen layout and local interaction.

A rectangular screen layout cannot simply be cropped into a circle. Content near the perimeter has less horizontal room, so the shape influences hierarchy and placement.
The concept connects touch input with application screens within the available circular display area.
Embedded C++ and state-based control provide the software context for the concept. Screen navigation is linked to device operation, with interface implementation left for later development.
Record 011 / Engineering studies
A control concept for managing a heated enclosure using environmental inputs and defined operating limits.
The concept relates environmental measurements to the desired operating range.
Control and alarm thresholds define when the system should change its response.
The concept establishes inputs, state transitions and output responsibilities. These relationships allow the intended control logic to be reviewed before detailed hardware choices are made.
Record 014 / Engineering studies
A technical assessment covering embedded requirements, interface considerations and engineering documentation.
An assessment needs to distinguish what the system is expected to do from the technology that might implement it. That separation keeps a component choice from becoming an unstated requirement.
The assessment documents where system functions exchange information or depend on one another.
Record 018 / Engineering studies
An engineering design document organising system requirements, interfaces and implementation choices.
Requirements describe what the system needs to do. Keeping them visible beside the design discussion helps prevent an implementation detail from changing the original objective.
The document records how system parts exchange information, power and decisions.
Record 041 / Engineering studies
A hardware integration plan documenting an Arduino based system and its interfaces.
The plan defines wiring, interfaces and USB connections within an Arduino-based system.
The interface documentation gives assembly and firmware work a common connection reference.
Record 070 / Engineering studies
An irrigation control architecture relating environmental inputs to pumps, valves and ventilation outputs.

The system illustration shows plant containers above a circulating water channel, with supply and overflow paths. This makes the physical process visible before the control logic is considered.
The architecture connects environmental information with scheduled pumps, valves and ventilation outputs. Each equipment type has a different role within the broader growing system.
The architecture study maps environmental inputs to pumps, valves and ventilation outputs.
Record 073 / Engineering studies
A design study for fan control using sensor input and operating requirements.

The circuit illustration includes temperature, humidity and distance sensing around an Arduino Uno. These inputs describe different aspects of the local environment and should have clearly defined roles in a control application.
An OLED display is shown in the same arrangement. A local view gives the system a place to present readings or operating information alongside the sensor connections.
This is a design study for sensor informed fan control. The sensing arrangement provides a foundation for discussing the intended response before a complete fan driver and operating strategy are settled.
Record 080 / Engineering studies
A study of electronics and mechanical fit for a smart ring concept, using a rigid-flex PCB within a constrained enclosure.
A ring offers a narrow, curved volume rather than a conventional flat board area. The study considers component placement in relation to that envelope and the space available around the wearer’s finger.
The PCB concept uses the ring geometry to organise the electronics. Rigid component regions and their connecting sections are considered together with enclosure shape, rather than resolving the circuit and mechanical package independently.
The CAD study shows the proposed board and enclosure arrangement. It examines the geometry and placement choices that shape later electrical and mechanical development.
Try a different term or clear the area filter.
Project enquiries
Tell us what you’re developing and where you need engineering support.