domesday
Posts: 258
Joined: Fri Oct 21, 2011 5:53 pm
Location: UK

Decimal to Binary Library

Sat Jun 09, 2012 10:52 am

I wonder if someone might like to help build a library for python.

I have an idea for teaching binary by attaching 8 LEDs to the GPIO port and having a simple python program that would take a decimal number and output it as a binary number to the GPIO pins.

So I though the best way to go about it would be create a library perhaps called BinaryIO that could be called simply by doing something like.

'BinaryIO == 3'

This would light up the first two LED's on the GPIO.

Anyone think they could do that ?

yeahbox
Posts: 36
Joined: Sun May 27, 2012 10:35 pm
Location: Manchester, UK

Re: Decimal to Binary Library

Sat Jun 09, 2012 11:06 am

domesday wrote:I wonder if someone might like to help build a library for python.
I have an idea for teaching binary by attaching 8 LEDs to the GPIO port and having a simple python program that would take a decimal number and output it as a binary number to the GPIO pins.
Python has a very large standard library, maybe what you want to do is already supported. Try playing around with some built in stuff:

Code: Select all

pi@raspberrypi:~$ python
Python 2.6.6 (r266:84292, Dec 27 2010, 21:57:32) 
[GCC 4.4.5 20100902 (prerelease)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> hex(100)
'0x64'
>>> 0x64
100
>>> ord('a')
97
>>> chr(97)
'a'
>>> bin(3)
'0b11'
>>> 0b11
3
>>> 
So to answer your question, bin(3) will output 0b11 which is the binary representation of the number 3

domesday
Posts: 258
Joined: Fri Oct 21, 2011 5:53 pm
Location: UK

Re: Decimal to Binary Library

Sat Jun 09, 2012 11:16 am

Thanks for the suggestion, that solves half of the problem, I guess the question would be how to convert the binary '0b11' so that it would provide a value for each GPIO. So the missing part and the part I'm not sure how to do would be to convert '0b11' to IO0 == 1, IO1 == 1, IO2 == 0 etc..

sharpapotheosis
Posts: 58
Joined: Thu May 24, 2012 6:47 pm

Re: Decimal to Binary Library

Sat Jun 09, 2012 1:11 pm

The binary command that yeahbox gave produces a string output. This means we can use python's string handling methods very easily to analyse the string and gain some output from it.

In python you can use strings as if they are arrays, which means you can address individual characters. For example:

Code: Select all

>>> x = "Hello world"
>>> print x
'Hello World'
>>> print x[0]
'H'
>>> print x[6]
'w'
>>> print x[2:4]
'll'
So what we want to do here is to look at each individual bit in the binary number, and if it's a 1, turn the relevant pin high, and if it's a 0, turn the relevant pin low.

Firstly it makes sense to remove the "0b" from the binary number given to us. To do this, we can use the string methods shown above. The colon on the last example given meant "to", so in the example above we went from character number 2 to character number 4. In this example, we want the first character we keep to be character number 2 (the third character, remember the indices start at 0) and we want to go all the way to the end. the code for that looks like this:

Code: Select all

x = x[2:]
We've left the number after the colon blank since that means "go to the end". So that gets rid of the first two characters. If we are using the example of the number being three 3, out code looks like this:

Code: Select all

>>> x = bin(3)
>>>print x
'0b11'
>>>x = x[2:]
>>> print x
'11'
So now what I would recommend doing is adding the correct number of "0"s on to the string to make the correct number of bits long. Lets use 8. To do this, we need to know two things. Firstly, we can multiply strings. So 'print "Hello World" * 3' would print 'Hello WorldHello WorldHello World'. The second thing we need to work out is the length of the string already. The command 'len(str)' does this for us, where str is the string. So len("Hello World") return 11.

We need to calculate how many 0s we need at the start of our number, then add that many 0s to the start of our string:

Code: Select all

>>> number_of_zeros = 8 - len(x)
>>> x = "0" * number_of_zeros" + x
>>> print x
'00000011'
Finally, we just need to assign the bits to their pins. So we check whether a character is 1 or 0, and then write "True" or "False" to the right pin. This code is just for the least significant bit:

Code: Select all

>>> if x[7] == "1":
...     GPIO.output(pin_number, True)
... else:
...     GPIO.output(pin_number, False)
So try it, if you want, but I'll see if I can wrap it up in a neat class :P

domesday
Posts: 258
Joined: Fri Oct 21, 2011 5:53 pm
Location: UK

Re: Decimal to Binary Library

Sat Jun 09, 2012 1:28 pm

Thats good thanks for the explanation.

That is really good because it means someone learning could actually set the GPIO using binary, decimal or hex, so they can better understand the number systems used.

sharpapotheosis
Posts: 58
Joined: Thu May 24, 2012 6:47 pm

Re: Decimal to Binary Library

Sat Jun 09, 2012 1:42 pm

I've put it in a really neat class, except it's not working ;D

I can't seem to get the inheritance from the RPi.GPIO class working...

domesday
Posts: 258
Joined: Fri Oct 21, 2011 5:53 pm
Location: UK

Re: Decimal to Binary Library

Sat Jun 09, 2012 1:48 pm

You know the RPi.GPIO class requires root privileges ?

sharpapotheosis
Posts: 58
Joined: Thu May 24, 2012 6:47 pm

Re: Decimal to Binary Library

Sat Jun 09, 2012 2:03 pm

Yep, it's my python class abilities that are to fault :P

Anyway, I've got something working now. The source looks like this:

Code: Select all

import RPi.GPIO as GPIO
class BinaryObject():
	def __init__(self, p):
		self.pin_array = p
		for i in self.pin_array:
			GPIO.setup(i, GPIO.OUT)
		
	def showBinary(self, x):
		x = bin(x)[2:]
		x = "0" * (8 - len(x)) + x
		for i in range(8):
			if x[i] == "1":
				GPIO.output(self.pin_array[i], True)
			else:
				GPIO.output(self.pin_array[i], False)
You can download the file here. Save the file in the same directory as you're working in, or in the python modules directory if you'll use it a lot.

An example of usage:

Code: Select all

import BinaryIO
x = BinaryObject([21,19,15,13,11,7,5,3]) 
x.showBinary(3)
In the brackets on line 2 should be an array containing the 8 pins your LEDs are connected to, with the most significant bit first (look at the numbers here). The value you pass in showBinary should be 0-255 inclusive.

yeahbox
Posts: 36
Joined: Sun May 27, 2012 10:35 pm
Location: Manchester, UK

Re: Decimal to Binary Library

Sat Jun 09, 2012 3:03 pm

Great that you have something up and working! I just want to make a note here about strings, since the OP wants to teach/learn about numbers and binary representations. Keep in mind that the above methods work on strings and not the actual values. This is usually fine and strings in Python are really nice to work with. But if we really want to understand what is going on below the hood we need to work with some integers. For example, the string "101" is actually an array of bytes with (integer) values [48, 49, 48]. So we are not really working with bits if we use the strings above.

So instead we could do this the hard way, which is the proper way in a sense. Basically we want to bitshift to the right and mask away the bits that are not interesting. For example:

Code: Select all

>>> b = 5
>>> bin(b)
'0b101'
>>> (b >> 2) & 0x1
1
>>> (b >> 1) & 0x1
0
>>> (b >> 0) & 0x1
1
Here we are really working with the bits that make up the value 5. This is probably how one would work in C also.

EDIT: of course the string "101" is [49, 48, 49] but even the sun has spots :)

sharpapotheosis
Posts: 58
Joined: Thu May 24, 2012 6:47 pm

Re: Decimal to Binary Library

Sat Jun 09, 2012 3:20 pm

I didn't know you could do bitshifting like that in python. Cool :P I've used it in arduino stuff before, but it's new to me :P

For the OPs sake though, shouldn't you use 0b1 instead of 0x1 to keep it in binary (rather than using hex, which, while it makes perfect sense, is not what we're dealing with here). Also, even when you've bitshifted you still have to use the If else statement to write to the actual pins.

yeahbox
Posts: 36
Joined: Sun May 27, 2012 10:35 pm
Location: Manchester, UK

Re: Decimal to Binary Library

Sat Jun 09, 2012 3:56 pm

Well, the 0b1 notation is sort of a python thing but 0x1 is more general since all languages that I've been exploring so far have all understood hex notation. So in my opinion hex notation like 0x1 or 0xFF is very useful to learn early on when one is dealing with bitshifts and bitwise logic (AND, OR, XOR) since they are so closely related.

texy
Forum Moderator
Forum Moderator
Posts: 5160
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England

Re: Decimal to Binary Library

Sat Jun 09, 2012 10:01 pm

sharpapotheosis wrote:Yep, it's my python class abilities that are to fault :P

Anyway, I've got something working now. The source looks like this:

Code: Select all

import RPi.GPIO as GPIO
class BinaryObject():
	def __init__(self, p):
		self.pin_array = p
		for i in self.pin_array:
			GPIO.setup(i, GPIO.OUT)
		
	def showBinary(self, x):
		x = bin(x)[2:]
		x = "0" * (8 - len(x)) + x
		for i in range(8):
			if x[i] == "1":
				GPIO.output(self.pin_array[i], True)
			else:
				GPIO.output(self.pin_array[i], False)
You can download the file here. Save the file in the same directory as you're working in, or in the python modules directory if you'll use it a lot.

An example of usage:

Code: Select all

import BinaryIO
x = BinaryObject([21,19,15,13,11,7,5,3]) 
x.showBinary(3)
In the brackets on line 2 should be an array containing the 8 pins your LEDs are connected to, with the most significant bit first (look at the numbers here). The value you pass in showBinary should be 0-255 inclusive.
Many thanks for the code in this post - it has helped me write a routine for a LCD driver.

Texy
Various male/female 40- and 26-way GPIO header for sale here ( IDEAL FOR YOUR PiZero ):
https://www.raspberrypi.org/forums/viewtopic.php?f=93&t=147682#p971555

sharpapotheosis
Posts: 58
Joined: Thu May 24, 2012 6:47 pm

Re: Decimal to Binary Library

Sun Jun 10, 2012 2:42 pm

Many thanks for the code in this post - it has helped me write a routine for a LCD driver.
I saw the driver before I saw this post and thought "wow, they've done it in a very similar fashion to me" :P

Although as an update: I forgot about the "bool()" function when writing the above code, and have since realised that instead of using the if else statements, this line works:

Code: Select all

GPIO.output(self.pin_array[i], bool(x[i]))

Return to “Python”