Challenge: Sustainable Agriculture: Precision farming
Going outside to do chores, cleaning, feeding dogs, raking leaves, and clearing fire piles that attack small dogs is uncomfortable and annoyingly hot and dangerous in Texas summers. Working outdoors for extended periods can cause sunburn and heat stroke. I came up with AYSE because I wasn't expecting the 100-degree weather to get better soon. Abbreviation for Autonomous Yard Scooping Entity, the robot has the following functions:
- Four Wheels
- Arduino Uno with Motor Shield and Particle Photon
- Double-Jointed Arms
- Strong Reused Aluminum Scoop
- Magnetic Odometer Sensor Setup (built with Infineon 3D 2Go Magnetic Sensor)
- Single Command setting in the works
- Custom Library
- Scalability for different robot sizes
The dual gearbox allows independent control of the rear wheels. The aluminum scoop is made from fully recycled materials. The arm and bucket use four servos to precisely manipulate the object. Setting up the magnetic odometer sensor allows you to record the distance traveled and ultimately allows you to customize your commands. How to make a MOSS is in my profile as it is a separate project.
SoftwareThe current command library is small, but extensions are under development. Current methods include preset stick and bucket positions, four-way rotation and movement, and offline support for repetitive tasks. AYSE is also using Blynk right now because she wants to try something new, but I will consider other user interfaces in the future (control more than one AYSE at the same time?).
ControlAYSE uses the latest home security system to give users real-time control. Users can set up the camera system to watch AYSE and move around using the app. If the task is too repetitive, the robot starts recording the distance traveled by pressing a simple button. When the autonomous mode is activated, the rover will do the same until a stop command is received.
BuildingThe Chasis
The base is made from an old phone circuit board with components removed and wrapped with duct tape. I glued the solid foam blocks cut to shape with a heated foam cutter. If you want to build, follow this link. The block has a protruding "arm" that holds the MOX in place. Styrofoam blocks are cut to fit the phone's circuit board and are 1" thick. I assembled a double gearbox with a gear ratio of 38.2:1 under the board (don't worry, there are instructions in the box). Other dual gearboxes or configurations can be used if desired. Make sure the motor is a double gearbox so that it can be controlled independently. Now just add wheels and you're done!
The Arms
Take two chopsticks and two servos in each hand. I used a 9g servo for the ladle servo and a bigger servo for the arm itself. Glue the two chopsticks in a V-shape so the little servo can fit snugly inside. Make sure to hold the servo in place and add some hot glue. Don't forget to change the servo direction for each arm as it will point in the opposite direction. We'll also have to deal with this later in the code.
If you have both hands, attach the ends with hot glue to the large servo on the V end. Now attach the large servo that is the base of the arm to the center of the chassis with hot glue. Make sure they are pointing in the opposite direction (outside the chassis).
The Scoop
First, take some thick aluminum wire and make a scoop frame. This will prevent bending of the aluminum sheet for later use. Make a W-shape and leave an extra inch at the end. You can use extra wire to secure the back of the ladle. For the aluminum sheet covering the skeleton, take two soda cans and cut them up and down. Cut the remaining cylinder once from top to bottom to form a rectangle. Fold this rectangle in half, leaving about 1/4 inch on one side. This will allow you to bend this part yourself to hold the aluminum plate in place. Fully insert the frame into the gaps in the plate and use aluminum tape to seal the ends without additional length of wire. First, take some thick aluminum wire and make a scoop frame. This will prevent bending of the aluminum sheet for later use. Make a W-shape and leave an extra inch at the end. You can use extra wire to secure the back of the ladle. For the aluminum sheet covering the skeleton, take two soda cans and cut them up and down. Cut the remaining cylinder once from top to bottom to form a rectangle. Fold this rectangle in half, leaving about 1/4 inch on one side. This will allow you to bend this part yourself to hold the aluminum plate in place. Fully insert the frame into the gaps in the plate and use aluminum tape to seal the ends without additional length of wire.
Now make another aluminum plate and insert it sideways into the assembly with the gaps facing left and right. Don't try to insert a skeleton here. Plates pass under the frame inside another plate. Fold it so that there is an extra plate as much as the wire. Now fold another sheet of aluminum so that the two corners cover the sides, as in a commercial backhoe loader. You can also make a notch in the gap on the back of the scoop to secure it. Glue them and the back of the bucket to the assembly taking care not to leave holes for the servo vanes. Don't forget to seal the ladle by taping the corners with tape. Attach the ladle to both servo blades by tightening the screws and adding tape (screw to the servo first). Wheeled chassis with nice hands with buckets, but now you need a brain.
The MicrocontrollerFirst, attach the motor shield to the Arduino Uno. Then align analog pin 05 and digital pin 05 on the Arduino with the particle photon. The code takes PMW into account, so you need to use a digital pin. This will save us 6 jumpers. Connect the VIN and GND of the photon to the Uno 3 using a jumper. One of the 3v and GND pins. Screw the rotary knob to the Infineon 3D 2Go's magnetic pickup and hot glue the middle of the knob to the center of the wheel using the raised foam "arms" built into the chassis. Slightly cut the "arm" to secure the sensor board. On the Bucket Servo, use the needle to poke the data (yellow/white) and power (red) pins out of the connector housing. Now push it back to another position (data that had force and vice versa). This should be done so that the entire connector pin can be inserted into the orange motor shield servo pin. Solder some wires to the motor and connect the right motor to channel B and the left motor to channel A on the motor shield. Disconnect the red wire from the 7V Li-ion battery with a switch (so that it can be powered on and off) and connect the resulting wire to VIN and GND next to the motor channel. Connect the arm servos together. They act like one big servo. If you have unusual servo connectors or additional jumpers, use them. If not, use curly braces like I did to connect the 3 ports. So instead of 6 you only need 3 jumpers. Connect power to the 5V pin of the shield, GND to GND, and data to pin 10. For MOSS, connect. Connect the I2C wire from the Infineon sensor to the white TWI IN connector on the screen. SDA and SCL are in different places so don't confuse them. Now you have everything except the code. There are no sensors in the diagram because Fritzing didn't have them.
The CodeThe code consists of three parts: Photon, MOX and the Arduino Uno itself. Register with Blynk first. It's free and useful for app prototyping. Copy this and paste it into build.particle.io and flash it to Photon. This will allow you to control your Photon using the Blynk app. Replace the asterisk with your own verification code.
#include <blynk.h>
#define BLYNK_PRINT Serial
char auth[] = "*************************";
void setup()
{
// Debug console
Serial.begin(9600);
delay(5000); // Allow board to settle
Blynk.begin(auth);
}
void loop()
{
Blynk.run();
}
For MOSS, paste this code into your Infineon sensor. We'll add a link to our GitHub repository as soon as it's available. Change wheel diameter to wheel diameter to get accurate distance readings. This program records the number of turns and the direction of rotation and reports it to the master (UNO) via I2C.
/* Eduardo Pecina, Jr. June 6, 2018 */
#include <Tle493d_w2b6.h>
#include <Wire.h>
#include <I2C_Anything.h>
int WHEEL_DIAMETER = 1; //units here will determine units for distance
boolean hasBeenCounted;//prevents a large number of false positive revolutions in case the wheel stays at the same position
boolean hasBeenHalfway;//minimizes the amount of false positives if the wheel moves back accidentaly
int numOfRots;//number of times the wheel completed a full revolution
int rpm;//rotations per minute
int lastAngle;//last recorded angle in radians before measurement termination
int lastPart;//part that didn't count as a full rotation in the end
float disTrav;//distance in units of wheel's diameter
boolean isRecording = true;//user input
boolean isStopped = false;//user input
boolean isForwards;//checks to see if the wheel is going forwards and not backwards
Tle493d_w2b6 TSensor = Tle493d_w2b6();
void setup() {
Serial.begin(9600);
//starts sensor
TSensor.begin();
TSensor.setWakeUpThreshold(1,-1,1,-1,1,-1);
TSensor.disableTemp();
hasBeenCounted = false;
hasBeenHalfway = true;
Wire.begin(21);
}
void loop() {
Wire.beginTransmission (21);
I2C_writeAnything (disTrav);
Wire.endTransmission ();
TSensor.updateData();
if((TSensor.getAzimuth() > 0)&&(!hasBeenCounted)&&(hasBeenHalfway)){
TSensor.updateData();
numOfRots++;
hasBeenCounted = true;
hasBeenHalfway = false;
if(TSensor.getAzimuth() > 2){
isForwards = false;
}else{
isForwards = true;
}
Serial.println(numOfRots);
Serial.println(TSensor.getAzimuth());
}
if(TSensor.getAzimuth() < 0){
hasBeenCounted = false;
}
if((TSensor.getAzimuth() < 2)&&(TSensor.getAzimuth() > 0)){
hasBeenHalfway = true;
}
//records current position to calculate remaining distance travelled
//in case it didn't make a full rotation
lastAngle = TSensor.getAzimuth();
//this if statement prevents the last rotation from being counted twice
//in case the user stops right on the rotation boundary
if((lastAngle == PI)||(lastAngle == -PI)){
//the direction is important to calculate how much of the wheel has spun
//going forwards or backwards could be the difference between having spun
//1/4th of the way versus 3/4ths of the way, a lot on a large wheel
if(isForwards){
lastPart = (lastAngle+PI)/(2*PI);
}else{
lastPart = ((2*PI)-(lastAngle+PI)/(2*PI));
}
}
//calculates distance travelled in units of wheel's diameter
disTrav = ((numOfRots+lastPart) * (PI * WHEEL_DIAMETER));
}
For Arduino Uno, download ayseBase.ino from GitHub repository and upload it to Uno. I think the comment went well, but I'm posting again. All methods prior to Arduino's setup{} method will be placed in a future ah header file so that the main code is not too large. The setup method itself consists of setting the pinMode for the A05 pin (which is connected to the Photon if you remember) to INPUT and setting the output pin for the motor shield. We also connect the 3 servos (remember the big ones are tied together) and start communicating with the Serial and Wires for the slave sensors for debugging. The loop takes care of the rest. Note that changing the servo method (setScoopPos) actually moves the servos in additional pairs. This means that if one servo is at 80, it has to go up 100 so that the other servo is at the same height. This is fixed in setScoopPos by subtracting the given angle from 180 degrees for the second servo.
ResultWi-Fi allows you to autonomously control yard mowing objects via your mobile device. If your Wi-Fi signal is too weak, add an antenna to your Photon to increase your AYSE range. I currently consider this build "alpha". Because it's a bit small for the garden work I had in mind. In the future, we plan to add more powerful motors and servos and add wireless control to increase range. I'm currently working on using an ultrasonic sensor for mapping and additional autonomy, so this has been adjusted. Current software is built to scale irrespective of the size of the physical robot. In the future, AYSE could be used by governments to clean parks and further improve communities. For now, we hope to use AYSE to give consumers a window into the booming robotics and autonomous industries, to get away from their mundane routines and to improve and inspire their lives.
Comments