HI i am in a high school robotics class and we had to make a 3 kg sumobot for a major project. So i went all out on this i have 2 560 oz-in gear motors 85 rpm 12 volt. but i am running them at 20 volts so it is more like 135 rpm and 800-900 oz-in, it will push over 13 pounds!! anyway my code is very glitchy it sometimes doesnt ping the sensors fast enough and sometimes it just cant find the other robot. so i hope you guys can help with this. i am using a ultrasonic sensor on the front and a sensor on the bottom to find the edge. here is my code.
#include "DualMC33926MotorShield.h"
DualMC33926MotorShield md;
#include <NewPing.h>
#define TRIGGER_PIN 30 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 32 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 130 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
int sensorVal1; //used to store the value from analogRead
#define sensor1 A4 //sensor pin connected to analog input 4
void setup()
{
delay (4700);
Serial.begin(115200);
md.init();
pinMode(sensor1, INPUT); //set as input so we can perform a read on the pin
}
void loop()
{
delay(30); // Wait 30ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
Serial.print("Ping: ");
Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
Serial.println("cm");
digitalWrite(sensor1, HIGH); //set it high to produce an output signal
//it seems weird because the sensor is an input device
sensorVal1 = analogRead(sensor1); //save the value from the analog read into sensorVal
Serial.println(sensorVal1); //display sensorVal
//delay(60); not sure if i need this
if (sensorVal1< 50){
md.setM1Speed(-400);
md.setM2Speed(-400);
delay(1000);
md.setM1Speed(400);
md.setM2Speed(-400);
delay (3500);
}
if (uS / US_ROUNDTRIP_CM <1){
md.setM1Speed(300);
md.setM2Speed(-300);
delay(2000);
}
if ( uS / US_ROUNDTRIP_CM > 1) {
for (int i = 0; i <= 400; i++)
{
md.setM1Speed(i);
md.setM2Speed(i);
if (abs(i)%200 == 100)
{
}
delay(1.5);
}
}
}
There's a lot of delay in that code. When you call delay, you effectively put the arduino to sleep for that length of time. It can't respond to sensors. It can't make decisions. It can't find other robots. It can't do anything but sit there like a brick until that delay is over.
Have a look at the infamous Blink Without Delay example to see how you can write non-blocking code to do these things. Then you will be able to read the ping sensor every few milliseconds and shouldn't have any trouble finding the other bot.
ok i thought you needed the delay for when you needed to do something for a period of time like here
if (sensorVal1< 50){
md.setM1Speed(-400);
md.setM2Speed(-400);
delay(1000);
in that code i am having the bot go backwards for 1 second so it has space to turn around, but now i do see what you mean because it is not looking for robots during this period of time, so it is glitchy, now i just need some help fixing it like the blink without delay example.
Have you had a look at that example? The concept is simple. Record the time you start doing something. On each pass through the loop, check that against the current time to see if it is time to do something else.
ok im still a newbie with coding so please correct me if this is wrong.
#include "DualMC33926MotorShield.h"
DualMC33926MotorShield md;
#include <NewPing.h>
#define TRIGGER_PIN 30 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 32 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 130 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
int sensorVal1; //used to store the value from analogRead
#define sensor1 A4 //sensor pin connected to analog input 4
const int ledPin = 13; // the number of the LED pin
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
long interval = 1000; // interval at which to blink (milliseconds)
void setup()
{
delay (4700);
Serial.begin(115200);
md.init();
pinMode(sensor1, INPUT); //set as input so we can perform a read on the pin
}
void loop()
{
delay(30); // Wait 30ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
Serial.print("Ping: ");
Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
Serial.println("cm");
digitalWrite(sensor1, HIGH); //set it high to produce an output signal
//it seems weird because the sensor is an input device
sensorVal1 = analogRead(sensor1); //save the value from the analog read into sensorVal
Serial.println(sensorVal1); //display sensorVal
//delay(60); not sure if i need this
if (sensorVal1< 50){
md.setM1Speed(-400);
md.setM2Speed(-400);
delay(1000);
md.setM1Speed(400);
md.setM2Speed(-400);
delay (3500);
}
if (uS / US_ROUNDTRIP_CM <1){
md.setM1Speed(300);
md.setM2Speed(-300);
delay(2000);
}
if ( uS / US_ROUNDTRIP_CM > 1) {
for (int i = 0; i <= 400; i++)
{
md.setM1Speed(i);
md.setM2Speed(i);
if (abs(i)%200 == 100)
{
}
delay(1.5);
}
}
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
ok so with this part i just added, i dont need to put any delays into the main code, im new to this and this is the first thing i am coding so im still trying to catch onto where you need and dont need delays especially with the sensors.
i added the part with the blink without delay but i am not totally sure what it does do i need the delays now because i thought you need them to tell the sensors when to ping is this closer to what i need
#include "DualMC33926MotorShield.h"
DualMC33926MotorShield md;
#include <NewPing.h>
#define TRIGGER_PIN 30 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 32 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 130 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
int sensorVal1; //used to store the value from analogRead
#define sensor1 A4 //sensor pin connected to analog input 4
const int ledPin = 13; // the number of the LED pin
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
long interval = 1000; // interval at which to blink (milliseconds)
void setup()
{
delay (4700);
Serial.begin(115200);
md.init();
pinMode(sensor1, INPUT); //set as input so we can perform a read on the pin
}
void loop()
{
delay(30); // Wait 30ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
Serial.print("Ping: ");
Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)
Serial.println("cm");
digitalWrite(sensor1, HIGH); //set it high to produce an output signal
//it seems weird because the sensor is an input device
sensorVal1 = analogRead(sensor1); //save the value from the analog read into sensorVal
Serial.println(sensorVal1); //display sensorVal
delay(60);
if (sensorVal1< 50){
md.setM1Speed(-400);
md.setM2Speed(-400);
md.setM1Speed(400);
md.setM2Speed(-400);
}
if (uS / US_ROUNDTRIP_CM <1){
md.setM1Speed(300);
md.setM2Speed(-300);
}
if ( uS / US_ROUNDTRIP_CM > 1) {
for (int i = 0; i <= 400; i++)
{
md.setM1Speed(i);
md.setM2Speed(i);
if (abs(i)%200 == 100)
{
}
delay(1.5);
}
}
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
long previousMillis = 0; // will store last time LED was updated
long interval = 1000; // interval at which to blink (milliseconds)
OK, I see you added those two lines. But blink without delay has a lot of other stuff going on too. Every time through loop you get a variable called currentMillis and set it equal to millis(). And then you do some checks to see if the interval has passed.
Blink without delay isn't a trick or a special piece of code that you just insert. It is a way of thinking. It is a way of thinking about how to time things. Don't copy anything from it. Learn from it and then implement the idea.
If you're having trouble understanding it, read this:
The only difference is that you are turning motors on and off instead of blinking leds. And you also aren't turning the motor back on at a set time after you turn it off. So you're not going to use this code exactly. But it's the concept you gotta get your head around.
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
Oh, there it is, just plunked in at the end of the loop. This code is talking about leds. Are you trying to time leds?