About Me

My photo
They never fall who never climb.

019 KEYBOARD MATRIX CONTROL - BASIC


019 KEYBOARD MATRIX CONTROL - BASIC

April 1, 2011    (See also Companion Blog )
[Go BACK to Table of Contents] [ Next Experiment ] [ Last Experiment ]

           To examine a method or methods of controlling a circuit by keyboard input. In previous experiments, the keyboard was limited to input-output of character values. After completing the matrix to flash a fixed pattern, the next logical step is to enter a value based on the keyboard and have that value display “a predictable pattern” on some LEDs.

           The previous LED matrix experiment was significantly different in that the patterns displayed were hard-coded. In this experiment, the pattern will depend on which key is pressed. Since I am using only 5 LEDs, the characters cannot be displayed, but the element of logic is present – a different key produces a different and expected response. The key word is “predictable”, since this time the Arduino does not know what I’m going to type.

           I will continue to use the Arduino as my power source for the LEDs, although I know this has limitations. However, I am leery of connecting larger voltages to the Arduino because I can only afford one right how.

           The interaction with the Arduino is via the built in serial monitor of the Arduino programming helper, often confusing called the IDE. This is a primitive device, as the Arduino cannot read the keyboard directly. The characters have to be typed into the text box and then sent to the microcontroller.

Theory:
           I connect five LEDs to five Arduino controller pins, that is simple. The idea is that when I press a number between one and five on the keyboard, that number of LEDs flash that number of times. This is done by counters which control the looping in the code. I have been unable to find the command that pauses the loop or if such a command exists.

           [The picture shown here was drawn using Fritzing, a free downloadable application for creating breadboard diagrams. It is only casually mentioned in the Arduino documentation, and like the name Fritzing tells you anything. It produces diagrams with a “fz” suffix that you have to export as a jpeg or pdf. A photo of the actual components is shown for comparison.]

           I realize again my coding is getting ahead of by building skills. At the same time, I have been both impressed and dismayed by the simplicity of robot parts, enough to realize the real diversity is in the programming code. One immediate problem is that the keyboard will output the characters 1 through 5 rather than the numbers 1 through 5.

Practice:
           The code is the complication in this instance. I thought of using the “case” statement but despite its claim to be elegant, it uses the good old BASIC case statment. Then I thought of calling subroutines, but that would introduce some fancy code. In the end, I decided on consecutive “if” statements. (I avoid nested “if” statements to also avoid the needless complication of counting punctuation marks, a perpetual headache with C.)

           I had to solve the conversion of characters to numbers by a very risky method. In C arithmetic, when an arithmetic operator acts, the result is converted the arithmetically least precise result. (This has always been a really stupid C thing because all conversions should be literally spelled out in the code.) Since I could not find any conversion commands, I subtracted the character “0” from the keyboard input, thus turning the character 1 into the number 1 and so forth. Please read the code!

           Thus, the code shows 5 different but sequential if statements to match the logic flow. I also felt this would be easier code to follow and you know my opinion of people who produce hard-to-follow code. For reasons unknown, digital pin 01 could not be made to behave, so I reassigned the output to pins 02 through 06 rather than chase down that path.

           This experiment was an eye-opener concerning the difficulties of communicating with the Arduino. It succeeded first time, but almost too well, for initial success is misleading. I got the correct number of lights to flash the correct number of times. But the looping continues, making it difficult to issue single instructions to the user. Worst, when programmed to C specs, when you push a number, it does not flush itself after the keypress, that is, it keeps on behaving as if you held the key down. The code does not reset itself and wait for another keypress.

           Shown below are two results. On the left, the 3 was only entered once. Note how the code keeps running by itself, over and over. On the right is my solution, although you can’t see the effect, after each number, the program stops and waits for the next entry. Not shown is an error statement ensuring only the correct range of numbers can be input.

[Photo missing] [Photo missing]

           I solved looping problem by a change to a C command. (Kudos to anyone who can figure out how I did this. You can get the answer by e-mailing me.) Still, one should not have to resort to such tactics. Now, the program waits for another keypress. This gives me another opportunity to dig at the C language. It has no software reset command, or if it does, it is a secret. If the command exists, it should be in the beginner’s manual.

           As it is, every C language manual I have ever read leaves out something important, telling the so-called C experts are, by my standards, obnoxious amateurs. If they knew how to write and teach, they would merely be obnoxious. Real experts would understand that the void loop command is infinite loop, something real programmers don’t do.


Conclusion:
           The experiment was successful, although the challenge was the code. I had to do several hours of reading on various aspects of the Arduino commands and hardware behavior. I never did find out why pin 1, when used, would not respond properly, but I notice it does have a TX tag so switched to another pin. (Pin 1 would flash the LED whenever it wanted to.)

           During the process, I discovered many new aspects of the coding. Alas, I seek more experience with the wiring, not more code. This experiment is a major milestone for me in that I am one small step closer to getting an LED dot matrix to display a matching character while totally understanding the process. It is also my first completely original design. This is important as I move toward a more intermediate stage my studies, a place where there is a woeful lack of examples. As I like to say about on-line tutorials, the easy ones are too easy and the hard ones are too hard.

           The ones that are too hard are usually for lack of practical documentation which I always try to provide. Others don’t cover anything at all about what can go wrong, which is the normal state of affairs. Trust me, I know it is difficult to accompany videos with diagrams and code, but if people are not willing to expend the effort, maybe they should not be posting what amounts to only their glowing successes.

Here is the code (using the Arduino IDE command “Copy as HTML”)

/*****************************************************************/
// Experiment 019 - Keyboard Circuit Control
// Today is March 31, 2011
// This sketch corresponds to Minutes 019 blog

/* This experiment is designed to allow the user to 
 * to enter any number between 1 and 5, then have
 * the Arduino interpret that keypress to flash a
 * number of LEDs the same number of times.  If the
 * user presses 3, then 3 LEDs should flash 3 times.
 */
 
////////////////////////////////////////////////
//Begin Initialization & Variables

int LEDpin02 = 2; //Set the pins
int LEDpin03 = 3;
int LEDpin04 = 4;
int LEDpin05 = 5;
int LEDpin06 = 6;

int vKeyboardInput; //Store the character value
int vLEDControl; //Store the number LEDs
int vInterval = 500; //Set the delay

//End Initialization & Variables
/////////////////////////////////////////////////

/////////////////////////////////////////////////
// Begin Main Program
/////////////////////////////////////////////////

void setup()
{
  pinMode(LEDpin02,OUTPUT);
  pinMode(LEDpin03,OUTPUT);
  pinMode(LEDpin04,OUTPUT);
  pinMode(LEDpin05,OUTPUT);
  pinMode(LEDpin06,OUTPUT);
  
  Serial.begin(9600);
  //Serial.println("Enter a number between 1 and 5.");
  Serial.println();

// End setup

//-----------------------------------------------------------------------

void loop()
{
  Serial.println("Enter a number between 1 and 5:");
  Serial.println();
  delay(vInterval*8);
  
  digitalWrite(LEDpin02,LOW); //clear the pins, this step is not
  digitalWrite(LEDpin03,LOW); //entirely necessary, but ensures
  digitalWrite(LEDpin04,LOW); //the LEDs are set to off after
  digitalWrite(LEDpin05,LOW); //each pass through the code.
  digitalWrite(LEDpin06,LOW);

//-----------------------------------------------------------------------
   if (Serial.available() > 0);
   {
     vKeyboardInput = Serial.read(); //Read the keyboard
     vLEDControl = (vKeyboardInput - '0'); //convert char to num
   }
//-----------------------------------------------------------------------
   if (vLEDControl > 5 && vLEDControl < 1)
   {
     Serial.println("That was an invalid response. Try again");
     Serial.println();
     delay(vInterval);
   }
//-----------------------------------------------------------------------
   if (vLEDControl == 1)
   {
     Serial.println("You have entered a 1 ");
     Serial.println();
     for (int i = 0; i <= (vLEDControl - 1); i = i + 1)
     {
       digitalWrite(LEDpin02,HIGH);
       delay(vInterval);
       digitalWrite(LEDpin02,LOW);
       delay(vInterval);
     }  
   }
 //-----------------------------------------------------------------------
   if (vLEDControl == 2)
   {
     Serial.println("You have entered a 2 ");
     Serial.println();
     for (int i = 0; i <= (vLEDControl - 1); i = i + 1)
     {
       digitalWrite(LEDpin02,HIGH);
       digitalWrite(LEDpin03,HIGH);
       delay(vInterval);
       digitalWrite(LEDpin02,LOW);
       digitalWrite(LEDpin03,LOW);
       delay(vInterval);
     }
   }
 //-----------------------------------------------------------------------
     if (vLEDControl == 3)
   {
     Serial.println("You have entered a 3 ");
     Serial.println();
     for (int i = 0; i <= (vLEDControl - 1); i = i + 1)
     {
       digitalWrite(LEDpin02,HIGH);
       digitalWrite(LEDpin03,HIGH);
       digitalWrite(LEDpin04,HIGH);
       delay(vInterval);
       digitalWrite(LEDpin02,LOW);
       digitalWrite(LEDpin03,LOW);
       digitalWrite(LEDpin04,LOW);
       delay(vInterval);
     }
   }
 //-----------------------------------------------------------------------
    if (vLEDControl == 4)
   {
     Serial.println("You have entered a 4 ");
     Serial.println();
     for (int i = 0; i <= (vLEDControl - 1); i = i + 1)
     {
       digitalWrite(LEDpin02,HIGH);
       digitalWrite(LEDpin03,HIGH);
       digitalWrite(LEDpin04,HIGH);
       digitalWrite(LEDpin05,HIGH);
       delay(vInterval);
       digitalWrite(LEDpin02,LOW);
       digitalWrite(LEDpin03,LOW);
       digitalWrite(LEDpin04,LOW);
       digitalWrite(LEDpin05,LOW);
       delay(vInterval);
     }
   }
 //-----------------------------------------------------------------------
     if (vLEDControl == 5)
   {
     Serial.println("You have entered a 5 ");
     Serial.println();
     for (int i = 0; i <= (vLEDControl - 1); i = i + 1)
     {
       digitalWrite(LEDpin02,HIGH);
       digitalWrite(LEDpin03,HIGH);
       digitalWrite(LEDpin04,HIGH);
       digitalWrite(LEDpin05,HIGH);
       digitalWrite(LEDpin06,HIGH);
       delay(vInterval);
       digitalWrite(LEDpin02,LOW);
       digitalWrite(LEDpin03,LOW);
       digitalWrite(LEDpin04,LOW);
       digitalWrite(LEDpin05,LOW);
       digitalWrite(LEDpin06,LOW);
       delay(vInterval);
     }
   }
// End void loop
//-----------------------------------------------------------------------

////////////////////////////////////////////////////
// END MAIN PROGRAM
////////////////////////////////////////////////////

// Key entered by Anton da Bassguy 2011
// Verified March 31, 2011.
// Corresponds to meeting minutes project 019
// Schematic 019 - Keyboard Circuit Control
////////////////////////////////////////////////////

/*****************************************************************/





Now, is that slick or what!
Yes, you can copy and paste this code.
Can you find the command I modified to cause the looping to stop and wait for the next character to be entered? And do you know why this command works when it should not?