Dot matrix printing: Difference between revisions

From XPUB & Lens-Based wiki
 
(43 intermediate revisions by 2 users not shown)
Line 1: Line 1:
==OKI Microline 320==
==Dot-matrix printers as pedagogical devices==
 
Today we will work with the dot-matrix printers as pedagogical devices.
 
And zoom into the layers of "languages" that are at play when producing graphics and layout produced with '''text'''.
 
BUT. Computers don’t actually work with text. <br>
Computers are calculators that work with numbers.
 
This means that any kind of input to the computer and any kind of output from the computer exists as numbers somewhere in between.
 
To explore the layers and complexities of these '''encoding''' and '''decoding''' processes and the politics that these systems are entangled with, dot-matrix printers are great to work with.
 
What can we learn from the printers today? Which questions come up?
 
==Dot-matrix materiality==
 
What is the materiality of dot-matrix printers?
 
<gallery>
File:9 nadel druckkopf-star nl10--hinnerk ruemenapf vs01-p50.jpg|thumb|right|An example of a dot-matrix printer head with 9 pins (this one is from the Star NL 10)
File:Xerox Roman PS Daisywheel - mono.jpg|thumb|right|An example of a daisywheel printer (this one is for Xerox & Diablo printers)
</gallery>
 
Before was the daisy wheel printer (close to typewriter), but with the dot-matrix printers work with a printer head and pins.. so you can make your own characters. Which helped to promote it and sell it internationally. Other character cards were also distributed, with fonts etc, which you could load into your printer.
 
<div style="color:coral !important;border-left:3px solid coral;padding:0 0 0 1em;margin:1.5em 0;">
'''EXERCISE: Warm up and turn the printers on'''
 
Taking an '''exploratory approach'''...
 
# Pick one printer
# Print the self-tests of the machine (see [[#Howto]] section below)
# Print the menu with the current settings (see [[#Howto]] section below)
 
Now, let's try to talk with printer from a computer.
 
# Connect to the printer, you can follow the [[#Howto]] section below.
# Once you are connected, print some words or plain text files from the command line. See which command works for you:
 
$ echo "hello" > /dev/usb/lp1
$ echo "hello" | lp
$ lpr hello.txt
 
</div>
 
===What language does the printer speak?===
 
Let's zoom into the text we just sent to the printer...
 
We just sent <code>hello</code> to the printer... so the characters h, e, l, l, o.
 
But good to know is... that when you send these characters.. you are actually not sending the character itself, you are sending a number.
 
Your computer and the printer both have their own understanding of characters.. They represent each character with a number. <code>a</code> often is represented by <code>97</code> for example these days (and there is a reason for that)!
 
But back in the days.. the different machines that were made represented characters in all different ways, each device did it differently. When the moment came that there was a need to send text from device A to device B, it was clear that this needed to be resolved somehow, and that there was a need for a shared way to represent characters. 
 
And this is why we have: 💀'''encoding systems'''💀
 
====ASCII imperialism====
 
One famous one... is... ASCII, first published in 1963.
 
$ man ascii
<!--[[File:Asciitable.png]]-->
 
<div id="asciitable">
  Binary      Dec  Hex  Char                        Binary      Dec  Hex  Char
  ────────────────────────────────────────────────────────────────────────────────
  0000 0000  0    00    NUL '\0' (null character)  0100 0000  64    40    @
  0000 0001  1    01    SOH (start of heading)      0100 0001  65    41    A
  0000 0010  2    02    STX (start of text)        0100 0010  66    42    B
  0000 0011  3    03    ETX (end of text)          0100 0011  67    43    C
  0000 0100  4    04    EOT (end of transmission)  0100 0100  68    44    D
  0000 0101  5    05    ENQ (enquiry)              0100 0101  69    45    E
  0000 0110  6    06    ACK (acknowledge)          0100 0110  70    46    F
  0000 0111  7    07    BEL '\a' (bell)            0100 0111  71    47    G
  0000 1000  8    08    BS  '\b' (backspace)        0100 1000  72    48    H
  0000 1001  9    09    HT  '\t' (horizontal tab)  0100 1001  73    49    I
  0000 1010  10    0A    LF  '\n' (new line)        0100 1010  74    4A    J
  0000 1011  11    0B    VT  '\v' (vertical tab)    0100 1011  75    4B    K
  0000 1100  12    0C    FF  '\f' (form feed)        0100 1100  76    4C    L
  0000 1101  13    0D    CR  '\r' (carriage ret)    0100 1101  77    4D    M
  0000 1110  14    0E    SO  (shift out)            0100 1110  78    4E    N
  0000 1111  15    0F    SI  (shift in)              0100 1111  79    4F    O
  0001 0000  16    10    DLE (data link escape)      0101 0000  80    50    P
  0001 0001  17    11    DC1 (device control 1)      0101 0001  81    51    Q
  0001 0010  18    12    DC2 (device control 2)      0101 0010  82    52    R
  0001 0011  19    13    DC3 (device control 3)      0101 0011  83    53    S
  0001 0100  20    14    DC4 (device control 4)      0101 0100  84    54    T
  0001 0101  21    15    NAK (negative ack.)        0101 0101  85    55    U
  0001 0110  22    16    SYN (synchronous idle)      0101 0110  86    56    V
  0001 0111  23    17    ETB (end of trans. blk)    0101 0111  87    57    W
  0001 1000  24    18    CAN (cancel)                0101 1000  88    58    X
  0001 1001  25    19    EM  (end of medium)        0101 1001  89    59    Y
  0001 1010  26    1A    SUB (substitute)            0101 1010  90    5A    Z
  0001 1011  27    1B    ESC (escape)                0101 1011  91    5B    [
  0001 1100  28    1C    FS  (file separator)        0101 1100  92    5C    \ 
  0001 1101  29    1D    GS  (group separator)      0101 1101  93    5D    ]
  0001 1110  30    1E    RS  (record separator)      0101 1110  94    5E    ^
  0001 1111  31    1F    US  (unit separator)        0101 1111  95    5F    _
  0010 0000  32    20    SPACE                      0110 0000  96    60    `
  0010 0001  33    21    !                          0110 0001  97    61    a
  0010 0010  34    22    "                          0110 0010  98    62    b
  0010 0011  35    23    #                          0110 0011  99    63    c
  0010 0100  36    24    $                          0110 0100  100  64    d
  0010 0101  37    25    %                          0110 0101  101  65    e
  0010 0110  38    26    &                          0110 0110  102  66    f
  0010 0111  39    27    '                          0110 0111  103  67    g
  0010 1000  40    28    (                          0110 1000  104  68    h
  0010 1001  41    29    )                          0110 1001  105  69    i
  0010 1010  42    2A    *                          0110 1010  106  6A    j
  0010 1011  43    2B    +                          0110 1011  107  6B    k
  0010 1100  44    2C    ,                          0110 1100  108  6C    l
  0010 1101  45    2D    -                          0110 1101  109  6D    m
  0010 1110  46    2E    .                          0110 1110  110  6E    n
  0010 1111  47    2F    /                          0110 1111  111  6F    o
  0011 0000  48    30    0                          0111 0000  112  70    p
  0011 0001  49    31    1                          0111 0001  113  71    q
  0011 0010  50    32    2                          0111 0010  114  72    r
  0011 0011  51    33    3                          0111 0011  115  73    s
  0011 0100  52    34    4                          0111 0100  116  74    t
  0011 0101  53    35    5                          0111 0101  117  75    u
  0011 0110  54    36    6                          0111 0110  118  76    v
  0011 0111  55    37    7                          0111 0111  119  77    w
  0011 1000  56    38    8                          0111 1000  120  78    x
  0011 1001  57    39    9                          0111 1001  121  79    y
  0011 1010  58    3A    :                          0111 1010  122  7A    z
  0011 1011  59    3B    ;                          0111 1011  123  7B    {
  0011 1100  60    3C    <                          0111 1100  124  7C    |
  0011 1101  61    3D    =                          0111 1101  125  7D    }
  0011 1110  62    3E    >                          0111 1110  126  7E    ~
  0011 1111  63    3F    ?                          0111 1111  127  7F    DEL
</div>
 
<blockquote>
Thanks to the power of the US Military and US corporations the American computing industry became the global computing industry. Computers that we use today are rooted in American networking history, and so is the ASCII standard. However, the reality is that ASCII can only represent 26 Latin letters in the English alphabet but computers are used all over the world, by people speaking different languages. They would often end up with American computers that could not represent their language in ASCII. Think for example of scripts like Greek, Cyrillic and Arabic or even Latin scripts that use accents such as the ü or ø. Altough 128 might sound like a lot of characters, it is not enough to represent all different languages.<ref>https://vvvvvvaria.org/curriculum/In-the-Beginning-...-Was-the-Commandline/READER.html#ascii-encoding</ref>
</blockquote>
 
As you can see in the table above, it lists '''all sorts of characters''', also ones that are not represented on our keyboards (like "ESC").
 
Some of these are legacy characters from a teletype/typewriter past.. Like the "bell" character.
 
In order to type these characters, like a ''line feed character'' (LF), you use the code point representation of that particular character.
 
<blockquote>
For a time people used the 8th bit, numbers 1000 0000 to 1111 1111 (or 128 to 256) to encode the specific parts of their own language. That way there was an overlap with ASCII but the own language could also be encoded.<ref>https://vvvvvvaria.org/curriculum/In-the-Beginning-...-Was-the-Commandline/READER.html#ascii-encoding</ref>
</blockquote>
 
<div style="color:coral !important;border-left:3px solid coral;padding:0 0 0 1em;margin:1.5em 0;">
'''ASCII exercise'''
 
* take a piece of paper and a pen, and:
** count to 10 in decimal
** count to 10 in binary
** count to 10 in hex
 
</div>
 
====Unicode universalism====
 
<blockquote>
The Unicode Standard supports three character encoding forms: UTF-32, UTF-16, and UTF-8. Each encoding form maps the Unicode code points '''U+0000..U+D7FF''' and '''U+E000..U+10FFFF''' to unique code unit sequences.<ref>https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G7404</ref>
</blockquote>
 
Let's explore these code points!
 
In Python, you can use the <code>chr()</code> function to print Unicode code points. You give it a decimal.
 
chr(97)
 
returns: "a"
 
And if you want to find the code point of a character, you can use ord():
 
ord("a")
 
returns: 97
 
You can explore all the '''code points''', which are organized in code blocks, here:
 
* https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G7404
* https://en.wikipedia.org/wiki/Unicode_block
* http://www.unicode.org/charts/
* https://www.unicode.org/Public/UCD/latest/charts/CodeCharts.pdf
 
<div style="color:coral !important;border-left:3px solid coral;padding:0 0 0 1em;margin:1.5em 0;">
'''Unicode exercise'''
 
* let's print U+0000 until U+D7FF and U+E000 until E+10FFFF with python
* first convert the numbers of the code blocks from hex to decimal
* then loop through these blocks by printing them
 
'''Extra'''
 
* some characters are printed as (so-called) "tofu's".. install a font that has coverage (glyphs) for these characters, like Unifont!
* find a nice range of code points and make a small terminal animation in python
</div>
 
====Model specific printer commands====
 
Each printer comes with a '''different set of special commands''', '''different character sets''' and '''different fonts'''.
 
The '''special commands''' can change the behavior of the printer (like superscript, bold, alignment, and even loops!).
 
To switch to italic for instance on the NEC P60, you need to send <code>esc</code> and <code>4</code>. And to send the <code>esc</code> key in hex in Python, you send: <code>chr(27)</code>.
 
To find these special commands... we need to dive into the specific manual of a printer.
 
The '''character set''' of a printer can be changed, to support different languages. Each printer supports a different range of character sets.
 
And of course, each printer comes with '''different fonts''' installed. And some of them have the option to install extra fonts using a card ridge.
 
<div style="color:coral !important;border-left:3px solid coral;padding:0 0 0 1em;margin:1.5em 0;">
'''Printer commands exercise'''
 
* pick a dot-matrix printer to work with
* use the python script below to send a "hello" to the printer
* find the manual of the printer and find the list of special commands this printer can work with
* work with the special commands using your python script
** we can't type these special commands with our keyboards directly, but we can execute them using the hex code points listed in the manual!
** use <code>chr()</code> and the hex code point and see what they do
* pick one special command and try to make a prototype with it (use it to draw something, make a playful layout, a mini poem, etc!)
 
</div>
 
<syntaxhighlight lang="python">
msg = "hello"
 
# Linux/OSX?
printer = open("/dev/usb/lp1", "w")
printer.write(msg)
printer.close()
 
# Windows/OSX
import os
printer = open("tmp.txt", "w")
printer.write(msg)
printer.close()
cmd = "lpr tmp.txt"
#cmd = "cat tmp.txt | lp"
os.system(cmd)
</syntaxhighlight>
 
====Control individual pins====
 
Exciting thing to try one day: There are also special commands to control the individual pins (!).
 
This means that you can print without using a driver. A driver translates the pixelated image into the pins of the printer.
 
Here you can find dithering strategies to convert an image into a type of image that could be printed on the dot-matrix printer.
 
So dithering was a technical limitation. These days, it's often an aesthetic choice, which is different.
 
==Dot-matrix printers @ XPUB==
===OKI Microline 320===


[[File:Oki-microline-320.png]]
[[File:Oki-microline-320.png]]
Line 15: Line 271:
Current intuition is that it is a hardware issue.
Current intuition is that it is a hardware issue.


==NEC PINWRITER P60==
===NEC PINWRITER P60===


[[File:Screenshot from 2025-02-05 13-35-48.png|300px]]
[[File:Screenshot from 2025-02-05 13-35-48.png|300px]]
Line 23: Line 279:
* '''connect to the printer''': USB-A → centronics cable (you can find this one either in the office or XML, it's black)
* '''connect to the printer''': USB-A → centronics cable (you can find this one either in the office or XML, it's black)
* '''user manual''': (cannot find it...)
* '''user manual''': (cannot find it...)
* '''comprehensive support document''': [[:File:Pinwriter p6-specification.pdf]]
* '''comprehensive support document''': [[:File:Pinwriter p6-specification.pdf]] (you can find the special commands here!)
* '''maintenance guide''': [[:File:P60_SM_NEC_EN_text.pdf]]
* '''maintenance guide''': [[:File:P60_SM_NEC_EN_text.pdf]]
* '''links''': https://www.vclab.de/paperware-inventory/pinwriter-p60-p70-verdammt-nah-am-laser/# (protected with password...)
* '''links''': https://www.vclab.de/paperware-inventory/pinwriter-p60-p70-verdammt-nah-am-laser/# (protected with password...)
Line 35: Line 291:
The printer works with 80 columns.
The printer works with 80 columns.


==Citizen Swift 90''e''==
===NEC PINWRITER P20===
 
[[File:NEC-Pinwriter-P20.jpg|300px]]
 
* '''brought to XPUB for this trimester by''': Joak
* '''status''': works
* '''connect to the printer''': USB-A → centronics cable
* '''user manual''': [[:File:Pinwriter p2000p2x-manual.pdf]]
* '''links''': http://www.digitanto.it/mc-online/PDF/Articoli/105_122_127_0.pdf
 
Running the '''self test''': see page 5 in the manual (page 13 in the pdf)
 
Printing the '''menu with current settings''': see page 17 in the manual (page 25 in the pdf) [SELECT + Power on]
 
===Citizen Swift 90''e''===


[[File:Citizen-swift-90-printer.jpg|300px]]
[[File:Citizen-swift-90-printer.jpg|300px]]


* '''brought to XPUB for this trimester by''': Joseph
* '''brought to XPUB for this trimester by''': Joak
* '''status''': works, see comments below
* '''status''': works but bumpy, see comments below
* '''connect to the printer''': USB-A → centronics cable  
* '''connect to the printer''': USB-A → centronics cable  
* '''user manual''': [[:File:Citizen-swift-90-user-manual.pdf]]
* '''user manual''': [[:File:Citizen-swift-90-user-manual.pdf]]
* '''datasheet''': [[:File:Citizen-swift-90e-datasheet.pdf]]
* '''datasheets''': [[:File:Citizen-swift-90e-datasheet.pdf]]
* '''technical sheet''': [[:File:Citizen-swift-90-technical-sheet.pdf]]


The printer works, but the continuous paper feed (for the paper with holes on the sides) is a bit slippery, so you need to help the printer a bit sometimes. If you use the external paper feed adapter and work with A4, it's much smoother.
The printer works, but the continuous paper feed (for the paper with holes on the sides) is a bit slippery, so you need to help the printer a bit sometimes. If you use the external paper feed adapter and work with A4, it's much smoother.
Line 55: Line 326:
More info on '''codepages'''? See '''page 32''' in the manual: ''Codepages - International Characters''.
More info on '''codepages'''? See '''page 32''' in the manual: ''Codepages - International Characters''.


==Dot-matrix printing in practice==
Sending '''printer control commands''' works when you use the build-in '''Epson FX1170 emulation''' (found this in the [[:File:Citizen-swift-90-technical-sheet.pdf|technical sheet]]). See [[:File:Epson-fx1170-manual.pdf|Epson FX1170 manual]] chapter 8 "Command Summary" for a listing of special commands.


There is a way to speak to these pins individually.
===Star SG-10===


A driver translates the pixelated image into the pins of the printer. Here you can find dithering strategies to convert an image into a type of image that could be printed on the dot-matrix printer. So dithering was a technical limitation. These days, it's often an aesthetic choice, which is different.
[[File:Star-SG-10.jpg|300px]]


Before was the daisy wheel printer (close to typewriter), but with the dot-matrix printers you can make your own characters. Which helped to promote it and sell it internationally. Other character cards were also distributed, with fonts etc, which you could load into your printer.
* '''brought to XPUB for this trimester by''': Joak
 
* '''status''':
There was not one fixed character set for all dot-matrix printers.
* '''connect to the printer''': USB-A → centronics cable
 
* '''user manual''': [[:File:Star-SG-10.pdf]]
You send a character as ASCII, and depending on which font is loaded, it is printed.
* '''links''': https://www.msx.org/wiki/Star_SG-10
 
Some ASCII characters are not printable, like the bell or the esc key. To send it, you need to send it as ASCII but translate it from another encoding system on your computer, for example with Python, and send it to the print in hex.


The user manual lists all the possible special commands that can be used.
The language in the manual is funny, very conversational :).


To switch to italic for instance on the NEC P60, you need to send <code>esc</code> and <code>4</code>.
You can switch between character sets, "modes" and character pitch (size) using the dip switches. See page 133 in the manual.


To get the esc key in hex in Python: <code>chr(27)</code> which returns <code>'/x1b'</code>, etc.
The '''special commands''' are a bit everywhere in the user manual, but mostly in chapter 5-10, and there is an index of all of them on page 240.


There are also special commands to control the individual pins (!).
==Howto==
 
Each printer comes with a different set of special commands, different character sets and different fonts.


===Printing on OSX===
===Printing on OSX===
Line 113: Line 380:
  > lpr myfile.txt
  > lpr myfile.txt


But! This only prints files, not output of commands like <code>echo</code>. To do so, there are options:  
But! This only prints files, not output of commands like <code>echo</code>.. But maybe there is a way.. this might work, it looks like it's worth a try:


* we do it with Python
* https://support.elliott.com/knowledgebase/articles/1100086-using-raw-data-pass-through-for-dot-matrix-printer
* you can try this answer: https://stackoverflow.com/a/6296182
 
====Claudio's notes====
First things first, I used the "CITIZEN Swift 90e" printer.
On Windows I had multiple unexpected errors but after all Joseph helped and we did not end up using lpr but we used the [https://www.pdq.com/powershell/out-printer Out-Printer] command.
 
and the final commands were:
 
<code>cat yourfile.txt | Out-Printer</code>
 
or to write directly a string avoiding using a file:
 
<code>"The text you want to print" | Out-Printer</code>


===Printing on Linux===
===Printing on Linux===
Line 135: Line 413:
  $ cat hello.txt | lp
  $ cat hello.txt | lp
  $ lpr hello.txt
  $ lpr hello.txt
==ASCII art==
===jp2a===
lightweight tool to convert images into ascii, written by Christian Stigen Larsen
https://web.archive.org/web/20200517095853/https://csl.name/jp2a/
$ jp2a
* Linux: <code>$ sudo apt install jp2a</code>
* Mac: <code>brew install jp2a</code>
* Windows: https://www.samgalope.dev/2024/10/24/how-to-use-jp2a-for-creating-stunning-ascii-art/#aioseo-on-windows


==Examples==
==Examples==
Line 196: Line 488:
[[Category:Cookbook]]
[[Category:Cookbook]]
[[Category:Printers]]
[[Category:Printers]]
==Footnotes==
<references />

Latest revision as of 09:50, 11 March 2025

Dot-matrix printers as pedagogical devices

Today we will work with the dot-matrix printers as pedagogical devices.

And zoom into the layers of "languages" that are at play when producing graphics and layout produced with text.

BUT. Computers don’t actually work with text.
Computers are calculators that work with numbers.

This means that any kind of input to the computer and any kind of output from the computer exists as numbers somewhere in between.

To explore the layers and complexities of these encoding and decoding processes and the politics that these systems are entangled with, dot-matrix printers are great to work with.

What can we learn from the printers today? Which questions come up?

Dot-matrix materiality

What is the materiality of dot-matrix printers?

Before was the daisy wheel printer (close to typewriter), but with the dot-matrix printers work with a printer head and pins.. so you can make your own characters. Which helped to promote it and sell it internationally. Other character cards were also distributed, with fonts etc, which you could load into your printer.

EXERCISE: Warm up and turn the printers on

Taking an exploratory approach...

  1. Pick one printer
  2. Print the self-tests of the machine (see #Howto section below)
  3. Print the menu with the current settings (see #Howto section below)

Now, let's try to talk with printer from a computer.

  1. Connect to the printer, you can follow the #Howto section below.
  2. Once you are connected, print some words or plain text files from the command line. See which command works for you:
$ echo "hello" > /dev/usb/lp1
$ echo "hello" | lp
$ lpr hello.txt

What language does the printer speak?

Let's zoom into the text we just sent to the printer...

We just sent hello to the printer... so the characters h, e, l, l, o.

But good to know is... that when you send these characters.. you are actually not sending the character itself, you are sending a number.

Your computer and the printer both have their own understanding of characters.. They represent each character with a number. a often is represented by 97 for example these days (and there is a reason for that)!

But back in the days.. the different machines that were made represented characters in all different ways, each device did it differently. When the moment came that there was a need to send text from device A to device B, it was clear that this needed to be resolved somehow, and that there was a need for a shared way to represent characters.

And this is why we have: 💀encoding systems💀

ASCII imperialism

One famous one... is... ASCII, first published in 1963.

$ man ascii
  Binary      Dec   Hex   Char                        Binary      Dec   Hex   Char
  ────────────────────────────────────────────────────────────────────────────────
  0000 0000   0     00    NUL '\0' (null character)   0100 0000   64    40    @
  0000 0001   1     01    SOH (start of heading)      0100 0001   65    41    A
  0000 0010   2     02    STX (start of text)         0100 0010   66    42    B
  0000 0011   3     03    ETX (end of text)           0100 0011   67    43    C
  0000 0100   4     04    EOT (end of transmission)   0100 0100   68    44    D
  0000 0101   5     05    ENQ (enquiry)               0100 0101   69    45    E
  0000 0110   6     06    ACK (acknowledge)           0100 0110   70    46    F
  0000 0111   7     07    BEL '\a' (bell)             0100 0111   71    47    G
  0000 1000   8     08    BS  '\b' (backspace)        0100 1000   72    48    H
  0000 1001   9     09    HT  '\t' (horizontal tab)   0100 1001   73    49    I
  0000 1010   10    0A    LF  '\n' (new line)         0100 1010   74    4A    J
  0000 1011   11    0B    VT  '\v' (vertical tab)     0100 1011   75    4B    K
  0000 1100   12    0C    FF  '\f' (form feed)        0100 1100   76    4C    L
  0000 1101   13    0D    CR  '\r' (carriage ret)     0100 1101   77    4D    M
  0000 1110   14    0E    SO  (shift out)             0100 1110   78    4E    N
  0000 1111   15    0F    SI  (shift in)              0100 1111   79    4F    O
  0001 0000   16    10    DLE (data link escape)      0101 0000   80    50    P
  0001 0001   17    11    DC1 (device control 1)      0101 0001   81    51    Q
  0001 0010   18    12    DC2 (device control 2)      0101 0010   82    52    R
  0001 0011   19    13    DC3 (device control 3)      0101 0011   83    53    S
  0001 0100   20    14    DC4 (device control 4)      0101 0100   84    54    T
  0001 0101   21    15    NAK (negative ack.)         0101 0101   85    55    U
  0001 0110   22    16    SYN (synchronous idle)      0101 0110   86    56    V
  0001 0111   23    17    ETB (end of trans. blk)     0101 0111   87    57    W
  0001 1000   24    18    CAN (cancel)                0101 1000   88    58    X
  0001 1001   25    19    EM  (end of medium)         0101 1001   89    59    Y
  0001 1010   26    1A    SUB (substitute)            0101 1010   90    5A    Z
  0001 1011   27    1B    ESC (escape)                0101 1011   91    5B    [
  0001 1100   28    1C    FS  (file separator)        0101 1100   92    5C    \  
  0001 1101   29    1D    GS  (group separator)       0101 1101   93    5D    ]
  0001 1110   30    1E    RS  (record separator)      0101 1110   94    5E    ^
  0001 1111   31    1F    US  (unit separator)        0101 1111   95    5F    _
  0010 0000   32    20    SPACE                       0110 0000   96    60    `
  0010 0001   33    21    !                           0110 0001   97    61    a
  0010 0010   34    22    "                           0110 0010   98    62    b
  0010 0011   35    23    #                           0110 0011   99    63    c
  0010 0100   36    24    $                           0110 0100   100   64    d
  0010 0101   37    25    %                           0110 0101   101   65    e
  0010 0110   38    26    &                           0110 0110   102   66    f
  0010 0111   39    27    '                           0110 0111   103   67    g
  0010 1000   40    28    (                           0110 1000   104   68    h
  0010 1001   41    29    )                           0110 1001   105   69    i
  0010 1010   42    2A    *                           0110 1010   106   6A    j
  0010 1011   43    2B    +                           0110 1011   107   6B    k
  0010 1100   44    2C    ,                           0110 1100   108   6C    l
  0010 1101   45    2D    -                           0110 1101   109   6D    m
  0010 1110   46    2E    .                           0110 1110   110   6E    n
  0010 1111   47    2F    /                           0110 1111   111   6F    o
  0011 0000   48    30    0                           0111 0000   112   70    p
  0011 0001   49    31    1                           0111 0001   113   71    q
  0011 0010   50    32    2                           0111 0010   114   72    r
  0011 0011   51    33    3                           0111 0011   115   73    s
  0011 0100   52    34    4                           0111 0100   116   74    t
  0011 0101   53    35    5                           0111 0101   117   75    u
  0011 0110   54    36    6                           0111 0110   118   76    v
  0011 0111   55    37    7                           0111 0111   119   77    w
  0011 1000   56    38    8                           0111 1000   120   78    x
  0011 1001   57    39    9                           0111 1001   121   79    y
  0011 1010   58    3A    :                           0111 1010   122   7A    z
  0011 1011   59    3B    ;                           0111 1011   123   7B    {
  0011 1100   60    3C    <                           0111 1100   124   7C    |
  0011 1101   61    3D    =                           0111 1101   125   7D    }
  0011 1110   62    3E    >                           0111 1110   126   7E    ~
  0011 1111   63    3F    ?                           0111 1111   127   7F    DEL

Thanks to the power of the US Military and US corporations the American computing industry became the global computing industry. Computers that we use today are rooted in American networking history, and so is the ASCII standard. However, the reality is that ASCII can only represent 26 Latin letters in the English alphabet but computers are used all over the world, by people speaking different languages. They would often end up with American computers that could not represent their language in ASCII. Think for example of scripts like Greek, Cyrillic and Arabic or even Latin scripts that use accents such as the ü or ø. Altough 128 might sound like a lot of characters, it is not enough to represent all different languages.[1]

As you can see in the table above, it lists all sorts of characters, also ones that are not represented on our keyboards (like "ESC").

Some of these are legacy characters from a teletype/typewriter past.. Like the "bell" character.

In order to type these characters, like a line feed character (LF), you use the code point representation of that particular character.

For a time people used the 8th bit, numbers 1000 0000 to 1111 1111 (or 128 to 256) to encode the specific parts of their own language. That way there was an overlap with ASCII but the own language could also be encoded.[2]

ASCII exercise

  • take a piece of paper and a pen, and:
    • count to 10 in decimal
    • count to 10 in binary
    • count to 10 in hex

Unicode universalism

The Unicode Standard supports three character encoding forms: UTF-32, UTF-16, and UTF-8. Each encoding form maps the Unicode code points U+0000..U+D7FF and U+E000..U+10FFFF to unique code unit sequences.[3]

Let's explore these code points!

In Python, you can use the chr() function to print Unicode code points. You give it a decimal.

chr(97)

returns: "a"

And if you want to find the code point of a character, you can use ord():

ord("a")

returns: 97

You can explore all the code points, which are organized in code blocks, here:

Unicode exercise

  • let's print U+0000 until U+D7FF and U+E000 until E+10FFFF with python
  • first convert the numbers of the code blocks from hex to decimal
  • then loop through these blocks by printing them

Extra

  • some characters are printed as (so-called) "tofu's".. install a font that has coverage (glyphs) for these characters, like Unifont!
  • find a nice range of code points and make a small terminal animation in python

Model specific printer commands

Each printer comes with a different set of special commands, different character sets and different fonts.

The special commands can change the behavior of the printer (like superscript, bold, alignment, and even loops!).

To switch to italic for instance on the NEC P60, you need to send esc and 4. And to send the esc key in hex in Python, you send: chr(27).

To find these special commands... we need to dive into the specific manual of a printer.

The character set of a printer can be changed, to support different languages. Each printer supports a different range of character sets.

And of course, each printer comes with different fonts installed. And some of them have the option to install extra fonts using a card ridge.

Printer commands exercise

  • pick a dot-matrix printer to work with
  • use the python script below to send a "hello" to the printer
  • find the manual of the printer and find the list of special commands this printer can work with
  • work with the special commands using your python script
    • we can't type these special commands with our keyboards directly, but we can execute them using the hex code points listed in the manual!
    • use chr() and the hex code point and see what they do
  • pick one special command and try to make a prototype with it (use it to draw something, make a playful layout, a mini poem, etc!)
msg = "hello"

# Linux/OSX?
printer = open("/dev/usb/lp1", "w")
printer.write(msg)
printer.close()

# Windows/OSX
import os
printer = open("tmp.txt", "w")
printer.write(msg)
printer.close()
cmd = "lpr tmp.txt"
#cmd = "cat tmp.txt | lp"
os.system(cmd)

Control individual pins

Exciting thing to try one day: There are also special commands to control the individual pins (!).

This means that you can print without using a driver. A driver translates the pixelated image into the pins of the printer.

Here you can find dithering strategies to convert an image into a type of image that could be printed on the dot-matrix printer.

So dithering was a technical limitation. These days, it's often an aesthetic choice, which is different.

Dot-matrix printers @ XPUB

OKI Microline 320

Oki-microline-320.png

Test report 5 Feb 2025:

Joseph and Manetta tried to get this printer to work, we changed the settings to match the NEC printer, but this did not help.

Current intuition is that it is a hardware issue.

NEC PINWRITER P60

Screenshot from 2025-02-05 13-35-48.png

This printer has 21 pins. One is broken, you can see it.

In the back there are magnets, one for each pin, and when the electricity hits the magnet, the pin is being activated or not.

There are 2 rows of pins, one is slightly shifted (you can see it!), which makes the resolution higher. It is divided into 2 rows, because there is no mechanical space to have so many pins so narrowly next to each other in one row.

The printer works with 80 columns.

NEC PINWRITER P20

NEC-Pinwriter-P20.jpg

Running the self test: see page 5 in the manual (page 13 in the pdf)

Printing the menu with current settings: see page 17 in the manual (page 25 in the pdf) [SELECT + Power on]

Citizen Swift 90e

Citizen-swift-90-printer.jpg

The printer works, but the continuous paper feed (for the paper with holes on the sides) is a bit slippery, so you need to help the printer a bit sometimes. If you use the external paper feed adapter and work with A4, it's much smoother.

Did manage to print test pages and the menu! But did not manage to change the settings in the menu... the printer gives an error.

How to print test pages? See page 29 in the manual: Printer Self-Tests.

How to print the menu? See page 25 in the manual: Making A Print Out Of The Printer’s Default Settings.

More info on codepages? See page 32 in the manual: Codepages - International Characters.

Sending printer control commands works when you use the build-in Epson FX1170 emulation (found this in the technical sheet). See Epson FX1170 manual chapter 8 "Command Summary" for a listing of special commands.

Star SG-10

Star-SG-10.jpg

The language in the manual is funny, very conversational :).

You can switch between character sets, "modes" and character pitch (size) using the dip switches. See page 133 in the manual.

The special commands are a bit everywhere in the user manual, but mostly in chapter 5-10, and there is an index of all of them on page 240.

Howto

Printing on OSX

Using CUPS:

  1. Connect the printer with the USB cable
  2. Install the printer with CUPS, go to http://localhost:631 in your browser and select Administration → Add printer
  3. Select "Unknown" in the Local Printers section
  4. You can add a "name" and "location", mostly for yourself, so you can find the printer back later.. "connection" should say something like: usb://USB2.0-Print/
  5. For "make" (which is the manufacturer) you select "Generic" and for "model" you select "Generic Text-Only Printer", click "Add Printer"
  6. Your printer is installed!
  7. Now go to "Printers" and select your printer
  8. Now make this printer your default printer: click on "Administration" and select "Set as server default"
  9. You can now send files to the printer with: $ lpr myfile.txt or $ echo "hello" | lp

Backup option, without CUPS:

  1. Connect the printer with the USB cable.
  2. Go to System Settings → Printers → Add printer
  3. Select the USB one (the printer will start to print stuff, don't worry, you can ignore this)
  4. Choose "General PostScript printer" (even though this is not true!)
  5. Make the printer your default printer
  6. You can now send files to the printer with: $ lpr -o raw myfile.txt or $ echo "hello" | lp -o raw

Printing on Windows

Once installed, you should be able to send files to the printer with:

> lpr myfile.txt

But! This only prints files, not output of commands like echo.. But maybe there is a way.. this might work, it looks like it's worth a try:

Claudio's notes

First things first, I used the "CITIZEN Swift 90e" printer. On Windows I had multiple unexpected errors but after all Joseph helped and we did not end up using lpr but we used the Out-Printer command.

and the final commands were:

cat yourfile.txt | Out-Printer

or to write directly a string avoiding using a file:

"The text you want to print" | Out-Printer

Printing on Linux

Search for the printer by running this command with the USB cable unplugged and plugged:

$ ls /dev/usb/

Mine appears at: /dev/usb/lp2

Then send stuff to the printer by using > /dev/usb/lp2, so for instance:

$ echo "hello" > /dev/usb/lp2
$ cat hello.txt > /dev/usb/lp2

Or, if you install the printer with CUPS and make it the default printer on the system (see above at OSX section), you can use:

$ cat hello.txt | lp
$ lpr hello.txt

ASCII art

jp2a

lightweight tool to convert images into ascii, written by Christian Stigen Larsen

https://web.archive.org/web/20200517095853/https://csl.name/jp2a/

$ jp2a

Examples

Testing the PINWRITER P60 (during SI26)

linefeed = chr(10)
tab = chr(11)
italic = chr(27) + chr(4) # does not work
linespacing_big = chr(27) + chr(48)
linespacing_small = chr(27) + chr(50)
superscript = chr(27) + chr(83) + chr(0)
subscript = chr(27) + chr(83) + chr(1)
condensed = chr(27) + chr(15)
spacing_wide = chr(27) + chr(32) + chr(127) # 0 - 127
loop_start = chr(27) + chr(86) + chr(255) # 0 - 255
loop_stop = chr(27) + chr(86) + chr(0)

# printer = open("NEC_PINWRITER_P60", "w")
printer = open("/dev/usb/lp2", "w")
# printer.write("hello\n")
printer.write(loop_start + "hello " + loop_stop)
# printer.write("hello\n")
printer.close()

Pruning Station with Irmak and Aglaia (SI19)

The magic of scanner, OCR and dotmatrix printer

Pruning Station in progress

See: How_do_We_Library_That???#Pruning_Station_with_Irmak-_The_magic_of_scanner,_OCR_and_dotmatrix_printer

Python script to scan a page from a book, apply OCR (optical character recognition) and print it on the dot matrix printer.

import os
print("starting the pruning process")
scanning = "sudo scanimage --resolution 300 --mode color -o image.png"
os.system(scanning)
os.system("tesseract  image.png text.txt -l eng")
fantasyname = open("text.txt.txt" , "r")
fantasyname = fantasyname.readlines() 
for line in fantasyname: 
    line = line.split(" ")
    for l in line:
        if l!="" or l != ['\n', '\r\n']:            
            print(l)
            os.system("echo '"+l+"' > /dev/usb/lp0")

Related links

Footnotes