A calculator which uses RPN instead of infix notation
The PCBs arrived, I've uploaded photos to the project page. They arrived in a small parcel lined with bubble wrap, with the 5 boards held together with an elastic band. they were well protected and I cant see them easily being damaged in transit.
The quality of the solder mask and silkscreen was better than expected, with most every detail retained. The only silkscreen issue was the point of an exclamation mark, which i expected to be cut out and wasn't shocked by. The major issue i took with PCBWay is that they dont calculate your price VAT inclusive, and indeed, they dont pay VAT or import tax. In retrospect, this makes some sense, but it was dissapointing to be handed an URGENT letter from DHL requesting $18 in taxes, plus an $11 fee on DHLs part to handle the tax payment. this reduced the economy of the boards, but in larger quantities and with foreward knowledge of the situation, I imagine it can be avoided. It does feel like a kick in the teeth though. I have assembled a single board, and have discovered some hardware issues, luckily all of them easy enough to remedy.
i began my PCB layout by creating a footprint for the screen. the 'correct' method would be to create a part in altium, but since this part consisted of just 4 mounting holes and a header, i decided to use a header part and 4 Via holes, and just lock them in place.
that set the width constraint for the design, so my next step was to arrange the buttons.
I made sure to hide the ref-designators under the button area, so as to keep the silkscreen clear for the button functions (in the screencap they are all SWX_1 because i copied the buttons to a blank area of the screen)
I then arranged the components roughly on the board. Note the light blue traces are on the bottom side of the PCB, and the red holes are plated vias from top to bottom.
I wanted to keep all the components on the bottom face, so that the battery would fit in the gap between the screen, to keep it safe.
i then fit the smaller passives around the device, and began routing. there was nothing incredibly eventful about the routing, bar the fact that i realised i would need a way to flash a bootloader to the Atmega (bootloaded Atmega's are super expensive, and i might try using optiboot). To that end i had to add a single pad, as most of the bootloading pins are broken out over the screen connection. I should hopefully be able to bootload the Atmega without too much stress.
when laying out the silkscreen, I took care to ensure the text was centred around the middle of the switch. I had to get creative with some of the symbols, the altium silkscreen text seems to only support certain character sets, so the root symbols are actually comprised of a few segments of PCB trace, shifted to the overlay layer.
I originally was planning to use OSHPark to order these PCBs, but in the end i went for PCBWay, due to the lower cost and better selection of copper mask colors. I picked black with white silkscreen, and used all the other default options for substrate, thickness, coating, etc..
I'm impressed with the level of detail that seems to be present in their production process, they have a tracker online that informs you exactly where your PCB is in the factory.
In my last post i explained the project, and my choice in MCU, display, and button count. In this log, I'll run through the more intricate parts of the component selection, and how i laid them out as a schematic.
I used Altium CircuitStudio to design this circuit. I use Altium proper at work, and the familiar layout is convenient. I began by laying out a minimum viable circuit for the Atmega328P-AU . the minimum requirement is simply a voltage supply between 1.8-5V, a pull-up resistor on the reset pin (pin 11), and a crystal oscillator with 2 20pF capacitors. The crystal is strictly optional, but since this chip may have to run at a lower frequency for efficiency purposes, and since i need to be able to load the bootloader onto the device, I do need an external crystal (you can't install the bootloader using the internal oscillator, and bootloaded Atmega328p's are expensive). I also added a 1uF capacitor on the voltage rail. this may be insufficient and I may have to add additional capacitance.
I then added the FT232RL chip for converting USB signals to UART signals to program the Atmega. The observant of you will note that this is (pretty much verbatim) the circuit for an Arduino board. I used a genuine FT232RL instead of the cheaper CH340 used on some Arduino clones, since i wanted this to be easy to reprogram.
I attached the Tx and Rx lines to the Atmega via 1k resistors to pins PD1/PD0 (pins 31 and 30).
I now needed a USB port. I chose micro-USB despite wanting to use USB C since USB-B is easier to layout and compatible with the arduino nano profile on the arduino IDE.
I then needed to design my button array. I originally designed around these style of buttons to be arranged at 45 degree angles on the board. I gave this idea up after thinking about it and deciding that it may lead the buttons to flex along their longest axis when pushed hard. I went for the slightly larger 4 pin buttons for extra stability.I laid these buttons out in a 5*5 array to be multiplexed
You'll notice the R and C wires (rows and columns), which connect to 10 IO pins on the Atmega. The 1k resistors are overkill probably, but I can always adjust the value later on. The basic principle here is that C1 through C5 will be outputs, and one of them will be on at a time. R1 through R5 will be inputs (pulled down on the Atmega328), and in order to scan the button array, C1 will be drawn high, and the R pins will be read, then this will be repeated with C2 through C5 in order to determine which switches are on. Multiplexing is a useful way to drastically reduce the amount of IO needed. in this case, i save 2.5X as much IO.
I then reached a pretty interesting issue, which is, how can you safely battery power a device? i took inspiration here from Adafruit, in the form of their battery range. they have a wide selection of small Li-Ion batteries, which feature protection circuitry on the battery, preventing over and under-voltage, and over-current situations. this allows you to use the battery as a simple power source, without too much worry about it exploding. The issue then is charging the battery, and again, Adafruit comes through with a solution. they have a reference design for a single cell lithium charging system. I followed the reference design to some extent.
In my design, the value of R10 is set at 4k, as in the datasheet, it defines the formula for setting the charge current. I decided to use a 500mAh battery, and during a regular charge cycle it expects 0.1C current (500mAh * 0.1 = 50mA). A fast charge can run safely at 1C. I decided on a compromise of 0.5C (250mA). this can easily be adjusted by varying R10 if this proves unsafe.
BATSTAT is a tri-state pin, which can be driven either disconnected, high, or low. I pulled it up to VCC and attached it to an IO pin on the atmega
via a 1k resistor. This pin indicates the state of charging. to put it simply, low voltage indicates...Read more »
I'm making this project log a little late. I decided that none of the calculators i use regularly (FX-83GT, NatSciCalc for android, and Windows calculator) did everything i wanted from a calculator, and i found myself reaching for a notebook to write my calculations out by hand.
It's difficult to think of everything you'd like from a calculator in one go, so the first specification is that it must be reprogrammable, and easily so at that. I wanted to use RPN (Reverse Polish Notation), as it can make you faster and less prone to errors, as well as allowing you to easily use lots of memory variables temporarily. With these two specifications in mind i started to hash out a design.
Initially, i decided on a rough estimate of the number of buttons I needed. I used an FX-83GT calculator, counted how many buttons i used regularly, and then added a couple buttons for redundancy. That said, i wanted every button to have two purposes, activated by a 'Mod' key that toggled in a second feature set. I arrived at 25 buttons, for up to 48 functions.
With this in mind, i knew i needed at least 10 IO pins. 5 row drivers, 5 column drivers.
I was initially drawn to the Atmega328p, the trusty tool of any DIY and hobbyist electronics engineer. I also briefly considered the ESP32, another system i am familiar with, and whilst i decided against it for now, due to the difficulty in hardware layout and the slightly less developed and more fragmented toolchain, i may well come back to it if i find the Atmega running out of processing steam.
As an aside, it may seem sort of blasé to use the most mundane, generic IC on the planet as my MCU, but it's important that this calculator is reprogrammable, and there's arguably no easier chipset to layout and program than the Atmega328. Besides this, I think it will have the necessary capability to drive this calculator.
With that out of the way, I needed to select a screen. I originally wanted to use the HP 6064 bubble display, maybe 2 or 3 of, but decided this wouldn't provide enough visual feedback, and would offer limited options for reprogramming. I also researched e-ink displays and found the refresh rate was severely worse than I anticipated.
I began scouring Amazon and farnell. for an individual engineer, it was desirable to find a screen with a daughter PCB and headers to allow easy integration into the device, at least initially. Maybe going forward I would switch to a bare mounted OLED on the main PCB. I didnt have too many constraints on the OLED itself, and indeed it became the driving factor for the size of the device, which I was happy about.
I found this 1.5" 128*128 OLED, and decided it hit all the marks. I especially liked that it had standoffs that would allow me to mount it safely on the main PCB. It runs on 4 wire SPI, so i only need the extra 4 wires on the Atmega328.
That's all for now, I'll update soon with the more detailed component selection and the schematic capture!