I build the tools that keep operations organized. I use Claude and Claude Code every day to research, draft, plan and ship working software, then own the result until it is done. Everything below runs in the page, so you can click through it.
Mexicali, Baja CaliforniaEnglish and Spanishgithub.com/Larry70455Resume and background
I took the checklists at Dee Ro Logistics, an Amazon delivery service partner where I worked, and turned them into working web tools. I also took a controller from schematic to 1,500+ units in the field. Try the checklists.
Use Claude Code to build lightweight tools
I built the dispatch, training and ride-along checklists for the team at Dee Ro with Claude. Try them below.
Automate manual work
A daily Excel import macro turns a raw dispatch export into a finished sheet with waves and van codes. Run a simulation.
Build systems and dashboards
A fleet dashboard for connected water-treatment controllers, backed by Cloudflare. Open a simulated fleet.
Work independently on complex problems
Custom hardware and firmware from schematic to deployed product, including a controller with 1,500+ units in the field. Open the boards.
Clear written English, plus Spanish
Bilingual in English and Spanish, with a technical sales and field background that has me writing to customers, drivers and engineers.
Live demo
Dee Ro Logistics dispatch tools
I worked at Dee Ro Logistics, an Amazon delivery service partner, and helped the team with tools. Here are three checklists I built for them. Each one is a single HTML file. Pick one and use it: tick boxes, type in fields, and on the ride-along form try Save and the Saved Forms list.
Demo copies. Saving stays in this page only, contact numbers are removed, and print and PDF export are turned off in the preview. The real versions save to the cloud so several people can fill out forms at once.
What it showsI spot a recurring operational problem and ship a working tool for it myself, without waiting on a developer.
Every morning a dispatch export arrives with a different file name. I wrote a VBA macro that finds it, pulls the routes into the team workbook, turns dispatch times into wave labels, and turns long service names into short van codes. Edit the sample below and press Run import to see the same rules at work. The routes and drivers are made up.
Route
Dispatch time
Staging
Driver
Service type
Route
Wave
Van
Staging
Driver
What it showsWave times change daily, so the macro sorts the distinct dispatch times from earliest to latest instead of hardcoding clock times. It reads the size or level number out of the service text, so a new van length still works. It also warns about service types it cannot map instead of guessing.
Excerpt from the VBA
' Clear ALL previous route data (every input column) before writing today's rows,
' so a shorter file never leaves stale rows behind. Skips V, AF, AG, AK - those are
' formulas (MATCH check + rescue totals) and must never be cleared or they break.
Dim clearRow As Long
clearRow = leadsRow - 2
book2WS.Range("B4:U" & clearRow).ClearContents
book2WS.Range("W4:AE" & clearRow).ClearContents
book2WS.Range("AH4:AJ" & clearRow).ClearContents
book2WS.Range("AL4:AQ" & clearRow).ClearContents
The full macro also opens a file picker, reuses a copy that is already open when the file name has a (1) in it, and shows a confirmation with the detected waves. The button on the sheet is a shape with the macro assigned, so nobody needs the Developer tab.
Live demos
EDIE tool suite
EDIE is a chlorine dioxide controller I designed and built, with more than 1,500 units in the field. The site around it is several separate tools, not one page: a fleet dashboard, the controller's own web interface, a calibration screen, field calculators and an equipment tracker. Pick one and use it. All numbers are made up.
The real dashboard watches connected controllers. It runs on Cloudflare: the latest reading of each unit sits in KV, and history is stored as files in R2. This is a simulated fleet. Click a unit, switch the range, and filter by status.
What it showsI turn a pile of device logs into something an operator can read in seconds. Units that stopped reporting still show their last known data, so history is useful even when you do not know the dates a system was running.
Real figures from the live system: each unit writes about 10 MB a month at one-minute logging, and a full history pull takes roughly 15 seconds.
This is the page the controller serves over its own WiFi. Pick a status and watch the banner, gauges and totalizers react. Gauges move inside a small range around the live value so they look like a real process, and a disconnected unit shows no signal instead of a made-up number.
One second here counts as ten simulated minutes.
What it showsI wrote the firmware and the web interface together, so the status list, the colors and the totalizers match what the operator sees on the unit's own screen.
Every probe and flowmeter needs two reference points before its reading means anything. This screen turns a raw 0 to 4095 reading into a real value. Press Start updates to see live raw readings, then move the raw slider, or change the calibration points and watch the gauge rescale.
What it showsRaw numbers only appear while updates are running, and a stopped or unplugged input shows N/A instead of a negative number, because that is what confused people in the field.
A field tool for setting chemical pumps. Enter the top flow rate, the target concentration and the pulse ratio, and it returns the analog pump rate and the volume for each pulse, with the same limits I use on the job. Try 15 GPM at 120 PPM to hit the capacity limit.
Analog pump0.090 GPH
Pulse pump0.038 mL/pulse
What it showsI find a real user problem (you could not delete a digit to type a new number) and fix it: values are checked when you leave the field, not on every keystroke.
The design I worked out for tracking installs, replacements, troubleshooting and repairs across EDIE and TITAN units, with replacement parts so each job shows cost and the price to charge. Filter by component to see, for example, every pump issue across the fleet. Add a job to see the totals move. Units and costs are sample data.
Unit
Model
Job
Component
Part
Part cost
Price to charge
What it showsI design a data model around how the business asks questions: per unit, per component across the fleet, and per job type, with the money attached.
Hardware and firmware
From schematic to the field
The tools above sit on top of hardware I design myself. Each board below has its parts and connections, plus something you can run that shows how it works. Schematic and layout files are in my KiCad and EasyEDA projects, and I can share them.
Built and deployed
Custom PCB with an ESP32 and C++ firmware. It reads a 4-20 mA flowmeter, calculates the dose for the pumps, logs chlorine dioxide, ORP and pH probe data, and runs an on-board screen with buttons and a built-in WiFi web app. It uploads JSON to a Cloudflare backend. Access is split into PIN-protected User, Tech and Master levels. More than 1,500 units are in the field.
Try the software side of this board:
Designed
ESP32 board in KiCad with a 1.77 inch TFT over SPI, an IR receiver, a three-LED IR blaster switched by a MOSFET, WS2812B status LEDs and an MCP23017 for up to 16 buttons. Parts chosen from LCSC for JLCPCB assembly. Click a signal to highlight it, and build an IR frame to see what the blaster pin sends.
Designed
A USB-C hub with an ESP32 and small battery nodes that take commands over BLE advertising instead of WiFi, to get months of battery life. Nodes use a TPS63070 buck-boost regulator so any battery from AAA to 18650 to 9V works, and ship on one panel with the hub, joined by mouse bites. Try the regulator feedback divider and a battery life estimate.
Mirrors Vout = 0.8 × (1 + R1 / R2). A first draft used 56k and 10k, which gives 5.3 V. Checking the datasheet caught it.
Node battery life estimator. The inputs are placeholders: put in your own measured currents.
Estimated runtime--
Average draw--
Designed
ESP32 board that interfaces with a wide range of equipment: analog outputs of 0-5 V, 0-10 V, plus or minus 10 V and 4-20 mA from a GP8630N DAC, four analog inputs through an ADS1115, optocoupled digital inputs, two relays and a second USB-C for serial. Two layers, about 140 by 110 mm. Try the output scaling and the input conversion.
Analog output: pick a mode and a setting, get the DAC code
DAC code--
Output--
Set the bit count from the datasheet of the DAC you fit. The code is the fraction of full scale times 2^bits minus 1.
Analog input: a 4-20 mA loop through a shunt into the ADS1115 (±4.096 V range, 125 µV per count)
Voltage across shunt--
ADC counts--
Back to mA--
Built
I refactored DFRobot's GP8302 4-20 mA DAC library onto Wire.h so the module shares an I2C bus with other devices. This is the same math as the library's calibrated output: set the DAC codes you measured at 4 mA and 20 mA, then ask for a current.
DAC code sent--
I2C bytes--
Excerpt from the library
uint16_t DFRobot_GP8302::output(float current_mA) {
// inside the calibrated 4-20 mA span, interpolate between the two measured codes
if (_calibration && (current_mA >= 4) && (current_mA <= 20)) {
_digital = _dac_4 + (current_mA - 4) * (_dac_20 - _dac_4) / (20 - 4);
// round to nearest
}
return output_mA(_digital);
}
float DFRobot_GP8302::output_mA(uint16_t dac) {
Wire.beginTransmission(_twiaddr);
Wire.write(GP8302_CONFIG_CURRENT_REG);
Wire.write((_digital << 4) & 0xF0); // low nibble first
Wire.write((_digital >> 4) & 0xFF); // then high byte
Wire.endTransmission();
}
Built
One firmware codebase builds for three boards. Here is the learning flow in the page. Press buttons on the pretend remote, turn Learn on, save a capture under a name, then replay it. Each capture is reduced to a hash of its bucketed timings, so tiny differences between presses still match, and it works for protocols the library cannot name.
The hash, from main.cpp
// bucketed hash of raw timings - tolerant of small jitter,
// works for ANY protocol including ones IRremote can't decode by name
code.hash = 0;
for (uint16_t i = 0; i < code.len; i++) {
code.hash = code.hash * 31 + (code.data[i] / 50);
}
What it showsI take a vague need, choose the parts, check them against datasheets, and see it through to something that ships.
More live examples
Other things I have built
Facilities send yearly audit workbooks full of merged cells, formula errors and inconsistent text. A Python script reads each workbook and rolls it into one master table. Edit the sample rows below (location, then four quarters) and press Clean to apply the same rules: Excel errors become N/A, locations are title-cased, and occupancy is the average of the quarters that have a number.
Location
Q1
Q2
Q3
Q4
OCC %
The design for checking an order bag: the scale reading is compared with the weight the order should have, using known per-item weights. If the weights disagree, it works out which item is most likely missing or extra. A camera would be a second opinion, but the scale is the deterministic check. Items are samples. Change the quantities in the bag and the scale reading.
Item
Unit weight (g)
Ordered
In bag
Excel inventory systems, and Power BI and Excel reports fed by JSON from the Cloudflare dashboards.
A local AI setup running Qwen models on an Intel NPU and GPU behind OpenAI and Ollama compatible APIs.
A universal infrared learner and blaster. One firmware codebase builds for three boards, so the same remote library works on a screenless devkit, a touchscreen panel, and a knob-and-display board.
Learns IR codes from any remote, stores them in named remotes, and replays them on demand.
Runs a built-in web interface for adding, renaming, reordering, importing and exporting remotes, with mDNS discovery on the local network.
Supports MQTT and keeps profiles in the on-board LittleFS filesystem.
Uses the touchscreen directly on the Cheap Yellow Display board and an LVGL interface on the ESP32-C3 LCD kit.
A refactor of DFRobot's GP8302 Arduino code. The original bit-banged the bus, which kept the module from sharing it. I rewrote it on top of Wire.h so the GP8302 works alongside other I2C devices on the same bus.