Using four 555 relay toggle circuits

GroupDIY Audio Forum

Help Support GroupDIY Audio Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.
Currently I am using a cd4043 into a uln2803.

My point earlier was that with enough pins, you can do dedicated sensing and cv using arrays, and code the latching natively.
Still would need some form of relay drivers, of course.  In the EE world, I'm sure this solution is quite bulky and unsophisticated, but keeps code rudimentary.

Dare to post your code roc? =P
 
doing this in a hardware solution is way too much work.
Spend the $3 on an arduino Nano. The software is not terribly complex.
Worst case, you can actually do it graphically using ardublock software.

Looks like someone has already created a library for this: https://arduinoplusplus.wordpress.com/2016/03/29/radio-buttons-in-the-real-world/

And a video to show it. https://www.youtube.com/watch?v=CdPgtCAkko4&feature=youtu.be

Now connect the LED's to relays and you're done, right?
 
Rochey, thank you. Yeah I am going than Nano route.  I will post the relevant portion of the code as it is long.
And thanks to everyone for the pointers. You all seem to point in the same direction.
Breadboarding the cd4043 to uln2803 is messy looking with a ton of wires and it doesn't take much to make a solder bridge if I am not on my game.
 
Rocinante,

if I understood correctly, you have 4x relays which need to be driven from the device. In which case, simply use some IO and a PN2222 transistor with a resistor. You can use a through hole resistor to jump any other traces that need to go below it.

Software side is quite simple. Ideally, you set up your input pins as an interrupt.

Pseudo Code:
Trigger the interrupt - https://www.jeremyblum.com/2011/03/07/arduino-tutorial-10-interrupts-and-hardware-debouncing/
Count to 100mS or so
Read the input pin
Clear the output pins
Set the appropriate output pin.

Job done. nice and easy.

/Dafydd
 
You don't need an interrupt for this. And I cannot recommend that video. I stopped watching when he started describing using extra hardware to debounce which is non-sense. And you should NEVER use delay() in microcontroller code. Ever. Using delay() is for silly examples for kids making LEDs blink.

The proper way to "delay" is with code like this:

Code:
#define POLL_PERIOD 100

uint32_t ctime;
uint32_t time_last_poll = 0;

void
loop()
{
    ctime = millis();

    if (ctime > time_last_poll + POLL_PERIOD) {
        time_last_poll = ctime;

        // this will execute every 100ms
    }
}

And before you say "no, this is inefficient", realize that this is not a process or thread like on a PC. Microcontrollers as designed to just run in a loop, at full speed, forever.
 
Square, your warning to avoid the use of delay() is so code can keep looping and chunking through operations , because delay() temporarily halts progression of the loop?
 
boji said:
Square, your warning to avoid the use of delay() is so code can keep looping and chunking through operations , because delay() temporarily halts progression of the loop?
Exactly. What Square describes is what I used to know as a super loop. For simple systems you can put all the functions you want to achieve inside this loop. Each one gets checked/run each time through the loop. When the loop gets big with quite a number of functions in it there can be some jitter on the timing of individual functions but provided they are none time critical (like debouncing) this does not matter.

Time critical functions do require an interrupt e.g firing an inkjet head in a printer.

Cheers

Ian
 
I was going through the code when i saw some mistakes
This version is for 3 ins and 4 outs (I couldn't find the 4 in 4 out but its uploaded already)
I tried to condense it to the relevant part. Keep in mind channels 1 - 3 are inputs and channels 4 - 7 are outputs.
With this code 1 and 2 work like 'radio buttons' but 3 also effects 1.  I am certain i should be able figure that out pretty easily and I am just not declaring 3 correctly.
As far as 4 - 7 go though only 7 works.  I am fairly certain my wiring is correct as the correct led's light up and they are at the end of each channel.

pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);
  pinMode(buttonPin5, INPUT_PULLUP);
  pinMode(buttonPin6, INPUT_PULLUP);
  pinMode(buttonPin7, INPUT_PULLUP);
  debouncer.attach(buttonPin1);
  debouncer.interval(debouncerInterval);
  debouncer2.attach(buttonPin2);
  debouncer2.interval(debouncerInterval);
  debouncer3.attach(buttonPin3);
  debouncer3.interval(debouncerInterval);
  debouncer4.attach(buttonPin4);
  debouncer4.interval(debouncerInterval);
  debouncer5.attach(buttonPin5);
  debouncer5.interval(debouncerInterval);
  debouncer6.attach(buttonPin6);
  debouncer6.interval(debouncerInterval);
  debouncer7.attach(buttonPin7);
  debouncer7.interval(debouncerInterval);
  pinMode(relayPin1, OUTPUT); //Define pin as output
  pinMode(relayPin2, OUTPUT); //Define pin as output
  pinMode(relayPin3, OUTPUT); //Define pin as output
  pinMode(relayPin4, OUTPUT); //Define pin as output
  pinMode(relayPin5, OUTPUT); //Define pin as output
  pinMode(relayPin6, OUTPUT); //Define pin as output
  pinMode(relayPin7, OUTPUT); //Define pin as output // put your setup code here, to run once:

}

void loop() {

  // Button 1
  if(debouncer.update()){
    if(debouncer.read() == 0){
      if(buttonOneState == 0){
        Serial.println("Turn Relay 1 ON");
        digitalWrite(relayPin1, HIGH);
        digitalWrite(relayPin2, LOW);
        digitalWrite(relayPin3, LOW);
        buttonOneState = 1;
        buttonTwoState = 0;
        buttonThreeState = 0;
      }
      else{
        Serial.println("Turn Relay 1 OFF");
        digitalWrite(relayPin1, LOW);
        digitalWrite(relayPin2, HIGH);
        digitalWrite(relayPin3, LOW);
        buttonOneState = 0;
        buttonTwoState = 1;
        buttonThreeState = 0;
      }
    }
  }

  // Button 2
  if(debouncer2.update()){
    if(debouncer2.read() == 0){
      if(buttonTwoState == 0){
        Serial.println("Turn Relay 2 ON");
        digitalWrite(relayPin2, HIGH);
        digitalWrite(relayPin1, LOW);
        digitalWrite(relayPin3, LOW);
        buttonTwoState = 1;
        buttonOneState = 0;
        buttonThreeState = 0;
      }
      else{
        Serial.println("Turn Relay 2 OFF");
        digitalWrite(relayPin2, LOW);
        digitalWrite(relayPin1, HIGH);
        digitalWrite(relayPin3, LOW);
        buttonTwoState = 0;
        buttonOneState = 1;
        buttonThreeState = 0;
      }
    }
  }

  // Button 3
  if(debouncer3.update()){
    if(debouncer3.read() == 0){
      if(buttonThreeState == 0){
        Serial.println("Turn Relay 3 ON");
        digitalWrite(relayPin3, HIGH);
        digitalWrite(relayPin2, LOW);
        digitalWrite(relayPin1, LOW);
        buttonThreeState = 1;
        buttonTwoState = 0;
        buttonOneState = 0;
      }
      else{
        Serial.println("Turn Relay 3 OFF");
        digitalWrite(relayPin3, LOW);
        digitalWrite(relayPin1, HIGH);
        digitalWrite(relayPin2, LOW);
        buttonOneState = 1;
        buttonTwoState = 0;
        buttonThreeState = 0;
       
      }
    }
  }

// Button 4
  if(debouncer4.update()){
    if(debouncer4.read() == 0){
      if(buttonFourState == 0){
        Serial.println("Turn Relay 4 ON");
        digitalWrite(relayPin4, HIGH);
        buttonFourState = 1;
      }
      else{
        Serial.println("Turn Relay 4 OFF");
        digitalWrite(relayPin4, LOW);
        buttonFourState = 0;
      }
    }
  }
// Button 5
  if(debouncer5.update()){
    if(debouncer5.read() == 0){
      if(buttonFiveState == 0){
        Serial.println("Turn Relay 5 ON");
        digitalWrite(relayPin5, HIGH);
        buttonFiveState = 1;
      }
      else{
        Serial.println("Turn Relay 5 OFF");
        digitalWrite(relayPin5, LOW);
        buttonFiveState = 0;
      }
    }
  }
  // Button 6
  if(debouncer6.update()){
    if(debouncer6.read() == 0){
      if(buttonFourState == 0){
        Serial.println("Turn Relay 6 ON");
        digitalWrite(relayPin6, HIGH);
        buttonSixState = 1;
      }
      else{
        Serial.println("Turn Relay 6 OFF");
        digitalWrite(relayPin6, LOW);
        buttonSixState = 0;
      }
    }
  }
    // Button 7
  if(debouncer7.update()){
    if(debouncer7.read() == 0){
      if(buttonSevenState == 0){
        Serial.println("Turn Relay 7 ON");
        digitalWrite(relayPin7, HIGH);
        buttonSevenState = 1;
      }
      else{
        Serial.println("Turn Relay 7 OFF");
        digitalWrite(relayPin7, LOW);
        buttonSevenState = 0;
      }
    }
  }

}
 
That code looks fine to me just glancing at it. It's inline but that's fine. I haven't really studied and it doesn't show the "debouncer" code but if it works maybe just roll with that.

But if you're curious, this is probably more like what I would do:

Code:
#define BTIME_PERIOD 10
#define DEBNC_PERIOD 50

#define BPIN1 8
#define BPIN2 6

#define NBTN 2

struct btn {
    uint8_t pin;
    uint8_t state;
    uint32_t dtime_last_time;
};
struct btn btns[] = { 
    { BPIN1, 0, 0 },
    { BPIN2, 0, 0 },
};

#define RTIME_PERIOD 100

#define RPIN1 4
#define RPIN2 5

#define NRLY 2

struct rly {
    uint8_t pin;
    uint8_t state;
};
struct rly rlys[] = { 
    { RPIN1, 0 },
    { RPIN2, 0 },
};

uint32_t ctime;
uint32_t btime_last_time = 0;
uint32_t rtime_last_time = 0;

void
setup()
{
    int i;

    for (i = 0; i < NBTN; i++) {
        pinMode(btns[i].pin, INPUT_PULLUP);
    }   
    for (i = 0; i < NRLY; i++) {
        pinMode(rlys[i].pin, OUTPUT);
        digitalWrite(rlys[i].pin, LOW);
    }   
}

void
loop()
{
    ctime = millis();

    if (ctime > btime_last_time + BTIME_PERIOD) {
        btime_last_time = 0;

        // debounce tactile buttons

        for (int bi = 0; bi < NBTN; bi++) {
            struct btn *btn = &btns[bi];

            if (digitalRead(btn->pin) == LOW) {
                if (btn->dtime_last_time == 0) {
                    // start debounce timing
                    btn->dtime_last_time = ctime;
                } else if (ctime > btn->dtime_last_time + DEBNC_PERIOD) {
                    // yes, pin as been LOW for DEBNC_PERIOD
                    btn->dtime_last_time = 0;

                    btn->state = 1; // button pressed
                }
            } else {
                btn->dtime_last_time = 0; // nope, just a "bounce"
            }
        }
    }

    if (ctime > rtime_last_time + RTIME_PERIOD) {
        rtime_last_time = 0;

        // now evaluate buttons and change relays however

        struct btn *btn;

        btn = &btns[0];
        if (btn->state == 1) {
            btn->state = 0;

            digitalWrite(rlys[1].pin, LOW);
            digitalWrite(rlys[0].pin, HIGH);
        }

        btn = &btns[1];
        if (btn->state == 1) {
            btn->state = 0;

            digitalWrite(rlys[0].pin, LOW);
            digitalWrite(rlys[1].pin, HIGH);
        }
    }
}

Of course I just wrote this off-the-cuff as they say. So no doubt it will not work the first time and probably has a few serious bugs. But it's enough to give you ideas perhaps. And it just toggles two relays. You would have to adjust the last bit to make it do what you want. The main thing is that it's a little more modular and can grow.
 
SquareWave that was really awesome.  Some of it i didn't understand but that's what google is for.
So somewhere around channels 3 and 4 seems to be my problem I think as I transition from radio buttons aka interlocking, to 1 or 2 at a time for 4-7.
I also don't get why only channel 7 works and 4, 5, and 6 don't.
thanks all
 
Honestly I'm not really sure what you're trying to do precisely. Maybe just start with buttons that toggle each relay so that you're sure the buttons and relays work. Then maybe draw up a truth table of some sort and adjust the code as necessary.
 
Took guts Roc, thanks for posting. And looks like it paid off, as square has given you a nice springboard!

Have to admit the most exciting 'a-ha' moment was discovering the relationship between functions and libraries.
 
Don't know what "debouncer2.attach/interval()" is exactly doing, but couldn't hurt to assign pins as outputs before calling anything.  Seeing your declarations might reduce my confusion.  Are your relay pins 4-7 in actuality using analog pins 14-17 on the arduino?



 
Okay so I didn't post the earlier part of the code that shows the buttons and pins assignments. I thought what I posted was the most relevant.
Everything is definitely assigned to the right pin and for the most part it works minus channels 4, 5, 6.
But the led indicators which are connected to my buttons are indicating I am hitting the right pin as they are at the end of everything.
I am using pin 2 as 1, 3 as 2, etc... up until pin 8.  And yes the buttons are pins  9 -16
 
> Time critical functions do require an interrupt e.g firing an inkjet head in a printer.

IIRC (I wasn't there), an early example of interrupts was a chain-printer with no brain. A chain of letters spun past the paper like a chain-saw. A row of hammers banged the links against a ribbon to paper. Without its own brain, it *interrupted* the mainframe at every letter position. The mainframe parked its thought, worked out which letters had to be hammered, and went back to the main thought.

Of course this took time to save the current thought, load the letter-hammer code and the text being printed, then go back to the real work. What would be better is 1/10th of a mainframe dedicated to the printer. In those days it was usually cheaper to interrupt the mainframe even if that killed 20+% of its thinking-power, because a second brain for the printer was not a whole heap cheaper than a main brain.
 
Back
Top