Week 7: Minimum Viable Product

Lol... NOT Crushing It


How to Apply Crushing Force?
Making a product that requires the application of brute force repeatedly can make designing machine very challenging. Originally, I had thought about having a robot arm that would hover over my mortar and it will be applying the up and down motion from above. However, this is difficult because the arm would need a lot of support and need significant amounts of power to exert force from up top.

After talking with Nathan, I realized a different way to think about this project is applying force from below. Instead of having a robot arm from up top, I can have a stepper motor from the base of the mortar and have it be connected to a lead screw with a nut. The stepper motor will rotate and the nut will rotate on the screw, but if there is something to stop the rotation of the nut, then instead of going up and down in a spiraling motion, it will be going vertically without any spirals.

In order for the nut to travel up, the stepper motor would have to turn in one direction. To travel down, it will have to turn in the opposite direction. Since the motion of crushing peanuts is fast and repetitive in nature, we can think about changing the direction of the motor every few seconds, and it will carry out up and down motions in a more reliable manner.

Therefore, the power of the pestle is actually coming from below the mortar. I was inspired by how the printers use a stepper motor and a lead screw to create an up and down motion. Below is a video recording of the 3D printer in the FAB Lab, and my goal is to emulate that. How a 3D printer does it is that they stop the rotation of the nut by having a guiding straight stick attached to it, so I will be doing the same.


Board Design:

I will be using an A4988 motor stepper. In order to use this stepper motor, I would need a stepper driver. I will need 1 large circuit, but it requires two power supplies, the logic power supply and also the power supply for the stepper motor, which needs more power than 5V. I ended up getting this block that I can plug into the outlet, and it supplies 12 volts. The logic power supply is just the 5V from my computer and is used by the microconctroller.

Circuit schematic
3D Design:

Once I have decided on my motor, I need to account for it in my 3D Design, so I measured its base, and made a slot for the stepper motor in the container I am making in Autodesk Fusion. The container is a cylinder with a really big lid on top. The cylinder, for now, has a hole in order to let the wires out. The lid is a big plate with a small hole in it. The hole is there to let the screw come through. The lid is wide to allow for the guiding stick to have a place to stand next to the lead screw.
3D Design of the container from Fusion
Container with a hole for the wires and a slot for the stepper motor currently printing
Logistically, the guiding stick will need to be situated off the plate or else it will get caught in with all the peanuts, but we will get there in 1-2 weeks.

Code to switch vertical direction:


This is the code:
  

const int stepPin = 13; const int dirPin = 12; unsigned long previousMillis; int interval = 5000; void setup() { // put your setup code here, to run once: pinMode(stepPin, OUTPUT); pinMode(dirPin, OUTPUT); digitalWrite(dirPin, LOW); } void loop() { unsigned long currentMillis = millis(); //high = ccw DOWN //low = cw UP //digitalWrite(dirPin, LOW); digitalWrite(stepPin, LOW); delay(1); digitalWrite(stepPin, HIGH); delay(1); if(currentMillis - previousMillis > interval) { previousMillis = millis(); if (digitalRead(dirPin) == LOW) { digitalWrite(dirPin, HIGH); } else { digitalWrite(dirPin, LOW); } }
Code for Switching Directions and Speed:
  

//For this code, I will be creating two classes: Button and //Zaxis. I want my mortar and pestle to have a few //different settings, but today, we will start with just //two. A low speed and a high speed setting. The low speed //setting is indicating when only button is pressed, and the //high speed setting is activated when both buttons are pressed. //As for the Zaxis class, the range of motion is greatly //inspired by how 3D printers use lead screws + nut to go up //and down. When it is the high speed setting, there //be a less of a delay in the stepper motor. When it is the //low speed setting, there will be a bigger delay in the step //sequence of the stepper motor. //Below is the class Button: int interval = 1000; class Button{ //Establish my member variables: int buttonPin; int buttonState; //Constructor public: Button(int pin){ buttonPin = pin; //This will let my microcontroller know //pin the button is connected to. pinMode(buttonPin, INPUT_PULLUP); buttonState = HIGH; //I am starting off saying that //e button is off, or not pressed. } int Update(){ buttonState = digitalRead(buttonPin); //I want to know //the on/off status of my buttons. return buttonState; } }; //Below is the class Zaxis: class Zaxis{ //Establish my member variables: int mstepPin; //Apparently, there are many ways to set my member variables. //https://stackoverflow.com/questions/10198046/c-member-variables //This site talks about the pro's and con's of three different methods, and I //chose the method below: //void A::setNumber(int number){mNumber = number;} //so that is why you see mstepPin and mdirPin and see it be set by stepPin and dirPin int //later in the constructor. int mdirPin; bool highspeed; bool lowspeed; unsigned long updateInterval; //I didn't know how to make it so that //if the pestle reached the mortar then it would go back up, //so for now, I am just putting in an interval, and telling //it to go up 1 second and down 1 second and repeat. unsigned long previousMillis; //to avoid delays, I am invoking millis. //Constructor public: Zaxis (int stepPin, int dirPin, long interval){ updateInterval = 1000; previousMillis = 0; mstepPin = stepPin; mdirPin = dirPin; pinMode(mstepPin, OUTPUT); pinMode(mdirPin, OUTPUT); highspeed = false; //I am putting my initial //bool values at false. At the very beginning lowspeed = false; // neither speed settings are being //indicated until a button is pressed. } void Quicker(bool value) { highspeed = value; } void Slower(bool value){ lowspeed = value; } void Open(int speed) { unsigned long currentMillis = millis(); if (speed > 0) { digitalWrite(mstepPin, LOW); delay(speed); digitalWrite(mstepPin, HIGH); delay(speed); } else{ digitalWrite(mstepPin, LOW); } //if the reached a second, the stepper motor will turn the other way if(currentMillis - previousMillis > interval) { previousMillis = millis(); if (digitalRead(mdirPin) == LOW) { digitalWrite(mdirPin, HIGH); } else { digitalWrite(mdirPin, LOW); } } } }; //Now that I have defined my classes, I can then use them: Button button1(5); //one button is connected to pin 5 Button button2(7); // one button is connected to pin 6 Zaxis pestle(13,12,1000); //stepPin is connected to pin 13, //dirPin is connected to pin 12 //interval is 1000 ms. int speed; void setup() { //I am using a serial monitor to see which buttons I have pressed } void loop () { // Serial.print("Button 1: "); // Serial.print(button1.Update()); // Serial.print(" Button 2: "); // Serial.println(button2.Update()); //below is the logic: if both buttons are pressed, high speed. //If only button 1 is pressed, low speed. //Anything else: either only button 2 is pressed, or none is pressed, //the speed settings are false. //In the next stage of this project, just button 2 is another speed setting. //I also need to find a way to make my stepper motor stop moving if(button1.Update() == LOW ){ //== LOW && button2.Update() == LOW){ // pestle.Slower(false); // pestle.Quicker(true); speed = 1; } else if(button2.Update() == LOW ){ //== LOW && button2.Update() == HIGH){ // pestle.Slower(true); // pestle.Quicker(false); speed = 10; } else{ // pestle.Slower(false); // pestle.Quicker(false); speed = 0; } pestle.Open(speed); }