Firmware
Order Handler:
Here is our Github repo
We wrote an order handler class that runs on the ESP8266 and is responsible for getting orders from the API and sending them via serial to the Arduino. The order handler works by sending a get request to our API to get the latest order in the queue. If an order is found, the handler sends the order over serial to the Arduino, and waits until it receives a message back from the arduino that the order has been completed.
We wrote the order handler using platformio to manage libraries and compiling. We used the ESPAsyncWebServer-esphome library to send get requests and the ArduinoJson library to handle parsing the json payload from the api. The bulk of the order class that handles getting and sending orders can be viewed here: Github repo.
There are 4 methods in this class. The connectWifi connects the ESP to the Olin devices wifi. One problem we have with the current implementation of this function is that the passwords are stored in the code rather than passed in from a configuration file that is hidden. The getOrder sends a get request to our API at https://cupnoodle-api.herokuapp.com/order to get the latest order as json data. Next, the json data is parsed using the parseOrder method. This stores the mode, flavor, and toppings of the order. The mode of an order is included to differentiate when a customer wants to manually control the machine versus having the machine create it for you. We did not end up implementing manual controls. Lastly, after the data has been parsed the order is sent by printing to serial using the sendOrder method.
Noodle Controller:
Here is our Github repo
The noodle controller is responsible for receiving orders and fulfilling them using our machine. The controller features a step motor class for controlling our gantry as well as a chef class for integrating all of our subsystems to create an order. We wrote the noodle controller using platformio to manage libraries and compiling. Full source code can be found here.
Steps of an order:
- Our gantry system first calibrates by traveling to three corners of the gantry to find the maximums and minimums.
- Upon receiving an order, the gantry then travels to the correct flavor of ramen, stops below the dispenser, and a motor spins a spiral of wire for a set time to dispense a cup noodle. The wire pushes the cup forward so it falls in our holder, which then travels up towards our hot water dispenser.
- The holder pushes the cup into the sharpened straw so that hot water can be dispensed into the ramen. A stepper motor turns a valve which allows hot water to fall through the straw. After a period of time, the stepper motor closes the valve and the cup holder drops down to the bottom of the vending machine so the customer can obtain their order when they are ready.
The code for our step motor class can be viewed here. We used the popular AccelStepper library to interact directly with our stepper motors. The main methods to highlight in this class are the calibrate and goToB methods. After the stepper motors have been attached and set up with speeds and acceleration, the calibrate method can be called. This moves the gantry to the left and right until a limit switch is activated, which defines the x range of the gantry. It then moves the gantry up until another limit switch is hit, setting our maximum y range. After this method has been called, the goToB method can be used. This method takes in an x percentage and y percentage. These percentages represent what percentage of the total range for x and y to move the gantry to. For example, calling goToB(50, 50) will send the gantry to the center of our machine. One note is that goToB is a blocking method that does not allow other processes to happen while it is running. This was by design, as we want our processes to occur in a specific order.
Our Chef class was written using the ArduinoJson and Adafruit_MotorShield libraries and the code can be viewed here. The main method in this class is the make method. This method takes in a flavor and a JsonArray of toppings, and makes that specific order. We did not end up implementing the toppings in our final iteration. The make method calls a helper method called getFlavor. Given a flavor, getFlavor sends the gantry to a specific position corresponding to that flavor. Next, the DC motor in that position is turned on for a set amount of time. The gantry is then sent back to position (50, 0). After getting a given flavor, the make method calls getWater. This method moves the gantry upwards, puncturing the cup noodle with our water injection tool. Next, the stepper motor that is on the kettle valve is turned to position 300 in order to open it, and after a delay of 2300 ms the motor is turned back to position 0. Ideally, we would have a way to calibrate the kettle valve motor, but currently we must ensure that its starting position is closed. Lastly, the make method sends the gantry to position (50, 0) and the machine is delayed to allow the customer to pick up their cup noodles.