music
Profile
Available for work

I like to build cool things...

Web AppsMobileIoT / MCUAI / ML

From browser to hardware — Arduino, ESP32, Raspberry Pi ....

Projects
18+
Location
GH
Degree
B.Sc
1/5
— move cursor to explore —

Selected work

Projects

51 projects
CediCash  Mobile Money Raffle Platform
Live
Web2026

CediCash Mobile Money Raffle Platform

A raffle-ticket platform for Ghana where people buy numbered tickets into pooled groups using mobile money, reachable two ways: a full web app, and a USSD menu (*716#) for anyone without a smartphone or data — so taking part never depends on owning a particular kind of phone. Both channels share the same backend: a payment is debited through a mobile money gateway, left pending until the network actually confirms it (never assumed successful early), and only then does it issue tickets and notify the buyer — a payment that's slow to confirm is retried in the background rather than treated as failed. Each ticket pool has its own real-time group chat, with moderation tooling (reporting, muting, admin oversight) rather than an open unmoderated room. The admin side is a full operations dashboard: a live feed of payments as they happen, revenue and payout breakdowns, and account/role management for the team running it. A meaningful chunk of the build was defensive, not feature work: automated bulk-purchase attempts using fabricated identities needed a real fraud-detection layer, not a one-off patch — one that adapts as the abuse pattern adapts, and is tuned carefully so it never penalizes a genuine customer in the process. That tension (catch the bot, never the real buyer) shaped most of the decisions on that side of the system more than any single clever trick did.

Next.jsTypeScriptPrisma+7
FlexiPhones , Phone Hire-Purchase Platform
Live
Web2026

FlexiPhones , Phone Hire-Purchase Platform

A full hire-purchase platform for FlexiPhones (by Waltergates Ghana) letting customers walk out of a shop with a smartphone on a small deposit and pay the rest daily over 3, 6, or 12 months, instead of needing full cash upfront or a bank loan. Built the customer-facing web frontend on Laravel with Inertia.js and React, so the whole site — Home, Customers, Vendors, Agents, How it Works, Pricing, Contact, Trustonic security — runs as a single-page app without ever leaving the Laravel backend or shipping a separate API layer just for routing. Customers land on a marketing site that explains the model (deposit → daily MoMo autopay → device unlocks fully on the final payment via Trustonic device-level security), see live vendor coverage across Accra, Kumasi, Tema, Takoradi, and Cape Coast, and can reach support through email, WhatsApp deep links, or a two-mode contact form (general inquiry vs report-an-issue) that posts to dedicated Laravel API routes. Vendors get their own dedicated pages laying out zero-credit-risk financed sales, a self-serve APR editor, cash-sales subscription tiers with a live pricing/plan-selection flow, and a phone-frame video showcase demoing the actual vendor portal in use. Every page is built around Framer Motion — scroll-triggered reveals, animated count-up stats, staggered card grids, and a two-video technique (blurred cover + true-aspect contain layer) to show portrait phone-in-hand demo footage without cropping it into a landscape box. Alongside the web platform, the customer-facing mobile app is built in Flutter and published for download, so someone can browse phones, put down a deposit, and manage their daily payment plan entirely from their phone rather than needing the website. Deployment ran on shared cPanel hosting rather than a managed platform: the Laravel app root sits outside the public web root for security, with the domain's document root holding only the compiled public/ assets and a path-corrected index.php pointing back at the real app directory, vendor/, and bootstrap — plus getting Node and PHP version mismatches (system npm vs nvm-managed Node, PHP 8.2 vs the 8.3 Composer required) sorted out over SSH to get npm run build and the artisan commands running cleanly in that environment.

LaravelInertia.jsReact+5
Bot-pid-instrumentation Data-Driven PID Tuning Dashboard
In progress
Robotics2026

Bot-pid-instrumentation Data-Driven PID Tuning Dashboard

A third pass at the two-wheel self-balancing robot, this time built around instrumentation first, tuning second. Same ESP8266 + MPU6050 + L298N stack as the earlier builds, but the actual project this time is the tooling: a Next.js dashboard that turns PID tuning from slider-guessing into an evidence-driven process. Every gain (Kp, Ki, Kd), per-motor trim, per-motor deadband, and an error deadzone all apply live over WebSocket with no reflash. A dedicated Motor Test mode isolates each wheel with raw, trim-bypassed PWM so real motor breakaway thresholds can be measured directly instead of guessed — deadband compensation is then calibrated from that real number, not an assumption. The dashboard streams raw accelerometer angle alongside the complementary-filtered angle on the same chart, so sensor noise is visible rather than invisible — the gap between the two lines is a direct picture of what the filter is actually doing, and why Kd interacts with that noise the way it does. A third chart tracks loop timing (ms between control loop passes) to rule out timing stalls as a hidden variable in PID behavior. The most useful feature turned out to be data logging: hitting Capture starts a timestamped recording, with two marker buttons ('tilting forward' / 'tilting backward') tagging exactly when an intentional test tilt happened, and an export button generates a full PDF — config snapshot, marker timeline, and the complete sample-by-sample log — that can be studied after the fact rather than read live off a scrolling chart mid-test. That log is what actually found the real issue: the robot recovers reliably within roughly a 10-12 degree lean, and PID output was confirmed mathematically correct at every logged sample (Kp*error - Kd*gyroRate matched the recorded output every time) — but past that angle, output saturates at max PWM and still can't arrest the fall. That's a physical torque ceiling, not a tuning bug, and no amount of Kp/Kd/Ki adjustment changes it. A fall-detection cutoff now kills the motors once the lean exceeds that recoverable range, instead of holding at max output for no benefit. Still not reliably self-balancing outside that window — next steps are either improving mechanical torque/traction, or accepting a narrower recoverable range and building on top of it.

ESP8266MPU6050L298N+8
5 DOF Servo Rig Controller test (Robotic Arm)
In progress
Robotics2026

5 DOF Servo Rig Controller test (Robotic Arm)

A 5 degree of freedom rig controller built on an ESP8266 running as its own WiFi hotspot with a WebSocket server on board, so a frontend page connects straight to it with no bridge process in between. Four of the five joints are real analog servos driven through a PCA9685 I2C PWM driver rather than directly off the ESP8266, since the chip has no spare hardware PWM channels to spare for four independent servos at once. The fifth joint is a 28BYJ-48 stepper motor driven through a ULN2003 darlington array on plain GPIOs, half-stepped across an 8-phase sequence for smoother, quieter motion than full-stepping, at the cost of needing twice the steps to cover the same angular distance. Every commanded move, servo or stepper, is non-blocking. Instead of jumping straight to a target angle, each servo eases there a couple degrees at a time on a timed slew-rate ramp, and the stepper advances at most one half-step per loop iteration gated by a microsecond interval, so nothing ever stalls the WebSocket event loop the way a delay()-based move would. Each joint fires its own acknowledgment back over the socket the moment it actually arrives at its target, rather than assuming the command succeeded the instant it was sent. The real challenge turned out to be mechanical, not code. Past a certain load on the arm, a servo simply cannot move: it draws current and heats up but stays physically stuck at the same angle no matter what PWM value is sent to it. That's a stall torque limit, not a bug, and no amount of slew-rate smoothing, retrying, or PID-style correction fixes a motor that is mechanically out of torque budget for the weight it's being asked to lift. The only real fixes are mechanical: gearing down, cutting the load, or moving up to a stronger servo.

ESP8266PCA9685I2C+6
FarmCam  Remote Monitoring Robot
In progress
Robotics2026

FarmCam Remote Monitoring Robot

A pivot of the RC car / ESP32-CAM platform into a remote monitoring tool aimed at farmers, or anyone who needs eyes on a place they can't physically be. Same ESP32-CAM + ESP8266 hardware as the surveillance tracker, but reworked around a capture-and-log workflow instead of live tracking: point it at a crop, a plot of land, livestock, whatever needs watching, and check in on it from anywhere with internet. The landing page is the live view itself, not a dashboard bolted on top of one. The ESP32-CAM's MJPEG stream is parsed frame by frame in the browser and painted to a canvas that fills the entire panel edge to edge, with the drive controls (D-pad, per-motor speed trim, a settings panel) rendered as a translucent glass overlay directly on top of the video feed rather than a separate control panel — buttons are clickable, everything else lets the feed show through. A capture button grabs the frame currently on canvas via canvas.toBlob(), the same source the recording feature already pulled from, and posts it straight to the backend: no dependency on a still-capture endpoint existing on the camera firmware, since the only proven-reliable path to a frame is the one the stream itself already provides. Every capture is uploaded to UploadThing and the resulting URL plus metadata (capture type, timestamp, an optional note) is written to MongoDB via Mongoose. Captured images are run through Grok for automatic analysis, so a photo isn't just stored, it comes back with a description of what's actually in frame. The farmer/user can also attach their own note to any capture, layered on top of or independent from the AI analysis. A calendar view lets you browse captures by day: a compact month grid with a dot marking any day that has activity, clicking through to a gallery of everything captured that day with timestamps and notes attached. The whole UI (sidebar icon dock, capture button, calendar, glass control overlay) is styled to an Apple-like visual language, matching the rest of the platform. Open issue: on rough terrain the chassis struggles to move smoothly, and video streaming stutters under weak internet connections.

ESP32-CAMESP8266C++ / Arduino+7
ESP32-CAM AI Surveillance Tracker _ Servo Pan/Tilt
Live
AI2026

ESP32-CAM AI Surveillance Tracker _ Servo Pan/Tilt

A live surveillance camera built around an ESP32-CAM with AI-assisted object tracking and physical pan/tilt servo tracking layered on top. The ESP32 captures frames in RGB565, converts them to JPEG on-device, and serves an HTTP MJPEG stream with no external server involved at this stage. Pushing the resolution higher stammers the stream since RGB565 is uncompressed pixel data, so every step up multiplies the raw bytes the chip has to push over WiFi each frame. That stream is normally LAN-only, so it's tunneled out to get the ESP32 a public URL, reachable from anywhere with internet instead of just the room it sits in. Started on Cloudflare Tunnel but switched to Tailscale Funnel after the free tier kept dropping and killing the stream mid-track; Tailscale has been stable since. A Next.js frontend fetches that public stream and manually parses the raw MJPEG byte stream, pulling out each JPEG frame by hand and painting it to a canvas, with reconnect and backoff logic for when the tunnel drops. Every frame painted to canvas gets scanned live under two tracking modes. Object mode runs TensorFlow.js (COCO-SSD) in-browser, matching against a chosen class like 'cup' and drawing a box around it whenever it's in frame. Color mode skips the model entirely: click any pixel in the video to set it as the target, and the system tracks that exact color in real time via raw pixel comparison, which is faster and lower-lag than the AI path. A position map beside the video shows where the tracked object currently sits in frame, with a fading trail of its last few positions, so movement is visible over time rather than as a single snapshot. The tracking is no longer just visual, it now physically moves. Built a pan/tilt servo rig driven by an ESP8266 that follows whatever's being tracked in real time. The bounding box center is converted into a real angular offset in degrees using the camera's field of view, and a per-axis proportional controller turns that angle into a pan/tilt correction sent to the servo board over the LAN. Corrections are throttled and gated per axis until the servo has had time to physically settle, since pan swings more mass than tilt and needs a longer window, which is what fixed an early oscillation bug where the mount kept chasing its own overcorrections. A dead zone per axis stops the rig from twitching once it's roughly centered on target. Possible use case: a low-cost remote monitoring setup, watching a space, room, or object from anywhere with internet, with the camera automatically turning to keep whatever it's tracking centered in frame instead of requiring constant manual attention or a fixed field of view.

ESP32-CAMESP8266C++ / Arduino+8
ESP32-CAM AI Surveillance Tracker
In progress
AI2026

ESP32-CAM AI Surveillance Tracker

A live surveillance camera built around an ESP32-CAM with AI-assisted object tracking layered on top. The ESP32 captures frames in RGB565, converts them to JPEG on-device, and serves an HTTP MJPEG stream with no external server involved at this stage. Pushing the resolution higher stammers the stream since RGB565 is uncompressed pixel data, so every step up multiplies the raw bytes the chip has to push over WiFi each frame. That stream is normally LAN-only, so it's tunneled out with Cloudflare to get the ESP32 a public URL, reachable from anywhere with internet instead of just the room it sits in. A Next.js frontend fetches that public stream and manually parses the raw MJPEG byte stream, pulling out each JPEG frame by hand and painting it to a canvas, with reconnect and backoff logic for when the tunnel drops on the free tier. Every frame painted to canvas gets scanned live under two tracking modes. Object mode runs TensorFlow.js (COCO-SSD) in-browser, matching against a chosen class like 'cup' and drawing a box around it whenever it's in frame. Color mode skips the model entirely: click any pixel in the video to set it as the target, and the system tracks that exact color in real time via raw pixel comparison, which is faster and lower-lag than the AI path. A position map beside the video shows where the tracked object currently sits in frame, with a fading trail of its last few positions, so movement is visible over time rather than as a single snapshot. Possible use case: a low-cost remote monitoring setup, watching a space, room, or object from anywhere with internet, and automatically flagging when something specific enters frame instead of requiring constant manual attention to the feed.

ESP32-CAMC++ / ArduinoCloudflare Tunnel+5
Updated : Path Planning in a Maze — Webots Sim
In progress
Robotics2026

Updated : Path Planning in a Maze — Webots Sim

Follow up on the GPS goal seeking bot, this time dropped into a 17-wall maze instead of open space. The earlier version was purely reactive: drive straight at the goal, nudge away when a sensor sees something. That works fine in open space but it has no memory, so in a maze it can wall-follow around the wrong side of an obstacle and wander further from the goal with zero awareness it's going the wrong way. Not a tuning problem, a structural one. This version adds a real planning layer on top of the reactive controller. The exact wall coordinates were already known from the world file, so an occupancy grid gets built from them, inflated by the robot's radius plus a safety margin, and A* runs over that grid to produce waypoints that route around every wall before the robot even starts moving. The raw A* path gets simplified into straight line legs instead of a jagged cell by cell staircase, and the robot steers toward the current waypoint instead of the raw goal, advancing waypoint by waypoint until it reaches the actual destination. The old reactive layer (obstacle avoidance, stuck detection, wall following) is kept, but now it only needs to cover small real-time discrepancies between the plan and reality instead of doing all the work. Initially worked cleanly on shallow goals but struggled the deeper the goal was buried in the maze. Turned out to be neither a grid resolution nor a waypoint tolerance issue. The actual bug was one step past the planner: the routine that walks the solved A* path back into a waypoint list had a size limit, and on long routes through several rooms it would hit that limit and discard a path it had already solved correctly, reporting no path found. Shallow goals never got close to the limit, so they always looked fine. Fixing the limit removed the correlation between goal depth and failure entirely. A secondary issue remains at sharp corners near walls: the robot occasionally clips the wall, backs off, and retries before getting around cleanly. Much softer than the depth bug was, and next on the list to tighten up. End result: the robot can now find and reach a goal anywhere in the maze, not just shallow ones. Corner handling is the remaining open item.

WebotsCA* Search+5
RC Toy Car — Scoop Pickup Prototype
In progress
Robotics2026

RC Toy Car — Scoop Pickup Prototype

A cardboard-chassis two wheel RC car built mostly to mess around with wireless control patterns rather than as a serious build. The ESP8266 runs as its own standalone WiFi hotspot and hosts a WebSocket server directly on the board, so a Next.js control page connects straight to it with no bridge process or companion app in between. Drive is skid steered off two DC motors through an L298N, controlled from a press-and-hold D-pad with arrow key support and a speed slider, mixed into independent left/right wheel speeds and streamed to the board at a fixed interval with a watchdog that auto-stops the car if the connection drops. A single servo sits at the back doing one job: scooping up small items. Getting it working exposed a real ESP8266 quirk, the chip has no hardware PWM, so the Servo library and the software PWM used for motor speed both compete for the same timer, and running WiFi as an active hotspot on top of that made it worse; a permanently attached servo would move once at boot then go dead. Fixed by attaching the servo only for the brief window it takes to move, then detaching immediately after, freeing the timer the rest of the time. Also added an RGB LED that runs a continuous rainbow color cycle, speeding up and brightening the harder the car is currently being driven, and settling into a calmer cycle at rest. Wiring it hit its own string of dead ends: A0 turned out to be the board's dedicated analog input, not a usable GPIO; one pin died mid-build; and D0/GPIO16 can't do smooth PWM at all since it lacks the interrupt hardware the software-PWM trick relies on, so that channel ended up driven on/off instead of faded, with the two working color channels moved onto RX and TX once the more conventional pins ran out.

ESP8266WebSocketsArduinoJson+4
Path Planning in a Maze — Webots Sim
In progress
Robotics2026

Path Planning in a Maze — Webots Sim

Follow up on the GPS goal seeking bot, this time dropped into a 17-wall maze instead of open space. The earlier version was purely reactive: drive straight at the goal, nudge away when a sensor sees something. That works fine in open space but it has no memory, so in a maze it can wall-follow around the wrong side of an obstacle and wander further from the goal with zero awareness it's going the wrong way. Not a tuning problem, a structural one. This version adds a real planning layer on top of the reactive controller. The exact wall coordinates were already known from the world file, so an occupancy grid gets built from them, inflated by the robot's radius plus a safety margin, and A* runs over that grid to produce waypoints that route around every wall before the robot even starts moving. The raw A* path gets simplified into straight line legs instead of a jagged cell by cell staircase, and the robot steers toward the current waypoint instead of the raw goal, advancing waypoint by waypoint until it reaches the actual destination. The old reactive layer (obstacle avoidance, stuck detection, wall following) is kept, but now it only needs to cover small real-time discrepancies between the plan and reality instead of doing all the work. Works cleanly when the goal is shallow in the maze. Still struggles the deeper the goal is buried, likely a mix of grid resolution and waypoint tolerance stacking error over a longer path. Next step is figuring out which one it actually is.

WebotsCA* Search+5
Import Website
In progress
Web2026

Import Website

A full stack e-commerce platform for importing goods into Ghana, built on Next.js App Router with MongoDB/Mongoose and Firebase Auth. The storefront and the admin dashboard are genuinely separate surfaces sharing one codebase: customers get a landing page, product catalog with variant-level pricing and discount support, cart, and an order pipeline they can track stage by stage (confirmed → processing → shipped → in transit → arrived → delivered); admins get a role-based dashboard with real aggregation-driven analytics. The standout feature is visual product search. Instead of typing a product name, a customer can point their camera at an item and the app finds visually similar products in the catalog. This runs on CLIP (Xenova/clip-vit-base-patch32) via Hugging Face's transformers.js, loaded vision-only since both sides of the comparison — the catalog photo and the customer's live photo — are images, so the text tower is dead weight. Embeddings are quantized (q8) for a smaller download and faster cold-start inference, module-level singleton-cached so the model only loads once per running process instead of once per request, and cosine similarity reduces to a plain dot product since every embedding is pre-normalized. A one-time backfill script walks existing products and generates embeddings for anything missing one. The admin side includes a full role and permissions system: admins can create roles, attach granular permissions, and assign or revoke them per user. Every assignment fires an email via Gmail SMTP (nodemailer) notifying the person of their new access — sending is treated as best-effort so a mail failure never blocks the underlying database update. The admin dashboard itself is backed by real MongoDB aggregation pipelines, not client-side math: revenue and order volume grouped by day, orders broken down by status, top categories by revenue, most-viewed and most-ordered products pulled from dedicated view-tracking and order-item aggregations, all rendered with Recharts. The landing page went through several iterations to land on a 'shipping manifest' visual identity that ties the whole site together: a hero section with a scattered, scroll-triggered 'unscattering' photo card animation, an honest order-pipeline timeline reusing the platform's own real status stages instead of invented marketing copy, and a three-zone footer (black CTA band, navy link grid, black legal bar) modeled on how Apple and Adobe structure footer weight rather than a flat single-tone block.

Next.jsTypeScriptMongoDB+9
Self Balancing Robot v2 — Obstacle Avoidance Prototype
In progress
Robotics2026

Self Balancing Robot v2 — Obstacle Avoidance Prototype

A rebuild of my original self balancing robot on a shortened frame, moved from ESP8266 to an Arduino Nano, with an ultrasonic sensor added as the first step toward a self balancing obstacle avoidance bot. Shortening the frame changed the mass distribution enough that every PID gain had to be retuned from scratch. The original derivative term differentiated the filtered angle directly, which meant dividing tiny sensor noise by a ~2.4ms loop time and amplifying it into fake rotation rates strong enough to blow the motor effort into the thousands. Fixed by feeding the gyro's own measured rate straight into the D term instead of re-deriving it from angle differences. The Kd gain schedule was also inverted: the least damping was firing exactly when the robot was falling fastest and needed the most resistance. Flipped so maximum lean triggers maximum damping and near vertical uses light damping to avoid jitter. Motor vibration was also coupling into the IMU and showing up as gyro rate noise, addressed with a light low pass filter on the rate signal feeding the D term, while keeping the raw rate for angle integration to avoid adding lag to the angle estimate itself. The robot now self recovers if picked up mid fall and set upright again, with no reset needed. Still working through a persistent low amplitude oscillation while holding balance, next tuning target is the near zone Kd and possibly motor deadband compensation. Next step: wiring the ultrasonic sensor into the balance loop so the robot can sense and react to obstacles while still holding itself upright.

Arduino NanoMPU6050Ultrasonic Sensor+3
Autonomous Navigation with Obstacle Avoidance — Webots Sim
In progress
Robotics2026

Autonomous Navigation with Obstacle Avoidance — Webots Sim

Simulating autonomous navigation with obstacle avoidance in Webots. GPS goal seeking based, click anywhere on the floor and the robot drives to that point. A green cylinder appears at the clicked location marking it as the destination. The moment the robot gets close enough, the cylinder vanishes, signifying it arrived. Proportional obstacle avoidance, not a binary left or right flag. Each sensor is weighted by how close the obstacle is and the direction it is facing. The robot swerves harder the closer it gets. Fully dynamic retargeting, click a new point mid-run and the robot drops the old goal and heads for the new one immediately. The issue I ran into: when the goal was in front of the robot it worked perfectly. But place it behind and the robot would shake left and right forever, never actually turning around. The heading estimate from GPS alone was the problem. Replaced it with a compass, which gives a direct world-frame heading every timestep without needing the robot to move at all, and it was fixed immediately. Sensors used: GPS, Compass, 8 IR distance sensors.

WebotsCGPS+4
QUAD-1 Flight Controller Stack — Bar Balancer Update
In progress
Robotics2026

QUAD-1 Flight Controller Stack — Bar Balancer Update

Update on the PID tuning workstation. The system now works for any PID controlled hardware project, not just the drone. Plug in the Arduino Nano over USB, select the port, and the Python bridge opens a WebSocket automatically. The Next.js frontend connects and you are live with real time sensor data, motor outputs, and PID corrections all streaming. Currently testing with a bar balancer setup using two coreless motors. From the UI you can tune Kp, Ki, Kd, and deadband with sliders and changes hit the board instantly with no reflash needed. The balance point is captured with one tap and saved to EEPROM so it survives a reboot. A live 3D model in the viewport responds to the actual IMU angles from the MPU6050 in real time. The Python bridge is unchanged. It is still just a serial to WebSocket passthrough, completely agnostic to what hardware is on the other end. The way it is being built, the same stack works for anything PID related. Self balancing robot, bar balancer, gimbal, whatever the project is. Same UI, same bridge, different firmware on the other end. New in this update: four motor X config support with diagonal pair testing so each diagonal can be validated independently before running all four together. Lift test mode ramps all motors to full throttle in one go to confirm the frame lifts before any balance tuning begins. Base throttle slider for setting the hover baseline. Pitch axis PID added alongside roll so both axes are now controlled and logged simultaneously.

Arduino NanoMPU6050PID Control+6
Forex Signal Engine
In progress
AI2026

Forex Signal Engine

A forex signal engine where two systems vote on every trade. One runs pure technical analysis, one uses AI to reason about what those numbers actually mean together. The technical brain runs six indicators on 15 minute OHLCV candles pulled from Yahoo Finance. RSI and MACD handle momentum, EMA 20/50 crossover confirms trend direction, Bollinger Bands catch mean reversion setups, Stochastic acts as a second momentum check, and Volume acts as a confidence dial that amplifies or dampens the whole signal without voting on direction. All six scores get averaged into one number. The AI brain receives that exact snapshot and reasons about what it means. It is given a system prompt instructing it to think like an experienced forex analyst, be contrarian when readings are extreme, factor in macro patterns like USD strength on risk-off days, and lean NEUTRAL when uncertain. It returns a direction, a confidence score, and a one line rationale. That confidence becomes its vote. The two votes are blended: final signal = (math brain x 0.70) + (AI brain x 0.30). If both agree the signal is strong. If they disagree the blend weakens and nothing trades. Only genuine agreement between both systems opens a position. APScheduler runs the full pipeline across all pairs concurrently every N seconds. Every signal gets logged to MongoDB regardless of outcome, building a dataset for future analysis. The Next.js frontend shows live signals, a paper trading dashboard, and closed trade history with P&L.

PythonFastAPIGroq+7
QUAD-1 Flight Controller Stack
In progress
Robotics2026

QUAD-1 Flight Controller Stack

A full drone flight controller stack built from scratch. PID controller written in C++ with a complementary filter on the MPU6050 giving clean pitch and roll angles in real time. 98% gyro 2% accelerometer to balance fast response with drift correction. The PID loop sits on top of that trying to keep the board level automatically. NRF24L01 link between an ESP8266 transmitter and an Arduino Nano on the receiver end. Joystick Y axis handles throttle, SW button is a kill switch. Signal loss timeout cuts all motors automatically if the link drops. Currently testing how a single motor responds to tilt using PID before scaling to all four. The PID work from the self balancing two wheel robot carried over directly here. Python sits in the middle as a bridge, reading serial DIAG packets from the Nano over USB, parsing them, and serving the live drone state as JSON on localhost. A Next.js ground control station UI sits on top of that consuming the feed. Two sidebars, live attitude indicator showing real time pitch and roll, per motor output bars, PID corrections, and a system log. Makes it a lot easier to see what the flight controller is actually doing rather than reading raw serial output.

Arduino NanoESP8266MPU6050+6
Custom Brushed ESC for 720 Hollow Cup Drone Motor
In progress
Robotics2026

Custom Brushed ESC for 720 Hollow Cup Drone Motor

A single channel brushed motor speed controller I designed from scratch for the 720 Hollow Cup motor (3.7V, 46,000 RPM) used in micro quadcopters. I built and verified the whole thing through SPICE simulation in KiCad before buying any physical components. This let me validate gate switching behavior, flyback protection, and PWM response at 1kHz in simulation first. The driver uses an IRLM6802TRPBF N channel MOSFET (RDS(on) = 13.5mΩ, ID = 5.8A) driven directly from a 5V Arduino PWM pin. At 1.83A motor load the MOSFET dissipates only 45mW, so no heatsink needed. A 1N4148 fast recovery diode (4ns reverse recovery) clamps the inductive kickback from the motor winding on every PWM off cycle. A 47Ω series gate resistor damps switching oscillations that would otherwise cause EMI resets on the flight controller. A 10kΩ pull down guarantees the gate is fully discharged and the motor fully off whenever the Arduino pin goes low. I modeled the motor in SPICE as a series R+L load (2Ω winding resistance, 100µH inductance) which correctly reproduces the current ripple behavior of a real brushed DC motor under PWM switching. Simulation confirmed clean gate switching, correct flyback clamping, and stable current through the motor winding across the full 10ms simulation window. It's designed to be replicated 4 times for a complete quadcopter, with one channel per motor, all sharing the same 3.7V LiPo rail.

KiCad 9ngspiceSPICE Simulation+4
Refuse Collecting Bot Web Control Panel
Live
Robotics2026

Refuse Collecting Bot Web Control Panel

A browser based control panel for the refuse collecting robot. Point the camera at the floor, take a picture, and the system runs it through a Roboflow litter detection model to identify targets and overlay them on the image. Distance calibration is handled using a known size reference object in frame, converting pixel measurements to real world distances so the robot knows which target to go for first. The car's position is tracked live in the same view. Check the video to see it in action.

Next.jsRoboflowOpenCV+2
GAMA Hotspot Tracker
Live
Web2026

GAMA Hotspot Tracker

A web based mapping system built to document and manage high risk locations across the Greater Accra Metropolitan Area in Ghana for public health research and outreach planning. Every recorded location appears as a pin on an interactive map with a risk level (Low, Medium, High, or Critical) along with a description, category tags, and the GAMA district it falls in. The map is scoped strictly to GAMA's 25 districts with a live boundary overlay, auto fit on load, and a Focus GAMA button. Users can add hotspots via device GPS or manual coordinates, edit existing records, and filter by district or risk level instantly. The sidebar shows a live risk distribution breakdown with animated bars, recent reports with a focus button that flies the map to that location and opens its popup automatically, and summary stats that count up when new data arrives. Backend is a Next.js API connected to MongoDB Atlas via Mongoose. State is managed with Zustand. The initial dataset covers 20 documented clusters across 10 GAMA districts including the CBD, Osu, Labadi, Tema Harbour, Madina, Nima, Kasoa, and Spintex Road.

Next.jsTypeScriptMongoDB+4
Refuse Collecting Bot Vision and Navigation Layer
In progress
Robotics2026

Refuse Collecting Bot Vision and Navigation Layer

The perception layer for an ongoing refuse collecting bot project. Since the bot has no onboard camera yet, the laptop camera feeds into a real time litter detection pipeline using a fine tuned model from Roboflow. This detects trash in the environment with segmentation masks rendered as live overlays. The robot's position is tracked in the same frame using a red marker on the bot. I isolate it via HSV masking and contour detection. Once both the robot position and litter positions are known in pixel space, the system calculates which piece of litter is nearest and emits a direction command: RIGHT, LEFT, UP, DOWN, or ARRIVED. Detection runs every 15 frames to keep latency manageable while drawing arrows from the robot to the nearest target and updating a live status overlay. The next step is closing the loop and piping those direction signals back to the bot's control layer.

PythonOpenCVRoboflow+3
Pray3 Refuse Collecting Bot Flutter App
In progress
Web2026

Pray3 Refuse Collecting Bot Flutter App

The control and navigation app for the refuse collecting robot, built in Flutter. Two modes: Autonomous and Manual. In autonomous mode, you open the app and take a top view picture of the environment with the robot in frame. The image is posted to a Next.js backend hosted on Vercel, which runs it through a Roboflow litter detection workflow detecting water sachets, bottles, and cans. It then returns annotated results back to the app. Distance measurement is handled without a depth sensor. An AA battery (50.5 mm standard length) is placed next to the robot in every picture and used as a known size reference point. The app calculates pixel to mm scale from the battery and uses it to estimate the distance between the bot and each detected item, so it can decide which one to target first. The app also integrates MPU6050 gyroscope data for turn angle estimation by integrating rotational rate over time to estimate how many degrees the bot has turned. The manual section gives full direct control with options for forward, pick, hold, drop, and directional commands. Backend is live at detect coral.vercel.app.

FlutterDartNext.js+4
WorldCall Real Time Global Communication
In progress
Web2026

WorldCall Real Time Global Communication

A real time video and voice calling app built around an interactive 3D globe UI. Users appear as live pins on the globe at their actual geolocation, with accurate day and night shading driven by real sun position calculations. Tap a pin to call. The globe is the interface. Includes a full browser based beat engine with genre specific generators for Afrobeats, Highlife, Dancehall, Reggae, and HipHop. Each produces authentic rhythmic patterns and an audio effects chain with reverb, chorus, distortion, echo, autotune, and more running entirely client side via the Web Audio API. Currently in active development. Video calling and audio effects pipeline are functional. Globe authentication via Google and real time presence are integrated. Beat engine and remaining call features are in progress.

Next.jsFirebaseThree.js+3
Forex War Room Multi Agent Debate Engine
Live
AI2026

Forex War Room Multi Agent Debate Engine

A multi agent AI system where three trader personas (Bull, Bear, and Sniper) autonomously debate a forex pair using real market data before a Commander agent fires a final BUY, SELL, or WAIT verdict. The system fetches 30 days of price history from Frankfurter API and calculates seven real technical indicators before any agent speaks: RSI(14), EMA(9/21) crossover, ATR(14), ICT premium and discount zones, 10 day swing highs and lows, 5 day momentum, and market structure (HH+HL vs LH+LL). News headlines are scraped live from ForexLive, FXStreet, and DailyFX then scored by an LLM, not keyword counting, so 'ECB holds rates' is understood as bearish for EUR, not just neutral. Each agent has a locked personality: Bull argues macro opportunity with George Soros energy, Bear counters with risk first Paul Tudor Jones discipline, Sniper ignores all macro and trades pure ICT structure. The debate is sequential with each agent reading what the previous ones said and responding directly. The Commander then reads the full transcript plus raw indicator data and applies a 6 point decision framework: structure, ICT zone, RSI, EMA, Sniper levels, and sentiment. Four signals aligned equals confident trade. Fewer than three equals genuine WAIT. Frontend streams the debate live via SSE with tokens arriving one by one per agent panel with a blinking cursor. A technical dashboard renders RSI as a radial dial, ICT zone as a range bar with a price cursor, EMA crossover badge, structure badge, and key levels. A timeline view shows the debate as a live chat feed. The Commander's verdict includes an entry trigger price and an invalidation level.

PythonFastAPIGroq+7
Self Balancing Robot Inverted Pendulum
In progress
Robotics2026

Self Balancing Robot Inverted Pendulum

A two wheeled self balancing robot built around an Arduino Nano and MPU6050 IMU. The core challenge was PID tuning since Kp, Ki, and Kd interact in ways that make blind adjustment almost impossible. The breakthrough came from two things: mounting the IMU at or just below the center of mass to eliminate mechanical noise from the sensor readings, and building a real time telemetry dashboard so the behavior is visible instead of guessed. The ESP8266 runs as a standalone WiFi hotspot. A Next.js dashboard connects to it over WebSocket and plots angle, motor output, and gyro rate live. If Kp is too low the angle chart shows it drifting. If Kd is too high the output chart shows it twitching. Tuning became a feedback loop instead of trial and error. The firmware uses a complementary filter fusing gyroscope and accelerometer data, a dynamic balance point calibrated on startup by holding the robot still for 1.5 seconds, per motor PWM boosting to compensate for physical asymmetry between the two drive sides, and an anti windup system that bleeds off the integral when the robot is near balance. This prevents the stored correction energy from firing as a lurch when direction changes are commanded.

Arduino NanoESP8266MPU6050+5
Ghana News AI Agent
In progress
AI2026

Ghana News AI Agent

An autonomous AI agent that scrapes major Ghanaian news sites daily, summarises headlines using an LLM, converts the summary into a voice audio briefing via ElevenLabs, and delivers a morning email digest with the audio attached. Built as a scheduled pipeline where the scraper feeds into the summariser, the summariser feeds into the voice generator, and output fires through email automatically every morning with zero manual input.

PythonGroqLLaMA 3.3 70B+3
Head Controlled RC Car
Live
Robotics2026

Head Controlled RC Car

Extended the MPU6050 head tracker into a full wireless RC car control system. Strapped the IMU to a helmet and applied a Kalman filter to fuse gyroscope and accelerometer data. This eliminated the drift and phantom movements that made raw gyro integration unusable for physical control. The filtered yaw angle maps directly to steering and pitch to throttle. ESP8266 on the transmitter side reads the sensor at 50Hz, runs the Kalman filter onboard, and fires packets over ESP NOW to a second ESP8266 on the car. The receiver ESP forwards motor commands over SoftwareSerial to an Arduino Uno which drives the L298N motor driver. Built a side by side browser visualization in Next.js showing two 3D head models receiving the same sensor data: one raw, one filtered. Live scrolling charts for pitch, roll, and yaw show the noise reduction in real time. Also added a web UI with a D pad and speed slider as a fallback controller. Turn head left, car turns left.

ESP8266ESP-NOWMPU6050+8
Healthcare Assistant MCP Server
Live
AI2026

Healthcare Assistant MCP Server

A Model Context Protocol (MCP) server exposing four clinical tools to any AI agent: patient demographics lookup, active medication retrieval, lab result analysis, and drug interaction checking. Built on FHIR R4 standards, the server fetches real patient data from FHIR compliant hospital systems and falls back to structured mock data when needed. Implements the SHARP extension spec for automatic patient context propagation. When a clinician has a patient file open in their EHR, the patient ID and FHIR credentials flow automatically into every tool call via HTTP headers without any manual input. The drug interaction checker catches dangerous combinations like Warfarin and Aspirin before they reach the patient. An AI agent connecting to this server autonomously chains tool calls: fetching medications then checking each one against a new drug. It does this without being explicitly programmed to do so. It reads the tool descriptions and figures out the sequence itself. Deployed via Docker on Render with SSE transport, registered on the Prompt Opinion healthcare AI marketplace where any compliant agent can discover and invoke the tools.

PythonFastMCPFHIR R4+5
Biblical Simulation Engine
Live
AI2025

Biblical Simulation Engine

A multi agent simulation engine inspired by MiroFish, a Chinese open source swarm intelligence system that went viral with 10k+ GitHub stars. The engine extracts character personalities directly from any raw text document, builds independent AI agents from those profiles, and simulates how those characters would interact around a given question or scenario. For the Bible demo, key scripture passages are fetched per character and fed to an extractor that derives personality traits, beliefs, speech style, inner conflicts, and relationships solely from the text evidence, not from the LLM's general knowledge. Each character becomes a fully independent agent with its own system prompt. Agents are genuinely unaware of each other's profiles. They only know what has been said in the shared conversation transcript, which is what produces emergent behavior nobody explicitly programmed. A final Report Agent watches the entire simulation and synthesizes the conversation into a structured insight: identifying the core tension, what each character represents, where they found common ground, and what the exchange reveals that no single perspective could. The engine is document agnostic. The Bible is the demo. Feed it a news article, a novel chapter, a historical speech, or any private document the LLM has never seen and it extracts whoever is in that text and simulates them.

PythonGroqLLaMA 3.3 70B+2
AI Agent Discord Bot
Archived
AI2025

AI Agent Discord Bot

A personal AI agent running on Discord, powered by Groq (LLaMA 3.3 70B) with a full function calling tool loop. The agent receives natural language messages and autonomously decides which tools to invoke. Weather lookups via OpenWeatherMap, live currency conversion across 170+ currencies including GHS, real time news digests via NewsAPI, web search via Tavily, and anime discovery via the Jikan/MyAnimeList API. Built with a clean multi layer architecture separating the agent loop, tool registry, Discord gateway, and conversation memory. The core loop keeps iterating: calling tools, feeding results back to the LLM, and chaining calls until the model produces a final answer. Per channel conversation memory persists across message turns within a session.

Node.jsDiscord.jsGroq SDK+5
Autonomous Job Search Agent
Live
AI2026

Autonomous Job Search Agent

A fully autonomous job search agent that runs every two hours without supervision. Searches government employment portals across Germany, Canada, Poland, Netherlands, New Zealand, and Japan for visa sponsored factory, farm, and manual labour positions. The German Federal Employment Agency API alone returns 90+ fresh listings per run. For each job found, the agent calls a CV matcher that scores the role against the applicant's background using an LLM. Jobs scoring above 60% proceed to cover letter generation: a tailored, human sounding letter written specifically for that role, company, and country. Jobs with apply emails receive the letter and CV automatically by email. Jobs without emails are logged to Firebase for manual form submission. Built as a separated MCP server and agent. The tools run as a standalone MCP server while the agent loop is a separate Python process that connects to it. Firebase Realtime Database serves as persistent memory, preventing duplicate applications across runs. A digest email arrives every morning summarising what was applied to overnight.

PythonFastMCPGroq+5
MPU6050 Head Tracker
Archived
Robotics2025

MPU6050 Head Tracker

A test project for tracking head orientation in real time using an MPU6050 IMU on an ESP8266. Mounted the sensor on a bottle cap to sit on the head. Firmware reads pitch, roll, and yaw at 50Hz. Gyro calibrates on startup, deadzone filters idle noise, and angles are integrated from gyro data. A Python bridge reads serial output and pushes live JSON over WebSocket to a Next.js frontend that renders a 3D head model in Three.js mirroring the movement. Wanted to see if the yaw angle alone was stable enough to use as a directional control signal. It is.

ESP8266MPU6050C++ / Arduino+4
Texasthumb Digital Election Platform
Live
Web2025

Texasthumb Digital Election Platform

End to end election management system built for organisations that want to run secure, transparent digital votes without the logistical overhead of paper ballots. The platform is split into two distinct surfaces: a sleek dark themed voter portal and a full featured admin control panel. On the admin side, election officers can upload an entire voter list from a standard Excel file in one step. The system parses the sheet client side, previews every row, flags duplicate student IDs in real time, hashes all passwords server side with bcrypt, and bulk inserts only clean records. Single voters can also be added manually through a form. Each voter can be individually enabled or disabled at any point, and admins can search, filter by department or status, and see a live department breakdown bar chart that updates as the voter list grows. Election lifecycle is controlled through a four state machine: Not Started, Active, Paused, and Closed. There's a dedicated Elections panel showing a pulsing live indicator, timestamp trail, real time turnout percentage, and a gradient progress bar. Admins can pause voting mid session to address issues, resume it, or close it permanently, all with a confirm dialog to prevent accidents. A full reset wipes all votes and voter statuses for a clean re run. The admin dashboard also features a live Voting Results chart with a Standings view (ranked aspirants per position with crown indicator and progress bars) and a Trend view (cumulative votes per hour as a multi line chart), both polling the database every 30 seconds. On the voter side, students visit the home URL and see a context aware screen: a countdown style holding page if the election hasn't started, a paused notice if it's temporarily halted, or a dark themed login card when voting is live. Authentication uses Student ID and password with a JWT session cookie valid for eight hours. Once in, voters navigate between positions using pill shaped tabs that turn green as each choice is confirmed. Votes save automatically on selection with a quiet 'Saved' indicator. No submit button required per position. Voters can freely change their selection on any position for as long as the election remains active.

Next.jsMongoDBFirebase Auth+5
Enva Church Outreach Tracker
Live
Web2025

Enva Church Outreach Tracker

Full stack evangelism tracking platform for church teams. Workers log GPS coordinates of every person they visit and pastors and admins monitor team activity in real time on a shared live map. Features a public landing page showing all visited locations interconnected with animated arcs, a real time group chat with WebRTC voice calls, per visit records with filtering, and role based access (Admin, Worker, User) with an approval flow.

Next.jsFirebaseMongoDB+3
Gob3 Affiliate Platform
Live
Web2024

Gob3 Affiliate Platform

Affiliate marketing platform where product owners list items and offer commissions. Affiliates copy product links, share them, and earn money directly to their mobile accounts when sales are made.

Next.jsPaystackMongoDB+2
Restaurant POS System
Archived
Web2025

Restaurant POS System

Full featured POS for restaurant management with role pages for hot kitchen, cold larder, and pastries. Supports facial and PIN login, real time order tracking via sockets, and an admin panel for taxes, discounts, tables, and sales reports.

Next.jsSocket.ioMySQL
RSS Feed Scraper and Dashboard
Live
Web2024

RSS Feed Scraper and Dashboard

Full stack app for managing and scraping RSS feeds. Go backend handles feed creation, scraping, and Firebase auth. Next.js frontend provides a dashboard to create, view, and follow feeds with real time updates.

GoLangMongoDBFirebase+1
TicketRoom
Live
Web2024

TicketRoom

Ticketing platform where users can sell and purchase event tickets. Sellers list tickets with event details and buyers browse and securely pay through Paystack.

Next.jsMongoDBPaystack
Collection Bowl
Live
Web2024

Collection Bowl

Donation platform where users create payment endpoints for receiving donations via mobile money and credit cards. Each endpoint generates a unique QR code. No donor account required.

Next.jsFirebaseMongoDB+1
NGO Fundraising Platform
Live
Web2023

NGO Fundraising Platform

Dynamic NGO platform enabling organizations to manage donations, create projects, and collect funds via Mobile Money. Provides transparency and efficiency in fundraising efforts.

Next.jsSupabaseMongoDB
FoodStore
Archived
Web2023

FoodStore

Web app for online food ordering from a local restaurant. Features menu browsing, cart management, and secure online ordering.

Next.jsMongoDBTailwindCSS
SpaceInfo
Live
Web2023

SpaceInfo

Web app using the NASA API to provide real time space data. Shows a map with your location and the ISS position, distance, and speed. Also displays astronauts aboard the ISS and lets users browse Mars rover images by Sol (Martian day).

Vue.jsNASA APITailwindCSS+1
BirdGame
Live
Web2022

BirdGame

Web based click game where players shoot ravens moving across the screen. Includes sound effects. Built entirely with vanilla JS.

HTMLCSSVanilla JS
AI Sermon Assistant
Live
AI2024

AI Sermon Assistant

Listens to live preaching and suggests relevant Bible verses in real time. Processes speech and displays full scripture references based on implicit and explicit cues from the preacher.

Next.jsGoogle Gemini API
AI Sentence Matching System
Live
AI2024

AI Sentence Matching System

Uses sentence embeddings to compare and match sentences based on semantic similarity. Provides a 2D visualization using UMAP for dimensionality reduction. Input sentences and instantly see how closely related they are.

Next.jsFastAPISentence Transformers+2
Hand Tracking Ball Burst
Archived
AI2023

Hand Tracking Ball Burst

On screen game using OpenCV to track hand movements via a camera in real time. Players burst randomly appearing balls by moving their hands over them. No controller needed.

PythonOpenCV
NLP Text Classification Suite
Live
AI2024

NLP Text Classification Suite

Multi domain text classification system built end to end. Fine tuned BERT and DistilBERT models achieving 90%+ accuracy across news categorisation (AG News), spam detection (SMS), and toxic content moderation (Jigsaw). Includes a modular preprocessing pipeline handling class imbalance and text normalisation. Models deployed to Hugging Face Hub.

PyTorchTransformersscikit learn+2
ASL Sign Language Recognition
Live
AI2024

ASL Sign Language Recognition

ASL sign language image classifier trained on Google Colab using a free T4 GPU. Improved accuracy from 60% (fully connected network) to 85% by switching to a CNN architecture on the same dataset. Documented real world domain shift limitations and deployed the final model to Hugging Face Hub for public inference.

PyTorchCNNsscikit learn+2
Crypto Market Clustering
Live
AI2024

Crypto Market Clustering

Applied K Means clustering to 10,422 cryptocurrencies to group coins by market behaviour, revealing four distinct clusters: BTC, USDT, altcoins, and outliers. This is useful for identifying true portfolio diversification. Used the elbow method to determine K=4, StandardScaler for normalisation across vastly different scales, and PCA for 2D visualisation of 11 dimensional data.

scikit learnpandasmatplotlib+2
Sound to RF Wireless Transmitter
Archived
Robotics2019

Sound to RF Wireless Transmitter

A purely analog wireless system with zero microcontrollers. A salvaged phone speaker acts as a microphone. Blowing air or making sound generates a signal that gets amplified by an op amp, modulated onto a 433 MHz RF transmitter, and received wirelessly to trigger an LED on the other end. Raw electronics, no firmware.

Op Amp433MHz RFAnalog Circuits+1
Device Tracker and Nearby Finder
Live
Web2024

Device Tracker and Nearby Finder

Flutter app for tracking devices and discovering nearby amenities. Users search for places like schools, restaurants, or hospitals, view them on a map, and adjust the search radius with a distance slider.

FlutterFirebaseMongoDB
TrackiMe v1
In progress
Web2024

TrackiMe v1

Flutter app for tracking and saving visited locations. Users can store routes and revisit them. Integrates Gemini API to provide historical information about the current location.

FlutterGoogle Gemini APIMongoDB+1