You are browsing as a guest. Sign up (or log in) to start making projects!

gauss

@gauss

Joined June 1st, 2026

  • 21Devlogs
  • 7Projects
  • 0Ships
  • 0Votes
Isn't this fun?
Open comments for this post

1h 58m 22s logged

First Drive

I checked the devboard for any last errors and connected it to the motors on the robot!

Final checks

I verified that the KineticBoard Leaf works when it’s powered by USB and by the 5000mAh Li-Ion battery. I did this by writing a simple program that toggles a GPIO pin, and used a multimeter to read the oscillating voltages. It worked!! :fastparrot:

Test Drive!

I already had firmware from the design stage, but it was written for a different motor driver so I decided to start from scratch. I created a basic motor drive “class” (structs/functions to go with the struct) in C and set up my CMake project in a way that I could add a demos folder later. Now that I had custom firmware for the TB6612FNG, I wired up each screw terminal pair to the M1 and M2 pins on each motor, and flipped the switch to see it drive perfectly! :yayayayayay:

It was really relieving to see everything work on first try, and I gained a huge confidence boost in my embedded programming skills.

Future Enhancements

The motors came with 6-pin connectors, and I should have included appropriate receivers for these connectors on the KineticBoard Leaf rather than just generic screw terminals. Currently, I have to connect the 6-pin connector to 6 jumper wires, which is quite the eyesore. :screaming-cat:

0
0
10
Open comments for this post

21m logged

Lab Visit + THE DEVBOARD WORKS NOW WOHOOO :fastparrot:

After inhaling a mole of lead-based solder fumes, I finally got the devboard to work!!! It’s my first ever PCB so I’m really stoked!!

I visited my friend’s lab at the university where he works and we were able to debug and fix the devboard in a few hours. Unfortunately, I remembered that I had to record the whole thing in lapse in the last 20 minutes, but I guess that’s just karma for taking 9 hours ( :oops: ) to hand solder/debug a PCB in my last devlog (yes ik i suck).

Issues

My previous attempt at soldering failed because I set the temperature of my hot air gun too low, and I overestimated surface tension’s effect on my hot plate. I used a high-res microscope at the lab and saw that most of the QFN components were only partially soldered. I could quite literally see a tiny gap between the two pads. Another thing I saw was some obvious bridging, which I quickly fixed with a soldering iron.

One of my biggest takeaways from the lab was that THE TYPE OF SOLDER FLUX MATTERS!!! I previously used some generic $14 flux from Amazon, but it was so bad that even some of the most powerful ultrasonic flux cleaners couldn’t get it off easily. It was also so thick that even the infrared lamp couldn’t get the RP2040 to stick down. My friend used (and recommended) water-soluble flux, which makes it easy to clean off without messy isopropyl alcohol.

I ended up salvaging the parts from my old PCB to build a new one from scratch. I learned how to solder QFP packages, 0603s, and even 0402s with an iron. In the end, a soldering iron is THE BEST way to guarantee that your components are soldered down, especially when verified with a microscope. I also learned how to solder using an infrared lamp and hot air (properly, this time).

Results???

Right as I finished soldering the last component, I connected it to my computer and held down bootselect….and IT WAS DETECTED AS A MASS STORAGE DEVICE!!! I was so excited at this time that I finally rekindled my motivation to keep building more of these PCBs (I was pretty close to giving up on PCB-related projects ngl). Anyway, right before leaving, I put it in the ultrasonic washer they have for PCBs (which is just a tiny container with water and ultrasonic waves being fired it at from all directions to take the flux off. I’m currently waiting until tomorrow for it to air dry, and then I’ll incorporate it in the robot!

0
0
7
Open comments for this post

2h 44m 4s logged

Concept and Initial Design

I brainstormed a mechanism to speed up the beyblade and designed one plate of the beyblade’s chassis in Fusion.

Background

In the Beyblade Burst anime series, Fafnir is a left-spinning top that is widely known for its ability to “steal spin” from its right-spinning opponents. It appears to magically increase its own angular speed with every hit and then outlast its opponent. However, in reality, this ends in more draws rather than wins. Additionally, the physical beyblade doesn’t gain a “sudden boost” of spin as depicted in the anime.

How Does it Work?

Think of two gears isolated from each other. One gear is spinning clockwise (CW) and the other isn’t spinning at all. If the two gears were put near each other to the point where the teeth interlock, then you would be able to see that the other previously stationary gear begins to spin in the other direction (counterclockwise, or CCW). In the Beyblade world, Fafnir is launched CCW with very little spin power, so it gains more spin whenever it is hit by a CW attack. The main principle here is that the two Beyblades are trying to reach the same angular speed whenever they are in contact, so if the CCW is slower than the CW one, the CW beyblade will transfer some of its spin over to the other beyblade to help reach a point of equilibrium. Unfortunately, what happens often in real life is that the two beyblades hit each other until they are spinning at the same speed, and then they both run out of spin at the same time.

Conservation of Angular Momentum

Angular momentum is defined as L = I * ω, where I represents the moment of inertia and ω represents the angular velocity. The conservation of angular momentum states that this quantity remains constant unless acted on by an external torque (ignore friction for now). This means that if the moment of inertia were to decrease, then the angular speed would have to increase in order to maintain a constant angular momentum. But how do we reduce the moment of inertia? Well, I won’t get too deep in the details, but an easy way to do so is to move the mass distribution closer to the beyblade’s center of gravity.

The Mechanism

I’ll keep four masses that are attached to neodymium magnets near the edge of the beyblade, and I’ll have a rotating wall with four pockets. The magnets on the edge will have the same polarity, and there will be another magnet (with opposite polarity) at the center of the beyblade’s energy layer that pulls the other ones in. Usually, the wall will prevent this attraction. However, if the wall is tilted such that the pockets are exposed, then the outer weights will instantly get pulled towards the center of the beyblade; hence, the moment of inertia of this system is lowered, and it will speed up to conserve angular momentum.

0
0
30
Open comments for this post

4h 8m 51s logged

Auth and Profiles

I added a proper authentication mechanism and the ability for users to view each others profiles, as well as edit their own!

Authentication

Users can create and log into their accounts. An OTP is sent to the user’s email during creation, and expires in 10 minutes. A password reset mechanism also exists and also uses OTPs.

Profiles

I added a profiles page that allows users to see each others profiles! For now, the profiles display the user’s name, role, event track, bio, avatar, and awards! A separate award_medal.php exists but it is only accessible to admins to give awards.

0
0
4
Open comments for this post

3h 13m logged

Setup

I set up my Hack Club Nest VM by installing MariaDB to hold relational data; Cloudflared to tunnel traffic from my domain to the server; and Nginx to host the web server itself.

Architecture

For whatever reason, I have an affinity towards older software, so I decided to use a PHP backend for this website. Usually, PHP is paired with an Apache web server, but I decided to use Nginx instead because it is non-blocking and even-driven, so it doesn’t use up as much memory (mainly cuz I only have 2 GB of RAM on the VM :pf: ).

I guess that makes this an LNMP stack? Idk.

Mail!

So I’m planning on having a password reset mechanism and automated email notifications, so I needed something more secure than PHP’s native mail() function. I chose to use PHPMailer with Brevo as the SMTP service provider because they offer a very generous free tier.

Stuff I Gotta Work On

  • The emails are going to my junk folder?
  • The emails are also getting wrapped in a really odd way
0
0
5
Open comments for this post

9h 42m 1s logged

Broken Devboard

So this was my first time ever soldering a PCB, and I didn’t go easy on myself especially considering I used 0402 footprints on a 4-layer double-sided layout. I had hoped that it would work after soldering all the parts but unfortunately, it did not.

Areas of Error

The front portion was soldered using a hot plate, and the back was soldered with a hot air gun. This was my first time using a hot air gun, so I had my dad (a former electronics hobbyist) help me out a little. Turns out we both couldn’t fix it. One potential error is that the back side wasn’t properly soldered because we ran the air gun at 220 degrees fahrenheit, wihch could have meant that the core of the gun was that hot but outside it could be 150 or something. Another thing that could have gone wrong is the ICs could have been overheated and cooked, or a tiny bridge on the RP2040 could have shorted the whole thing.

Next Steps and Debug

I asked a friend (a guy who has a PhD in computer/rf engineering) to help me debug the board, and he said he’ll be more than happy to in a few weeks. In the meantime, I guess I’ll just make a bunch of more projects!

0
0
4
Open comments for this post

3h 13m logged

SMD Soldering Attempt

The parts from LCSC and JLCPCB had arrived! This meant that I could finally build the final part of the robot: the KineticBoard controller (yk, the devboard with a motor driver on it?). It’s gonna be difficult because I have to solder both sides of the PCB, but so far I only soldered the first side. Some parts were misaligned but it looks mostly ok.

0
0
5
Open comments for this post

2h 27m 39s logged

Rebuilt the Robot

The new standoffs had finished 3D printing, so I could finally replace the faulty old ones. Since I had to tear the robot down anyway, I decided to fix the motor slant problem as well. The solution to the motor slant problem was relatively simple: some foam padding to lift the motors up to the horizontal. This solution not only worked perfectly, but also gave the robot a little bit of shock absorbance. After that, all I had to do was build the robot with the new standoffs, which was actually quite a chore because it’s hard to use a screwdriver at an angle.

0
0
5
Open comments for this post

55m logged

Standoff Redesign

The old standoffs had an issue because they weren’t properly threaded, which meant that there really wasn’t much aside from minimal friction that was holding the screws in place.

The Fix

I redesigned the standoffs by making them wider, thoroughly hollow, and exposed on one half. This allowed me to slide nuts and screws inside the standoffs, which will guarantee a perfect lock. Another issue that this redesign fixed was the blocked hole problem. Essentially, when I put a screw in a hole on the middle chassis, I couldn’t then use that same hole for another standoff to connect the other side. This solves that issue since a single screw on the middle chassis can now go through two standoffs at once, allowing me to connect both sides.

0
0
3
Open comments for this post

2h 14m 59s logged

Assembly Time!

Alas, the fun part officially begins! At the time of writing this, most of the parts I ordered online have arrived, with the exception of the custom PCB from JLC. The parts for the chassis just came out of the 3D printer an hour before I started my session, so I had enough parts to finally build the robot!

Challenges

Building the actual robot brought tiny errors that I had previously overlooked to light. For starters, the 2.5mm trough, while looking very aesthetic, caused the motors to tilt slightly upwards. Additionally, the custom 3D-printed standoffs didn’t really hold on to the M3 screws, so I’m just hoping gravity does its thing. I might have to hot glue them later if more issues arise out of this. Lastly, the motors come with female-to-female cables, but my KineticBoard Leaf expects female-to-male. I might add male headers to the next iteration of the KineticBoard Leaf.

0
0
8
Open comments for this post

2h 33m 19s logged

Quality-of-life Updates for the Chassis

I had used horseshoe-type straps previously in an RC Car design but those had a tendency to slide horizontally. With that in mind, I decided to use the motor’s 2 M3 screws to build a strap on each side of the chassis to lock the motors in place. I’ll still keep one horseshoe clamp for each motor in addition to this for stability purposes.

0
0
2
Open comments for this post

3h 34m 1s logged

Fixing the KineticBoard

Did you know that something as simple as a double-sided version of a Pi Pico can cost around $150 to manufacture from JLC? Yea, I didn’t either.

Silkscreen Redesigns!

I made some newer art to put as a silkscreen. I think what I had before was okay, but it seemed a bit sloppy.

GitHub submodule stuff

I updated the KineticBoard Repo and added it as a submodule to my main repository.

Capacitor Fix

From my last session, I ended with picking a capacitor that had a higher voltage rating since passing 12V through a 6.3V capacitor will definitely cause dielectric breakdown. My solution last time was to use an 25V electrolytic aluminum capacitor, which ended up being too big. To resolve the overlap, I just chose a different SMD Capacitor footprint—this time for a tantalum capacitor since they’re much smaller.

Inverted Screw Terminals

Apparently the screw terminals were inverted this whole time. I realized this since the arrows were pointing toward the terminals from the center of the board, rather from the outside (the arrows indicate the direction that the wire will enter). I fixed this by rotating each screw terminal by 180 but this just caused 19 DRC violations. Of course, I had to reroute all of the traces that were flipped, and of course I had made it so that fixing one trace blocks the other trace from passing through. I ended up solving this problem by dropping a via and routing the board through one of the 2 middle layers.

And it costs WHAT???

Yup. The board itself costs $7, but then JLCPCBA decided to ramp up the cost to $150 with a $50 setup fee, $30 “loading into the feeder” fee, and so on. I’m thinking of buying a hot plate to “solder” all of the SMD parts on the board at home, but some of my caps are 0402 and those things are genuinely microscopic.

0
0
7
Open comments for this post

4h 12m 1s logged

CAD Touch-ups

I had previously built a chassis for this robot before in Stasis, but I had never shipped it. Today, I looked at the BOM for the assembly and saw that the metal standoffs that hold the layers together cost more than $2 per piece. I avoided this fee by modeling my own plastic standoffs that had M3 holes on both ends. I also updated the wheels to fit better with the chassis and use less filament. Unfortunately, this increased the mass moment of inertia of the wheels so stopping them and getting them to start might be a future issue? (I hope not tho plsplspls).

You have a devboard too? Whatttt

Yep! At Stasis, I also made a devboard known as the KineticBoard for this robot. This wasn’t shipped either. Since the devboard was almost complete, I decided to start looking up how to use JLCPCB and realized that I had yet another BOM to fill. Yayyyy🫠. I spent a solid hour figuring JLC out and also saw that one of my capacitor footprints needs to be updated because they don’t make 100uF capacitors in a size that’s expected of the 22pF ones (oopsie). Unfortunately, doing so resulted in another issue which is that the new capacitor is colliding with the motor driver, so fixing that is gonna be a lot of fun 🫠🫠🫠🫠. Anyway that’s a task for tomorrow.

0
0
10
Open comments for this post

1h 12m 38s logged

Dual-motor…drive?

I added a second motor and added support for turning in the Pico’s firmware. The main challenge in this session was figuring out how the robot will turn. Since the entire purpose of the Pico is to be the Pi’s personal uber driver, it should have the ability to process almost every command on its own without reliance on the Pi. To put it simply, the Pi won’t say “hey, turn one motor this way and the other one in the opposite direction to create a torque to make the robot spin,”; instead, it will simply say something like “turn this way!” and the Pi will figure out the angle in which it should turn and it will internally compute how it should control the motors. The new command structure is now 2 bits for direction + 2 dummy bits + 4 control bits. Having the 2 bits for direction allows for 4 possible outputs. Since my histogram from the algorithm used intervals of 45 degrees, having 4 of those 45 degree chunks is enough to cover a 180 degree arc. With turning support in both the left and right direction using the command nibbles 0xD and 0xE, respectively, it is possible to complete a full rotation.

INFINITE RECURSIONNNNNN

Since the robot is supposed to only rotate for a little bit and then resume moving in whatever direction it was going in, I implemented this by using a recursive call to the control function itself and passing in the value of the old command as the new command to execute. This recursive behavior was only meant for turns, not straight movement. As you could guess from the header, this resulted in the program calling itself over and over if I did two turns (since the last command was a turn and it’s last command, by my stupid function call, is also a turn). I patched this by making the program only recall straight moves and not turns, that way it would never have a old_cmd encoding for another turn.

0
0
28
Open comments for this post

28m 27s logged

It’s running on the Pi!

I used a docker container to allow the web app to be easily hosted on a Raspberry Pi 4. Docker provided a somewhat seamless transition from my local linux environment to the Pi, but I still had to cross compile it for the ARM64 architecture and had to modify a few things

Andddd of course I got stuck somewhere in the middle

So web apps in docker apparently dont use localhost, instead, they use 0.0.0.0 and expose their port at runtime. This made it quite complicated, because the JavaScript needed to call its websocket from…itself (but on the browser end aka localhost), whereas the Python server would serve 0.0.0.0, which would be then connected to localhost by the daemon. This took me some time to realize, and it was more annoying to recompile the image every time I wanted to make a subtle change.

0
0
13
Open comments for this post

3h 33m 15s logged

Hardware Setup + Communication Interfaces drive me crazy

Before you look at the time and freak out, I ran into like a dozen errors and each could have been caused by at least ten different independent variables 😭.

What did you do?

Anyway, I set up a Raspberry Pi 4 (the thing I’m also currently using for my website, www.StatixLabs.org) and a Pi Pico. I soldered the pins on a DRV8833 motor driver module and connected it to the Pico. I then created 2 UART lines from the Pi to the Pi Pico, allowing them to communicate serially. I then attached a mini N20 motor (with encoders) to the Pico’s motor driver, but this will change when I get the funding to buy motors that can actually sustain the weight of the robot. I then created a command structure in which the Pi transmits a single byte of data to control the motor. The structure of the packet (well, at least I think it’s a packet?) is 4 bits for speed + 4 bits for command. On the regular Pi, I created a script that accepted user input in the form command,speed in which speed was a normalized float, being optional for the command stop which assumes a speed of 0. Commands like forward and backward transmit 0x?A and 0x?B, respectively, and the ? is just a placeholder for the speed nibble.

Sooooo, why three and a half hours?

Great question! It took me a solid hour to figure out how to use the motors with the Pi Pico. This is because I initially had one of the Undercity themed Pico Devboards, and I thought they were really cool so I didn’t wanna mistakenly ruin the design because of my lousy soldering. So, I just decided to use header pins and sandwiched the devboard in between the header pins and the breadboard. It partially worked, but it was unreliable for the entire right half of the board. I ended up having to use one of my Pico 2’s that I had already soldered, and I also had to change the CMake to account for this. I was extra confused because UART communication worked perfectly fine with my previous sandwich approach, but simple PWM motor control didn’t. Oh well, at least everything worked out in the end after the switch 🫠.

0
0
29
Open comments for this post

2h 26m 39s logged

Added Web UI

Since the robot is targeted towards a more non-technical audience, I decided that a web interface is much better than a pygame window. This will also be a key part in a “ship” since it’s meant to be “published” and you can’t really publish a pygame script that first of all isn’t even a game lol. I learned how WebSockets work and I made a copy of the graphing script but stripped away the pygame API and added a web server to it. Some challenges I ran into were synchronization, so I solved it by creating a different thread in which the LiDAR runs and sends its data to a buffer, while the main thread runs the web server and sends the buffered data.

0
0
43
Open comments for this post

2h 32m 51s logged

Rework + Better Navigation

I decided to rewrite the entire pygame display since whoever wrote it before did it totally backwards and it had caused my algorithms to break and a bunch of other problems. So after that pygame refresher, I also reworked my algorithm because tuning the linear max offset seemed to be too unreliable for a broad range of environments and using something like a reciprocal function would make the algorithm amplify noise because my lidar often picks up random particles that are super close to it’s surface (I tried wiping it with a dry cloth; it didn’t work). Anyway, the new algorithm turns the unit circle into a histogram of angles and then calculates the average distance in each interval to determine which direction is the furthest away. The algorithm then picks that direction since it is the best direction that the robot can move in for autonomous navigation (you know, finding new areas?). Anyway, this algorithm is still pretty elementary but it worked first try (well, technically second because of an optimization).

0
0
21
Open comments for this post

1h 40m 2s logged

Basic Navigation Algorithm

I implemented a naive navigation algorithm for the robot. the algorithm uses an obstacle avoidance strategy. So far, it uses a linear transform that pushes the robot away from nearby items. However, I noticed that IRL, the LiDAR doesn’t feel the push in the opposite direction until the obstacle gets too close. I’m planning on fixing this later by using an inversion function or something rather than just subtraction.

0
0
8
Open comments for this post

1h 33m 45s logged

I created a basic scanner by using an RPLiDAR library from a YouTube Video. I adjusted the script for my LiDAR type and fixed a few bugs in the code such as angular positioning inversions. I also started working on the readjustment logic in which the frame is held still when the robot turns by rotating every point on the frame in the opposite direction that it is turning in. I also improved the color logic by using an actual gradient-based shader.

0
0
11
Loading more…

Followers

Loading…