Skip to content

jef41/tilt-micro-bridge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Micro Bridge (Tilt Hydrometer tool)

This project was originally a fork of Tilt-Pitch. It is a remodelling of the work already done in that project. Tilt-Pitch is written in Python. This project aims to convert functionality to MicroPython.

The intention is to create a minimal hardware Bluetooth -> wifi bridge, this project has been developed using a Raspberry Pi Pico W. Requirements;

  • Raspberry Pi Pico 2 W (RP2350, wifi and bluetooth)
  • micro USB cable
  • Thonny software
  • UF2 release from this project

Since adding the option to use a display this project has had limited testing on the slightly older Pi Pico W (RP2040, wifi and bluetooth). Although it will run, the RP2040 microcontroller version of the Pico has less SRAM (264KB of SRAM vs 520KB) and flash storage (2MB of on-board flash memory vs. 4MB) than the newer RP2350. The price difference is minimal. UF2 files are available for both versions, using a Raspberry Pi Pico 2 W is recommended.

My personal interest is in getting this to work with the Grainfather system and website, then to get some averaging of values: the Tilt seems to transmit very regularly (as in every second), Grainfather allows logging every 15 minutes (which seems reasonable). Rather than log one potentially noisy value every 15 minutes, store the latest n minutes of data in a circular buffer, when a timer has elapsed do some normalisation and/or averaging on that data and log a single, averaged data point.

Below are some graphics, the first GIF shows the Pico W running with no display - the LED blinks every 3 seconds. The second image shows the addition of a Pico Display, and finally a demo showing the display enclosed in a 3d Printed case.

Pico W running with no display

Pico 2 W running with a display

Pico 2 W running with a display and enclosed in a case

Features

The following features are implemented, planned, or will be investigated in the future:

  • Get a minimal demonstration working
  • Get Grainfather provider working
  • Tilt status data saved to log file (JSON)
  • Enable averaging
  • More robust WiFi check/reconnect - though more can be added in here
  • Watchdog/restarts
  • Error logging
  • Calibrate Tilt readings with known good values
  • Build Instructions
  • UF2 release
  • LCD display
  • visual warning about low storage space

Installation

More detailed, step by step instructions are available, the below may suffice

Quick Start

Download the UF2 release (https://github.com/jef41/tilt-micro-bridge/releases) for your device - either Raspberry Pi Pico W or Raspberry Pi Pico 2 W.

Hold down the button on the Pico whilst plugging it into a USB port on your computer.

The device should appear as a mass storage device. Drag and drop the downloaded UF2 file onto the device. This file should take a few seconds to copy over. On completion the mass storage device will disappear. The green LED on the Pico should then light up.

Open Thonny, issue Ctrl-F2 (to stop and restart the connection). Thonny should now display a message about execution interrupt and the REPL prompt >>>. At this point you must edit the config.json file using Thonny.

The Thonny window should show some files on the device, at the bottom left of your screen. Double click the config.json file, add content according to the documentation below. Save this (Ctrl-S) file on the root of the Pico as config.json. These examples of configuration files might help as a starting point. The configuration section below details each option.

Perform aa soft reboot (Ctrl-D), the device will restart and you should see some text output from the deivce in the Thonny shell window. If this output looks OK and includes data from configured Tilt devices then the device is configured and may now be unplugged.

Once configured and in use, the device requires only USB power, it does not necessarily need to be connected to a computer.

Configuration

Custom configurations can be used by creating a file config.json in the root directory on the Pico. Values in config.json will override any that are already in place, as shown below.

Option Purpose Default Example
ssid (str) SSID for your wifi newtork None Example config
password (str) password for your wifi newtork None Example config
country_code (str) ISO 3166-1 alpha-2 character country code for wifi None Example config
debug_log (list) How many kb in each and how many debug backup files to keep [20, 1]
display_type (str) currently only option is "DISPLAY_PICO_DISPLAY" None Example config
display_update_secs (float) how frequently to cycle content of display screen 5 Example config
lcd_gpio (dictionary) GPIO numbered pins for LCD display {"cs": 17, "dc": 16, "sck": 18, "mosi": 19,"bl": 20} Example config
lcd_backlight (float) brightness of LCD display 0.7 Example config
rgb_led_gpio (list) GPIO pins for RGB LED, for PICO_DISPLAY this is [6,7,8] None Example config
rgb_brightness (float) brightness of RGB LED 0.05 Example config
default_averaging_period (int) Average data over this period of seconds, 0 = no averaging, use most recent value that is within log period. Value must be less than log period. This default will be used if no provider averaging period is present 30 No example yet
default_temp_unit (char) The deault temperature unit to display, valid values are either C or F. This default will be used if no provider averaging period is present C No example yet
temp_range_min (int) Minimum temperature (Fahrenheit) for Pitch to consider a Tilt broadcast to be valid. 32 Example config
temp_range_max (int) Maximum temperature (Fahrenheit) for Pitch to consider a Tilt broadcast to be valid. 212 Example config
gravity_range_min (float) Minimum gravity for Pitch to consider a Tilt broadcast to be valid. 0.7 Example config
gravity_range_max (float) Maximum gravity for Pitch to consider a Tilt broadcast to be valid. 1.4 Example config
csv_log_period (int) log data at intervals of this many seconds 60 Example config
csv_bkp_count (int) Keep this number of older files 4 Example config
csv_log_tilt_colours (list) List of colours of Tilt devices to log to a CSV formatted file None Example config
csv_log_averaging_period (int) Seconds of data to average over default_averaging_period Example config
csv_log_temp_unit (str) Log temperatures in °C or °F default_temp_unit Example config
grainfather_temp_unit (str) Temperature unit sent to Grainfather F or C C Example config
grainfather_custom_stream_urls (dict) Dict of color (key) and URLs (value), seen as a Custom device on Grainfather site None/empty Example config
grainfather_tilt_stream_urls (dict) Dict of color (key) and URLs (value), as above, but seen as a Tilt Device None/empty Example config
grainfather_averaging_period (int) Average data over this period of seconds, 0 = no averaging, use most recent value that is within log period. Value must be less than log period. default_averaging_period Example config
{colour}_name (str) Name of your brew, where {colour} is the color of the Tilt (purple, red, etc) colour (e.g. purple, red, etc) Example config
{colour}_original_gravity (float) Original gravity of the beer, where {color} is the color of the Tilt (purple, red, etc) None/empty Example config
{colour}_temp_offsets (list) Temperature calibration points See Calibration None/empty Example config
{colour}_gravity_offsets (list) Gravity calibration points See Calibration None/empty Example config

Calibration

The broadcast temperature and gravity readings from the Tilt device may be adjusted by linear interpolation, using the same method as the Tilt2 App.

You may calibrate gravity for each Tilt by colour. At the moment, to apply and test calibration points you will need to run the device while connected to Thonny or other serial connection to observe the data. Alternatively set the config.json to use File CSV logging and run the device for a few minutes in each solution, then connect the device to Thonny and look in the CSV files for data. It is suggested to calibrate for temperature first - allowing 15 minutes for the temperature to stabilise. Then place the Tilt in known gravity solutions that are at a stable, room temperature, i.e. about 20°C. Gather all the temperature calibration points, then apply them to teh config.json, then repeat a similar process for the gravity calibration.

With the bridge running it will show uncalibrated values for the first hour, printed to the debug.log file and to a serial terminal as they are received.

Example output:

    data: blue SG:1.0246 72.41°F

Once the value is stable, write down this uncalibrated value and repeat the process with the next solution.

Temperature

The Tilt takes about 15 minutes to equilibrate with the temperature of a solution. You will need locations where you can maintain a solution at a stable temperature for at elast this amount of time. Insert the Tilt into a liquid at a stable temperature, wait for it to equilibrate then make a note of the Tilt reading and the solution temperature. Repeat as required at different temperature points. Once you have the required readings, enter the values into the config.json, using the colour of the Tilt, e.g.:

    "blue_temp_offsets" : [ "C", [4.8,5.0], [49.3,50.0] ],

Note the first list entry identifies the units used for calibration - in this case celsius. In subsequent pairs, the first reading is that received from the Tilt, the second is the known temperature of the liquid.

Gravity

Insert the Tilt into solutions of known gravity, e.g. 1.000, 1.060, 1.100, leaving the device to settle in each.

Add the uncalibrated values and their associated calibration points to the config file, using the correct colour code for the Tilt, e.g.:

    "blue_gravity_offsets" : [ [1.005,1.000], [1.090,1.100], [1.060,1.060] ],

Note that for each pair, the first value is the (uncalibrated) reading from the debug messages, the second value is the calibration point.

The example above shows the Tilt was reading 1.005 in pure water.

As per the Tilt instructions it is suggested that you have at least 2 calibration points, 1.000 & 1.200. Futher points may be added as you see fit.

These calibration points are not stored on the Tilt, but in the Pico. This is also true of the Tilt2 App and the TiltPi setup. You can therefore alternatively use, say the Tilt2 App to view the uncalibrated readings.

Running without a Tilt

If you want to run tilt-mico-bridge for development, or without a Tilt you can use the SIMULATE_BEACONS flag to create fake beacon events instead of scanning for Tilt events via Bluetooth. Edit main.py to set simulate_beacons to True or False. The default is False (i.e. listen for iBeacon Bluetooth transmissions). There is also a debug level that may be set. These are declared in the first few lines of main.py

DEBUG_LEVEL = logging.INFO
SIMULATE_BEACONS = False

Status LED

The Pico board has an onboard LED. This is used to give a basic visual indication of the condition of the code. The table below should help to interpret the LED status;

Condition Appearance Timing (on/off) milliseconds Indication
STARTUP solid ON None The Pico is in its initial startup state, loading variables etc. It should progress within 1 second to initiate a wifi connection
CONNECTING fast blink (on-off ~ twice per second) 10, 400 Initial configuration loaded, in process of connecting to wifi
CONNECTED 1Hz blink brief 200, 800 The Pico has connected to wifi. After 5 seconds it will progress from this state once a stable wifi connection has been established, or try to reconnect
NOT CONNECTED 1Hz blink slow 800, 200 A wifi connection has not been established. If not requiring wifi (i.e. logging locally to file) this will not be a problem
RUNNING blink once per 3 secs 10, 3,000 Once the startup routine has finished the LED should change to this status to indicate that the application is running and listenting for data from Tilt devices

If the LED remains solidly lit this indicates that the Pico has encountered an error. It is most likely that either the config.json file is not present, or this file is invalid. In this situation, use Thonny to connect to the device, inspect the debug.log file and correct the issue.

During startup, if a LCD display is present, some information on progress (and errors) will be shown. Once starup has completed and the device is running, the display will normally report Tilt beacon data. If the wifi connection becomes disconnected the LED will revert to its NOT CONNECTED state and (if an LCD is present) the wifi connection status will be added to the display pages. The device will try to reconnect every 2 minutes, unless the password is detected as being incorrect, in which case the device will stop and cease to record Tilt data.

Integrations

Don't see one you want, send a PR

CSV Log File

Tilt status broadcast events can be logged to a .csv file using the config option csv_log_tilt_colours. Enter a list of Tilt colours to listen for, e.g. ["red'] to log only Red Tilt data to CSV. Example file:

2025-02-19 16:40:24, Simulated Tilt, Festbier logger added
2025-02-19 16:40:34, header, Simulated Tilt for Festbier:
timestamp, ABV (%), Apparent Attenuation (%), Temperature (°C), Specific Gravity
2025-02-19 16:40:34, 5.71, 77.04, 21.9, 1.0259
2025-02-19 16:41:04, 6.28, 85.10, 22.5, 1.0216
2025-02-19 16:41:34, 6.37, 86.41, 22.5, 1.0209
2025-02-19 16:42:04, 6.76, 92.03, 22.2, 1.0179

The data logged are;

  • Timestamp
  • Tilt colour
  • Beer name
  • ABV
  • Apparent Attenuation
  • Temperature (°C or °F as specified)
  • SG

The log file name will be {colour}.csv. If beer name is included in the config file then the file will be named after the beer name.

If original gravity for the beer is not detailed in the config file then ABV and apparent attenuation will not be present.

When ABV is calculated, the calculation is the longer formula. This is more accurate at higher ABV values than the shorter formula (which is used by the Tilt2 App).

'Quick' ABV Formula:

ABV = (OG – FG) * 131.25

More accurate ABV Formula:

ABV = (76.08 * (OG - FG) / (1.775 - OG)) * (FG / 0.794)

Note The Pico has limited flash storage, some of which is used for the program files. RP2350 & RP2040 devices are available with more flash storage, but if using CSV logging it is recommended to remove old files before starting a new logging session. Old files with the same name will be overwritten. See the CSV File examples for more detail.

Grainfather

Tilt data can be logged to Grainfather using their Custom Fermenation Device feature. See Configuration section for setting this up in the file config.json. Grainfather only allows logging data every fifteen minutes per Tilt, which micro-bridge adheres to. You must create a custom device per Tilt and save each URL into the micro-bridge config.

Tilt data can alternatively be logged to Grainfather using their Tilt Fermentation Device feature. The set up is the same as per the Custom device, the only difference being whether Grainfather displays your device as a Custom or a Tilt device.

Note that temperatures displayed on the Grainfather website will use the preference you have configured on their website. This means whether you configure micro-bridge to upload data in Farenheit or Centigrade, the temperature will be converted by the Grainfather website and displayed in your preference configured there. i.e. the Tilt hydrometer natively uses Farenheit, if you want to see temperature data displayed in Centigrade, then change your configuration on the Grainfather website.

To setup, first log in into Grainfather then go to the section My Equipment. Click Add Fermenation Device.

Add Device options shown by Grainfather website

Select either the Custom or Tilt Wireless Hydrometer and Thermometer option. Set the name for a Custom device, or select the colour if you used the Tilt option. Save. Now click the "i" (info) button next to the device and copy this URL into pitch.config. See the Grainfather Provider examples for more detail.

Program Flow

At startup the device will look for a file named main.py on the root of the device. If not found, this file will be created and populated. It will then look for config.json, if not found a generic (but invalid) config.json will be created.

The software will then start from main.py and will look for and validate config.json, this must be located in the root folder of the file system on the device. If the configuration file is invalid the device will halt.

Once the configuration has loaded the Pico will look to see if wifi credentials have been specified. If they have been specified then the device will try to connect to the network. If no wifi credentials are present the device will disable all but the CSV file provider, then continue.

The Tilts and providers detailed in config.json will be provisioned (though if no wifi is present all but CSV file provider will be ignored).

The Pico will start to listen for Tilt devices using Bluetooth. As data is received it will be stored on a queue of data points.

At the specified upload intervals data will be retrieved from the queue. Averaging, calibration and conversion will then be applied as specified from the configuration, and a value stored or uploaded to the provider(s).

If the Pico is plugged in to a USB port on a computer you may use either Thonny, MicroPython's mpremote or a serial terminal (e.g. Putty) to observe messages from the Pico. In its default state received Tilt data will be displayed for the first hour - this is intended to help the calibration process.

In a normal running state the built in LED on the Pico board will blink approximately every 3 seconds to indicate that the device is operating correctly. If an LCD display is present and configured, the display will cycle between configured Tilt devices and a clock display.

Developing

The UF2 release contains all the necessary code, pre-compiled into .mpy and frozen (hidden) into the UF2. If you wish to develop/play/test things it is suggested that you manually copy the whole folder and contents /bridge/lib to the root of the Pico filesystem. This will result in reduced filespace for CSV files, but allows for development and testing.

It is worth noting that the UF2 release will automatically (re)create main.py if it is not present. To disable this autorun file, rename main.py to, for example tilt-micro-bridge.py then create a new main.py that contains somethign simple, for example:

print("new main, done.")

More information on drag and drop setup and links to standard releases are available on the Raspberry Pi website

Buy me a coffee (beer)

If you like TiltMicroBridge, feel free to buy me a coffee (or a beer) here: https://www.buymeacoffee.com/jef41

About

a wifi bridge between the Tilt hydrometer and the internet, built for RP2350 & RP2040 mcu

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors 8