CALC - SINGLE BUTTON (MORSE) CALCULATOR

CALC - SINGLE BUTTON CALCULATOR

In December everyone is doing 'advent of code', but I thought I will make 'advent of things'. Make something every week, and I thought I will learn a lot by making everyday things that I am taking for granted, my plan was to make a calculator, a wrist watch and a remote controlled car (433mhz). To think deeply about things that have the same design for decades: why are they the way they are?

I only managed to make a calculator.

While making it I thought I would teach my kid some basic electronics, but in the end, I hope I showed her how to be patient. Nothing worked the way I thought it would, I broke like 10 things, burned my hands like 20 times and every proptotype was worse than the previous one.

I also thought I would have a good experience and learnings to share, but I only accumulated scars, so I will just present the versions I made and hope that the next time I will manage to build on top of the scars.


I really wanted to make something so cool that my daughter would use it at school, and since she knows python, I wanted the calculator to be just a python repl. So I needed full functioning keyboard, and I thought I will make one with 8 buttons and chords. I bought a bunch of esp32s from aliexpress (s2, c3, wroom32 etc), and I bought all kinds of voltage regulators, since I wasnt sure if I would manage to power it with cr2032 batteries or I would fit cr123 in the case, or I would use a normal 9v battery. I am complete novice in electronics, so I thought I would just try things out. This is how the first version looked:

V0.0.0 (8 BUTTONS):

It had 8 buttons, most left one is shift, most right is control, the rest are 6 bits used to make 64 characters. The editor is controlled with basic bindings ctrl+n, ctrl+p, ctrl+j etc. Each line was executed with ctrl+r, and its output was printed below. and you could graph things, e.g. if you have x=5; x*9; and then g(1) (which means graph line 1), it will evaluate x*9 from x = -100 to x = 100 and draw its y value
 

V0.0.1 (8 BUTTONS):

Later I decided to use aviator connectors for the cables (for the cool factor) and two epaper displays. On the left display you have the code, and press ctrl + r (which is 00100101) which then is rendered on the second display:

keycodes
ctrl + 
r: run
l: refresh
p: prev line
n: next line
m: new line
a: home
e: end
b: left
f: right
0-9: help

keycodes:
s shift, c ctrl
s000001c: ' '
s110100c: a # A
s000010c: b # B
s000011c: c # C
s011011c: d # D
s000101c: e # E
s000110c: f # F
s000111c: g # G
s001000c: h # H
s001001c: i # I
s001010c: j # J
s001011c: k # K
s001100c: l # L
s001101c: m # M
s001110c: n # N
s001111c: o # O
s010000c: p # P
s010001c: q # Q
s010010c: r # R
s010011c: s # S
s010100c: t # T
s010101c: u # U
s010110c: v # V
s010111c: w # W
s011000c: x # X
s011001c: y # Y
s011010c: z # Z
s000100c: 0 # )
s011100c: 1 # !
s011101c: 2 # @
s011110c: 3 # #
s011111c: 4 # $
s100100c: 5 # %
s100001c: 6 # ^
s100010c: 7 # &
s100011c: 8 # *
s100000c: 9 # (
s100101c: - # _
s100110c: = # +
s100111c: [ # {
s101000c: ] # }
s101001c: ; # :
s101010c: \' # "
s101011c: , # <
s101100c: . # >
s101101c: / # ?
s101110c: ` # ~
s101111c: \ # |
    

Every day I would 3d print a new case and keep experimenting, I would tweak the design in the day, start the print and in 1am I would try it out, it would suck, and in the morning I would start again.

The aviator connectors and the eink display were contributing a lot to the cool factor, but I was upset that my daughter would have to learn a madeup sequences, so then I decided I would use just ASCII as she also knows most of the alphabet's codes, but as I was talking to her she said "why don't you just use morse code", and it got me thinking, what is the minimum amount of buttons you can have on a calculator?

V0.0.2 (ONE BUTTON):

So, yesterday I managed to make it just in time for the new year, and luckily my 3d printer got broken, so I didnt have a choice but to just use a naked board:



Parts (unaffiliated links):

A single calculator costs about 12€, but if you buy all the parts from aliexpress I think you can make it for about 5€.

Schematic:
Software:

By default ESP32's boot is somewhat slow, it has verbose logging enabled and validates the image at boot, so I had to compile micropython myself in order to disable those. This was somewhat annoying as esp-idf is at version 5.5 or something and micropython supports 5.1, but in the end I managed, nothing super suprising, just a bunch of random quirks that I wont even bother to remember and will just scratch my head again the next time I have to do it. I wont even bother to write about it.

How is it possible that every build system is so cursed.

Code: main.py ssd1306.py morse.py
You can copy them to your esp32 (after flashing with micropython) by doing:
micropython/tools/pyboard.py -b 115200 -d /dev/tty.usbmodem101 -f cp main.py :main.py
micropython/tools/pyboard.py -b 115200 -d /dev/tty.usbmodem101 -f cp ssd1306.py :ssd1306.py
micropython/tools/pyboard.py -b 115200 -d /dev/tty.usbmodem101 -f cp morse.py :morse.py

Each of the version had its own UX issues, the first version had only 5 rows, I thought it made sense to evaluate each row instead of the whole buffer, but then you couldnt make 'programs', the second version had a lot of UX issues due to the eink partial refreshing and deep sleep, but in the end it was working pretty ok, it just was kind of clunky, and of course the final version has most of the issues, but it is the coolest one.

Morse code table
----- 0
.---- 1
..--- 2
...-- 3
....- 4
..... 5
-.... 6
--... 7
---.. 8
----. 9
.- a
-... b
-.-. c
-.. d
. e
..-. f
--. g
.... h
.. i
.--- j
-.- k
.-.. l
-- m
-. n
--- o
.--. p
--.- q
.-. r
... s
- t
..- u
...- v
.-- w
-..- x (multiply)
-.-- y
--.. z
.-.-.- .
--..-- ,
..--.. ?
-.-.-- !
-....- -
-..-. /
.--.-. @
-.--. (
-.--.- )
-...- =
.-.-. +
.----. '
-.-.-. ;
..--.- _
.-..-. "
---... :
.-... &
........ ERROR

Its funny that this calculator is more powerul than the first computer I had, which was 133mhz AMD K5, and this esp32 runs at 160mhz :)

My new year resolution is to learn KiCad and FreeCAD and next year, and make many more things!


PS: I am working on those projects to teach myself and my daughter about basic electronics and programming. I made few games and projects that can print yourself:

Programming Time, which is a game to teach python and some more fundamental algorithms, from hash tables to RSA

The C Pointer Game - Pointers, Arrays and Strings, a game to teach kids to look at the computer memory and understand references and values

4917, a game to teach kids machine code and how the CPU works with memory and registers

The Unix Pipes Game, a game to teach kids to use basic UNIX commands: cat, sort, grep, head, tail, wc, uniq

The Unix Pipes Game - Process Substitution, an expansion of the Unix Pipes Game to teach process substitution and also: paste, tr, cut, bc

RunLength Encoding for Kids, small cards "game" to explain runlength encoding

PUNK0 - The Function Composition Card Game, use cards to manipulate a list and use its values to win the game

PROJEKT: OVERFLOW, RISCV assembler boardgame

Programming for kids, a log of my journey of teaching my daughter how to code