rpi-rgb-led-matrix
rpi-rgb-led-matrix copied to clipboard
Updating matrix panels from a flask app
I am using a raspberry pi 4 with six 32x16 outdoor p10 matrix panels. They are being used as part of a sports scoreboard (cricket).
To interface with the board, I am trying to build a very simple RESTful API using flask. It is just a post method which takes in a string that essentially specifies what score to display on a particular panel.
I am having problems getting the displays to work properly when they are part of the flask app. Standalone, they work fine (I can display and update numbers to all panels with no issues whatsoever).
The issue is a little difficult to describe, so I'll use some pictures. Anyone have any ideas of how I could get it to work properly?
-
When I start the web service, the 'OVERS' panel will display '0'

-
Then I send a post request to update the number to '33.2'

-
All good it seems ... but after a small amount of time (variable, but of the order of a few seconds), the number fades away back to '0' with a residual ghosted outline of '33.2'

(Actually, even in 2) you can make out a ghosted outline of the original '0').
I don't think there is anything too controversial with my code (not a seasoned python programmer btw).
Here is the flask app:
from scoreboard import Scoreboard
from flask import Flask, request
app = Flask(__name__)
scoreboard = Scoreboard()
scoreboard.display() # Default display
def update_scoreboard_display(requestJson):
requestData = requestJson['data']
scoreType = requestData[0:3]
scoreData = requestData[3:]
updateScoreboard = True
if scoreType == "OVB":
scoreboard.setOversBowled(float(scoreData))
if updateScoreboard:
scoreboard.display()
@app.route('/scoreboard', methods=['POST'])
def get_scoreboard_data():
requestJson = request.get_json()
update_scoreboard_display(requestJson)
return '', 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port='80', debug=True)
And here is some of my scoreboard code. I have omitted the utility code which translates which pixels to switch on for which number. Essentially, each number maps to a set of pixels which should be switched on, this is implemented in the loop in the 'display' method. My panel options are shown in the constructor.
from scoreboardUtils import ScoreboardArray, ScoreboardArrayController
from rgbmatrix import RGBMatrix, RGBMatrixOptions
class Scoreboard(object):
def __init__(self):
self.values = [0, 0.0, 0, 0, 0, 0]
options = options = RGBMatrixOptions()
options.rows = 16
options.cols = 32
options.chain_length = 6
options.parallel = 1
options.row_address_type = 0
options.multiplexing = 8
options.pwm_bits = 1
options.brightness = 100
options.hardware_mapping = "adafruit-hat"
options.pwm_lsb_nanoseconds = 1300 # Default was 130
options.led_rgb_sequence = "RGB"
options.pixel_mapper_config = ""
options.panel_type = ""
options.gpio_slowdown = 4
options.drop_privileges = False
#options.daemon = 0
#options.show_refresh_rate = True
self.matrix = RGBMatrix(options = options)
digitStrokeInPixels = 2
self.controller = ScoreboardArrayController(options.cols, options.rows, digitStrokeInPixels)
def setOversBowled(self, oversBowled):
self.values[1] = oversBowled
def display(self):
decimalSizeInPixels = 2
margin = 2
rightMargin = 2
offset_canvas = self.matrix.CreateFrameCanvas()
for i in range(len(self.values)):
scoreboardArray = ScoreboardArray(self.values[i], True if (i == 1) else False, decimalSizeInPixels, self.controller, margin, 0.5*rightMargin if (i == 1) else rightMargin)
for x in range(i*self.controller.arrayWidth, (i+1)*self.controller.arrayWidth):
for y in range(0, self.matrix.height):
if (scoreboardArray.IsDigitPixel(y,x-i*self.controller.arrayWidth)):
offset_canvas.SetPixel(x,y,255,255,255)
offset_canvas = self.matrix.SwapOnVSync(offset_canvas)
flask runs multiple threads simultaneously. You might need to disable multithreading or rework the application. Suggest stackoverflow for this question instead of this repo