Controller for aerator - Solved

I have a boat that the timer module for the aerator is not working. I can switch it to manual and operate it that way but if I'm busy fishing I really will not be thinking about turning it on periodically. That's where the timer module comes in. I'd like it to have 4 selections which are 1m on/10m off, 1m on/7m off, 1m on/5m off, and 1m on/3m off. Those times are a starting point and may change but that's what I want to do. I haven't done anything with arduino in a while so I will all but be starting over with it. I'll pick up on this quickly as my memory gets refreshed so any help is greatly appreciated.

I'm not sure if the control code needs to be in the setup section or the loop section. I really don't know where to start to tackle this project. I need to define input pins from the rotary switch and output pins for the LED and relay.

If someone can guide me in the right direction I would be grateful.

Thanks.

The "timing" would be in loop().

Not sure what an aerator is exactly and what it requires electrically.

Sorry for not mentioning voltages. The system is 12v and will utilize a linear regulator to power the arudino.

Can you still use the relay from the original system?

Paul

I don't know what the original one actually incorporated. This is in a 1987 Bass Tracker boat and the module is a blue plastic housing with the circuit potted. I wish I knew if it could be de-potted but if it doesn't work now I don't think I can make it work afterwards. Either way, short answer is no. It may or may not have a relay but I think it probably is some simple circuit. The original module's timing was controlled with a 500k pot that had been badly corroded. I only know it was that value as I had to completely disassemble it and test the trace inside.

I have started out with the blink sketch to try and re-educate myself on this stuff. I really wish I had not gotten away from it for so long. Such a waste to learn only to forget.

bigone5500:
I don't know what the original one actually incorporated. This is in a 1987 Bass Tracker boat and the module is a blue plastic housing with the circuit potted. I wish I knew if it could be de-potted but if it doesn't work now I don't think I can make it work afterwards. Either way, short answer is no. It may or may not have a relay but I think it probably is some simple circuit. The original module's timing was controlled with a 500k pot that had been badly corroded. I only know it was that value as I had to completely disassemble it and test the trace inside.

I have started out with the blink sketch to try and re-educate myself on this stuff. I really wish I had not gotten away from it for so long. Such a waste to learn only to forget.

The aereator must have a motor running an air pump. Right? Then you need a relay of some type to control power to the motor.

Paul

Correct. I have a relay module which uses the 5v output from the arduino to turn it on and off. There are 3 input and 3 output pins which will be used. I am currently trying to learn how to write my timing part of the sketch. I will absolutely need assistance with that part.

Here is what I have so far:

/* The purpose of this sketch is to control the on/off times for an aerator according to the input.
 *  The purpose is to control the on/off times according to the input.
 *  There are 3 selections possible.
 *  1 is on for 1 minute and off for 10.
 *  2 is on for 1 minute and off for 7.
 *  3 is on for 1 minute and off for 5.
 */
void setup() {
  const int timerpin1 = 8;
  const int timerpin2 = 9;
  const int timerpin3 = 10;
  const int relaypin = 2;
  int ledpin = 11;

  pinMode(timerpin1, INPUT);
  pinMode(timerpin2, INPUT);
  pinMode(timerpin3, INPUT);
  pinMode(relaypin, OUTPUT);
  pinMode(ledpin, OUTPUT);
}

void loop() {
}

If anyone sees anything I have done wrong, please post.

Thanks.

Think about changing you input to input pullup. To save having to add external resistors.

Paul

Like this?

/*  The purpose of this sketch is to control the on/off times for an aerator according to the input.
 *  There are 3 selections possible.
 *  1 is on for 1 minute and off for 10.
 *  2 is on for 1 minute and off for 7.
 *  3 is on for 1 minute and off for 5.
 */
void setup() {
  const int timerpin1 = 8;
  const int timerpin2 = 9;
  const int timerpin3 = 10;
  const int relaypin = 2;
  int ledpin = 11;

  pinMode(timerpin1, INPUT_PULLUP);
  pinMode(timerpin2, INPUT_PULLUP);
  pinMode(timerpin3, INPUT_PULLUP);
  pinMode(relaypin, OUTPUT);
  pinMode(ledpin, OUTPUT);
}

void loop() {
}

Ok. I want to start simple and build from it. I want to begin by getting the first input to control the relaypin. What do I need to do to read timerpin1 and begin the timer which should be set to on 1 minute/off 10 minutes?

I'm ok with subtle hints as to what needs to be done. I actually learn better that way. I really hate to ask for assistance just to get someone to write the code for me. Then I haven't learned anything at all.

bigone5500:
Ok. I want to start simple and build from it. I want to begin by getting the first input to control the relaypin. What do I need to do to read timerpin1 and begin the timer which should be set to on 1 minute/off 10 minutes?

What will be your input method? There are several possibilities.

  1. A pushbutton for each selection - programmed 'radio button' style.
  2. A selector switch with four positions.
  3. A single pushbutton which cycles through the options sequentially.
  4. A quadrature encoder with pushbutton.

How will the user know which timer has been selected?

The input will be controlled via rotary selector.

I've been racking my brain trying to figure out how to activate the timer when a given pin has input. When the system is powered, the timer will automatically run. For example, when you power the arduino, which ever position the selector switch is in will run the part of the sketch that corresponds to that input.

Can anyone give some guidance to what I need to do?

Thanks.

-current code-

/*  The purpose of this sketch is to control the on/off times for an aerator according to the input.
 *  There are 3 selections possible.
 *  1 is on for 1 minute and off for 10.
 *  2 is on for 1 minute and off for 7.
 *  3 is on for 1 minute and off for 5.
 *  The LED will be illuminated while the relay is active.
 */
void setup()
{
  const int timerpin1 = 8;
  const int timerpin2 = 9;
  const int timerpin3 = 10;
  const int relaypin = 2;
  int ledpin = 11;

  pinMode(timerpin1, INPUT_PULLUP);
  pinMode(timerpin2, INPUT_PULLUP);
  pinMode(timerpin3, INPUT_PULLUP);
  pinMode(relaypin, OUTPUT);
  pinMode(ledpin, OUTPUT);

  const int duration1 = 60000;
  const int duration2 = 300000;
  const int duration3 = 420000;
  const int duration4 = 600000;
}

void loop()
{

}

bigone5500:
I've been racking my brain trying to figure out how to activate the timer when a given pin has input. When the system is powered, the timer will automatically run. For example, when you power the arduino, which ever position the selector switch is in will run the part of the sketch that corresponds to that input.

Can anyone give some guidance to what I need to do?

Thanks.

-current code-

/*  The purpose of this sketch is to control the on/off times for an aerator according to the input.

*  There are 3 selections possible.
*  1 is on for 1 minute and off for 10.
*  2 is on for 1 minute and off for 7.
*  3 is on for 1 minute and off for 5.
*  The LED will be illuminated while the relay is active.
*/
void setup()
{
  const int timerpin1 = 8;
  const int timerpin2 = 9;
  const int timerpin3 = 10;
  const int relaypin = 2;
  int ledpin = 11;

pinMode(timerpin1, INPUT_PULLUP);
  pinMode(timerpin2, INPUT_PULLUP);
  pinMode(timerpin3, INPUT_PULLUP);
  pinMode(relaypin, OUTPUT);
  pinMode(ledpin, OUTPUT);

const int duration1 = 60000;
  const int duration2 = 300000;
  const int duration3 = 420000;
  const int duration4 = 600000;
}

void loop()
{

}

Put the idea of a "timer" completely out of your mind. Instead think of a "clock" you are watching to know when to do something and when to stop doing something. You will use millis to get the current time in milliseconds. Then when a switch is thrown, get the current millis and save it. In loop(), get the millis and subtract the original millis from the current one. When the difference is > than your required time, your "timer" has expired and stop doing what you were doing.

There is an excellent tutorial on doing several things at a time as the very first post in this section. Will help you know how to use the Arduino to maximum benefit!

Paul

Thanks. I will look into it.

You will also find it useful to have the first five demo sketches in IDE->file/examples/digital/ in your Arduino repertoire.

dougp:
You will also find it useful to have the first five demo sketches in IDE->file/examples/digital/ in your Arduino repertoire.

Excellent. I think I may be able to figure it out now. I will post back with my findings.

Thanks.

So I worked on the code a little and I think this might possibly be in the right direction. I know it needs much, much more work. You guys will probably laugh when you look at it.

Seriously though, I'd like someone to take a look at it and see what may be out of place. Currently, I have it so it is reading each input pin state and either turning on/off the relaypin and ledpin. I can't help but think I'm being redundant with something.

I'm trying to grasp the millis sketch but I still need to go over it a few more times. That part I may have to have more extensive help with.

Thanks again.

/*  The purpose of this sketch is to control the on/off times for an aerator according to the input.
 *  There are 3 selections possible.
 *  1 is on for 1 minute and off for 10.
 *  2 is on for 1 minute and off for 7.
 *  3 is on for 1 minute and off for 5.
 *  The LED will be illuminated while the relay is active.
 */
const int timerpin1 = 8;
const int timerpin2 = 9;
const int timerpin3 = 10;
const int relaypin = 2;
const int ledpin = 11;

int timerpinState1 = 0;
int timerpinState2 = 0;
int timerpinState3 = 0;

void setup()
{
  pinMode(timerpin1, INPUT_PULLUP);
  pinMode(timerpin2, INPUT_PULLUP);
  pinMode(timerpin3, INPUT_PULLUP);
  pinMode(relaypin, OUTPUT);
  pinMode(ledpin, OUTPUT);
}

void loop()
{
  timerpinState1 = digitalRead(timerpin1);

  if (timerpinState1 == HIGH) {
    digitalWrite(relaypin, HIGH);
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(relaypin, LOW);
    digitalWrite(ledpin, LOW);
  }

  timerpinState2 = digitalRead(timerpin2);
  
  if (timerpinState2 == HIGH) {
    digitalWrite(relaypin, HIGH);
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(relaypin, LOW);
    digitalWrite(ledPin, LOW);
  }

  timerpinState3 = digitalRead(timerpin3);
  
  if (timerpinState3 == HIGH) {
    digitalWrite(relaypin, HIGH);
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(relaypin, LOW);
    digitalWrite(ledPin, LOW);
  }
}

bigone5500:
I'm trying to grasp the millis sketch but I still need to go over it a few more times. That part I may have to have more extensive help with.

See if this helps. Read from the bottom up.

millis illustration.PNG

In principle I think this should work (compiles, not tested.) It's a way to do it using millis().

It looks complicated but it's really not. It divides the timing up into 4 distinct states:

  • initialize, which reads the switches and determines the on/off times from two tables. If the on/off times
    are "invalid" - not one of your patterns -- the values are set to zero which results in no aerator operation. You can change this to whatever you'd like
  • if a valid switch input is recognized, the on/off times are grabbed from the tables, the aerator turned on and the timing started
  • when the on-time is done, the aerator is turned off and the off-timing starts
  • when the off-time is done the aerator is turned back on and the on-timing starts again

If you change the condition of the input switches, the code should immediately turn off the aerator, wait 5-seconds and then re-init the timers and start again. If you set the switches to all-off (or one of the unrecognized patterns) the aerator will stay off.

As I said, compiles but not tested. Give it a try and see if it makes sense to you.

/*  The purpose of this sketch is to control the on/off times for an aerator according to the input.
 *  There are 3 selections possible.
 *  1 is on for 1 minute and off for 10.
 *  2 is on for 1 minute and off for 7.
 *  3 is on for 1 minute and off for 5.
 *  The LED will be illuminated while the relay is active.
 */
const int timerpin1 = 8;
const int timerpin2 = 9;
const int timerpin3 = 10;
const int relaypin = 2;
const int ledpin = 11;

int timerpinState1 = 0;
int timerpinState2 = 0;
int timerpinState3 = 0;

#define CHANGE_TIME_DELAY       5000ul      //5-sec off-time before applying new settings

const unsigned long
    culAeratorOnTimes[] =
    {
        0ul,                //000   - aerator off
        60000ul,            //001   - on 1 minute (60000mS)
        60000ul,            //010   - on 1 minute (60000mS)
        0ul,                //011   - "not recognized"; always off
        60000ul,            //100   - on 1 minute (60000mS)
        0ul,                //101   - "not recognized"; always off
        0ul,                //110   - "not recognized"; always off
        0ul                 //111   - "not recognized"; always off
        
    };

const unsigned long
    culAeratorOffTimes[] =
    {
        0ul,                //000   - aerator off
        600000ul,           //001   - off 10 minutes (600000mS)
        420000ul,           //010   - off 7 minutes (420000mS)
        0ul,                //011   - "not recognized"; always off
        300000ul,           //100   - off 5 minutes (420000mS)
        0ul,                //101   - "not recognized"; always off
        0ul,                //110   - "not recognized"; always off
        0ul                 //111   - "not recognized"; always off
        
    };

void setup()
{
    pinMode( timerpin1, INPUT_PULLUP );
    pinMode( timerpin2, INPUT_PULLUP );
    pinMode( timerpin3, INPUT_PULLUP );
    
    pinMode( relaypin, OUTPUT );
    pinMode( ledpin, OUTPUT );
    
}//setup

//state machine state names
#define INIT            0
#define AERATOR_ON      1
#define AERATOR_OFF     2
#define CHANGE_TIME     3
//
void loop()
{
    byte
        sw;
    static unsigned long
        timeAeratorOn,
        timeAeratorOff,
        timeAerator;
    static byte
        oldSwitches = 0,
        stateAerator = INIT;
    unsigned long
        timeNow;     

    timeNow = millis();

    switch( stateAerator )
    {
        case    INIT:
            sw = ReadSwitches();
            timeAeratorOn = culAeratorOnTimes[sw];
            timeAeratorOff = culAeratorOffTimes[sw];

            //if pattern is not recognized (i.e. both on and off times are zero) we just wait in this state
            //aerator will remain off
            if( timeAeratorOn > 0 && timeAeratorOff > 0 )
            {
                //valid times...turn on the aerator and start timing its run-time
                digitalWrite( relaypin, HIGH );
                digitalWrite( ledpin, HIGH );
                timeAerator = timeNow;
                oldSwitches = sw;           //save a copy of current switches so we can compare later for change
                
                stateAerator = AERATOR_ON;
                
            }//if
            
        break;

        case    AERATOR_ON:
            if( timeNow - timeAerator >= timeAeratorOn )
            {
                //on-time is done; turn off the aerator and time the off-time
                digitalWrite( relaypin, LOW );
                digitalWrite( ledpin, LOW );
                timeAerator = timeNow;
                
                stateAerator = AERATOR_OFF;
                
            }//if
            
        break;

        case    AERATOR_OFF:
            if( timeNow - timeAerator >= timeAeratorOff )
            {
                //off-time is done; turn the aerator back on and set up to time it
                digitalWrite( relaypin, HIGH );
                digitalWrite( ledpin, HIGH );
                timeAerator = timeNow;
                stateAerator = AERATOR_ON;
                
            }//if
        
        break;

        case    CHANGE_TIME:
            //wait for pause time then go back to INIT to read switches, get new times and re-start
            if( timeNow - timeAerator >= CHANGE_TIME_DELAY )
                stateAerator = INIT;
        
        break;
        
    }//switch

    //each time through the loop we check to see if the switches have changed
    if( ReadSwitches() != oldSwitches )
    {
        //if switches have changed, shut the aerator off, pause and then re-start via CHANGE_TIME state
        digitalWrite( relaypin, LOW );
        digitalWrite( ledpin, LOW );
        timeAerator = timeNow;
        stateAerator = CHANGE_TIME;
        
    }//if
    
}//loop

byte ReadSwitches( void )
{
    byte
        switchStates;

    //this will set switchStates to a value from 0 (all switches open) to 7 (all switches closed)
    //this will be used as an index into the on/off tables. If a switch combo is not recognized,
    //its table entry for on/off will be zero. 
    switchStates = (digitalRead(timerpin1) == LOW)?0x01:0x00;   //if timerpin1 low, OR stateSwitches with 0x01, else 0x00
    switchStates |= (digitalRead(timerpin2) == LOW)?0x02:0x00;  //if timerpin1 low, OR stateSwitches with 0x02, else 0x00
    switchStates |= (digitalRead(timerpin3) == LOW)?0x04:0x00;  //if timerpin1 low, OR stateSwitches with 0x04, else 0x00

    return switchStates;

}//ReadSwitches