I thought it would be a fun idea to turn my BBC Microbit into a digital clock - specifically, a binary digital clock. I knocked up a bit of code in Python to do just that:
from microbit import *
def makeBinary(intValue,padding):
number = intValue
returnValue = ""
brightness = 4 #value 0 to 8
while number > 0:
bit = number % 2
if bit > 0:
bit = brightness
quotient = number / 2
returnValue = str(bit)+returnValue
number = quotient
for i in range(len(returnValue),padding):
returnValue = "0"+returnValue
return returnValue
timeAdvance = 0
minuteAdvance = 0
hourAdvance = 0
secondCounter = 0
while True:
if button_a.was_pressed():
#advance hours
hourAdvance = hourAdvance + 1
if hourAdvance > 23:
hourAdvance = 0
timeAdvance = (hourAdvance*60*60*1000)+(minuteAdvance*60*1000)
elif button_b.was_pressed():
#advance minutes
minuteAdvance = minuteAdvance + 1
if minuteAdvance > 59:
minuteAdvance = 0
timeAdvance = (hourAdvance*60*60*1000)+(minuteAdvance*60*1000)
else:
#calculate and display time
if (running_time()-secondCounter) > 1000:
secondCounter = running_time()
seconds = (running_time()/1000)%60
minutes = ((running_time()+timeAdvance)/1000/60)%60
hours = ((running_time()+timeAdvance)/1000/60/60)%24
pmString = "0"
addthirtyMString = "00000"
addthirtySString = "00000"
if hours>12:
pmString = "9"
hours = hours - 12
if minutes>29:
addthirtyMString = "00900"
minutes = minutes - 30
if seconds>29:
addthirtySString = "00900"
seconds = seconds - 30
hourString = makeBinary(hours,4)
minuteString = makeBinary(minutes,5)
secondString = makeBinary(seconds,5)
time = Image(pmString+hourString+":"+minuteString+":"+addthirtyMString+":"+secondString+":"+addthirtySString)
display.show(time)
The problem is that is doesn't work! Running it on the Microbit results in the binary fields returning all 1 unless the number is 0. So 10:48:01AM is (incorrectly) displayed as
****
*****
*****
It should be displayed as
* *
* *
*
*
Given that the am/pm led, and the add 30 seconds / add 30 minutes markers work fine this is clearly just an issue with formatting up a binary representation of the decimal number (the makeBinary
function). I initially tried using 'format' to do this - but microPython, at least on the microBit, clearly doesn't like it.
When I run makeBinary
on my 'real' computer, it works fine. Does anyone have any idea what might be amiss here? Or any suggestions for other simple ways of converting decimal to a binary string without using any functions which might confuse the MicroBit?
The microbit uses python 3 for micropython. This means that the division of two integers will often return a float value, not an integer. If you explicitly want integer division you should use //
(Which will also work with Python 2.) To summarise:
Py 2 Py 3 and microbit
35 / 10 3 3.5
35 // 10 3 3
35.0 / 10 3.5 3.5
Since hours is coming out as float, it is confusing the make_binary()
function, which expects an int.
quotient = number // 2
[...]
seconds = (running_time()//1000)%60
minutes = ((running_time()+timeAdvance)//60000)%60
hours = ((running_time()+timeAdvance)//3600000)%24
Should fix the first problems with division.
If you install and use python 3 on the computer you might find it easier to debug.
Now, python already has a bin()
function that takes an integer and returns a binary expression as a string
>>> bin(58)
'0b111010'
And your code should be using this instead of writing your own.