how to set servo to rotate only once in 1 condition - arduino

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

Related

How to delay the sound of the piezo buzzer.in arduino

I'm trying to implement a car warning sound using a piezo buzzer and an ultrasonic sensor.If an object is 50 to 30 cm away, it will sound for 1 second and try to turn off the sound for 1 second, but I can't think of a way to implement this code. Can you help me? Here is my code.
#define echoPin 4
#define trigPin 3
#define buzPin 5
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buzPin, OUTPUT);
}
void loop() {
digitalWrite(trigPin, LOW);
digitalWrite(echoPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
unsigned long duration = pulseIn(echoPin, HIGH);
float distance = ((float)(340 * duration) / 10000) / 2;
Serial.print(distance);
Serial.println("cm");
if (distance <= 50 && distance > 31)
{
tone(buzPin, 391, 1000);
}
else if (distance <= 30 && distance > 21)
{
tone(buzPin, 391, 500);
}
else if (distance <= 20 && distance > 11)
{
tone(buzPin, 391, 100);
}
else if (distance <= 10)
{
tone(buzPin, 391);
}
else {
noTone(buzPin);
}
}
After each time you tell the arduino to start making a tone (this is the tone() command) add some delay. To do this just follow the instructions bellow:
//code
if(statement)
{
tone(buzPin, 391, 500);
delay(x); //x=with the delay you want the buzzer to sound in ms
noTone(buzPin); //after that the sound stops
delay(y); //y=with the delay you want the buzzer to be silent in ms
}

Ultrasonic sensors

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

LED stays on even when digitalRead is low

I am just creating a simple basic program, but I can't figure out what's going wrong.
I have set three pins as output and three pins as input. When those three pins digitalRead == HIGH they will set an LED to HIGH, but instead my LED is always staying high.
Here is my Arduino code:
int LED_Low = 4; // Red LED
int LED_Avg = 3; // Yellow LED
int LED_High = 2; // Green Led
int WaterLow = 7;
int WaterAvg = 8;
int WaterHigh = 9;
void setup() {
// Put your setup code here, to run once:
pinMode(LED_Low, OUTPUT);
pinMode(LED_Avg, OUTPUT);
pinMode(LED_High, OUTPUT);
pinMode(WaterLow, INPUT);
pinMode(WaterAvg, INPUT);
pinMode(WaterHigh, INPUT);
}
void check(){
if(digitalRead(WaterLow) == HIGH){ // If Water level is low
digitalWrite(ledLow, HIGH); // Turn on red LED indication water level is low
}
else{
digitalWrite(ledLow, LOW);
}
if(digitalRead(WaterAvg) == HIGH){ // If water level is medium
digitalWrite(ledAvg, HIGH); // Turn on yellow LED indicating water level is average
}
else{
digitalWrite(ledAvg, LOW);
}
if(digitalRead(WaterHigh) == HIGH){ //
digitalWrite(ledHigh, HIGH); //
}
else{
digitalWrite(ledHigh, LOW);
}
}
void loop() {
// Put your main code here, to run repeatedly:
check();
}
In the above image I have connected led on pin 2, 3, and 4 with 1.5 kilohm resistor and three wires in pin 7, 8, and 9 which will receive input from the 5 volt pin and turn on the LED. Accordingly, the 5 volt pin is connected to the positive terminal on the power bus and with 9.1 *2 resistors in series and then this wire connect with pin 2, 3, and 4.
I found the issue. My code was OK. It was my circuit.
The pins I declared to receive input were not connected to ground.
You can make that with the help of two cases
Define the delay
if (digitalRead(WaterLow) == HIGH) // If Water level is low
{
digitalWrite(ledLow, HIGH); // Turn red LED indication water level is low
delay(2000);
}
else
{
digitalWrite(ledLow, LOW);
}
Make a condition like this
int stateled = LOW;
int previous = LOW;
long time = 0;
long debounce = 200;
void loop()
{
stateButton = digitalRead(WaterLow);
if (stateButton == HIGH && previous == LOW && millis() - time > debounce)
{
if(stateLED == HIGH)
{
stateLED = LOW;
}
else
{
stateLED = HIGH;
}
time = millis();
}
digitalWrite(ledlow, stateLED);
previous == stateButton;
}

Arduino, if else LED "stuck"

So the code is not working properply, there are two leds that wont turn off "highliten" the problem. when i run the Else part of the program. i want to turn them off in the else part. :)
include
byte ledPin[] = {8, 9, 10, 11, 12, 13}; //--------------------------------.
int ledDelay; // Del 1
int direction = 1;
int currentLED = 0;
unsigned long changeTime;
int potPin = 0;
Servo myservo; // create servo object to control a servo
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
int va;
void setup()
{
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, INPUT);
myservo.attach(3); // attaches the servo on pin 9 to the servo object
Serial.begin(9600);
for (int x=0; x<6; x++) {
pinMode(ledPin[x], OUTPUT); }
changeTime = millis();
}
void loop() {
int on = digitalRead(6);
if (on == HIGH)
{
myservo.attach(3);
// Here is the problem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if va < 523)
{
digitalWrite(5, HIGH);
}
else if (va > 555)
{
digitalWrite(4, HIGH);
}
else
{
digitalWrite(4, LOW);
digitalWrite(5, LOW);
}
// Here is the problem!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
va = analogRead(potPin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(va, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
delay(1); // waits for the servo to get there
}
else
{
myservo.detach();
digitalWrite(5, LOW);
digitalWrite(4, LOW);
ledDelay = analogRead(potPin) / 4;
if ((millis() - changeTime) > ledDelay)
{
changeLED();
changeTime = millis();
}
}
}
void changeLED() {
for (int x=0; x<6; x++)
{
digitalWrite(ledPin[x], LOW);
}
digitalWrite(ledPin[currentLED], HIGH);
currentLED += direction;
if (currentLED == 6) {direction = -1;}
if (currentLED == 0) {direction = 1;}
}
in advance Thank you!
Right at the end of the sketch you have the following line:
if (currentLED == 6) { direction = -1; }
I think, without actually running the program, that the problem is here. In the previous line you have added one to the value of currentLED and you are checking to see if you have gone off the end of the ledPin array. You change the direction but you don't reset the currentLED position to be back inside the ledPin range.
The next time changeLED is called it tries to call digitalWrite(ledPin[currentLED], HIGH); but the value of currentLED is 6, which is outside the ledPin array. The Arduino probably gets upset at this point.
I think you simply need to change the statement to check whether currentLED == 5 rather than 6. This will mean that next time that changeLED is called the last LED will be turned on and the value of currentLED will be decremented (direction == -1), keeping it inside the ledPin range.

Servo motor reacts to other things

I am working with Arduino, I connected a servo motor and a normal motor. They both work but when I start the normal motor script, the servo motor does small spastic stuff.
Could anyone help me with this?
// Includes
#include <Servo.h>
// Aanmaken van de variabelen voor in de code
int ledPin = 13;
const int motorPin = 2;
int usbnumber = 0;
Servo stuurServo; // create servo object to control a servo
int pos = 90; // variable to store the servo position
// De eerste setup maken
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(motorPin, OUTPUT);
stuurServo.attach(12);
Serial.begin(9600);
stuurServo.write(pos);
}
void loop()
{
if (Serial.available() > 0) {
usbnumber = Serial.read();
}
if (usbnumber > 0) {
if (usbnumber == 1){ // Lampje knipperen
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(500);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(500);
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);
delay(500);
}else if(usbnumber == 2){ // Motor aan voor 5 seconden
digitalWrite(motorPin, HIGH);
delay(20000);
digitalWrite(motorPin, LOW);
}else if(usbnumber == 3){ // stuur servo +10 graden
if(pos != 180){
pos + 10;
stuurServo.write(pos);
}
}else if(usbnumber == 4){ // stuur servo -10 graden
if(pos != 0){
pos - 10;
stuurServo.write(pos);
}
}else if(usbnumber == 5){ // stuur servo liks
pos = 0;
stuurServo.write(pos);
}else if(usbnumber == 6){ // stuur servo rechts
pos = 180;
stuurServo.write(pos);
}else{
delay(500);
}
usbnumber = 0;
}
}
Most (hobby) servo motors will twitch or give a little jerk when they are powered up, especially if you power the motor before driving the servo (providing a position control signal). The solution is to write to the control line to the servo before allowing power to it. Some easy solutions include:
controlling power to the servo through something you can turn off/on (PWM, MOSFET someone else help here?)
having a secondary power manual switch you can toggle once your controller is up and running.
There is basically nothing you can do in code without some way to have the circuit start up with no power to the Servo until you are driving the position control line.

Resources