Martin / 820028 / Schreibmaschine Brother mit Interface

... und hier kann der eigene "Fuhrpark" präsentiert werden.
Antworten

Topic author
brotty
Rank 1
Rank 1
Beiträge: 11
Registriert: Mo 25. Aug 2025, 14:45
Hauptanschluß: 820028

Martin / 820028 / Schreibmaschine Brother mit Interface

#1

Beitrag: # 50766Beitrag brotty »

Aus einer Brother CE-550 Schreibmaschine mit seriellem Interface Brother IF-60 entstand in einigen Abenden mit Hilfe von hier und dank der beeindruckenden Software piTelex eine (zugegebenermassen eher unorthodoxe) Fernschreib-Station:
  • Fernschaltgerät simuliert über unbelegte Tasten, auch die Rufnummer wird über die Tastatur eingegeben.
  • headless-Ausführung von piTelex ist in Vorbereitung, auf einem RaspberryPi.
  • Der Blatteinzug ist leicht unpraktisch, ich behelfe mir aktuell mit zusammengeklebten Papierbogen.
bro-ce550-if60.jpg
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Folgende Benutzer bedankten sich beim Autor brotty für den Beitrag (Insgesamt 3):
roliwRolandISBRAND
i-Telex: 820028 ehrbar ch Eigenbau, Testbetrieb
Standort https://ehrbar.space
Benutzeravatar

obrecht
Rank 8
Rank 8
Beiträge: 816
Registriert: Fr 26. Jun 2020, 18:53
Wohnort: Aachen
Hauptanschluß: 833539 fili d

Martin / 820028 / Schreibmaschine Brother mit Interface

#2

Beitrag: # 50768Beitrag obrecht »

Hallo Martin,

Klasse Projekt! Was man mit piTelex nicht alles machen kann... wäre prima wenn du deine piTelex- Konfiguration hier kurz vorstellst (hard- und Software). Es ist immer interessant, neue Lösungen kennen zu lernen.

Telexrollen gibt's u.a. günstig bei Werner, eBay&Co rufen da eher Mondpreise auf. Einen Rollenhalter müsstest du dann noch basteln 😃

Viel Spaß mit deiner unkonventionellen Telex Station.
Folgende Benutzer bedankten sich beim Autor obrecht für den Beitrag (Insgesamt 2):
brottyISBRAND
Viele Grüße,
Rolf

833533 rolfac d (T100S)  24/7
833538 obrac d  (FS220)  24/7
833539 fili d   (T100a)  24/7 
833540 rowo d   (T100/R) 24/7 
833541 obby d   (T37h)   24/7
833142 rolf d   (Lo15A)  24/7
83110 aachen d  (T68d)   24/7 (ETSt Aachen)

Topic author
brotty
Rank 1
Rank 1
Beiträge: 11
Registriert: Mo 25. Aug 2025, 14:45
Hauptanschluß: 820028

Martin / 820028 / Schreibmaschine Brother mit Interface

#3

Beitrag: # 50806Beitrag brotty »

Hier eine etwas detailliertere Vorstellung:
  • Schreibmaschine mit Typenrad (96 Typen). Typenrad natürlich austauschbar, habe aber nur eins... Schweizer Tastaturbelegung und Typenrad (multilingual d/f/i). Kaufdatum gemäss Vorbesitzer 21.4.1987, letzter Farbbandwechsel Di. 1.1.1991, alles säuberlich beschriftet.
  • Trotz des guten Zustands hatte die Maschine zwei Defekte, die ich glücklicherweise reparieren konnte. Siehe dazu classic-computing-Forum.
  • Interface Brother IF-60 mit serieller und Centronics-Schnittstelle. Verwendung als Drucker oder als Terminal (auch via Modem) vorgesehen.
  • Konfiguration IF-60 mit DIP-Schaltern einstellbar. Aktuelle Einstellung 111000 | 00000101, siehe S. 42 in der sehr detaillierten Bedienungsanleitung.
  • Verbindung IF-60 zu Laptop via Nullmodem-Kabel und USB-Seriell-Adapter, 300 Baud, 8N1.
  • Laptop mit Linux Mint, testing-Zweig des GitHub-Repos von piTelex. Modifiziertes txDevTerminal.py (s. unten) im piTelex steuert nebst den Fernschreiber-Funktionen auch den gesamten Ausdruck. Um gesendeten Text vom empfangenen zu unterscheiden, wird dieser unterstrichen. Das bedeutet zwei Anschläge pro Zeichen, was bereits langsamer ist, als ich tippen kann. Aber Tempo ist sekundär :hehe:
  • Mit Wagenrücklauf CR und Zeilenvorschub LF musste ich etwas rumpröbeln, dazu war die Screen-Ausgabe äusserst nützlich!
  • Senden eigene Kennung mit Taste ¨ (Zweipunktakzent) / ASCII ! / gesendet als #, Anforderung Kennung Gegenstelle mit Taste $ / ASCII $ / gesendet als @.
  • Nummer wählen mit Taste ü / ASCII {, Verbindung beenden mit Taste ä / ASCII }.
  • Leistung gemäss Hersteller 50 W. Für den Dauerbetrieb ist das etwas viel, muss mal nachmessen. Vermutlich ist die Leistung deutlich tiefer, wenn die Motoren nicht laufen.
So sieht ein Telex aus:
telex.png
Offen:
  • Verbindung zu IF-60 via GPIO-Pins eines RaspberryPi.
  • Dauerbetrieb mit einem headless RaspberryPi
  • Glocke bzw. ASCII Bell wäre via ESC-Steuercode und eingebauten Piepser verfügbar.
  • Das local echo möchte ich noch so umprogrammieren, dass die Funktionstasten nicht mitgedruckt werden.
  • Tasten mit Sonderfunktionen beschriften.
  • Papierrollenhalter?
  • Steampunk :dance2: ? Fast ein bisschen schade, das Beige der Achtzigerjahre ist schliesslich auch sehenswert :lol:
Modifiziertes txDevTerminal.py:

Code: Alles auswählen

#!/usr/bin/python3
"""
Telex Device - Serial Communication over System TTY in ASCII-Mode

EPSON is a registered trademark of Seiko Epson Corporation.
ESC/POS is a registered trademark or trademark of Seiko Epson Corporation.
"""
__author__      = "Jochen Krapf"
__email__       = "jk@nerd2nerd.org"
__copyright__   = "Copyright 2021, JK"
__license__     = "GPL3"
__version__     = "0.0.2"

import serial
import serial.rs485
import time

import logging
l = logging.getLogger("piTelex." + __name__)

import txCode
import txBase
import log

#######

class TelexTerminal(txBase.TelexBase):
    def __init__(self, **params):
        super().__init__()

        self.id = 'Trm'
        self.params = params

        portname = params.get('portname', '/dev/ttyUSB0')
        baudrate = params.get('baudrate', 300)
        bytesize = params.get('bytesize', 8)
        stopbits = params.get('stopbits', serial.STOPBITS_ONE)
        parity   = params.get('parity', serial.PARITY_NONE)
        dsrdtr   = params.get('dsrdtr', False)
        rtscts   = params.get('rtscts', False)
        xonxoff  = params.get('xonxoff', False)
        RS485  = params.get('RS485', False)
        self._local_echo = params.get('loc_echo', True)
        self._show_capital = self.params.get('show_capital', False)
        self._show_BuZi = self.params.get('show_BuZi', False)
        self._show_ctrl = self.params.get('show_ctrl', True)
        self._show_info = self.params.get('show_info', False)
        self._send_only = self.params.get('send_only', False)
        self._auto_CRLF = self.params.get('auto_CRLF', 0)
        self._replace_char = self.params.get('replace_char', {})
        self._replace_esc = self.params.get('replace_esc', {})

        self._rx_buffer = []

        # init serial
        if RS485:
            self._tty = serial.rs485.RS485(portname, write_timeout=0)
        else:
            self._tty = serial.Serial(portname, write_timeout=0)

        if baudrate not in self._tty.BAUDRATES:
            raise Exception('Baudrate not supported')
        if bytesize not in self._tty.BYTESIZES:
            raise Exception('Databits not supported')
        if stopbits not in self._tty.STOPBITS:
            raise Exception('Stopbits not supported')
        if parity not in self._tty.PARITIES:
            raise Exception('Parity not supported')

        self._tty.baudrate = baudrate
        self._tty.bytesize = bytesize
        self._tty.stopbits = stopbits
        self._tty.parity = parity
        self._tty.dsrdtr = dsrdtr
        self._tty.rtscts = rtscts
        self._tty.xonxoff = xonxoff
        if RS485:
            self._tty.rs485_mode = serial.rs485.RS485Settings()

        text = params.get('init', '')
        if text:
            self._write_hextext(text)
        
        self.char_count = 0

    # -----

    def exit(self):
        self._tty.close()

    # -----

    def __del__(self):
        super().__del__()

    # =====

    def read(self) -> str:
        if self._send_only:
            return
        if self._tty.in_waiting:
            b = self._tty.read(1)
            if b == b'\r':  # Carriage Return (CR)
                if self._local_echo:
                    # Send both CR (0x0D) and LF (0x0A) for local echo
                    self._write_raw(b)  # Send CR
                    self._write_raw(b'\n')  # Send LF
                self._rx_buffer.append('\n')
                self._rx_buffer.append('\r')   # send CR
            elif b == b'\n':  # Line Feed (LF)
                pass
            elif b[0] < 0x20:
                    pass
            else:
                if self._local_echo:
                    self._write_raw(b'\x1bE') # Lokaler Text unterstrichen
                    self._write_raw(b)
                    self._write_raw(b'\x1bR') # Unterstreichung wieder aufheben
                a = b.decode('ASCII', errors='ignore')

####### Fernschreiber-Steuerung via Schreibmaschinentastatur
                if a:
                    if a == "}":
                        self._rx_buffer.append('\x1bAT')  # ESC + AT
                        self._write_raw(b"nummer: ")

                    elif a == "{":
                        self._rx_buffer.append('\x1bST')  # ESC + ST
                        self._write_raw(b"trennen")

                    elif a == "%":
                        self._rx_buffer.append('\x07')  # ASCII BELL (BEL)
                        # no additional text

                    elif a == "$":
                        self._rx_buffer.append('@')  # WRU

                    elif a == "!":
                        self._rx_buffer.append('#')  # ESC + Kennungsgeber

                    else:
                        a = a.upper()
                        self._rx_buffer.append(a)
#########

        if self._rx_buffer:
            ret = self._rx_buffer.pop(0)
            return ret

    # -----

    def write(self, a:str, source:str):
        if not a:
            return

        if len(a) != 1:
            a = a[1:]
            if a in self._replace_esc:
                self._write_hextext(self._replace_esc.get(a, '?'))
                return

            self._check_commands(a)
            if (self._show_ctrl and a[0].isalpha()) or (self._show_info and not a[0].isalpha()):
                a = '{' + a + '}'
            else:
                return

        else:   # single char
            if not self._show_BuZi and a in '<>':
                return
            if a in self._replace_char:
                self._write_hextext(self._replace_char.get(a, '?'))
                return

            if self._show_capital:
                a = a.upper()
            else:
                a = a.lower()
# orig            
#        self._write_ascii(a)

######### new
        if self._local_echo:
            self._write_ascii(a)
        else:
            self._write_ascii(a)  # You might skip this line entirely if echo = send

##########
    # =====

    def _write_raw(self, bb:bytes):
        self._tty.write(bb)

    # -----

    def _write_ascii(self, text:str):
        if not text:
            return

        bb = text.encode('ASCII')
            
        if self._auto_CRLF:
            for b in bb:
                self.char_count += 1
                if b == b'\r':
                    self.char_count = 0
                self._write_raw(b)
                if self.char_count >= self._auto_CRLF:
                    self._write_raw(b'\r\n')
                    self.char_count = 0

        else:
            self._write_raw(bb)

    # -----

    def _write_hextext(self, s:str):
        if not s:
            return b''

        ishex = False
        hexval = ''
        for c in s:
            if c == '[':   # start hex string
                ishex = True
                hexval = ''
            elif c == ']':   # end hex string
                ishex = False
            else:   # normal char
                if ishex:
                    if c == ' ':
                        continue
                    if hexval == '':
                        hexval = c
                    else:
                        hexval += c
                        self._write_raw(bytes([int(hexval, 16)]))
                        hexval = ''
                else:
                    self._write_ascii(c)

    # =====

    def idle20Hz(self):
        pass

    # -----

    def idle(self):
        pass

    # =====

    def _check_commands(self, a:str):
        if a == 'A':
            pass

        if a == 'Z':
            pass

        if a == 'WB':
            pass

#######
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Folgende Benutzer bedankten sich beim Autor brotty für den Beitrag (Insgesamt 2):
WolfgangHRobbi
i-Telex: 820028 ehrbar ch Eigenbau, Testbetrieb
Standort https://ehrbar.space
Antworten

Zurück zu „Maschinen-Vorstellungen / Register“