Revive Retro Tech: Building a Daily News Display with a Dot Matrix Printer

Like many, my mornings often began by reaching for my phone and diving into the endless scroll of news and social media. Recognizing the impact this had on my mental well-being and wanting to reduce screen time, I sought a different approach to staying informed, especially in those crucial first hours of the day. That’s when the idea struck: what if I could use a Dot Matrix Printer, a piece of technology from a bygone era, to create a custom, physical “front page” of news and information each morning? This project was born from a desire to blend retro charm with modern information consumption, and it turned out to be a surprisingly effective and enjoyable way to get my daily updates.

Printer ASMR noises in the video below 👇

[Insert Video Placeholder – Unfortunately, as a text-based AI, I cannot directly embed videos. In a real markdown context, you would use the appropriate video embed code here if available from the original.]

This article will walk you through the journey of setting up this project, detailing the hardware I used, the setup process, and the PHP script that brings it all to life.

Eager to dive into the code? The full source code is available on the GitHub repo!

Gathering the Hardware for Your Dot Matrix Printer Project

The parts list for this project is refreshingly concise. Aside from the star of the show – the dot matrix printer – most components are readily available from online retailers like Amazon.

  • Dot matrix printer
  • Raspberry Pi Zero W [link]
  • Serial to USB adapter [link]
  • Power supply

For the printer itself, I opted for a Star NP-10, a model that hails from the 1980s. While the exact model isn’t critical, the key is to find a dot matrix printer equipped with a serial port. Prices can vary, typically ranging from $80 to $120 USD, but patience and a bit of eBay hunting allowed me to snag mine for around half that price, even though it was listed with an “unsure if working” status.

Alt text: A vintage Star NP-10 dot matrix printer, highlighting its classic 80s aesthetic and the serial port essential for connecting to modern systems.

Upon arrival, a little cleaning and some adjustments to the ink ribbon cartridge – a wonderfully nostalgic element reminiscent of typewriters – were all it took to get it running smoothly. It powered up and printed a test page without a hitch.

Setting up the connections was straightforward. The Raspberry Pi Zero W, connected to my home WiFi network, interfaces with the printer’s serial port via the USB adapter. After powering on the printer and accessing the Raspberry Pi via ssh, I confirmed that the printer was recognized and accessible at /dev/usb/lp0.

But the question remained: how do I actually make this dot matrix printer print?

Decoding the Dot Matrix Printer Language

My initial approach was to see if simply sending raw text to the printer’s device file would work. I tried the command:

echo "Hello, world!" > /dev/usb/lp0

Unfortunately, this resulted in a “permission denied” error. A quick fix using chmod resolved this:

sudo chmod 666 /dev/usb/lp0

While there might be more elegant solutions to permission management, this allowed my echo command to go through, and to my delight, “Hello, world!” appeared on the dot matrix printer output! This confirmed that I could indeed send raw data to the printer through this file, paving the way to scale up the project.

Being most comfortable with PHP, I chose it for scripting. A simple script using fopen() to access the device file and write text was my next step. Experimenting with sentences, spacing, and even some unicode art, I quickly encountered a limitation: the printer’s character support was not as extensive as what I was sending.

Alt text: Output from the dot matrix printer demonstrating character encoding issues when attempting to print unsupported characters.

It became clear that understanding the printer’s inner workings was crucial. Thanks to the invaluable resources of online archives and dedicated individuals, I discovered a scanned PDF of the full user manual for the Star NP-10 printer.

Delving into the manual revealed that, likely due to its age and manufacturing choices, this dot matrix printer operates with a very specific character set. Closely resembling IBM PC’s Code Page 437, it primarily supports standard alphanumeric characters, along with a limited set of special symbols, line drawing characters, and boxes. Intriguing!

Sending these supported characters is straightforward. PHP allows you to output hex values directly, like this example:

<?php
$horizontalDouble = "xCD";
$deg = "xF8";

echo str_repeat($horizontalDouble, 24);
echo '78' . $deg . 'F' . PHP_EOL;
?>

With the ability to send text and special characters within the printer’s supported range, the next step was to decide on the content for my daily front page.

Fetching and Curating Daily Data Feeds

I envisioned four key sections for my personalized daily briefing: weather, stock market updates, major news headlines, and a selection of trending Reddit posts. These categories mirrored my typical morning phone check.

To keep the project cost-effective, I aimed to utilize free data sources whenever possible. The public-apis GitHub repository, a fantastic collection of free and public APIs, proved to be an invaluable resource. I explored this repository to identify suitable APIs for each section.

For each data section, I developed basic PHP code to retrieve data from the chosen API endpoint and extract the specific information I wanted to display. I focused on particular stocks, news categories, and subreddits. To ensure data integrity, the script includes error handling: if any section fails to retrieve data, the script gracefully exits, preventing a partial or incomplete printout and allowing for a retry later.

Here’s a snippet illustrating the news headline fetching process:

<?php
// Get news headlines data
echo "Fetching news headlines data..." . PHP_EOL;
$newsUrl = NEWS . "?api-key=" . NEWSKEY;
$newsData = [];
$newsAmount = 0;

$data = json_decode(file_get_contents($newsUrl), true);

if (!isset($data['results'])) {
    die("Unable to retrieve news data");
}

foreach ($data['results'] as $article) {
    if (
        ($article['type'] === 'Article') &&
        (in_array($article['section'], ['U.S.', 'World', 'Weather', 'Arts'])) &&
        ($newsAmount < MAXNEWS)
    ) {
        $newsData[] = $article;
        $newsAmount++;
    }
}
?>

In this code, NEWS, NEWSKEY, and MAXNEWS are constants defined at the beginning of the script for easy configuration.

Running these data-gathering scripts compiles all the necessary information into an array, ready for formatting and printing. The next challenge was to translate this data into a visually appealing format suitable for the dot matrix printer and send it as raw data.

Formatting and Printing Your Personalized Front Page

While simply printing section headings would be functional, I wanted to add a touch of visual appeal. I decided to incorporate a bordered box at the top of the page to display the current date, day of the week, and the name of my custom “newspaper.”

Achieving this required some careful calculation and leveraging the dot matrix printer’s 80-character page width limit, combined with the hex character codes for box drawing and line characters. By combining these elements with PHP’s str_repeat function, I was able to create the desired bordered header.

For each section, I printed a concise heading, like this example for weather:

<?php
echo str_repeat($horizontalSingle, 3) . " WEATHER " . str_repeat($horizontalSingle, (PAGEWIDTH - 9)) . "n";
?>

Then, the relevant data for that section was printed below the heading. For weather and stock information, which tended to be shorter, single-line outputs, I could print directly:

<?php
echo "".round(($weatherData['daily']['daylight_duration'][0] / 3600), 2)."h of Sunlight - Sunrise: ".date('g:ia', strtotime($weatherData['daily']['sunrise'][0]))." - Sunset: ".date('g:ia', strtotime($weatherData['daily']['sunset'][0])).PHP_EOL;
?>

However, news headlines and Reddit post titles often exceeded the page width. While the printer would automatically wrap long lines, I wanted to implement word wrapping to prevent words from being split mid-line. To address this, I created a function called splitString:

<?php
function splitString($string, $maxLength = PAGEWIDTH) {
    $result = [];
    $words = explode(' ', $string);
    $currentLine = '';

    foreach ($words as $word) {
        if (strlen($currentLine . $word) <= $maxLength) {
            $currentLine .= ($currentLine ? ' ' : '') . $word;
        } else {
            if ($currentLine) {
                $result[] = $currentLine;
                $currentLine = $word;
            } else {
                // If a single word is longer than maxLength, split it
                $result[] = substr($word, 0, $maxLength);
                $currentLine = substr($word, $maxLength);
            }
        }
    }

    if ($currentLine) {
        $result[] = $currentLine;
    }

    return $result;
}
?>

This function takes a string and a maximum line length as input and returns an array of strings, where each string represents a line wrapped to fit within the specified length. I then used this function to print news headlines and Reddit posts:

<?php
foreach (splitString($redditPost) as $line) {
    fwrite($printer, $line) . "n";
}
?>

With all the formatting and data handling in place, the final step was to run the script and witness the dot matrix printer in action!

Usage and Wrapping Up

While I can manually trigger the printing process by running php print.php, I opted for automation using a cron job.

Set to run every morning around 8 am, the cron job automatically generates and prints my personalized front page. Each morning, I tear off the freshly printed sheet and enjoy reading it while having my coffee.

Alt text: Sample output from the dot matrix printer project, showcasing a neatly formatted daily news summary printed on continuous form paper.

It might sound whimsical, but there’s a genuine satisfaction in having a finite, tangible summary of information on a single sheet of paper. It provides a defined endpoint, a point of completion, unlike the endless feeds of websites and social media apps.

Beyond its practicality, this project was incredibly enjoyable. Working with physical hardware, especially vintage technology like this dot matrix printer, is always a rewarding experience. Integrating it with modern technology and finding creative new uses reignites the passion that drew me to programming in the first place.

So, what are your thoughts? If you have any project ideas inspired by this, or any questions or comments, I’d love to hear them! Connect with me on Twitter to continue the conversation.

My Newsletter

Read sample

Subscribe using the form below and about 1-2 times a month you’ll receive an email containing helpful hints, new packages, and interesting articles I’ve found on PHP, JavaScript, Docker and more.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *