Playing Tetris on an electromechanical screen

Playing Tetris on an electromechanical screen

One day, while viewing ads on Avito, I came across a very curious thing - a blinker board or a flip-dot display in English. These boards are used to display information at airports, train stations, stadiums or route signs on public transport.

I thought that with this type of display you can do a lot of interesting things.

Where my screen was installed, one can only guess from the remainder of the inscription (“AGAZIN”). Perhaps it was an information stand at the station or stop OT - write your ideas in the comments.

The screen was a matrix of cells with a size of 7 rows per 30 columns. Each cell contained a round, rotating two-color plate and a green LED. The board had a number of logic elements of the 74HCxxx series and other microcircuits, which, as it turned out later, were almost enough to control the screen through a simple serial interface.
After the purchase, I spent some time searching for information on how to work with such screens, given that I had only the part directly outputting the image, and usually there is also a controller that can be controlled by the keyboard or through the UART port software from the PC .

It was not possible to identify the manufacturer with the label on the board, but perhaps I didn’t try hard, because it was more interesting to figure out how it works, draw a device diagram and develop a interface module with a typical microcontroller.

But first you had to set yourself a specific goal, for which you can apply this screen in everyday life. The first idea was a clock displaying extended weather information on the street and at home, time, date, short motivating messages;), etc. Then I thought that if you turn the screen 90 o , it It looks great like a glass for Tetris, so it was decided to make Tetris, and then we will see.

How electromechanical screens work

Very simple: each cell of the screen (checkbox) consists of a disk - a flat permanent magnet painted on one side in yellow, and on the other in black, and an electromagnet located under the disc. When an electric pulse is applied to the coil of an electromagnet, the flag turns over and, importantly, is fixed in one position. When changing the direction of the current and supplying a repeated impulse, the flag is turned and fixed by the other side. For switching, a pulse of 1 millisecond duration of 12 volts is sufficient.
Electromagnet coil resistance is approximately 18 ohms.

Cell device, source: Eldi datasheet

How the disk rotates, source: Flip-Disc Display

For convenience of control, the coils through two diodes are combined into a matrix of rows and columns. To switch any point on the screen, you need to activate the current source (current source) on the line and the current sink on the row, at the intersection of which there is an electromagnet coil or, on the contrary, to switch to the other side. In essence, this is analogous to controlling DC motors through an H-bridge, only in a pulsed mode.

With how to manage the flags in the theory, we figured out. It's time to move on to practical implementation.

Screen Reverse Engineering

Armed with a multimeter and Kicad, I began to redraw the screen layout, starting with LED control. It turned out that this part is self-sufficient, and when powering up and control signals it is possible to light any LED in any row of the screen through a rather simple interface. Only one line can be active at a time, so the output should be dynamic.

The module circuit consists of a matrix of LEDs whose cathodes are connected to Toshiba TB62705 LED drivers. From the point of view of control logic, these are ordinary 8-bit shift registers connected in a chain. The anodes of the LEDs in each row are connected and connected to the drain of the MOSFET transistors. The sources are connected to the output of the DC-DC converter, and the gates of all 7 transistors are connected to the outputs of the decoder 3: 8 74HC238.

Thus, to control the LEDs, you need to select the line of the screen, submitting its number to the input of the decoder, then load 32 bits of data through the SERIAL and CLOCK inputs of the first LED driver. Then file a log. “1” at the LATCH input, and the corresponding LEDs will light up while the LATCH is held at “1”.

To blink LEDs, I used the arduino-compatible card at hand Teensy 3.5 . An example of the LED control code can be found at GitHub

The second part of the scheme, responsible for managing blinkers, is a bit more complicated.

The power part of the control column consists of a pair of current source/drain chips (current source/sink), the outputs of which are connected via protective diodes to the first output of each coil in the column. The Toshiba TBD62783 chip is used as a current source, and the ULN2803 from TI, beloved by many, is used as a drain source. The second terminals of the coils are combined into lines and connected to the connector on the screen board. Apparently, this was done in order to take control of the lines into a separate module, since several screens can be combined into one long screen. However, it is a little confusing why the developers placed all the necessary components on each screen board for controlling the LEDs.

The logic consists of eight 3: 8 74HC238 decoders, the control inputs of which are connected in parallel. The outputs of the even decoders are connected to the control inputs of the current sources, and the odd ones to the inputs of the sinks. The enable inputs 74HC238 are connected to another 3: 8 decoder, which allows to completely eliminate the situation when the source and current drain chips are active at the same time. The enable input of the general decoder is connected to the comparator chip and is activated only when the values ​​at its input coincide. This part of the scheme is most likely also responsible for combining several modules into one big screen.

Thus, to select a specific column, you need to submit its number (0-7) in the group to the COL_A0-A2 bus, and then activate the outputs of a specific 74HC238 by feeding its number to the COL_EN_A0-A2 inputs of the common decoder. Moreover, the input A0 can be used as a source/drain feature, and the remaining 2 bits - as a group number (0-3).

The inputs of the control logic and power are connected to two 50-pin IDC connectors. Wiring one of them is shown in the diagram.

After analyzing the scheme, I realized that blinking the flags without the help of Kicad and a soldering iron did not work and proceeded to create a module for selecting strings and pairing.

Adapter Module and String Management

To simplify the design, I decided to repeat the column selection implementation and put the TBD62783 and ULN2803 paired with 74HC238 decoders to select the desired line, as well as a single 74HC00 (4xNAND) logic chip to clearly separate the SET, RESET and PULSE input modes that directly activate the supply voltage on the selected electromagnet. To save the conclusions of the microcontroller, it was decided to connect the signals for selecting rows and columns to the outputs of one shift register.

As a result, to control the checkbox you need:

  1. send and fix its coordinates in a serial code via SERIAL/CLOCK/LATCH
  2. select the desired SET/RESET state
  3. briefly activate PULSE

Decoding byte coordinates:

The first version of the scheme without a shift register was assembled on a solderless breadboard. After checking and a little excitement that everything would burn out, I turned on the power and gave PULSE a manual impulse by quickly pressing a button. The current flowing through the electromagnet coil was limited just in case at the laboratory power source. The checkbox switched successfully, and when the SET/RESET level was changed, it switched back. “This is a success,” I thought, and began to transfer the circuit to a regular prototyping board using my favorite MGTF-0.07 and single-core kynar-wire for power/ground tires.

To connect to the screen via a 50-pin connector on the board, 22 contacts + power needed to be used, so I didn’t want to mess around with individual wiring. The use of a flat loop, as for IDE or rather old SCSI devices, was suggested.

A little googling led me to a special tool for crimping IDC connectors, which was decided to immediately buy: Crimper ProsKit 6PK-214 for IDC connectors . Having trained on small connectors, I made a 20-cm cable with IDC-50F connectors at the ends the first time.

We write the control program

As I mentioned above, TEENSY 3.5 was used as the controlling controller, the development environment for which is the Arduino IDE, so the program was written in the arduino dialect C.

The main function of changing the state of the screen point
  void update_dot (bool state  , byte row, byte col) {
  byte cmd = 0;

//set 7-5 cmd bits to row 2-0 bits
  cmd = (row & amp; B111) & lt; & lt; 5;
//set 4-0 cmd bits to col 4-0 bits
  cmd = cmd | (col & amp; B11111);

//write to Register
  digitalWriteFast (DOT_LATCH, LOW);
  for (byte i = 0; i & lt; 8; i ++) {
  byte onebit = bitRead (cmd, 7-i);
  digitalWriteFast (DOT_CLOCK, LOW);
  digitalWriteFast (DOT_SERIAL_DATA, onebit);
  digitalWriteFast (DOT_CLOCK, HIGH);
  digitalWriteFast (DOT_LATCH, HIGH);
  delayMicroseconds (10);
  digitalWriteFast (DOT_LATCH, LOW);

//set set/reset pin
  if (state) {
  digitalWriteFast (DOT_SET_RESET, HIGH);
  else {
  digitalWriteFast (DOT_SET_RESET, LOW);

  digitalWriteFast (DOT_PULSE, HIGH);
  delay (1);
  digitalWriteFast (DOT_PULSE, LOW);

I conducted several experiments to determine the optimal voltage of the power source and the time of the pulse. It turned out that 12V and 1ms is enough for a stable fixation of the flag in one of the positions.

After the test fills with one color, I noticed that one “pixel” was broken and did not turn over.Measuring with a multimeter the resistance of the coil showed a few mega-ohms, and a detailed inspection revealed that one conclusion had come off. Very lucky that the non-working “pixel” was at the edge of the screen, so I managed to solder the wire. The problem has been resolved.

Fixed cell photo

That's what happened after the first experiments with fills and text output:


Writing a Tetris implementation on C turned out to be easier than I thought. Thanks to Javier López and his leadership Tetris tutorial in C ++ for beginners . I rewrote the basic functions as I understood them, and adapted the code to the features of my screen (no boundaries and low resolution). I will not bore the details of the work, everything is described in the manual.

An analog joystick module was used for control, so I had to write a function to convert the values ​​at the ADC output into digital constants. Here there was a difficulty in order, on the one hand, to prevent false positives, and on the other, to ensure the correct gameplay. If the position of the joystick does not change after the next reading of the state, a delay is added.

After playing for 10 minutes, I realized that I was bored, because the speed of falling figures does not change and the score is not displayed. There is no competition element.

It was ugly to display the score with flags because of the lack of space on the screen, so it was decided to use the LEDs to create an alternative information output plane. I found on the Internet a bit representation of the 3x5 font for numbers from 0 to 9 and wrote the function of displaying the count by the number of lines removed. For greater beauty, I decided to add a blinking of the filled line when it disappears.

The dynamic nature of the display prompted the idea of ​​calling the function of updating the LED part of the screen in a timer interrupt. The interrupt frequency and the hold time of the LED string in the active state determine the brightness of the glow.

I also made it so that the speed of the fall of the tetramino figures increases as the lines are cleared. In the first version, the figures were shifted one line down every 200 ms. If we take away from this number 40 msec every 10 lines removed, then the pace of the game is greatly accelerated, and interest arises. My record is 38 lines!

The rare case when vertical video fits perfectly.

Project Code , screen layout and interface module are laid out on GitHub.

If you have any ideas what else you can do with such a screen, please write in the comment.

Useful links:

1. Hackaday: Flip-Dot Display & amp; DIY Controller .
2. Tetris tutorial in C ++ in game logic for beginners .
3. Project repository on GitHub .

Source text: Playing Tetris on an electromechanical screen