PE File Reader

Pe File Reader [Opening .exe files to analyze the PE-header] Hello_Friend, and welcome to the 20's, Cybermonkeys! Let's start this decade by learning some stuff. Last year, we already took an in-depth look at Linux-binaries (aka ELF files) , now let's start messing around with it's infamous Windows-Counterpart (that also happens to be the xBox file format). Introduction The PE-file format is around for quite some time now, and while heavy optimizations took place, it hasn't really changed all that much since then. In fact, it is one of the most widely encountered file formats out in the wilds. Although there is technically a difference between PE32 files (32bit) and PE32+ files (64bit), we will ignore this fact for the sake of this blogpost. Some file extensions deriving from this format are: .acm   [ a Windows audio-codec] .ax    [MPEG-4 DVD format] .cpl   [dynamic link libraries for control panels] .dll   [dynamic link lib...

4x4 Matrix Keypad driver


Building a 4x4 matrix keypad driver

[ in c++, using an Arduino ]


Hellofriend,

Today I wanna show you some stuff I built with Arduino.
Building hardware drivers is fun and ez, and there isn't really much stuff you can't build with Arduino microcontrollers. There are many cheap vendors for these little gems, and they range from 3€ to about 25€, depending on model and vendor.

So, what are we gonna build here anyways?

Introduction

Everybody knows how to use a keypad.
Just type in your code or whatever and press ok.
These parts are often build into security locks, you could for example tape one onto your computer to prevent anybody to turn it on without the correct pin. Since it has a powerfull self-glueing backpatch, you can stick it basicly everywhere.

Unfortunately, most of the code in the Arduino forums is crap somebody copied from somebody else, and the one originally writing the tutorial was rather doing a proof-of-concept.

Luckily, we can just write our own code.
Since this is a tutorial about a keypad, not about Arduino itself,
I am going to keep it simple. You can always improve the code I am going to present you, the first thing to come to mind would be using pin change interrupts. Feel free to mod the hell out of this code.

[disclaimer: we are not using any kind of library here, this is all plain code]

A look inside the hardware

Before we even start coding anything, we have to further investigate how this piece basicly worx.
As you can see in the picture, the keypad has 8 pinouts. This is rather much for a simple keypad, so you might wanna use a single Arduino nano as hardware driver, communicating with the rest of the system per serial output.

Here is a picture of the connection inside the keypad:
As you can see, each conductor track is going straight forward in a line, crossing other tracks as it reaches inside the keypad. If we press a button, the 2 underlying tracks will close and we will (hopefully) recognize a signal. That said, you should have already figured out that 4 tracks are used as current input, while the other 4 are listening ports.

So, the basic wireing for out project is as simple as this:
[picture not related]
ATTENTION!
Please double check the code we are going to write, and make sure you have set the input pullup option for the input pins in every case to prevent the hardware from getting damaged!
Although Arduinos have build-in short-circuit preventions, what we are basicly doing is exactly this: a short-circuit. Don't blame me if you brick your shit!

The code

Let's first fly over the code, I will explain more below:


 /* Reverse Keypad Handler  
  * 2nd version  
  * by clockw0rk @ 26.02.2017  
  */  
   
 //define rows and columns  
 const byte row [4] = {9,8,7,6};  
 const byte col [4] = {5,4,3,2};  

 //keep it generic-for different keypads, you can use this
 //const byte rowCount = sizeof(row) / sizeof(row[0]);
 //const byte colCount = sizeof(col) / sizeof(col[0]);

 byte counter = 0;  
 byte colCount;  
   
 //16 felder tastenbelegung 4x4 matrix  
 const byte keys [ 0x4 ] [ 0x4 ] =  
 {  
   {0x1,0x2,0x3,0xA},  
   {0x4,0x5,0x6,0xB},  
   {0x7,0x8,0x9,0xC},  
   {0xE,0x0,0xF,0xD}  
 };  
   
   
 void setup() {  
  for(int c = 0; c != 4; c++)  
  {  
   pinMode (row[c], INPUT_PULLUP);  
   pinMode (col[c], OUTPUT);  
   digitalWrite(col[c], LOW);  
  }  
    
   Serial.begin (9600); //9600 BAUD for Uno Board Serial Communication  
   Serial.println("INITIALISATION FINISHED\nEntering work loop...\n");  
    
 }  
   
 void loop() {  
    
  // cycle through input pins and check for a signal  
  if(digitalRead(row[counter]) == 0)  
  {  
   checkRoutine();  
  }  
   
  //reset counter for each iteration cycle  
  counter <3 ? counter++ : counter = 0;  
   
 }  
   
 void checkRoutine(){  
   
  colCount = 0;  
    
  //debugging: give me the linecount  
  Serial.print("[ LOW ] on line ");  
  Serial.print(counter);  
  Serial.print("\n");  
   
  //now find which number is pressed  
  while(colCount < 4 && digitalRead(row[counter]) == 0)  
  {  
    digitalWrite(col[colCount], HIGH);  
    colCount++;  
  }  
   
  //remember we incremented in while loop  
  Serial.print("Button pressed is [ ");  
  Serial.print(keys[counter][colCount -1]);  
  Serial.print(" ]\n");  
   
   
  //reinitialise output  
  for(int c = 0; c != 4; c++)  
  {  
     digitalWrite(col[c], LOW);  
  }  
   
  //wait until user releases button  
  while(digitalRead(row[counter])==0)  
  {;}  
 }  


I marked some lines and blocks for, let's now again crawl through the code. I will provide some information about stuff that is going on there.

Lines 7 - 16

Arrays:
We are initialising and declaring some stuff here. First of all, we are creating 2 arrays representing our rows and columns, respectivly. We are declaring them as const so the compiler will have it easy to optimize stuff.
If you want, you can also write these values to flash-memory using the keyword PROGMEM, but I don't really feel like doing this for 8 bytes.

out-commented:
If you are programming for keypads with variable length, you could use this old c-trick to dynamicly get the lenght of the arrays, but for this simple example we don't really need them.

The last two variables are for controling the program-flow, hence they are not set to const.

Line 19

Here we are declaring the actual values that are printed out later, and since we have exactly 16 keys on our keypad, I felt like giving them hexadecimal values.


Lines 28 - 39

This is our setup routine. First, we are iterating over the row- and cols-arrays, setting the pinMode for each one. The colums are our output pins here, so we are writing a LOW-signal on each one.
The current-tracks are therefor going vertically from bottom to top.

Line 44

I don't really like overloading the loop function with to much stuff, so all we are doing here is checking wether one of our input-pins has a signal coming in (check for 0 → LOW signal)
[ the imaginary button is on low state, thus pressed down, so we have active connection ]

Line 50

Using ternary operator here for swag. All this line does is resetting the counter if it reaches the maximum value ( 3 in this case ).

Line 54 - 85

In this routine we are finding the actual key that was pressed. Remember I told you that each pin goes in a straight track through the buttons on the keypad? This means that if we have a signal, there are 4 possible buttons that could be pressed in this moment, so we have to figure out which is the button that is actually pressed, entiendes?

So, first we need the line on which the signal was received. If you actually read through the code, you found out that we already have this information available: the counter variable.

So, how to find out which is the actual button? Well, we can find out which button is not pressed.
We are going to cycle over the output pins with out colCount variable, disabling one output pin after another. As long as the input pin's state does not change, we know that this is not the button we are looking for. As soon as the signal is gone (which we are checking in the while loop btw), we know we have a hit.

Now we print the pressed button to serial, and voila! we have successfully read a keypress.
But we still aren't finished here, let's make sure the keypad keeps working as intended.
First, we set all outputs to LOW again, so the keypad is in it's initial state again.
Next, we wait for the user to release the button again, so we won't read it twice. When the button is released eventually, we are leaving the frame, freeing the stack and returning to our normal waiting routine.

Summary



This is a rather simple project, cybermonkeys, which you should, even as a scrub, solve in about half an hour. But it shows the basics really good: Arduino is component-orientated. If you have a bigger system and want to expand it with a keypad, just plug another nano onto serial and go for it.

Of course, this code is for presantation purpose only, and can be improved by some means:

  1. The use of pinchange interrupts
  2. A sleeping function (so the MC won't leech energy all the time)
  3. Outsourcing the functionality into a oop-style class system (we will look into this later)
If I where to work on this project for a customer / company, I would for sure implement all 3 of the above points (and even more), but for scrambling around this code will always do.


That's it - I hope you took something from this post. If you have any questions, improvements or comments, just feel free to post them below.


Rules of thumb:
Watch your back.
Have a plan B.
Never ever cut a deal with a dragon

- numb.3rs

Comments