Author Topic: A Simple Fan Timer with a NANO  (Read 1918 times)

0 Members and 1 Guest are viewing this topic.

OperaHouse

  • Hero Member
  • *****
  • Posts: 1084
  • Country: us
A Simple Fan Timer with a NANO
« on: September 13, 2016, 10:28:03 AM »
It doesn't have to be complicated to be useful.  These two programs may be the kiddie
table of programming but can serve a purpose at low cost.  They are also good demonstrator
programs and can serve as a boiler plate for other programs.  I always start with copying
some existing program that has some of the routines that will be used.  It is hard to
remember the structure and where things are placed if you are not programming all the
time.  I'm a finger by finger typer, cut and paste saves a lot of time.  Most programs
center around some timing.  In my home program there is a pump section.  Every 50 minutes
I turn on a pump for a period of time if the voltage is over 14V. 14V insures me that
there are no other demands on the battery.  It happens often enough there is never an
issue.

I made my wife a box fan with three computer fans to give a breeze when she sleeps.
She is always worried that she will leave it on all night.  It usually cools off a
bit at night.  I just got three NANO Arduinos that cost about $2.35 each and was
looking for a project.  The first is truly the kiddie table of programming.  Using
a simple delay statement the fan is turned off in 66 minutes. The hardware is fairly
simple.  I use six diodes in series to drop the voltage down to about 9V.  Add a
capacitor to filter out any noise and power it on Vin. The drive for a FET 9is on
pin 13 which also happens to be the on board test LED.I always like to drive
through a couple hundred ohm resistor to protect the micro should the drive
become accidently shorted to commom.  As you can see, no need to be fancy.  Note that
I use a smaller test value to see if the program is working as expected and the values
are sent out the serial USB cable to be read in TOOLS.

// This program turns the LED pin# 13 on for one hour

 int second  = 0;
 int count   = 0;
 
 //int endtime = 40;               // quick test value
 int endtime = 3600;             // 60 seconds X 60 minutes
void setup() 
{
   Serial.begin(9600);           //  setup serial
   pinMode(13, OUTPUT);          // sets the digital LED pin 13 as output
   pinMode(3, OUTPUT);           // sets the PWM digital pin as output
}

 
void loop()  {                                         
                           
   
    delay(1000);                                        // waits for a second
   
   
    if (second <= endtime) digitalWrite (13, 1);        // turn on fan
   
    if (second > endtime) digitalWrite (13, 0);         // turn off fan
   
    if (second > 32000) (second = 32000);               // limit upper count to
                                                        // prevent restart when
                                                        // counter over runs
   
    second = second + 1;                                // increment count
   
    Serial.println(second);                             // debug value 
   
}   
 

This second fan program is more interesting.  The longest time you want to run the
fan is entered into the program.  It then calculates 2/3 of that time to start a ramp
down of speed.  The MAP routine then calculates the PWM value that is needed for each
second.  This MAP function is worth the price of admission. It would take a lot of head
scratching to figure out the logic needed to replicate that.  They have done all the
work for you.  This is very handy for sensor conversion like 4-20 ma. Just enter the
two extremes of the of the sensor A/D and what real world values the represent.  255
is fully on and 100 is about the lowest useful speed. The PWM speed for this port is
factory set at 490Hz.  This routine in the beginning changes the timer used in PWM port
3 & 11 down to 30Hz.  This makes the PWM noise bairly audible.  With that change the this NANO
is operating with three PWM speeds 980, 490, and 30Hz.  Pins 5 & 6 are normally 980hZ.  If you
change the timing on these it messes with program delays, AVOID.  980 is nice for PWMing relays.  Pictures later.


// This program flashes the LED pin# 3 on every second
// Calculates the ramp time & ramp PWM values to send out
// on PWM pin 3 operating at 30Hz

 int second   = 0;
 int count    = 0;
 int PWM3     = 0;
 
 int state    = 0;
 int ramptime = 0;
 //int endtime  = 100;              // quick test value
 int endtime = 4000;             // 60 seconds X 66 minutes


void setup() 
{
   Serial.begin(9600);              //  setup serial
   pinMode(13, OUTPUT);          // sets the digital LED pin 13 as output
   pinMode(3, OUTPUT);            // sets the PWM digital pin as output
}

 
void loop()  {   
 
    // Pins 11 and 3 for 16MHz clock
    // Setting  Divisor    Hz
    // 0x01         1         31250
    // 0x02         8       3906
    // 0x03         32      976
    // 0x04         64      488
    // 0x05         128     244
    // 0x06         256     122
    // 0x07         1024    30.5
   
    // TCCR2B = TCCR2B & 0b11111000 | <setting>;
   
    TCCR2B = TCCR2B & 0b11111000 | 0x07;
   
    ramptime = 2 * endtime / 3;                // make beginning of ramp 2/3 of endtime
   
                                                              // to flash LED every second
    if (count > 10)                                    //  ten counts = 1 second
    {
       count  = 0;                                      // reset count
       second =  second + 1;                     // increase second count                         
    }
   
    delay(100);                                         // waits for a 1/10 second
                                                               // you could insert a lot of program
                                                               // steps and use that as your delay
                                                               // just measure how many counts it takes
                                                               // to make a second.
   
    PWM3 = map (second, ramptime, endtime, 255, 100);   // calculate ramp dowm
 
    if (second < ramptime  && count == 1) PWM3 = 255;   // turn fan on
    if (second >= endtime) PWM3 = 0;                              // turn fan off
   
    if (second > 32000) (second = 32000);               // limit upper count
   
    if (PWM3 >255) PWM3 = 255;                          // limit upper PWM
    if (PWM3 < 0) PWM3 = 0;                             // limit upper PWM
    analogWrite (3, PWM3);                              // output state
   
    count = count + 1;                                     // increment count
   
    if (count == 2) Serial.print(second);            // debug value
    if (count == 2) Serial.print("S    PWM ");       // debug value 
    if (count == 2) Serial.println(PWM3);            // debug value
   
    digitalWrite(13, 0);                                      // sets the LED off
    if (count == 2) digitalWrite(13, 1);              // sets the LED on at 1 second intervals
}   
 
« Last Edit: September 13, 2016, 10:36:36 AM by OperaHouse »

Bruce S

  • Global Moderator
  • Super Hero Member Plus
  • *****
  • Posts: 4577
  • Country: us
  • USA
Re: A Simple Fan Timer with a NANO
« Reply #1 on: September 13, 2016, 12:27:48 PM »
I have to say,, even the kidde table is much easier to understand  than my //millis timer.
The 2nd one I'm still ciphering . There just seems to be so many ways of going about this. There's allot to take in.
could be I'm trying to over think things.

Copy n paste in my "FRIEND"
Cheers
Bruce S

PS>> This is my new favorite website "https://www.arduino.cc/en/Reference/HomePage "
A kind word often goes unsaid BUT never goes unheard

OperaHouse

  • Hero Member
  • *****
  • Posts: 1084
  • Country: us
Re: A Simple Fan Timer with a NANO
« Reply #2 on: September 14, 2016, 07:48:30 AM »
There are many methods that can be used.  I think it was a mistake to move it to diaries where it will get lost. You program is more accurate, but has the techy appearance that can scare people.  I used that for a SUN distributor machine that would read out degrees for each firing of a distributor.  Most things do not require precise timing. One of my minutes got close to two minutes when I added more program. I don't like introducing things like  TCCR2B to change the PWM timer early on. Even mixing longs and unsigned can cause problems for beginners as they copy from one program to the next and forget how the first was set up.  I like to have every line stand its own.  Often I will have a series of if's operating on the same variable. The last one wins.

Bruce S

  • Global Moderator
  • Super Hero Member Plus
  • *****
  • Posts: 4577
  • Country: us
  • USA
Re: A Simple Fan Timer with a NANO
« Reply #3 on: September 14, 2016, 01:46:08 PM »
I may move it back, I was more worried the pics and ramblings would muddle the posts.

As winter approaches and harvesting/canning/ ground care rushes towards us, work at home is limited.
I've begun using Arduino's portable program. Pretty sweet! Works on one of my many 1Gig CF cards with room to spare.

I especially like using the verify part. I can add code , then verify, add a little more , etc.

I do have a FAN question:  You are using the PWM (analogWrite) to run your fan(s)? Are you triggering the power connection via FET on the pos or neg leg?
 
My thought is to use it, start the fan(s) around 12Vdc then step them down using the PWM mode.

 Going way too far into it, I'd like to read the battery voltage and allow the fan(s) to either start their run on a lower voltage or not at all depending on measured battery voltage. (still trying to decide if I want to go with my durable NiCDs or switch over to Li )

Cheers
Bruce S 
 
A kind word often goes unsaid BUT never goes unheard

OperaHouse

  • Hero Member
  • *****
  • Posts: 1084
  • Country: us
Re: A Simple Fan Timer with a NANO
« Reply #4 on: September 15, 2016, 11:43:57 AM »
Negative leg with FET to common -.

Here is another way to change power levels that combines elements of the
first and second programs. It is a manual PWM that may seem clunky but is
probaly more useful to people that have an inverter running all the time
and want to use a space heater or water heater as a dump load. The UNO's
PWM can not be used with solid state relays even if you slow it down a
bunch.  Any time you mix two frequencies the result will be the sum and
the difference.  With a zero crossing relay this becomes even more
complicated. One option is monitor the power line and fire the scr at a
certain phase angle.  It is much easier to just take a time period like
a second or more and turn on for a percentage.  It divides the time period
into 12 sections.  At each count it checks the power level and turns on if
it matches.  At the end it turns off if it is at less than full power.  A
heating element will average this power.  Some inverters control loop may
balk at a load being turned on and off at certain rates.  The time period
may be lengthened or shortened in that event.

// FAN05
// This program flashes the LED pin# on a long PWM of a second
// or more Calculates the ramp time & ramp values to send out
// on LED pin 13.  This is for heating elements working on line power.

 int second     = 0;
 int count      = 0;
 int powerlevel = 0;
 
 int ramptime = 0;
 int endtime  = 100;              // quick test value
 //int endtime = 4000;             // 60 seconds X 66 minutes

void setup() 
{
   Serial.begin(9600);               //  setup serial
   pinMode(13, OUTPUT);          // sets the digital LED pin 13 as output
}

 
void loop()  {   
   
    ramptime = 2 * endtime / 3;          // make beginning of ramp 2/3 of endtime
   
    if (count > 12)                               // 12 counts = 1 second
    {                                                  // this bracket indicates start of actions
                                                        // when IF is true
       count  = 0;                                // reset count
       second =  second + 1;                // twelve counts = 1 second                         
    }                                                   // end of those operations
   
    delay(82);                                       // waits for a 1/12 second
   
   
    powerlevel = map (second, ramptime, endtime, 12, 0);   // calculate ramp powerlevel
 
    if (powerlevel < 0) powerlevel = 0;                   // insure powerlevel is within range
    if (powerlevel > 12) powerlevel = 12;
   
    // digitalWrite is used with digital pins.  Do not confuse with analogWrite for PWM.
    // The higher the powerlevel, the longer LED stays on.
   
    if (count == 1 && powerlevel == 12)digitalWrite (13, 1) ;  // turn fan on
    if (count == 2 && powerlevel == 11)digitalWrite (13, 1) ;  // turn fan on
    if (count == 3 && powerlevel == 10)digitalWrite (13, 1) ;  // turn fan on
    if (count == 4 && powerlevel == 9) digitalWrite (13, 1) ;  // turn fan on
    if (count == 5 && powerlevel == 8) digitalWrite (13, 1) ;  // turn fan on
    if (count == 6 && powerlevel == 7) digitalWrite (13, 1) ;  // turn fan on
    if (count == 7 && powerlevel == 6) digitalWrite (13, 1) ;  // turn fan on
    if (count == 8 && powerlevel == 5) digitalWrite (13, 1) ;  // turn fan on
    if (count == 9 && powerlevel == 4) digitalWrite (13, 1) ;  // turn fan on
    if (count == 10 && powerlevel == 3)digitalWrite (13, 1) ;  // turn fan on
    if (count == 11 && powerlevel == 2)digitalWrite (13, 1) ;  // turn fan on
    if (count == 12 && powerlevel == 1)digitalWrite (13, 1) ;  // turn fan on
   
    if (count == 0 && powerlevel < 12)  digitalWrite (13, 0);   // turn fan OFF at end of cycle
                                                                                         // when power level is less than 12
     
   
    //                       SEND DATA TO SERIAL IN TOOLS
    //           Printing takes time.  Comment out this in final working program.
    //           There are two options; every second or every count.
    //if (count == 0) Serial.print(second);                      // debug value 1 per second
    //if (count == 0) Serial.print("S    Power level ");         // debug value 
    //if (count == 0) Serial.println(powerlevel);                // debug value
 
    Serial.print(second);                      // debug value every count
    Serial.print("S    Power level ");         // debug value every count
    Serial.print(powerlevel);                  // debug value every count
    Serial.print("    count= ");               // debug value every count
    Serial.println(count);                     // debug value every count
   
    if (second > 32000) (second = 32000);            // limit upper second count or use
                                                                         //unsigned int or long for higher count
    count = count + 1;                                         // increment count
}   
 

OperaHouse

  • Hero Member
  • *****
  • Posts: 1084
  • Country: us
Re: A Simple Fan Timer with a NANO
« Reply #5 on: September 17, 2016, 10:20:42 AM »
Just need to connect three pins. Don't have to be pretty!