DC motor control with Arduino and relay shield- coding question
-
Trying to run a DC motor with an Arduino UNO and a relay shield - need help with the code! I'm using a relay shield (this one: http://tinyurl.com/pv23nve) on top of my Arduino Uno to run a DC motor for a specific amount of time after a button press. After that time, the motor should shut off. This is the code I've come up with after much struggling, but it still doesn't work (just turns on the motor for the 'long offDelay' value, then turns off, after which the button just turns the motor on for as long as it's pressed): byte relayPin = 7; //D7 -> RELAY2 volatile long lastSwitchtime = 0; long offDelay = 5000; //change this to increase/decrease delay void setup(){ attachInterrupt(1, active, CHANGE); pinMode(relayPin, OUTPUT); lastSwitchtime = millis(); } void loop(){ if ((millis() - lastSwitchtime) > offDelay) { digitalWrite(relayPin,LOW); } else { digitalWrite(relayPin,HIGH); } } void active() { lastSwitchtime = millis(); } any suggestions?
-
Answer:
I don't work with Arduino and I'm sure it probably has a safeguard about code like this (especially with timer interrupts) but I get really nervous when the main loop is running flat-out as fast as possible and possibly not letting other things get updated. I know the example code you're basing your work from does this. What happens if you skip reading the millisecond timer and do something like this instead?byte relayPin = 7;long motor_run;void setup() { attachInterrupt(1, active, CHANGE); pinMode(relayPin, OUTPUT); digitalWrite(relayPin,LOW); // start with output OFF. motor_run = 0; // start with time bucket empty}void loop() { if (motor_run > 0) { digitalWrite(relayPin,HIGH); // turn relay ON, motor runs. motor_run--; // drain the bucket } else { digitalWrite(relayPin,LOW); // no more time left, it's off } sleep(1); // come back in 1 mSec}void active() { motor_run = 5000; // mSec to run the motor}The idea here is to fill a "bucket" with milliseconds to count down. If the bucket has milliseconds in it, the output is switched on. Pressing the button refills the bucket. The sleep(1) does the work of watching the clock and coming back when it's time to loop.
AutoPilot83 at Ask.Metafilter.Com Visit the source
Other answers
In general, you might try asking this sort of thing over at the http://arduino.stackexchange.com/, or just generic http://stackoverflow.com, considering this is really a programming question and your hardware seems fine. All your logic seems sound to me -- store the last time the value of input1 changed, and if lastchangetime + runtime < current-time, turn on the output pin. It seems like you might want to make sure you are using https://www.arduino.cc/en/Reference/AttachInterrupt correctly? Right now you're triggering on any change; you might want to try RISING so the timer is only triggered when the button is pushed, rather than as long as the button is held? In general, when dealing with physical switches, you need to worry about https://www.arduino.cc/en/Tutorial/Debounce your inputs, but I don't think a bouncing problem would cause what you're seeing. You might look at comparisons of longs in Arduino-flavored C -- maybe do something like (millis() - lastSwitchTime) < offDelay? That's cargo-cult-y on my part; I have no reason to believe it would work but I'd try it. I have to run to work, so I can't add more now. Apologies if I'm missing some really basic logic error, I'm writing in a hurry. Cheers and good luck!
Alterscape
Oh also, try using your digital pin to switch a LED (through a transistor, yatta yatta) to make sure your problem really is timing on the MCU and not some weird hardware boojum. It doesn't sound like a weird hardware boojum, but who knows.
Alterscape
Seems to me like your interrupt isn't getting triggered. As an interim thing, how about tracking the state of your switch pin (1) in the main loop, and resetting your motor based on that? Set an output pin based on that input pin state and make sure the input is getting read? And I don't think you need to worry about debouncing your button, because the worst that happens with a few spurious bounces is that your timer gets reset to a little longer.
straw
Joe, this makes so much more sense. The analogy helps tremendously.
AutoPilot83
Glad to help. So, does it work? =)
JoeZydeco
Related Q & A:
- How do identify an Arduino counterfeit?Best solution by Electrical Engineering
- How to send an email with Arduino and a WiFi shield?Best solution by Arduino
- How to relay all local mail through external SMTP relay?Best solution by Server Fault
- Birth control question?Best solution by Yahoo! Answers
- How much does Blue Cross Blue Shield pay?Best solution by wiki.answers.com
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
For every problem there is a solution! Proved by Solucija.
-
Got an issue and looking for advice?
-
Ask Solucija to search every corner of the Web for help.
-
Get workable solutions and helpful tips in a moment.
Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.