LoginSignup
1
0

昨日買ったものを動かしてみた話

Last updated at Posted at 2024-04-07

また、つまらぬ物を買ってしまった…。 ...嘘です、面白かったです!

はじめに

動作

  • stripLEDの連続した7つを「白、赤、緑、青、黄色、水色、紫色」で光らせて、スクロールさせた。
  • エンコーダも活躍させるため、ダイヤルをひねるとスクロール速度を変化させ、ボタンを押している間、スクロール方向を反転させることとした。
    GIF_20240407_173642_883.gif

書いたコード(arduinoIDE)


#include <M5Unified.h>
#include <Unit_MiniEncoderC.h>
#include <Adafruit_NeoPixel.h>

#define SIGPIN 32  // 信号ピン
#define LEDNUM 15  // stripLEDのLED数

UNIT_MINIENCODERC encoder;

static M5Canvas cv1(&M5.Lcd);//エンコーダのボタン状態、エンコード値表示用
static M5Canvas cv2(&M5.Lcd);//エンコーダ値の増減表示用
static M5Canvas cv3(&M5.Lcd);//stripLEDのループ周期と方向表示用

uint8_t i2c_address = 0;      //エンコーダのアドレス
int32_t last_value = 0;       //最後に取得したエンコード値
uint8_t strip_loop_time = 0;  //stripLEDのループ周期(msec)
bool strip_direction = true;  //stripLEDのループ方向
uint16_t cnt = 0;

uint8_t brt = 30;  //stripLEDの明るさ(0-255)
Adafruit_NeoPixel strip(LEDNUM, SIGPIN, NEO_GRB);

void page_get_encoder(void) {
  int32_t encoder_value = encoder.getEncoderValue();  //1ノッチで、2増減する。ノッチ間で回転を止めると奇数も可。1回転で60。
  bool btn_status = encoder.getButtonStatus();        //通常1,押された状態で0
  Serial.println(encoder_value);

  //増減でエンコーダ裏面のLED色変化
  if (last_value != encoder_value) {
    if (last_value > encoder_value) {
      encoder.setLEDColor(1, 0x000011);  //増加:赤
    } else {
      encoder.setLEDColor(2, 0x110000);  //減少:青
    }
    last_value = encoder_value;
  }

  //エンコーダのボタンでエンコーダ裏面のLED変化
  if (!btn_status) {
    encoder.setLEDColor(0, 0x001100);  //ボタン押下:緑
  }

  cv1.fillScreen(BLACK);
  cv1.setTextColor(WHITE);
  cv1.drawString("ボタン状態:" + String(btn_status), 10, 10);
  cv1.drawString("エンコーダ値:", 10, 40);
  cv1.setCursor(10, 65);
  cv1.setTextColor(GREEN);
  cv1.printf("%d", encoder_value);
  cv1.pushSprite(0, 0);

  //上下限設定
  if (encoder_value < -126) {
    encoder.setEncoderValue(-126);
    encoder_value = -126;
  } else if (encoder_value > 126) {
    encoder.setEncoderValue(126);
    encoder_value = 126;
  }

  //stripLED用の設定
  strip_loop_time = 128 + encoder_value;  //128msを中心に増減
  strip_direction = btn_status;           //順方向1,逆方向0

  //stripLED用の設定表示
  cv3.fillScreen(BLACK);
  cv3.setTextColor(WHITE);
  cv3.drawString("loop方向:" + String(btn_status ? "順" : "逆"), 10, 10);
  cv3.drawString("loop時間(msec):", 10, 40);
  cv3.setCursor(10, 65);
  cv3.setTextColor(GREEN);
  cv3.printf("%d", strip_loop_time);
  cv3.setTextColor(WHITE);
  cv3.pushSprite(0, 140);
}


//7色表示
void stripShow(uint16_t cnt) {
  strip.clear();                                                               //消灯
  strip.setPixelColor((LEDNUM + cnt - 0) % LEDNUM, strip.Color(80, 80, 80));   //白(R+G+B)
  strip.setPixelColor((LEDNUM + cnt - 1) % LEDNUM, strip.Color(240, 0, 0));    //赤(R)
  strip.setPixelColor((LEDNUM + cnt - 2) % LEDNUM, strip.Color(0, 240, 0));    //緑(G)
  strip.setPixelColor((LEDNUM + cnt - 3) % LEDNUM, strip.Color(0, 0, 240));    //青(B)
  strip.setPixelColor((LEDNUM + cnt - 4) % LEDNUM, strip.Color(120, 120, 0));  //黄(R+G)
  strip.setPixelColor((LEDNUM + cnt - 5) % LEDNUM, strip.Color(0, 120, 120));  //水(G+B)
  strip.setPixelColor((LEDNUM + cnt - 6) % LEDNUM, strip.Color(120, 0, 120));  //紫(R+B)
  strip.setPixelColor((LEDNUM + cnt - 7) % LEDNUM, strip.Color(0, 0, 0));      //黒
  strip.setPixelColor((LEDNUM + cnt + 1) % LEDNUM, strip.Color(0, 0, 0));      //黒(逆方向で色を消すのに必要)
  strip.show();                                                                //点灯
}

void setup() {
  M5.begin();

  cv1.createSprite(135, 100);  //エンコーダのボタン状態、エンコード値表示用
  cv2.createSprite(135, 40);   //エンコーダ値の増減表示用
  cv3.createSprite(135, 100);  //stripLEDのループ周期と方向表示用
  cv1.setFont(&lgfxJapanMincho_16);
  cv2.setFont(&lgfxJapanMincho_16);
  cv3.setFont(&lgfxJapanMincho_16);

  encoder.begin(&Wire, MINIENCODERC_ADDR, 0, 26, 100000UL);
  i2c_address = encoder.getI2CAddress();

  strip.begin();             //pixelLED初期化
  strip.setBrightness(brt);  //明るさ(0-255)
}

void loop() {
  M5.update();
  if (M5.BtnA.wasPressed()) { //前回ボタンAを押した時点からの増減値を取得
    cv2.fillScreen(BLACK);
    cv2.setTextColor(WHITE);
    cv2.drawString("増減:", 10, 10);
    cv2.setTextColor(CYAN);
    cv2.setCursor(50, 10);
    cv2.print(encoder.getIncrementValue());  //前回取得時との差異
    cv2.pushSprite(0, 100);

  } else if (M5.BtnB.wasPressed()) { //ボタンBを押すとエンコーダ値リセット
    encoder.resetCounter();  
    cv2.fillScreen(BLACK);
    cv2.drawString("リセット!", 10, 10);
    cv2.pushSprite(0, 100);
  }

  page_get_encoder();
  stripShow(cnt);
  cnt = cnt + (strip_direction ? 1 : -1);  //ボタンを押している間、逆方向にスクロール
  delay(strip_loop_time);
}

コードの内容

  • 動作に書いたこと以外を書くと、M5stickCPlus2のボタンBを押すと、エンコード値がリセット(0)となり、ボタンAを押すと、前回ボタンAを押したときからのエンコード値の増減を画面に表示する。
  • stripLEDのスクロールはloopによるものだが、loop周期(msec)は128を中心とし、エンコード値を加えたものとした。

コードの解説

  • エンコーダのライブラリとstripLEDのライブラリを利用したので、お手軽に実装できた。
  • エンコーダの初期設定は、 encoder.begin(&Wire, MINIENCODERC_ADDR, 0, 26, 100000UL);
  • 0はSDA、26はSCLに割り当てたM5stickCPlus2のピン番号。
  • 最後の100000ULはspeedのようだが、深く考えず、sampleのスケッチを使い回した。
  • 使用したエンコーダのメソッドは、
    • getI2CAddress() I2Cアドレス取得
    • getEncoderValue() エンコーダ値取得
    • setEncoderValue(int32_t value) エンコーダ値設定
    • resetCounter() エンコーダ値リセット
    • getIncrementValue() 前回の増減取得時からの増減を取得
  • ダイヤルを一周回すとエンコード値は60増減する(時計回りで増加)。
  • 回すとノッチ感があり、1ノッチで2増減する。
  • stripLEDの初期設定は、 Adafruit_NeoPixel strip(LEDNUM, SIGPIN, NEO_GRB);
  • 最後のNEO_GRBはledの色指定時の並びを定義している模様。
  • 使用したstripLEDのメソッドは、
    • clear() 消灯
    • show() 点灯
    • setPixelColor(uint16_t n, uint32_t c) n番目のledの色指定

終わりに

  • 今日は、サイクルモード東京2024にチャリで行くか、昨日買ったものを動かすプログラムを書くか、迷った末に、プログラムを書くことにした。
  • 気がつけば、富士ヒルクライムのエントリー期限も過ぎてたし、このまま運動をサボっているとBMIがK点超えするのも時間の問題。
  • そろそろ、プログラムを書くのも控えた方がいいかも。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0