ButtonPress - setting of variable

I have a small loop with 3 buttons. digital read each button, each loop. When button pressed (only once every few seconds) places an integer in variable for that button.

Not clear on when status goes from HIGH to LOW and variable set, how does the status get back to HIGH, ready for the next loop looking for another button press.

void loop() {
if(digitalRead(BUTTON1_PIN) == 0) new_pos = 1;
if(digitalRead(BUTTON2_PIN) == 0) new_pos = 2;
if(digitalRead(BUTTON3_PIN) == 0) new_pos = 3;

That is, at the start of the loop each time the BUTTON_PIN are all 1 (using pin pullup) (and if say #2 pin pressed the variable (new_pos=2 gets set to LOW) How to make sure all pins at HIGH for the start of each loop. Is this done on release of button and is there enough time to update the variable before reverting to HIGH.
Thanks

Just keep in mind that the loop will run tens of thousands of times per second.

If code detects a button press and records that in a variable then the usual thing is for you to reset that variable when you've handled whatever it is that the button press signifies.

I think you need to think this through a bit more - it would be helpful if you could give us more information on what you're trying to achieve :slight_smile:

If it helps, here's some really clunky code that I wrote some time ago that does lots of switch reading and variable handling (note to others: "no need to critique it :D")

I'm sure others will chip in shortly - I need to go off to work so will try to help more later.

/* This program is designed to turn off a set of lights that are normally controlled by 3 switches. The lights are turned off initially - regardless of switch position - and
 *  will turn on any time that the position of any of the 3 switches changes. From this point a change of position of any switch toggles the lights from their previous state.
 *  If there are no changes in switch position for the set period (15 or maybe 30 minutes) then the lights turn off until there is another switch position change.
 */

// DECLARE VARIABLES

   int Light_Control_Pin = 13;                                                  // Pin 13 controls lights; 0 = off & 1 = on
   int Lights_State = 0;                                                        // Define lights state variable and set to 0

   int Light_Switch_1_Pin = 2;                                                  // Map light switches to pins
   int Light_Switch_2_Pin = 3;                                                  //
   int Light_Switch_3_Pin = 4;                                                  //

   int Current_Light_Switch_1_State = 0;                                        // Define current light switch state variables. May not be accurate, but are updated in setup code section.
   int Current_Light_Switch_2_State = 0;                                        // Needed to set them to something for the code to load into the simulator properly.
   int Current_Light_Switch_3_State = 0;                                        //

   int Old_Light_Switch_1_State = 0;                                            // Define old light switch state variables. Same notes above apply.
   int Old_Light_Switch_2_State = 0;                                            //
   int Old_Light_Switch_3_State = 0;                                            //

   int TimeOutTimer;                                                            // Time out timer current value
   int TimeOutTimerStart = 200;                                                 // Time out timer reset value (10th of a second)

// SETUP CODE

   void setup() {                                                               // Setup code starts here (runs once)

      pinMode(Light_Control_Pin, OUTPUT);                                       // Set light control pin as output
      
      pinMode(Light_Switch_1_Pin, INPUT);                                       // Set switch inputs as inputs
      pinMode(Light_Switch_2_Pin, INPUT);                                       // 
      pinMode(Light_Switch_3_Pin, INPUT);                                       // 

      TimeOutTimer = TimeOutTimerStart;                                         // Initialize Timer
      
      Determine_Switch_States();                                                // Determine light switch positions (subroutine)
      Update_Old_Switch_States();                                               // Set old switch states to be the same as current ones (subroutine)
      
      LightsOff();                                                              // Start with lights off (subroutine)

   }                                                                            // End of setup code

// MAIN CODE

   void loop() {                                                                // Main code starts here (runs repeatedly)

      Determine_Switch_States();                                                // See where the switches are (subroutine)

      if (Current_Light_Switch_1_State +                                        // Has a switch changed position?
          Current_Light_Switch_2_State +                                        //
          Current_Light_Switch_3_State -                                        //
          Old_Light_Switch_1_State -                                            //
          Old_Light_Switch_2_State -                                            //
          Old_Light_Switch_3_State != 0) {                                      // 
                                                                                // If yes then:
          ToggleLightsState();                                                  // - Toggle the lights (subroutine)
          Update_Old_Switch_States();                                           // - Update the old switch states (subroutine)
          TimeOutTimer = TimeOutTimerStart;                                     // - Reset Time out timer
       }                                                                                                                                                                                        //
    
       delay(100);                                                              // Wait 0.1 sec & decrement timer
       TimeOutTimer = TimeOutTimer -1;                                          // 
       
       if (TimeOutTimer == 0) {                                                 // Time to turn out the lights?
                                                                                // If yes then:
          LightsOff();                                                          // - Turn lights off (subroutine)
          TimeOutTimer = TimeOutTimerStart;                                     // - Reset timer (Stops it going negative and underflowing)
       }                                                                        // 
       
    }                                                                           // End of Main Code Loop

// SUBROUTINES

   void LightsOff() {                                                           // Subroutine "Turn Lights Off"
      digitalWrite(Light_Control_Pin, LOW);                                     // Set light control pin low
      Lights_State = 0;                                                         // Set lights state variable to indicate lights now off
   }                                                                            // 


   void LightsOn() {                                                            // Subroutine "Turn Lights On"
      digitalWrite(Light_Control_Pin, HIGH);                                    // Set light control pin high
      Lights_State = 1;                                                         // Set lights state variable to indicate lights now on
   }                                                                            // 

   void ToggleLightsState() {                                                   // Subroutine to toggle current state of lights
      if (Lights_State == 0) {                                                  // Are lights off?
         LightsOn();                                                            // If so then turn lights on
      }                                                                         // End if
                                                                                //
      else {                                                                    // Otherwise they must already be on
         LightsOff();                                                           // In which case turn them off
      }                                                                         // End else
   }                                                                            // 
   
   void Determine_Switch_States() {                                             // Subroutine to determine current light switch states
      Current_Light_Switch_1_State = digitalRead(Light_Switch_1_Pin);           //
      Current_Light_Switch_2_State = digitalRead(Light_Switch_2_Pin);           //
      Current_Light_Switch_3_State = digitalRead(Light_Switch_3_Pin);           //
   }                                                                            //

   void Update_Old_Switch_States() {                                            // Subroutine to update old light switch states
      Old_Light_Switch_1_State = Current_Light_Switch_1_State;                  //
      Old_Light_Switch_2_State = Current_Light_Switch_2_State;                  //
      Old_Light_Switch_3_State = Current_Light_Switch_3_State;                  //
   }                                                                            //

Check out my tutorial on Debouncing Switches in Arduino which has examples of handling switch changes from H/L

Thanks CJ Southern
My project is for model railroad. (I am an Arduino beginner btw) There is a thing called a transfer table that moves 1 loco at a time backward and forward to different tracks.(a turntable goes rotationally around to each track) Using stepper motor.
Ideas is to tell the steppr motor direction and then number of turns. Distance between each track is exactly the same. Stepper is at set speed.
There are variables for
current position (which is obtained from new postion (when its reached its destination.)(held in an Eprom (which is obtained from button press)
motor direction (worked out from diff between variable new pos and current pos)
movement (in # of motor turns) (obtained by diff between each selected position.
Code below. There will be some errors which I hope to learn and fix, at the moment just trying to clarify how the button press works and how to make it refresh each loop so after a button press on 1 loop the next loop does not see it anymore. and the variable has been updated. Need something like -- button pressed, digital read, change variable, and then back to state before the was button pressed all in 1 loop. Do I need to go as far as using the button states etc
Is there a way to use 'Create to check the code.'
Bear in mind I am aged deficient or is that over supplied I am 77 and a bit slow on the uptake.

Thanks and go easy.
Charles Harris
Downunder NZ

/* Sketch using UNO R3 ??? with stepper motor and driver, with 5 buttons. For use on model railroad transfer table 5 loco track positions. Use of buttons for track selection allows user to go between any 2 tracks in either direction. Retains current position(from previous session) on startup.
*/

#include <EEPROM.h>

#define ENABLE_PIN A0 // LOW = driver enabled – stepper motor
#define M1_PIN A1 // M1 microstepping mode// is this necessay??
#define M2_PIN A2 // M2 microstepping mode?? ditto
#define DIR_PIN A3 // to DIR pin of driver
#define STEP_PIN A4 // to DIR pin of driver
#define MTRSPEED_PIN A5 // set speed

#define ONOFF_LED_PIN 13 // Motor running LED
#define DIR_LED_PIN 4 // Motor direction LED
#define PULSES_PER_REV 200 // Pulses per revolution

#define BUTTON1_PIN = ; //pushbutton to select track #1
#define BUTTON2_PIN = ; //pushbutton to select track #2
#define BUTTON3_PIN = ; //pushbutton to select track #3 NEED PINs
#define BUTTON4_PIN = ; //pushbutton to select track #4
#define BUTTON5_PIN = ; //pushbutton to select track #5

// Define number of positions, and number of each position
// NUM_POSITIONS = 5

unsigned long positions = {0,800,1600,2400,3200}; // this needs fixing to pos 1 + step
#define step = 800etc

byte dir, current_pos, new_pos, totalmovement;

void motor_enable() {
set speed(200)
digitalWrite(ENABLE_PIN, LOW); // LOW = driver enabled
digitalWrite(ONOFF_LED_PIN, HIGH);
digitalWrite(DIR_PIN, dir);
}

void motor_idle() {
digitalWrite(ENABLE_PIN, HIGH); // HIGH = driver disabled
digitalWrite(ONOFF_LED_PIN, LOW);
}

void setup() {

pinMode(BUTTON1_PIN, INPUT); pullup? And == positions ?
pinMode(BUTTON2_PIN, INPUT);
pinMode(BUTTON3_PIN, INPUT);
pinMode(BUTTON4_PIN, INPUT);
pinMode(BUTTON5_PIN, INPUT);

pinMode(M1_PIN, OUTPUT);
pinMode(M2_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(ENABLE_PIN, OUTPUT);
pinMode(ONOFF_LED_PIN, OUTPUT);
pinMode(DIR_LED_PIN, OUTPUT);
digitalWrite(M1_PIN, LOW); // set M1,M2 to 0,0 for no microstepping ??
digitalWrite(M2_PIN, LOW);
motor_idle();

current_pos = EEPROM.read(0);
if(current_pos > NUM_POSITIONS) {
current_pos = 1;
EEPROM.write(0,1);
}
new_pos = current_pos;

}

void loop() {

if(digitalRead(BUTTON1_PIN) == 0) new_pos = 1, (BUTTON1_PIN) == 1; This ??????
if(digitalRead(BUTTON2_PIN) == 0) new_pos = 2;
if(digitalRead(BUTTON3_PIN) == 0) new_pos = 3;
if(digitalRead(BUTTON4_PIN) == 0) new_pos = 4;
if(digitalRead(BUTTON5_PIN) == 0) new_pos = 5;

if(new_pos != current_pos) {
if(new_pos > current_pos) {
dir = 1;

  movement step
  //totalmovement(tt_position[new_pos] – tt_position[current_pos]); 
}
else {
  dir = 0;
  totalmovement(tt_position[current_pos] - tt_position[new_pos]);
}
current_pos = new_pos;
EEPROM.write(0, current_pos);

}
}
//b

Hi, @sswcharlie
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".

It will show you how to post your code so it is in a scrolling window.

What model Arduino controller are you using?
What scale and model style of the railroad?

Thanks.. Tom.... :smiley: :+1: :coffee: :australia:

Hi Charlie,

I'll take a closer look when I get home tonight for you.

I'm not too far behind you (coming up on 61) ... and live in Nelson at the good old "top of the south" on the mainland :wink:

Hi Tom
Apologies I will check next time when I post code the code the correct way. Thanks.

Thanks for your message. I am using UNO R3 at the moment to get sorted. Later will probably go ESP way for wifi and phone with button presses etc.

I am enjoying the learning curve very much.

I model in HO the Cotton Belt in 1950-70s. Have a layout in old New Zealand Guards Van (caboose).
cheers

Charles

Wow. A kool place to live. We live trackside in Ashhurst near the entrance to Manawatu Gorge.
Your comments will be appreciated. just trying to solve bit by bit so I can learn.

cheers

Charles

Hi Charles - just a thought ... are you able to post what you have so far using the correct tags? I think what you've posted above is a bit too broken up for me to pick it up this end.

The easist way to post code here it to just do a ctrl+A to select everything in the IDE - then a shift+ctrl+C to copy to the clipboard in a forum-friendly format - then just the regular ctrl+V to paste it into your message. You can also get to the select all and copy for forum via the edit menu in the IDE.

Cheers,

Colin

Hi,

Nice, the age of steam, yes they are Guards Vans.
WOW a great place to build...

Caboose !!!!!! Whats that, sounds like the rear of a moose!!!! :laughing: :sweat_smile: :rofl: :sweat_smile: :laughing:

My dad, brother and myself had a 20ft x 12ft layout HO/OO modelled on GWR, Gods Wonderful Railway.
Dad was from Slough, right in the middle of GWR country.

My brother models in N Scale, T-Trak.

I went the way of electronics, I have a T-Trak module here, a job in progress to make an automated layout for display purposes, using CanBus to tie the modules together.

I'll be interested to see how you go with this project.

Tom... :smiley: :+1: :coffee: :australia:

Would this work in the loop , for each pin. digital write reads 1, Button changes to 0 runs variable, then resets the pin to 1 , then continues loop. No need for prevoius setting etc

if(digitalRead(BUTTON1_PIN) == 0, new_pos = 1, digitalWrite(BUTTON1_PIN == 1))

Charles

Hi Charles,

I'm not understanding what you're meaning, but detecting switch closures only involve digital reads.

Because the loops usually run so fast you need to be careful that you don't detect and then take an action - say - 10,000 times during the brief moment the switch is closed - and you also need to be careful that you allow for contact bounce or you'll press the button once but yet 2 to 4 activations.

I think we need to break this down to something simple that just deals with 1 switch and one response for now ... and when we've got that working the way you need (or doing something you understand) then we can easily scale it up to handle more switches and more things.

It just seems like at the moment we're not clear and specific about anything; I think the fastest way forward is to slow down and take 3 steps back ... eating the elephant one small bite at a time.

Thanks. I will .play around and get back to you tomorrow afternoon with a better explanation

Charles

No worries Charles.

I think it would be good to start with something like:

  1. I press and release a button

  2. I need the program to detect that and change a variable to indicate that it's been pressed.

  3. I then need the program to take some action because the contents of that variable now indicates that a button has been pressed before finally ...

  4. Clearing that indication after the action taken has completed so that we're ready for the next time the button is pressed.

Hi CjSouthern

Had a think about what you said and came up with the sketch in link. This is only only on the loop to check what is coming out. First time setting up something like this. It includes only the items I think need to be in it to get a result.

Do you think it would work. A friend saw me doing and is having a look too.
Charles

Hi Charles,

(Colin's my name by the way)

Let's "think like a computer" and just do one thing at a time.

So first thing I see is your #Define statements; they don't actually work that way ... and generally it's preferable to use "const" instead anyway because it then gives the compiler a greater chance of picking up errors.

If you want to keep using #define then here's a link to how to use it:

And if you want to do it the preferred way then here's a link to how to use "const":

How about we sort that first then continue looking at your sketch?

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.