Python code to determine board revision


19 posts
by simplesi » Sat Sep 22, 2012 8:10 pm
I need to modify some code behaviour depending the RPi is a revision 1 or revision 2 board.

Is there method of find out that information from within a Python program?

regards

Simon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 1784
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by sjfaustino » Sat Sep 22, 2012 8:21 pm
/proc/cpuinfo ?
Posts: 87
Joined: Tue Jun 12, 2012 5:21 pm
by simplesi » Sat Sep 22, 2012 8:25 pm
/proc/cpuinfo ?


Doesn't look like any Python code I've come across so far :)

Simon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 1784
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by sjfaustino » Sat Sep 22, 2012 8:45 pm
Sorry, assumed you were familiar with this file and just didn't know it could be used to get several information such as the revision and overvolt bit status.

_VERY_ overkill for what you need but nothing a little pruning and changing won't fix:
http://www.koders.com/python/fidB436B80 ... f%3Apython
Posts: 87
Joined: Tue Jun 12, 2012 5:21 pm
by MattHawkinsUK » Sat Sep 22, 2012 9:14 pm
Here is an article I wrote on getting the board revision in Python :

http://www.raspberrypi-spy.co.uk/2012/09/getting-your-raspberry-pi-revision-number-using-python/
My Raspberry Pi blog and home of the BerryClip Add-on board : http://www.raspberrypi-spy.co.uk/
Follow me on Google+, Facebook and Twitter (@RPiSpy)
User avatar
Posts: 449
Joined: Tue Jan 10, 2012 8:48 pm
Location: UK
by croston » Sat Sep 22, 2012 10:37 pm
The latest RPi.GPIO does this. Check the variable RPI_REVISION. It will be set to either 1 or 2.
User avatar
Posts: 420
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool
by simplesi » Sat Sep 22, 2012 11:16 pm
@croston

You caught me trying to go behind your back :(

I didn't think you'd released V0.4 :(

Sorry - won't do it again :)

So, I use this at the moment
Code: Select all
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11,GPIO.OUT)
GPIO.setup(12,GPIO.OUT)
GPIO.setup(13,GPIO.OUT)
GPIO.setup(15,GPIO.OUT)
GPIO.setup(16,GPIO.OUT)
GPIO.setup(18,GPIO.OUT)
GPIO.setup(22,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(7,GPIO.IN,pull_up_down=GPIO.PUD_UP)


What do i need to change so that is just auto handles Rev1/Rev2 boards? :) (If yoru still speaking to me :) )



Simon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 1784
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by croston » Sat Sep 22, 2012 11:32 pm
You don't need to change a thing if you use board pin numbers.
User avatar
Posts: 420
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool
by simplesi » Sat Sep 22, 2012 11:33 pm
Slighty more pressing problem I just installed 0.4 and now I'm gettting
No module named RPi.GPIO


If I downgrade back to 0.3 - my Python prog works fine :(

Simon
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 1784
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by simplesi » Sat Sep 22, 2012 11:35 pm
I use
Code: Select all
sudo dpkg -i python-rpi.gpio_0.xxxxx_armhf.deb

to install it and don't get any errors

Using it in Python 2 in case that makes a diff
Simon

PS Off to bed now - need to get up in the morning :(
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 1784
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by ACP_ » Sun Sep 23, 2012 12:54 pm
As a side note: you can use my module raspberrypi http://www.raspberrypi.org/phpBB3/viewtopic.php?f=32&t=17388to get boar REV. I believe this is the easiest way (especially since I plan to release new version pretty soon with additional functionality based on vcgencmd wrapper)

Code: Select all
import raspberrypi
print 'Revision :', raspberrypi.hw_rev


Hope that will be helpful.
Posts: 33
Joined: Sat Aug 18, 2012 10:40 pm
by Grumpy Mike » Mon Sep 24, 2012 4:58 am
If you want to do it by "hand" this Python function will do it:-
Code: Select all
def findRevision():
    global boardRevision
    fin = open('/proc/cpuinfo')
    boardRevision = -1
    while True: # go through the file line by line
       line = fin.readline()
       if not line: break # end if reached the end of the file
       if "Revision" in line:
         rev = line[11:15]
         if rev == "0002" or rev == "0003" :
           boardRevision = 1
         if rev == "0004" or rev == "0005" or rev == "0006" :
           boardRevision = 2
    fin.close()
    if boardRevision == -1:
        print "Error can't recognise board revision ", rev
        terminate()
User avatar
Posts: 748
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
by simplesi » Mon Sep 24, 2012 6:45 am
@acp_ and @Grumpy Mike - Ta

Simon
PS for others - the latest RPi.GPIO 0.4.1 now works OK :)
Seeking help with Scratch and I/O stuff for Primary age children
http://cymplecy.wordpress.com/ @cymplecy on twitter
Posts: 1784
Joined: Fri Feb 24, 2012 6:19 pm
Location: Euxton, Lancashire, UK
by BlackJack » Mon Sep 24, 2012 8:10 am
A more pythonic and usable version:
Code: Select all
def get_revision():
    with open('/proc/cpuinfo') as lines:
        for line in lines:
            if line.startswith('Revision'):
                return int(line[line.index(':') + 1:])
    raise RuntimeError('No revision found.')


def get_board_revision():
    revision = get_revision()
    if revision in (2, 3):
        return 1
    if 4 <= revision <= 6:
        return 2
    raise RuntimeError('Can not recognize board revision.')
Code: Select all
while not self.asleep():
    sheep += 1
Posts: 288
Joined: Sat Aug 04, 2012 8:28 am
by Grumpy Mike » Mon Sep 24, 2012 2:27 pm
A more pythonic

Yes certainly more obscure I will give you that. :roll:

Did you know that if you are overclocking you get a very much bigger number for the revision, will that code cope with that?

and usable version:

Not sure I would agree, I use my version very well.
User avatar
Posts: 748
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
by BlackJack » Mon Sep 24, 2012 5:43 pm
@Grumpy Mike: With more pythonic I meant using the features of Python to write more robust, shorter, and more readable code. It seems your definition of readable does not match the idea of the Python developers or Python programmers which choose the language because of that language features.

It may be usable by you. I guess you also have the `terminate()` function defined somewhere.

My code is complete. It can be used to get the firmware and the board revision, not just the latter. It does not print messages or calls a function that terminates the program but raises an exception — it leaves the decision what to print or do in case the revision can not be determined to the programmer who uses these functions.

I do not know that overclocking changes the reported firmware revision and it sounds like a really stupid idea. Sure you don't confuse this with the bogomips value‽ Anyway, the `get_revision()` function can deal with any number that fits into memory. Unlike your code which is limited to 4 digits.
Code: Select all
while not self.asleep():
    sheep += 1
Posts: 288
Joined: Sat Aug 04, 2012 8:28 am
by MattHawkinsUK » Mon Sep 24, 2012 6:52 pm
@BlackJack your code (if I understand it properly) would fail to retrieve a valid number if the user had, for example, a revision code 0002 but had over-volted and triggered the over-volt bit/flag.

@Grumpy Mike is referring to the fact that when over-volting is used the firmware sets an "over-volting" bit. The means in the cpuinfo file the "Revision" reads as "10000002" rather than "0002". In Mike's code this is why he only targets the last 4 digits. As real revisions are only going to increment the number by one this gives the Foundation 9999 revisions before Mike's code stops working.

The thing that confuses the whole topic for some people is that the "Revision" in the cpuinfo file (0002, 0003, 0004 etc) is not aligned to the "Pi Revision" which is either 1.0 or 2.0. There have been plenty of people asking if they have got a Revision 2.0 board because their Revision number is 0002. I wish the Foundation had used a different term.

But for anyone using the RPi.GPIO library the function RPI_REVISION is now the easiest option. I will probably just use that and save myself some lines of code.
My Raspberry Pi blog and home of the BerryClip Add-on board : http://www.raspberrypi-spy.co.uk/
Follow me on Google+, Facebook and Twitter (@RPiSpy)
User avatar
Posts: 449
Joined: Tue Jan 10, 2012 8:48 pm
Location: UK
by BlackJack » Mon Sep 24, 2012 7:46 pm
@MattHawkinsUK: Okay, I did not know that not just the firmware revision is encoded into that value. So just the last four digits:
Code: Select all
def get_revision():
    with open('/proc/cpuinfo') as lines:
        for line in lines:
            if line.startswith('Revision'):
                return int(line.strip()[-4:])
    raise RuntimeError('No revision found.')
Code: Select all
while not self.asleep():
    sheep += 1
Posts: 288
Joined: Sat Aug 04, 2012 8:28 am
by notro » Mon Jul 08, 2013 6:16 pm
BlackJack wrote:A more pythonic version:
Thanks. I have adjusted the code slightly to work with more boards:
Code: Select all
def get_revision():
   with open('/proc/cpuinfo') as lines:
      for line in lines:
         if line.startswith('Revision'):
            return int(line[line.index(':') + 1:], 16) & 0xFFFF
   raise RuntimeError('No revision found.')

def get_board_revision():
   revision = get_revision()
   if revision in (2, 3):
      return 1
   else:
      return 2
Posts: 416
Joined: Tue Oct 16, 2012 6:21 pm
Location: Norway