Robot won't move any further after a few wheel turns - arduino

I'm building a robot for a school project. I am currently using an Arduino Uno, two DC motors and an ultrasonic sensor. The two motors are being controlled via the Arduino Motor Shield v3. I want the robot to be autonomous so it has to be able to move around on its own using the ultrasonic sensor.
This is the latest version of my source code:
#include <Servo.h> // include Servo library
#include <AFMotor.h> // include DC motor Library
#define trigPin 12 // define the pins of your sensor
#define echoPin 13
AF_DCMotor motor2(7); // set up motors.
AF_DCMotor motor1(6);
void setup() {
Serial.begin(9600); // begin serial communication
Serial.println("Motor test!");
pinMode(trigPin, OUTPUT); // set the trig pin to output to send sound waves
pinMode(echoPin, INPUT); // set the echo pin to input to receive sound waves
motor1.setSpeed(105); // set the speed of the motors, between 0-255
motor2.setSpeed (105);
}
void loop() {
long duration, distance; // start the scan
digitalWrite(trigPin, LOW);
delayMicroseconds(2); // delays are required for a successful sensor operation.
digitalWrite(trigPin, HIGH);
delayMicroseconds(10); // this delay is required as well!
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1; // convert the distance to centimetres.
// if there's an obstacle ahead at less than 25 centimetres, do the following:
if (distance < 25) {
Serial.println("Close Obstacle detected!" );
Serial.println("Obstacle Details:");
Serial.print("Distance From Robot is " );
Serial.print(distance);
Serial.print(" CM!"); // print out the distance in centimeters.
Serial.println (" The obstacle is declared a threat due to close distance. ");
Serial.println (" Turning !");
motor1.run(FORWARD); // Turn as long as there's an obstacle ahead.
motor2.run (BACKWARD);
} else {
Serial.println("No obstacle detected. going forward");
delay(15);
motor1.run(FORWARD); // if there's no obstacle ahead, Go Forward!
motor2.run(FORWARD);
}
}
The current issue is that the wheels are rotating as expected but after a few turns they stop.
I suspect that the issue is software related, but I am not completely sure. Moreover, I believe that the motors are correctly connected to the motor shield, but I might not handle them properly in the code.
Could anyone please help me solving this issue?

Simple answer - get rid of the delay in the loop
delay(15);
in combination with the used libraries this leads after some time to no motion at all. Delay stops processing everything, so use a nonblocking time measurement to give the motor routines the processing time instead of blocking everything. See blinkwithoutdelay example in ArduinoIDE how to implement this kind of routine. When working with robots always look into the libs (= advantage of open source) if the author uses delay() If yes either rewrite the function or ditch the lib. Especially in Arduino environment a lot of really bad libs are around - they work in simple testing cases on the desktop, but not in complex close to real time environments like robotics.

I think you must use PWM pins for motors. Since AFMotor library has option to set speed. So please change pin 7 to pin 5 for motor2 and check.

Related

I set my pushbutton switch up incorrectly

I am fiddling with an Arduino Uno and trying to get two switches to operate two servo motors. I am not able to do this right now, and I am not sure what my issue is. I know that my servos are wired correctly; however, I highly doubt that my switches are correctly wired.
Here is a diagram of my circuit and the code that I am using.
#include <Servo.h>
Servo servo_11;
Servo servo_10;
void setup()
{
servo_11.attach(11);
servo_10.attach(10);
pinMode(A3, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A2, INPUT);
}
void loop()
{
servo_11.write(0);
servo_10.write(0);
digitalWrite(A3, LOW);
digitalWrite(A2, LOW);
if (analogRead(A2) != LOW) {
servo_11.write(180);
}
delay(10);
}
Circuit image
If anyone could point out what's wrong, I would really appreciate it!!
You have floating inputs. When the button isn't pressed the pin isn't connected to anything. So the pin can read whatever noise it happens to pick up from the environment. You need pull-down or pull-up resistors. If you use pull-ups, then you can use the ones built into the chip.
You also seem to be confusing analogRead and digitalRead. It's digitalRead that gets HIGH and LOW. analogRead gets values from 0 to 1023 for 0 to 5V.
pull-down resistor circuit
try looking on this to understand the concept
it makes sure that when you dont press the pin will read ground and only when it presses the button you make voltage divider that ups the volage to a non-zero to give you HIGH

Conneting Adafruit m0 with dht22

I am new to low-level programming, and attempting to connect a DHT22 sensor onto my Adafruit M0 Lora for temperature readings. So far I only retrieve NaNs.
The connections I have set up are identical with this sketch, aside from using pin 13 as opposed to pin 2 for sensor input/output. I am aware of the sketch being made for a different feather board, although the logic should still remain the same from what I can understand.
I am making use of Adafruit's DHT library
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
// pin connected to DH22 data line
#define DATA_PIN 13
DHT_Unified dht(DATA_PIN, DHT22);
void setup() {
// start the serial connection
Serial.begin(9600);
// wait for serial monitor to open
while(! Serial);
// initialize dht22
dht.begin();
// connect to io.adafruit.com
Serial.print("Connecting to Adafruit IO");
// we are connected
Serial.println();
}
void loop() {
sensors_event_t event;
dht.temperature().getEvent(&event);
float celsius = event.temperature;
float fahrenheit = (celsius * 1.8) + 32;
Serial.print("celsius: ");
Serial.print(celsius);
Serial.println("C");
Serial.print("fahrenheit: ");
Serial.print(fahrenheit);
Serial.println("F");
// save fahrenheit (or celsius) to Adafruit IO
dht.humidity().getEvent(&event);
Serial.print("humidity: ");
Serial.print(event.relative_humidity);
Serial.println("%");
delay(5000);
}
Would anyone be able to help point of what I am doing incorrectly? I tried at other bauds than 9600, as well as changing the programmable pin. Any help at all would be greatly appreciated.
I don't think it's a code problem. Pin 13 is special. Choose a different pin.
Specifically:
NOTE: Digital pin 13 is harder to use as a digital input than the other digital pins because it has an LED and resistor attached to it that's soldered to the board on most boards. If you enable its internal 20k pull-up resistor, it will hang at around 1.7V instead of the expected 5V because the onboard LED and series resistor pull the voltage level down, meaning it always returns LOW. If you must use pin 13 as a digital input, set its pinMode() to INPUT and use an external pull down resistor.
From Arduino documentation.

Arduino Uno DC Motor not working with simple test. Can not get Arduino to spin the motor

I am using the V2.3 motorsheild on the arduino uno r3.
I no almost nothing about ardunio excpet from what ive read about the past week.
I have been trying to simply turn the motor with the code below and it wont work. I have the arduino plugged into my computer and 12v going to the blue power box thing.
I am using this motor https://www.servocity.com/html/900_rpm_micro_gearmotorblocks.html#.VyELIFaDFBc
I cannot get the dang thing to spin, motor works fine if i wire it straight to the 5v/grnd but not when its in the M1 connection
wiring: https://i.groupme.com/747x1328.png.54a01e30433241d4a99905bd0e8ede2b let meknow if this link doesnt work
Heres an Imgur link for the wiring http://imgur.com/J92ewnu
#include
AF_DCMotor motor(1);
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Motor test!");
// turn on motor
motor.setSpeed(200);
motor.run(RELEASE);
}
void loop() {
uint8_t i;
Serial.print("tick");
motor.run(FORWARD);
for (i=0; i<255; i++) {
motor.setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
motor.setSpeed(i);
delay(10);
}
Serial.print("tock");
motor.run(BACKWARD);
for (i=0; i<255; i++) {
motor.setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
motor.setSpeed(i);
delay(10);
}
Serial.print("tech");
motor.run(RELEASE);
delay(1000);
}
I am not expert in current particular shield and its library. But what i see when first time look at your sketch and motor connection image is that you are trying to run dc motor at a certain speed with commands, which seems to be for servo or stepper motors.
You should know that running DC motor at some speed is possible if you have speed calculation based on its current and voltage or when a speed sensor is located at motor's shaft. This motor doesn't have the sensor (i know it for sure, because used same in my projects) and i think the shield can't calculate speed. What you can is only switch it on and off and maybe change its direction.
So, first of all you should look (and use) at the library for such functions.
Looking for what the function you called "AF_DCMotor" does I see how you were confused. There is also this product, which is another adafruit motor sheild.
But it's actually a very different motor driver. Both shields have a power stage which takes pulses and amplifies them to drive a motor. The V2 apparently has a chip which generates these pulses, and you send it serial data to command it using I2C. The V1 just gets these pulses directly from the Arduino.
For yours, a V2 motor shield, try the guide Adafruit provides.
Here's the link - Adafruit Motor Sheild V2 DC motor control
And here's the code
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
AFMS.begin();
myMotor->setSpeed(100);
myMotor->run(FORWARD);
It mentions the use of I2C on the introductory page
Instead of using a latch and the Arduino's PWM pins, we have a fully-dedicated PWM driver chip onboard. This chip handles all the motor and speed controls over I2C
That's why it includes the Wire library. You could make your own code to run this, but it would have to use I2C to send commands to the PWM driver chip they are using.

Arduino UNO + Ethernet Shield + Ultrasonic Sensor = Fail

With my Arduino Uno I measure the distance using HC-SR04 ultrasonic sensor with no problems at all using the wiring below.
When I attach ethernet shield, my ultrasonic sensor does not measure distance any more, it constantly says 0cm no matter what. I have tried different digital pin pairs such as 5-7, 6-8, 5-9, 3-5, 2-8 but no luck.
I suspect that HC-SR04 is not compatible with my Ethernet shield but I haven't seen such warning anywhere on the net.
There are no components attached to arduino besides ethernet shield and the ultrasonic sensor itself.
There is no SD Card in SD Card slot.
My ethernet shield works fine while running a web server or web client script.
Digital pins of ethernet shield works fine with all other components such as temperature sensor, motion sensor etc.
Here is the ethernet shield I have;
http://www.ezshopfun.com/product_info.php?products_id=169
Here is my actual circuit;
http://s7.postimg.org/vyi2z36qz/20140826_001130.jpg
http://s7.postimg.org/6eb7ewvzf/20140826_001150.jpg
http://s7.postimg.org/6psnrocff/20140826_001156.jpg
http://s7.postimg.org/y6ro2ooh7/20140826_001229.jpg
http://s7.postimg.org/71a44fsvf/20140826_001247.jpg
Here is my code;
#define trigPin 6
#define echoPin 7
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
int duration, distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH) / 2;
distance = duration / 29.1;
Serial.print(distance);
Serial.println(" cm");
delay(500);
}
Today I bought a multimeter and tested my circuit. Here are the results;
When my circuit directly attached to Arduino itself;
4.80V & 5.7mA
When my circuit attached to ethernet shield;
3.06V & 3.8mA
I think the problem is that 3.06V is not enough for my HC-SR04 to operate.
Yeah based on this photo
you're not grounding your sensor. You have two power supplies going into it. This, needless to say, is bad for a number of reasons. First and foremost because it wont work ungrounded lol
As others have said, it looks like the main issue is that you need this connected to 5V and check your wiring generally.
However, there is another potential issue:
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
You only need to set the trigger pin high for 10 microseconds, not 1000 microseconds. I don't know if this is an issue or not but there is no need to wait this long. You could potentially be missing some or all of the incoming pulse by waiting that long.
You might want to checkout out some HC-SR04 tutorials too, like this one:
http://superawesomerobots.com/tutorials/hc-sr04-tutorial-for-arduino/
Hope that helps.
I had a similar problem with a wifi shield + ultrasonic sensor. I found switching from pins 13(trig) and 11(echo) to 8(trig) and 3(echo) fixed it.
See here: http://forum.arduino.cc/index.php?topic=201827.0

Arduino ultrasonic initialisation issue

Hardware:
Arduino MEGA 2560
2 x MaxBotix MaxSonar-EZ0
Software (relating to Ultrasonics, by no means the entire program):
void setup() {
Serial.begin(9600);
//Ultrasonic Left
pinMode(26, OUTPUT);
pinMode(2, INPUT);
digitalWrite(26, LOW);
//Ultrasonic Right
pinMode(27, OUTPUT);
pinMode(3, INPUT);
digitalWrite(27, LOW);
}
void readSonar() {
digitalWrite(26, HIGH);
delayMicroseconds(25);
digitalWrite(26, LOW);
data[0] = pulseIn(2, HIGH);
digitalWrite(27, HIGH);
delayMicroseconds(25);
digitalWrite(27, LOW);
data[1] = pulseIn(3, HIGH);
return data;
}
Problem:
When the Arduino is first booted, the readings from the two Ultrasonic sensors are not being updated. They are reporting as non-zero values, typically in the range of 500 - 1500. They fluctuate a little (most likely due to noise in the power supply), but tend to stay around the value that they initialise to.
As per the data sheet for these sensors, there are no obstacles within 14 inches of the sensors during the initialisation stage.
By simply disconnecting and reconnecting the cable going to the sensors (from the back of the sensor, not directly to the Arduino inputs), I am able to receive accurate readings from the sensors immediately.
Has anyone had this problem before? My setup() function looks 'normal' from the examples that I have seen. In order to fix this problem, I have connected a switch for the active lines of both sensors. This way the Arduino can boot and then I can give the sensors power. This seems like a botched workaround to me, and I would like a hard-coded software solution, if anyone is able to provide one!
If you look at the characteristics of the sensor it looks clear that you need to start them with the Rx at 0. Look at this link. This is most probably the reason why you have to disconnect the sensor after you start the Arduino to get it working. You also need to make sure that you have pullup resistors connected to avoid unreliability of the readings.

Resources