Wednesday, April 14, 2021

Hacking the DJI mini 2 to add active payload control

 I hacked my DJI mini 2 to build a payload dropper that I can control from the Fly App. Here's the video:



Friday, February 5, 2021

Simulating Hoot Owl Hoot! in Python to find the best strategy

 Here's a board game simulation I wrote in Python to work out which strategy is the best to win the kid's game Hoot Owl Hoot!

My 5-year-old loves to play this board game made by Peaceable Kingdom where the players work cooperatively to move the owls along a path to the nest before running out of time. 

We were all playing one day and ended up debating on what the best strategy is to win - do you always move the piece that can go the farthest, or do you always move the piece in the back? It didn't seem like a clear answer at first - there are several game pieces and one moves on each turn to a color space chosen from the shuffled deck of cards, but they can jump over other pieces if there is one occupying the space they would otherwise land on. I thought it was best to move the one in the back so as to not strand one far behind the others (and therefore maximize the chance of getting to jump over spaces), while my wife thought you should always figure out which piece can go the farthest and move that one. 


Not satisfied with just not knowing the answer, I wrote a Python script that simulates the game. In this script only four owls are used (the way we usually play) and it doesn't bother including the sun chip - for my purposes it was sufficient to just see which strategy won in the fewest moves. 

The game is fairly simple to simulate - I made an array that holds the actual colors on the path which I copied from the game board, and there is an array of owl positions on that path. 


Each turn, a random color value is chosen and then some simple logic can move an owl forward to the next matching color while also checking for owls occupying the space that it could jump over and checking if it has reached the nest:


I wrote functions that would be used to evaluate the potential moves for each strategy by simply finding the rearmost owl:


and finding the longest potential move:


With those it was easy to make functions that would simulate an entire game played strictly by each strategy, and to make it really fair I had them both run simultaneously from the same random card deck sequence:


This got wrapped up in the main program that is run in a terminal and lets you choose the number of iterations to run and then gives the statistics on the result:


It turns out that the two strategies are remarkably close, despite leading to very different games each time, but if you run it through very many iterations, the longest move strategy tends to be best most of the time:



Here's the code. It's a bit messy with some nearly-duplicate functions since I built it up layer-by-layer and included a lot of stuff earlier on to print out the whole game board and detail each move to make sure the algorithms were correct before just running them without printouts to collect the statistics. 

Thursday, January 14, 2021

Friday, January 8, 2021

Hacking and upgrading a 3Doodler 3D pen

 



I recently received a 3Doodler 3D pen after only using cheapo $20 no-name 3D pens for several years (like this one). While the mechanical design on this one is nice, it had a few issues that left me not wanting to use it in its stock form:
  • used 3mm filament instead of the 1.75mm that my printers use
  • used switch presses as stop and start commands instead of momentary (hold to extrude, release to stop)
  • slow extrude was not slow enough (not their fault, I always want a slower extrude to better do detail work)
  • annoying behavior of the cooling fan (just runs along with the extrude regardless of temperature)
I decided to tear it apart and implement several upgrades to fix it:
  • closed-loop feedback control on the extrude speed to achieve slower speeds and better consistency
  • add temperature monitoring of the cold end of the extruder to more effectively use the cooling fan
  • change the power input to USB-C
These changes required some hardware updates and a complete rewrite of the firmware. First I worked on switching the filament size to 1.75mm. I was lucky enough to have the dimensions of common brass M3 threaded inserts work out to act as spacers on top of the existing extruder gears that grip the filament. I had to add the serrations to grip the filament by forming a screw into a cutter by cutting an axial slot in it, and spinning it against the inserts:

The spacers needed a small amount of trimming on the ends, and then I press-fit them onto the existing drive gears. I also cut down a short section of teflon tube (the kind used for Bowden extruders with 2mm ID) and pressed it into the cold end of the extruder to avoid the plastic building up there. The teflon tube is just visible at the bottom of this picture:

Those two changes were sufficient to mechanically convert the system to 1.75mm, but I also decided added some sections of tubing further upstream to better center the filament before it reaches the extruder. 

After the filament size conversion I worked on the speed control upgrade. Initially I tried to add rotation speed measurement to the bevel gear on the output of the motor gearbox, by drilling a hole and adding a 2mm magnet, and mounting a hall effect sensor above it on the PCB:

In the end I had to abandon this implementation since the rotation period was too slow to effectively implement feedback control. It took up to about 7 seconds for a revolution at the lower speeds so the control loop was too slow to be useful. To fix it, I set up rotation rate measurement further upstream in the gear train by finding a spot to add a very small magnet, which I cut and shaped using sandpaper from a larger magnet. In this particular gear train there happened to be a spot I could fit it on the third gear which spins roughly 40 times faster than the output shaft. I ground down the gear slightly to make a flat mounting spot and attached it with both CA glue and then epoxy:

I could then check the placement with a hall effect sensor and see how close I had to be to detect it. The camera frame rate happened to sync up with the motor speed here:
I mounted the hall effect sensor to the brass plates of the gearbox with CA glue, and it fit entirely within the envelope of the gearbox, so I didn't have to make any changes to the plastic frame that the motor fits into:

This new setup gave rotation measurement periods in the range of 50-200ms which was much more usable to close the feedback loop on extruder speed. 

The cooling fan upgrade was much simpler, I just installed a thermistor on the cold end of the extruder to monitor its temperature. This is an 0603 thermistor wrapped with kapton and mounted to the cold end with CA glue:

With all the hardware updates done it was time to do firmware, starting with reverse-engineering the control board. The stock microcontroller was an unlabelled 16-pin SOIC part:

Along with the microcontroller, the board has a FET and gate drive transistor for the heater, a FET and flyback diode for the fan, a motor driver (the SOIC-8 package), an RGB LED, and all associated passives. I took measurements on the microcontroller pins while operating the pen and came up with this list of pin functions:
1: VCC 5.05V
2: pulled low if switch is back (off)
3: pulled low if switch is forward (ABS mode)
4: icsp, not used in circuit
5: heater pwm 1khz active high
6: 2.5V reference for adc 
7: rear switch
8: fan pwm 200Hz 20% duty
9: extruder active low (high = backward)
10: red led active low
11: green led active low 
12: blue led active low
13: extruder forwards active high 600Hz 50% fast 20% slow
14: front switch
15: hot end temperature. lower=hotter. pla = 1.51V, abs = 1.24V
16: ground

With all those identified I could safely remove the stock microcontroller and install a new one. I chose to use the PIC16F1579 in a QFN package, and mounted it upside-down in the middle of the old uC pads with CA glue:


 I wired up the new microcontroller, using 34AWG enameled magnet wire. I also added a small chunk of PCB to hold the pull-down resistor and capacitor used to read the added thermistor, as well as a piece of a PCB to act as a programming port:


With that the hardware changes were complete and I moved on to firmware. For the initial work I set up a temporary UART debugging output so I could watch values for hotend temperature and extruder speed in order to tune those control loops. I ended up getting decent results for both using PD control loops, although the way I implemented it also has a sort of half-assed integral term since the P and D term results get added to the current duty cycle instead of calculating a new duty cycle every loop. After all the hardware and the two control loops (extruder speed and hotend temperature) were working, I figured out the new UI I wanted. Here it is as I wrote it before coding the state machine that runs the UI:
        /*switch on: rise to temperature
once up at temp, allow extruder movement
front switch is momentary forward extrude
short retract after forward movement
click rear switch shifts between 3 speeds
hold rear switch backs out filament until released
safety timeout 3 minutes
broken thermistor detection*/ 

The final source code is uploaded here: https://github.com/tterev3/3D_pen

In the course of finalizing the firmware I ended up wanting to fully reassemble the pen but still be able to reprogram, so I added a new programming port (this time just a flat PCB onto which I press a pogo pin programming header). The pen had this useful port on the side with a removable cover, which wasn't used for anything in the stock product, so I added the port there and could fully reassemble it:

Around this time I also decided to add one last hardware upgrade and swap out the barrel jack for a USB-C jack, which required a bit of trimming of the rear cover:


Here's a demo of how the pen works now after finishing my new firmware:

After all these changes I'm quite happy with this pen now - it's much nicer hardware to use than the cheapo pens, can do lower extrude speed, and can be run from a power bank since it's now 5V USB-C powered.