I've been interested in research and building a robot for a long time. I've loved space ever since a young age and consider myself a big space nerd, and I've wanted to get into robotics/become an engineer ever since I was young, but only now have I really "locked in". I don't know if that's too much exposition, but basically I want to make a rover capable of enhancing Martian soil by aerating, adding nutrients, and collecting samples for analysis. Couple of things though:
-I'm in senior year of high school, and haven't taken anything past Calculus 2 or Basic Physics, both of which I just took over the summer, and passed easily.
-I have no real prior coding experience, only a bit with Python (variables, if/true statements), but I have a lot of time on my hands and am willing to dedicate hours each day to learn it.
-I also have next to no experience building robots. Like zero, I literally just learned what an Arduino is.
-I do have past research experience and have worked on other types of research (chemistry, physics) and thus both have decent connections and some innate curiosity/dedication. Also, my dad has a lot of experience in agriculture and can help me at least design and put together the robot.
-I'm definitely not rich or anything but I'm willing to invest around $500 into this project.
-I just want a working prototype within around 1-2 months. Of course, I plan to add onto it as I both gain more experience in researching, coding, and designing.
I also want to get this into Regeneron, but that seems ambitious even for me. Please, any tips, resources, recommendations, literally anything would help! I can answer any further questions as well, but hopefully this post gives you enough of an idea for my idea, if that makes sense.
Starting from nothing, with no coding or mechanical or electrical engineering background, plan on a year or two of hard work. There is a truly phenomenal amount of material to cover and learn.
You can buy 2wd, 4wd or tracked robot kits with basic beginner code, which would be a good place to start learning how to program vehicle movement and navigation. As you progress, add sensors, design/build/test sampling equipment, etc.
Don't be taken in by the popular "NPK" soil sensors on the hobby market. They are completely fraudulent.
I am sorry to say I feel you are not quite ready to start the project at this point. We have no real idea of your skill set or what resources you have available to you. I would suggest you start with some of the tutorials that are on line, sorry to say some are not so good but many are very good. Start by learning and building the basics, you will need to control outputs as well as interpret inputs such as reading a switch, receiving a message etc. Start with the LED, they are not expensive and there is even one on most of the Arduinos. At this point you should have also found several tutorials on basic electronics that you have gone through. You should acquire a copy of the Arduino Cookbook and go through that. I have no clue as to how fast you will learn this but it will probably take a few months.
So he's no doubt familiar with skid steering/differential steering where such as on a zero turn mower. That's what you'll be starting with, since car-type (Ackermann) steering is far too complex and unnecessary for your build.
You'll need to select two identical motors with identical drive systems (gearboxes or chain drives).
I have used Peg Perego ride on toy motors since they come with the gearboxes attached and the wheels fit over top very easily. Then just use castor(s) of an appropriate size at the front and or rear for stability, available inexpensively from your local farming supply house or GOOD hardware store (probably not the big box retailer).
This will give you a bot about the size of a desktop PC case with wheels on it (in fact, my first one used a mid-sized PC chassis tipped on its size and customized to purpose with exactly the drive system I described).
Funnily enough, motor controllers made by Dimension Engineering keep coming up in posts here over the last week or so, and I heartily recommend the Sabertooth line.
Specifically, while it may be pricey, you need something that can drive over real terrain if you want to sample soil. By the way, $500 is a little low in this economy.
Don't fool around, use the 2x60 and you'll have options to spare, whether you choose a tele-operated (RC control - again, not toy grade, think RC aircraft hobby type) or Arduino packetized serial motor control. The 2x60 is reliable and I can say that mine haven't failed me once in even 250lb+ bots pulling wagons or driving up steep hills (currently installed in an electric wheelchair based bot), with something like 5-10 years worth of use.
And since this code is already making the rounds, here's some starter code for a Sabertooth, tested and working as expected. Code improvements and suggestions courtesy of fellow forum member, @alto777 . By the way, The Arduino Mega is a great choice over the Uno, might as well grab those extra hardware serial ports and such now.
/*********** Powerwheels Sabertooth Altonate Version *********************
NOTE: Fun revision. Identical to Powerwheels Sabertooth
by revised to use code suggestions of Arduino
Forum guru, Alto777.
Tested on equipment described below, working well
as expected.
!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!
!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!
!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!
THIS CODE WILL ALLOW OVERRIDING OF KID'S RIDE ON TOYS
SUCH AS THOSE MADE BY POWERWHEELS AND PEG PEREGO
IT IS UNTESTED CODE IN ACTUAL RIDE ON WITH RIDER.
USE AT YOUR OWN RISK!
DO NOT, I MEAN DO NOT USE ON RIDE ON TOY WITH ANY
RIDER UNTIL IT HAS BEEN CALIBRATED AND THOROUGHLY
TESTED TO THE SATISFACTION OF A COMPETENT ADULT
CARE PROVIDER FOR THE RIDER IF THE RIDER IS NOT AN
ADULT.
THIS CODE CONTAINS NO EMERGENCY OVERRIDE AND THE TOY
SHOULD ONLY BE OPERATED WITHIN THE REACH OF A
COMPETENT ADULT CARE PROVIDER WHERE A MECHANICALLY
OPERATED EMERGENCY STOP OVERRIDE DEVICE HAS BEEN INSTALLED,
EFFECTIVELY REMOVING ALL BATTERY POWER TO THE MOTORS.
END OF IMPORTANT NOTE
--------- INSTRUCTIONS TO BUILDER ------------
Requires changes to code depending on your hardware
if using two position button type pedal, activate
the line
pinMode(sensorPin, INPUT_PULLUP);
by uncommenting it.
if using typical potentiometer, leave that line
commented out.
Also, in function void checkSpeedPot(){}
have a read through and there's some stuff to set there
Defaults to testing (printing data to PC over Serial)
and assumes pushbutton type "all-or-nothing"
throttle input. These can be adjusted according to
the notes above and the comments found throughout
this sketch.
Also, select the instance of Sabertooth class that suits you
(default is for Arduino Mega or other with Serial1 UART)
The circuit:
- potentiomenter to analog input 0
OR if you use a switch type pedal
- switch pin A0 to GND
- forward switch to D3
- reverse switch to D4
- LED on digital pin 13 to ground
- view values in Serial monitor, 9600 baud
- Arduino TX to Sabertooth S1 (Uno) if selected
- Arduino RX to Sabertooth S2 (Uno) if selected
DEFAULT:
- Arduino TX1 to Sabertooth S1 (Mega)
- Arduino RX1 to Sabertooth S2 (Mega)
Tested with 2 x Razor E300 scooter brushed motors @12V, no load
and seems to be working as expected.
Test motor specs:
MY1016-B 24V 350W 2750 RPM electric scooter motor
Sabertooth DIP switch settings for this Packetized Serial Mode:
- 1: D for Packetized Serial address 128
- 2: D
- 3: D for LiPo, U for all other chemistries (battery cutoff switch)
- 4: U for 9600 baud, reverse this for 19200 baud: baud select pin 1 U for autobaud
- 5: U for 9600 baud, reverse this for 19200 baud: baud select pin 2
- 6: U for Standard Simplified Serial
by Hallowed31
2024-07-27
Library copyright Dimension Engineering, 2012
"Copyright (c) 2012 Dimension Engineering LLC
See license.txt for license details."
*/
#include <Sabertooth.h>
// add a library
#include <ezButton.h>
/* choose your version, normal or Mega. Use one only.
(or roll your own changing 2nd argument in the Sabertooth instance) */
// use line below for Uno Serial on pins 0 and 1
Sabertooth ST = Sabertooth(128); // address 128
// use line below for Mega, Leonardo, any with a Serial1
// Sabertooth ST = Sabertooth(128, Serial1); // address 128, port Serial1
const int maximum = 1017; // throttle max as calibrated with analogRead();
const int minimum = 13; // throttle min as calibrated with analogRead();
const byte speedPot = A0;
const byte heartbeatLED = 13;
const byte backwardSwitch = 3;
const byte forwardSwitch = 4;
// make some buttons
ezButton aForwardButton(forwardSwitch);
ezButton aBackwardButton(backwardSwitch);
enum { REVERSE = -1,
NEUTRAL = 0,
FORWARD = 1
};
int directionFlag = NEUTRAL;
int speed = 0;
int m1 = 0; // signal to motor 1
int m2 = 0; // signal to motor 2
unsigned long heartbeatTime;
unsigned long checkSSpeedPotTime;
void setup() {
Serial.begin(9600);
Serial1.begin(9600); // if you got a compile error here, you don't have one of these
SabertoothTXPinSerial.begin(9600);
Sabertooth::autobaud(SabertoothTXPinSerial);
// the line below is for a button type pedal
// comment this out if using potentiometer
pinMode(speedPot, INPUT_PULLUP);
pinMode(forwardSwitch, INPUT_PULLUP);
pinMode(backwardSwitch, INPUT_PULLUP);
pinMode(heartbeatLED, OUTPUT);
// set the debounce time
aForwardButton.setDebounceTime(25);
aBackwardButton.setDebounceTime(25);
}
void loop() {
checkSwitches();
if (millis() - heartbeatTime >= 500ul) { //500ms
heartbeatTime = millis();
digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
}
if (millis() - checkSSpeedPotTime >= 100ul) { //100ms
checkSSpeedPotTime = millis();
checkSpeedPot();
}
/************************************************
Other non blocking code goes here.
That means no while(), no delay();
*************************************************/
}
void checkSwitches() {
aForwardButton.loop();
aBackwardButton.loop();
// forward switch
if (aForwardButton.isPressed()) directionFlag = FORWARD;
if (aForwardButton.isReleased()) directionFlag = NEUTRAL;
// backward switch
if (aBackwardButton.isPressed()) directionFlag = REVERSE;
if (aBackwardButton.isReleased()) directionFlag = NEUTRAL;
}
void checkSpeedPot() {
speed = analogRead(speedPot);
// uncomment for testing, comment out for final install
// printRawData();
/* IMPORTANT - use only ONE of these speed = map(etc) functions at at time */
// for potentiometer type throttle
speed = (map(speed, minimum, maximum, 0, 1023)) / 8; //for speed 0 to ±127
// for pushbutton type throttle, map is reversed because INPUT_PULLUP
// speed = (map(speed, minimum, maximum, 1023, 0)) / 8; //for speed 0 to ±127
// uncomment for testing, comment out for final install
// printMappedData();
speed = constrain(speed, 0, 127); //for speed 0 to ±127
speed = directionFlag * speed;
m1 = speed;
m2 = speed;
// uncomment for testing, comment out for final install
// printFinalDriveSignal();
ST.motor(1, m1); // motor 1, speed cast to m1
ST.motor(2, m2); // motor 2, speed cast to m2
}
void printRawData() {
Serial.print("Throttle Input: ");
Serial.print(speed);
Serial.print(" ");
}
void printMappedData() {
Serial.print("Throttle Mapped To: ");
Serial.print(speed);
Serial.print(" ");
}
void printFinalDriveSignal() {
Serial.print(" Final Drive Signal M1: ");
Serial.print(m1);
Serial.print(" Final Drive Signal M2: ");
Serial.println(m2);
Serial.println();
}