Micro:bit uPython: HTTP UART OBLOQ POST request to Flask server

In this tutorial we are going to learn how to send a HTTP POST request using a micro:bit board and a UART OBLOQ.

Introduction

In this tutorial we are going to learn how to send a HTTP POST request using a micro:bit board and a UART OBLOQ. We will be using MicroPython to program the micro:bit board.

Please visit this previous tutorial to check the connection diagram between the two devices. Also, please check this post for a detailed explanation on how to connect the UART OBLOQ to a WiFi network, using the micro:bit board to send the serial commands.

For this tutorial, we will setup a Python Flask server, which will receive our request and return back to the client a very simple message. For an introductory tutorial on Flask, please check here.

The Flask code

As usual, we will begin our Python code with the imports. We will need the Flask class, which we will use to configure our server, and the request object, which will be used to access the request body and headers.

from flask import Flask, request

After that, we will create an object of the Flask class we have just imported. We will make use of this object to configure the routes of our server and to start the application.

app = Flask(__name__)

Our server will have a single route, which will only listen to HTTP POST requests. We will call our route “/post“.

@app.route('/post', methods = ["POST"])
def post():

Then, in the implementation of the route handling function, we will first print the body of the request, so we make sure the received content matches the one sent from the micro:bit.

print(request.data)

Additionally, we will also print the headers of the received request.

print(request.headers)

To finalize the code of our route handling function, we will return a string to the client indicating the request was received.

return 'Received'

To finalize the whole Python code, we need to call the run method on our Flask object, so the server starts listening to incoming requests.

This method receives the IP and the port where the server will be listening. We will use the IP “0.0.0.0“, which indicates the server should listen in all the available interfaces. As port, we will use 8090.

The final Flask code can be seen below and already includes the run method call.

from flask import Flask, request

app = Flask(__name__)

@app.route('/post', methods = ["POST"])
def post():

    print(request.data)
    print(request.headers)
    return 'Received'

app.run(host='0.0.0.0', port= 8090)

The micro:bit code

We will start the MicroPython code with the imports. We will need the uart object and the sleep function, which are both available in the microbit module.

from microbit import uart, sleep

After that, and like we did on this previous post, we will define a helper function that allows to read content from the serial port until a given character is received.

This will be a very simple helper function that will not have any timeout safeguard, which means that it will basically loop infinitely until the expected character is received. Naturally, this is just to keep the code simple and in a real application scenario you should implement some safeguard mechanisms to prevent your code from entering an undesired infinite loop.

This function will have as input a uart object and the termination character and it will return all the content read until that character.

def readUntil(uartObject, termination):
  result = ''

  while True:
    if uartObject.any():

        byte = uartObject.read(1)

        result = result + chr(byte[0])

        if chr(byte[0]) == termination:
          break

    sleep(100)

  return result

After defining this utility function, we will initialize the serial interface to use the micro:bit pins 0 and 1 for Tx and Rx, respectively.

uart.init(baudrate=9600, tx = pin0, rx = pin1)

Then, we will flush the garbage byte that is sent by the micro:bit when opening the serial connection. We do this by sending a command termination character (“\r“) to the serial port. This will force the UART OBLOQ to complete the current command that it was building.

Since the command doesn’t exist, the UART OBLOQ should return back the |1|-1| value plus the “\r” termination character. So, we can flush it by using the readUntil function to read until the “\r” character is received.

Note: Flushing this byte is only needed if you are using an older version of MicroPython. In the newer versions, this bug is no longer present. For this tutorial I’m using version 1.7.0, which still suffers from this issue.

uart.write("\r")
readUntil(uart, '\r')

Next we will connect the UART OBLOQ to a WiFi network, which is needed before we try to do the actual POST request. The procedure was covered in detail on this previous tutorial.

The MicroPython command to use is the one shown below, where you should place the credentials of your WiFi network.

uart.write("|2|1|yourNetworkName,yourNetworkPassword|\r")

After we send this command,  the UART OBLOQ should return |2|1| to acknowledge its reception. Then, it should periodically return |2|2| during the WiFi connection procedure. Please take in consideration that it may take sometime until the UART OBLOQ finishes to establish the connection.

After a successful connection, it will return a |2|3|ipAddress| response, where ipAddress corresponds to the IP assigned to the UART OBLOQ on the network.

Taking this in consideration, we can leverage our readUntil function to wait for the character ‘3‘. This should get all the content until the UART OBLOQ sends back to us the IP it got from connecting to the network.

Then, we can call the readUntil function again to get the rest of the answer, which includes the IP. In this case, since we don’t need the IP for any of the next function calls, we don’t need to store the returned value from the readUntil function.

readUntil(uart, '3')
readUntil(uart, '\r')

After this, we can finally send the HTTP POST request. The UART OBLOQ command we should use is covered in greater detail on this previous post. Basically, we should send the serial command in the following format:

|3|2|destinationURL,postBody|

In our case, since we are reaching a local Flask server, the destination URL takes the following format, where you should change #yourFlaskMachineIp# by the local IP of the computer that is running the server:

http://#yourFlaskMachineIp#:8090/post

The full MicroPython command can be seen below. Note that we are simply sending a string with the value “test” as body of our request.

uart.write("|3|2|http://192.168.1.83:8090/post,test|\r")

The format of the answer returned by the UART OBLOQ is the following:

|3|HTTPResponseCode|RequestResponseBody|

So, we will first read bytes until we receive the value ‘3‘ and after that we will read content again until the end of the command (which corresponds to the character ‘\r‘). In this second readUntil function call, we will store the result that contains the response from the server.

readUntil(uart, '3')
result = readUntil(uart, '\r')

To finalize, we will re-enable the MicroPython prompt and print the content returned by the server. The final code can be seen below.

from microbit import uart, sleep

def readUntil(uartObject, termination):
  result = ''

  while True:
    if uartObject.any():

        byte = uartObject.read(1)

        result = result + chr(byte[0])

        if chr(byte[0]) == termination:
          break

    sleep(100)

  return result

uart.init(baudrate=9600, tx = pin0, rx = pin1)

uart.write("\r")
readUntil(uart, '\r')

uart.write("|2|1|yourNetworkName,yourNetworkPassword|\r")

readUntil(uart, '3')
readUntil(uart, '\r')

uart.write("|3|2|http://192.168.1.83:8090/post,test|\r")

readUntil(uart, '3')
result = readUntil(uart, '\r')

uart.init(baudrate=115200)
print(result)

Testing the code

To test the whole system, start by running the Flask server in a Python tool of your choice. I’ll be using IDLE, a Python IDE.

Then, after finishing all the connections between the micro:bit and the UART OBLOQ, run the previous MicroPython script on the micro:bit. Once the script finishes executing, you should get an output similar to figure 1.

As can be seen, after running the script, we obtain both the status code (200, which indicates success) and the message we have defined in the Flask code.

Sending HTTP POST request to Flask server using micro:bit and the UART OBLOQ, with microPython

Figure 1 – Output of the MicroPython script.

If you check the output in the environment where you are running the Flask server, you should get a result similar to figure 2, which shows the reception of the request sent by the UART OBLOQ.

As can be seen, the server received the ‘test‘ string we have sent. We can also check the headers of the request. Note that we don’t have any control over the headers, which are defined by the UART OBLOQ firmware.

Reception of HTTP POST request from UART OBLOQ on a Flask Server

Figure 2 – Reception of the POST request on the Flask server.

Related Posts

Advertisements

One Reply to “Micro:bit uPython: HTTP UART OBLOQ POST request to Flask server”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s