I have developed a code to get distance using an Ultrasonic Sensor. But it doesn't seem to work. It just output 0. Here's the code.
`#include <math.h>
void setup() {
Serial.begin(9600);
}
void loop() {
int dist = getcm();
delay(100);
Serial.println(dist);
}
int getcm() {
digitalWrite(A0, LOW);
delayMicroseconds(2);
digitalWrite(A0, HIGH);
delayMicroseconds(10);
digitalWrite(A0, LOW);
int duration = pulseIn(A1, HIGH);
int distance = (duration*.0343)/2;
distance = round(distance);
return distance;
}`
Is anything wrong with the code? Or the problem is with the sensor?
I do not know how the interface on these sensors work but, there are easier ways to do this like using the NewPing.h library.
#include <NewPing.h>
NewPing sonar (10, 11, 20);
void setup() {
Serial.beign(9600);
delay(50);
}
void loop() {
Serial.print("The Distance is:");
Serial.println(sonar.ping_cm());
delay(1000);
}
This should work. So, try this way and if it won't work still, it is probably a faulty sensor.
Related
This is the code I wrote:
I set the pins given accordingly I checked my ultrasonic sensors, transistor, and resistors are in working condition. CS (in code denoted as chipset) is pinned in pin 10, resistor to 9, and that resistor is connected to the transistor, and then it is connected to the speaker.
#define trigPin1 3
#define echoPin1 2
#define trigPin2 4
#define echoPin2 5
#define trigPin3 7
#define echoPin3 8
#define cs 10
#include "SD.h"
#include "TMRpcm.h"
#include "SPI.h"
TMRpcm tmrpcm;
long duration, distance, RightSensor, BackSensor, FrontSensor, LeftSensor;
void setup()
{
tmrpcm.speakerPin = 9;
Serial.begin(9600);
if (!SD.begin(cs))
{
Serial.println("SD fail");
}
pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(trigPin3, OUTPUT);
pinMode(echoPin3, INPUT);
}
void loop() {
SonarSensor(trigPin1, echoPin1);
RightSensor = distance;
tmrpcm.setVolume(6);
if (RightSensor > 10)
{
tmrpcm.play("RightFormatted.wav");
}
SonarSensor(trigPin2, echoPin2);
LeftSensor = distance;
if (LeftSensor > 10)
{
tmrpcm.play("LeftFormatted.wav");
}
SonarSensor(trigPin3, echoPin3);
FrontSensor = distance;
if (FrontSensor > 10)
{
tmrpcm.play("FrontFormatted.wav");
}
Serial.println(LeftSensor);
Serial.println(" - ");
Serial.print(FrontSensor);
Serial.print(" - ");
Serial.println(RightSensor);
}
void SonarSensor(int trigPin, int echoPin)
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) / 29.1;
}
The error I am getting is:
Error of this code
Instead of typing the name of the .wav file directly inside the .play method, create a const char variable to assign the name(s):
const char* audio1= "RightFormatted.wav";
then you can use it as:#
tmrpcm.play(audio1);
However, based on the examples from the library, you do not need the file extension, but I might be wrong in this regard.
Try first my proposal and please report your results
Now i am using 2 ultrasonic sensors but i found that they become unstable outdoors and give random readings .....although they act normally inside a room .....how can i solve this problem???
That is the code
it seems like the off Sensor always Reading and i checked the wiring and it is good so i don't really know where is the problem is ??
#define trig 2
#define echo 3
#define led 7
#define relay 4
#define trig2 10
#define echo2 9
#define led2 8
long duration,distance,OnSensor,OffSensor;
void setup() {
// put your setup code here, to run once:
pinMode(echo,INPUT);
pinMode(echo2,INPUT);
Serial.begin(9600);
pinMode(led,OUTPUT);
pinMode(led2,OUTPUT);
pinMode(relay,OUTPUT);
pinMode(trig,OUTPUT);
pinMode(trig2,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(led,LOW);
digitalWrite(led2,LOW);
digitalWrite(relay,LOW);
SonarSensor(trig2, echo2);
OffSensor = distance;
delay(50);
SonarSensor(trig, echo);
OnSensor=distance;
if(OnSensor<80&&OffSensor>=80){//sensor 1 activated
digitalWrite(led,HIGH);
digitalWrite(relay,HIGH);
delay(150);
digitalWrite(led,LOW);
digitalWrite(relay,LOW);
delay(1000);
digitalWrite(led,HIGH);
digitalWrite(relay,HIGH);
delay(150);
digitalWrite(led,LOW);
digitalWrite(relay,LOW);
}
else if(OnSensor>80&&OffSensor>80){//No sensor activated
digitalWrite(led,LOW);
digitalWrite(relay,LOW);
}
else if(OnSensor>80&&OffSensor<80){//sensor2 activated
digitalWrite(led2,HIGH);
digitalWrite(relay,LOW);
delay(5000);
}
else if(OnSensor<80&&OffSensor<80){//Both sensors activated
digitalWrite(led2,HIGH);
digitalWrite(led,HIGH);
digitalWrite(relay,LOW);
delay(3000);
}
}
void SonarSensor(int trigPin,int echoPin)
{
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = duration*0.034/2;
}
I think there are 2 problem here
You use 2 sensor
List item
Use use it outdoor
From my experience the ultra sonic wave can bouncing around object many time. depend on your setup, second sensor might read echo form first sensor.
follow these step
1. Try to use 1 sensor per time to see if it error
2. If single sensor work you should add more delay after sensor reading
3. Plot the data to see how it look like you might need digital filter to improve reading
For step 3 if you use sensor as On Off by threshold you can see my example code.
This code work the same way as button de-bouncing so in need to trig continuously for 10 time to prevent false alarm (This code for single sensor)
#define ULTRASONIC_TRIG_PIN 8
#define ULTRASONIC_ECHO_PIN 7
#define RELAY_PIN 4
/**/
#define ULTRASONIC_INTERVAL_MS 100//50
#define ULTRASONIC_TRIG_COUNT_THRESH 10
#define ULTRASONIC_DISTACE_THRESH_CM 50
/**/
#define RELAY_TRIG__INTERVAL_MS 5000
#define RELAY_TRIG_LOGIC HIGH
void setup()
{
pinMode (RELAY_PIN, OUTPUT);
pinMode (ULTRASONIC_TRIG_PIN, OUTPUT);
pinMode (ULTRASONIC_ECHO_PIN, INPUT);
Serial.begin(115200);
}
void loop()
{
static unsigned long ultrasonic_timer = millis();
static unsigned long relay_trig_timer = millis();
static float us_distance_cm = 0;
static int us_trig_count = 0;
static byte relay_state = !RELAY_TRIG_LOGIC; // initial value as off;
if (millis() - ultrasonic_timer >= ULTRASONIC_INTERVAL_MS) {
ultrasonic_timer += ULTRASONIC_INTERVAL_MS;
us_distance_cm = getDistanceCM();
if (us_distance_cm <= ULTRASONIC_DISTACE_THRESH_CM) {
if (us_trig_count >= ULTRASONIC_TRIG_COUNT_THRESH) {
digitalWrite(RELAY_PIN, RELAY_TRIG_LOGIC);
relay_state = RELAY_TRIG_LOGIC;
relay_trig_timer = millis();
}
else {
us_trig_count++;
}
}
else {
us_trig_count = 0;
}
Serial.print("distance = ");
Serial.print(us_distance_cm);
Serial.print("cm, relay = ");
Serial.print(relay_state);
Serial.print(", count = ");
Serial.println(us_trig_count);
}
if (relay_state == RELAY_TRIG_LOGIC) {
if (millis() - relay_trig_timer > RELAY_TRIG__INTERVAL_MS) {
relay_state = !RELAY_TRIG_LOGIC;
digitalWrite(RELAY_PIN, !RELAY_TRIG_LOGIC);
}
}
}
float getDistanceCM() {
digitalWrite(ULTRASONIC_TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(ULTRASONIC_TRIG_PIN, LOW);
unsigned long duration = pulseIn(ULTRASONIC_ECHO_PIN, HIGH, 50000);
float distance = float(duration * 343) / 20000.0;
delay(5);
return distance;
}
I created a program that is intended to turn a servo motor 180 degrees then back if an object is within 20cm of the ultrasonic sensor. This works fine except sometimes when the if condition is not met. In this case, the motor doesn't move at all and the distance is put into the serial monitor. This works fine sometimes, but in most cases the serial monitor just prints 0 repeatedly and I have to restart the program for it to work again. Even when I put an object within 20cm of the sensor it still prints 0. I am quite new to Arduino so this really just stumped me haha. Any tips or help would be greatly appreciated.
#include <Servo.h>
Servo servo1; // create servo object to control a servo
#define trigPin 13
#define echoPin 12
void setup()
{
Serial.begin(9600);
servo1.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop()
{
long duration = 0, distance = 0;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) / 29.1;
if(distance > 2 && distance < 20){
servo1.write(180);
Serial.println(distance);
delay(1000);
servo1.write(-180);
}
else{
servo1.write(0);
Serial.println(distance);
}
delay(2000);
}
See what happens when you try this code, as I cleaned it up a little bit:
#include <Servo.h>
#define trigPin 13
#define echoPin 12
Servo servo1; // create servo object to control a servo
void setup() {
Serial.begin (9600);
servo1.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
float duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) * 29.1;
if (duration) {
if (distance > 2 && distance < 20) {
servo1.write(180);
Serial.println(distance);
delay(1000);
servo1.write(-180);
}
else {
servo1.write(0);
Serial.println(distance);
}
}
delay(2000);
}
I think if you use a float it might work. However, if it doesn't work, try switching up the pin assignments to different pins on the Arduino and see if that works. If the distance measurment is off the best way to adjust it is with the multiplied value in the distance variable in the void loop ().This one works for me.
With this code written in the Arduino IDE I used to be able to call functions based on which Infrared sensor detected an object(right, left, or both). I altered the code a little bit lately but I've continued to make sure it wasn't missing any key components which made it work in the first place. I'm not sure if it's an error in my program or hardware but now, no matter what sensor detects an object, my robot just turns slightly to the left.
//Include Servo Library
#include <Servo.h>
//Define Pins for the Sensors and LEDs
#define LsensorPin 8
#define RsensorPin 5
#define LeftTransPin 7
#define RightTransPin 6
I'm using continuous rotation servos so using 0's and 180's is how I would control them at full speed. I checked the numbers over and over but they don't seem to be the problem.
//Constants for driving servo
const int RForward = 0;
const int RBackward = 180;
const int LForward = RBackward;
const int LBackward = RForward;
const int RNeutral = 90;
const int LNeutral = 90; //0 Speed
//Name the Servos for Left and Right Motor
Servo LMotor;
Servo RMotor;
The following 2 functions, when called, transmit an infrared signal through the transmitters. I do not think this is related to the problem because the sensors still detect objects, but my robot just doesn't respond the way I want it to.
//Take Reading from Left IR Sensor
void LeftIRled(){
for(int i=0;i<=384;i++){
digitalWrite(LeftTransPin, HIGH);
delayMicroseconds(13);
digitalWrite(LeftTransPin, LOW);
delayMicroseconds(13);
}
}
//Take Reading from Right IR Sensor
void RightIRled(){
for(int i=0;i<=384;i++){
digitalWrite(RightTransPin, HIGH);
delayMicroseconds(13);
digitalWrite(RightTransPin, LOW);
delayMicroseconds(13);
}
}
These functions control the direction in which the robot moves. I've checked it many times but this could possibly be one of the problems. They basically just control the spin of each individual servo with the previously declared variables.
//Controlling Servo Directions with Functions
void Forward(){
RMotor.write(RForward);
LMotor.write(LForward);
}
void Backup(){
RMotor.write(RBackward);
LMotor.write(LBackward);
}
void Stop(){
RMotor.write(RNeutral);
LMotor.write(LNeutral);
}
void Left(){
RMotor.write(RForward);
LMotor.write(LNeutral);
}
void Right(){
RMotor.write(RNeutral);
LMotor.write(LForward);
}
//Declare INPUT and OUTPUT for each Pin connected
//to Arduino Uno and set them to LOW
void setup(){
pinMode(LeftTransPin, OUTPUT);
digitalWrite(LeftTransPin, LOW);
pinMode(RightTransPin, OUTPUT);
digitalWrite(RightTransPin, LOW);
//drive forward
LMotor.attach(9);
RMotor.attach(10);
Forward();
}
Although I can't pinpoint the problem I believe it has something to do with the loop function. It is here that I transmit the infrared signal, receive it, and then call various functions which control the movement of the robot.
void loop(){
/*Drive forward until you reach an obstacle on either the
right side, left side, or both together(something in front of
you). If the left sensor goes low, he turns right, if the right
sensor goes low, he turns left. if both turn on at the same time
he stops, backs up, and turns right till he is out of danger
*/
int lstate;
int rstate;
LeftIRled();
lstate = digitalRead(LsensorPin);
delay(50);
RightIRled();
rstate = digitalRead(RsensorPin);
delay(50);
if (lstate == LOW && rstate == LOW)
{
Stop();
delay(100);
Backup();
delay(1000);
Stop();
delay(100);
Right();
delay(500);
}
else if (lstate == LOW)
{
Stop();
delay(100);
Backup();
delay(1000);
Right();
delay(500);
}
else if (rstate == LOW)
{
Stop();
delay(100);
Backup();
delay(1000);
Left();
delay(500);
}
else
{
Forward();
}
}
Any help or advice is greatly appreciated!
I'm trying to code an Arduino avoidance robot as a learning project. When I run the following code only one motor (the left one) works. If I comment out the if statement that uses the checkDistance() function and just loop the forward() function both motors work fine. I'm using an Adafruit Motorshield v1.2, and I believe this is the motor: Link. I've tried powering directly through USB, and also through external power supply (4 x AAs), and have the same issue. Any pointers would be appreciated. Thank you!
#include <AFMotor.h>
#define trigPin 3
#define echoPin 2
AF_DCMotor left_motor(2, MOTOR12_64KHZ); // create motor #1, 64KHz pwm
AF_DCMotor right_motor(1, MOTOR12_64KHZ); // motor #2\
int maxDistance = 30;
//int minDistance = 0;
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
left_motor.setSpeed(255);
right_motor.setSpeed(255);
}
void forward(int delayTime) {
left_motor.run(FORWARD);
right_motor.run(FORWARD);
delay(delayTime);
}
void backward(int delayTime) {
left_motor.run(BACKWARD);
right_motor.run(BACKWARD);
delay(delayTime);
}
void stop(int delayTime) {
left_motor.run(RELEASE);
right_motor.run(RELEASE);
delay(delayTime);
}
void right(int delayTime) {
left_motor.run(FORWARD);
right_motor.run(BACKWARD);
delay(delayTime);
}
void left(int delayTime) {
left_motor.run(BACKWARD);
right_motor.run(FORWARD);
delay(delayTime);
}
int checkDistance(){
long duration, distance;
/* The following trigPin/echoPin cycle is used to determine the
distance of the nearest object by bouncing soundwaves off of it. */
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
//Calculate the distance (in cm) based on the speed of sound.
distance = duration/59.1;
return distance;
}
void loop() {
int currentDistance = checkDistance();
Serial.print(currentDistance);
if (currentDistance >= maxDistance){
Serial.println(" cm. No immediate obstacles detected. Moving forward.");
forward(2000);
stop(1000);
}
else {
Serial.println(" cm. Obstacle detected. Changing direction.");
right(1500);
stop(1000);
}
}
If I were trying to debug this, I would first test each of the motor functions without any logic check from the sensor. (e.g. do both wheels turn and in the correct direction when left, right, backward, etc are called just from loop()). That will give confidence that it is not a wiring or other hardware problem. If they don't work then sorting that out give you a place to start.
If they do work, then it must be the values with the sensor, right? How did you determine the maxDistancevalue? If it is too high then this line:
if (currentDistance >= maxDistance){
may never evaluate to true. You have some log statements in there so you have some sense of the value of currentDistance. Does it seem to be reflecting accurate values when you place objects at varying distances from the sensor?
Anyway... some thoughts.