Pages: [1]   Go Down
Author Topic: button array status poll via PORTD  (Read 1021 times)
0 Members and 1 Guest are viewing this topic.
Glasgoow
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi guys I have an Arduino 2009 board with Atmega 328 and it's configured in this way:
pins ,4,5,6 are connected to switch buttons (in total 3)
pins 7 is to connected to a LED

I want to poll the status of the buttons and if any change is detected update the LED status.
I wrote a simple code but is not working (the LED never switches on), I never used the PORTD register before so I guess is something wrong with the data type.


byte old;
int buttons[6];
void setup() {
  
        int pin;
        old=0;
        for (pin=1; pin <= 6; ++pin) {
            pinMode (pin, INPUT);
        }

        for (pin=7; pin <= 13; ++pin) {
            pinMode (pin, OUTPUT);
            digitalWrite (pin, HIGH);
        }
}
void allOn()
{
       for (int pin=8; pin <= 13; ++pin) {
            digitalWrite (pin, HIGH);
        }
}

void allOff()
{
         for (int pin=8; pin <= 13; ++pin) {
            digitalWrite (pin, LOW);
        }
}

boolean output()
{

}
boolean check()
{
  byte check=PORTD & B01110000;
  byte diff=check ^ old;
  old=check;
  if(diff>0)
    return true;
  else
    return false;
    
}

void loop(){

  //something has changed!
  if(check())
  {
  output();
  digitalWrite (13, HIGH);
  delay(500);
  }
  else
  {
     digitalWrite (13, LOW);
  //sample every 10 msec
  delay(10);
  }
}
Logged

0
Offline Offline
Sr. Member
****
Karma: 4
Posts: 329
KC4MM
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How do you have your switches wired? Between the input pins and what?
If they are wired from the inputs to ground and you don't have external pullups turn on the internal ones by writing each of the INPUT pins high.

int pin;
       old=0;
       for (pin=1; pin <= 6; ++pin) {
           pinMode (pin, INPUT);
           digitalWrite(pin, HIGH);    // add this
       }
« Last Edit: May 24, 2009, 08:47:21 pm by RoyK » Logged

0
Offline Offline
Faraday Member
**
Karma: 16
Posts: 2857
ruggedcircuits.com
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

When reading digital inputs you need to read the PIND register, not the PORTD register. When writing to outputs you write to the PORTD register.
Logged

Glasgoow
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the tip.
Now is almost working:



unsigned char old;
unsigned char check;
unsigned char diff;
void setup() {
  
        int pin;
        old=0;
        for (pin=1; pin <= 6; ++pin) {
            pinMode (pin, INPUT);
        }

        for (pin=8; pin <= 13; ++pin) {
            pinMode (pin, OUTPUT);
            //digitalWrite (pin, HIGH);
        }
}
void allOn()
{
       for (int pin=8; pin <= 13; ++pin) {
            digitalWrite (pin, HIGH);
        }
}

void allOff()
{
         for (int pin=8; pin <= 13; ++pin) {
            digitalWrite (pin, LOW);
        }
}

void actuate()
{
  PORTB = B00000111;
  //PORTB |= check>>5;
}
boolean checkstatus()
{
  check=PIND & B01110000;
  diff=check ^ old;
  old=check;
  if(diff==0)
    return false;
  else
    return true;
    
}

void loop(){

  //something has changed!
  if(checkstatus())
  {
  actuate();
  //digitalWrite (13, HIGH);
  delay(500);
  }
  else
  {
     //digitalWrite (13, LOW);
  //sample every 10 msec
  delay(10);
  }
}


but strangely the LED on port 10 is always HIGH and the other LEDS on port 8,9 are always LOW.
Am i Using PORTB correctly?
Logged

0
Offline Offline
Faraday Member
**
Karma: 16
Posts: 2857
ruggedcircuits.com
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You're using PORTB correctly, but never initializing it. Try calling allOff() in the setup().

And as another poster noted, if you have your switches wired from the input pin to ground, you have to enable the internal pullup on the inputs.
Logged

Glasgoow
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi now is working and thanks ALL for the big help.

My buttons are wired with a pull-up resistor:
so when the buttons are not pressed the register's bits are set to 1.
I saw another tutorial here:
http://www.ladyada.net/learn/arduino/lesson5.html
and they are using an input resistor of 100 Ohm.
Should I add that one as well or I can just use the internal pull up with the code by RoyK ?

The working code is now:

unsigned char old;
unsigned char check;
unsigned char diff;
void setup() {
  
        int pin;
        old=0;
        for (pin=4; pin <= 6; ++pin) {
            pinMode (pin, INPUT);
        }

        for (pin=8; pin <= 10; ++pin) {
            pinMode (pin, OUTPUT);
            digitalWrite (pin, LOW);
        }
         Serial.begin(9600);
        
         test();
}

void test()
{
  
          for (int pin=8; pin <= 10; ++pin) {
            digitalWrite (pin, HIGH);
                delay(500);
        }
        /*
  PORTB = B00000000;
    delay(500);
  PORTB = B00000100;
    delay(500);
  PORTB = B00000010;
    delay(500);
  PORTB = B00000001;
  */
}
void allOn()
{
       for (int pin=8; pin <= 13; ++pin) {
            digitalWrite (pin, HIGH);
        }
}

void allOff()
{
         for (int pin=8; pin <= 13; ++pin) {
            digitalWrite (pin, LOW);
        }
}

void actuate()
{
  PORTB = ~old>>4;
}
boolean checkstatus()
{
  check=PIND & B01110000;
  diff=check ^ old;
  old=check;
  if(diff==0)
    return false;
  else
    return true;
    
}

void loop(){

  //something has changed!
  if(checkstatus())
  {
  Serial.println(old, BIN);
  actuate();
  //digitalWrite (13, HIGH);
  delay(500);
  }
  else
  {
  //PORTB = B00000000;
  //sample every 10 msec
  delay(10);
  }
}
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 77
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can use the internal pull-up resistors for this, just connect the other side of your switches to ground and do:

pinMode(pin, input);
digitalWrite(pin, HIGH);

I looove the internal pull-up resistors.  smiley
Logged

Glasgoow
Offline Offline
Newbie
*
Karma: 0
Posts: 15
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wow that's amazing, even if is setup as an input pin I can drive it high to enable the internal pull-up!
Oky I try this as well!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 48
Bald-Headed, Middle-Aged Nerd
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Re: internal pull-up resistors

If I run this code:

pinMode(pin, input);
digitalWrite(pin, LOW);

Will the internal pull-up resistor be disconnected?

I'm NOT asking if it will pull the input DOWN.
I understand that that won't happen.

I have no practical need to do this.
I just want to understand this better.
Thank you.

BobW
Logged

0
Offline Offline
Faraday Member
**
Karma: 16
Posts: 2857
ruggedcircuits.com
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

That's correct. The pull-up will be disconnected.
Logged

Pages: [1]   Go Up
Jump to: