Tuesday, May 2, 2017

Programming the MeinEnigma - Decimal Points


In the next programming example we'll look at another relatively simple piece of hardware - the decimal point indicators on the displays.

The MeinEnigma display uses four 16-segment alphanumeric LEDs which can display letters and numbers as well as a decimal point. The 16 alphanumeric segments of the displays are driven by an HT16K33 LED Controller Driver chip. We'll look at this in some future example programs. The chip doesn't directly support driving the decimal points however, so some additional circuitry on the board (7402 and 4002 logic gates) are used to handle controlling the decimal points.

The HT16K33 chip is still used to control the timing of this circuitry, so it needs to be properly initialized. We'll do that using an external library that has been written for the HT16K33. We'll cover this library in more detail in future blog posts.

Once the HT16K33 chip is set up, the four decimal point indicators can be controlled by the Arduino's A0 through A3 outputs. While these happen to be analog outputs, they are only used here as digital outputs. You might think that we could control the brightness of the decimal points using the analog outputs, but they are not driven directly by the Arduino, they go through the previously mentioned digital gates, so they can only be driven high or low.

The example program is shown below (you can access the latest version from the git repository here).

In the setup() function we create an instance of ana HT16K33 object from the external library for the chip. We set the four i/o pins to be outputs. Then we call the HT16K33 library's begin() method to initialize the chip. We don't need to do anything else with the chip in this program.

In the main program we can control the decimal point segments. A0 controls the leftmost digit decimal point. A3 controls the rightmost. Setting an output to 1 (high) turns the associated decimal point off. Setting an output to 0 (low) turns the decimal point on. In a larger program (as we'll see later) we would probably want to hide the details of controlling the decimal points in a convenient function that we could call.

In this example I provided two demonstrations. The first makes the decimal points count from 0 to 15 in binary. The other "walks" the decimal points from left to right.


You can enable either or both of the sections of code by adjusting the "#if 1" and "#if 0" directives.

/*
  MeinEnigma Example

  Demonstrates controlling the decimal points on the 4-digit
  alphanumeric LED display. These are controlled differently from the
  other display segments.

  Jeff Tranter

*/

// External library for HT16K33 chip.
#include "ht16k33.h"

void setup() {
  HT16K33 HT;

  // Set the pins used for output. These happen to be analog outputs
  // but are only used at digital levels.
  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);

  // Need to initialize the chip in order for the decimal points to
  // work. This also clears all display segments.
  HT.begin(0x00);
}

// A0 controls the leftmost digit decimal point. A3 controls the
// rightmost. Setting an output to 1 (high) turns the associated
// decimal point off. Setting an output to 0 (low) turns the decimal
// point on.
void loop() {

#if 1
  // Make the decimal points count from 0 to 15 in binary.
  for (int i = 0; i < 16; i++) {
    digitalWrite(A0, !(i & 8));
    digitalWrite(A1, !(i & 4));
    digitalWrite(A2, !(i & 2));
    digitalWrite(A3, !(i & 1));
    delay(200);
  }
#endif

#if 0
  // Alternative pattern. Walk decimal points from left to right.
  for (int i = 0; i <= 4; i++) {
    digitalWrite(A0, !(i == 1));
    digitalWrite(A1, !(i == 2));
    digitalWrite(A2, !(i == 3));
    digitalWrite(A3, !(i == 4));
    delay(200);
  }
#endif
}

No comments: