[Banana Pi] GPIO now supported

Things go really fast around the Banana Pi board.
Lemaker team released the Raspbian_for_BananaPi_V3 image, and it is a very nice step in the good direction. Some additional documentation is also available, and hacking with the Banana Pi can really start.

See the Raspbian_for_BananaPi_V3 release notes :

> The Raspbian version is based on the newest original version 1.3.8 released by raspberry pi at 2014-06-20;
> Change the SD partition from 4 partitions to 2 partitions; Delete the noobs partitios for Raspberry Pi;
> This Raspbian can both been used to boot Banana Pi and Raspberry Pi;
> Kernel version for Banana Pi is 3.4.90, for Raspberry Pi is 3.12.2;
> The default login account is pi/bananapi;
> Do some changes in the FEX configure for Banana Pi;
> Modified the gpio driver to make it compatible with RPi.GPIO;
> Added the i2c-sunxi and i2cdev drivers into kernel;
> Added the spi-sun7i.ko and spi-dev.ko into modules;
> Added the led driver into kernel, the user-defined led will blink like a heartbeat;
> Open the driver support for CSI cammera such as ov5460;
> Pre-installed the Arduino 1.5.4;
> Pre-installed the S4A;
> Pre-installed the modified RPi.GPIO for Banana Pi and Raspberry Pi; it can be used for both Banana Pi and the directory is /opt/gpio_lib;Delete the default RPi.GPIO just for Raspberry Pi;
> Pre-installed the modified wiringPi for Banana Pi, it is just a beta version, but most basic function works well except the spi has some little bug; users can test your wiringPi programe on Banana Pi
> Pre-installed the modified ScratchGPIO5 for Banana Pi,it is also has some little bugs;
> Fix the shutdown problem, it can cut off the power completely;
> Pre-installed the eject so that you can safely remove the storage device;
> Pre-installed the ntfs-3g so that you can write the NTFS sata drive;
> Change the default desktop wallpaper to new Banana Pi wallpaper;
> Enable the serial port login from ttyS0;
> Fix the dynamic mac address problem.

So, in short :
– the Banana Pi Raspbian image can boot both in a Raspberry and in a Banana
– GPIO are now (almost) working as intended. Wiringpi v1 and RPi.GPIO librairies are now working, and Raspberry numbering scheme is respected (but is fully customizable)
– working i2c and SPI
– onboard green led is now user definable (not part of the main GPIO header)
– fixed shutdown problem
– ntfs support

With the GPIO basically working, the Banana Pi can now be used like a Raspberry. But with better hardware.

GPIO header

Here is the official Banana Pi GPIO documentation for the main headers :
gpio

pic1Here is my own pinout table, with both Banana and Raspberry and additional functions (more about this later). One can notice the similar pinouts. I did this using the available schematics : A20_Blockdiagramm_BananaPI
There’s a PDF version here.

I will update it if there’s missing/wrong information, everything is still not 100% clear

Banana
Pi

FUNCTIONS

[SUNXI-PIN]

[WiringPi]

Raspberry
Pi

FUNCTION

[BCM
rev1, rev2]

[WiringPi]

Header

Raspberry
Pi

FUNCTION

[BCM
rev1, rev2]

[WiringPi]

Banana
Pi

FUNCTIONS

[SUNXI-PIN]

[WiringPi]

3,3v

3,3v

1

2

5v

5v

TWI2-SDA
[PB21] [8]


SDA0
[1,2] [8]

3

4

5v

5v

TWI2-SCK
[PB20] [9]


SCL0
[2,3] [9]

5

6

GND

GND

GPCLK
[PI3] [7]


GPIO7
[4] [7]

7

8


TXD
[14] [15]


UART3_TX

[PH0] [15]

GND

GND

9

10


RXD

[15] [16]


UART3_RX

[PH1] [16]

IO-0,
UART2_RX

SPI1_MISO
[PI19] [0]


GPIO0
[17] [0]

11

12


GPIO1
[18] [1]

IO-1
[PH2] [1]

IO-2,
UART2_TX

SPI1_MOSI
[PI18] [2]


GPIO2
[21,27] [2]

13

14

GND

GND

IO-3,
UART2_CTS
SPI1_CLK [PI17]
[3]


GPIO3
[22] [3]

15

16


GPIO4
[23] [4]

IO-4,
CAN_TX [PH20] [4]

3,3v

3,3v

17

18


GPIO5
[24] [5]

IO-5,
CAN_RX [PH21] [5]


SPI0_MOSI
[PI12] [12]


MOSI
[10]
[12]

19

20

GND

GND


SPI0_MISO
[PI13] [13]


MISO

[9]
[13]

21

22

[GPIO6]
[25] [6]

IO-6,
UART2_RTS
SPI1_CS0
[PI16] [6]


SPI0_CLK
[PI11] [14]


SCLK

[11]
[14]

23

24


CE0
[8] [10]


SPI0_CS0
[PI10] [10]

GND

GND

25

26


CE1
[7] [11]


SPI0_CS1
[PI14] [11]

Banana
Pi

FUNCTIONS

[SUNXI-PIN]

[WiringPi]

Raspberry
Pi

FUNCTION

[BCM
rev1, rev2]

[WiringPi]

Header

Raspberry
Pi

FUNCTION

[BCM
rev1, rev2]

[WiringPi]

Banana
Pi

FUNCTIONS

[SUNXI-PIN]

[WiringPi]

So, GPIOs, I2C, SPI, UART are at the same place, and wiringpi keeps the same numbering scheme. Very convenient. Let’s go.

1 – GPIO

Because making some experiments doesn’t mean doing something useless, I will add two usefull features :
– RGB status LED
– multipurpose button : shutdown, reboot and an unused function.

Let’s check wiringpi version and GPIOs state at boot :
Capture du 2014-07-18 16:20:40For ease, I will name the GPIOs with BOARD scheme (« phys » column).
For the red LED, we will use a GPIO that is HIGH during boot. This way, the LED will start fix red for « not ready yet ». We will use GPIO 13.
Green and Blue doesn’t really matter, I will use GPIO 11 and 15.
For a nicer effect, and to test it, the « heartbeat » will use wiringpi software PWM.

Button is on GPIO 18.
3 functions are possible on this single button, using different pression durations. Short press is everything between 0.1s and 1s, long press is > 1s (restart), very long press is > 4s (shutdown).

Here is the code, also available on GitHub :

#!/usr/bin/env python2.7

from time import sleep
import subprocess
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD) # choose BCM or BOARD numbering schemes. I use BOARD 

button_A = 18 # GPIO channel 24 is on pin 18 of connector P1
# it will work on any GPIO channel
# Optional 50K Ohm pull up to 3.3v. A push button will ground the pin, creating a falling edge.

long_press = 1 #s
very_long_press = 4 #s

red = 16 # set pin 16 for red led
green = 11 # set pin 11 for green led 
blue = 15 # set pin 15 for blue led 

Freq = 60 #Hz
pause_time = 0.01 # you can change this to slow down/speed up

GPIO.setup(button_A, GPIO.IN, pull_up_down=GPIO.PUD_UP) # set button pin as input
GPIO.setup(red, GPIO.OUT) # set red led pin as output
GPIO.setup(green, GPIO.OUT) # set green led pin as output
GPIO.setup(blue, GPIO.OUT) # set blue led pin as output
RED = GPIO.PWM(red, Freq)
GREEN = GPIO.PWM(green, Freq)
BLUE = GPIO.PWM(blue, Freq)

RED.start(0)
GREEN.start(0)
BLUE.start(0)

state = 1

def system_button(button_A):
	global state
	
	button_press_timer = 0
	while True:
			if (GPIO.input(button_A) == False) : # while button is still pressed down
				button_press_timer += 0.1 # keep counting until button is released
			else: # button is released, count for how long
				if (button_press_timer > very_long_press) : # pressed for > 5 seconds
					# do what you want with a very long press
					print "very long press : ", button_press_timer
					state = 0
					subprocess.call(['shutdown -h now "System halted by GPIO action" &'], shell=True)
					
				elif (button_press_timer > long_press) : # press for > 1 < 5 seconds 					# do what you want with a long press 					print "long press : ", button_press_timer 					state = 2 					subprocess.call(['sudo reboot &'], shell=True) 					 				elif (button_press_timer > 0.1):
					# do what you want with a short press
					print "short press : ", button_press_timer

				button_press_timer = 0
			sleep(0.1)

GPIO.add_event_detect(button_A, GPIO.FALLING, callback=system_button, bouncetime=100)
# setup the thread, detect a falling edge on channel and debounce it with 100mSec
	
# assume this is the main code...
try:
	while True:
		
		# do whatever while "waiting" for falling edge on channel
		for i in range(0,101):      # 101 because it stops when it finishes 100 
			if state == 0:
				RED.ChangeDutyCycle(i)
				GREEN.ChangeDutyCycle(0)
				BLUE.ChangeDutyCycle(0)
			if state == 1:
				RED.ChangeDutyCycle(0)
				GREEN.ChangeDutyCycle(i)
				BLUE.ChangeDutyCycle(0)
			if state == 2:
				RED.ChangeDutyCycle(i)
				GREEN.ChangeDutyCycle(0)
				BLUE.ChangeDutyCycle(100 - i)
			sleep(pause_time) 
			
		for i in range(100,-1,-1):      # from 100 to zero in steps of -1 
			if state == 0:
				RED.ChangeDutyCycle(i)
				GREEN.ChangeDutyCycle(0)
				BLUE.ChangeDutyCycle(0)
			if state == 1:
				RED.ChangeDutyCycle(0)
				GREEN.ChangeDutyCycle(i)
				BLUE.ChangeDutyCycle(0)
			if state == 2:
				RED.ChangeDutyCycle(i)
				GREEN.ChangeDutyCycle(0)
				BLUE.ChangeDutyCycle(100 - i)
			sleep(pause_time) 
			
except KeyboardInterrupt:
	GPIO.cleanup()       # clean up GPIO on CTRL+C exit
GPIO.cleanup()           # clean up GPIO on normal exit

Everything is working as expected… Very nice !

2 – I2C and RTC1307

I won’t reinvent the wheel, and I will use my RTC DS1307 tutorial for Raspberry Pi.
Let’s list the I2C buses :
Capture du 2014-07-18 02:59:47So we have five I2C buses. Trying the i2cdetect tool on each one should tell us where is our RTC. We are looking for 0x68 address.

Capture du 2014-07-18 04:08:43Here it is, on /dev/i2c-2 !

Unfortunately, there’s is no trace of the ds-1307 module in the kernel. So, the ds-1307 adventure stops here.

3 – I2C and LCD2004

So I’m now trying with something that doesn’t need a module : a LCD2004 display. I’ll follow my own LCD2004 display on Raspberry Pi tutorial step by step, starting at step #3.

Check if the LCD is detected :

Capture du 2014-07-18 14:18:30It’s there, with 0x27 address.

I just have to modify the i2c bus number in i2c_lib.py :

class i2c_device:
def __init__(self, addr, port=2):

Full result :

 

Here is the final script.

note : the 2 tiny green leds on the left are low level cpu cores status. I will cover this later, this is a complete procedure on its own.

About Captain Stouf

Spécialiste en systèmes informatiques, Développeur matériel et logiciel, Inventeur, Maker : électronique, Systems on Chip, micro-controlleurs, Internet of Things, Modélisation / Scan / Impression 3D, Imagerie...

10 thoughts on “[Banana Pi] GPIO now supported

  1. rv4848
    07/08/2014 at 18 h 38 min

    Do you know if it’s possible to supply the banana pi from GPIO like in the Raspberry Pi ?

    1. Captain Stouf
      07/08/2014 at 18 h 48 min

      Hi,
      no, powering the Banana pi from GPIO is not possible

  2. Ted
    01/12/2014 at 20 h 38 min

    Hi, I’m running your button-script and it works pretty fine. Now I’m trying to start it at boot time (init.d and cron tried). It starts but nothing happens on button-press. Do you have any ideas? the process is running.
    thanks
    ted

    1. Captain Stouf
      01/12/2014 at 20 h 41 min

      Hi,
      Try putting it in /etc/rc.local instead.

Laisser un commentaire