More help with C code

  • Thread starter Thread starter slimbizzy
  • Start date Start date
  • Views Views 1,130
  • Replies Replies 3

slimbizzy

call me watchu want
Member
Joined
Apr 7, 2020
Messages
301
Reaction score
3,229
Trophies
1
Location
Calgary
Website
linktr.ee
XP
1,033
Country
Canada
Alright, so I have a new issue. And this one I REALLY cant figure out! I got the basics done, and I got some code written. But it gives me a weird output. Let me explain...

Alright so I got one of those membrane-matrix 4x4 keypads you can hook up to your Arduino or Rpi. I am using it with my pi.

The goal of this script is simple and that is that I just want to have it say which key I have pressed. Because once I have a nice, basic template I can proceed to make better and/or more complicated stuffs.

Anyways, I hook the keypad up to my GPIO pins, and I run this code:
Code:
 #include <wiringPi.h>
#include <stdio.h>

#define ROWS 4
#define COLS 4

char pressedKey = '\0';
int rowPins[ROWS] = {1, 4, 5, 6};
int colPins[COLS] = {26, 27, 28, 29};

char keys[ROWS][COLS] = {
   {'1', '2', '3', 'A'},
   {'4', '5', '6', 'B'},
   {'7', '8', '9', 'C'},
   {'*', '0', '#', 'D'}
};

void init_keypad()
{
   for (int c = 0; c < COLS; c++)
   {
      pinMode(colPins[c], OUTPUT);  
      digitalWrite(colPins[c], HIGH);
   }

   for (int r = 0; r < ROWS; r++)
   {
      pinMode(rowPins[0], INPUT);  
      pullUpDnControl(rowPins[r], PUD_UP);
   }
}

int findLowRow()
{
   for (int r = 0; r < ROWS; r++)
   {
      if (digitalRead(rowPins[r]) == LOW)
         return r;
   }

   return -1;
}

char get_key()
{
   int rowIndex;

   for (int c = 0; c < COLS; c++)
   {
      digitalWrite(colPins[c], LOW);

      rowIndex = findLowRow();
      if (rowIndex > -1)
      {
         if (!pressedKey)
            pressedKey = keys[rowIndex][c];
         return pressedKey;
      }

      digitalWrite(colPins[c], HIGH);
   }

   pressedKey = '\0';

   return pressedKey;
}

int main(void)
{
   wiringPiSetup();

   init_keypad();

   while(1)
   {
      char x = get_key();

      if (x)
         printf("you pressed: %c\n", x);
      else
         printf("you have nothing pressed shit head\n");

      delay(250);
   }

   return 0;
}

Now from what I can see, this code would theoretically work perfectly. Cept' when I excecute the script, I am greeted with a continuous message of, "you pressed: 1" even when I am NOT pressing "1".

Yeah that's it! If I were to press anything else, it would still say "you pressed 1". At first I thought the problem was the actual keypad, so what I did was disconnect the row1 and column1... Still got the "you pressed 1". Next I tried to run the script without the fucking keypad attached at all! And guess what, I still get "you pressed 1"...

SO. I have come to conclusion of thought that it is not the keypad that is broken, it is my code. If it would be too much trouble, could someone possibly tell me what I am doing wrong or if this shit is even possible? lol. Thanks in advance B)
 
I don't know if this can help but are you sure the input pins you're using can be properly used as input pins with pullup/pulldown? I never used GPIO on raspberry pi's but I remember having issues with using some pins as inputs on ESP32 microcontrollers
 
I don't know if this can help but are you sure the input pins you're using can be properly used as input pins with pullup/pulldown? I never used GPIO on raspberry pi's but I remember having issues with using some pins as inputs on ESP32 microcontrollers
To be honest, I don't know. I can try a different combination of pins and see if that changes anything.
 
I believe two things:

1. You're being too fast for the GPIO pins, you should probably wait between changing the state of the output and reading the state of the inputs.
2. I don't think it is a good idea to set all columns to output, with one column to LOW and the others to HIGH, this leads to fire when you are annoying and press two keys in the same row at the same time (as you then shortcircuit two column outputs); I would put ALL columns to HiZ/Input, and only one to OUTPUT/LOW instead.

I also believe that when you iterate over the ROWS in that for in init_keypad, you might want to do "pinMode(rowPins[r], INPUT);" instead of "pinMode(rowPins[0], INPUT);"

Also, I am not familiar with wiringPi, but checking the reference if you call wiringPiSetup() then it later only expects pin numbers from 0 to 16:

wiringPiSetup (void) ;
This initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. See the pins page for a table which maps the wiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector.

This function needs to be called with root privileges.

Check here:
http://wiringpi.com/reference/setup/
https://projects.drogon.net/raspberry-pi/wiringpi/pins/

So in short:
  • I believe it doesn't work mainly because you are using incorrect pin numbers
  • It would be a good idea to wait between write to pin and read from pin
  • I think you will want to avoid setting all columns to output and some with different levels, unless you like broken outputs
 
Last edited by sarkwalvein,

Site & Scene News

Popular threads in this forum