Microbit:POV wheel project

Questions and discussion about running MicroPython on a micro:bit board.
Target audience: MicroPython users with a micro:bit.
Post Reply
gingemonster
Posts: 3
Joined: Sat Jul 23, 2016 10:57 pm

Microbit:POV wheel project

Post by gingemonster » Sat Jul 23, 2016 11:05 pm

Hi Guys

I have been playing around with the microbit trying to get a persistence of vision bike wheel display working where it writes words as the wheel spins on a bike.

I have written some code and it essential works, using the compass to detect a magnet on the bike frame as the microbit (fixed to the spokes) passes the frame. BUT it doesn't seem synchronized enough for the effect to actually work. I'm wondering if any of the following are factors and thought people on this forum may have some insight:

1) My codes just wrong (always the most likely it's at the bottom of the post) I don't write much python
2) The LEDs cannot cycle fast enough (seems unlikely)
3) I shouldn't use the whole matrix to write letters but just one row (is what all commercial version of this do)
4) The magnet sensing is just too inaccurate
5) I shouldn't use the higher level "display" functionality to write letters but should turn on and off the LEDS I need myself, perhaps display has inherent speed constraints?
6) something else I haven't considered ;-)

Thanks for any advice or insight you can give

Here is the code:
====================================


# Example code to display a message on a rotating bike wheel by fixing the
# microbit to a spoke and a magenet to the bike fork. Each time the
# microbit passes the magenet we know the wheel has rotated once
from microbit import *


def areAllValuesInRange(timeToCompleteOneRev, timeToMoveOneDegree, timeBetweenLetters, message):
if timeToCompleteOneRev < timeToMoveOneDegree:
return False
if len(message) * (timeToMoveOneDegree + timeBetweenLetters) > timeToCompleteOneRev:
return False
if timeToMoveOneDegree > timeBetweenLetters:
return false
return True

# displays each letter for a given time then leaves a time gap between the next letter
def displayMessage(message, timeBetweenLetters):
display.show(message, timeBetweenLetters, wait=False, loop=False, clear=True)

# works out the current revolutions per minute (RPM) of the wheel
def calculateTimeToCompleteOneRev():
global lastReadTime
# using the global variable timeSinceLastReading work out the time difference between now
# and the last reading time in milliseconds
now = running_time()
timeSinceLastReading = now - lastReadTime

# set new last read time as now
lastReadTime = now

return timeSinceLastReading



# works out how long a time gap to leave between each letter
# degreesToSpan is how many degrees to spread the letters over
def calculateLetterTimeGap(numLetters, timeToMoveOneDegree, degreesToSpan = 300):
# work out given the number of degrees to spread out over, the number of letters
# and the time it takes to move one degree, what time gap to leave between letters
return int(degreesToSpan / numLetters * timeToMoveOneDegree)

def calculateTimeToMoveOneDegree(timeToCompleteOneRev):
return int(timeToCompleteOneRev / 360)

lastReadTime = 0
hasPassedTrigger = False

while True:
# the message we want to write
# try out different things like leaving spaces between letters
# and spaces before you message so that the first letter appears
# a little after the magnt is triggered
message = " M I C R O : B I T"

# the field strength reading from the compass that we associate with the magnet
# passing the microbit you will need to tweak this value for your own magnet
fieldStrengthTriggerLevel = 200000
fieldStrengthReading = compass.get_field_strength()
# print(fieldStrengthReading)

if not hasPassedTrigger and fieldStrengthReading > fieldStrengthTriggerLevel:
print("field strength triggered: " + str(fieldStrengthReading))
# set hasPassedTrigger True here so that this logic does not trigger again until the next revolution when the magnetic
# field has gone below fieldStrengthTriggerLevel again
hasPassedTrigger = True

# get the current time it takes to complete one revolution (turn) of the wheel
timeToCompleteOneRev = calculateTimeToCompleteOneRev()
print("time to complete one rev:" + str(timeToCompleteOneRev/1000) + " seconds")
timeToMoveOneDegree = calculateTimeToMoveOneDegree(timeToCompleteOneRev)
print("time to move one degree:" + str(timeToMoveOneDegree) + " ms")

# get the time we should leave between each letter
timeBetweenLetters = calculateLetterTimeGap(len(message), timeToMoveOneDegree)
print("time between letters:" + str(timeBetweenLetters) + " ms")

# check all values are in range expected, if not return to start of while loop
if not areAllValuesInRange(timeToCompleteOneRev, timeToMoveOneDegree, timeBetweenLetters, message):
print("some values not in range, probably getting wheel up to speed")
continue

# clear display incase its still displaying something
# it should not be unless the RPM suddenly changed i.e as the bike starts
display.clear()

# write message, assume we want to only show letter for the time it takes to move 1 degree
# average bike wheel is aprox. 630mm circumference so 1 degree is aprox, 2mm of distance
# which should be ok for letter's appearing in one location on the wheel
displayMessage(message, timeBetweenLetters)

elif compass.get_field_strength() < fieldStrengthTriggerLevel:
# field strength fallen below trigger so make sure we set hasPassedTrigger false
# ready for next trigger
hasPassedTrigger = False

gingemonster
Posts: 3
Joined: Sat Jul 23, 2016 10:57 pm

Re: Microbit:POV wheel project

Post by gingemonster » Sun Jul 24, 2016 7:19 pm

Updated my code to try:

3) I shouldn't use the whole matrix to write letters but just one row (is what all commercial version of this do)

Didn't seem to make any real difference that I could see, also tried extending the period of time each frame is displayed for.

One other thought is I have to round the length to display an LED to an int as the display class only takes ms in ints, perhaps that could have an effect but from my calculations it seems unlikely

gingemonster
Posts: 3
Joined: Sat Jul 23, 2016 10:57 pm

Re: Microbit:POV wheel project

Post by gingemonster » Sun Jul 24, 2016 8:28 pm

Digging a little deeper perhaps this idea is dead in its tracks:

https://mail.python.org/pipermail/micro ... 00767.html

and

https://mail.python.org/pipermail/micro ... 00768.html

The critical but being "The complete cycle to illuminate all the LEDs takes 18 millseconds." which might suggest even displaying a few takes more than 1-3ms which is what you seem to need for a POV project :-(

Post Reply