-1

I have 2 sketches that control a fan using Arduino UNO, that I try to combine. The 1st is a timer, that turns a pin ON and OFF for a determined period of time. The pin signal drives a MOSFET that in turn switches a small fan ON and OFF. Since I need to control the speed of the motor, I would rather use the PWM control, however I am not sure how I can apply the timer since analogWrite command refers to a pin and value. Thanks

timer code:

const byte relayPin = 6; // relay module on pin 6
const byte monitorPin = 13; // builtin LED output
const unsigned long interval_1 = 1000UL * 15, interval_2 = 1000UL * 15; // ON timer + OFF timer in milliseconds
unsigned long currentMillis, previousMillis = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH); // relay OFF
  pinMode(monitorPin, OUTPUT);
  digitalWrite(monitorPin, LOW); // LED off
}

void loop() {
  // put your main code here, to run repeatedly:
  currentMillis = millis();
  if (currentMillis - previousMillis >= interval_1)
  {
    digitalWrite(relayPin, LOW); // relay ON
    digitalWrite(monitorPin, LOW); // LED on
  }
  if (currentMillis - previousMillis >= (interval_1 + interval_2))
  {
    digitalWrite(relayPin, HIGH); // relay OFF
    digitalWrite(monitorPin, HIGH); // LED off
    previousMillis = currentMillis; // reset
  }

PWM code:

int PWMControl= 6;
int PWM_Input = A0;

int PWM_Value = 0 ;

void setup() {
  pinMode(PWMControl, OUTPUT);
  pinMode(PWM_Input, INPUT);
}

void loop() 
{
  PWM_Value = analogRead(PWM_Input);
  PWM_Value = map(PWM_Value, 0, 1023, 0, 255);
  analogWrite(PWMControl, PWM_Value);
}
  • Thanks for the hand with editing the code – kwhunter Jul 2 '19 at 19:11
  • I don't really understand, what your problem is. have you tried to just pu the analogwrite into the timer code? – chrisl Jul 2 '19 at 20:04
  • chris1 - I did and it did not work; just replacing digitalWrite with analogWrite doesn't do the trick: the fan runs continually whereas the LED follows the timing – kwhunter Jul 2 '19 at 22:06
  • Then please provide your combined code and describe how it does not work. What are you expecting to see? And what do you actually see? – chrisl Jul 3 '19 at 6:25
  • 1
    Then show us your combined code, since that is the problematic code – chrisl Jul 3 '19 at 16:51
1

Don't think of what you have as a "timer". That's not what it really is. What you have is a loop function that repeats itself thousands of times per second and an if statement that asks "is it time to do this yet". So if you want to use analogWrite instead of digitalWrite when it is time to do that thing then use analogWrite instead. It doesn't change your timing setup one bit. Just replace the digitalWrite calls with analogWrite calls. If you want to read your pot at the same time then put that in there as well. Basically everything inside the block of code controlled by that if statement is going to happen every time that interval passes no matter what it is that you put there. If you want something to print every interval then you could put a print statement in there. If you want it to call some custom function every interval then call that function in there. There's nothing special about that way of timing that only works with digitalWrite.

| improve this answer | |
1

If I understand correctly, this is what you want to do:

  1. Fan + led off for 15s
  2. Fan on (speed determined by A0) + led on for 15s
  3. Repeat

clearly defining your goal in english can help with coding, so I hope I guessed right.

here's my suggestion for your code

 const byte controlPin = 6; // MOSFET on pin 6
 const byte monitorPin = 13; // builtin LED output
 const unsigned long interval_1 = 1000UL * 15, interval_2 = 1000UL * 15; // ON timer + OFF timer in milliseconds
 unsigned long currentMillis, previousMillis = 0;
 int PWM_Input = A0;
 int PWM_Value = 0 ;

 // setting pin direction and default state
 void setup() {
   pinMode(controlPin, OUTPUT);
   digitalWrite(controlPin, HIGH); // MOSFET OFF
   pinMode(monitorPin, OUTPUT);
   digitalWrite(monitorPin, LOW); // LED off
 }

 // run fan for a while, then stop fan for a while
 void loop() {

   currentMillis = millis();

   //fan on, led on, both signals active low
   if (currentMillis - previousMillis >= interval_1){
       PWM_Value = analogRead(PWM_Input);
       PWM_Value = map(PWM_Value, 0, 1023, 0, 255);
       analogWrite(PWMControl, PWM_Value);
       digitalWrite(monitorPin, LOW);
   }

   //fan off, led off, reset timing
   if (currentMillis - previousMillis >= (interval_1 + interval_2)){
      digitalWrite(controlPin, HIGH); // MOSFET OFF
      digitalWrite(monitorPin, HIGH); // LED off
      previousMillis = currentMillis; // reset
   }
 }

There are still issues I can with this code:

  1. You did not tell us what type of MOSFET you are using, so I can't tell if it is actually active low
  2. I believe that the LED on most arduino boards (pin 13) is active high, so that's probably wrong
  3. Don't forget comments. I find comments more useful for a block of code than for a single line, but you can do both if you want ;)
  4. I find your code convoluted regarding millis logic, for me it would be more logical to have something along the lines of:

     current = millis()-previous
     if current < interval1 
        fan off
     elseif current < inteval1+interval2
        fan on
     else
        previous = millis() 
    

It would be more readable for a human, the result on the arduino would be similar.

| improve this answer | |
  • you've got it right; I use a BUZ11 N-channel MOSFET to control the fan. The code as it is now, works fine: the LED is on only when the fan is on. I tried replacing the digital Write with the analogWrite as suggested but it didn't work so that's why I posted the code here. It's obvious I'm not an experienced programmer... – kwhunter Jul 2 '19 at 21:06
  • @kwhunter have you tried to use the Serial monitor to make sure your initial program does what you think it does? It's extremely useful to debug arduino code. A few thing to monitor: does the fan turn on/off when you think your code turns it on/off. You also should monitor the PWM_Value before and after map, to make sure you are feeding analogWrite with the proper parameter. These would be the first things I look at. – MAB Jul 3 '19 at 0:17
  • No I did not, application not critical; for the record, I use the fan to move around the air in the Humidor for the temperature and humidity to even out. Current setting is 1 minute ON and 15 minutes off. – kwhunter Jul 3 '19 at 16:51
  • Thinking back at my note#4, the resulting program would actually be different, since while the fan is on, it would immediately react to a change on A0, which is arguably better. your initial program with the on-off structure would have been easily implemented with delay() - also if you plan to run this program for a very long time, you will have an unexpected behavior when millis() overflows. – MAB Jul 3 '19 at 17:14
  • I made some edits to your program since the fan was ON all the time and when timer 2 kicked in it changed speed since A0 controlled it; now it works as it should, thanks. Aren't the millis() reset each cycle? if not what can I do to prevent the overflow? – kwhunter Jul 3 '19 at 17:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.