Omocha: Spontaneous cat toy idea
After a week long vacation in Ishikawa with a ton of snow promising a solid winter this year and some snowboarding we returned home to our cat and I had that guilty concise with me.
We’ve left her for almost a week at home while enjoying ski resorts and local confectionery shops some 300 kilometers away so I decided to make something up for this.
Idea of making a remote-controlled robot to play with her came fairly quick, I knew I had some leftover components from my previous failed / unfinished projects so I decided to recycle them.
I had an esp8266 development board lying around, as well as some spare 1000mAh 3.7 batteries and boost converters for power delivery.
After trying to lay out components I came up with this design.

Two wheels and chassis with offset center of mass so it can move around instead of spinning around wheels axis. Hole at the bottom to place microUSB port for charging. Three pieces of chassis are sandwiched together with 4 x M4 screws.
I was still short of servos and some way to charge the battery, since unlike with my previous drone project I cannot take it out every time I need to charge it. Quick search on Amazon showed these FS90R continuous servos and TP4056 battery charging / protection circuit.

With those arrived it was the time to layout components and actually design the thing with all required dimensions. It took me few iterations to get the tolerances right but after 3rd print I got usable chassis.

I had to split chassis into two parts because of overhangs, but I probably could have gotten away with it, since all the overhanging surface would be hidden inside the toy.
Idea I had that chassis would be centered around motors axes and all the electronics would go below that into a bottom part providing for stability when moving around. It turned out however the motors were too powerful for such a small toy so it could easily go spinning if too much power was provided - but more on that later.
I have previously used Rust’s embedded-hal for esp8266 board, but since it has limited support for peripherals and I wanted to hack something together quickly I decided to explore MicroPython for this one.
MicroPython still requires substantial amount of space, around 600kb in my case which is way more than I used in my previous projects on stm32f103 board - which only used 35kb of 64kb flash storage. My dev board was equipped with 4MB - a clear overkill for the project.
But it has its benefits, all the peripherals work out of the box, including WiFi (which I needed for remote control) and you can connect to your board in live Python REPL session for interactive development.

Last part turned out to be problematic and soon I learned that USB-to-Serial processing circuit on my board has known problem hanging picocom, minicom, screen, putty and any other app I tried to use with it. It took me a bit of reading forums and trying to figure out what exactly does not work (flashing went fine), including swapping cables, host ports, etc. Luckily it came to me that I can use FTDI programmer to bypass internal USB-to-Serial converter and talk to esp chip directly over UART Tx/Rx pins.

My setup with FTDI programmer, using lab bench power supply. Red LED of FTDI programmer certainly adds to the mood.
With REPL and being able to transfer files I was finally able to setup my dev workflow. I decided to make a static app with rudimentary UI that will be hosted on the toy itself.
Server would export a single endpoint to set duty values for each motor and those duty values would be computed on the client side as part of UI loop.
# here p4 and p5 are pin number where servos are connected
# and duty values are set in range between 0 and 50
# corresponding to full throttle forward / backward
/set?p4=0&p5=0
For the UI I’ve initially tried to use UIL library, that I was familiar with from another project, but since I only needed a single widget - joystick to control it I soon realized that pulling 100kb+ of minified UIL code might be too much. I’ve implemented naive buffered read on my webserver with 4096 bytes buffer, but it took quite a bit of time to load UI every time. After a bit of searching I discovered JoyStick a JS library that provides joystick widget which is only about 3kb minified.

I mapped joystick axes which range in [-100, 100]
to values corresponding to duty sent to endpoint, where x
axis used to flip direction for turning left & right while y
axes actually sets moving speed (duty value). Controller is not feeling very responsive but I just wanted to get something ready quick for testing. Since controller logic running on a client I could do more easily iterate it later without need to flash the board every time I want to tweak it.
With wiring figured out and basic control logic implemented it was time to assemble toy and try to fire up motors while on battery. All the tests I’ve done before were looking good but I have been using lab-bench power supply for them.
Here is where I hit another issue, when I tried to control motors from Web UI they would start spinning then stop almost immediately. At first I thought battery might be lacking punch after all motors and mainboard were drawing about 800mAh when connected to power supply and battery was only rated up to 1A peak. But doing more tests and reading Arduino forums I suspected that board might be rebooting due to voltage drop introduced by servos when they power on. I had my boost converter set to 5v which should have been enough for both servos which were rated between 4.8 and 6v as well as esp’s on-board voltage regulator that required between 5 and 12v. But enabling servos likely triggered voltage drop below 5v - causing esp board to restart. Here I say luckily because I do not have oscilloscope and my multimeter did not register anything abnormal.
Changing output voltage of boost converter to 8v helped to mitigate microcontroller restart but it was too high to reliably power servos which likely would burn if used for long time with this voltage.
Unfortunately boost converter I had only had 4 different options for output voltage and there was no potentiometer to tune it, so I decided to try MT3608 which is a very common circuit with potentiometer that can fine tune voltage and rated up to 2A. When I hooked it up to the battery output however and connected load - voltage broke down and I couldn’t use it at all. Board would not power up and motors showed no signs of life. Then I realized that my battery protection had over-current safety as well, so when this new boost converter tried to pull more than 1A, safety would trigger cutting off battery - another miss.
Turned out spare boost converters I had lying around from another project were exactly right for this battery protection circuit. At the end I decided to get buck converter module to step down voltage for servos, making it somewhat weird design since usually you want to step down voltage for your microcontroller unit but mine dev board had on-board voltage regulator which was perfectly happy with 8v input.
With power delivery issue solved, here is final wiring diagram.
After figuring out power delivery issue it was finally time to put it all together and do the main test…
Well, cat was not impressed. Not sure if it was for sluggish controls or she was generally not in a mood to play at that moment.
Final design did not have a lot of idle time, it can discharge in about 6 hours due to high power draw of esp8266 running HTTP server, but I still had about an hour of play time which is plenty. I guess I could still call it success since I was able to recycle some components idly lying around as well as to learn quite a few things about electronics, especially battery powered circuits.
Update: After doing a few charge-discharge cycles I noticed another issue, when toy is simply lying around it can go into a state where battery is low and I cannot charge it back anymore. At first I thought something has happened to the battery, but in the end it turned out to be quite simple issue. TP4056 I used for charging determines charging current based on battery capacity and it was around 100mAh for my battery. However idle current draw of mainboard was about 150mah, and battery is not disconnected during charging. So it simply couldn’t provide enough current to charge the battery while the board is connected.
Again Arduino forums came to the rescue, in particular post from one gentleman about LiPo charger using TP4056 which suggested to use load-sharing circuit to disconnect mainboard during charging.
To implement it, I had to order a P-channel MOSFET, resistor and a diode. I ended up not using a diode since my version of TP4056 was looking a bit different than one in the post.
DMP1045 is P-channel MOSFET suggested in the post. With this modification I was able to make it behave and any time battery died - it was as simple as putting it to charge with microUSB cable.
Link to github repo with code and other materials: https://github.com/wg-romank/omocha