My Pi Description

My Experiences With the Raspberry Pi -- Tracking My Learning -- My Pi Projects

Wednesday, April 17, 2013

Dirty Little Secret About Wireless Keyboards

A Little Diversion From the Raspberry Pi.
Was I the only one who did not know that wireless Keyboards did not have Caps Lock, Num Lock, and Scroll Lock indicators?
My $7 USB keyboard decided it had enough and stopped accepting my keystrokes. When I went to purchase another, I went with a very nice Microsoft, wireless, keyboard and mouse combination. I didn't have a solid reason to go wireless, I guess I just wanted to be more modern.
When it was time to press the Caps Lock Key, for the first time, I went looking for the LED to tell me it was on. I was flabbergasted - it did not exist. Were they suggesting that the "Lock" indicators are not needed? Rubbish! Of course they're needed. I found myself back in the store a couple of days later and went over to the keyboard display. They had about five or six wireless models and none had any kind of indication for the "Lock" keys. An internet search of computer and electronics stores convinced that this is the norm. I guess it is a matter of battery life. But, why are there are no small LCD displays to convey to the typist that they pressed one of those keys. LCD displays consume very, very little power.
But wait a minute, here, there's more to the story. Let's go back to the time when I pressed the Caps Lock key for the first time. While no LED lit on my keyboard, there was an LED that did light. The Caps Lock key on the wired keyboard lit. I realized I never disconnected the wired keyboard, but had shoved it back under the monitor.
That gave me an idea. I took that $7 wired keyboard apart and extracted the small circuit board with the three LEDs. This small board also has the chip that interfaces the computer to the keyboard, and has the USB cable - which is now plugged back into the computer. Now I have my nice Microsoft keyboard, which I like, and my "Locked" indicators.
Printed Circuit Board With Caps and Num Lock LEDs Lit.

Sunday, April 14, 2013

Hexadecimal Numbers and Bit Minipulation

The code in the last few posts have numbers such as 0x28 and characters such as "&" and "^". Those numbers are written in hexadecimal notation, or in hex, and the "&" and "^" are characters used to minipulate binary bits. In this post, I will indicate a hexadecimal, or hex, number like this: XXh.
Hexadecimal numbers are numbers to the base 16 rather than 10. Consequently, they require 16 different digits. The first 10 are 0 through 9, the remaining 6 consist of "A" through "F", inclusive. What is so special about hexacecimal numbers and why do we need them ,if indeed we do need them? There is nothing special or magical about hexadecimal numbers, and we really could do without them. Any hexadecimal number can be expressed in another way. For example, 20h can be expressed as decimal 32 or binary 100000. So why bother? The answer is convenience.
How long could you remember a binary number such as 01101011? For me, about one second. Perhaps it would be easier to remember the decimal equivalent. So let's convert 01101011 to decimal. Well, let's see, I know I have to add up all the power of 2's that are represented by a 1. So, I add 1, and 2, not 4, but 8, not 16, but 32, and 64. Gee, anybody have a calculator?
How long would it take to convert 01101011 to hexadecimal? In about 2 seconds I can tell you that 01101011 is 6Bh. Sure I have done it a couple of thousand times, but it's easy. First, I mentally split the binary number into groups of four digits: 0110 and 1011. Now, I do the power of 2 thing for each four bit piece (called a nibble). So, 0110 is 4 + 2 or 6, and the 1011 is 8 + 2 + 1 or 11. I know that ten is A, so eleven must be B. After a while you can do it in your head. The biggest power of 2 I have to add is 8. I don't have to add in my head those larger power of 2's like 16, 32, 1004, 32768, etc.
Converting a large binary number to decimal = time consuming.
Converting a large binary number to hexadecimal = quick.
That is why the code in my posts do not show long binary numbers. It's just easy to convert back and forth from binary and hex numbers in your head. There is another reason why we use hexadecimal notation in the code, rather than decimal, and that is we plan to do some bit minipulation. And, why do we do bit mimipulation? To make the code efficient. We are able to save quite a few lines of code.
In my display code, every time I write a character to one line, I have to erase the character in the same position on the other line. I have a variable address_counter that corresponds to the position of the next character to be displayed. The variable address_counter goes from 0x00 to 0x27 for the first line and 0x40 to 0x67 for the second line. I have to constantly shift from one line to the other. I could do this with the following code:
if address_counter < 0x28
    address_counter += 0x40
else
    address_counter -= 0x40
Adding 0x40 puts address_counter in the line below at the same horizontal position .Subtracting 0x40 puts address_counter in the line above at the same horizontal position.
OR I could replace all of those lines with the following line:
address_counter = address_counter ^ 0x40
The single line of code with the "^" doesn't care if you are on the top or bottom line, it just switches from one to the other.
It's that character "^" that makes it work. It is one of the bitwise operators. It's called an exclusive OR and is joined by the AND, OR, NOT, and shift right and shift left operators. Here is how those operators work:
The NOT (or complement) Bitwise Operator:
    Symbol: ~
    Every 1 becomes a 0 and every 0 a 1
    ~10010110 becomes 01101001
The AND Bitwise Operator
    Symbol: &
    Applied to two binary numbers. Only if both digits are a 1 will there be a 1 in the resulting number.
    1001 0110    96h
    1100 1100    CCh
    1000 0100    84h
The OR Bitwise Operator
    Symbol: |
    Applied to two binary numbers. If either digit is a 1 there will be a 1 in the resulting number. Only if both are a 0 will there be a 0 in the resulting number.
    1001 0110    96h
    1100 1100    CCh
    1101 1110    DEh
The Exclusive OR Bitwise Operator
    Symbol: ^
    Applied to two binary numbers. If the two digits are the same (0,0 or 1,1) the resulting digit will be a 0. If the two digits are different (0,1 or 1,0) the resulting digit will be a 1.
    It is a very convenient way to flip a bit. If the original bit is a 0, exclusive ORing it with a 1 will make it a 1, if it was already a 1, exclusive ORing it with a 1 will make it a 0. Exclusive ORing a bit with a 0, leaves it alone.
    Since 40h is equivalent to 0100 000, all address_counter ^ 0x40 does is flip one bit:
    0010 1000    28h    0110 1000    68h
    0100 0000    40h    0100 0000    40h
    0110 1000    68h    0010 1000    28h
The Shift Left and Shift Right Bitwise Operators
    Symbol: << and >>
   Shifts the bits to the right or left the number of positions in the second argument. The new bits added to the right or left are 0's.
    0xAA << 2 becomes 0xA8    1010 1010 -> 0101 0100 -> 1010 1000
    0xAA >> 2 becomes 0x2A    1010 1010 -> 0101 0101 -> 0010 1010
To reiterate the value of hexadecimal numbers, try doing the same operations with the decimal equivalent of the hex numbers.
Have fun using hex numbers and bitwise operators in your python code.

Monday, April 8, 2013

16 X 2 LCD Display Times Square Scroll, Continued

This is a continuation of the prior post about the Times Square Scroll display on a 16 character by 2 line LCD Display.  The entire Python code for that program is at the top of that blog post.  I discussed a code fragment for a simplier version that only displays on the top line of the display.  That fragment replaced lines 49 through 75.  It's now time to discuss the two line version.  So that the reader will not have to go back and forth between this post and the last post, I have repeated the code fragment for the top line only display and made a code fragment that corresponds to lines 49 through 75 of the complete program.
Code Fragment for Top Line Only Display
Code Fragment for Two Line Display
Recall in the prior post I showed that it is possible to have a garbled display of the text where previously entered characters on the other display line, and newly entered characters both get displayed.  Recall Fig. 5 from the last post.
There are two opportunities for this to occur with the two line display.  We have the end of the address space situation discussed in the last post.  Recall, if we don't take corrective action, the next character will be displayed on the wrong display line.  That situation will be solved in nearly the same manner as we solved it before.
The end of the address space situation is solved in the four lines, 12 to 15, in the top line only display.  The four lines, 17 to 20, handle this in the two line display.  The code is very similar but the two line display must deal with characters on both lines.  The two line version simply subtracts 28h from the address counter if the address counter reaches 28h or 68h.  I'm going to explain line 18 further in my next post which talks about hexadecimal numbers.
Now let's discuss the second cause of a garbled display.  When we have completed the first pass through the text on the top line, we move down to the bottom line.  However, the characters that we put into the top line memory are still in that memory.  Eventually, as we add more characters to the bottom line, and the Visible Memory window continues to move, the characters that are in the top line memory start to become visible.  When we finish the bottom line, we move to the top line and the old bottom line characters evenually start to show up.  This goes on and on until we push the switch to stop the program from running.
I solve that problem by overwriting the old characters with spaces.  Evety time I finish writing a character to the display, I erase a character before I write the next character.  I could not allow the display to shift automatically after I write a character.  Code line 1 of the top line only version does not appear in the two line version.  After I write a character (code line 11), I write a space to the same address position on the other display line (code lines 12 and 13).  I then restore the address counter back to the line I was writing characters to, and increment the address counter (code line 14, and increment by adding 81h rather than 80h to the address counter).  Finally, I manually shift the display to the left, which moves the Visible Memory window to the right (code line 15).
For example, if I write a character to memory position 10h on the top line, I write a space to memory position 50h, overwriting any character that was there.  Look at Figures 2,3, or 4 in the last post for reference.
Code line 12 of the two line version will be discussed further in the next post.

Wednesday, April 3, 2013

16 X 2 LCD Display Times Square Scroll

Here is a more complex program using the LCD display.  Just watch the video to see what the program does:
Here is the python code:
As you can see, the Times Square Scroll program asks the user to input text.  That text enters at the right end of the LCD display, on the top line, and scrolls to the left.  Once the entire text has gone to the display, it starts over on the bottom line.  Once all of the text has appeared on the bottom line it repeats to the top line.  This continues until the user pushes the switch and stops the process.
There is not a great deal of additional code to make the Times Square Scroll program work.  The shortness of the code, however, belies the fact that it is somewhat complex and requires a pretty good understanding of the 44780 display controller.  Remember that all of the code from the file LCD_2X16.py is imported into this program.
The display controller has two internal memories.  One is the character memory that converts an ASCII character to a pattern of dots that correspond to the letter, number, or symbol you see on the display.  It is the other memory, however, that concerns us.  This memory, called the Display Data RAM, contains 80 memory locations (80 eight bit bytes).  When you send a character to the display controller, it goes into this RAM.
The first 40 memory locations are devoted to the top line of the display, and they correspond to memory addresses 00h to 2Fh.  The bottom line's 40 memory locations are found at addresses 40h to 67h.  The data sheet for the display controller uses Hexadecimal notation for memory addresses, so, I will be using Hexadecomal notation too.  While there are 80 memory locations, only a maximum of 32 characters appear on the display.  Obviously, characters in some some of the memory are visible, and some are not.  To make it easier to determine what is visible, we can define a window corresponding to the visible portion of the memory.  Let's call that the Visible Memory window.  Take a look at Fig. 1, below.  It is a graphical representation of Display Data RAM.  I have indicated the Visible Memory window with a red rectangle.  It is important to know that this window can be moved to display characters in different memory locations, but it will always be the same size.
I am going to talk about sending characters to the memory.  Actually, we will be writing the ASCII equivalent of the characters to the memory.  For example, if we want a space, 20h, or 32 decimal will be written.  We'll keep it simple and say we are sending a space to the memory.
If you want a simple display project, like in my previous blog, you would not need to concern yourself with the Display Data RAM and my Visible Memory window.  Figure 1, shows how the memory was utilized in the previous blog.  The Visible Memory window stayed put and there were never any characters placed in the memory locations that were not visible.  The Times Square Scroll, however, makes plenty use of the Visible Memory window.
Figure 1.
There are two other important memory elements within the 44780 controller chip.  The first is the instruction register.  The commands (as opposed to characters) you write to the controller go there.  Pages 23 through 29 of the controller's data sheet explain the commands quite well.  That other important element is the address counter.  The address counter contains the memory location that will receive the next character.  You can write to the address counter if you wish to change where the next character will go - the code does this frequently.  It is important to know that once you write a character into a memory location, the controller will increment (or decremen) the contents of the address counter.  In this way you don't have to keep changing the address counter yourself.  As a matter of fact, you can't stop the address counter from incrementing or decrementing.
Before we look at the code for this two line version of the Times Square Scroll, I have a simpler version that uses the top line only.  The code fragment, below, replaces lines 49 through 75 above.  It's a little easier to understand.
Let's assume the user has asked to send "Now is the time for all good men to come to the aid of their party" to the display.  Recall that I said you can change the contents of address counter, and that is what I do in line 3 and 6.   I set it to the position just to the right of the Visible Memory window and upload it to the display controller.  In line 1, I commanded the controller to make a left shift after I upload each character.  Line 1 also says to increment the address counter after uploading each character.  If I had been writing in a language that reads from right to left, Hebrew, for example, I would have told it to decrement the address counter.  When I start to upload characters, the first character "N" goes to position 10h.  See Figure 2.
Figure 2.
After uploading the "N", the display does a left shift.  Hitachi considers the shift direction from the point of view of the character.  From my point of view, the Visible Window moves one position to the right.  In effect, it moves the "N" one position to the left.  The "N" is now within the Visible Window, so it appears on the display.  See Figure 3.
Figure 3.
When the "o" is uploaded, the address counter has been incremented to 11h (by the controller), which again, is one position to the right of the Visible Window.  Once uploaded, the "o" becomes visible because the controller shifts the Visible Window. See Figure 4.  This process continues as each character is added to the display.
Figure 4.
What happens once the address counter has gotten to the end of the memory space of the top line (address 27h)?  Lines 12 to 15 of the code handle that situation.  If those lines of code were not there, the address counter would move to the beginning of the bottom line.  As more characters are added, characters that were previously uploaded to the top line, and still in memory, would also start to be visible.  Old characters would be seen on the top line while new characters are seen on the bottom line.  Eventually, old and new characters would be seen on both lines and you get a mess like in figure 5.
Figure 5.
Code lines 12 to 15 along with line 3 address that problem.  We keep track of the address counter, and when it reaches the memory address beyond the end of the top tine (28h), we simply set it to the beginning address of the top line, 00h.  Note that the Visible Window will now split in two parts.  See Figures 6 and 7.
I could have avoided the problem in another way.  I could have told the display controller that I had a one line display. I could have written:
lcd_byte(0x20, LCD_CMD)
By saying I had a one line display, I could have dispensed with code lines 12 to 15.  However, I knew the one line display was going to be a precursor to my ultimate two line Times Square Scroll.  The two line version, also has code similar to lines 12 to 15.
Figure 6.
Figure 7.
That's enough to absorb for now. I'm going to save the rest of the discussion of the Times Square Scroll for the next blog entry.