SSD1306是一塊常見的小螢幕,解析度為128*64,色彩為單色。
這邊使用的是I2C版本做Demo(也有SPI的但我手邊沒有)。
在Java中要與硬體溝通(GPIO, I2C, SPI, PWM, Serial)通常都會用PI4J這個底層套件包做通訊。
在這個範例中使用的是PI4J v1.4版,最新版是PI4J v2但是我們要用的SSD1306 Lib沒有支援到最新版所以需要降版本使用。
目前PI4J v1.4與Raspberry Pi搭配使用時,會跳出Unable to load [libpi4j.so] using path
這個錯誤,因為PI4J也要依賴Wiring Pi才可以運作,所以我們要先在Raspberry Pi作業系統上安裝WiringPi。
官方說明:https://pi4j.com/1.4/dependency.html
sudo apt-get remove wiringpi -y sudo apt-get --yes install git-core gcc make cd ~ git clone https://github.com/WiringPi/WiringPi --branch master --single-branch wiringpi cd ~/wiringpi sudo ./build
安裝完後就把環境準備好了。
接下來將SSD1306與Raspberry Pi做連接,I2C很方便我們只要把4條線都接上即可。
SSD1306 | Raspberry Pi |
GND | 任一GND |
VCC | 任一3.3V |
SCL | SCL (Pin5) |
SDA | SDA (Pin3) |
連接好後,先來檢查I2C的位址:
sudo i2cdetect -y 1
sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
3c就是我們SSD1306的I2C位址,不同地方買的有可能會不一樣,目前主流預設的位址都是3c。
確認好位址後,就可以開始撰寫主程式囉。
場景轉到Java專案中,首先在pom.xml
加入套件:
測試過了幾套Lib覺得這個比較好用:https://github.com/entrusc/Pi-OLED
<dependencies> <dependency> <groupId>com.pi4j</groupId> <artifactId>pi4j-core</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>de.pi3g.pi</groupId> <artifactId>pi-oled</artifactId> <version>1.2</version> </dependency> </dependencies>
如果專案有使用到module-info.java
架構,記得把Lib加進去:
requires pi4j.core; requires pi.oled;
接下來就可以使用了:
try{ //初始化.連接螢幕 OLEDDisplay display = new OLEDDisplay(); //清除畫面,不清除的話就會一直疊加上去 display.clear(); //使用內建字體顯示文字,顯示在畫面中央,高度在y=25的位置 display.drawStringCentered("Hello World", de.pi3g.pi.oled.Font.FONT_5X8, 25, true); display.update(); }catch (Exception e){ e.printStackTrace(); }
效果:
假如I2C位址不是預設的,則可以在產生OLEDDisplay
物件時進行設定:
OLEDDisplay display = new OLEDDisplay(1, 0x3c);
指定I2C BUS的號碼(預設為1)、設定I2C位址。
但上面的效果常常不是我們想要的,而且不能顯示中文,為了達到最大化靈活性,這邊我會用圖片的方法來顯示我們想要的任何畫面(或文字)。
以下是一個把文字轉換為圖檔的範例,因為螢幕是128*64,所以畫布大小都是用128*64。
private BufferedImage getImg(String text){ //螢幕解析度 int width = 128; int height = 64; // 螢幕是吃 BufferedImage 物件 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); // 使用 Graphics 繪圖 Graphics graphics = image.getGraphics(); // 指定背景顏色為黑色,並填滿 graphics.setColor(Color.BLACK); graphics.fillRect(0, 0, width, height); // 文字為白色,並指定字體產生文字 graphics.setColor(Color.WHITE); Font font = new Font("Arial", Font.PLAIN, 40); graphics.setFont(font); // 取得文字字串的寬高,顯示在畫面中間 FontMetrics fontMetrics = graphics.getFontMetrics(font); int textWidth = fontMetrics.stringWidth(text); int textHeight = fontMetrics.getHeight(); int x = (width - textWidth) / 2; int y = (height - textHeight) / 2 + fontMetrics.getAscent(); // 繪製文字 graphics.drawString(text, x, y); // 釋放資源 graphics.dispose(); return image; }
把產生的BufferedImage
顯示到螢幕上:
display.clear(); //因圖檔大小=螢幕大小,所以從0,0處開始顯示 display.drawImage(getImg("猛禽洛"),0, 0); display.update();
利用BufferedImage
就可以顯示任何想要的畫面了!
-END-
發佈留言