Drawing bot¶
One of our ideas was implementing the two motors to draw. Using the motors to control the pen to move around on a canvas we can draw lines, shapes and other things.
Spirobot¶
We originally encountered a small robot named Spirobot, which had several versions but was essentially a robot that drove around with a pencil, much like what was a possibility on the Little Endian.
Expanding on the idea we wanted to look into creating a robot specifically designed for drawing using the two stepper motors. This meant that we could have more liberty with the drawing blocks on the frontend, and more precision with what exactly we drew.
Moving the pen¶
To move the pen using two stepper motors we can employ three strategies, achieving either a cartesian system where you have two coordinates that describe an x and a y location, or a polar coordinate system where you have an angle (usually called θ, theta) and a length to get a coordinate.
- Translating both rotations into an x and y coordinate to move the pen
- Translating one of the rotations into an x coordinate and using the polar coordinate of the other motor to move the pen
- Having both axes use polar coordinates to move the pen
We argued about these three possibilities and decided to use the cartesian coordinate system. The main appeal of this system is how easy it is to understand the underlying mechanics. x-axis moves the pen left and right, y-axis moves the pen up and down. This is not an advantage you get with the polar systems.
Dual axes polar system¶
Presenting these ideas to the client we instead decided to use the polar system. The cartesian system had the disadvantage of being rather complex in terms of hardware and requiring unique parts. The polar system is much simpler in hardware, however requires more calculations to deal with the weird behaviour encountered when two polar coordinates are combined.
Another big reason was cost. A proper leadscrew is a lot more expensive than we would prefer, and this contradicts one of our core ideas: it must be cheap to produce, and we want to be able to give away the final products to get kids excited for tech.
Another thing that came up was another concept that we didn’t quite grasp in earlier meetings. The product to be able to be made by the kids themselves, with a variety of different materials. This meant that the cartesian system was out of the window, and the fully polar system was the idea we stuck with.
Mechanical design¶
A two axes polar system uses two rotary movements to get to all coordinates. There are different ways to do this. One of those ways would be to combine the different motions into one motion. This idea can be seen in this video.
This has quite a few moving parts however, and the canvas reach isn’t that great, and limited by the size of both the discs. It makes little intuitive sense how exactly movements combine.
Another way we could use the two rotations was to have one rotation spin the drawing arm, and another spin the canvas. This can be seen in this video:
We ended up choosing this way to do things due to the simplicity that this allows.
Sidenote: both concepts can be combined to create some really interesting patterns from very little actual coding. These stepper motors are running at a constant speed. This is not ideal for our purposes though, because it only complicated the design.
Design¶
After choosing a mechanical idea of what our design would look like, we started planning our prototype. We made some sketches and based our initial dimensions on those. We modelled a
link to the 3D design documentation
Code¶
Initially the firmware of the prototype was a separate file on its own. The code below allows one of the stepper to run for and backward, this will move the pen holder across the disk, and make lines.
void loop(){
if (stepper2.distanceToGo() == 0)
stepper2.moveTo(-stepper2.currentPosition());// reverse rotation
stepper1.run();//rotate the motor
stepper2.run();//rotate the motor
}
}
to give the user more freedom and control we decided to use the old code from the previous team and added our touch to it, this method allows one of the motors to run constantly in one direction and the other one to run for and backward. at the end of the method we set all pins to low so the motors won’t get heated
void draw(int target) {
_stepper1.move(-target);
_stepper2.move(target / 7);
steps1 = _stepper1.distanceToGo();
steps2 = _stepper2.distanceToGo();
while (steps2 != 0) {
steps1 = _stepper1.distanceToGo();
steps2 = -_stepper2.distanceToGo();
_stepper1.setSpeed(stepperSpeed);
_stepper2.setSpeed(stepperSpeed);
_stepper1.runSpeedToPosition();
_stepper2.runSpeedToPosition();
delay(1);
}
_stepper1.move(-target);
_stepper2.move(-target / 7);
steps1 = _stepper1.distanceToGo();
steps2 = _stepper2.distanceToGo();
while (steps2 != 0) {
steps1 = _stepper1.distanceToGo();
steps2 = -_stepper2.distanceToGo();
_stepper1.setSpeed(stepperSpeed);
_stepper2.setSpeed(stepperSpeed);
_stepper1.runSpeedToPosition();
_stepper2.runSpeedToPosition();
delay(1);
}
setPinsLow();
};
this function is our solution to stop the stepper motors to get heated, it sets all the pins to low and which will save some energy and make sure that the motors will not get heated.
giving more freedom to user to draw by coding was one of the points that the points that was mentioned by the client that is why we decided to add two extra functions to control the disk and the pen holder. here under are code snippets of the functions we have added.
this function is responsible for turning the disk of the draw bot by running the stepper motor few steps to a specific position given by the user as parameter.
void halveCircle(int target) {
_stepper1.move(-target / 6);
steps1 = _stepper1.distanceToGo();
while (steps1 != 0) {
steps1 = _stepper1.distanceToGo();
_stepper1.setSpeed(stepperSpeed);
_stepper1.runSpeedToPosition();
delay(1);
}
setPinsLow();
}
and this is the method which is responsible to move the pen holder left or right, also by running the stepper motor few steps to specific position given by the user as parameter.
void movePen(int target) {
_stepper2.move(-target / 6);
steps2 = _stepper2.distanceToGo();
while (steps2 != 0) {
steps2 = _stepper2.distanceToGo();
_stepper2.setSpeed(stepperSpeed);
_stepper2.runSpeedToPosition();
delay(1);
}
setPinsLow();
}