3

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?

Brian
  • 14,610
  • 7
  • 35
  • 43
headbanger
  • 1,038
  • 1
  • 11
  • 32

1 Answers1

2

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.

James K
  • 3,692
  • 1
  • 28
  • 36
  • Thanks for this James - your integer / float answer fits the bill perfectly! In fact, I tried bin - but the Microbit threw a wobbler at the trimming of the 0b and the padding to the required length (perhaps also due to my own misunderstanding of format in Python 3?) No matter! It all works now. – headbanger Aug 26 '16 at 18:04