Ultrasonic sensors - arduino

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;
}

Related

how to set servo to rotate only once in 1 condition

I want to make a gate using 360 servo and ultrasonic sensor, here I use if else. when ultrasonic conditions >= 10 cm the servo should rotate one time to the right for 5 seconds, and vice versa. but when it reaches the condition >= 10 cm where the servo continues to rotate without stopping, how to make it stop in 1 rotation? and also i need distance data from ultrasonic sensor to display.
I'm a beginner in this, I will be very grateful for the help.
this is my code :
#include <Wire.h>
#include <Servo.h> //Servo library
#define echoPin 3 //triger pin, echo pin
#define triggerPin 4
int waktu;
int jarak;
int hasiljarak;
Servo servo;
void setup()
{
Serial.begin(9600);
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop()
{
digitalWrite(triggerPin, LOW);
delayMicroseconds(2);
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
waktu = pulseIn(echoPin, HIGH);
jarak = waktu * 0.034 / 2;
Serial.print(jarak);
Serial.print(" CM");
delay(100);
servo.attach(9);
if(jarak<=10)
{
servo.write(2000);
delay(5000);
}
else if(jarak>=30)
{
servo.write(1000);
delay(5000);
}
else
{
servo.write(1500);
delay(1000);
}
servo.detach();
}
i've finish the servo with this code
void loop()
{
int ultra1 = tinggiUltra - sonar.ping_cm();
int ultra2 = tinggiUltra - sonar2.ping_cm();
delay(1000); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
Serial.print(ultra1); // Send ping, get distance in cm and print result (0 = outside set distance range)
Serial.println("cm");
Serial.print(ultra2);
Serial.println("cm");
if (ultra1 >= 11 && ultra1 <= 40 && ultra2 >=11)
{
servo.write(posClose);
delay(2000);
}
else if (ultra1 >= 5 && ultra1 <= 10 && ultra2 <=10)
{
servo.write(posOpen);
delay(2000);
}
else if (ultra2 <= 4 && ultra2 >= 0)
{
servo.write(pos);
delay(2000);
}
statPin = servo.read();
}
delay(2000);
}
else if (ultra1 >= 5 && ultra1 <= 10 && ultra2 <=10)
{
servo.write(posOpen);
delay(2000);
}
else if (ultra2 <= 4 && ultra2 >= 0)
{
servo.write(pos);
delay(2000);
}
statPin = servo.read();
}
for the servo I use it works normally as i wanted, and I use the MG955 360 servo. for the project I made using threads to open and close the door. I used if else for the code, and it worked fine by adding a parameter to restrict the movement of the door that I made. and thanks for the answer
if someone have to correct my program code, i'm grateful

Implementing Infrared sensor to an arduino

Is there a way to implement an Infrared sensor as input in an Arduino code ? I want the sensor to send data to the Arduino in values (changes of the IR position) and then use that value as an input in the software.
Code is an example of a light resistive sensor that turns on the LED every time it's dark, and turns it off when the light sensor detects its bright.
int sensor1Value = 0;
void setup()
{
// declare the ledPins as an OUTPUT:
pinMode(13, OUTPUT);
}
void loop() {
// read the value from the sensor:
sensor1Value = analogRead(A0);
{
if(sensor1Value <200) // check the value of sensor
{ //if the value is less than 200 then turn the leds on
digitalWrite(13, HIGH);
delay(500);
}
else // if the value is greater than or equal to 200 then turn leds off
{
digitalWrite(13, LOW);
delay(500);
}
}
The simpliest way is to use IR phototransistor
There is no need for a delay after each digitalWrite(), just add it at the end of the loop() function.
void loop() {
// read the value from the sensor:
sensor1Value = analogRead(A0);
if(sensor1Value <200) // check the value of sensor
{ //if the value is less than 200 then turn the leds on
digitalWrite(13, HIGH);
}
else // if the value is greater than or equal to 200 then turn leds off
{
digitalWrite(13, LOW);
}
delay(500);
}

I am facing some issues while using arduino working with memory card and speaker, please help me

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

How do i make an ultrasonic sensor trigger an LED to stay on until reset?

So, I know it's probably SUPER simple, but I'm new to arduino and I'm just drawing a blank. I'm making a motion detector with an HC-SRO4 ultrasonic sensor. Right now I have it set so whenever it senses an object within 60 cm, it turns on an LED light, but when the object disappears, the LED turns off. What I would like to happen is that it would stay on until I press a button to reset it. Any help is really appreciated and i thank you in advance.
void setup() {
#define LED 8
#define trigPin 12
#define echoPin 13
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LED, OUTPUT);
}
void loop() {
int duration, distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1
;if (distance >= 60 || distance <= 0){
Serial.println("no object detected");
digitalWrite(LED, LOW);}
else {
Serial.println("object detected");
digitalWrite(LED, HIGH);
}}
for this you have make low pushbutton pin while pressing.once the oobject came near the flag will set once the set it will move to while loop and run until the button pressed
#define LED 8
#define trigPin 12
#define echoPin 13
#define push_button 5
int flag=0;
void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LED, OUTPUT);
pinMode(push_button,INPUT);
}
void loop() {
int duration, distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
if(digitalRead()==0)
{
flag=0;
}
if (distance >= 60 || distance <= 0){
Serial.println("no object detected");
digitalWrite(LED, LOW);}
else {
Serial.println("object detected");
flag=1;
while(flag=1)
{
digitalWrite(LED, HIGH);}
}}

Ultrasonic program giving me an odd error

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.

Resources