Arduino Timers Is this possible

Hello:

I have a project where I am using two 555 timers. One timer creates a a adjustable pulse from 10 to 100 ms. This is used to trigger a another 555 timer that outputs the previous pulse from a adjustable 3 pulses per second to once every 10 seconds. The purpose is to power a pneumatic valve to control CO2 for a planted freshwater tank. Works fine, but wanted to see if I can add some bells and whistles and use a Arduino to accomplish this.

Wanted to add a display and allow the use to adjust the pulses etc, but not sure if it is possible on the Arduino. I assume I would need to use two timers, similar to the 555 setup, one for the pulse and the second how often the pulse is outputted.

Is this possible, maybe just too much work, but would make for a nice project to add a rotary encoder and a display with some menus.

Not a problem at all even for the most basic arduino. You won't need to worry about using the atmega chip's internal timers, you can simply use the arduino millis() function for timing purposes.

Have you purchased an arduino yet? If you can find a suitable ready-made shield with a display, rotary encoder, buttons that you like, then buy an uno. If you don't like or can't find a shield, then don't make the mistake of buying an uno. If you are looking at building your own circuit with display and controls you like, buy a Nano, a couple of good sized breadboards and other components that can also plug directly on the breadboard.

Thanks for the reply. I have a nano, uno, encoders, some breadboards etc so all good to go on that front. Any suggestions how to best tackle it. I don't think a PWM output is what I would be looking for. The "pulse" output once set by the user shouldn't change as it determines the bubble size of CO2 that is dispensed. In short once adjusted to the equipment it shouldn't need to be changed.

So what I envision which would be similar to the 555 timers is a adjustable pulse that once set stays static. Then this pulse is outputted depending on the user requirements which would vary from 3 times a second all the way up to once per 10 seconds. I would assume I need to utilize two timers for this, one to set the pulse itself and the second to how often the pulse is outputted.

Appreciate any framework ideas on how I should tackle this. If I have a concept on how best to accomplish this I can probably figure out the rest. Have done some other Arduino projects, but by no means a expert in programming.

Cheers

One Arduino and some simple programming, have a look at the examples in the IDE and look for things like blink without delay and several things at the same time. There is a simple coding system that uses milli seconds to trigger events, this will make life easy for you. Do not be tempted to use delay for timing it stops the whole program. Displays are a little harder but again examples in the IDE will get you started, the easiest (if not the most elegant) way to change the bubble rate is to use a pot to an analog input and scaled from 1 - 10 seconds, this will just change the milli second setting.

As PaulRB has explained, this task is essentially trivial for a microcontroller. You need to study this thread to understand the basic steps.

Now if you want it to be adjustable, you will need an indicator. Your choice is between a simple numeric display

or a character LCD.

The next exercise is to learn to display text and your parameters and adjust these using a rotary encoder or just simple buttons. Once that is done, you can put the two functions - parameter setting, and timing - together.

you are probably looking at something along the lines of the attached photo

  1. Arduino mega
  2. 20*4 LCD for menus and data display
  3. rotary encoder for meny control

this also has relays for pump control and Lora and Sigfox communications facilities

Thanks everyone. So i am thinking out loud. Use milli() in some fashion to create a toggle on a output at a interval anywhere from 300msec to 10 seconds. Once toggled then stay high for a period of time that is determined by the user. Any where from 10ms to 100ms.

To start I would just hard code the output timing values and once the timing portions are designed and tested then work on user input, displays and menus.

horace:
you are probably looking at something along the lines of the attached photo

  1. Arduino mega
  2. 20*4 LCD for menus and data display
  3. rotary encoder for meny control

Would be overkill for what I want to design, but some good examples on programming the menus and display. Thanks for sharing.

Hi,
Can you please post a copy of your LM555 circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

See attached. Not my design, but a compilation of various schematics. Pot adjusts the pulse frequency of the pulse, pot_2 adjusts the pulse output per sec. The values of some of the components may be off as I was experimenting with various values. I can not attach the LtSpice asc file, so It is in zipped format.

Clippard.zip (1.17 KB)

pulse.jpg

It is (extremely) bad security practice to download "zip" files as they are able to auto-execute in Windoze systems.

Potentiometers have the advantage that they hold their position whilst powered down, but may not be entirely stable. Values can of course be stored in the EEPROM whilst powered down.

Horace's image:
Img_0644.jpg

A Mega 2560 is gross overkill for the vast majority of Arduino applications, and an inconvenient form factor to boot.

Paul__B:
A Mega 2560 is gross overkill for the vast majority of Arduino applications, and an inconvenient form factor to boot.

the prototype also had a GSM modem connected using Serial1 hence to use of a mega

Bryan, that irf1404 mosfet won't be suitable for use with the arduino. Your 555 timer circuit runs at 12V and so can apply 12V to the mosfet gate, ensuring it switches fully on. But the arduino outputs only 5V, which won't be enough, causing the mosfet to drop some of the voltage and get hot. The arduino output can be boosted up to 12V with extra components, but it would be easier to replace the mosfet with one that has a "logic level gate" such as something starting IRLxxx rather than IRFxxx.

Actually, given the timescales involved, it might be slightly better to use micros() rather than millis(). Your pulses might be as short as 10ms, in which case an error of 1ms might be considered significant.

For a solenoid valve in this application, that probably will not make much difference at all.

It's not a fuel injector! :astonished:

Paul__B:
For a solenoid valve in this application, that probably will not make much difference at all.

It's not a fuel injector! :astonished:

Yes, none of the timing values would be critical.

PaulRB:
Bryan, that irf1404 mosfet won't be suitable for use with the arduino. Your 555 timer circuit runs at 12V and so can apply 12V to the mosfet gate, ensuring it switches fully on. But the arduino outputs only 5V, which won't be enough, causing the mosfet to drop some of the voltage and get hot. The arduino output can be boosted up to 12V with extra components, but it would be easier to replace the mosfet with one that has a "logic level gate" such as something starting IRLxxx rather than IRFxxx.

Yes, that would be the wrong MOSFET. I just cobbled something together in the schematic so i can observe the output on the LTspice simulator. The 555 12v project wouldn't even sue that MOSFET. Just something I picked for the list. The current on the valve is only 55ma so even a 2N2222 transistor could be used easily enough.

So, still unsure on how to best tackle this. I suppose I could create a 100ms timer using milli(). So if a user wanted a bubble of CO2 every second then have a output toggle every 10th iteration of the timer for the one second. But how do I then keep the output on for the "on" time which could be say 40ms. Won't I need two timers?

The two values are somewhat independent of each other.

Hmm, maybe use milli() for 1ms as that would be a value that could be shared between the two values. A variable keeps track of each 1ms loop, 1000 for 1 second, then toggle a output and keep open for another 40 loops, then toggle the output off reset the variables and start over again.

The way to tackle it is with a state variable, and use it to control both the output state (on, off) and also choose the timing constant (offTime, onTime).

So looking at the Blink without delay example and a few modifications it should be easy enough. Haven't coded yet, more or less just thinking it through

//Using some nested loops.(currentMillis - previousMillis >= interval) toggle ledState high. Then increment variable pulse_on_counter until >= constant pulse_on Then toggle ledstate low and reset pulse_on_counter.

/*
  Blink without Delay

  Turns on and off a light emitting diode (LED) connected to a digital pin,
  without using the delay() function. This means that other code can run at the
  same time without being interrupted by the LED code.

  The circuit:
  - Use the onboard LED.
  - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
    and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
    is set to the correct LED pin independent of which board is used.
    If you want to know what pin the on-board LED is connected to on your
    Arduino model, check the Technical Specs of your board at:
    https://www.arduino.cc/en/Main/Products

  created 2005
  by David A. Mellis
  modified 8 Feb 2010
  by Paul Stoffregen
  modified 11 Nov 2013
  by Scott Fitzgerald
  modified 9 Jan 2017
  by Arturo Guadalupi

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin
  

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
int pulse_on_counter = 0;       // variable to keep track of ms

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

// constants won't change:
const long interval = 1000;   // interval at which to blink (milliseconds)
const int pulse_on = 25;      // pulse on setting 

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  [b]//Using some nested loops.(currentMillis - previousMillis >= interval) toggle ledState high. Then increment
 // variable pulse_on_counter until >= const pulse_on
  //Then toggle ledstate low and reset pulse_on_counter[/b]

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}