Arduino - Light is staying on for more than expected duration - arduino

Code is suppose to Light the inbuit-LED at Pin 13 whenever Pin 5 is High, however i have encountered couple of problem.
While measuring Voltage though Digital Meter - one pin at arduino GND and other at 1,2,3,4. They are showing some non-zero values. Earlier triggering Pin was 4 and light was staying on all the time.
When Pin 5 is high (by connecting 5V Pin from Arduino to Pin 5) it lights the LED as it should, but if Pin 5 stays high for more than 1/2 second, light stays high for more than 0.5 second even after the Pin 5 is disconnected from 5V Pin.
int buttonState = LOW;
int light = 13;
void setup() {
// put your setup code here, to run once:
pinMode(gateopen,INPUT);
pinMode(light, OUTPUT);
}
void loop()
{
// put your main code here, to run repeatedly:
buttonState = digitalRead(gateopen);
if (buttonState == HIGH)
{
digitalWrite(light, HIGH);
}
else
{
digitalWrite(light, LOW);
}
//delayMicroseconds(500);
}

As suggested earlier, use a pull down resistor. Or change your circuit to active low and use INPUT_PULLUP.
I believe you're using delayMicroSeconds, which means the led is just blinking waaay too fast for your eyes. If you want 'half a second' as you hinted on your query, you would be using delay(500) instead.

You are experiencing electrical noise, just like Juraj said, just put a 220 Ohm pull down resistor

Related

cannot turn on relay indefinitely on an arduino

I want to make a device like Knocki(https://knocki.com), which essentially is a relay control using a vibration sensor. i can detect vibrations rn but the problem is, once i knock the relay blinks on and then turns off. i understand this is a lack of programming that is causing this. could someone help me write code which makes it so that when i knock the relay is turned on indefinitely; until I knock again to turn relay off.
And yes u can probably tell that this code is copied from somewhere(https://wiki.keyestudio.com/Ks0068_keyestudio_37_in_1_Sensor_Kit_for_Arduino_Starters#Project_21:_Vibration_Sensor).I took it from the home page of the vibration sensor. the code was initially so that every time i knocked, the onboard Arduino led lit up. Also, right now the relay is blinking faintly every time i knock(Although correctly,in sync with my knocks)
#define SensorLED 13
#define SensorINPUT 3 //Connect the sensor to digital Pin 3 which is Interrupts 1.
unsigned char state = 0;
int Relay = 5;
void setup()
{
pinMode(SensorLED, OUTPUT);
pinMode(SensorINPUT, INPUT);
attachInterrupt(1, blink, FALLING);// Trigger the blink function when the falling edge is detected
}
void loop()
{ if(state!=0)
{
state = 0;
digitalWrite(SensorLED,HIGH);
delay(500);
digitalWrite(Relay,HIGH);
}
else
digitalWrite(SensorLED,LOW);
digitalWrite(Relay,lOW);
}
void blink()//Interrupts function
{ state++;
Yes its in your code: The (bad) example works only because there is a
digitalWrite(SensorLED,HIGH);
->>> delay(500);
a delay for 1/2 sec to keep the led on.So as a check put an other delay after the relay line and it should go on for 1/2 sec too (so the led is lit 1 sec in total)
digitalWrite(SensorLED,HIGH);
delay(500);
digitalWrite(Relay,HIGH);
delay(500);
Thats just for checking -> NEXT STEP:
Get rid of the delays (see blinkwithoutdelay example in
Arduino->File->Examples->2.Digital -> blinkwithoutdelay
and introduce a second state variable e.g.
bool relayStateOn = false;
to get an independent on/off of the relay and the led.(If thats - what I understand -what you want to do)
If you feed your relay from the board, that is not the problem. Please, check the voltage in your relay when you try to set it on, if your voltage falls down, it means that this output to your relay does not supply the necessary current.

How to turn motor counter-clockwise

Currently, my code below turns on the motor, delays for a bit then starts again. This is all being done in the clockwise direction, however how can I write my code so it can turn counter-clockwise?
int motorPin = 3;
void setup()
{
pinMode(motorPin, OUTPUT);
}
void loop()
{
startStopMotor(135);
delay(1000);
startStopMotor(0);
delay(1000);
}
void startStopMotor(int speed){
analogWrite(motorPin, speed);
}
By the code you share i'am guessing you are running a low power 5v dc motor... but you should edit your answer to give us what type of hardware you are using. This is not an answer but an idea of what you should be looking for... Basically on the motor i suppose you have, you have pin 1 and pin 2. Pin 1 is connected to a PWM signal and pin 2 is connected to ground. This configuration allows you to run your motor clock'wise. To run your motor counter clock'wise you need to invert the direction of the current basically have pin 1 connected to ground and pin 2 connected to a PWM signal.
Now there are multiple ways of doing this, i am unsure of the exact code to do this on an arduino but your pin 1 and 2 will be connected each to a PWM pin. In the code you will need to tell the arduino to put Pin 1 or 2 as a pullDown pin which basically mimics a ground thus telling the direction the other pin will output a PWM
this is not example code but it will give you an idea of what it should look like
void loop(){
//move clock'wise
pin1.pullup();
pin2.pulldown();
analogWrite(pin1, 180);
//move counterclock'wise
pin2.pullup();
pin1.pulldown();
analogWrite(pin2, 180);
}

PIR Sensor that turns on DC Motors

I'm working on a side project where once motion is detected by the PIR sensor, the DC motors (2x) will turn on for 5 seconds and then shut off. And if the motion has stopped, then the DC motors will turn off.
So my problem is that I am not achieving the desired results I just mentioned above. From my perspective, it seems that my motion sensor is just going off and on, on its own and the DC motors are behaving how they should be with going on for 5 seconds, but the motion sensor is saying that there is motion despite there being motion, which causes the DC motors to run. The DC motors should run when there is motion.
I have tried this exact hardware and components on another arduino UNO and breadboard, the problem seems to be code related.
I have also tried taking a step back and seeing if I can get the motion detection to turn on a LED light. In the Serial monitor it seems to be picking up that there is motion being detected, but really there isn't.
I also tried adjusting the potentiometer on the PIR sensor as well as (adjusting the sensitivity and time) of it. I have also tried switching the "repeatable" trigger and the "non-repeatable" trigger around and seeing if that was an issue.
I have tried swapping the 9V battery to see if that was affecting the performance of the DC motors.
I also doubled checked and made sure each wire was in the correct placement.
As of now, below is the serial monitor... for the given code I provided. This is what the it is providing me. **Keep in mind, that I am not putting any motion into the arduino unit, and for some odd reason it detects that there is motion.
Here is what the Serial Monitor is showing...
2:31:43.219 -> Motors are ON
02:31:43.219 -> Motion detected!
02:31:48.215 -> Motors are ON
02:31:48.249 -> Motors are OFF
02:31:48.249 -> Motion stopped!
02:31:53.232 -> Motors are ON
02:31:53.232 -> Motion detected!
02:31:58.220 -> Motors are ON
02:31:58.253 -> Motors are OFF
02:31:58.253 -> Motion stopped!
02:32:03.238 -> Motors are ON
02:32:03.238 -> Motion detected!
02:32:08.230 -> Motors are ON
02:32:08.265 -> Motors are OFF
02:32:08.265 -> Motion stopped!
const int switchMotion=2;
const int motorPin=9;
const int motorPinB=8;
int motionState=0;
int motionDetected = LOW;
void setup() {
//Selecting as an input and output the switch and the motor
pinMode(switchMotion,INPUT);
pinMode(motorPin,OUTPUT);
pinMode(motorPinB, OUTPUT);
Serial.begin(9600); //Set serial out if we want debugging
delay(5000); //Allow time for the PIR Sensor to calibrate
}
void loop() {
motionState = digitalRead(switchMotion); // Reads the motion sensor
if(motionState == HIGH) // checks if Sensor is HIGH
{
digitalWrite(motorPin,HIGH); //turn on Motor A
digitalWrite(motorPinB,HIGH); //turn on Motor B
delay(5000); //runs for 5 seconds and stops
Serial.println("Motors are ON");
if (motionDetected == LOW) {
Serial.println("Motion detected!"); // print Motion Detected
motionDetected = HIGH; // update variable state to HIGH
}
else {
digitalWrite(motorPin,LOW); //turn off Motor A
digitalWrite(motorPinB,LOW); //turn off Motor B
Serial.println("Motors are OFF");
if (motionDetected == HIGH){
Serial.println("Motion stopped!");
motionDetected = LOW; // update variable state to LOW
}
}
}
}
The goal is to have it where once an individual is near the PIR motion sensor the DC motors turn on for a set period of time and when the time period is up, the motors turn off and there is a set delay time for the motion sensor to detect movement again for the DC motors to turn on again. It should be a constant cycle, where when there is not movement - the DC motors should be off. And when there is movement - the DC motors should be on. The exception is that there is a cooling time.
Actual results are that
I expect motionDetected to function properly, but when it's time to test it, it is reading that there is motion detected/not detected despite there being no real movement. My expected results is for the motion sensor to function properly so the DC motors can turn on/off accordingly.
I'm not sure I understand but if i'm correct isn't this just what you are looking for:
const int switchMotion = 2;
const int motorPin = 9;
const int motorPinB = 8;
void setup() {
//Selecting as an input and output the switch and the motor
pinMode(switchMotion,INPUT);
pinMode(motorPin,OUTPUT);
pinMode(motorPinB, OUTPUT);
Serial.begin(9600); //Set serial out if we want debugging
delay(5000); //Allow time for the PIR Sensor to calibrate
}
void loop() {
if(digitalRead(switchMotion) == HIGH) // checks if Sensor is HIGH
{
Serial.println("Motion detected!");
digitalWrite(motorPin, HIGH); //turn on Motor A
digitalWrite(motorPinB, HIGH); //turn on Motor B
Serial.println("Motors are ON");
delay(5000); //runs for 5 seconds and stops
digitalWrite(motorPin, LOW); //turn off Motor A
digitalWrite(motorPinB, LOW); //turn off Motor B
Serial.println("Motors are OFF");
}
// You can add a delay here if you want
}
Your logic is messed up.
If the sensor is low, nothing happens.
first run of loop after sensor turned high:
turn on the motors,
wait 5 seconds,
print "Motors are ON",
print "Motion detected",
set motionDetected HIGH.
second run of loop (if sensor is still high):
turn on the motors,
wait 5 seconds,
print "Motors are ON",
now motionDetected is HIGH so:
turn off motors
print "Motors are OFF"
print "Motion stopped"
set motionDetected LOW
second run of loop if (sensor is low again):
nothing happens -> motors stay on
To fix this make sure the else belongs to the correct if!
You want to turn the motors off when the sensor is low, not when the sensor is high and was high before.
Also the prints should be placed befor the delay. What's the point of printing "motion detected" 5 seconds after you actually detected it.

ARDUINO pin is constantly changing from HIGH to LOW?

I used this code to check the state of Arduino pin 8.
To see if the pin is High or Low but my output continuously changes from high to low.
I am not connecting anything to pin 8 while running this code.
const int Pin = 8;
int Reading=0;
void setup() {
Serial.begin(9600);
delay(2000);
pinMode(Pin, INPUT);
}
void loop() {
Reading = digitalRead(Pin);
if(Reading == HIGH)
{
Serial.println("HIGH");
delay(2000);
}
if(Reading == LOW)
{
Serial.println("LOW");
delay(2000);
}
}
But my Output Comes like this:
OUTPUT:
HIGH
HIGH
LOW
LOW
HIGH
HIGH
LOW
LOW
HIGH
HIGH
LOW
LOW
HIGH
HIGH
LOW
LOW
Don't know what to do ??
This is the correct behavior.
Since you don't connect the pin the read should be undefined (meaning it's unstable). Check "floating" state to learn more.
If you want to make it stable, consider using the internal pull-up resister. Change the line
pinMode(Pin, INPUT);
to
pinMode(Pin, INPUT_PULLUP);
to make it always HIGH while disconnected. In this case you should consider the internal pull-up resistance when you actually try to connect the pin.
The official Arduino documentation provides more detailed descriptions on each GPIO states.
As the internal pull ups are weak, sometimes adding
pinMode(Pin, INPUT_PULLUP);
won't solve the problem so you need to add a 10K or higher value resistance between pin and ground/power to initially make the pin pull up or pull down.

Arduino analogWrite() between two pins only working in one direction

I have a set of leds that are setup every other led reversed so when I apply power one way light 1,3,5... light. Change power and 2,4,6... I'm trying to set the brightness using PWM on the digital pins. Here's my code:
unsigned long flashCount = 0;
bool bSwitch = true;
void setup()
{
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
}
void loop()
{
if((flashCount + 1000) < millis())
{
if(bSwitch)
{
analogWrite(6, 0);
analogWrite(7, 1);
bSwitch = false;
}
else
{
analogWrite(7, 0);
analogWrite(6, 1);
bSwitch = true;
}
flashCount = millis();
}
}
If I change analogWrite to 255 instead of 1, it will switch both sets of leds. If I change analogWrite to 127 or less, only one set will light. If I switch the led wires to the pins, the problem switches to the other set of lights.
The leds are like so:
GPIO pin 6 --------.-LED+.---.-LED+.---.-LED+.---.-LED+.---|
GPIO pin 7 ---.+LED-.---.+LED-.---.+LED-.---.+LED-.--------|
Change the connection of the LEDs to pins that both support PWM.
Not all pins support PWM. The analogWrite documentation specifies which pins depending on which board:
On most Arduino boards (those with the ATmega168 or ATmega328P), this function works on pins 3, 5, 6, 9, 10, and 11. On the Arduino Mega, it works on pins 2 - 13 and 44 - 46. Older Arduino boards with an ATmega8 only support analogWrite() on pins 9, 10, and 11.
The other factor is that analogWrite(255) and analogWrite(0) will revert to driving the output as a digital output. So writing 255 causes both pins to output (one as a digital output and the other in PWM mode). But writing 1 to 127 only causes the PWM capable pin to change.
From arduino's manpages:
Syntax
analogWrite(pin, value)
Parameters
pin: the pin to write to. Allowed data types: int.
value: the duty cycle: between 0 (always off) and 255 (always on). Allowed data types: int
Using an analogWrite with a value of 1 is essentially near-zero. 255 would be full voltage. You're attempting to use analogWrite() as if it was digitalWrite().
Consider using digital write instead in your code: https://www.arduino.cc/reference/en/language/functions/digital-io/digitalwrite/
As for your LED's behavior, it seems like your circuit needs to be debugged as well: Your circuit will only allow current to flow when pin 7 is on. Diodes (Light Emitting Diodes) only allow current in one direction. If you're intending to have the LED's alternate, they should all be oriented with the positives pointing toward their GPIO pin and where they meet they should be grounded with a pull-down resistor.

Resources