diff --git a/README.md b/README.md
index 101ff21..ac57f1f 100644
--- a/README.md
+++ b/README.md
@@ -71,4 +71,5 @@ then take a look at the [known issues document](doc/known_issues.md).
* [Configuration_guide](doc/configuration.md)
* [Flashing guide](doc/flashing.md)
* [Known issues](doc/known_issues.md)
+* [Hardware information](doc/hardware.md)
* [Sponsoring](doc/sponsoring.md)
diff --git a/doc/hardware.md b/doc/hardware.md
new file mode 100644
index 0000000..10eddda
--- /dev/null
+++ b/doc/hardware.md
@@ -0,0 +1,244 @@
+< [Known issues](known_issues.md) | [Index](../README.md) | [Sponsoring](sponsoring.md) >
+
+# Hardware information
+
+In this section, you can find some of the information that was gathered
+during the reverse engineering of the Bedside Lamp 2 hardware.
+
+Table of contents:
+
+* [High level overview](#high-level-overview)
+* [ESP32 pinout](#esp32-pinout)
+* [Front panel](#front-panel)
+
+
+## High level overview
+
+No documentation is complete without some ASCII art schematics.
+
+```
+ RX/TX/GND for
+ 12V power supply flashing and logs
+ | |
+ v | Front panel
+ +---------------+ +---------------+ .---.
+ | Power supply |---- 3.3V -.----->| ESP-WROOM-32D | | O | -- color
+ +---------------+ \ | single core | | | button
+ | \ | 4 MB flash | | | |
+ 12V \ +---------------+ | | |
+ | \ | ^ | | | | -- slider
+ | `------|--|--|--- 3.3V ---->| | |
+ | | | | | | |
+ v | | +--- I2C ------| | |
+ +---------------+ | | | | |
+ | RGB and white |<---- RGBW + master ---+ +------ IRQ ------| | power
+ | LED circuitry | PWM on/off | O | -- button
+ +---------------+ `---`
+```
+
+The LED circuitry provides two light modes:
+
+* Colored RGB light;
+* Warm to cool white light.
+
+The front panel of the device contains a two touch buttons (power on/off and
+color selection) and a touch slider (for setting the brightness level). This
+panel is lit when the device is turned on. The light behind the slider will
+represent the actual brightness setting of the device.
+
+
+## ESP32 pinout
+
+In the following image, you can find the pinout as used for the ESP32:
+
+
+
+Here's an overview of all exposed pins of the chip, starting at the GND +
+3.3V pins, and going anti-clockwise. The table shows not only the functions
+of the pins that are actually in use by the lamp's circuitry, but also the
+pins that are not in use and their possible applications.
+
+| PIN | GPIO# | Function | Description | Possible use |
+|------|--------|-----------|--------------------------------|--------------|
+| GND | | Ground | Connected to ground | - |
+| 3.3V | | Power | Power supply input | - |
+| 9 | | Reset | Can be pulled to GND to reset | - |
+| 5 | GPIO36 | - | | I |
+| 8 | GPIO39 | - | | I |
+| 10 | GPIO34 | - | | I |
+| 11 | GPIO35 | - | | I |
+| 12 | GPIO32 | - | | I/O |
+| 13 | GPIO33 | LEDs | LEDs, master switch 1 | - |
+| 14 | GPIO25 | ??? | 10k pull up, unknown function | I/O (1) |
+| 15 | GPIO26 | - | | I/O |
+| 16 | GPIO27 | - | | I/O |
+| 17 | GPIO14 | LEDs | LEDs, green PWM channel | - |
+| 18 | GPIO12 | LEDs | LEDs, white PWM channel | - |
+| GND | | Ground | Connected to ground | - |
+| 20 | GPIO13 | LEDs | LEDs, red PWM channel | - |
+| 28 | GPIO9 | SPI | SPI flash memory | - |
+| 29 | GPIO10 | SPI | SPI flash memory | - |
+| 30 | GPIO11 | SPI | SPI flash memory | - |
+| 31 | GPIO6 | SPI | SPI flash memory | - |
+| 32 | GPIO7 | SPI | SPI flash memory | - |
+| 33 | GPIO8 | SPI | SPI flash memory | - |
+| 21 | GPIO15 | - | | I/O (2) |
+| 22 | GPIO2 | ??? | Debug pad, unknown function | I/O (3) |
+| 23 | GPIO0 | Boot mode | Pull to GND for flashing mode | - |
+| 24 | GPIO4 | LEDs | LEDs, master switch 2 | - |
+| 25 | GPIO16 | Front pnl | Front panel interrupt | - |
+| 27 | GPIO17 | EEPROM | EEPROM I2C SDA (4) | - |
+| 34 | GPIO5 | LEDs | LEDs, blue PWM channel | - |
+| 35 | GPIO18 | EEPROM | EEPROM I2C CLK (4) | - |
+| 38 | GPIO19 | Front pnl | Front panel I2C SCL | - |
+| N/C | | | | |
+| 42 | GPIO21 | Front pnl | Front panel I2C SDA | - |
+| 40 | GPIO3 | Serial | Debug pad, RX (flashing, logs) | - |
+| 41 | GPIO1 | Serial | Debug pad, TX (flashing, logs) | - |
+| 39 | GPIO22 | - | | I/O |
+| 36 | GPIO23 | - | | I/O |
+| GND | | Ground | Connected to ground | - |
+
+1. GPIO25 is connected to a 10k pull up resistor. This suggests that it
+ might have some function in the lamp, but I have not found that function
+ yet. If you find the actual use for this pin, or find that you can indeed
+ repurpose it, then please let me know.
+1. Beware that GPIO15 outputs a PWM signal at boot. This might make the pin
+ less useful for your use case.
+1. Often, GPIO2 is used for an on-board LED, but it looks like it is only
+ connected to the debug pad here. I think the pin is usable, and that it
+ might only be used for testing purposes in the original firmware.
+1. The connected IC, using I2C address 0x10, looks a lot like an EEPROM,
+ but this has yet to be confirmed. It uses a decicated I2C bus, separate
+ from the I2C bus of the front panel.
+ [This picture](images/hardware/IC_on_I2C_GPIO1718.jpg) shows the IC.
+
+For more information on the use of pins on the ESP32 chip, please check out
+this [ESP32 pinout reference information](https://randomnerdtutorials.com/esp32-pinout-reference-gpios/).
+
+
+## Front panel
+
+
+
+The front panel is a stand-alone component, with its own control chip
+(KungFu KF8TS2716). Communication between the ESP32 and the front panel
+is done using:
+
+- **An I2C bus**
+ - the front panel is the I2C slave, the ESP32 is the I2C master
+ (pardon the standard terminology, I am aware of the controversy)
+ - the front panel device ID is 0x2C
+ - SDA is connected to ESP32 pin GPIO21
+ - SCL is connected to ESP32 pin GPIO19
+- **An interrupt data line to signal the ESP32 about new events**
+ - this line is connected to ESP32 pin GPIO16
+ - the default state is HIGH
+ - line is pulled LOW for at least 6 ms when a new event is available
+
+Commands can be written to and data can be read from the front panel
+component using I2C. The I2C protocol is fairly simple. All read and write
+operations uses 6 bytes of data. No register selection is done before
+reading or writing.
+
+The interrupt data line is used by the front panel, to signal the ESP32 that
+a new button or slider event is available. Further details on this can be
+found below.
+
+**Connection to the main board**
+
+The front panel is connected to the main board using a flat cable.
+The picture below shows the connector on the main board, including the
+functions of the cable pins:
+
+
+
+**Writing commands to the front panel**
+
+Commands can be written to the front panel at any time.
+
+The available commands are:
+
+| Command | Byte sequence to send |
+|-------------------|-----------------------|
+| `TURN PANEL ON` | 02 03 5E 00 64 00 00 |
+| `TURN PANEL OFF` | 02 03 0C 00 64 00 00 |
+| `SET LEVEL 1` | 02 03 5E 00 64 00 00 |
+| `SET LEVEL 2` | 02 03 5F 00 64 00 00 |
+| `SET LEVEL 3` | 02 03 5F 80 64 00 00 |
+| `SET LEVEL 4` | 02 03 5F C0 64 00 00 |
+| `SET LEVEL 5` | 02 03 5F E0 64 00 00 |
+| `SET LEVEL 6` | 02 03 5F F0 64 00 00 |
+| `SET LEVEL 7` | 02 03 5F F8 64 00 00 |
+| `SET LEVEL 8` | 02 03 5F FC 64 00 00 |
+| `SET LEVEL 9` | 02 03 5F FE 64 00 00 |
+| `SET LEVEL 10` | 02 03 5F FF 64 00 00 |
+| `READY FOR EVENT` | 01 00 00 00 00 00 01 |
+
+*Note: The `READY FOR EVENT` command is only used when a new event is provided
+by the front panel. Information about this command can be found in the next
+section.*
+
+**Reading events from the front panel**
+
+The types of events that can occur can be summarized as:
+
+- Touch or release the power button
+- Touch or release the color button
+- Touch or release the slider at a certain level
+
+Because the front panel is an I2C slave device, it cannot contact the ESP32 via
+I2C. Only an I2C master device can initiate communication. Therefore, when the
+front panel has a new event available, it will pull down the interrupt line for
+a short period of time, to signal the ESP32 about this new event.
+
+*Note that the ESP32 needs to poll the interrupt line at least at 667 Hz to be
+able to trustworthy detect the 6 ms signal. Unfortunately, the interrupt line
+does not wait for the ESP32 to respond to its signalling. The best way to
+handle signals from this line, is to use an actual interrupt handler.*
+
+After detecting this signal, the ESP32 must first write the "READY FOR EVENT"
+command (`01 00 00 00 00 00 01`) via I2C to the front panel.
+
+After the front panel has ACK'ed this command, the ESP32 can read 6 bytes,
+which will represent the event that occurred.
+
+Here's the mapping for the events and their corresponding byte sequences:
+
+| | Touch event | Release event |
+|-----------------|----------------------|----------------------|
+| POWER BUTTON | 04 04 01 00 01 01 03 | 04 04 01 00 01 02 04 |
+| COLOR BUTTON | 04 04 01 00 02 01 04 | 04 04 01 00 02 02 05 |
+| SLIDER LEVEL 1 | 04 04 01 00 03 16 1A | 04 04 01 00 04 16 1B |
+| SLIDER LEVEL 2 | 04 04 01 00 03 15 19 | 04 04 01 00 04 15 1A |
+| SLIDER LEVEL 3 | 04 04 01 00 03 14 18 | 04 04 01 00 04 14 19 |
+| SLIDER LEVEL 4 | 04 04 01 00 03 13 17 | 04 04 01 00 04 13 18 |
+| SLIDER LEVEL 5 | 04 04 01 00 03 12 16 | 04 04 01 00 04 12 17 |
+| SLIDER LEVEL 6 | 04 04 01 00 03 11 15 | 04 04 01 00 04 11 16 |
+| SLIDER LEVEL 7 | 04 04 01 00 03 10 14 | 04 04 01 00 04 10 15 |
+| SLIDER LEVEL 8 | 04 04 01 00 03 0F 13 | 04 04 01 00 04 0F 14 |
+| SLIDER LEVEL 9 | 04 04 01 00 03 0E 12 | 04 04 01 00 04 0E 13 |
+| SLIDER LEVEL 10 | 04 04 01 00 03 0D 11 | 04 04 01 00 04 0D 12 |
+| SLIDER LEVEL 11 | 04 04 01 00 03 0C 10 | 04 04 01 00 04 0C 11 |
+| SLIDER LEVEL 12 | 04 04 01 00 03 0B 0F | 04 04 01 00 04 0B 10 |
+| SLIDER LEVEL 13 | 04 04 01 00 03 0A 0E | 04 04 01 00 04 0A 0F |
+| SLIDER LEVEL 14 | 04 04 01 00 03 09 0D | 04 04 01 00 04 09 0E |
+| SLIDER LEVEL 15 | 04 04 01 00 03 08 0C | 04 04 01 00 04 08 0D |
+| SLIDER LEVEL 16 | 04 04 01 00 03 07 0B | 04 04 01 00 04 07 0C |
+| SLIDER LEVEL 17 | 04 04 01 00 03 06 0A | 04 04 01 00 04 06 0B |
+| SLIDER LEVEL 18 | 04 04 01 00 03 05 09 | 04 04 01 00 04 05 0A |
+| SLIDER LEVEL 19 | 04 04 01 00 03 04 08 | 04 04 01 00 04 04 09 |
+| SLIDER LEVEL 20 | 04 04 01 00 03 03 07 | 04 04 01 00 04 03 08 |
+| SLIDER LEVEL 21 | 04 04 01 00 03 02 06 | 04 04 01 00 04 02 07 |
+| SLIDER LEVEL 22 | 04 04 01 00 03 01 05 | 04 04 01 00 04 01 06 |
+
+**Behavior when more events come in than can be handled**
+
+The front panel does not queue events. When a new event occurs, before the
+previous event has be read by the ESP32, the new event will replace the old
+event and a new signal is sent over the interrupt line.
+
+The ESP32 can read the last event multiple times. It will not be cleared
+by the front panel after reading it.
+
+< [Known issues](known_issues.md) | [Index](../README.md) | [Sponsoring](sponsoring.md) >
diff --git a/doc/images/hardware/ESP32_pinout.jpg b/doc/images/hardware/ESP32_pinout.jpg
new file mode 100755
index 0000000..131ab01
Binary files /dev/null and b/doc/images/hardware/ESP32_pinout.jpg differ
diff --git a/doc/images/hardware/IC_on_I2C_GPIO1718.jpg b/doc/images/hardware/IC_on_I2C_GPIO1718.jpg
new file mode 100755
index 0000000..2151a7b
Binary files /dev/null and b/doc/images/hardware/IC_on_I2C_GPIO1718.jpg differ
diff --git a/doc/images/hardware/esp-wroom-32d.jpg b/doc/images/hardware/esp-wroom-32d.jpg
new file mode 100755
index 0000000..2da5af1
Binary files /dev/null and b/doc/images/hardware/esp-wroom-32d.jpg differ
diff --git a/doc/images/hardware/front_panel.jpg b/doc/images/hardware/front_panel.jpg
new file mode 100755
index 0000000..de7589f
Binary files /dev/null and b/doc/images/hardware/front_panel.jpg differ
diff --git a/doc/images/hardware/front_panel_flat_cable_connection.jpg b/doc/images/hardware/front_panel_flat_cable_connection.jpg
new file mode 100755
index 0000000..1e7aabe
Binary files /dev/null and b/doc/images/hardware/front_panel_flat_cable_connection.jpg differ
diff --git a/doc/known_issues.md b/doc/known_issues.md
index 5e772a5..0c36813 100644
--- a/doc/known_issues.md
+++ b/doc/known_issues.md
@@ -1,4 +1,4 @@
-< [Flashing guide](flashing.md) | [Index](../README.md) | [Sponsoring](sponsoring.md) >
+< [Flashing guide](flashing.md) | [Index](../README.md) | [Hardware information](hardware.md) >
# Known issues
@@ -83,4 +83,4 @@ the ESP32.
For this reason, I advise to completely omit logging or use a very low log
level for production purposes.
-< [Flashing guide](flashing.md) | [Index](../README.md) | [Sponsoring](sponsoring.md) >
+< [Flashing guide](flashing.md) | [Index](../README.md) | [Hardware information](hardware.md) >
diff --git a/doc/sponsoring.md b/doc/sponsoring.md
index 86d9889..a11cf43 100644
--- a/doc/sponsoring.md
+++ b/doc/sponsoring.md
@@ -1,4 +1,4 @@
-< [Known issues](known_issues.md) | [Index](../README.md)
+< [Hardware information](hardware.md) | [Index](../README.md)
# Sponsoring the project
@@ -18,4 +18,4 @@ this project were:
the I2C protocol of the front panel.
* Various wires and buttons.
-< [Known issues](known_issues.md) | [Index](../README.md)
+< [Hardware information](hardware.md) | [Index](../README.md)