レフィクシア技術ブログ

レフィクシア社員が様々な技術を紹介します。

コミュニケーションロボットの構想~その2

あけましておめでとうございます(2週間遅れですが…)  
今年も技術情報を皆さんに発信していきます!

 

前回はコミュニケーションロボットの構想ということで簡単な機構のモデルを紹介しましたが、今回は少し組み込み系の内容になります.

コミュニケーションロボットにとって目という部位は重要なファクターとなります  
喜怒哀楽の感情表現ができると愛着が湧きそうです  
というわけで、目の実装をしてみたいと思います。  

必要なもの

用意するのは以下の物品  
①1.28インチ 丸形液晶ディスプレイモジュール 240×240  
マイコン(今回はESP32-WROVER-E)  
③ジャンプワイヤー8本  

f:id:Lefixea:20220118204039j:plain

f:id:Lefixea:20220118204046j:plain

1.28インチ 液晶モジュール

この液晶モジュールはスイッチサイエンスなどでも購入できます  

www.switch-science.com

この液晶はGC9A01というドライバーが積まれており、SPI通信で制御することができます.  


マイコンはスペックが高いものがより高速に描画できたり、表示できる領域が増えます.  
STM32やRaspberry Pi Picoなどでも良いかもしれません。

 

接続方法  

ESP32の場合は以下のように接続してください  

ESP32 液晶モジュール
3V3 VCC
14 SC
18 CLK
23 DIN
27 DC
32 BL
33 RST
GND GND

f:id:Lefixea:20220118204032j:plain

接続(きたない…)

STM32やPicoなどの他のマイコンを使う場合はSPI通信を行うピンを使用してください.

 

プログラム

Arduinoで書いていきます.

描画系のライブラリはいくつかありますが、今回はLovyanGFXを使用させて頂きました.

github.com

git cloneしてライブラリフォルダに配置するか、zipでダウンロードしてArduino IDEの[スケッチ] > [ライブラリのインクルード] > [.ZIP形式のライブラリをインストール]で読み込みます.

 

基本的な使い方はreadmeに書かれています.

今回はロボットっぽくSF感のある目を描画してみようと思います.

ソースコード

#include "LGFX_ESP32_sample.hpp" // またはユーザ自身が用意したLGFXクラスを準備します


static LGFX lcd;                 // LGFXのインスタンスを作成。
static LGFX_Sprite sprite(&lcd); // スプライトを使う場合はLGFX_Spriteのインスタンスを作成。

int cx;
int cy;
int x_max = 240;            // x軸移動最大値
int x_min = 0;              // x軸移動最小値
int y_max = 240;            // y軸移動最大値
int y_min = 0;              // y軸移動最小値
int over_y = 0;             // まぶたのy軸移動量

static int radius = 50;
static int r1 = 105;         // 円弧1内側半径
static int r2 = 110;         // 円弧1外側半径
static int dang = 60;       // 円弧の長さ
static int bet_ang = 30;    // 円弧同士の幅
static int speed = 2;       // 回転速度
static int over_speed = 1; 

int angle_count = 0;


static int back_color[3] = {255, 255, 255};
static int blue_eye[3] = {255, 0, 0};
static int red_eye[3];
static int green_eye[3];

// 1週分の円弧をつなげて表示
void drawArc(int x, int y, int r1, int r2, int angle1) {
  sprite.fillArc(x, y, r1, r2, angle1, angle1+dang, lcd.color332(blue_eye[0], blue_eye[1], blue_eye[2]));
  int angle2 = angle1+dang+bet_ang;
  sprite.fillArc(x, y, r1, r2, angle2, angle2+dang, lcd.color332(blue_eye[0], blue_eye[1], blue_eye[2]));
  int angle3 = angle2+dang+bet_ang;
  sprite.fillArc(x, y, r1, r2, angle3, angle3+dang, lcd.color332(blue_eye[0], blue_eye[1], blue_eye[2]));
  int angle4 = angle3+dang+bet_ang;
  sprite.fillArc(x, y, r1, r2, angle4, angle4+dang, lcd.color332(blue_eye[0], blue_eye[1], blue_eye[2])); 
}

// 中央に目を配置
void drawCenterEye(int x, int y, int rx, int ry) {
  sprite.fillEllipse(x, y, rx, ry, lcd.color332(blue_eye[0], blue_eye[1], blue_eye[2]));
}

// 上まぶたを配置
void drawOverEye(int x, int y, int width, int height) {
  sprite.fillRect(x, y, width, height, lcd.color332(back_color[0], back_color[1], back_color[2]));
}

void setup(void)
{
  lcd.init();                    // 最初に初期化関数を呼び出します。
  lcd.setRotation(2);            // 回転方向を 0~3 の4方向から設定します。(4~7を使用すると上下反転になります。)
  lcd.setBrightness(128);         // バックライトの輝度を 0~255 の範囲で設定します。
  lcd.setColorDepth(8);         // RGB888の24ビットに設定(表示される色数はパネル性能によりRGB666の18ビットになります)

  cx = x_max/2;
  cy = y_max/2;

}

void loop(void)
{
    // 円弧の回転処理
    if(angle_count >= 360) {
        angle_count = 0;
    }
    angle_count += speed;

    // まぶたの移動処理
    if(over_y >= 50) {
      over_speed = -over_speed;
    } if(over_y < 0) {
      over_speed = -over_speed;
    }
    over_y += over_speed;

    sprite.createSprite(240, 240);
    sprite.setColorDepth(8);
    sprite.fillScreen(lcd.color332(back_color[0], back_color[1], back_color[2]));
    sprite.setPivot(cx, cy);
    drawCenterEye(cx, cy, radius/2, radius);
    drawOverEye(0, 170-over_y, 240, 70);
    drawArc(cx, cy, r1, r2, angle_count);
    sprite.pushSprite(0, 0);


    delayMicroseconds(10);

}

このコードを実行すると以下のようなものが出来上がります

f:id:Lefixea:20220118204952g:plain

アニメーションしている様子

 

このような感じで液晶モジュールにアニメーションを描画することができます.

これで感情を表現できるロボットの目を作っていきます.

 

それではまた。