Iteration 4 - Analog Out | Sending Rotation Angle Between Micro:Bits with Google Sheets and a Flask Server
The Goal
After experimenting with IFTTT, I discovered its webhook integration with Google Sheets. This gave me the idea of using Google Sheets as a cloud-based database, allowing the Micro:Bit to store values remotely and retrieve them via HTTP GET requests. This was the goal for our next iteration.
However, after Arthur and I got this working (more details in his blog), we realized that IFTTT doesn’t handle requests in real time. Instead, requests often stacked up, causing significant delays when sending values to another Micro:Bit. As well as this, we could not configure a HTTP address for the Google Sheets API, therefore GET requests from a Micro:Bit directly to the API were not possible. Around this time, several classmates mentioned Flask, a lightweight Python web framework that acts as a local server, and were using it for similar projects. Initially, I had no plans to incorporate Flask into my iteration, but curiosity led me to try it out and see what it could do
Setting Up Flask
Setting up Flask is rather easy. It's just a simple pip install command on any python instance.
From there an app.py script is required with the Flask import, and one line of code.
This is all that's essentially needed to run the flask server. The next thing I did was write a simple GET request endpoint on the flask server which returns all values in the google sheet and filters out the most recent value. I did this in order to test HTTP requests through a command prompt to see how fast the flask server could handle requests.
As you can see, there is 0.002 seconds of delay on average per request when making these requests on the same local machine. Since I had the code for the GET requests done already through this test, Arthur and I decided to continue with the flask server and compare the two methods.
API Endpoints On Flask
As mentioned before, a HTTP GET endpoint was established on the flask server and without IFTTT-triggered webhooks, we needed another way to send values to the google sheet. To do this I created another endpoint which takes in a raw value through a HTTP POST request and redirects it to google sheets. The result of this gave us 2 clear endpoints which could allow us to send data through HTTP up and down from the cloud between, in theory, as many Micro:Bits as we wanted.
Sending Requests From A Micro:Bit
Once again, part of this was somewhat completed already due to our last iteration using IFTTT, however the GET request from the Micro:Bit did not work directly from Google Sheets. We later found that a HTTP address had to first be configured before the Micro:Bit is able to complete requests. Since the Google Sheets API has no direct IP for requests, Our only option was to send the requests on my laptop and write them to the Micro:Bit through serial. Which is technically cheating in my opinion.
Switching back to Flask, since the local server has a direct HTTP address and port, sending requests back and forth worked flawlessly and was incredibly easy to set up. Below on the code for the GET request on the Micro:Bit, you can see it is essentially just one block which handles the value returned by the GET request and sets it to a variable. That variable is then being printed to the LED panel on the Micro:Bit.
As for the POST request from the Micro:Bit, this too was really simple with the rotation variable being send through a POST request directly to the Flask server as shown in the code below.
Are There Any Bottlenecks For Requests?
As with most request based systems, real time streaming of data comes with some challenges. For us this was the speed in which the Micro:Bit could process the POST requests, with each request taking on average 1.5 seconds to be received by the local server. In most cases this speed would be considered real time and works very fast, However, if we were to implement a system that records data such as heart rate, which requires rapid sampling of multiple data points, sending each individual sample through a POST request would be inefficient. This approach would disrupt the timing and result in inaccurate calculations, such as the calculation of beats per minute (BPM).
How Do We Solve This?
The next iteration would have to have data streaming, where many samples are sent in a single POST and are essentially unravelled after reaching the flask server. However, this has proven to be difficult due to the lack of JSON compatibility on a Micro:Bit. As well as this, the original code written for the POST endpoint on the Flask server could only take in a single raw value per request, so I needed to refactor a bit, both on the Micro:Bit and the Flask Server.
Comments
Post a Comment