B4J Question [solved][IoT] Raspberry & WiringPi & B4J & LCD 2x16

KMatle

Expert
Licensed User
Longtime User
After some tries with B4J I took this working Python Script to check if my wiring is ok:

B4X:
import time
import RPi.GPIO as GPIO

# GPIO <-> HD44780 LCD ZUORDNUNG
DISPLAY_RS = 2
DISPLAY_E  = 3
DISPLAY_DATA4 = 4
DISPLAY_DATA5 = 14
DISPLAY_DATA6 = 15
DISPLAY_DATA7 = 17
DISPLAY_LIGHT = 10

# HD44780 HARDWARE-FACTS
DISPLAY_WIDTH = 16
DISPLAY_LINE_1 = 0x80
DISPLAY_LINE_2 = 0xC0
DISPLAY_CHR = True
DISPLAY_CMD = False
E_PULSE = 0.00005
E_DELAY = 0.00005

# GPIO INIT
GPIO.setmode(GPIO.BCM) # Verwenden der BCM GPIO Zahlen
GPIO.setwarnings(False)
GPIO.setup(DISPLAY_E, GPIO.OUT)
GPIO.setup(DISPLAY_RS, GPIO.OUT)
GPIO.setup(DISPLAY_DATA4, GPIO.OUT)
GPIO.setup(DISPLAY_DATA5, GPIO.OUT)
GPIO.setup(DISPLAY_DATA6, GPIO.OUT)
GPIO.setup(DISPLAY_DATA7, GPIO.OUT)
GPIO.setup(DISPLAY_LIGHT, GPIO.OUT)

# HD44780 senden
def lcd_byte(bits, mode):
    GPIO.output(DISPLAY_RS, mode)
    GPIO.output(DISPLAY_DATA4, False)
    GPIO.output(DISPLAY_DATA5, False)
    GPIO.output(DISPLAY_DATA6, False)
    GPIO.output(DISPLAY_DATA7, False)
    if bits&0x10==0x10:
      GPIO.output(DISPLAY_DATA4, True)
    if bits&0x20==0x20:
      GPIO.output(DISPLAY_DATA5, True)
    if bits&0x40==0x40:
      GPIO.output(DISPLAY_DATA6, True)
    if bits&0x80==0x80:
      GPIO.output(DISPLAY_DATA7, True)
    time.sleep(E_DELAY)
    GPIO.output(DISPLAY_E, True)
    time.sleep(E_PULSE)
    GPIO.output(DISPLAY_E, False)
    time.sleep(E_DELAY)
    GPIO.output(DISPLAY_DATA4, False)
    GPIO.output(DISPLAY_DATA5, False)
    GPIO.output(DISPLAY_DATA6, False)
    GPIO.output(DISPLAY_DATA7, False)
    if bits&0x01==0x01:
      GPIO.output(DISPLAY_DATA4, True)
    if bits&0x02==0x02:
      GPIO.output(DISPLAY_DATA5, True)
    if bits&0x04==0x04:
      GPIO.output(DISPLAY_DATA6, True)
    if bits&0x08==0x08:
      GPIO.output(DISPLAY_DATA7, True)
    time.sleep(E_DELAY)
    GPIO.output(DISPLAY_E, True)
    time.sleep(E_PULSE)
    GPIO.output(DISPLAY_E, False)
    time.sleep(E_DELAY)

# HD44780 Zeile schreiben
def lcd(zeile,text):
    if zeile == 1:
        lcd_byte(DISPLAY_LINE_1, DISPLAY_CMD)
    if zeile == 2:
        lcd_byte(DISPLAY_LINE_2, DISPLAY_CMD)
       
    message = text.ljust(DISPLAY_WIDTH," ")
    for i in range(DISPLAY_WIDTH):
        lcd_byte(ord(message[i]),DISPLAY_CHR)
       
# HD44780 initialisiserung und loeschen
def lcd_init():
    lcd_byte(0x33,DISPLAY_CMD)
    lcd_byte(0x32,DISPLAY_CMD)
    lcd_byte(0x28,DISPLAY_CMD)
    lcd_byte(0x0C,DISPLAY_CMD)
    lcd_byte(0x06,DISPLAY_CMD)
    lcd_byte(0x01,DISPLAY_CMD)
       
# HD44780 Hintergrundbeleuchtung ein oder aus
def lcd_backlight(what):
    GPIO.output(DISPLAY_LIGHT, what)
   


lcd_init()

lcd(1,'Powerdev.de')
lcd(2,'LCD HD44780')
lcd_backlight(True)

Because I want to have the same in B4J I took a look to our beloved "How to's" site: http://www.rwblinn.de/b4j/b4jhowto/528.htm to use the magic WiringPi.

The installation was successfull on the pi:

B4X:
pi@raspberrypi /home $ gpio readall
+-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
| BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
|     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
|   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5V      |     |     |
|   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
|   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT0 | TxD     | 15  | 14  |
|     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
|  17 |   0 | GPIO. 0 |   IN | 1 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
|  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
|  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
|     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
|  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |
|   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
|  11 |  14 |    SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |
|     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |
|   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
|   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
|   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
|  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
|  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
|  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
|     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
+-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
pi@raspberrypi /home $

I've put it in a B4J app and let it run:

B4X:
Dim lcd As JavaObject
    lcd.InitializeStatic("com.pi4j.wiringpi.Lcd")
    'int  lcdInit (int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4, int d5, int d6, int d7) ;
    Dim handle As Int = lcd.RunMethod("lcdInit", Array(2,16,4,2,3,4,14,15,17,0,0,0,0))
    lcd.RunMethod("lcdPuts", Array(handle, "text"))

It runs without an error, but it does not work.

- Is something missing? (It looked like a working example)
- handle is: 0 (0x0)
- there are no errors/exceptions
- wrong GPIO-Pins? (the Python example is working)
 

rwblinn

Well-Known Member
Licensed User
Longtime User
Hi,

I can not test - you triggered me to buy a LCD for the Pi :) - but think the pins needs to be defined and initialized first in B4J like done in Phyton.
So probably something like:
B4X:
Private Pin2 As GpioPinDigitalOutput
Pin1.Initialize(2, True)

Etc for the other Pins. Then call the API methods - if working let know and the HowTo will be enhanced (and not only show the API methods).
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
I first did it that way but I had problems to initialize the LCD (Switch to 4 Bit mode, etc.). Then I found the python script which worked at once (to check if I have broken the lcd due to my previous tries). Will give it a try the next days.
 
Upvote 0

Toley

Active Member
Licensed User
Longtime User
Hi KMatle, did you declare and initialize GpioController first?

I have this code working for me, but I surely don't have the same pinout as you.

B4X:
Sub Process_Globals
    Private controller As GpioController
End Sub

Sub AppStart (Args() As String)
    controller.Initialize
    Private lcd As JavaObject
    lcd.InitializeStatic("com.pi4j.wiringpi.Lcd")
   
    'int lcdInit(int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4,
    '     int d5, int d6, int d7);
    Private handle As Int = lcd.RunMethod("lcdInit", Array(2,16,4,3,14,4,12,13,6,0,0,0,0))
    lcd.RunMethod("lcdPosition", Array(handle, 0,0))
    lcd.RunMethod("lcdPuts", Array(handle, "Test LCD on Rpi"))
    lcd.RunMethod("lcdPosition", Array(handle, 0,1))
    lcd.RunMethod("lcdPuts", Array(handle, "Pi4j with B4J"))
    'StartMessageLoop        ' Comment if don't want to run continiously
End Sub
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
@Toley : Thank's but it still does not work:

B4X:
 controller.Initialize
    Private lcd As JavaObject
    lcd.InitializeStatic("com.pi4j.wiringpi.Lcd")
 
    'int lcdInit(int rows, int cols, int bits, int rs, int strb, int d0, int d1, int d2, int d3, int d4,
    '     int d5, int d6, int d7);
    Private handle As Int = lcd.RunMethod("lcdInit", Array(2,16,4,2,3,4,14,15,17,0,0,0,0))
    lcd.RunMethod("lcdPosition", Array(handle, 0,0))
    lcd.RunMethod("lcdPuts", Array(handle, "Test LCD on Rpi"))
    lcd.RunMethod("lcdPosition", Array(handle, 0,1))
    lcd.RunMethod("lcdPuts", Array(handle, "Pi4j with B4J"))

The python script (same pins) works. Is something missing on the Raspberry? Did you change the mapping or other things? I don't get errors so it must be a mapping thing.

"handle" is set to zero. Is that correct?
 
Upvote 0

KMatle

Expert
Licensed User
Longtime User
Well. It's easy:

Take a look at the pi's hardware pins:

GPIO_Pi2.png


If you wan to use GPIO2 you would plug the cable to physical pin #3, GPIO3 to #5 and so on.

When you use libs to access it (like to use a lcd) these libs use WiringPi components on the Raspberry. WiringPi is good to map the pin-names like you need it. The idea seems to keep your app unchanged even if f.e. Raspberry model 3 is released with an other pin layout. Rempap them and all is good.

In the RaspBerry's prompt type "gpio readall" which will give you the mapping:

B4X:
pi@raspberrypi /home $ gpio readall
+-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
| BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
|     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
|   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5V      |     |     |
|   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
|   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT0 | TxD     | 15  | 14  |
|     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
|  17 |   0 | GPIO. 0 |   IN | 1 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
|  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
|  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
|     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
|  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |
|   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
|  11 |  14 |    SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |
|     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |
|   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
|   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
|   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
|  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
|  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
|  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
|     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
+-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
| BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
+-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+

Our GPIO2 is physical pin #3. Now search in the table under column "Physical". In the line with "3" you can see that it has been remapped to #8, physical pin #3 (GPIO3 on the picture) is now 9. That's it. Very confusing at the start.

I will write a tutorial how to wire and drive a lcd with B4J.
 
Upvote 0
Top