Mechanized Cheese Fedora
The fedora has been at the peak of fashion since the 1890's, but unfortunately its popularity since 2004 (and since the 1920's) has been dwindling. The fedora appears to be at a crossroads: adapt or die, and so I've created the mechanized cheese fedora hat. As the ultimate intersection between style and technology and natural evolution of cheese, fedoras, and fashion I expect billions of users by 2030.
This project is a 3D printed cheese slice mounted on a fedora. Inside is a battery, servo motor, and ESP32. The servo motor is controlled based on a webserver hosted on the ESP32. It allows the user to lift up and move down the mouse on top.
Supplies
- 3D printer with greater than 165 x 180 x 80 mm dimesions.
- Paints: light yellow, grey, dark grey, black, pink, tan
- ESP32
- 3 10 cm. male to female wires
- USB battery pack or equivalent
- Small USB micro B cable (to power the ESP) It's a tight fit! A right angle cable may help.
- Tape
- Double sided tape (preferably clear)
- Scissors
- Velcro with sticky side(can be substituted with double sided tape)
- Fedora (or a less fashionable hat)
Printing
I've printed each piece in white filament because it's the easiest to paint over. Only the "Cheesehat lift arm" won't be visible.
I designed the lift arm and platform entirely in Fusion360. The cheese was created in Fusion360, then the holes were created in blender using booleans. The mouse was created using the sculpting tools in blender.
The platform and lift arm can be printed without supports, the other two files need supports. For all the files I used .2 mm layer height with a .35 mm nozzle, 60 C bed temperature, 200 C extruder temperature, and 6% infill. The parts were sliced in simplify 3D and printed on a MakerGear M3-SE.
Painting
Feel free to get as creative as you'd like with color, but I prefer to avoid green cheese!
I painted the cheese and the top of the platform with a light yellow.
The mouse's fur is grey, its ears and nose are pink, its eyes are blue, its mouth is black, its eyebrows are dark grey, and its tail is tan.
Code
/* Created by Andrew Goldberg A webserver which produces a page where a servo motor is turned ninetry degrees up or down based on the button pressed on the webpage. http://yourAddress/H turns the motor up http://yourAddress/L turns it down This example is written for a network using WPA encryption. For WEP or WPA, change the Wifi.begin() call accordingly. Circuit: Servo motor control to D15 power to 3v3 ground to GND Parts of the code are based on the example called SimpleWiFiServer included with the ESP32. I've left the authors names here. created for arduino 25 Nov 2012 by Tom Igoe ported for sparkfun esp32 31.01.2017 by Jan Hendrik Berlin */ #include <WiFi.h> #include <ESP32Servo.h> Servo myservo; // create servo object to control a servo int pos = 0; // variable to store the servo position int servoPin = 15; //Corresponds to D15 const char* ssid = ""; //place your ssid between the "" const char* password = ""; //place your password between the "" WiFiServer server(80); void setup() { Serial.begin(115200); delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); server.begin(); //Servo stuff myservo.setPeriodHertz(50); // standard 50 hz servo myservo.attach(servoPin,500,2500); // attaches the servo on pin 15 to the servo object } void loop(){ WiFiClient client = server.available(); // listen for incoming clients if (client) { // if you get a client, Serial.println("New Client."); // print a message out the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); // the content of the HTTP response follows the header: client.print("<body style = 'background-color: black'>"); client.print("<div style = 'text-align: center;'><a href=\"/H\"> <button type = 'button' style = 'height: 45vh; width: 45vh; background-color: black; border: 5px solid #C0C0C0; border-radius: 100%;'> <p style = 'font-size:12vh; color: green'> △ <br> </p> </button> </a>"); client.print("<div style = 'height: 5vh'></div>");; client.print("<a href=\"/L\"> <button type = 'button' style = 'height: 45vh; width: 45vh; background-color: black; border: 5px solid #C0C0C0; border-radius: 100%;'> <p style = 'font-size:12vh; color: red'> ▽ <br> </p> </button> </a></div>"); // The HTTP response ends with another blank line: client.println(); // break out of the while loop: break; } else { // if you got a newline, then clear currentLine: currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } // Check to see if the client request was "GET /H" or "GET /L": if (currentLine.endsWith("GET /H")) { if (pos <= 0) { for (pos = 0; pos <= 90; pos += 1) { // goes from 0 degrees to 180 degrees // in steps of 1 degree myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } } } if (currentLine.endsWith("GET /L")) { if (pos >= 90) { for (pos = 90; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees myservo.write(pos); // tell servo to go to position in variable 'pos' delay(15); // waits 15ms for the servo to reach the position } // GET /L turns the LED off } } } } // close the connection: client.stop(); Serial.println("Client Disconnected."); } }
Uploading Code
Copy the code in the previous step to the Arduino IDE. Insert your ssid and password into the variables called ssid and password. This is necessary to connect to WIFI.
Next, install the ESP32 servo library under sketch > include > manage libraries > ESP32Servo (click install).
The code should now compile successfully. If it does upload it.
It's important to double check that the library is in your Arduino/libraries folder and that your tools>boards menu is set for the correct ESP.
Testing Code
Open the Serial monitor and run the code. The monitor will display the ip address of your board. If it doesn't do this it's possible that your baud rate is set incorrectly, it should be 115200. Type into a browser (preferably on your phone) the ip address. It should bring you to a website as seen in the picture. Next, wire the servo motor to the ESP32: GND to brown, D15 to orange, and 3v3 to red. When the up button on the website is pressed the servo should spin around 90 degrees. Pressing the down arrow will bring the servo back 90 degrees.
This will move the arm piece that raises and lowers the platform with the mouse.
Also, ensure the system works when plugged in to your battery.
Assembling
Use Elmer's glue to attach the servo addon to the lift arm.
Insert your USB battery into the cheese slot. Attach the USB micro B cable to the ESP32; then, insert the ESP32 pins up into the slot aligned with the battery. Next, insert the servo motor so the wires face upwards and wrap it into the the slot on the right of the servo. Use tape to keep the wires from sliding out of the cavity. After, attach 3 male to female wires to the servo wires. Then, attach those wires as follows: red to 3V3, orange to D15, and brown to GND. Finally, tape the wires on the wall low enough to avoid the platform and to avoid interfering with the lift arm.
Ensure the platform arm is installed at the correct angle by running the code and putting it in the up position. Then connect the arm slightly past perpendicular to the ground so it will give the platform the most height.
Attach the USB micro B cable to the battery's top USB port. Use tape to keep the wire down and to the side so it doesn't interfere with the platform or arm.
At this point the platform should be placed on top and the mechanism should work.
Next, cut double sided tape and stick it to the flat parts on the bottom of the mouse. Attach the mouse to the platform.
Finally, attach velcro on the bottom of the cheese and on the top of your hat.
Finish
Attach the hat to the cheese with the velcro.
Congrats! The hat should now work like the video! Be careful, it's high levels of fashionability may make it a target for jealous (and less fashionable) thieves.
Thank you for reading about my project! I hope you enjoyed it! Feel free to leave questions, comments, or suggestions and if you make it then I'd love to see!