pdf-icon

Arduino入門

2. デバイス&サンプル

5. 拡張モジュール&サンプル

アクセサリー

6. アプリケーション

Chain Mono 使用チュートリアル

1. 準備

  • 環境設定: Arduino IDE 入門チュートリアル を参考に IDE のインストールを完了し、実際に使用する開発ボードに応じて対応するボードマネージャと必要なドライバライブラリをインストールします。

  • 使用するドライバライブラリ:

  • 使用するハードウェア製品:

2. サンプルプログラム

コンパイル要件
M5Stack ボードマネージャバージョン >= 3.2.4
M5Chain ライブラリバージョン >= 1.0.4

ピクセルモード

単一ピクセル制御と一括書き込み

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
#include "M5Chain.h"
#include "M5Unified.h"

#define TXD_PIN GPIO_NUM_2
#define RXD_PIN GPIO_NUM_1

Chain M5Chain;

chain_status_t chain_status = CHAIN_OK;
uint8_t mono_id          = 0;
uint8_t operation_status = 0;

bool findFirstMonoDevice()
{
    // Enumerate devices and use the first Mono node
    uint16_t device_nums = 0;
    if (M5Chain.getDeviceNum(&device_nums) != CHAIN_OK || device_nums == 0) {
        Serial.println("No Chain devices found");
        return false;
    }

    device_info_t *infos = (device_info_t *)malloc(sizeof(device_info_t) * device_nums);
    if (infos == nullptr) {
        return false;
    }

    device_list_t devices;
    devices.count   = device_nums;
    devices.devices = infos;

    bool found = false;
    if (M5Chain.getDeviceList(&devices)) {
        for (uint8_t i = 0; i < devices.count; i++) {
            if (devices.devices[i].device_type == CHAIN_MONO_TYPE_CODE) {
                mono_id = devices.devices[i].id;
                found   = true;
                break;
            }
        }
    }

    free(infos);
    if (found) {
        Serial.printf("Mono device found, id=%d\r\n", mono_id);
    } else {
        Serial.println("No Mono device found");
    }
    return found;
}

bool prepareMono()
{
    // Initialize display mode, rotation, and brightness
    if (!findFirstMonoDevice()) {
        return false;
    }

    if (M5Chain.setMonoMode(mono_id, MONO_PIXEL_MODE, &operation_status) != CHAIN_OK || operation_status != 1) {
        return false;
    }

    M5Chain.setMonoRotation(mono_id, MONO_ROTATION_0, &operation_status);
    M5Chain.setMonoBrightness(mono_id, MONO_BRIGHTNESS_LEVEL_7, &operation_status);
    M5Chain.setMonoClear(mono_id, &operation_status);
    return true;
}

void setup()
{
    M5.begin();
    Serial.begin(115200);
    Serial.println("Pixel demo");
    M5Chain.begin(&Serial2, 115200, RXD_PIN, TXD_PIN);

    if (!prepareMono()) {
        Serial.println("Chain Mono init failed");
        while (1) {
            delay(100);
        }
    } else {
        Serial.println("Chain Mono init success");
    }
}

void loop()
{
    static bool single_phase = true;
    static uint8_t single_x  = 0;
    static uint8_t single_y  = 0;
    static uint8_t block_x   = 0;
    static uint8_t block_y   = 4;

    if (single_phase) {
        // Walk through the first 4 rows with a single pixel
        M5Chain.setMonoClear(mono_id, &operation_status);
        chain_status = M5Chain.setMonoPixel(mono_id, single_x, single_y, true, &operation_status);
        if (chain_status == CHAIN_OK && operation_status == 1) {
            Serial.printf("Single pixel on: x=%d, y=%d\r\n", single_x, single_y);
        }

        delay(200);

        single_x++;
        if (single_x >= 8) {
            single_x = 0;
            single_y++;
        }

        if (single_y >= 4) {
            single_phase = false;
            block_x      = 0;
            block_y      = 4;
        }
    } else {
        // Walk through the last 4 rows with a 2x2 block
        MonoPixelInfo pixels[] = {
            {block_x, block_y, true},
            {(uint8_t)(block_x + 1), block_y, true},
            {block_x, (uint8_t)(block_y + 1), true},
            {(uint8_t)(block_x + 1), (uint8_t)(block_y + 1), true}};

        M5Chain.setMonoClear(mono_id, &operation_status);
        chain_status = M5Chain.setMonoPixel(mono_id, pixels, sizeof(pixels) / sizeof(pixels[0]), &operation_status);
        if (chain_status == CHAIN_OK && operation_status == 1) {
            Serial.printf("Block on: (%d,%d) (%d,%d) (%d,%d) (%d,%d)\r\n", pixels[0].x, pixels[0].y, pixels[1].x,
                          pixels[1].y, pixels[2].x, pixels[2].y, pixels[3].x, pixels[3].y);
        }

        delay(200);

        block_x++;
        if (block_x >= 7) {
            block_x = 0;
            block_y += 2;
        }

        if (block_y >= 8) {
            single_phase = true;
            single_x     = 0;
            single_y     = 0;
        }
    }
}

サンプルの動作は以下のとおりです:

文字表示

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
#include "M5Chain.h"
#include "M5Unified.h"

#define TXD_PIN GPIO_NUM_2
#define RXD_PIN GPIO_NUM_1

Chain M5Chain;

uint8_t mono_id          = 0;
uint8_t operation_status = 0;
const char text[]        = "I'mChainMono";

bool findFirstMonoDevice()
{
    // Enumerate devices and use the first Mono node
    uint16_t device_nums = 0;
    if (M5Chain.getDeviceNum(&device_nums) != CHAIN_OK || device_nums == 0) {
        Serial.println("No Chain devices found");
        return false;
    }

    device_info_t *infos = (device_info_t *)malloc(sizeof(device_info_t) * device_nums);
    if (infos == nullptr) {
        return false;
    }

    device_list_t devices;
    devices.count   = device_nums;
    devices.devices = infos;

    bool found = false;
    if (M5Chain.getDeviceList(&devices)) {
        for (uint8_t i = 0; i < devices.count; i++) {
            if (devices.devices[i].device_type == CHAIN_MONO_TYPE_CODE) {
                mono_id = devices.devices[i].id;
                found   = true;
                break;
            }
        }
    }

    free(infos);
    if (found) {
        Serial.printf("Mono device found, id=%d\r\n", mono_id);
    } else {
        Serial.println("No Mono device found");
    }
    return found;
}

bool prepareMono()
{
    // Initialize display mode, rotation, and brightness
    if (!findFirstMonoDevice()) {
        return false;
    }

    if (M5Chain.setMonoMode(mono_id, MONO_PIXEL_MODE, &operation_status) != CHAIN_OK || operation_status != 1) {
        return false;
    }

    M5Chain.setMonoRotation(mono_id, MONO_ROTATION_0, &operation_status);
    M5Chain.setMonoBrightness(mono_id, MONO_BRIGHTNESS_LEVEL_7, &operation_status);
    M5Chain.setMonoClear(mono_id, &operation_status);
    return true;
}

void setup()
{
    M5.begin();
    Serial.begin(115200);
    Serial.println("Character display demo");
    M5Chain.begin(&Serial2, 115200, RXD_PIN, TXD_PIN);

    if (!prepareMono()) {
        Serial.println("Chain Mono init failed");
        while (1) {
            delay(100);
        }
    } else {
        Serial.println("Chain Mono init success");
    }
}

void loop()
{
    static uint8_t index = 0;

    // Show characters one by one from the array
    M5Chain.setMonoClear(mono_id, &operation_status);
    M5Chain.setMonoPrintChar(mono_id, text[index], 1, 1, &operation_status);
    Serial.printf("Character shown: %c\r\n", text[index]);

    delay(400);

    index++;
    if (index >= sizeof(text) - 1) {
        index = 0;
    }
}

サンプルの動作は以下のとおりです:

カスタムパターン表示と回転

説明
ここでの回転とは、描画前に表示方向を設定することを指します。設定後に行う描画操作は、その方向を基準に表示されます。すでに描画済みの表示内容を直接回転変換するものではありません。
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
#include "M5Chain.h"
#include "M5Unified.h"

#define TXD_PIN GPIO_NUM_2
#define RXD_PIN GPIO_NUM_1

Chain M5Chain;

uint8_t mono_id          = 0;
uint8_t operation_status = 0;

// 8x8 arrow pattern
uint8_t arrow[8] = {
    0b00011000,  //    ■■   
    0b00111100,  //   ■■■■  
    0b01111110,  //  ■■■■■■ 
    0b11111111,  // ■■■■■■■■
    0b00111100,  //   ■■■■  
    0b00111100,  //   ■■■■  
    0b00111100,  //   ■■■■  
    0b00111100   //   ■■■■  
};

bool findFirstMonoDevice()
{
    // Enumerate devices and use the first Mono node
    uint16_t device_nums = 0;
    if (M5Chain.getDeviceNum(&device_nums) != CHAIN_OK || device_nums == 0) {
        Serial.println("No Chain devices found");
        return false;
    }

    device_info_t *infos = (device_info_t *)malloc(sizeof(device_info_t) * device_nums);
    if (infos == nullptr) {
        return false;
    }

    device_list_t devices;
    devices.count   = device_nums;
    devices.devices = infos;

    bool found = false;
    if (M5Chain.getDeviceList(&devices)) {
        for (uint8_t i = 0; i < devices.count; i++) {
            if (devices.devices[i].device_type == CHAIN_MONO_TYPE_CODE) {
                mono_id = devices.devices[i].id;
                found   = true;
                break;
            }
        }
    }

    free(infos);
    if (found) {
        Serial.printf("Mono device found, id=%d\r\n", mono_id);
    } else {
        Serial.println("No Mono device found");
    }
    return found;
}

bool prepareMono()
{
    // Initialize pixel mode and brightness
    if (!findFirstMonoDevice()) {
        return false;
    }

    if (M5Chain.setMonoMode(mono_id, MONO_PIXEL_MODE, &operation_status) != CHAIN_OK || operation_status != 1) {
        return false;
    }

    M5Chain.setMonoBrightness(mono_id, MONO_BRIGHTNESS_LEVEL_7, &operation_status);
    M5Chain.setMonoClear(mono_id, &operation_status);
    return true;
}

void setup()
{
    M5.begin();
    Serial.begin(115200);
    Serial.println("Custom pattern rotation demo");
    M5Chain.begin(&Serial2, 115200, RXD_PIN, TXD_PIN);

    if (!prepareMono()) {
        Serial.println("Chain Mono init failed");
        while (1) {
            delay(100);
        }
    } else {
        Serial.println("Chain Mono init success");
    }
}

void loop()
{
    // Rotate through 0/90/180/270 degree display states
    for (uint8_t rotation = MONO_ROTATION_0; rotation <= MONO_ROTATION_270; rotation++) {
        M5Chain.setMonoRotation(mono_id, (mono_rotation_t)rotation, &operation_status);
        M5Chain.setMonoBufferRefresh(mono_id, arrow, &operation_status);
        Serial.printf("Rotation set to: %d°\r\n", rotation*90);
        delay(800);
    }
}

サンプルの動作は以下のとおりです:

文字列スクロールモード

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
#include "M5Chain.h"
#include "M5Unified.h"

#define TXD_PIN GPIO_NUM_2
#define RXD_PIN GPIO_NUM_1

Chain M5Chain;

chain_status_t chain_status = CHAIN_OK;
uint8_t mono_id          = 0;
uint8_t operation_status = 0;
const char text[]        = "Hi I'm Chain Mono! ";

bool findFirstMonoDevice()
{
    // Enumerate devices and use the first Mono node
    uint16_t device_nums = 0;
    if (M5Chain.getDeviceNum(&device_nums) != CHAIN_OK || device_nums == 0) {
        Serial.println("No Chain devices found");
        return false;
    }

    device_info_t *infos = (device_info_t *)malloc(sizeof(device_info_t) * device_nums);
    if (infos == nullptr) {
        return false;
    }

    device_list_t devices;
    devices.count   = device_nums;
    devices.devices = infos;

    bool found = false;
    if (M5Chain.getDeviceList(&devices)) {
        for (uint8_t i = 0; i < devices.count; i++) {
            if (devices.devices[i].device_type == CHAIN_MONO_TYPE_CODE) {
                mono_id = devices.devices[i].id;
                found   = true;
                break;
            }
        }
    }

    free(infos);
    if (found) {
        Serial.printf("Mono device found, id=%d\r\n", mono_id);
    } else {
        Serial.println("No Mono device found");
    }
    return found;
}

bool prepareMono()
{
    // Switch to string scroll mode and set basic parameters
    if (!findFirstMonoDevice()) {
        return false;
    }

    if (M5Chain.setMonoMode(mono_id, MONO_STRING_SCROLL_MODE, &operation_status) != CHAIN_OK ||
        operation_status != 1) {
        return false;
    }

    M5Chain.setMonoRotation(mono_id, MONO_ROTATION_0, &operation_status);
    M5Chain.setMonoBrightness(mono_id, MONO_BRIGHTNESS_LEVEL_7, &operation_status);
    return true;
}

void setup()
{
    M5.begin();
    Serial.begin(115200);
    Serial.println("Mono string scroll demo");
    M5Chain.begin(&Serial2, 115200, RXD_PIN, TXD_PIN);

    if (!prepareMono()) {
        Serial.println("Chain Mono init failed");
        while (1) {
            delay(100);
        }
    } else {
        Serial.println("Chain Mono init success");
    }

    chain_status = M5Chain.setMonoStringScroll(mono_id, text, MONO_SCROLL_LEFT, MONO_SCROLL_MODE_LOOP, 100,
                                               &operation_status);
    if (chain_status == CHAIN_OK && operation_status == 1) {
        Serial.printf("String scroll started: %s\r\n", text);
    }
}

void loop()
{
    delay(1000);
}

サンプルの動作は以下のとおりです:

On This Page