Pages: [1] 2   Go Down
Author Topic: multiple buttons on one analog pin  (Read 1009 times)
0 Members and 1 Guest are viewing this topic.
Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I have been looking through the forum and have tried several methods to get multiple buttons, in my case 4, on a single analog pin.  I have everything set up with one side of the buttons going to 5V and the other going through varying resistors to the analog pin.  Then, when I put in the code it gives me an error from the AnalogButtons.h header file stating that "'boolean' does not name a type" or "'boolean' has not been declared.  This is being used in a timer.  The buttons are suppose to increase the time or start/stop or reset the timer.  The code follows:

float analogpin = 0;           // select pin as analog input to detect button push
float ButtonPushed = 0;     // variable to store button push value
float startbutton = 0;        // variable to store if startbutton is pushed


  do
  {
    ButtonPushed = analogRead(analogpin);
 
    if (ButtonPushed > .00025 && ButtonPushed < .0006) // in mV
    {
      initTime += 5;
      delay (200);
    }
    else if (ButtonPushed > .00015 && ButtonPushed < .00025)
    {
      initTime += 15;
      delay (200);
    }
    else if (ButtonPushed > .00006 && ButtonPushed < .00015)
    {
      startbutton = 1;
      delay (200);
    }
    else if (ButtonPushed > .00004 && ButtonPushed < .00006)
    {
      delay (200);
      return;
    }
   }while (startbutton = 0);
Logged

Santa Fe
Offline Offline
Full Member
***
Karma: 1
Posts: 201
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

looks like a perfectly good sketch to me.  I tried it and go no compile errors ( not using AnalogButtons.h )
I am not sure why you need AnalogButtons.h. Where did you find this library?
Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

in the tutorial for using analog pins and buttons it says that you need it.  I tried it without and it compiles but I am having other issues now.  I will post again later with an update and questions.

Thanks again for the help.
Logged

Phoenix, Arizona USA
Offline Offline
Faraday Member
**
Karma: 40
Posts: 5570
Where's the beer?
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You might want to re-read the section on "analogRead()":

http://arduino.cc/en/Reference/analogRead

Note - and I quote:

"Returns: int (0 to 1023)"

You are attempting to (somehow) return a float value and use it; this -will not- work. You need to redefine your variables as int data types, and return that value, and compare them to an integer value between 0 and 1023 (inclusive). Modify your code to do this, try it out, then if you are still having problems, repost your new code here.
Logged

I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the help.  I made the changes and it seems to recognize the button pushes now but I don't know how to tell for sure.  I tried writing another short program to see the button pushes and print the values to the computer screen but that isn't working.  I read through some posts and tutorials and don't know what to do now.  I am using an Uno by USB.

here is the changes to the code

Code:
do
  {
    ButtonPushed = ceil(analogRead(analogpin));
    // Increment Time 5 minutes
    if (ButtonPushed > 900 && ButtonPushed < 1000)
    {
      initTime += 5;
      delay (200);
    }
    // Increment Time 15 minutes
    else if (ButtonPushed > 600 && ButtonPushed < 800)
    {
      initTime += 15;
      delay (200);
    }
    // Start/Stop
    else if (ButtonPushed > 250 && ButtonPushed < 400)
    {
      startbutton = 1;
      delay (200);
    }
    // Reset
    else if (ButtonPushed > 50 && ButtonPushed < 150)
    {
      delay (200);
      return;
    }
   }while (startbutton = 0);

« Last Edit: June 05, 2012, 06:27:35 pm by bhunt2 » Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks again everyone for the help.

Here is all of my code to take a look at: (it is a variation of other code that was shared and much of my doing, which is probably the issue).

Code:
// Count down timer starting at a user inputted time designated by the pushing
// of 5 or 15 minute incrementing buttons.  There is also a start/stop button
// and a reset button.

int unsigned long initTime = 0;
int time = 0;

// Bit maps for the seven segment display
const unsigned char Segments[] =
{ //dot,G,F,E,D,C,B,A
  0b11000000, // 0
  0b11001111, // 1
  0b10100100, // 2
  0b10000110, // 3
  0b10001011, // 4
  0b10010010, // 5
  0b10010000, // 6
  0b11000111, // 7
  0b10000000, // 8
  0b10000011, // 9
};


// List of digit select lines, least significant digit first
const unsigned char DigitPins[] = {9, 10, 11, 12};  // Anodes (LOW for on, HIGH for off)
const unsigned char SegmentPins[] = {8,7,6,5,4,3,2};  // Cathodes (HIGH for on, LOW for off)


int analogpin = A0;     // select analog input pin to detect button push
int ButtonPushed = 0;   // variable to store button push value
int startbutton = 0;    // variable to store start button push to begin countdown
int stopbutton = 0;     // I have not implemented the stop sequence as I am unsure
                        // as to how to do it.

void setup()
{
  for (int i=0; i<4; i++)
  {
    pinMode(DigitPins[i],OUTPUT);
    digitalWrite(DigitPins[i],HIGH);
  }

  for (int i=0; i<8; i++)
  {
    pinMode(SegmentPins[i],OUTPUT);
    digitalWrite(SegmentPins[i],LOW);
  }
}

void loop()
{
  do
  {
    ButtonPushed = ceil(analogRead(analogpin));
    // Increment Time 5 minutes
    if (ButtonPushed > 900 && ButtonPushed < 1000)
    {
      initTime += 5;
      delay (200);
    }
    // Increment Time 15 minutes
    else if (ButtonPushed > 600 && ButtonPushed < 800)
    {
      initTime += 15;
      delay (200);
    }
    // Start/Stop
    else if (ButtonPushed > 250 && ButtonPushed < 400)
    {
      startbutton = 1;
      delay (200);
    }
    // Reset
    else if (ButtonPushed > 50 && ButtonPushed < 150)
    {
      delay (200);
      return;
    }
   
    // Display initTime while user is inputting.
    WriteDigit(initTime);
   }while (startbutton = 0);
   // Start counting down when Start/Stop button is pushed
 
  // calculate time according to user input
  unsigned long hundredths = ((initTime*60000)-millis()) / 10;
  unsigned long seconds = hundredths / 100;
  unsigned long minutes = seconds / 60;

  int hours = minutes / 60;
  int clock;

  // Display minutes:seconds up to 100 minutes or hours/minutes dependant on user input
  if (seconds < 100)
    clock = (seconds % 100) * 100 + (hundredths % 100);
  else if (minutes < 100)
    clock = (minutes % 100) * 100 + (seconds % 60);
  else
    clock = (hours % 100) * 100 + (minutes % 60);

  // Display countdown on 7-Segment
  WriteDigit(clock);
}


void WriteDigit(int time)
{
  // Clear all segments before enabling a digit
  for (int s=0; s<8; s++)
  {
    digitalWrite(SegmentPins[s],HIGH);
  }
 
// Display each digit, right to left
  for (int i=0; i<4; i++)
  {
   
    // Peel a digit off the low end of the number
    int digit = time % 10;
    time /= 10;
   
    // Blank the MSD if it is zero
    if (i==3 && digit == 0)
    {
      for (int s=0; s<8; s++)
        digitalWrite(SegmentPins[s],HIGH);
    }
    else
    {
      // Display the digit on the seven segments
      unsigned char segments = Segments[digit];

      for (int s=0; s<8; s++)
      {
        digitalWrite(SegmentPins[s], segments & 1);
        segments >>= 1;
      }
    }

    // Turn on the digit briefly
    digitalWrite(DigitPins[i], HIGH);  // Select one digit

    delay(3);
    digitalWrite(DigitPins[i], LOW);
  }
}

I have made notes throughout, but the issue I am currently having is the display.  Before putting the buttons in the display worked fine.  I would just initialize initTime to a desired value and it would display the countdown.  Now, I am getting most of the segments lit up and it is not showing the current initTime value or counting down after I push the StartButton.

Please take a look and see what you think.
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This probably don't do what you expect it to:

Code:
}while (startbutton = 0);

This is an assignment and not a value check. The loop will execute exactly once as the condition is always false (assignment returns the value assigned).
Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ah yes, I will try that here shortly.  I totally missed that, thank you.  Does anyone else see anything wrong?
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The ceil() is completely unnecessary here:

Code:
ButtonPushed = ceil(analogRead(analogpin));

analogRead returns an integer, you're enforcing a double cast (to float and back to integer again).
Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, I made all of those changes and a couple of others.  When the program starts it should display '0000', but it displays '0137'.  I don't get this at all.  I tried a test run with an earlier version of the code before the buttons were added and the digits are all wired properly still.  So, the only thing I can think of is that there is a code issue with do/while loop getting the initial time from the buttons.

If anyone has any ideas it would be greatly appreciated.


Code:
// Count down timer starting at a user inputted time designated by the pushing
// of 5 or 15 minute incrementing buttons.  There is also a start/stop button
// and a reset button.

int unsigned long initTime = 0;
int time = 0;

// Bit maps for the seven segment display
const unsigned char Segments[] =
{ //dot,G,F,E,D,C,B,A
  0b11000000, // 0
  0b11001111, // 1
  0b10100100, // 2
  0b10000110, // 3
  0b10001011, // 4
  0b10010010, // 5
  0b10010000, // 6
  0b11000111, // 7
  0b10000000, // 8
  0b10000011, // 9
};


// List of digit select lines, least significant digit first
const unsigned char DigitPins[] = {9, 10, 11, 12};  // Anodes (LOW for on, HIGH for off)
const unsigned char SegmentPins[] = {8,7,6,5,4,3,2};  // Cathodes (HIGH for on, LOW for off)


int analogpin = 0;     // select analog input pin to detect button push
int ButtonPushed = 0;   // variable to store button push value
int startbutton = 0;    // variable to store start button push to begin countdown
int stopbutton = 0;     // I have not implemented the stop sequence as I am unsure
                        // as to how to do it.

void setup()
{
  for (int i=0; i<4; i++)
  {
    pinMode(DigitPins[i],OUTPUT);
    digitalWrite(DigitPins[i],HIGH);
  }

  for (int i=0; i<8; i++)
  {
    pinMode(SegmentPins[i],OUTPUT);
    digitalWrite(SegmentPins[i],LOW);
  }
}

void loop()
{
  do
  {
    ButtonPushed = analogRead(analogpin);
   
    // Increment Time 5 minutes
    if (ButtonPushed > 900 && ButtonPushed < 1000)
    {
      initTime += 5;
      delay (200);
    }
   
    // Increment Time 15 minutes
    else if (ButtonPushed > 600 && ButtonPushed < 800)
    {
      initTime += 15;
      delay (200);
    }
   
    // Start/Stop
    else if (ButtonPushed > 250 && ButtonPushed < 400)
    {
      startbutton = 1;
      delay (200);
    }
   
    // Reset
    else if (ButtonPushed > 50 && ButtonPushed < 150)
    {
      delay (200);
      return;
    }
   
    // Display initTime while user is inputting.
    WriteDigit(initTime);
   
   }while (startbutton == 0);
   // Start counting down when Start/Stop button is pushed
 
   // calculate time according to user input
   unsigned long hundredths = ((initTime*60000)-millis()) / 10;
   unsigned long seconds = hundredths / 100;
   unsigned long minutes = seconds / 60;

   int hours = minutes / 60;
   int clock;
 
   // Display minutes:seconds up to 100 minutes or hours/minutes dependant on user input
   if (seconds < 100)
     clock = (seconds % 100) * 100 + (hundredths % 100);
   else if (minutes < 100)
     clock = (minutes % 100) * 100 + (seconds % 60);
   else
     clock = (hours % 100) * 100 + (minutes % 60);
 
   // Display countdown on 7-Segment
   WriteDigit(clock);
}


void WriteDigit(int time)
{
  // Clear all segments before enabling a digit
  for (int s=0; s<8; s++)
  {
    digitalWrite(SegmentPins[s],HIGH);
  }
 
// Display each digit, right to left
  for (int i=0; i<4; i++)
  {
   
    // Peel a digit off the low end of the number
    int digit = time % 10;
    time /= 10;
   
    // Display the digit on the seven segments
    unsigned char segments = Segments[digit];

    for (int s=0; s<8; s++)
    {
      digitalWrite(SegmentPins[s], segments & 1);
      segments >>= 1;
    }
   

    // Turn on the digit briefly
    digitalWrite(DigitPins[i], HIGH);  // Select one digit

    delay(3);
    digitalWrite(DigitPins[i], LOW);
  }
}
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 108
Posts: 5144
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I haven't seen your circuitry but I'd guess A0 is floating while no button is pressed (not connected anywhere). You can use a bigger resistor to GND to have a default reading of 0.
Logged

Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, I made some more changes and got "better" results.  I guess while copying and pasting from file to file I misplaced part of the card that dealt with the actual calculation of how to display the digits.  I put it in and did a couple of other things and now I get '0000' initially and the 5 minute increment button works but the others don't.  In response to the schematic for the timer, I don't have anyway of putting one up as of right now.  I can't take a picture and I don't know of a program I could use to make one.

Also, I am currently using a voltage divider setup for the buttons (i.e. a resistor from the Vs to one side of the button and a resistor on the other side going to ground with the connection back to analog pin A0 from that side. the resistor to ground is 10k)

Here is my new code.

Code:
// Count down timer starting at a user inputted time designated by the pushing
// of 5 or 15 minute incrementing buttons.  There is also a start/stop button
// and a reset button.

// List of digit select lines, least significant digit first
const unsigned char SegmentPins[] = {8,7,6,5,4,3,2};  // {A,B,C,D,E,F,G} Cathodes (HIGH for on, LOW for off)
const unsigned char DigitPins[] = {9, 10, 11, 12};  // {1,2,3,4} Anodes (LOW for on, HIGH for off)

// Button setup
int analogpin = A0;     // select analog input pin to detect button push
int ButtonPushed = 0;  // variable to store button push value
int startbutton = 0;   // variable to store start button push to begin countdown
int stopbutton = 0;    // I have not implemented the stop sequence as I am unsure
                       // as to how to do it.


// Bit maps for the seven segment display
const unsigned char Segments[] =
{ //dot,G,F,E,D,C,B,A
  0b11000000, // 0
  0b11001111, // 1
  0b10100100, // 2
  0b10000110, // 3
  0b10001011, // 4
  0b10010010, // 5
  0b10010000, // 6
  0b11000111, // 7
  0b10000000, // 8
  0b10000011, // 9
};




void setup()
{
  for (int i=0; i<4; i++)
  {
    pinMode(DigitPins[i],OUTPUT);
    digitalWrite(DigitPins[i],HIGH);
  }

  for (int i=0; i<8; i++)
  {
    pinMode(SegmentPins[i],OUTPUT);
    digitalWrite(SegmentPins[i],LOW);
  }
}

void loop()
{
  // variables used for time initialization
  int initTime = 0;
 
  do
  {
    ButtonPushed = analogRead(analogpin);
   
    // Increment Time 5 minutes
    if (ButtonPushed > 500 && ButtonPushed < 600)
    {
      initTime += 5;
      delay (200);
    }
   
    // Increment Time 15 minutes
    else if (ButtonPushed > 250 && ButtonPushed < 400)
    {
      initTime += 15;
      delay (200);
    }
   
    // Start/Stop
    else if (ButtonPushed > 125 && ButtonPushed < 250)
    {
      startbutton = 1;
      delay (200);
    }
   
    // Reset
    else if (ButtonPushed > 50 && ButtonPushed < 125)
    {
      delay (200);
      return;
    }
     // calculate time according to user input
   unsigned long hundredths = (initTime*60000) / 10;
   unsigned long seconds = hundredths / 100;
   unsigned long minutes = seconds / 60;
   int hours = minutes / 60;
   
   // Display initTime while user is inputting.
   WriteDigit(hundredths, seconds, minutes, hours);
   
   }while (startbutton == 0);
   // Start counting down when Start/Stop button is pushed
 
   int currentmillis = millis(); // used to initialize the time for countdown
   
   // calculate time according to user input
   unsigned long hundredths = ((initTime*60000+currentmillis)-millis()) / 10;
   unsigned long seconds = hundredths / 100;
   unsigned long minutes = seconds / 60;
   int hours = minutes / 60;
   
   // Display countdown on 7-Segment
   WriteDigit(hundredths, seconds, minutes, hours);
}


void WriteDigit(unsigned long hund, unsigned long sec, unsigned long minu, int hrs)
{

 
  int clock;
 
    // Display minutes:seconds up to 100 minutes, then hours/minutes
  if (sec < 100)
    clock = (sec % 100) * 100 + (hund % 100);
  else if (minu < 100)
    clock = (minu % 100) * 100 + (sec % 60);
  else
    clock = (hrs % 100) * 100 + (minu % 60);
  // Clear all segments before enabling a digit
  for (int s=0; s<8; s++)
  {
    digitalWrite(SegmentPins[s],HIGH);
  }
 
// Display each digit, right to left
  for (int i=0; i<4; i++)
  {
   
    // Peel a digit off the low end of the number
    int digit = clock % 10;
    clock /= 10;
   
    // Display the digit on the seven segments
    unsigned char segments = Segments[digit];

    for (int s=0; s<8; s++)
    {
      digitalWrite(SegmentPins[s], segments & 1);
      segments >>= 1;
    }
   

    // Turn on the digit briefly
    digitalWrite(DigitPins[i], HIGH);  // Select one digit

    delay(3);
    digitalWrite(DigitPins[i], LOW);
  }
}
Logged

New Hampshire
Offline Offline
God Member
*****
Karma: 17
Posts: 781
There are 10 kinds of people, those who know binary, and those who don't.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

a resistor from the Vs to one side of the button and a resistor on the other side going to ground with the connection back to analog pin A0 from that side.

You're gonna have to find some way of showing exactly how you have your buttons wired up.  I'm not convinced you have things wired up properly.  Are you trying to take into account multiple buttons being pushed at the same time?
Logged


Portland, OR
Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am not taking into account that multiple buttons may be pushed.  I don't intend on that being a problem.  The wiring I am sure is ok because I tested it by other means to make sure I would be getting what I wanted from them.

After reviewing the code for a few hours last night I was able to get the 5 and 15 minute increment buttons to work and the start button.  Now, for some reason my reset button doesn't work anymore (it had been working during the initial time setting stage by resetting the count to zero).

I also would like to use the start button as a stop button to be able to stop and start the countdown at will.  I am not sure how this can be accomplished, but at the least I would like to figure out the reset button so that I can restart the program again while the countdown is going.

Any ideas?
Logged

Global Moderator
Boston area, metrowest
Offline Offline
Brattain Member
*****
Karma: 534
Posts: 26958
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Use the button to set/clear a flag to indicate which state you are in:
Code:
if (digitalRead(startStopbutton == 0){ // assumes pin has internal pullup, button press connects the pin to ground
startStop = 1-startStop;  // so startStop changes 1,0,1,0 when the button is pressed
// add a time check if you want to limit how often it is checked, like every 50mS or something
}
// do something based on new state of startStop
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Pages: [1] 2   Go Up
Jump to: