-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);
}
Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81
kwhunter
  • 23
  • 10

2 Answers2

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.

MAB
  • 111
  • 3
0

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.

Delta_G
  • 3,391
  • 2
  • 13
  • 24