From 0628cf59a6ae18f47159f9989dc95d7baf354dbc Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Sun, 3 Dec 2017 12:45:15 +0100 Subject: [PATCH] Remove the text that comes from huzzah32-featherwing --- README.md | 217 +----------------------------------------------------- 1 file changed, 1 insertion(+), 216 deletions(-) diff --git a/README.md b/README.md index 814f786..8e4e066 100644 --- a/README.md +++ b/README.md @@ -2,220 +2,5 @@ ## Introduction -This project is a demonstration of the capabilities of Mongoose OS. It is -build around two popular pieces of hardware, both available from Adafruit: - -* [Huzzah32 ESP32 Feather](https://learn.adafruit.com/adafruit-huzzah32-esp32-feather/) -* [2.4" TFT/TouchScreen Featherwing](https://learn.adafruit.com/adafruit-2-4-tft-touch-screen-featherwing/) - -[![Video Intro](https://img.youtube.com/vi/d9CZ4VMgTGI/0.jpg)](https://www.youtube.com/watch?v=d9CZ4VMgTGI) - -## Hardware: Moving Parts - -The TFT Featherwing features three components: - -* ILI9341 2.4" TFT screen driven by SPI -* STMPE610 Resistive touchscreen driven by SPI -* MicroSD storage device driven by SPI - -The Huzzah32 plugs right into the TFT Featherwing for a compact device -without the need for breadboards, dupont wires and the like. It's really -a great platform to showcase the power of Mongoose OS. - -### Hardware: Observations - -The Huzzah32 uses its SPI bus to communicate with the touch sensor and the -TFT screen. Its `MOSI`, `MISO` and `SCLK` pins are shared with the other -devices, and it selects which slave device to communicate with by means of -three `CS` pins. - -Peculiarities of the hardware setup: - -* The TFT driver chip, ILI9341, has an additional pin called `DC`, - which it uses to receive blobs of data from the microcontroller. -* The Touchscreen driver chip, STMPE610, has an additional pin called - `IRQ`, which it pulls low when a touch event has registered. The - chip buffers the last 128 touch events, and the microcontroller, - upon receipt of the interrupt, can read them. That means no polling - or busy waiting! -* The TFT Featherwing has an additional pin called `LITE`, on which it - accepts a 10KHz PWM signal. Setting the duty cycle to 0% turns off the - backlight entirely, setting it to 100% turns on the backlight, and - values in between partially dim the backlight. -* The Huzzah32 has a built in 3.7V LiPo, and charges it when the device - is connected to USB. Adafruit have helpfully connected the battery - output to an ADC pin (A13 / GPIO35) using a 1:1 voltage divider (so a - full LiPo battery at 4.2V will read out at 2.1V on the ADC channel. - -#### Soldering Requirements - -The `LITE` and `IRQ` pads on the TFT Featherwing have to be soldered to -connect them to the Huzzah32: - -* Solder the `IRQ` pad to pin 23, the top left pad. -* Solder the `LITE` pad to pin 22, the second from the top left pad. - -Here's a picture to help you find your bearings: - -![Soldering image](docs/Mongoose-Touch_2.png) - - -### General Design - -To showcase the idiomatic use of Mongoose OS, we will to do the following: - -1. Write drivers for the [ILI9341](https://github.com/pimvanpelt/ili9341-spi) - and [STMPE610](https://github.com/pimvanpelt/stmpe610-spi) chips. We've taken - the native Mongoose OS SPI driver as a base -- this way, this code will run - on _any hardware target_ that Mongoose OS supports. -1. Install an interrupt handler for the touch screen events. -1. Install a PWM driver for the backlight. -1. Install an ADC reader on GPIO35. -1. Create a UI container which can display `widgets`, both provided in C code, - such as `src/widget_*.c`, but also provided by users in a JSON - configuration. -1. Store the JSON and image data on the provided `SPIFFS` filesystem in `fs/`. -1. Interact with the user by performing actions on the `widgets`. -1. Report on system statistics using Prometheus. - -## User Interface - -### Anatomy of the UI - -There are two main components: `widgets` and `screens`. - -#### Widgets - - A `widget` is an object that describes a user interface element (an image, a -button, or a system `widget` with specific implementation behavior). System -`widgets` can have timers associated with them, as such they can perform -regular callbacks to redraw themselves. They are initialized with a few -variables, notably their (x,y) coordinates and width and height. They also -have a name and, optionally a `user_data` blob can be attached to them. - -##### Time widget - -This `widget` exposes `widget_time_ev()` which gets called every second, and -displays the current NTP time. - -##### Battery widget - -This `widget` exposes `widget_battery_ev()` which gets called every now and -again, measures the current voltage of the attached LiPo, and draws a battery -icon in green (full), yellow (half full), or red (empty). - -##### WiFi widget - -This `widget` exposes `widget_wifi_ev()` which gets called every 5 seconds, and -it retrieves the current WiFi signal strength (RSSI), mapping it to a value -between 0 and 100%, and draws a WiFi icon in white. - -##### Network widget - -This `widget` exposes `widget_network_ev()` which gets draws two arrows, one -pointed up (for Send traffic), and one pointed down (for Recv traffic). It -has two helper functions: `widget_network_send()` and `widget_network_recv()` -which redraw the arrows in yellow, setting a 100ms timer that will redraw the -arrows in grey again. - -Users can call the send and recv functions to show network activity. - -##### Name widget - -This `widget` exposes `widget_name_ev()` which prints a string based on some -local state it keeps. Its event handler implements `TOUCH_DOWN` and `TOUCH_UP` -Which cycles between the `app.hostname` system configuration string (see -`mos.yml` for its defintion), the IP address, the associated WiFi SSID, and -the `screen` name (see below). - - -#### Screens - -A `screen` is an object that holds the `widgets`. The API for screens is -meant to be simplistic: both to be able to fit in the available compute -resources of smaller micro controllers, but also to show readers how these -things work without bogging them down in overly complex code to wade through. - -Users typically create a screen by: - -```c - struct screen_t *screen; - struct widget_t *w; - screen=screen_create_from_file("/screen_home.json", widget_default_ev, NULL); - - // Add a custom widget - w = widget_create("time", 240, 0, 80, 20); - widget_set_handler(w, widget_time_ev, NULL); - widget_set_timer(w, 1000); - screen_widget_add(screen, w); -``` - -#### Touch Handler - -The main app installs the interrupt handler for STMPE610, which is where all -the action is. When users interact with the device, the interrupt handler -calls a callback with an event number and additional data (such as the -(x,y) coordinates, pressure, direction of the touch (`TOUCH_DOWN` and `TOUCH_UP`) -and duration of the touch. - -The handler `touch_handler()` then looks if any `widgets` are covering the -(x,y) coordinates in the current `screen`, and if so, passes the event to a -hander for the `widget` (in our example above, `widget_default_ev` for -`widgets` we read from the JSON file, and `widget_time_ev` for the manually -added time `widget`. - -#### Backlight - -The Featherwing has a PWM based backlight. The implementaion in -`src/backlight.c` shows a way to dim the screen when it is not in use. -The way this works, is by means of `backlight_keepalive()` which sets the -backlight on, and updates `backlight_last_keepalive`. A timer checks if -the last keepalive call hasn't been too long ago, and if it was, it initiates -a screen dimmer by setting a new target duty cycle and time to get to that -target (usually 1000ms). Then it'll start a repeating a 20ms timer that dims -the backlight until the target it reached, after which it deinstalls itself. -See `backlight_fader_cb()` for details. Very slick! - -If the screen is off, `backlight_active()` will return false. The main -`touch_handler()` (the one that gets interrupts from the STMPE610), will -ignore the first `TOUCH_DOWN` and `TOUCH_UP` events in that case, but it -will wake up the screen again by calling `backlight_keepalive().` - -### Other tricks - -The application includes [Prometheus Metrics](https://github.com/mongoose-os-libs/prometheus-metrics) -which allows users to export metrics to a monitoring system. The library comes -with several Mongoose OS specific metrics (such as memory, build platform, -MQTT statistics, etc), but also allows users to add handlers of their own. - -For example, the battery `widget` installs a callback adding one such metric -(the measured battery voltage). - -## Unit Tests - -Unit tests are an incredibly important tool for any software engineer. The -author wrote the `widget` and `screen` implementations by means of _test based -engineering_, in which the code is written by first authoring tests, and then -making the tests pass. This is a wonderful way to prove non-trivial -implementations. - -See the `unittest/Makefile` for a compilable target (on Linux at least). It -runs tests against the code, ensuring that timers are set and removed, -object creation and destruction are working, and getters/setters and other -code operates as designed. - -## Acknowledgements - -Several pieces of code were borrowed from other authors. In particular, kudos -go to the following fine individuals: - -* ***Espressif Systems*** for the SPI driver -* ***LoBo*** (loboris@GitHub) for a reference ILI9341 driver for ESP32 (which - the author rewrote to use native Mongoose OS SPI). -* ***Adafruit*** for inspiration on the STMPE610 driver (which the author - rewrote to support interrupts), as well as the fonts. -* ***Lode Vandevenne*** and ***Sean Middleditch*** for the uPNG code to - handle PNG images. -* ***Cesanta*** for Mongoose OS, Mongoose, and the JSON `frozen` library. - +For basic introduction, see [huzzah32-featherwing](https://github.com/mongoose-os-apps/huzzah-featherwing)