- DIY
- A
How I get daily news with a dot matrix printer
For a long time now, I start my day by unlocking my phone and scrolling through various news and social media to stay updated. This doesn't reflect well on my mental state and I've been trying to reduce screen time for a while. But I still want to stay informed, especially in the mornings.
For a long time now, I start my day by unlocking my phone and scrolling through various news and social media to stay updated. This doesn't reflect too well on my mental state, and I've been trying to reduce screen time for a while. But I still want to stay informed, especially in the mornings.
Recently, I bought a dot matrix printer on Ebay and thought it was a great opportunity to create my own news summary, printed and ready to read. So that's what I did!
In this article, I'll show what was used, how to set everything up, and the PHP script that manages it all.
“The full code is available in the repository on Github”
Acquiring the hardware
The list of necessary items for this project is relatively small, and except for the printer itself, most of it can be found on Amazon or other online stores.
Dot matrix printer
Raspberry Pi Zero W
USB to Serial adapter
Power supply
The printer I bought is a Star NP-10 from the mid-80s. I can't give a 100% guarantee, but theoretically, any dot matrix printer with a serial port should work. Prices range from $80 to $120, but I managed to grab this one for about half that price because it was marked as "not sure if it works".
Of course, it needed to be cleaned and set up with an ink ribbon cartridge (just like in a typewriter, isn't that cool?), but after that, it started right up and printed a test page.
Then I connected everything together. The Raspberry Pi is connected to WiFi and to the printer's serial port using a USB adapter. After turning on the printer and connecting to the Pi via ssh, you can verify that the printer is available as /dev/usb/lp0
.
So, how do you print on this thing?
Understanding the printer code
Since the printer is available as lp0
, I wanted to check if anything would print if I just sent text to it using echo
. I executed the following command:
echo "Hello, world!" > /dev/usb/lp0
Which gave an error that the file was unavailable. Well, a permission error. This can be easily fixed with chmod
:
sudo chmod 666 /dev/usb/lp0
There might be a more correct way to solve the issue, but after executing the command, I was able to send echo and the text successfully printed on the printer. So, we can send raw data to the printer through this file, so let's try to go further.
I use php for everyday tasks, and this is no exception. I wrote a simple script that opens the file using fopen()
and writes text to it. I tried sending a few sentences, a few blank lines, and some Unicode art, but quickly found that the printer's character support was much less than expected.
It looks like it's time to figure out how it actually works. Thanks to the efforts of people gathering various information, I was able to find a complete manual for the printer in pdf format.
It turned out that either due to the trends of the time or due to certain decisions in production, this printer has a very specific set of supported characters. Roughly based on Code Page 437 for IBM PC, it consists mostly of standard numbers and letters, but also has a small set of special characters, lines, and blocks. Excellent!
Sending these characters is quite simple, you can just use hex values with PHP as follows:
So, we figured out how to print text on our printer, add special characters, and format the text. Now we need to figure out what exactly I want to read in the morning.
Data Collection
I wanted to have 4 sections for my daily summary: weather, stocks, top news headlines, and a few top posts on reddit. After all, this is what I usually check on my phone in the morning.
Also, since the project is experimental, I wanted to avoid unnecessary expenses in obtaining information, ideally avoiding them altogether. Fortunately, there is a wonderful repository on Github with a list of free and public APIs, so I went through it and selected the ones I needed.
The weather is pulled from Open-Meteo, no API key required.
Stock data can be obtained from twelvedata thanks to the free plan.
News headlines are obtained from NYTimes, whose free plan is sufficient for this project.
Posts on reddit are pulled from the free Reddit JSON (but had to spoof the User-Agent).
For each section, I wrote simple PHP code to get the payload from the API endpoint and collect the necessary data into a common array. I only needed information for specific stocks, types of headlines, and subreddits. If any section had no data, the script simply terminates and restarts later.
This can be seen in the news headlines fetching snippet:
The constants NEWS
, NEWSKEY
, and MAXNEWS
are initialized at the beginning of the script for easier editing.
When the script runs, it collects all the information I want to see on paper, but now we need to deal with formatting and sending it to print.
Printing the daily summary
I could just print the title of each section, but that's a bit boring. I wanted to add some style to the project, so I decided to create a block at the beginning containing the current date, day of the week, and the summary title in a nice frame.
It took a bit of calculation, but I managed to get everything working using a combination of the previously mentioned hex values, str_repeat
, and knowing that the width of the printer's page is 80 characters.
Now we just go through each section and print a small header:
And then print the necessary data for the section:
For weather and stocks, I was sure they wouldn't reach the edge of the page, so I just wrote everything in long single lines. The situation is different for news headlines and Reddit posts.
If you just pass a long string to the printer, it is smart enough to split it and continue printing on the next line. But I didn't want it to cut a word in half and move part of it to a new line, so I wrote a small function to handle the string length and return an array of lines with a length not exceeding the page width.
After that, I can use it as follows:
Now all that's left is to run the script!
Usage and Summarizing
I can start printing manually by simply running php print.php
, but instead I set up a cron job that will do it for me.
Every morning around 8 am, my personal summary starts printing. I tear it off and review it in the morning over a cup of coffee.
It may sound silly, but I like having a limited amount of news on one sheet of paper. It gives me the opportunity to finish reading and stop there instead of endlessly scrolling through websites and social media apps.
It was also a very interesting project and I hope I can find more uses for this printer. Using real hardware (especially such vintage ones) always brings me pleasure, and the ability to integrate it with modern technologies or use it in unusual projects ignites interest and reminds me why I got into development in the first place.
Write comment