Lucas Girard
Lucas Girard

Reputation: 13

How to use the grovepi with pi4jv2 on Java?

I recently wanted to use a grove lcd rgb display using the pi4j v2 library with a raspberry pi 3, os: dietpi. I followed all the pi4j documentation (https://www.pi4j.com/about/new-in-v2/) , I also followed the documentation (a bit dated) of the grove library (https://dexterind.github.io/GrovePi/). Despite all my attempts, I can't write on the i2c ports with pi4j. However, I get no error on the console when I launch the jar, and my test script tells me that I'm writing to it. The i2c ports are enabled on the dietpi, and strangely enough, my tests work just fine in python. Have you ever encountered a similar problem?

Here's my java example test: (Note: the GrovePi4j class is a preconfigured class supplied by the grove library. The i2c inputs/outputs are preconfigured and identical to those in the python example.)



import java.io.IOException;
import java.util.Random;

import com.github.yafna.raspberry.grovepi.GroveDigitalOut;
import com.github.yafna.raspberry.grovepi.GrovePi;
import com.github.yafna.raspberry.grovepi.devices.GroveRgbLcd;
import com.github.yafna.raspberry.grovepi.pi4j.GrovePi4J;
import com.pi4j.Pi4J;
import com.pi4j.context.Context;


public class LcdService {
    
    public void exec() throws IOException, InterruptedException {
        Context pi4j = Pi4J.newAutoContext();
        GrovePi grovePi = new GrovePi4J(pi4j);
        GroveRgbLcd lcd = grovePi.getLCD();

        String[] phrases = new String[]{
          "Hi! ALL!",
          "This should work just fine",
          "A message\nA response",
          "More data that you can handle for sure!",
          "Welcome to the internet of things with java",
          "Short\nMessage"
        };
        int[][] colors = new int[][]{
          {50, 255, 30},
          {15, 88, 245},
          {248, 52, 100},
          {48, 56, 190},
          {178, 25, 180},
          {210, 210, 210}
        };
        while (true) {
          try {
            String text = phrases[new Random().nextInt(phrases.length)];
            int[] color = colors[new Random().nextInt(colors.length)];
            lcd.setRGB(color[0], color[1], color[2]);
            Thread.sleep(100);
            lcd.setText(text);
            Thread.sleep(2000);
          } catch (IOException io) {
          }
        }
    }
}

Here's my python example test:

import time,sys

if sys.platform == 'uwp':
    import winrt_smbus as smbus
    bus = smbus.SMBus(1)
else:
    import smbus
    import RPi.GPIO as GPIO
    rev = GPIO.RPI_REVISION
    if rev == 2 or rev == 3:
        bus = smbus.SMBus(1)
    else:
        bus = smbus.SMBus(0)

# this device has two I2C addresses
DISPLAY_RGB_ADDR = 0x62
DISPLAY_TEXT_ADDR = 0x3e

# set backlight to (R,G,B) (values from 0..255 for each)
def setRGB(r,g,b):
    bus.write_byte_data(DISPLAY_RGB_ADDR,0,0)
    bus.write_byte_data(DISPLAY_RGB_ADDR,1,0)
    bus.write_byte_data(DISPLAY_RGB_ADDR,0x08,0xaa)
    bus.write_byte_data(DISPLAY_RGB_ADDR,4,r)
    bus.write_byte_data(DISPLAY_RGB_ADDR,3,g)
    bus.write_byte_data(DISPLAY_RGB_ADDR,2,b)

# send command to display (no need for external use)
def textCommand(cmd):
    bus.write_byte_data(DISPLAY_TEXT_ADDR,0x80,cmd)

# set display text \n for second line(or auto wrap)
def setText(text):
    textCommand(0x01) # clear display
    time.sleep(.05)
    textCommand(0x08 | 0x04) # display on, no cursor
    textCommand(0x28) # 2 lines
    time.sleep(.05)
    count = 0
    row = 0
    for c in text:
        if c == '\n' or count == 16:
            count = 0
            row += 1
            if row == 2:
                break
            textCommand(0xc0)
            if c == '\n':
                continue
        count += 1
        bus.write_byte_data(DISPLAY_TEXT_ADDR,0x40,ord(c))

#Update the display without erasing the display
def setText_norefresh(text):
    textCommand(0x02) # return home
    time.sleep(.05)
    textCommand(0x08 | 0x04) # display on, no cursor
    textCommand(0x28) # 2 lines
    time.sleep(.05)
    count = 0
    row = 0
    while len(text) < 32: #clears the rest of the screen
        text += ' '
    for c in text:
        if c == '\n' or count == 16:
            count = 0
            row += 1
            if row == 2:
                break
            textCommand(0xc0)
            if c == '\n':
                continue
        count += 1
        bus.write_byte_data(DISPLAY_TEXT_ADDR,0x40,ord(c))

# Create a custom character (from array of row patterns)
def create_char(location, pattern):
    """
    Writes a bit pattern to LCD CGRAM

    Arguments:
    location -- integer, one of 8 slots (0-7)
    pattern -- byte array containing the bit pattern, like as found at
               https://omerk.github.io/lcdchargen/
    """
    location &= 0x07 # Make sure location is 0-7
    textCommand(0x40 | (location << 3))
    bus.write_i2c_block_data(DISPLAY_TEXT_ADDR, 0x40, pattern)

# example code
if __name__=="__main__":
    setText("Hello world\nThis is an LCD test")
    setRGB(0,128,64)
    time.sleep(2)
    for c in range(0,255):
        setText_norefresh("Going to sleep in {}...".format(str(c)))
        setRGB(c,255-c,0)
        time.sleep(0.1)
    setRGB(0,255,0)
    setText("Bye bye, this should wrap onto next line")

Upvotes: 0

Views: 37

Answers (1)

user82523
user82523

Reputation: 11

Use the Linux i2cdetect tool to confirm that the Grove LCD RGB Display is correctly detected on the I2C bus

sudo i2cdetect -y 1

addresses 0x62 and 0x3E should appear (the addresses for the backlight and text, respectively). If they don’t, check the wiring and connection.

Upvotes: 0

Related Questions