For the final engineering project I wanted to get done with parts of my final fab project. My final fab project would be a working maestro camera, shown in a 3d model here: https://sketchfab.com/3d-models/evil-eye-rainbow-six-siege-84f762c42ade4eb68c0009a71c95ba2f. I want it do be as accurate as possible, so the final fab project will hopefully feature:
Openable translucent doors that hide the camera
Infinite rotation when looking horizontally
180 degrees of rotation when looking vertically
an easy to use interface on phone
low cost
After finishing as much as I could, I am safe to say that for the final project, an easy to use interface on phone and low cost are confirmed, as most of the things required for that have been completed now.
Here's the joystick working to move the motor. the motor is connected to one microcontroller, the server is hosted on another, and both receive a message from the computer. None of these are connected by anything but WiFi
End Writeup
The (un) finished project
Because of the fact that I am doing this for my fab academy final project too, I shot for the moon and landed among the stars. Of my final fab project, there are probably around eight different parts that have to come together to make it work. Thanks to the time I had in engineering, I had got three of those steps done. Those three steps I got done were: figuring out how i would communicate data between steppers and their control boards, figuring out how I would power the whole thing, and figuring out how to move the steppers.
Networking
I struggled with networking the most for this. My definition of successful networking for this project was to connect 2 esp32's together through a stable, low latency link accessible through phone. The only way to do that, that I knew from previous experience, was a website hosted on the microcontroller through WiFi. It essentially used the same technique as all servers do: youtube, google, twitter. It served a webpage, that then is interactive and would send data back to the website. In this case, the website was a simple joystick. This joystick, when moved, would send out a post request, a packet of data to both microcontrollers seperatly. Those microcontrollers would receive the packet, parse the data into just the values it sent, and then move the steppers accordingly.
Issues and Solutions in Networking
Working through this was very annoying, as some syntax was just unexplainably weird, for example, I used MDNS to be able to server the webpage through maestro.local instead of an Ip address like 172.168.4.1. Specifically, I used 2 functions from the built in MDNS.h library, I used MDNS.begin(maestro2) to make the webpage available through maestro2.local. The second function I used, MDNS. queryHost() would take in a MDNS name, and give the ip assigned to that name. The absolutely insane, weird part of this that I just could not wrap my head around was that MDNS.queryHost() did not take the way you access the webpage, maestro2.local, but rather the network name put in, maestro2. This is absolutely not how it should be, as all other functions inside the MDNS library I have tried take ONLY the maestro2.local.
This would not work
This code would work
When accessing through a web browser, this is the web address I would type in.
Another Issue that I ran into occurred on the second part of my networking journey, when I was trying to get camera output from a seeed esp32s3 sense. The issue here was that I can get the output easily, but if I want to have a joystick on the same webpage, I would have to track down where the seeed stored the HTML code that it sent. I spent a day looking through the file structure of the esp32 camera library, and I was unable to find even the slightest mention to any html, javascript or css. I fixed this by figuring out how the camera sent images to be displayed on the webpage I could not find. By examining the HTML code using inspect element, I was able to analyze the network and see that my webpage would send a request to maestro.local/stream, and it would return the next image to display. If I were to go further with this, I could get a joystick on the camera by creating my own camera server code, that would request an image from maestro.local/stream, then combine the joystick html code with that to have a joystick and camera stream on the same page.
All the settings the camera had, none of which I cared about as all I wanted was a joystick
Powering
Coinciding with my work on connecting, I also worked on figuring out how I would power the two devices. There were only 2 practical ways I thought of doing it by, the first was using only one power input for the entire camera. I thought I could do that by using a device called a slip ring, which allowed for a wire to rotate forever without ever being twisted. I would need that as I planned to make this as realistic to the game as possible, and in the game the base of it can spin around forever. The issue with this, is that slip rings are expensive, and I really like to be able to save costs on everything. I break down costs near the end of this portfolio. The second was going all battery powered, using multiple different batteries to power the two microcontrollers and steppers. While this seems like it would be expensive, I would consider myself of an expert in low cost, janky, battery powered devices. Coinciding with about the middle of this project also was black friday, where I was able to get a 3500mah 10amp max discharge rate cell for only $1.50 per. Adding on the cost of a mass produced charge discharge module, which I got 10 of from amazon a while back for 7$, means that I was able to get 1 amp of portable power embedded anywhere in the system for about 2$, and I plan on using 2 of them total.
The battery pack I used, combing a wholesale 18650 with a charge discharge module.
The holder I use on the bottom of the battery to allow it to stand up. I can modify the design to make it interlock with any other design I need it to.
Custom ESP32C3 Board
For this project, I decided to use my experimental esp32c3 dev board that I had just started to work on recently. I made the board because:
I wanted to
ESP32C3 boards really struggled to fit on breadboards
ESP32C3 boards were pretty big
making my own boards were cheaper
In total, I went through 4 different board designs before settling on the one I used in this project. The first design did not work, and I instantly scrapped it. The second design did work, but I used an external usb-c module instead of building in a port. The third design worked, however as it was my first take at a board with a usb c module built in, I forgot to make it breadboard compatible. The fourth design, the one I used passed all criteria. I designed it to be just wide enough where the chip sat, but thin out in an area to allow it to be fully breadboard compatible.
Steps to recreate:
As this project was not finished, im going to focus the steps to recreate on the networking and making the custom esp32 board.
To make the custom esp32 board, which i designed in kicad, you first need to open it in kicad, then export it in the correct manufactoring settings. the files for the board are here: https://drive.google.com/drive/folders/1ZgJqxibTQJItHr_KJXY_JQI7eJf0JXFl?usp=sharing. Once imported into kicad, I highly suggest having the plugin "Fabrication Toolkit" installed, if it is not already. This plugin allows for 1 click output of all production gerbers required to have this board made.
2. to make this board, you must have it professionally made, as the tolerances are too tight for milling machines. After using whatever method you are comfortable with, you also need to make sure you have the componets required. here is an image of all of the componets labeled with their value, but there are some too specific to just give a value.
The three specific componets are the voltage regulator, marked U3 in the photo, is this part of digikey https://www.digikey.com/en/products/detail/richtek-usa-inc/RT9080-33GJ5/6161634. it was chosen thanks to its small form factor, low cost, and ease of integration.
for the usb c connector, marked j5 on the image, I used the cheapest usb c connector with full data pins on digikey, found that his link here: https://www.digikey.com/en/products/detail/amphenol-cs-commercial-products/12402012E212A/13683192.
for the main module, the esp32-c3 chip itself, i used the wroom module, which integrates all required componets into a much smaller package than i could make by hand. The link to the specific module i used can be found here https://www.digikey.com/en/products/detail/espressif-systems/esp32-c3-wroom-02-h4/14553033, but there are different modules with the same dimensions and pinouts that feature more or less ram, and more or less heat resistance
for all the componets I just labled in the images, ensure you are getting size "1206" componets, as those are the sizes i designed for so that it would be hand solderable.
In soldering it, I found most of it was normal, except for the usb c connector, where the easiest way was to put solder paste in a line on the pins, and then just run a soldering iron with a very thin tip across, which would prefectly distrubite the solder. if there was a bridge somewhere on it, just run the soldering iron on it again and add flux if the solder stopping holding.
After finishing the board, next you would need to upload the code to it. I had a more complicated way that involved library's not installed by default on arduino, but changed it to make it all work as long as espressif's esp core was installed in the board manager.
to install the esp32 series onto arduino, navigate to the additional board manager URL's in preferences, and add in this line:
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
after adding it in, save and restart the arduino ide. now, once you go to the board manager, you should see esp32 by espressif systems. install those boards, and then restart arduino ide again. Now, to upload the code, you just need to select the right board and com port, which in this case would be a xiao esp32s3 sense for the code under the folder mainstepper and a esp32c3 dev module for the code under the folder basestepper, with all code being found in this google drive folder: https://drive.google.com/drive/folders/1qWTlmdx9qYpJWIbELlUyUNB31R6dxWSM?usp=sharing
Additionally, the custom esp board has no usb to jtag bridge other than the one built into the esp32c3, and therefore requires the setting "USB CDC On boot" to be set to "Enabled" under the tools section. If you dont turn this on, no serial output will work from this module. Once ensuring the settings are correct, simply press the upload button. and the servers will be started and able to connect with eachother.
Here is the bottom portion of the board, the blue text denotes the value of the 1206 size resistor or capacitor.
Costs Breakdown
As I made some changes to my project to account for cost, I would like to break down the costs here. Due to the fact that I build things at home too, I also applied those money saving measures here, and im proud of the result I got.
Adding up all of the costs, this project cost around 35$ to get over half of the materials for my fab academy final project.
Some notable things I would like to mention are my:
custom esp32-c3 module, which cost me about $3.25 for all of the parts, with the main reason of that being the esp32 chip was 2$, the usb c 0.50$, and the pcb about 0.50$ when using JLCPCB's global standard direct line shipping, which is essentially free but takes 13 days to get to you.
and the battery packs I would be using are custom built by me, consisting of a 18650 cell directly connected to a charge discharge module. As mentioned above, these are probably the highest energy density and cost form factor I could achieve, with second place going to non rechargeable AA batteries. Estimating by power consumption, A single charge of the battery could allow for 4 hours of continuous use, and that includes the steppers spinning at maximum speed the whole time.
Next Steps
The next steps to completing this in fab would probably be to design a custom esp32 c3 board, not meant for fitting in a breadboard, but meant for perfectly working in this exact use case, that being holding a stepper driver in a confined area. I also would need to design the 3d model of the camera, as I do not plan on taking the design linked below. I also need to remeber that one of my core objectives for this project was not spending alot on it, and keep that in mind in the 3d design, essentially making it as low density as possible as PLA will become a big cost once I get onto that step.
Daily Journal
Reviewing the gantt chart, I completed most of what I was planning on doing, with the exception of the 3d design, which I underestimated the time for, while at the same time accidentally scheduling myself to work over thanksgiving break, essentially elimintating a whole week. If I removed that one week that I could not of worked during, and removed the 3d design portion, then I would of done exactly what I set out to do.
Here are the two references I had going into this, I had the 3d design of the evil eye, which is what I want to make my thing as close as possible too, and a diy pan tilt camera, which is essentailly what the evil eye is, but much more barebone.
Here are the Pinouts for the two boards I am using, my personal board and the ESP32-S3 XIAO sense. Ignore the bad wiring, I tried a auto router plugin on kicad to see if it would work, and it did albeit poorly
Journal
11/19: I worked on figuring out how im going to power this, I want to use only one connector and with this high power its gotta be a barrel jack, I chose 12v at around 2.5A as the input, so that should be able to power everything. Im planning on using a voltage regulator for the power, as the microcontroller I have can take any input from 1.2 to 5.5 and regulate to 3.3v
11/20 I remembered that at home I had some 5-12 to 3.3v regulators, so im bringing those in tomorrow to use, aside from that I cleaned and checked what componets the lab had
12/2 Over the break, I succesfully figured out how to power the stepper, powered, it, and got it to spin. It spun using 5v at roughly half a amp (I think it was exactly .495A at 5.1V), so i can power around 3 steppers off 15w wall wart, and since Im aiming for 2 steppers and 2 microcontrollers, one for the steppers and one for the camera, so 15w should be enough for 7.5W for the steppers and 7.5W for the microcontrollers, while both would in reality be drawing close to 5w for the steppers and around 3w for the 2 microcontrollers, which will allow me to give more power to the steppers incase of low torque, which is a worry for this.
12/3 Today I worked on getting the stepper to be spun by a website, I thought it would be easy but latin's system of wifi means i have to essentially have the esp act as its own router while on campus, which really does not help with working with it, also the library that i use received a update recently that broke it, due to a dependency so now i had to go in and revert that update. I also was doing all this without serial on, as my custom board uses the esp32-c3 built in usb and not a external connector, which caused me to forget to turn on usb cdc on boot, causing it to not be able to use the usb during normal operation, but i got that working after changing one small setting
The wrong lines of code, they had _ret at the end which a dependency stopped using
The one setting I needed to turn on to have serial again, off by default.
12/4-5 These two days Ive continued to work on the website, which i got working to control 2 steppers at once, I also got the camera working, and now need to combine the two. I also worked on the design a bit at home, which is going to be simple right now then fleshed out during fab
Heres me blinking a led with my custom board
12/9-11
These days I worked on the code, I succesfully got a camera server working, and then also got it to communicate between 2 esp32s. A challenge that happened during this was the fact that my code is going to be used for other projects, and i used a library that isnt default to arduino, I rewrote (with the help of ai) the code to make it use the default wifi library instead of the library i used, the asynctcp
12/12-13
I have been working on 2 things at once, first was getting successful communication between the two chips, which is harder as i also switched wifi libraries i was using to allow for the code to be compiled with no additional library installs. The second thing i was doing was due to me getting fed up with my arduino compiling taking so long, so I started to work on a small program to compile on my home computer, send the binary's over to my laptop, and then upload from that. It isnt done yet, but this will greatly help me in everything once i start it.
12/16 I finally fixed the most annoying error I have ever seen that has the dumbest solution. So, my networking is set up where i host 2 servers on 2 esps, that use MDNS (multicast domain name system) to give them a text based way to get to them, instead of an ip. I have maestro.local and maestro2.local. In the image on the left below, networkname is the string "maestro2" and to access it i type in maestro2.local in my browser. It also has function, MDNS.queryHost that prints the ip of the entered mdns name. for the entire day, i tried while failing to connect the two over wifi, but then with one change i fixed it. the change was to instead of querying maestro2.local, i had to query maestro2. This does not make sense to me. Every thing else requires the .local, but when you are using that one function, using the .local doesnt throw an error, but rather always gives an undefined ip address (0.0.0.0).
The code I assumed would work.
The code that worked
The code to start up MDNS
When accessing through a web browser, the web address