The youth section of my orienteering club has a Sportident thermal printer connected to an SI station for use on trainings. This has worked fine for a few years, but for some reason it started printing garbage and I was asked to have a look at it.
I had never used the printer before, but I started troubleshooting. The SI station had old firmware, so I updated that using Sportident Config+, but this did not help. At first I did not get the printer to print anything, but that turned out to be because I had failed to realize that the SI logo was actually a hidden power button one has to press briefly to turn the printer on or off. After the printer was powered on, it did indeed print garbage when I tried to print the contents of an SI card.
The printer is a Martel MCP7830-242 printer with a serial port and I was able to find a manual for it. It turns out a customized manual is also available from Sportident. I suspected the problem might be that the printer was set up to use an incorrect baud rate and I first tried to set the SI station in its two possible states, namely 4800 and 38400 bauds, but that did not help. The manuals have instructions on how to change the baud rate on the printer and according to those instructions, one should keep the power button pressed a couple of seconds until the LED starts blinking, then one should press the button four times and wait for the LED to blink four times (this enters the baud setting mode), then press the button six times to select 4800 baud. Unfortunately this did not help and the printer still printed garbage.
I then decided to talk to the printer from a PC and I wrote a small Python script to try to send commands to it at different baud rates. After some fiddling around, the printer started responding, but at the unexpected baud rate of 600 bauds!
The Python code is shown at the end of this post in case someone is interested.
I retried the baud rate setting, but still with the result of getting the printer to accept 600 bauds. A note above the tables in the manual says one should do a single button press to select 19200 bauds, but the table says the button should be pressed five times. This made me try to press the button three instead of six times (4800 comes two steps after 19200 in the table) and after this, the printer started working at 4800! So the correct sequence for setting the baud rate to 4800 is this:
- Printer is off
- Hold down the button for a few seconds until the LED starts flashing.
- Press the button 4 times.
- Wait for the LED to flash 4 times.
- Press the button 3 times.
- Wait for the LED to flash 3 times.
- Done!
After I got it all to work I realized that one can check the mode of the printer in the following way:
- Printer is off
- Hold down the button for two seconds.
- The printer prints its status, including the baud rate.
If I had known this from the start I might have solved this much quicker.
Below is the Python code.
#! /usr/bin/python
"""
com-port-sender.py
Rev 0.1, 2016-09-28
Per Magnusson, Axotron, axotron.se/blog
This code is public domain and comes with absolutely no warranty. Enjoy!
Send some data on a serial port to test a Martel/Sportident MCP7830 printer.
"""
from __future__ import print_function
import serial
import serial.tools.list_ports
import sys
import time
import msvcrt
import struct
# Look for a COM port that might have a serial port adapter connected
portfound = False
ports = list(serial.tools.list_ports.comports())
for p in ports:
print(p)
print(p[1])
if "Prolific" in p[1]:
print("Found port on " + p[0])
if not portfound:
portname = p[0]
portfound = True
print("Using " + portname)
else:
print("Ignoring this port, using the first one that was found.")
if portfound:
ser = serial.Serial(portname, 4800, timeout=0.1)
else:
print("No good serial port found. Exiting.")
time.sleep(10)
sys.exit("No good serial port found.")
def to_printer(ser, data):
for b in data:
print("{:d} ".format(ord(b)), end="")
ser.write(data)
print("")
def send_ESC(ser):
to_printer(ser, b'\x1b') # 27 == ESC
def send_NULL(ser):
to_printer(ser, b'x\00')
def set_sweden(ser):
send_ESC(ser)
to_printer(ser, b'R5')
def set_mode_default(ser):
send_ESC(ser)
to_printer(ser, b'!\x00')
def reset_printer(ser):
send_ESC(ser)
to_printer(ser, b'\xff')
def reset_printer2(ser):
send_ESC(ser)
to_printer(ser, b'@')
def printer_self_test(ser):
send_ESC(ser)
to_printer(ser, b'\xfe')
def printer_move_fwd(ser):
send_ESC(ser)
to_printer(ser, b'J\x08')
def printer_print(ser):
send_ESC(ser)
to_printer(ser, b'd\x01')
def print_something(ser):
to_printer(ser, b'abc\x0d\x0a\x0c')
#set_sweden(ser)
#printer_self_test(ser)
#reset_printer(ser)
#reset_printer2(ser)
#set_mode_default(ser)
#printer_move_fwd(ser)
#to_printer(ser, b'abc\x0d\x0a\x0c')
#printer_print(ser)
rates = [300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]
for rate in rates:
print('baud: {:d}'.format(rate))
ser.setBaudrate(rate)
print_something(ser)
time.sleep(5)
ser.close()