Replacement firmware for iSpindel (GravityMon)

Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum

Help Support Homebrew Talk - Beer, Wine, Mead, & Cider Brewing Discussion Forum:

This site may earn a commission from merchant affiliate links, including eBay, Amazon, and others.

mper

Supporting Member
HBT Supporter
Joined
May 24, 2020
Messages
367
Reaction score
110
I've been tinkering with a replacement firmware for the iSpindle. I've been using it myself for the last year and nowI'm looking for people to try it out and give feedback on functions that might be missing. It uses the exact same hardware as the iSpindle but I have implemented a few features that was rejected by the iSpindle project.

I still have some long term battery tests to perform but I have been running it for 2+ weeks without issues.

The main features are:
  • Operates in two modes gravity monitoring and configuration mode (simplify calibration)
  • Modern web based UI for configuration (in config mode)
  • REST API
  • Send data to multiple endpoints when pushing data (2xhttp, brewfather, influxdb v2, mqtt supported)
  • Automatic temperature adjustment of gravity reading
  • OTA support from local webserver
  • Built in function to create gravity formulas, no need for additional software, just enter tilt/gravity.
  • Visual graph showing how formula will be interpreted
  • Using the temperature sensor in gyro instead of DS18B20 (faster)
  • Built in performance measurements (used to optimise code)
The project can be found here mp-se/gravitymon: iSpindle replacement firmware for beer brewing/fermenting (github.com) and the documentation here; GravityMon 0.6.0 documentation (mp-se.github.io)
 
Here are a few screenshots from the UI. This is the graph that shows the expected gravity for the current formula and the raw values entered.
formula2.png

Configuration pages with possible options. All of these can be active at the same time.
config2.png

Main page that shows the typical values and there is the possibility to force the UI to be active when doing calibration.
index.png
 
OTA support from local webserver
That's interesting man... Soooo, there's still an intermediary bridge that is the webserver (ie, an always-on pi) or are you saying that the iSpindle actually hosts a web service (for as long as the battery lasts? can't be, right)? Anyhow-- I'm intrigued. Certainly following this thread... Thanks!
 
That's interesting man... Soooo, there's still an intermediary bridge that is the webserver (ie, an always-on pi) or are you saying that the iSpindle actually hosts a web service (for as long as the battery lasts? can't be, right)? Anyhow-- I'm intrigued. Certainly following this thread... Thanks!
If you force it into configuration mode it will start a webserver, however this will drain the battery much faster so its not recommended for fermentation tracking. But its a neat feature when you are doing configration or doing the initial calibration. You dont have to put the device in Access Point mode, just attach to power or lay it flat to activate the web server.
1642174081496.png

This is a simpel overview on what the software contains, the green parts are only active when in configuration mode to save battery power. When in calibration mode it behaves like the standard iSpindle.

Feel free to try it out and you can always flash it with iSpindle firmware again if you dont like it. However any feedback is appreciated to make this better.
 
Last edited:
I assume the mqtt message is the same so I should be able to still send to my BrewPiless?
I'm currently using an iSpindle json format for MQTT. I have not checked if this is the format used in the iSpindle. I will have a look at the details and get back. I've mainly used HTTP endpoints myself and I'n new to MQTT.

I'm working on a feature for the next version that allows the users to specify the format they want to make it more flexible. This would enable support for more services.
 
Last edited:
I assume the mqtt message is the same so I should be able to still send to my BrewPiless?
I've checked how iSpindle sends data to mqtt and in the current version it's not compatible. I will change the MQTT integration so the format is compatible, I will include this in the next version. I will post an update here once that is done.
 
A new release of GravityMon is now published in brewflasher and on github ( Release v.0.7.0 SSL support, custom push formats and plato · mp-se/gravitymon (github.com) ).

These are the changes in this version, enjoy!
  • SSL support for HTTP targets.
  • SSL support for MQTT targets
  • SSL support for OTA.
  • Added support for gravity in Plato.
  • Added error handling for calibration page.
  • Added experimental target ESP32 (using an ESP32 D1 Mini which is pin compatible with ESP8266). Not really usable since wifi connection is extreamly slow with current Arduino releases (3-8 seconds).
  • Added experimental format editor so users can customize their data format used for pushing data. This will reduce the need for custom push targets. As long as the service is supporting http or https then the data format can be customized.
  • Added check so that pushing data is not done if memory is low (this will avoid crashes)
  • MQTT topic has been removed from config (handled via format templates)
  • MQTT port port number added. Port over 8000 will activate SSL.
  • Breaking change: To simplify the internal structure the temp sensor adjustment is now stored in C. So if you have enabled this function using F you will need to go into the configuration and update the adjustment factor again (hardware config).
  • Breaking change: The MQTT push option has been changed to match the iSpindle behaviour. If the behaviour in v0.6 is wanted this can be done via the format editor.
@gello22, this version should send data to mqtt with the same setup as in the iSpindle.
 
wow awesome I'll have to give this a try my last few brews have been either kviek or lagers so even just the temperature correction is interesting.
 
Just published a new version of GravityMon v0.8 and it can be installed via brewflasher. Lots of documentation and support for services.

Changes in this version:
  • dded option to set http headers (2 per http endpoint), these can be used for other http formats than json (default) and for adding authentication headers.
  • Added possibility to view last 10 errors on device page.
  • Added possibility to define token parameter used in iSpindle format.
  • Added instructions for how to configure integration with Brewspy
  • Added instructions for how to configure integration with Thingspeak
  • Added option to do a factory reset via API.
  • Logging the runtime, how long a measurement take (last 10 are stored). This can be used to check how good the wifi connection is and estimate the lifetime when on battery. Check the device page in the UI for this information.
  • Refactored code to free up more RAM to make SSL more stable.
  • Before connecting to an SSL endpoint the device will try to use a new SSL feature called MFLN (Maximum Fragment Length Negotiation) that allow us to reduce the buffers from 16k to 2k. This can make a huge difference on a device with only 40k RAM. Not all servers might support this feature.
  • Updated documentation pages.
  • Tested batterylife, 47 days using an update frequency of 5 min
 
Just published a new version of GravityMon v0.8 and it can be installed via brewflasher. Lots of documentation and support for services.

Changes in this version:
  • dded option to set http headers (2 per http endpoint), these can be used for other http formats than json (default) and for adding authentication headers.
  • Added possibility to view last 10 errors on device page.
  • Added possibility to define token parameter used in iSpindle format.
  • Added instructions for how to configure integration with Brewspy
  • Added instructions for how to configure integration with Thingspeak
  • Added option to do a factory reset via API.
  • Logging the runtime, how long a measurement take (last 10 are stored). This can be used to check how good the wifi connection is and estimate the lifetime when on battery. Check the device page in the UI for this information.
  • Refactored code to free up more RAM to make SSL more stable.
  • Before connecting to an SSL endpoint the device will try to use a new SSL feature called MFLN (Maximum Fragment Length Negotiation) that allow us to reduce the buffers from 16k to 2k. This can make a huge difference on a device with only 40k RAM. Not all servers might support this feature.
  • Updated documentation pages.
  • Tested batterylife, 47 days using an update frequency of 5 min
Looks promising. Unfortunately I could only get so far. Pretty smart and could follow step by step instructions as per open source distilling, but not having a background in coding etc.... puts me at a disadvantage as I hit many roadblocks. Have no idea why temp reads -491 or where json is located etc... Just need more simplistic instructions without any assumptions of abilities.
 
Looks promising. Unfortunately I could only get so far. Pretty smart and could follow step by step instructions as per open source distilling, but not having a background in coding etc.... puts me at a disadvantage as I hit many roadblocks. Have no idea why temp reads -491 or where json is located etc... Just need more simplistic instructions without any assumptions of abilities.

I will try to help you get it to work. Since I'm not really sure on how far you have got I will have to make a few assumtions. Based on what you wrote this is a new build and you have not used the iSpindle firmware on it. I also assume you got the gravmon software installed and are able to view the web interface. The temperature indicates that there might be an issue with the temperature sensor since it will default to this value if not found (the ispindle firmware would not even start if it cant detect the temp sensor).

Under the device tab there is a button "show error log", check there if you have an error message connected to the temperature probe.

If thats the case, check if the DS18B20 is soldered correcly and in the right orientation (if its on backwards it will fail).

also check that there is power and ground on the sensor, i had one board that the 5v was broken on.

If this does not solve the problem I would ask you to hook up a serial monitor and send me the output for further troubleshooting (remove any sensitve data, like wifi password before). Instructions for connecting a serial monitor is in the docs.
 
Last edited:
I will try to help you get it to work. Since I'm not really sure on how far you have got I will have to make a few assumtions. Based on what you wrote this is a new build and you have not used the iSpindle firmware on it. I also assume you got the gravmon software installed and are able to view the web interface. The temperature indicates that there might be an issue with the temperature sensor since it will default to this value if not found (the ispindle firmware would not even start if it cant detect the temp sensor).

Under the device tab there is a button "show error log", check there if you have an error message connected to the temperature probe.

If thats the case, check if the DS18B20 is soldered correcly and in the right orientation (if its on backwards it will fail).

also check that there is power and ground on the sensor, i had one board that the 5v was broken on.

If this does not solve the problem I would ask you to hook up a serial monitor and send me the output for further troubleshooting (remove any sensitve data, like wifi password before). Instructions for connecting a serial monitor is in the docs.
Thanks for the suggestion. Backwards it was, which was weird because the video I watched to assemble soldered it backwards as well.

As you can see, the temp is good now, kind of. The house is 70F but it is reading 77.9F inside the sealed petling. Maybe that is normal?
1646966129910.png

The odd part now is that when I connected to Ubidots, the angle and battery are different values than I see in gravmon. The second odd part is that out of the 10 variables that are showing up, I only recognize angle, battery, gravity and interval. The rest are gibberish to me. It's been awhile since I've added variables/dashboards and I'm not sure why temp isn't showing up or how to add it. I'll have to go back and watch some tutorials. Not sure if the push url's I added are correct and have no idea what headers are. Sorry to be a pain.
1646966242601.png

1646966428052.png
 
Thanks for the suggestion. Backwards it was, which was weird because the video I watched to assemble soldered it backwards as well.

As you can see, the temp is good now, kind of. The house is 70F but it is reading 77.9F inside the sealed petling. Maybe that is normal?

The odd part now is that when I connected to Ubidots, the angle and battery are different values than I see in gravmon. The second odd part is that out of the 10 variables that are showing up, I only recognize angle, battery, gravity and interval. The rest are gibberish to me. It's been awhile since I've added variables/dashboards and I'm not sure why temp isn't showing up or how to add it. I'll have to go back and watch some tutorials. Not sure if the push url's I added are correct and have no idea what headers are. Sorry to be a pain.
Good you got that far. Since the device is on when doing the configuration it will show a higher temperature, this will be normal when it has time to cool down between readings if you are using 300seconds or higher.

There is a lot of data in the standard ispindle format but you can customise that to only send the datapoints you want. See Format Editor and Service integration in the docs. There should be documentation on what the parameters means.

This is the format I suggest in the docs, it would send temp, gravity, angle, battery and wifi strength.
{
"temperature": ${temp},
"gravity": ${gravity},
"angle": ${angle},
"battery": ${battery},
"rssi": ${rssi}
}

From you screenshot is indicates that the data in Ubi is one day old? Are you sure the data has been sent? This can be the reason for having different values. There should not be a difference. If you start the device in config mode it will take 15 min (900s as this is the set value) before data is sent to ubidots.

I have not used ubidots myself (other than testing the integration). But I can dig into it more if you dont get it to work.

for testing purposes you can change the interval to like 10s so that the data is updates in ubidots more frequent, dont forget to change it back.
 
Last edited:
Good you got that far. Since the device is on when doing the configuration it will show a higher temperature, this will be normal when it has time to cool down between readings if you are using 300seconds or higher.

There is a lot of data in the standard ispindle format but you can customise that to only send the datapoints you want. See Format Editor and Service integration in the docs. There should be documentation on what the parameters means.

This is the format I suggest in the docs, it would send temp, gravity, angle, battery and wifi strength.
{
"temperature": ${temp},
"gravity": ${gravity},
"angle": ${angle},
"battery": ${battery},
"rssi": ${rssi}
}

From you screenshot is indicates that the data in Ubi is one day old? Are you sure the data has been sent? This can be the reason for having different values. There should not be a difference. If you start the device in config mode it will take 15 min (900s as this is the set value) before data is sent to ubidots.

I have not used ubidots myself (other than testing the integration). But I can dig into it more if you dont get it to work.

for testing purposes you can change the interval to like 10s so that the data is updates in ubidots more frequent, dont forget to change it back.
That's a very good point and no, I'm not 100% sure that the data is being sent (not sure how to verify). This is what I have under push url settings. API token is in place and appears correct, although if it is not sending data, the token may not be correct(?)
1647006641805.png
 
Last edited:
That's a very good point and no, I'm not 100% sure that the data is being sent (not sure how to verify). This is what I have under push url settings. API token is in place and appears correct, although if it is not sending data, the token may not be correct(?)
View attachment 762350
I see you are using the old endpoint, when I tested I used the following endpoint which is different compared to what you used. You should only need one of the URL's for that, unless you are posting to two different accounts. It's probably the bottom one that is most similar to what i have used.

http://industrial.api.ubidots.com/api/v1.6/devices/<devicename>/?token=<api-token>

but you can also set the token as a http header (see docs link below). Please login to ubidots and it should be visible what the endpoint should be. Docs on service integration can be found here; Service Integration - GravityMon 0.8.0 documentation (mp-se.github.io)

If there is a problem with sending data the error should be listed under the device tab and would look like this;
PUSH: HTTP push failed response=<some http response code>

Use the error code to check in the ubidots what it is. OK would be 200. Or post the response here and I can check.

I have in the plan to add some way to test the endpoints since this can be a pain to validate.
 
I see you are using the old endpoint, when I tested I used the following endpoint which is different compared to what you used. You should only need one of the URL's for that, unless you are posting to two different accounts. It's probably the bottom one that is most similar to what i have used.

http://industrial.api.ubidots.com/api/v1.6/devices/<devicename>/?token=<api-token>

but you can also set the token as a http header (see docs link below). Please login to ubidots and it should be visible what the endpoint should be. Docs on service integration can be found here; Service Integration - GravityMon 0.8.0 documentation (mp-se.github.io)

If there is a problem with sending data the error should be listed under the device tab and would look like this;
PUSH: HTTP push failed response=<some http response code>

Use the error code to check in the ubidots what it is. OK would be 200. Or post the response here and I can check.

I have in the plan to add some way to test the endpoints since this can be a pain to validate.
Option 2 worked like a charm, thank you!

I just have 1 other question. Do you still have to calibrate to 25 degrees in pure water like the original firmware says to do?
 
Option 2 worked like a charm, thank you!

I just have 1 other question. Do you still have to calibrate to 25 degrees in pure water like the original firmware says to do?
Its the same approach, 25 is the target but if the angle is between 20-30 it should work fine in pure water. You then need to follow the same approach for calibration as defined on the ispindle docs. I would recommend at least 3 points to get a good formula. You can enter the values in the web interface and have the device create the formula. It will also show a simulated graph of the angle to gravity transformation.
 
I got this up and running today. I'm not running a ds18b20 and set it to use the gyro. Temp works in the web interface, but does not seem to report that temp to brewfather. Is that expected without the ds18b20? If so, is there a way to change it so it is reporting to BF? Btw thanks a ton for your work on this!
 
I got this up and running today. I'm not running a ds18b20 and set it to use the gyro. Temp works in the web interface, but does not seem to report that temp to brewfather. Is that expected without the ds18b20? If so, is there a way to change it so it is reporting to BF? Btw thanks a ton for your work on this!
Thanks for reaching out. It should work with the gyro temp as well. I checked my documentation and I was not that clear so I will update that part.

The Brewfather endpoint is using the custom stream endpoint in brewfather. I tested it on my dev chip and that worked fine. I could see the temperature in brewfather. I will do some tests later today on the iSpindle endpoint as well to see if I can document that.

What endpoint did you use ? iSpindle or Custom ? What version are you using?

The implementation of the brewfather endpoint is basically a http request with the following format template.

{
"name": "${mdns}",
"temp": ${temp},
"aux_temp": 0,
"ext_temp": 0,
"temp_unit": "${temp-unit}",
"gravity": ${gravity},
"gravity_unit": "${gravity-unit}",
"pressure": 0,
"pressure_unit": "PSI",
"ph": 0,
"bpm": 0,
"comment": "",
"beer": "",
"battery": ${battery}
}
 
Last edited:
Oh I see, I was using the iSpindel endpoint. I changed to custom stream, and now I see temp! I don't see voltage now, but my battery is currently disconnected so that's probably expected (plugged in via usb). One other thing I've noticed, and this also may be because I don't have my battery attached, when I lay the device horizontal it does not enter config mode. I have to hit the reset button then it starts up. I will attach my battery today and see if that helps. Thanks again for your work on this and for the assistance with the brewfather push!
 
Oh I see, I was using the iSpindel endpoint. I changed to custom stream, and now I see temp! I don't see voltage now, but my battery is currently disconnected so that's probably expected (plugged in via usb). One other thing I've noticed, and this also may be because I don't have my battery attached, when I lay the device horizontal it does not enter config mode. I have to hit the reset button then it starts up. I will attach my battery today and see if that helps. Thanks again for your work on this and for the assistance with the brewfather push!
You can use the ispindle endpoint as well, just enter the brewfather url under http 1 or 2 instead. That should work fine. Voltage is read and should be transmitted even if its connected via usb. Im also using brewfather and i could see batt on the ispindle endpoint but not custom, i will need to check that and see if its a bug.
 
Awesome, changed to http1 and now I see everything. Thank you!
I cant see the battery when using the custom endpoint either but the data format looks ok. I will need to check with the author if he ignores that data.
 
For sure, I'll be building a couple and test them out and let you know my thoughts.
 
Finally got around to calibrating. Is it ok or normal if the curve is a slope instead of a curve?

1648166161732.png
1648166192236.png
 
I've just released the v0.9 version of GravityMon. There are quite a few changes but it now supports using an ESP32 and that version can send data over bluetooth. I manged to attach an ESP32 D1 mini to a standard iSpindle board and it fits into the same pet tube (tight fit)...

Software is available via brewflasher or direct via Github; Release v0.9.0 · mp-se/gravitymon (github.com)

ispindel.jpg

Changes in this version:
  • Added one http push target that uses HTTP GET. This can be used with ubidots or blynk api's.
  • Added function to test push targets from configuration page. It will send data and show the return code as a first step.
  • Added documetation on how to integrate with Blynk.io using http get.
  • Config page now shows the estimated runtime for the device (based on a full battery and previous average runtime)
  • Experimental release of firmware using an esp32 instead of esp8266
  • Merged index and device pages into one so that all the needed information is available on the index page.
  • Removed api for device (/api/device), it's now merged into the /api/status api.
  • Test function in format editor now uses real data and not fake.
  • Split push configuration into two sections to make it fit better on smaller devices
  • Updated WifiManager and DoubleReset libraries
  • Updated esp32 target with littlefs support
  • Updated esp32 target with BLE send support (it will simulate a tilt)
  • Mounted esp32 d1 mini mounted to a iSpindle PCB 4.0 (CherryPhilip) which worked fine.
  • Documented hardware changes on esp32
  • Default mDNS name is now shown on WIFI setup page.
  • Added option to manually update/downgrade firmware under hardware settings.
  • BUG: Corrected PIN for voltage read on ESP32
  • BUG: If using plato and not gravity formula was defined the value was set to null.
  • BUG: Temp format name was incorrect in iSpindle format causing receiver to incorrectly read temperature.
  • BUG: Temperature sensor adjusmemnt value was not handled properly when using Farenheight.
  • BUG: If the ID was to low the device id could end up with a leading space causing errors in data post. Added leading zero to ID.
  • BUG: Entering wifi setup and a timeout occured the wifi settings could be deleted.
 
Finally got around to making a batch of apfelwein using the new firmware with ubidots. SG and FG were spot on identical to the glass hydrometer readings. Bravo! Definitely recommend it.
 
Finally got around to making a batch of apfelwein using the new firmware with ubidots. SG and FG were spot on identical to the glass hydrometer readings. Bravo! Definitely recommend it.
Thanks, really happy you liked it. Let me know if you have any suggestions for new features. Did you use the suggested format template with UbiDots or did you modify it?
 
This looks really good. I'm very impressed with the documentation. I'm going to give it a go over the next few weeks. Many thanks!
 
Back
Top