Desk command slab

A tiny desk brick with three pages: a clock, today's weather, and a message you type on your phone. Print three parts, click in an ESP32-C6 screen, and learn how gadgets join Wi-Fi, serve a web page and read the weather.

DifficultyIntermediate
Build time1h 10m
Est. cost$20
Parts4
Files8
Steps13

Things you'll need

QtyPartType
1
Waveshare ESP32-C6-LCD-1.47 board
Waveshare ESP32-C6-LCD-1.47 board The brain, the Wi-Fi and the screen in one board. 1.47-inch colour LCD, USB-C, and a tiny BOOT button that does everything.
electronics
3
Printed stand parts
Printed stand parts Head, wedge base and kickstand foot. All three are in the 3MF below. No supports, no glue.
printed
1
USB-C data cable Powers the board and loads the program. It must be a data cable, not a charge-only one.
electronics
25 g
PLA filament Any colour. The photos show black, with a carbon-fibre-look filament for the head.
consumable

Tools & software

1
Chrome or Edge browser Loads the program onto the board straight from this page. Nothing to install.
1
Phone or laptop with Wi-Fi To join the slab's own DeskCommand network and type a message.
1
Arduino IDE (optional) Only needed if you want to add your home Wi-Fi or change the code. See 'Level up' at the end.

Files & downloads

Download all

Flash writes a precompiled image over USB-C in Chrome or Edge. The .ino below is the source — you do not need Arduino IDE unless you want to change the sketch.

What you're building

A three-page desk brick. Page one is a clock. Page two is today's weather. Page three is a message you type on your phone, and it pops up on the little screen.

No soldering. No wires. Print three parts, drop in the board, push the parts together, plug in one cable, and click one button on this page to load the program.

Note

The program ships with empty Wi-Fi on purpose. So the slab makes its own little network called DeskCommand, and the message page works anywhere, even with no internet. The clock and the weather only go live once you add your home Wi-Fi in Level up at the end. Until then the clock shows a placeholder time and the weather shows a sample day.

What you'll learn

  • How one button can flip between three pages
  • The difference between joining Wi-Fi and being the Wi-Fi (a hotspot)
  • What a tiny web server does, and what GET and POST mean
  • How a weather API hands your program numbers as JSON
  • How a clock sets itself from the internet with NTP

Meet the parts

The three printed stand parts and the ESP32-C6 board laid out on a cutting mat
Everything you need: three printed parts and one board.
  1. Head: the frame the board drops into. One end is cut away for the USB-C plug and the two tiny buttons.
  2. Wedge base: the block with a pocket on top. The head sits in it.
  3. Foot: the small wedge with a tab. It pushes into the back of the base like a kickstand.
  4. The board: a Waveshare ESP32-C6 with a 1.47-inch screen. Brain, Wi-Fi and display in one. No touch: BOOT is the only button.
Tip

Pick your own colours. The photos show black PLA, with a carbon-fibre-look filament for the head. Three parts means you can mix three colours, or print it all in one.

Note

Before you start. The printer does about 2 hours of work on its own. You do about 10 minutes of pushing parts together and 2 minutes of loading the program. No tools needed. To send yourself a message you'll want a phone or laptop with Wi-Fi.


Part 1: Print

Three small parts, one file. Start the printer, then come back for Part 2 while it works.

1

Download the 3MF

Grab Stand (3MF) from Files & downloads above and open it in Bambu Studio, OrcaSlicer or PrusaSlicer, then press Arrange. Other slicer? Open the STL instead and use Split to objects.

Download the 3MF
2

Pick colours and print

Lay each part on its flattest face: head screen-side down, base pocket up, foot on its flat side. Use 0.2 mm layers, 3 walls, 15% infill. You should not need supports.

3

Check the parts

Look at the pocket on top of the base and the slot in its back: both must be clear of strings. Test-fit the foot's tab in the slot before you put the board in.


Part 2: Put it together

No glue, no screws. Everything pushes together. If a part feels tight, wiggle it; never force it.

1

Drop the board into the head

Screen facing the window, USB-C port toward the end that is cut away. Press the edges until the board sits flat. The two tiny buttons (BOOT and RESET) stay reachable at that end.

Drop the board into the head
2

Sit the head on the base

The head drops into the pocket on top of the wedge base. Screen toward the sloped side, so the USB-C hole ends up on your right when the screen faces you.

Sit the head on the base
3

Push the foot in

Turn it round. The foot's tab lines up with the slot on the back of the base. Push it in (yellow arrow) until it sits flat. It works like a kickstand: the slab leans back so the screen faces you.

Push the foot in

Part 3: Load the program

The board arrives empty. You are going to copy the slab program onto it from this web page. That takes about a minute.

Note

Word to know: flash. Flashing means copying a program onto a chip. The chip keeps it even when unplugged, like saving a game.

1

Plug in

Connect the USB-C cable from the side of the head to a computer (Windows, Mac, Chromebook or Linux). Remember: a data cable, not a charge-only one.

2

Click Flash to board

Scroll up to Files & downloads and click Flash to board. Use Chrome or Edge. Pick the port that appears, click Install, and wait for the green tick.

3

Watch it wake up

The screen shows CLOCK, a time and a date under a blue bar. The time is a placeholder until the slab is online (Lesson 5). It starts tall: hold BOOT about a second and it turns sideways to fit the stand.

Watch it wake up
Tip

No port in the list? Hold BOOT, tap RESET, let go of BOOT, then click Flash again. On a Mac the port is usually called usbmodem. Phones and Safari can't flash; use a computer.


Play it

Four things to try, in order.

1

Short press BOOT = next page

Clock → weather → message → back to clock. Watch the little light on the back of the board too: blue for clock, cyan for weather, amber for message.

Short press BOOT = next page
2

Hold BOOT = turn it round

Hold for about a second. The picture flips between tall and wide. The slab remembers your pick even after you unplug it.

3

Send yourself a message

On a phone, open Wi-Fi settings and join DeskCommand (no password). In the browser open http://192.168.4.1, type something (up to 140 letters) and tap Show on slab. The message page pops up with an amber countdown.

Send yourself a message
4

Watch it come back

After 60 seconds the slab returns to the page you were on. In a hurry? One short press of BOOT skips ahead right away.

Warning

The hotspot has no password. That's fine at home or in a classroom. Don't leave it running in a public place: anyone nearby could join DeskCommand and post a message to your desk.


How it works: five tiny lessons

You don't need to read the whole program (it's in Files & downloads if you're curious). Each lesson below shows the one small piece of code that does the job, and gives you something to try.

Lesson 1: One button, three pages

A page is just a number: 0 is the clock, 1 is weather, 2 is message. A short press adds 1. When the number reaches 3 it has nowhere to go, so the program uses % (the remainder after dividing) to wrap it back to 0. That one line is why the pages go round in a circle.

desk-command-slab.ino
enum Page { PAGE_CLOCK = 0, PAGE_WEATHER = 1, PAGE_MSG = 2, PAGE_COUNT = 3 };

static void nextPage() {
  msgHoldUntil = 0;                          // a new page cancels the message timer
  page = (Page)((page + 1) % PAGE_COUNT);    // 0 -> 1 -> 2 -> 0 -> ...
  dirty = true;                              // ask for a redraw
}

From nextPage(). (2 + 1) % 3 is 0, so page 2 wraps back to page 0.

Tip

Try it: press BOOT three times slowly and say the page number out loud each time: 1, 2, 0. Now imagine PAGE_COUNT was 2. Which page could you never reach?

Lesson 2: Joining Wi-Fi vs being the Wi-Fi

A Wi-Fi chip can do two jobs. Station: join someone else's network, like your phone at home. Access point (a hotspot): be the network, so other devices join you.

The slab tries to join for 8 seconds if you gave it a network name. If that fails, or the name is empty, it becomes DeskCommand. Good engineering: always have a way in.

desk-command-slab.ino
#define WIFI_SSID     ""              // empty = don't join anything
#define WIFI_PASSWORD ""
#define AP_SSID       "DeskCommand"   // the name of the slab's own network

// if WIFI_SSID is not empty: WiFi.begin(...) and wait up to 8 seconds
// joined?      -> set the clock from the internet, fetch the weather
// not joined?  -> WiFi.softAP("DeskCommand")   (no password)

Simplified from setupWifi(). Station = join a network. Soft-AP = be the network.

Tip

Try it: type status in the Serial Monitor (see Secret commands below). With empty Wi-Fi it answers AP 192.168.4.1. That is the slab's address on its own little network.

Lesson 3: Your first web server

A web server is a program that waits for a browser and answers. You don't need a big computer; the slab is enough.

GET / means 'show me the form'. POST /msg means 'here is a message, please display it'. POST is how a browser sends data. That same pair runs every login box and comment form on the real web.

desk-command-slab.ino
WebServer server(80);                        // 80 is the normal door for web pages

server.on("/",    HTTP_GET,  handleRoot);    // "show me the form"
server.on("/msg", HTTP_POST, handleMsg);     // "here is a message"
server.begin();

From setup(). handleRoot() sends the little HTML form; handleMsg() reads the text box and shows it for 60 seconds.

Tip

Try it: after you send a message, look at the browser's address bar. It ends in /msg. You just POSTed. Tap Send another to GET the form again.

Lesson 4: Weather is someone else's JSON

Once on your Wi-Fi, the slab asks Open-Meteo, a free weather service, for the conditions at one spot on the map (a latitude and a longitude). The answer comes back as JSON: text with labels and numbers. The program reads four of them: temperature, humidity, a weather code and wind. It asks again every 15 minutes.

Until the first answer arrives you see the built-in sample: 52°F, partly cloudy.

desk-command-slab.ino
// GET https://api.open-meteo.com/v1/forecast
//   ?latitude=41.8781&longitude=-87.6298
//   &current=temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m
//   &temperature_unit=fahrenheit&timezone=auto

JsonObject cur = doc["current"];
weatherTemp = cur["temperature_2m"] | 0.0f;   // read one field out of the JSON
weatherCode = cur["weather_code"]   | 0;

Simplified from fetchWeather(). The | 0 means 'if it's missing, use 0'. The default spot is Chicago.

Tip

Try it: paste that URL (the four comment lines, joined, without the //) into a browser. You'll see the exact JSON the slab reads. Find temperature_2m in it.

Lesson 5: Clocks from the internet

There is no battery clock on this board. Unplug it and it forgets the time. When it wakes up it starts from the moment the program was compiled, which is why the time is wrong until it gets online.

Once on Wi-Fi it asks pool.ntp.org, a network of time servers, for the exact time. That's NTP. Then it adds your time zone offset.

desk-command-slab.ino
#define TZ_OFFSET_HOURS  -6   // Chicago is 6 hours behind UTC
#define DST_OFFSET_HOURS  1   // add 1 hour in summer

configTime(TZ_OFFSET_HOURS * 3600L, DST_OFFSET_HOURS * 3600L,
           "pool.ntp.org", "time.nist.gov");

From setupWifi(). Only runs once the slab has joined your Wi-Fi. 3600 turns hours into seconds.

Tip

Try it: unplug the slab for a minute and plug it back in. Did the clock jump backwards? With home Wi-Fi filled in, it corrects itself a few seconds after it connects.


Secret commands

Your computer can chat with the board through the same USB-C cable. That chat is called serial. Open the Serial Monitor in Arduino IDE (or any serial app) at 115200, type a word, press Enter.

Type this What happens
help lists every command
status shows the page, rotation, Wi-Fi and the board's IP address, plus the time, weather and current message
page 1 jumps to a page: 0 clock, 1 weather, 2 message
rotate flips tall / wide, same as holding BOOT

Level up: change the code

Ready to make it yours? Download desk-command-slab.ino and c6_slab_pins.h, put them in a folder called desk-command-slab, and open the .ino in Arduino IDE. Change the include line near the top to #include "c6_slab_pins.h". Board: ESP32C6 Dev Module, USB CDC On Boot: Enabled. Libraries: GFX Library for Arduino, Adafruit NeoPixel and ArduinoJson.

Ideas, easiest first:

  • Fill in WIFI_SSID and WIFI_PASSWORD (2.4 GHz networks only). Now the clock and weather go live.
  • Set WEATHER_LAT and WEATHER_LON to your town and TZ_OFFSET_HOURS to your time zone. Want °C? Set WEATHER_FAHRENHEIT to 0.
  • Change MSG_HOLD_MS so messages stay longer than 60 seconds.
  • Change the page colours: COL_BLUE, COL_CYAN, COL_AMBER, and the light in setRgbFor().
  • Add a fourth page: a new name in enum Page, bump PAGE_COUNT, and draw it in render().

Never paste a real password into a copy you share online.

desk-command-slab.ino
#define WIFI_SSID        ""          // your 2.4 GHz network name
#define WIFI_PASSWORD    ""          // its password (keep this file private)
#define WEATHER_LAT      41.8781     // your town
#define WEATHER_LON      -87.6298
#define TZ_OFFSET_HOURS  -6          // hours from UTC
#define MSG_HOLD_MS      60000UL     // how long a message stays, in ms

The six lines most people change. Save, flash again, done.


If something goes wrong

  • Screen stays black after flashing. Press RESET once. Still black? Try a different USB-C cable; many are charge-only.
  • No port shows up. Hold BOOT, tap RESET, release BOOT, click Flash again.
  • Can't see the DeskCommand network. It only appears when WIFI_SSID is empty or joining failed. Give it 10 seconds after plugging in, then refresh your Wi-Fi list.
  • The page won't open. Type http://192.168.4.1 exactly, with http, not https. Stay on the DeskCommand network while you do it.
  • Clock is wrong. The slab isn't online yet (Lesson 5). Add your Wi-Fi in Level up.
  • Weather says 52°F every day. That's the built-in sample. It changes once Wi-Fi works.
  • Picture is sideways. Hold BOOT for about a second.
  • Screen looks a bit dim. On purpose. 50% backlight keeps the panel from getting a hot spot.

Build photos

Licensed under CC BY-SA 4.0. Check with the author before commercial use.