Hosting a website on an 8-bit microcontroller

zdw2 pts0 comments

Hosting a website on an 8-bit microcontroller. (Maurycy's blog)

Hosting a website on an 8-bit microcontroller.

2026-05-11 — 2026-05-14 (Electronics) (Programming)

In today's episode of "dumb things to do with an AVR microcontroller":

Does your server come with real wood?

MCU website demo<br>(may go down if this gets posted to HN)

My victim is the AVR64DD32 which is quite similar to the Atmega328 of Arduino fame.<br>Compared to the older Atmega, these AVR DD lines are cheaper for the same memory, use a single programming pin and have nicer peripherals:

CPU:Single 8-bit AVR core @ 24 MHz (max)<br>RAM:8 kB (static RAM)<br>Flash:64 kB<br>EEPROM:256 bytes<br>Voltage:1.8 - 5.5 Volts<br>Cost:$1

So that's the computer (a rather spacious one at that) but it'll need an internet connection to host a website.

The obvious choice is Ethernet, but even the slowest version (10BASE-T) still runs at 10 megabits/second.<br>Worse, it uses Manchester encoding:<br>a zero is sent as "10" and a one as "01", so 10 megabits of data is actually 20 megabits at the wire.

This is simply too fast for the AVR to generate.<br>While it's processor can run at 24 MHz, but all the peripherals and IO pins max out at a 12 MHz clock.<br>(although some other 8-bit chips should be able to do it)

The proper solution is to buy a dedicated ethernet chip from DigiKey, but then I'd be waiting weeks to finish this project.

... and ethernet is far from the only option:

Serial Line Internet Protocol (RFC 1055) is a very old and very simple standard for running networks over serial:

Before sending a packet, wrap it in 0xC0 bytes.<br>If the packet contains any 0xC0 bytes, replace them with 0xDB 0xDC.<br>To avoid ambiguity, any pre-existing 0xDB bytes are replaced with 0xDB 0xDD.

This scheme was widely used for connecting to the internet in the olden days:<br>A dial up modem creates a serial link over a phone line, and it's up the the computer to do anything with it.<br>(This also means that they are not limited to networking:<br>those same modems could be connected to a terminal for remote access)

... which is why SLIP is still supported by modern Linux:

# Just a normal USB to Serial adapter<br>stty -F /dev/ttyUSB0 115200 raw cs8<br>slattach -m -F -L -p slip /dev/ttyUSB0<br># ... and now it's a network interface

The hardware on the microcontroller's end is trivial:

www.c: Source code. www.elf: Prebuilt binary

It does work with no external components, but I wanted some blinkenlights, and an idiot-proofing diode<br>for when I inevitably connect the power backwards.

Because it only draws a few milliwatts, it can run the server of the serial adapter's 5 volt rail:<br>it's really nice to only have one cable to deal with.

Now it has an internet connection, but that's hardly a server.

In order for my web page to get to your computer, it needs to pass through dozens of different networks.<br>To do this, each packet has an IP header:<br>40 bytes that contain the address of the source and destination computers, and some other stuff I don't really care about.

The protocol used to be a lot more complex, with features like packet fragmentation<br>that require a lot of memory to handle correctly, but I don't have to:<br>every modern operating system disables fragmentation and IPv6 removed it entirely.

This makes implementing it very easy:<br>Just swap around the source and destination of a recieved packet to generate the header for the response.<br>(and reset the TTL counter)

The other protocol, TCP is a lot harder:<br>Implementing it requires the microcontroller to track connection states,<br>periodically retransmit lost packets and handle a huge number edge cases.

It took several days to get my custom implementation working well enough, and it's<br>still got a few bugs.

As for implementing HTTP, I didn't:<br>The server always sends a hardcoded "response" back to the client.<br>This works fine as long as there's only a single URL on the site.

[Video of the page loading. See web or files directory: loading.mp4]

Ok great, but what if I want to share it with friends?<br>Unfortunately, for their requests to reach it, it needs a publically routable IPv4 address.<br>Not only are these expensive but it's impossible to get a good internet connection at my place.

(no, Starlink is not good)

I do have a machine with a publically routable address,<br>but it's at a datacenter near Helsinki:<br>I'd need a very long serial cable...

another cool thing Linux supports is wireguard, which creates a virtual network link over the internet.<br>This works even if one of the machines is behind (CG)NAT or other annoyances.

Problem solved:

have the Linux router box connect to the VPS to get a proper internet connection?

... except the MCU still doesn't have it's own IP address:<br>I could forward everything from my VPS's address to it, but that would break my normal website.

Instead, I setup the server to proxy any requests under /mcu to the server using a local address block.<br>This means that visitors aren't directly connecting to the MCU's TCP/IP stack...<br>but hey, it's...

internet website microcontroller server serial address

Related Articles