I need help with an Arduino sketch , I want to repeat the blink sketch for a specified amount of time (3minutes for example) , then Stop .As we know , the loop() keeps runing forever which is not what I want . Any ideas how I can achieve this , blinking an LED for X minutes and Stopping ?
You should probably make use of some timer library. A simple (maybe naive) way to achieve what you want to do is to make use of a boolean that is set to 0 when 3 minutes has passed or simply digitalWrite the led to low when the timer has passed.
Check this link:
http://playground.arduino.cc/Code/Timer
I suggest that you use int after(long duration, callback).
Below is a (very) simple example of how you probably could do:
#include "Timer.h"
Timer t;
LED = 1;
void setup() {
int afterTime = t.after(180000, cancelLED);
}
void loop() {
t.update();
if(LED) {
//The "write HIGH" statement in your sketch here.
}
else {
//Write the led to LOW
}
}
void cancelLED() {
LED = 0;
}
I haven't used the library myself, I just checked the the docs and wrote an example to give you some ideas. Don't expect it to work right away.
Related
I am working on a school project for which I rotate a servo after a cable disconnects and a specific delay is over. This is my current code. We are using an Arduino Uno powered from the USB port
#include <Servo.h>
int reader=4;
int servo1Pin=8;
Servo servo1;
int value;
int pos=10;
int wacht=5000;
void setup() {
pinMode(reader, INPUT);
servo1.attach(servo1Pin);
}
void loop() {
value = digitalRead(reader);
servo1.write(pos);
if (value == LOW) {
delay(wacht);
pos=180;
}
else {
pos=10;
}
}
wacht is the specific delay. When we disconnected pin 4 to break that circuit we don't have a consistent time between the interruption of the power flow and the opening of the servo. It seems to vary from anywhere between 5 to 40 seconds of delay after triggering. Does anyone have any ideas to solve this issue?
try change
pinMode(reader, INPUT);
to
pinMode(reader, INPUT_PULLUP);
And for clarification delay don't use timer.
The order of your instructions seem strange. the usual order is:
Read
Decide
Act
Also, you may want to avoid sending useless instructions to the servo. For example, when you know the servo is already in the correct position. You should not rely on eternal code to do the right thing. In other terms, you have no idea how long servo1.write() takes to execute.
Which would give for your loop()
void loop()
{
if (digitalRead(reader) == LOW)
{
if (pos != 180)
{
delay(wacht); // delay() is only called once, when circuit breaks.
// this guarantees immediate response when circuit
∕/ closes again.
pos = 180;
servo1.write(pos);
}
}
else if (pos != 10)
{
pos = 10;
servo1.write(pos);
}
}
Also, have a look and implement Peter Plesník's answer. This will probably solve some of your problems. You input will definitely still have a random lag of up to 5 seconds when closing the circuit, though.
Hey i got a bit problem with my Arduino and sensor
Here is what i tried ;
#define USE_ARDUINO_INTERRUPTS true // Set-up low-level interrupts for most acurate BPM math.
#include <PulseSensorPlayground.h> // Includes the PulseSensorPlayground Library.
#include <SoftwareSerial.h>
SoftwareSerial blue(0,1);
const int PulseWire = 0; // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
const int LED13 = 13; // The on-board Arduino LED, close to PIN 13.
int Threshold = 550;
PulseSensorPlayground pulseSensor;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
blue.begin(9600);
pulseSensor.analogInput(PulseWire);
pulseSensor.blinkOnPulse(LED13); //auto-magically blink Arduino's LED with heartbeat.
pulseSensor.setThreshold(Threshold);
pulseSensor.begin();
}
void loop() {
// put your main code here, to run repeatedly:
int myBPM = pulseSensor.getBeatsPerMinute();
if(myBPM>200){
myBPM-100;
}
if (pulseSensor.sawStartOfBeat()) {
Serial.println(myBPM);
blue.println(myBPM);
}
delay(10);
}
this code I got from the example library and modified it.
so i want to send data to my android using Bluetooth but this sensor kinda ticked me off because whenever i use it with my HC-06 Bluetooth module it suddenly got a hearth beat without i even touching it and it just sends so much data ignoring the delay I set.
I just need to slowly sending data just like a second but the data didn't show up
so anyone can help?
I read your code and I noticed this piece of code
if(myBPM > 200){ myBPM - 100; }
that is poorly written if (I understand correctly) you want to check the size of myBPM and if it is larger than 200 then it should be subtracted 100.
it should be:
myBPM = myBPM - 100; not myBPM - 100;
I hope my answer will help you. Have a nice day!
i am trying to make a stopwatch and counter project for arduino. Code aside, is this wired correctly?
The top button is to start the stopwatch, second is the button to start the counter (every press increases by one), and the bottom button should be to reset any of them. the green light is to show the stopwatch is selected and blue is to show the counter is selected. the lcd is to display everything obviusly. Also, what is the best way to learn to code this and how long would it take? Thanks.
This is the code as per your requirement. I have defined pins as per above connections. counter mode has minutes and seconds and it does not contain milliseconds as I am encountering problem to implement it. You can suggest me if you have got any way. Counter mode selection button is the same button which is going to be used to increment the counter.
#include <LiquidCrystal.h>
LiquidCrystal mylcd(7,6,5,4,3,2);
int counter_sel=12,stopwatch_sel=11,reset1=10,stopwatch_led=9,counter_led=8;
void setup()
{
mylcd.begin(16,2);
mylcd.setCursor(0,0);
mylcd.print("Counter and ");
mylcd.print("Stopwatch");
delay(1000);
pinMode(counter_sel,INPUT);
pinMode(stopwatch_sel, INPUT);
pinMode(reset1, INPUT);
pinMode(counter_led,OUTPUT);
pinMode(stopwatch_led, OUTPUT);
}
void loop()
{ int state1=digitalRead(counter_sel);
int state2=digitalRead(stopwatch_sel);
if (state1==0) {delay(300); counter(); } // call counter function
else if (state2==0) {delay(300); stopwatch(); } // call stopwatch function
}
void counter()
{ mylcd.clear();
digitalWrite(counter_led,1);
mylcd.setCursor(0,0);
mylcd.print("Counter Mode :");
short int i=0;
while(1)
{
int rst=digitalRead(reset1);
if (rst==0) { delay(300); break;}
int state1=digitalRead(counter_sel);
if (state1==0) { i++; delay(200);}
mylcd.setCursor(0,1);
mylcd.print(i);
}
digitalWrite(counter_led,0);
}
void stopwatch()
{
mylcd.clear();
digitalWrite(stopwatch_led,1);
long int ms=millis();
byte sec=0, mins=0;
mylcd.setCursor(0,0);
mylcd.print("Stopwatch Mode : ");
while(1)
{
mylcd.setCursor(0,1);
int state1=digitalRead(reset1);
if (state1==0){delay(300); break; }
if (sec==59) {mins++; sec=0;}
if ((millis()-ms)>1000) {sec++; ms=millis(); }
mylcd.print(mins);
mylcd.setCursor(3,1);
mylcd.print(":");
mylcd.setCursor(5,1);
mylcd.print(sec);
mylcd.print(":");
//mylcd.print(millis()-ms);
}
digitalWrite(stopwatch_led,0);
}
As much as I can see, and considering what you explained above, the connections are correct. But the thing is you need to make it clear as much as you can, because due to intersecting point in LCD connection, it would be very much harder to debug and resolve the connection problem, for that you must make it neat. To learn to code this stuff there is no rocket science, just use your wisdom, and start reading books, blogs, articles on arduino ide(which is too simple too use), c programming and microcontrollers , and youtube videos are the great source to learn to code, you should have handful experience of c programming, that's all.
I am using Pro Micro as a USB Host and moving the cursor to predefined positions on the screen with a delay of 5 seconds. I'm using the AbsMouse library for absolute mouse cursor positions. What I want is, when the analog input goes above 300, I want it to perform XYZ function. Because I'm using delays of 5000, I can't poll the analog input always.
Basically, I want the cursor to move to these absolute positions continuously in a loop. Whenever the analog value goes above 300, it should perform the press and release functions.
I am not able to understand how to use Elapsed millis() or interrupts. Please show exactly how can it be done in code.
Help Much appreciated.
#include <AbsMouse.h>
int sensorValue = 0;
void setup()
{
AbsMouse.init(1920, 1080);
}
void loop()
{
sensorValue = analogRead(A0);
AbsMouse.move(640, 127);
delay(5000);
AbsMouse.move(640, 400);
delay(5000);
AbsMouse.move(640, 625);
delay(5000);
AbsMouse.move(1280, 127);
delay(5000);
AbsMouse.move(1280, 400);
delay(5000);
AbsMouse.move(1280, 625);
delay(5000);
if (sensorValue >= 300)
{
AbsMouse.press(MOUSE_LEFT);
AbsMouse.release(MOUSE_LEFT);
}
}
Implementing a delay of 5 seconds measuring elapsed milliseconds and reading the analog value while waiting goes like this:
startTime = millis();
while(millis()-startTime < 5000) {
sensorValue = analogRead(A0);
if (sensorValue >= 300) {
AbsMouse.press(MOUSE_LEFT);
AbsMouse.release(MOUSE_LEFT);
}
}
This has two disadvantages that you'll have to solve if needed. The first one is that the click events will be performed while the value stays above 300 (i.e. it can click more than once). The second problem, is that this is not an exact delay of 5 seconds, as it can have a jitter due to the code being executed inside the while block.
Another option, as you mentioned, is to use timer interrupts to achieve a more exact delay. Using a library like TimerOne it goes like this (inspired from library examples and modified to execute every 5 seconds):
#include <TimerOne.h>
void setup(void) {
Timer1.initialize(5000000);
Timer1.attachInterrupt(fiveSeconds);
}
void fiveSeconds(void) {
// do stuff
}
The function fiveSeconds should be executed every 5 seconds, with more precision than the millis() approach.
Now you should add code to that function, to achieve what you want to do. I'd suggest to use loop() for reading the analog value and clicking, and the interrupt for moving the mouse cursor, but your approach might be different.
I'm trying to work with a simple Arduino circuit that increments a counter variable on pressing a push button in the circuit (connected as INPUT to PIN 8). My code is as simple as follows:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int c = 0, btnPIN, btnVal;
void setup ()
{
btnPIN = 8;
pinMode(btnPIN, INPUT);
lcd.begin(16,2);
lcd.clear();
}
void void loop()
{
btnVal = digitalRead(btnPIN);
if (btnVal == LOW)
{
c++;
lcd.clear();
lcd.print(c);
}
}
Problem is the counter increases by more than 1 every time I push the button. A little bit of printing on the serial monitor indicates that each time the button is pressed and the voltage is LOW, the conditional code is executed multiple times and the counter increases by multiple times instead of 1.
Maybe, I need to write some logic that checks if the button was initially unpressed, then pushed and then released again and then these steps would trigger the required action.
The solution I'm currently working with is as under (which works just fine):
int btnStatus = 0;
void loop()
{
btnVal = digitalRead(btnPIN);
if (btnVal == LOW)
btnStatus = 1;
if(btnStatus == 1 && btnVal == HIGH)
{
c++;
lcd.clear();
lcd.print(c);
btnStatus = 0;
}
}
I'm not sure if there's a simpler solution available or if this approach is wrong for other reasons? Any advice would be most welcome!
Another problem you you may be having is that mechanical buttons bounce. That is, they jump between two positions several times quickly before settling to a final position. This is standard operation so it is necessary to "debounce" the button.
There are very many ways to do this, but Here is a tutorial using an Arduino.
The main issue, as you probably figured out, is that the loop function is getting called multiple times while the button is down. This is what is fixed by your code, and yours looks to be a good solution and I don't really see a simpler way. For another way, though, perhaps you could try just adding a call to delay at the end of loop to slow it down a bit. You would have to play with the delay amount a bit, but it could work. Really though, your solution looks just fine.
Your idea is correct, you need to track the previous state of the button to know if it is a new press or if it is simply being held down. Your code could be rewritten to look more like a state machine, however:
typedef enum {
BTN_STATE_RELEASED,
BTN_STATE_PRESSED
} ButtonState;
ButtonState btnStatus = BTN_STATE_RELEASED;
void increment_counter()
{
c++;
lcd.clear();
lcd.print(c);
}
void loop()
{
btnVal = digitalRead(btnPIN);
switch(btnStatus)
{
case BTN_STATE_PRESSED:
// Handle button release
if(btnVal == HIGH)
{
btnStatus = BTN_STATE_RELEASED;
}
break;
case BTN_STATE_RELEASED:
// Handle button press
if(btnVal == LOW)
{
increment_counter();
btnStatus = BTN_STATE_PRESSED;
}
break;
}
}
This was rewritten to use an enum to track the state of the system (a bit overkill for a simple button, but an important concept to know in case your system grows more complex).
The code to update the display was also moved into its own function to make it better separated between the display change and the actual update of the state.