Friday, June 19, 2020

HDSP clock with SCD5583 display

Here is another interesting "intelligent" LED matrix display, whose name actually makes some sense (unlike HDSP-2354, among many others): SCD5583A. I reckon it means: "Serial Character Display with 5x5x8 dot matrix". 3 is the code for green (0 for red, 1 for yellow).
This display is now obsolete (replaced by touch screens in avionics, the industry for which it was designed), but it is still available on ebay for a reasonable price (except for incredibly high shipping cost).

Compared to other intelligent displays like the above-mentioned HDSP-2534 employed by the HDSP clock (hence the bland unimaginative name), SCD558X does not have an internally-defined font and requires the user to provide one. This makes it a little more complicated to use, but also allows for more flexibility, making it truly international (non-English character set). Even more, each pixel can be addressed individually, like a graphical 5x40 LED matrix.
The fact that is serial means fewer pins are required for interfacing (3 control pins in this case) and less driving circuitry (no need for the external shift register).

The photo below shows the display connected to an Arduino and running the HDSP sketch adapted for SCD5833.


Practically, the HDSP sketch uses only one function to write to display, aptly called "writeDisplay()", that needs to be re-written. The support for SCD5583 is provided by the class SCD5583, shown below (header + cpp files, compiled with Arduino IDE 1.8.13).

#ifndef _SCD5583_H_
#define _SCD5583_H_

#include  "Arduino.h"

class SCD5583
{
  public:
    SCD5583(byte loadPin, byte dataPin, byte clkPin);
    void clearMatrix();
    void setBrightness(byte b);
    void writeLine(char text[9]);

  private:
    void _sendData(byte data);
    void _getCharDefinition(byte* rows, char c);
    void _selectIndex(byte position);

    byte _loadPin;
    byte _dataPin;
    byte _clkPin;
};

#endif // _SCD5583_H_

-----------------------------------------------
#include "SCD5583.h"
#include "font5x5.h"

#define MAX_CHARS 8   // set to 10 for SCD5510X (10 digits) or to 4 for SCD554X (4 digits);
#define NUM_ROWS  5

SCD5583::SCD5583(byte loadPin, byte dataPin, byte clkPin)
{
  pinMode(loadPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clkPin, OUTPUT);
  _loadPin = loadPin;
  _dataPin = dataPin;
  _clkPin  = clkPin;
  clearMatrix();
//  setBrightness(0);
}

void SCD5583::clearMatrix()
{
  _sendData(B11000000);
}

void SCD5583::setBrightness(byte b)
{
  if (b > 0 && b < 7)
  {
     _sendData(B11110000 + b);
  }
}

void SCD5583::_selectIndex(byte position)
{
   _sendData(B10100000 + position);
}

void SCD5583::_sendData(byte data)
{
  byte mask = 1;
  digitalWrite(_loadPin, LOW);
  digitalWrite(_clkPin,  LOW);
  for (byte i = 0; i < 8; i++)
  {
    digitalWrite(_dataPin, mask & data? HIGH : LOW);
    digitalWrite(_clkPin, HIGH);
//  delay(10);
    digitalWrite(_clkPin, LOW);
    mask = mask*2;
  }
  digitalWrite(_loadPin, HIGH);
}

void SCD5583::_getCharDefinition(byte* rows, char c)
{
  for (byte i = 0; i < NUM_ROWS; i++)
  {
    rows[i] = font5x5[((c- 0x20) * NUM_ROWS) + i];
  }
}

void SCD5583::writeLine(char* text)
{
  byte rows[NUM_ROWS];
  for (int i = 0; i < MAX_CHARS; i++)
  {
    _selectIndex(i);
    _getCharDefinition(rows, text[i]);
    for (int r = 0; r < NUM_ROWS; r++)
    {
      _sendData(rows[r]);
    }
  }
}

As mentioned previously, the font must be provided too (content of file "font5x5.h" shown below):

#ifndef _FONT5X5_H_
#define _FONT5X5_H_

// ascii characters 0x41-0x7a (32-127);
static unsigned char font5x5[] =
{
  0x00, 0x20, 0x40, 0x60, 0x80, // space
  0x04, 0x24, 0x44, 0x60, 0x84, // !
  0x0A, 0x2A, 0x40, 0x60, 0x80, // "
  0x0A, 0x3F, 0x4A, 0x7F, 0x8A, // #
  0x0F, 0x34, 0x4E, 0x65, 0x9E, // $
  0x19, 0x3A, 0x44, 0x6B, 0x93, // %
  0x08, 0x34, 0x4D, 0x72, 0x8D, // &
  0x04, 0x24, 0x40, 0x60, 0x80, // '
  0x02, 0x24, 0x44, 0x64, 0x82, // (
  0x08, 0x24, 0x44, 0x64, 0x88, // )
  0x15, 0x2E, 0x5F, 0x6E, 0x95, // *
  0x04, 0x24, 0x5F, 0x64, 0x84, // +
  0x00, 0x20, 0x40, 0x64, 0x84, // ,
  0x00, 0x20, 0x4E, 0x60, 0x80, // -
  0x00, 0x20, 0x40, 0x60, 0x84, // .
  0x01, 0x22, 0x44, 0x68, 0x90, // /
  0x0E, 0x33, 0x55, 0x79, 0x8E, // 0
  0x04, 0x2C, 0x44, 0x64, 0x8E, // 1
  0x1E, 0x21, 0x46, 0x68, 0x9F, // 2
  0x1E, 0x21, 0x4E, 0x61, 0x9E, // 3
  0x06, 0x2A, 0x5F, 0x62, 0x82, // 4
  0x1F, 0x30, 0x5E, 0x61, 0x9E, // 5
  0x06, 0x28, 0x5E, 0x71, 0x8E, // 6
  0x1F, 0x22, 0x44, 0x68, 0x88, // 7
  0x0E, 0x31, 0x4E, 0x71, 0x8E, // 8
  0x0E, 0x31, 0x4F, 0x62, 0x8C, // 9
  0x00, 0x24, 0x40, 0x64, 0x80, // :
  0x00, 0x24, 0x40, 0x6C, 0x80, // ;
  0x02, 0x24, 0x48, 0x64, 0x82, // <
  0x00, 0x3F, 0x40, 0x7F, 0x80, // =
  0x08, 0x24, 0x42, 0x64, 0x88, // >
  0x0E, 0x31, 0x42, 0x64, 0x84, // ?
  0x0E, 0x35, 0x57, 0x70, 0x8E, // @
  0x04, 0x2A, 0x5F, 0x71, 0x91, // A
  0x1E, 0x29, 0x4E, 0x69, 0x9E, // B
  0x0F, 0x30, 0x50, 0x70, 0x8F, // C
  0x1E, 0x29, 0x49, 0x69, 0x9E, // D
  0x1F, 0x30, 0x5E, 0x70, 0x9F, // E
  0x1F, 0x30, 0x5E, 0x70, 0x90, // F
  0x0F, 0x30, 0x53, 0x71, 0x8F, // G
  0x11, 0x31, 0x5F, 0x71, 0x91, // H
  0x0E, 0x24, 0x44, 0x64, 0x8E, // I
  0x01, 0x21, 0x41, 0x71, 0x8E, // J
  0x13, 0x34, 0x58, 0x74, 0x93, // K
  0x10, 0x30, 0x50, 0x70, 0x9F, // L
  0x11, 0x3B, 0x55, 0x71, 0x91, // M
  0x11, 0x39, 0x55, 0x73, 0x91, // N
  0x0E, 0x31, 0x51, 0x71, 0x8E, // O
  0x1E, 0x31, 0x5E, 0x70, 0x90, // P
  0x0C, 0x32, 0x56, 0x72, 0x8D, // Q
  0x1E, 0x31, 0x5E, 0x74, 0x92, // R
  0x0F, 0x30, 0x4E, 0x61, 0x9E, // S
  0x1F, 0x24, 0x44, 0x64, 0x84, // T
  0x11, 0x31, 0x51, 0x71, 0x8E, // U
  0x11, 0x31, 0x51, 0x6A, 0x84, // V
  0x11, 0x31, 0x55, 0x7B, 0x91, // W
  0x11, 0x2A, 0x44, 0x6A, 0x91, // X
  0x11, 0x2A, 0x44, 0x64, 0x84, // Y
  0x1F, 0x22, 0x44, 0x68, 0x9F, // Z
  0x07, 0x24, 0x44, 0x64, 0x87, // [
  0x10, 0x28, 0x44, 0x62, 0x81, // \
  0x1C, 0x24, 0x44, 0x64, 0x9C, // ]
  0x04, 0x2A, 0x51, 0x60, 0x80, // ^
  0x00, 0x20, 0x40, 0x60, 0x9F, // _
  0x0A, 0x2A, 0x40, 0x60, 0x80, // '
  0x00, 0x2E, 0x52, 0x72, 0x8D, // a
  0x10, 0x30, 0x5E, 0x71, 0x9E, // b
  0x00, 0x2F, 0x50, 0x70, 0x8F, // c
  0x01, 0x21, 0x4F, 0x71, 0x8F, // d
  0x00, 0x2E, 0x5F, 0x70, 0x8E, // e
  0x04, 0x2A, 0x48, 0x7C, 0x88, // f
  0x00, 0x2F, 0x50, 0x73, 0x8F, // g
  0x10, 0x30, 0x56, 0x79, 0x91, // h
  0x04, 0x20, 0x4C, 0x64, 0x8E, // i
  0x00, 0x26, 0x42, 0x72, 0x8C, // j
  0x10, 0x30, 0x56, 0x78, 0x96, // k
  0x0C, 0x24, 0x44, 0x64, 0x8E, // l
  0x00, 0x2A, 0x55, 0x71, 0x91, // m
  0x00, 0x36, 0x59, 0x71, 0x91, // n
  0x00, 0x2E, 0x51, 0x71, 0x8E, // o
  0x00, 0x3E, 0x51, 0x7E, 0x90, // p
  0x00, 0x2F, 0x51, 0x6F, 0x81, // q
  0x00, 0x33, 0x54, 0x78, 0x90, // r
  0x00, 0x23, 0x44, 0x62, 0x8C, // s
  0x08, 0x3C, 0x48, 0x6A, 0x84, // t
  0x00, 0x32, 0x52, 0x72, 0x8D, // u
  0x00, 0x31, 0x51, 0x6A, 0x84, // v
  0x00, 0x31, 0x55, 0x7B, 0x91, // w
  0x00, 0x32, 0x4C, 0x6C, 0x92, // x
  0x00, 0x31, 0x4A, 0x64, 0x98, // y
  0x00, 0x3E, 0x44, 0x68, 0x9E, // z
  0x06, 0x24, 0x48, 0x64, 0x86, // {
  0x04, 0x24, 0x44, 0x64, 0x84, // |
  0x0C, 0x24, 0x42, 0x64, 0x8C, // }
  0x00, 0x27, 0x5C, 0x60, 0x80, // ~
};

#endif  // _FONT5X5_H_

And finally, the changes in HDSP.ino are:

1. add the following line at the top:

#include "SCD5583.h"

// SCD5583 pins: LOAD to D4, DATA to D5, SDCLK to D3;
SCD5583 scd(4,5,3);

2. replace the function writeDisplay() written for HDSP-2534, with the following:

void writeDisplay()
{
  scd.writeLine(displayBuffer);
}

Hardware-wise, some re-wiring is required on the HDSP board, starting with the removal of the 595 shift register. Then, D3, D4 and D5 (ATmega328 pins 5, 6, 11) must be connected respectively to SDCLK, LOAD and DATA pins (1, 2, 27) of the SCD5583 display.

And there you have it, a working HDSP clock with SCD5583 display.

It is worth mentioning that the measured current drawn was between 10mA (lowest brightness) and 20mA (highest), and that it works similarly well when powered by 3V3.


Wednesday, June 3, 2020

Sure 32x16 bicolor display (HT1632) driven by ESP32

I was recently awoken from the Netflix-infused lethargy by an email from LukeW, who needed help with running the Wise Clock 4 on ESP32. What a great idea that is!

I had an epiphany when I realized what a powerful platform ESP32 is: unbelievable price (about $10 on amazon), serious hardware (memory, speed, WiFi, BT, BLE, multiple USARTs etc.), amazing software support (Arduino IDE, libraries, examples etc.).

The latest Arduino IDE I had was version 1.6.7 (2017). Trying to install the support package for ESP32, I got a security error along the lines:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

It works fine when downloading it through the browser (https://dl.espressif.com/dl/esptool-2.6.1-windows.zip), meaning that the server certificate that esspressif is using is not recognized by the JVM run by Arduino (folder "java" in the arduino directory). Identifying and adding the certificate to the JVM's keystore is time consuming, so I decided that it is just easier to upgrade to the latest Arduino IDE (currently 1.8.12), installed this time (a first for me) from Microsoft store. Even though the process is seamless, I have no idea where this software was placed (definitely not where I wanted it). I also learned the new way (where have I been for so long?) to include and manage libraries (through the "Add .ZIP library" menu item).

Using the ESP32 devkit is as easy as the first Arduino (Duemilanove). The only thing one needs is a solderless breadboard, which I was lucky to have one around, since I don't remember ever using one before. An interesting fact is that the ESP32 board, inserted in the breadboard I have, leaves room for connecting wires only on one side.


Next step was to connect the Sure 32x16 displays (two, daisy chained). I used these pins:

// pins used to connect to ESP32;
#define HT1632_DATA      12 // Data pin (pin 7 of display connector)
#define HT1632_CS            14 // Chip Select (pin 1 of display connector)
#define HT1632_WRCLK  13 // Write clock pin (pin 5 of display connector)
#define HT1632_CLK         27 // clock pin (pin 2 of display connector)

With only the pin changes, the HT1632 files used in Wise Clock 4 software work perfectly fine with ESP32. They can be found here, called from a test sketch that uses 2 displays (#define NUM_DISPLAYS 2 in file MyHT1632.h).

SD card should be next, using the ESP32 support libraries.
With ESP32, the sky is the limit: hopefully no more program memory limitations, no need for third party libraries (e.g. Sanguino), better support for sound, easier access to WiFi, support for extra peripherals etc. Wow!

It did not take long to test the SD card, using this wiring:

which looks like this on the breadboard:


Running SD_Test.ino sketch example coming with ESP32 libraries on a Wise Clock 4 SD card, this is what serial monitor shows:


Incredible, with no sweat at all, just out of the box. Wow again!

Another small step: modified the SD_Test.ino to read the content of the file, line by line:

void setup()
{
    Serial.begin(115200);
    if(!SD.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD card attached");
        return;
    }

  openFile(SD, "/quot1.txt");
}

void openFile(fs::FS &fs, const char * path)
{
    Serial.printf("Reading file: %s\n", path);

    file = fs.open(path);
    if(!file){
        Serial.println("Failed to open file for reading");
        return;
    }
}

char lineBuf[500] = {0};

void readLine()
{
  int i = 0;
  lineBuf[0] = 0;

  while (file.available())
  {
    char c = (char) file.read();
    lineBuf[i++] = c;
    if (c == '\n')  break;
  }
  lineBuf[i] = 0;
}

void loop()
{
  readLine();
  Serial.write(lineBuf);
  delay(1000);
}

And the output, in serial monitor:



Saturday, May 9, 2020

wsduino revision 2

Honestly, I think the hacking required to add buttons for hours and minutes to the Rothko clock is messy. But if  you want an easy, quick and intuitive way to set the time, there is no alternative for buttons; remote control (IR, XBee, BT) would require extra devices, GPS or NTP would need settings. Since the Nixie shield board is already overcrowded, the logical place for the buttons would be on wsduino. And this is the main reason I had to redesign it.
I opted for two right-angle tactile switches placed on the right side of the board, above and below the XBee module. These switches, connected to A0 and A1, are intended mostly for clock functionality, optional for other applications. They could also be replaced by wired external (panel-mounted, not on-board) buttons, when an enclosure is used.

This is how the new wsduino board looks.



Other improvements are:
  • moved the 3V3 regulator for better heat dissipation (it was on the opposite side of 7805);
  • moved the electrolytic capacitors around, to allow for easier removal of the processor from the socket;
  • moved the 1Hz output to a pin between the banks of analog and power pins;
  • removed the SDA and SCL from the top bank of digital pins (they were redundant anyway, plus makes more room for the screw and nut);

The switch that fits wsduino is number 24 in the chart below (used by sellers on ebay):

To recap, wsduino is the arduino-compatible board with DS3231 RTC and XBee support. To build a clock, just add a display shield like the 6-character LED display, the bicolor LED matrix shield ("Mondrian clock") or the 6-tube Nixie shield ("Rothko clock").


Tuesday, April 14, 2020

Electronics kits for kids

Continuing on the topic of "Introduction to Practical Electronics" course, today we are going to look at some of the electronics (soldering) kits available and suitable for the purpose.

What makes a good beginner electronics kit?
  • easy through-hole soldering
  • includes a variety of components
  • reasonably priced (this is relative; what may be expensive for me may be cheap for you)
  • standalone and all-inclusive: does not require extra parts/components/modules sourced from third parties and does not require loading software;
  • interesting (as opposed to boring) functionality: flashes LEDs, displays something on a screen, makes some sounds etc.
  • relative simplicity of the circuit, so it can be easy to understand and debug if necessary
  • aesthetics of the board (shape, colour, component placement etc.)
  • preferably open source
  • powered by low voltage (battery, USB, power adapter)
  • digital electronics rather than analog (easier to debug, if necessary)
  • practical utility: use it for a utilitarian purpose rather than forget about it once built
  • expandability: can be either integrated as part of a bigger project, or its capabilities and functionality can be extended by adding modules or parts
  • provides extra learning (besides soldering) by displaying information: wave forms, frequencies, binary/hex number representation, musical notes, proverbs etc.
  • satisfaction guaranteed once assembled and working  :)
Here is a list, in no particular order, of beginner kits I found to match some of the above criteria.

1. Elenco AM Radio kit


2. Chinese Radio kits: A, B



3. 6-digit LED Clock kit


4. 4-digit LED Alarm Clock kit


5. 4-digit LED Talking Clock kit



6. Elenco two-tone European Siren kit


7. Retro Classic Game (Tetris, Snake etc.) kit


8. 3D Christmas Tree Flashing LEDs kit


9. Electronic Piano kit


10. Electronic 16 Sound Music Box kit


11. Astable Multi-vibrator Circuit Learn kit


12. Mini Speaker Box Amplifier kit


13. Aviation Band Radio Receiver kit


14. Calculator and Counter with LCD and Keyboard kit


15. "Three Fives" Discreet 555 Timer kit


16. TV-B-Gone kit


17. MintyBoost kit


18. MintySynth kit (now discontinued)


19. Drawdio kit


20. Electronic Hourglass LED kit


21. Round LED Clock kit


22. Signal Generator with XR2206 Adjustable Frequency kit


23. Solder:Time Desk Clock kit


24. Geiger Counter kit(s)


25. Wristwatch LED kit


26. Burglar Electronic Alarm kit


27. Conway's Game of Life kit


28. Music Synthesizer kit


29. Line Following Robot kit


30. Jameco Atari Punk Console kit


31. 555 Forrest Mims Project kit(s)



32. Tesla Coil kit


33. Velleman voice changer kit



34. Various badges (Maker, Day of Geek, Unicorn, and many many others)


Sunday, April 5, 2020

HDSP clock revision 2

The latest revision of the HDSP clock uses the same schematic, but offers an improved PCB layout, with:
  • 4 holes in the corners, for encasing;
  • addition of I2C signals to the FTDI connector, for expansion;
  • the regular push buttons can be replaced with 2-pin right angle buttons;

This revision was successfully used as the assembly kit in the "Introduction to Practical Electronics" course for Grade 6 students.

This would also be a good place for step-by-step assembly instructions, for those who require directions.


melt a bit of solder on the battery pad, to raise it (not pictured)


slide in the CR1220 battery, flat side (+ pole) up (not pictured)


Use a mini B USB cable to power the clock. It should work right away, since the processor is already programmed with the clock software. Use the "Hours" (left) and "Minutes" (right) buttons to set up the time.
Also, insert the CR1220 battery into the holder. It powers the DS1307 RTC (real time clock) when the clock board is disconnected from USB. Note that the small coin battery ONLY powers the RTC integrated circuit, and not the whole clock. The display is lit only when connected to the USB power.

Troubleshooting
  • check for missing soldering joints; you may have forgotten to solder some terminals;
  • check for solder bridges; solder blobs may accidentally connect adjacent holes/terminals that should not be connected;
  • make sure the orientation of the integrated circuits and the display matches the silkscreen, by checking the notches/indentations;
  • ensure that the ICs are fully and completely pushed in the socket, until their bottoms touch the socket's plastic;

What's next

1. Catch up on the theory:
  • recognize components symbols in schematics;
  • recap units of measure for some of the components (ohms for resistors, farads for capacitors); read their intended values (3 digits, color code), measure their real values using a multimeter;
  • understand electrical concepts: voltage, current, resistance (and their dependency), frequency; recap their units of measure;
2. Design and make an enclosure (hint: the easiest is to sandwich the board between plates of transparent acrylic, with standoffs in the 4 corners).

3. Look for a new kit to assemble.