Compare commits
4 Commits
3c5dc3e0c4
...
c8eb654214
| Author | SHA1 | Date | |
|---|---|---|---|
| c8eb654214 | |||
| c6ee4beb11 | |||
| 1f85f22e7a | |||
| 602932bc00 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -113,3 +113,5 @@ test/
|
|||||||
|
|
||||||
output/
|
output/
|
||||||
.aider*
|
.aider*
|
||||||
|
|
||||||
|
content/.obsidian/workspace.json
|
||||||
|
|||||||
254
content/.obsidian/workspace.json
vendored
254
content/.obsidian/workspace.json
vendored
@@ -1,254 +0,0 @@
|
|||||||
{
|
|
||||||
"main": {
|
|
||||||
"id": "69e9da393623ab60",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "59ed96d9876185c9",
|
|
||||||
"type": "tabs",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "160122bd13ae4b72",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Secret Garden.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
},
|
|
||||||
"icon": "lucide-file",
|
|
||||||
"title": "Secret Garden"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "238ba022d07a7436",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Fake Dog.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
},
|
|
||||||
"icon": "lucide-file",
|
|
||||||
"title": "Fake Dog"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "d9a16803d250ddc4",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Secret Garden.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
},
|
|
||||||
"icon": "lucide-file",
|
|
||||||
"title": "Secret Garden"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "24a62ccdfd18a884",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Secret Garden.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
},
|
|
||||||
"icon": "lucide-file",
|
|
||||||
"title": "Secret Garden"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "1f1f024283ea8110",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Helios Alpha.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
},
|
|
||||||
"icon": "lucide-file",
|
|
||||||
"title": "Helios Alpha"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "60389a84493f7fa2",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "markdown",
|
|
||||||
"state": {
|
|
||||||
"file": "Hydroponics.md",
|
|
||||||
"mode": "source",
|
|
||||||
"source": false
|
|
||||||
},
|
|
||||||
"icon": "lucide-file",
|
|
||||||
"title": "Hydroponics"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"currentTab": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "vertical"
|
|
||||||
},
|
|
||||||
"left": {
|
|
||||||
"id": "3885f82c1ab72e1b",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "0e37795504669957",
|
|
||||||
"type": "tabs",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "e5f5df16367f5f9a",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "file-explorer",
|
|
||||||
"state": {
|
|
||||||
"sortOrder": "alphabetical",
|
|
||||||
"autoReveal": false
|
|
||||||
},
|
|
||||||
"icon": "lucide-folder-closed",
|
|
||||||
"title": "Files"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "15b64333baa0fbc2",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "search",
|
|
||||||
"state": {
|
|
||||||
"query": "",
|
|
||||||
"matchingCase": false,
|
|
||||||
"explainSearch": false,
|
|
||||||
"collapseAll": false,
|
|
||||||
"extraContext": false,
|
|
||||||
"sortOrder": "alphabetical"
|
|
||||||
},
|
|
||||||
"icon": "lucide-search",
|
|
||||||
"title": "Search"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "7bdb31d1bda5b8c9",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "bookmarks",
|
|
||||||
"state": {},
|
|
||||||
"icon": "lucide-bookmark",
|
|
||||||
"title": "Bookmarks"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "horizontal",
|
|
||||||
"width": 200
|
|
||||||
},
|
|
||||||
"right": {
|
|
||||||
"id": "260bba8f76f307a9",
|
|
||||||
"type": "split",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "21c556d6660f839b",
|
|
||||||
"type": "tabs",
|
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"id": "528c8f9657044ea2",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "backlink",
|
|
||||||
"state": {
|
|
||||||
"file": "Custom Air Quality Monitor.md",
|
|
||||||
"collapseAll": false,
|
|
||||||
"extraContext": false,
|
|
||||||
"sortOrder": "alphabetical",
|
|
||||||
"showSearch": false,
|
|
||||||
"searchQuery": "",
|
|
||||||
"backlinkCollapsed": false,
|
|
||||||
"unlinkedCollapsed": true
|
|
||||||
},
|
|
||||||
"icon": "links-coming-in",
|
|
||||||
"title": "Backlinks for Custom Air Quality Monitor"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "79f3ff4100fe3ae6",
|
|
||||||
"type": "leaf",
|
|
||||||
"state": {
|
|
||||||
"type": "outline",
|
|
||||||
"state": {
|
|
||||||
"file": "Custom Air Quality Monitor.md",
|
|
||||||
"followCursor": false,
|
|
||||||
"showSearch": false,
|
|
||||||
"searchQuery": ""
|
|
||||||
},
|
|
||||||
"icon": "lucide-list",
|
|
||||||
"title": "Outline of Custom Air Quality Monitor"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"currentTab": 1
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"direction": "horizontal",
|
|
||||||
"width": 300,
|
|
||||||
"collapsed": true
|
|
||||||
},
|
|
||||||
"left-ribbon": {
|
|
||||||
"hiddenItems": {
|
|
||||||
"bases:Create new base": false,
|
|
||||||
"switcher:Open quick switcher": false,
|
|
||||||
"graph:Open graph view": false,
|
|
||||||
"canvas:Create new canvas": false,
|
|
||||||
"command-palette:Open command palette": false,
|
|
||||||
"markdown-importer:Open format converter": false,
|
|
||||||
"templates:Insert template": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"active": "24a62ccdfd18a884",
|
|
||||||
"lastOpenFiles": [
|
|
||||||
"media/Pasted image 20251003082208.png",
|
|
||||||
"Custom Air Quality Monitor.md",
|
|
||||||
"media/airmonitor3.png",
|
|
||||||
"media/airmonitor2.png",
|
|
||||||
"media/Pasted image 20250622165324.png",
|
|
||||||
"media/airmonitor2.png",
|
|
||||||
"media/airmonitor1.jpg",
|
|
||||||
"Sensors.md",
|
|
||||||
"Protovac Retro Terminal.md",
|
|
||||||
"QotNews.md",
|
|
||||||
"Notica.md",
|
|
||||||
"Spaceport.md",
|
|
||||||
"media/spaceport1.png",
|
|
||||||
"Garage Door Opener.md",
|
|
||||||
"media/protovac1.jpg",
|
|
||||||
"Fake Dog.md",
|
|
||||||
"Bypassing Ports.md",
|
|
||||||
"Backup Strategy.md",
|
|
||||||
"Algae Growth.md",
|
|
||||||
"t0 Services.md",
|
|
||||||
"Solar Car.md",
|
|
||||||
"Protospace.md",
|
|
||||||
"Helios Alpha.md",
|
|
||||||
"Hand of Ozymandias.md",
|
|
||||||
"Airflow.md",
|
|
||||||
"media/protovac1.png",
|
|
||||||
"media/fake-dog.jpg",
|
|
||||||
"media/dress1.jpg",
|
|
||||||
"Acoustic Panels.md",
|
|
||||||
"About.md",
|
|
||||||
"Hydroponics Log 3.md",
|
|
||||||
"Hydroponics Log 2.md",
|
|
||||||
"Hydroponics Log 1.md",
|
|
||||||
"pages/writing.md",
|
|
||||||
"pages/projects.md",
|
|
||||||
"pages/creations.md"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
33
content/Bash Register.md
Normal file
33
content/Bash Register.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
Title: Bash Register
|
||||||
|
Date: 2026-01-25
|
||||||
|
Category: Creations
|
||||||
|
Summary: An old cash register with a thermal receipt printer.
|
||||||
|
Image: bash-register1.jpg
|
||||||
|
Tags: feed
|
||||||
|
Guid: 6836532b386642b9879f71f08e5d821f
|
||||||
|
|
||||||
|
The Bash Register is an old cash register that my friend and I stuck a Raspberry Pi Linux computer into. It's connected to a thermal receipt printer that prints images sent from the member portal [[Spaceport]] running at my local makerspace, [[Protospace]].
|
||||||
|
|
||||||
|
![[bash-register1.jpg]]
|
||||||
|
|
||||||
|
Protospace members are able to draw images on the portal:
|
||||||
|
|
||||||
|
![[bash-register2.jpg]]
|
||||||
|
|
||||||
|
Draw controls include colour, eraser, size, shade, undo history, and reset. The current drawing is stored in local storage so it doesn't get lost if the user accidentally navigates away.
|
||||||
|
|
||||||
|
Once a drawing is submitted, its filename is sent to the Raspberry Pi via MQTT. A simple [Python script](https://git.tannercollin.com/tanner/bashregister/src/branch/master/main.py) listens for the message and then immediately downloads and prints it.
|
||||||
|
|
||||||
|
All drawings are added to a gallery that can be publicly viewed [here](https://my.protospace.ca/gallery):
|
||||||
|
|
||||||
|
![[bash-register3.png]]
|
||||||
|
|
||||||
|
## Printing Garbage Bug
|
||||||
|
|
||||||
|
While developing the code, I was having an issue where every second print would output several inches of garbage characters instead of the image. After hours of debugging it seemed related to the height of the image being printed. I used `git bisect` to narrow it down to a commit where the canvas's height was changed.
|
||||||
|
|
||||||
|
It turned out to be a bug with the printer that happens when printing images with a height that's a multiple of 96 pixels tall:
|
||||||
|
|
||||||
|
<https://github.com/python-escpos/python-escpos/issues/367>
|
||||||
|
|
||||||
|
The fix for this was simply adjusting the aspect ratio of the canvas on the portal.
|
||||||
BIN
content/media/bash-register1.jpg
Normal file
BIN
content/media/bash-register1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 236 KiB |
BIN
content/media/bash-register2.jpg
Normal file
BIN
content/media/bash-register2.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
BIN
content/media/bash-register3.png
Normal file
BIN
content/media/bash-register3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 316 KiB |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block meta %}
|
{% block meta %}
|
||||||
<title>{{ article.title|striptags }} | t0.vc</title>
|
<title>{{ article.title|striptags }} | t0.vc</title>
|
||||||
<link rel="canonical" href="https://tannercollin.com/{{ article.slug }}/" />
|
<link rel="canonical" href="https://tanner.vc/{{ article.slug }}/" />
|
||||||
{% if article.date %}
|
{% if article.date %}
|
||||||
<meta name="date" content="{{article.date}}" />
|
<meta name="date" content="{{article.date}}" />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -50,10 +50,6 @@
|
|||||||
height: auto;
|
height: auto;
|
||||||
color-scheme: light;
|
color-scheme: light;
|
||||||
}
|
}
|
||||||
.floated {
|
|
||||||
float: left;
|
|
||||||
margin-right: 1rem;
|
|
||||||
}
|
|
||||||
@media screen and (min-width:63rem) {
|
@media screen and (min-width:63rem) {
|
||||||
.content .aside {
|
.content .aside {
|
||||||
display: inline;
|
display: inline;
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ Lead Hardware Engineer - Critical Control, '16-'18
|
|||||||
Electrical Engineer - Pivotal Aero, '16-'16
|
Electrical Engineer - Pivotal Aero, '16-'16
|
||||||
BSc Electrical Engineering - University of Calgary
|
BSc Electrical Engineering - University of Calgary
|
||||||
|
|
||||||
Blog
|
Creations
|
||||||
|
|
||||||
<a href=6>Makerspace Tours
|
<a href=3>Bash Register
|
||||||
<a href=p>Bypassing ISP Blocked Ports
|
<a href=0>Protovac Terminal
|
||||||
<a href=j>Japan Photography
|
<a href=7>Fake Dog for Home Security
|
||||||
<a href=h>Hydroponics
|
<a href=5>Garage Door Opener Hack
|
||||||
<a href=x>[more]</a>
|
<a href=z>[more]</a>
|
||||||
|
|
||||||
Projects
|
Projects
|
||||||
|
|
||||||
@@ -28,10 +28,10 @@ Projects
|
|||||||
<a href=n>Notica
|
<a href=n>Notica
|
||||||
<a href=y>[more]</a>
|
<a href=y>[more]</a>
|
||||||
|
|
||||||
Creations
|
Blog
|
||||||
|
|
||||||
<a href=7>Fake Dog for Home Security
|
<a href=h>Hydroponics
|
||||||
<a href=5>Garage Door Opener Hack
|
<a href=j>Japan Photography
|
||||||
<a href=3>Theatre Acoustic Panels
|
<a href=p>Bypassing ISP Blocked Ports
|
||||||
<a href=0>Wine Crate Coffee Table
|
<a href=6>Backup Strategy
|
||||||
<a href=z>[more]
|
<a href=x>[more]
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p class="footer">
|
<p class="footer">
|
||||||
<span class="wname">Webring:</span> <a href="https://nice42q.de/" class="wprev">< Previous</a> | <a href="https://webring.t0.vc" class="windex">Index</a> | <a href="https://udia.ca" class="wnext">Next ></a>
|
<span class="wname">Webring:</span> <a href="https://www.rottenwheel.com" class="wprev">< Previous</a> | <a href="https://webring.t0.vc" class="windex">Index</a> | <a href="https://udia.ca" class="wnext">Next ></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="xxiivv">
|
<p class="xxiivv">
|
||||||
|
|||||||
@@ -156,9 +156,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.content img {
|
.content img {
|
||||||
width: 100%;
|
max-width: min(100%, 36rem);
|
||||||
max-width: 36rem;
|
max-height: 36rem;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
width: auto;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user