FUNdamentals of Writing a Library

Since working at Digilent, I have learned several lessons. One of these is that whenever I am done programming a library, I should have some fun by creating a small side project using it. This way, I can understand my library on a new depth, and find any limitations or errors in it. Also I get to have fun, which is well, always fun!

20160816_150920
Having so much fun!

A good example of this occurred last week. I just finished a library for the PmodSSD, which is a 2 digit seven segment display. This Pmod utilizes 12 pins. Pins 1 through 7 each light up a single segment on the display, while pin 8 switches between the left and right digit. This display can only light up one digit at a time, so in order to simulate a 2 digit number it needs to flash the numbers on both sides fast enough so that the human eye can see both numbers at once.

Here is what I came up with:

void SnakePattern(){
// start timer
long startTimer = counter;
while(startTimer + displayTime > counter){
// select left digit
digitalWrite(pinArray[7], HIGH);
// print snake at segment A of left digit
digitalWrite(pinArray[0], HIGH);
digitalWrite(pinArray[1], LOW);
digitalWrite(pinArray[2], LOW);
digitalWrite(pinArray[3], LOW);
digitalWrite(pinArray[4], LOW);
digitalWrite(pinArray[5], LOW);
digitalWrite(pinArray[6], LOW);
delay(1);

// select right digit
digitalWrite(pinArray[7], LOW);
// print snake at segment A of right digit
digitalWrite(pinArray[0], HIGH);
digitalWrite(pinArray[1], LOW);
digitalWrite(pinArray[2], LOW);
digitalWrite(pinArray[3], LOW);
digitalWrite(pinArray[4], LOW);
digitalWrite(pinArray[5], LOW);
digitalWrite(pinArray[6], LOW);
delay(1);
}
startTimer = counter;
while(startTimer + displayTime > counter){
// select left digit
digitalWrite(pinArray[7], LOW);
// print snake at segment B right digit
digitalWrite(pinArray[0], LOW);
digitalWrite(pinArray[1], HIGH);
digitalWrite(pinArray[2], LOW);
digitalWrite(pinArray[3], LOW);
digitalWrite(pinArray[4], LOW);
digitalWrite(pinArray[5], LOW);
digitalWrite(pinArray[6], LOW);
delay(1);

// This continues on and on until pattern is done. It is a lot of lines.

My library was very simple, as you can see above. Basically, it takes a number, matches it to a case in a switch statement, and that case performs 7 digitalWrites() to display that number on the PmodSSD. This function worked, and I was about to publish it.

However, I followed my lesson and decided to have some fun! Numbers are boring, I wanted to make some extravagant patterns on the display. So I set off to simulate a pattern of a snake circling around the display.

I coded this pattern the same way I coded the numbers being displayed, by individually telling pins 1 to 7 to be HIGH or LOW. As you can imagine, this requires A LOT of lines of code, and therefore a lot of screen scrolling. Without wanting to make this pattern, I wouldn’t have known just how wasteful my code was. To make it more efficient, I fit all 7 lines of digitalWrite()’s into a single binary array.


void DisplayPattern(int binArray1[7], int binArray1[7]){
// grab current time from timer to start countdown
long startTimer = counter;
while(startTimer + displayTime > counter){
// start backwards so that the digit selection is written to first
for(int i = 7; i >= 0; i--){
if(binArray1[i]== 1){
digitalWrite(pinArray[i], HIGH);
} else {
digitalWrite(pinArray[i], LOW);
}
}
for(int i = 7; i >= 0; i--){
if(binArray2[i]== 1){
digitalWrite(pinArray[i], HIGH);
} else {
digitalWrite(pinArray[i], LOW);
}
}
}
}

void SnakePattern(){
// print snake at segment A of left digit
int snakeArray1[] = {1, 0, 0, 0, 0, 0, 0, 1};
int snakeArray2[] = {0, 0, 0, 0, 0, 0, 0, 0};
DisplayBinnaryArray(snakeArray1, snakeArray1);
delay(1);

// print snake at segment A of right digit
int snakeArray1[] = {0, 0, 0, 0, 0, 0, 0, 1};
int snakeArray2[] = {1, 0, 0, 0, 0, 0, 0, 0};
DisplayBinnaryArray(snakeArray1, snakeArray1);

// print snake at segment B of right digit
int snakeArray1[] = {0, 0, 0, 0, 0, 0, 0, 1};
int snakeArray2[] = {0, 1, 0, 0, 0, 0, 0, 0};
DisplayBinnaryArray(snakeArray1, snakeArray1);

// print snake at segment C of right digit
int snakeArray1[] = {0, 0, 0, 0, 0, 0, 0, 1};
int snakeArray2[] = {0, 0, 1, 0, 0, 0, 0, 0};
DisplayBinnaryArray(snakeArray1, snakeArray1);

// print snake at segment D of right digit
int snakeArray1[] = {0, 0, 0, 0, 0, 0, 0, 1};
int snakeArray2[] = {0, 0, 0, 1, 0, 0, 0, 0};
DisplayBinnaryArray(snakeArray1, snakeArray1);

// continues

This solution trimmed down a lot of lines of code. However, it could be reduced even more. Instead of passing a binary array, I wrote a function that takes a number between 0 and 255, interprets it as a binary array, and displays that pattern on the PmodSSD. This took my previous solution, and pushed it into one simple integer. Now I could easily write whole patterns in just one array of bytes.

void DisplayByte(int byte){
if(byte < 0 || byte > 255){
return;
}
int mask = 1 << (7); for(int x = 7; x >= 0; x--){
if( (byte & mask) == 0 ){
digitalWrite(pinArray[x], LOW);
}else{
digitalWrite(pinArray[x], HIGH);
}
mask >>= 1;
}
delay(1);
}

void DisplayArrayOfBytes(int ByteArray[], long displayTime){
// grab current time from timer to start countdown
long startTimer;
int i = 0;
while(ByteArray[i]!= -1){
startTimer = counter;
while(startTimer + displayTime > counter){
DisplayByte(ByteArray[i]);
// wait a bit

DisplayByte(ByteArray[i+1]);
// wait a bit
}
i += 2;
}
}

// Send DisplayByte an array of bytes containing a snake pattern
void SnakePattern(){
int circleAnimation[15] = {129, 1, 128, 3, 128, 6, 128, 12, 136, 8, 152, 0, 176, 0, -1};
DisplayBinnaryArray(circleAnimation);
}

What originally took 26 lines of code could now fit into just 2 lines of code! My library now seemed to be at its most optimal. Without creating a fun side project with my library, I wouldn’t know how much more improved it could be.

Of course, most anything could always be more optimal. If you have any ideas improving my code, leave a comment below! Keep in mind that this is not the actual code in the library, which you can find here, but a representation of the idea behind its design. Now that my library is published, I went a bit crazy with the patterns…

I hope this provided some insight on the creation of libraries, as well as the importance of doing projects to test out what you come up with!

Author

Be the 1st to vote.

Leave a Reply

Your email address will not be published. Required fields are marked *