Building a Custom GSM Phone: SIM800L, Custom PCB, and No Shortcuts
Published on May 2, 2026 · Hardware, Embedded Systems, PCB Design, GSM
I wanted to build a phone the same way people built them before Apple made it a religion — with components I understand, firmware I wrote, and a PCB I laid out myself. No Android, no proprietary stack. Just a microcontroller, a SIM module, an LCD, and a keypad. The goal: make and receive real calls and SMS on a 2G network.
The SIM800L — Power Gotcha First
The SIM800L is a quad-band GSM/GPRS module that communicates via UART using standard AT commands. Every tutorial online shows it wired to a 3.3V regulator and then wonders why it randomly resets mid-call. The reason: during a GSM transmission burst, the SIM800L can spike to 2A of current draw for milliseconds. A standard AMS1117 or LM3940 linear regulator can't sustain that.
I learned this the hard way. My first prototype with a linear regulator would drop calls the moment it tried to register on the network. Scoping the supply rail showed voltage dipping to under 3.0V during RACH bursts. The fix was a dedicated LM2596 buck converter with a 470µF low-ESR capacitor on the output, sized to handle those transient current spikes without rail sag.
AT Command Protocol — Talking to the Network
Once powered correctly, the SIM800L communicates over UART at 9600 baud by default. Every operation is a request-response cycle over AT commands. The tricky part isn't sending a command — it's handling the unsolicited result codes (URCs) the module sends asynchronously. An incoming call doesn't wait for you to poll; the module just interrupts with RING on the serial line.
Firmware: The Non-Blocking UART State Machine
The core firmware challenge is this: the keypad input, the LCD refresh, and the SIM800L serial buffer all need attention simultaneously. A blocking waitForResponse() call would freeze the UI while waiting for the network. The solution is a non-blocking state machine that processes one character at a time from the UART RX ring buffer per main loop iteration.
This means the phone is always responsive to button presses, even mid-network operation. The RING string in the buffer triggers the display to show the incoming call screen, while ATA\r is queued to be sent on the next answer key press.
The PCB — From Breadboard Chaos to a Real Board
The breadboard prototype worked but was fragile — RF signals don't like long jumper wires, and the SIM800L antenna trace especially needs controlled impedance. Moving to a custom PCB solved this. Key design decisions:
- The SIM800L antenna trace is routed as a 50Ω microstrip line, width calculated from the PCB's FR4 dielectric constant and copper thickness to prevent RF reflection at 850/900/1800/1900 MHz.
- The LM2596 buck converter is placed physically close to the SIM800L supply pins with a short, wide ground plane pour to minimise inductance.
- The TP4056 Li-Po charge controller handles battery charging from USB, with a protection IC for over-discharge cutoff.
- The 4×4 matrix keypad uses direct GPIO with internal pull-ups, scanned row by row on each main loop tick.
The Result
The device makes and receives calls, sends and receives SMS messages, and runs on a 1000mAh Li-Po battery. It's slower than a modern smartphone by every measure, but every layer of it — from the schematic to the firmware state machine to the PCB copper pour — is something I designed, debugged, and understand fully. That's the point.