1 button press , 1 pulse output (no long press) w/ Multiple IN & OUT

Hello everyone, Need help, Can anyone pls Convert this circuit to an Arduino Code?

Here is the youtube link: https://www.youtube.com/watch?v=coqsy1tKipU

This video shows a simple circuit that acts as a 555 monostable, but using just a Transistor & very few common components. (the reason why i choose this video as an example, is because i can't find any youtube video or google post of it done in an arduino code, most example videos uses multiple buttons & leds but if you press the button long, the led will also stay lit until you de-press it), (or when you press the button & let go, the led will stay lit & if you press it again, the led will turn off)

what this circuit does, is when you press a Button (regardless if long press or short press) , the LED will just blinks once or 1 pulse. (even if you press it longer, the led will still blink once (NOT steady lighting & not continuously blinking), then you press it again, still one pulse or 1 blink...

very simple right?, but the challenge arises if i'm going to make a code with 3 or more Buttons & LEDS (multiple ins & outs).

i already tried to make a code with just 1 button & 1 led (with delay & Millis), and it works fine, But my problem is, it will not work if i'm going to add another button pin & led pin. (probably a conflict with using "delay" and also not working right with "millis" (i need this for a project with multiple buttons and leds, with just 1 short blink when button is pressed long or short)

i hope someone can shed a light regarding this, Thanks & regards every one!

So let me get this straight. You’d like us to write a code for you? There’s a Category for that, called

Otherwise, perhaps if you show us what you have so far, someone will show you one of the many ways to expand it, while improving upon it by removing delay().

You need to detect when the button becomes pressed rather than when it is pressed
See the StateChangeDetection example in the IDE

When you detect a press, save the value of millis() as the start time and turn on the LED. Each time through loop() test whether the required period has elapsed since the start time and, if so, turn off the LED

The simple, but clumsy, way to do this for 3 buttons and LEDs is to repeat the code 3 times but use different variable names for each of then suach as startTime0, startTime1 and startTime2 etc

There is a better way to do what want but get the clumsy version working first then you can improve it

hello @camsysca , here is my code



#define button1 2 //INPUT
#define led1 3 //OUTPUT

// for multiple in out:

//#define button2 4 
//#define led2 5

//#define button3 6
//#define led3 7

//#define button3 8
//#define led3 9


int coinSlotSignal;
int coinCount = 0;
int requiredCoins = 1; // set how many coins to insert here 
boolean coinInserted = false;

void setup () {
  Serial.begin (9600);
  pinMode (button1, INPUT_PULLUP);
  pinMode (led1,OUTPUT);
delay (1000);
}
 
 void loop () {
  while (!coinInserted){
    coinSlotSignal = digitalRead (button1);
    if (coinSlotSignal < 1) {
      coinCount += 1;
      Serial.println (coinCount);
      coinInserted = true;
    }
  }
 while (coinInserted){
  coinSlotSignal = digitalRead(button1);
  if (coinSlotSignal > 0){
  coinInserted = false;
 }
 
 }

 if (coinCount >= requiredCoins ) {
 //1st pulse 
  delay (50);
  digitalWrite(led1, HIGH);
    delay (50);
    coinCount = (0);
    delay (10);
   digitalWrite(led1, LOW);

 
 }
 }

hello @UKHeliBob Thank you , here is my example code , using delays , My code millis doesnt work like this



#define button1 2 //INPUT
#define led1 3 //OUTPUT

// for multiple in out:

//#define button2 4 
//#define led2 5

//#define button3 6
//#define led3 7

//#define button3 8
//#define led3 9


int coinSlotSignal;
int coinCount = 0;
int requiredCoins = 1; // set how many coins to insert here 
boolean coinInserted = false;

void setup () {
  Serial.begin (9600);
  pinMode (button1, INPUT_PULLUP);
  pinMode (led1,OUTPUT);
delay (1000);
}
 
 void loop () {
  while (!coinInserted){
    coinSlotSignal = digitalRead (button1);
    if (coinSlotSignal < 1) {
      coinCount += 1;
      Serial.println (coinCount);
      coinInserted = true;
    }
  }
 while (coinInserted){
  coinSlotSignal = digitalRead(button1);
  if (coinSlotSignal > 0){
  coinInserted = false;
 }
 
 }

 if (coinCount >= requiredCoins ) {
 //1st pulse 
  delay (50);
  digitalWrite(led1, HIGH);
    delay (50);
    coinCount = (0);
    delay (10);
   digitalWrite(led1, LOW);

 
 }
 }

use a Library.

For example OneButton

thanks @noiasca , ill give it a try

Have you learned about arrays yet? What about structures, and arrays of structures?

I would guess at @MackieZ is not ready for arrays and structs just yet hence my suggestions in post #3, but I am sure that you can see the direction of travel I was aiming for from my suggested variable names

You need to get rid of those while loops. You could maybe make the sketch work for one button/LED using them but they block execution of any code in loop() that reads and reacts to second and third button presses

See my suggestion in post #3

Let’s see if he replies, and what that reply is. My time is limited this afternoon, so it’s all yours anyway.

I am feeling generous so here is some code that implements my suggestion.

const byte buttonPin0 = A3;
const byte ledPin0 = 3;
byte prevButtonState0 = HIGH;
boolean timerRunning0 = false;
unsigned long ledPeriod = 1000;
unsigned long startTime0;

void setup()
{
    Serial.begin(115200);
    pinMode(buttonPin0, INPUT_PULLUP);
    pinMode(ledPin0, OUTPUT);
}

void loop()
{
    unsigned long currentTime = millis();
    byte buttonState0 = digitalRead(buttonPin0);

    if (buttonState0 != prevButtonState0 && buttonState0 == LOW)  //button 0 has become pressed
    {
        startTime0 = currentTime;
        timerRunning0 = true;
        digitalWrite(ledPin0, HIGH);
    }
    prevButtonState0 = buttonState0;

    if (timerRunning0)
    {
        if (currentTime - startTime0 > ledPeriod)
        {
            timerRunning0 = false;
            digitalWrite(ledPin0, LOW);
        }
    }
}

NOTE that it severely lacking in many ways, not least that it needs code added to debounce the switch input, but adjust the pins used to meet your needs and give the ideas that it uses a go

As hinted above, I foresee arrays and structs in your future, but all in good time

Hi @MackieZ ,

This simulation is the same as is shown in the video, only the blink is set for 3000 milliseconds, but you can set the lenght to lower values.

WOKWI simulation

There you have the code and the libraries used.

Good luck!

Gaby.//

Hello @UKHeliBob, Thank you very much for this code, i tried it and it really works.

I managed to extend it to a version with 3 buttons & 3 leds, & it also worked, i just adjusted the "led period" to suit my needs.

Here is my modified code: (i will also send a video of it)



// I/O 1
const byte button1 = A3;
const byte led1 = 3;
byte prevButtonState0 = HIGH;
boolean timerRunning0 = false;

// 1/O 2
const byte button2 = A4;
const byte led2 = 4;
byte prevButtonState1 = HIGH;
boolean timerRunning1 = false;

// I/O 3
const byte button3 = A5;
const byte led3 = 5;
byte prevButtonState2 = HIGH;
boolean timerRunning2 = false;



unsigned long ledPeriod = 50; //variable, depending on what lenght of time is needed
unsigned long startTime0;

void setup()
{
    Serial.begin(115200);
    pinMode(button1, INPUT_PULLUP);
    pinMode(button2, INPUT_PULLUP);
    pinMode(button3, INPUT_PULLUP);
    
    pinMode(led1, OUTPUT);
    pinMode(led2, OUTPUT);
    pinMode(led3, OUTPUT);
}

void loop()
{
    unsigned long currentTime = millis();
    byte buttonState0 = digitalRead(button1);
    if (buttonState0 != prevButtonState0 && buttonState0 == LOW)  //button 0 has become pressed
    {
        startTime0 = currentTime;
        timerRunning0 = true;
        digitalWrite(led1, HIGH);
         }
    prevButtonState0 = buttonState0;
    if (timerRunning0)
    {
        if (currentTime - startTime0 > ledPeriod)
        {
            timerRunning0 = false;
            digitalWrite(led1, LOW);
           
        }
    }

     byte buttonState1 = digitalRead(button2);
    if (buttonState1 != prevButtonState1 && buttonState1 == LOW)  //button 0 has become pressed
    {
        startTime0 = currentTime;
        timerRunning1 = true;
        digitalWrite(led2, HIGH);
         }
    prevButtonState1 = buttonState1;
    if (timerRunning1)
    {
        if (currentTime - startTime0 > ledPeriod)
        {
            timerRunning1 = false;
            digitalWrite(led2, LOW);
           
        }
    }

    byte buttonState2 = digitalRead(button3);
    if (buttonState2 != prevButtonState2 && buttonState2 == LOW)  //button 0 has become pressed
    {
        startTime0 = currentTime;
        timerRunning2 = true;
        digitalWrite(led3, HIGH);
         }
    prevButtonState2 = buttonState2;
    if (timerRunning2)
    {
        if (currentTime - startTime0 > ledPeriod)
        {
            timerRunning2 = false;
            digitalWrite(led3, LOW);
           
        }
    }
}



& here is the video link below: (my apologies if this looks informal, Someone borrowed my bread board, so i just soldered the leds & button wirings directly to the nano.

thanks @gabygold , i'm also going to try this

byte buttonState2 = digitalRead(button3);

This looks wrong

Take a look at this to see how you can shorten the code using an array of data structures known as structs. It might also explain why I suggested using a suffix of 0, 1 and 2 for the variables in the clumsy version

struct dataLayout  //each button and LED will have this set of datadata
{
    byte buttonPin;
    byte ledPin;
    byte prevButtonState;
    unsigned long startTime;
    boolean timerRunning;
};

dataLayout data[] = {  //declare an array of such button/LED combinations and give them initial values
    { A3, 3, HIGH, 0, false },	//button pin, LED pin, previous button state, start time, timer running flag
    { A2, 5, HIGH, 0, false },
    { A1, 6, HIGH, 0, false }
};
const byte numberOfButtons = sizeof(data) / sizeof(data[0]);
unsigned long ledPeriod = 2000;

void setup()
{
    Serial.begin(115200);
    for (int b = 0; b < numberOfButtons; b++)  //use a for loop to set the pinMode()s
    {
        pinMode(data[b].buttonPin, INPUT_PULLUP);  //note how the data items are referred to uisng the array index and data item name
        pinMode(data[b].ledPin, OUTPUT);
        digitalWrite(data[b].ledPin, LOW);
    }
}

void loop()
{
    unsigned long currentTime = millis();
    for (int b = 0; b < numberOfButtons; b++)  //because the data is in an array we can iterate through it using a for loop
                                               //this drastically reduces the amount of code that we need to write
    {
        byte currentState = digitalRead(data[b].buttonPin);
        if (data[b].timerRunning == false)  //timer for this button is not running
        {
            if (currentState != data[b].prevButtonState && currentState == LOW)  //button b became pressed
            {
                data[b].timerRunning = true;
                digitalWrite(data[b].ledPin, HIGH);	//turn on the LED
                data[b].startTime = currentTime;
            }
            data[b].prevButtonState = currentState;
        }
        else  //the timer for this button is running
        {
            if (currentTime - data[b].startTime >= ledPeriod)	//? is it time to turn off the LED ?
            {
                data[b].timerRunning = false;
                digitalWrite(data[b].ledPin, LOW);		//turn off the LED
            }
        }
    }
}