User Tools

Site Tools


electronique:afficheur_bus_led:accueil

Reverse engineering d'un afficheur DATA Display (de 1992 !)

J'ai récemment récupéré un afficheur de bus de marque DATA Display (de 1992, à la vue du datecode des composants). L'afficheur comporte deux parties:

  • La partie d'un haut, composée de deux segments verts de 12 matrices (5×7 chacunes), soit d'une grande matrice de (2*(12*5))*7 pixels.
  • La partie du bas, un peu identique, mais avec des pixels rouges

La partie du bas est intéressante, car elle semble contenir une RAM qui, avec une connectique extérieure (et une batterie NiMH pour retenir la ram), permet de se faire téléverser des messages à afficher. Par contre, les fabricants n'ont plus le protocole de transmission. Ca va être un peu chiant à reverse-engeenirer.

La partie du haut, elle, est à peu près identique. Sauf le fait qu'elle contient une ROM contenant les caractères ASCII (du moins, leur représentation en matrice de 5×7) pour afficher le texte. Elle dispose aussi d'une connectique spéciale (RS232, mais pas trop). Ca va aussi être chiant à réaliser. Mais j'ai décidé de démonter l'afficheur du haut et de regarder comment il fonctionnait.

Fonctionnement de l'afficheur

Le module d'affichage peut-être, à première vue, daisy-chainé (vu que les deux sont identiques). Cela fait tout de suite penser (et cela sera confirmé plus tard après lecture des composants) à un (plusieurs !)shift-register.
Concrètement, l'afficheur dispose de 7 transistors (drivés eux-mêmes par des NPN, eux mêmes drivés par un darlington, qui est lui, drivé par un octuple-inverseur). Ces 7 transistors s'occupent d'afficher, ou pas, une des 7 lignes du module.
Ensuite, nous avons une cascade de shift-registers (SIPO). Ceux-ci on simplement trois entrées: une entrée de données, une entrée de clock, et une de reset. La sortie 6 de l'un est reliée à l'entrée DATA de l'autre. À chaque front haut d'horloge, chaque shift register regarde ce qu'il a dans son entrée, et applique la valeur de l'entrée à la valeur de sortie1, puis la valeur de sortie1 à la sortie2. Puis la sortie2 à la 3, et ainsi de suite.
Donc si on veut allumer seulement de 5èpme pixel (en partant de la droite), il faut envoyer “10000”.
Pour afficher du texte, ce qu'on fait est de balancer toute la première ligne dans le shift register, et d'activer seulement le transistor 1. Puis ensuite, on clear tout, on “désactive” T1, puis on envoie toute la ligne 2, etc… Bien sur, il faut faire cela plusieurs fois par seconde. Le rafraichissement est constant.

Ce qui nous donne, pour un premier test, avec les deux premiers transistors passant:

Connexion au raspberry pi

La première chose à faire est de connecter les 7 transistors au RPi. La première idée serait de connecter chaque base de chaque transistor à une sortie du RPi. Le problèmme est que l'afficheur n'est pas fait pour avoir plusieurs transistors allumés simultanément: le 74HC164 crèverait rapidement (test fait..). Les transistors sont en fait concus pour êtres exclusivement allumés (à un ratio de 1 pour 7). Donc, vu qu'on ne veut pas les allumer plus d'un en même temps, une solution sécuritaire et économe en GPIO est d'utiliser un multiplexeur: avec 3 sorties du RPi on peut piloter 2³ soit 8 sorties différentes. En plus, si un jour le RPi viendrait à planter, il est impossible que les 7 transistors soient passants en même temps: de la sécurité en plus !

Concrètement, nous aurons besoin de:

  • 3 sorties qui seront connectées à un 74LS138 (et ensuite, malheureusement, par une porte NON)
  • 1 sortie pour le clock
  • 1 sortie pour les données (prises en compte au front d'horloge haut)
  • 1 sortie pour le master reset (clear des latches)

Soit 6 sorties en tout; pas mal ;), Ce qui nous fait:

  • GPIO: 23,24,25: multiplex
  • GPIO 17: data
  • GPIO 21: MR
  • GPIO 22: clock

Okay, tout marche !

Il manque plus qu'à coder toute la partie software ;)
Si vous êtes intéressés, elle est disponible ici:

git://www.gw-computing.net/aei-matrixled.git
ou (c'est le même, juste backupé)
git://git.vi-di.fr/aei-matrixled.git

Ca peut vous intéresser

Quelques photos

Petit code de test

#!/usr/bin/python3.3
 
import RPi.GPIO as GPIO
import time
 
def chooseLine(line):
	GPIO.output(mr, GPIO.LOW)
	GPIO.output(mr, GPIO.HIGH)
	if(line == 2):
		GPIO.output(line1, GPIO.LOW)
		GPIO.output(line2, GPIO.LOW)
		GPIO.output(line3, GPIO.LOW)
	elif(line == 3):
		GPIO.output(line1, GPIO.HIGH)
		GPIO.output(line2, GPIO.LOW)
		GPIO.output(line3, GPIO.LOW)
	elif(line ==4):
		GPIO.output(line1, GPIO.LOW)
		GPIO.output(line2, GPIO.HIGH)
		GPIO.output(line3, GPIO.LOW)
 
 
line1=23;
line2=24;
line3=25;
 
data=17;
mr=21;
clock=22;
 
# to use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BOARD);
GPIO.setmode(GPIO.BCM)
 
GPIO.setup(line1, GPIO.OUT);
GPIO.setup(line2, GPIO.OUT);
GPIO.setup(line3, GPIO.OUT);
GPIO.setup(data, GPIO.OUT);
GPIO.setup(mr, GPIO.OUT)
GPIO.setup(clock, GPIO.OUT)
 
GPIO.output(line1, GPIO.LOW)
GPIO.output(line2, GPIO.LOW)
GPIO.output(line3, GPIO.LOW)
 
GPIO.output(data, GPIO.LOW)
GPIO.output(mr, GPIO.HIGH)
GPIO.output(clock, GPIO.LOW)
 
'''
##O## O#### O##O# OOOOO
#OOO# O#### O##O# ##O##
O###O OOOO# OOOO# ##O##
'''
 
pixLine2 = [0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1]
pixLine3 = [0, 1, 1, 1, 0, 1, 0, 0, 0 ,0, 1, 0, 0 ,1 ,0, 0, 0, 1, 0, 0]
pixLine4 = [1, 0 ,0 ,0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0 ,0]
 
#pixLine3 = [1, 0, 0, 0, 0, 0, 1, 0, 0, 1]
#pixLine4 = [1, 1, 1, 1, 1, 0, 1, 1, 1, 1]
 
'''
pixLine2 = [1, 0, 1, 0, 1, 0, 1, 0, 1]
pixLine3 = [0, 0, 1, 1, 0, 0, 1, 1, 0]
pixLine4 = [0, 0, 0, 1, 1, 1, 0, 0, 0]
'''
 
while(1):
	chooseLine(2)
	for i in pixLine2:
		GPIO.output(data, i)
		GPIO.output(clock, GPIO.HIGH)
		GPIO.output(clock, GPIO.LOW)
 
	time.sleep(0.002)
 
	chooseLine(3)
	for i in pixLine3:
		GPIO.output(data, i)
		GPIO.output(clock, GPIO.HIGH)
		GPIO.output(clock, GPIO.LOW)
 
	time.sleep(0.002)
 
	chooseLine(4)
	for i in pixLine4:
		GPIO.output(data, i)
		GPIO.output(clock, GPIO.HIGH)
		GPIO.output(clock, GPIO.LOW)
	time.sleep(0.002)
 
i=0
while(i < 10):
	GPIO.output(data, GPIO.HIGH)
#	GPIO.output(clock, GPIO.HIGH)
	time.sleep(0.1);
	GPIO.output(clock, GPIO.LOW)
	time.sleep(0.1);
 
	GPIO.output(data, GPIO.LOW)
	GPIO.output(clock, GPIO.HIGH)
	time.sleep(0.1);
	GPIO.output(clock, GPIO.LOW)
	time.sleep(0.1);
#	i = i+1
 
'''
 
# set RPi board pin 12 high
GPIO.output(12, GPIO.HIGH)
 
# set up GPIO output channel with an initial state
GPIO.setup(26, GPIO.OUT, initial=GPIO.LOW)
 
# set up GPIO input with pull-up control
#   (pull_up_down be PUD_OFF, PUD_UP or PUD_DOWN, default PUD_OFF)
GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_UP)
 
# input from RPi board pin 11
input_value = GPIO.input(11)
'''

Discussion

Enter your comment. Wiki syntax is allowed:
ERWFA
 
electronique/afficheur_bus_led/accueil.txt · Last modified: 2013/05/04 22:40 by frank