Reputation: 43
I would like to execute a function for X seconds every Y seconds on Arduino.
I'm trying to control a resistance to heat up some water in a constant rate (1o Celsius per minute), so what I thought was: I'll measure what is the rate when it's running for the whole minute and then I'll adjust it to the desired rate.
Let's say it heats up 5o celsius per minute, so I would like to activate the resistance for 60/5 seconds, but not all at once, I was thinking about activating the resistance for 1 second every 12 seconds to keep the rate constant for no matter what (if the day is too cold, too hot, if I change my equipment etc.)
Do you guys think this is possible? If not, any ideas how can I make it work? I saw the Timer.h library but it doesn't seems to solve my problem =/
Thanks in advance, please let me know if any information can be useful!
Upvotes: 4
Views: 5605
Reputation: 121
There's a good PID library for Arduino available here, with extensive documentation: http://playground.arduino.cc/Code/PIDLibrary
That page also does a decent job of explaining the theory behind it, but if it's not quite clicking, I suspect that Wiki can address the background stuff better than I can: http://en.wikipedia.org/wiki/PID_controller
However, that might all be moot given the resistor in question. Given that the max output of an Arduino pin is 5V, you'd then be looking at outputting 1000 A. But those same pins have an approximate max current of about 40 mA. So if you actually want to push that 5000 W margin, you'll need to be separating the power supplies for the Arduino and the resistor, which probably means using a relay to gate power to the resistor. But since a relay is an on-off deal, you wouldn't be able to use analogWrite() anymore. The PID still may work, though - see this example from that same library: http://playground.arduino.cc/Code/PIDLibraryRelayOutputExample . I've never personally tried working with relays that large, so I can't speak to the feasibility of this approach.
Let me know if you'd like any more help with the power supply issues.
Upvotes: 1
Reputation: 121
I think the easiest approach would be to use the millis() function. Here's one example, but this will depend on how your control is operating.
const int onTime=1000; // in ms
const int offTime=12000; // in ms
const int resistorPin=7; // Change as necessary
boolean currentlyOn=false;
unsigned long startTime;
void setup(){
pinMode(resistorPin,OUTPUT);
digitalWrite(resistorPin,LOW);
startTime=millis(); // Initialize
}
void loop(){
if (currentlyOn && millis()>startTime+onTime){ // Switch resistor off
digitalWrite(resistorPin,LOW);
currentlyOn=false;
startTime=millis(); // Reset timer
}
if (!currentlyOn && millis()>startTime+offTime){ // Switch resistor on
digitalWrite(resistorPin,HIGH);
currentlyOn=true;
startTime=millis(); // Reset timer
}
delay(10);
}
I have no idea if this is going to work as far as controlling the temperature, since I would expect there to be significant non-linearities involved in that, but at least the resistor would do what you want. If you really want to control the temperature, I would suggest a feedback loop in which you measure the temperature and adjust accordingly (maybe with a PID controller?). But that's of course much more complicated.
EDIT: A few additional thoughts: The reason I suggested the millis()-based approach was because it allows you to have other code executing while you wait, making it more versatile. But if you don't need that, you can always just go super-simple and use delay():
void loop(){
digitalWrite(resistorPin,HIGH);
delay(onTime);
digitalWrite(resistorPin,LOW);
delay(offTime);
}
Lastly, you could also just hook the resistor up to a PWM pin and use analogWrite() instead, keeping the resistor constantly activate at a low level.
Upvotes: 6