* easy-CでNeoPixelを制御するためのメモ#1
-(by [[K]], 2024.02.10)

** (1)
-資料1: https://garretlab.web.fc2.com/arduino.cc/docs/tutorials/uno-r4-wifi/r4-wifi-getting-started/
-資料2: https://cediablog.com/arduino-unor4wifi-review/
-資料3: https://maicommon.ciao.jp/ss/Arduino_g/serial/index.htm
-資料4: https://maicommon.ciao.jp/ss/Arduino_g/intrupt/index.htm
-資料5: https://maicommon.ciao.jp/ss/Arduino_g/
-資料6: https://qiita.com/hsgucci/items/eee5894e3651d0a8cb75
-資料7: https://www.zep.co.jp/nbeppu/article/z-pico-da2/
-資料8: https://ysin1128.hatenablog.com/entry/2021/08/25/143519
-資料9: https://ysin1128.hatenablog.com/entry/2021/12/10/131817
-資料10: https://kats-eye.net/info/2018/11/07/neopixel/
-資料11: https://learn.adafruit.com/adafruit-neopixel-uberguide
-資料12: https://ja.librosnews.com/getting-started-with-neopixel-ws2812-rgb-led

-資料1~6: Arduino UNO 向けの資料
-資料7~9: ラズベリーパイ pico 向けの資料

-ラズベリーパイ pico はモデルHがよい。なぜならピンが最初からついているから。

-Arduino UNO でも ラズパイpico でも、どちらでもできそう。ラズパイpicoのほうがたぶん安い。

-Arduino UNO R3 の場合、処理能力が十分かどうかは少し心配。
-しかしArduino UNO R4 Wifiで試したところうまくいかなかったので、UNO R3でやり直したらうまくいった。たぶんライブラリ<Adafruit_NeoPixel.h>がR4に対応できてないのだと思われる。



** (2)
-NeoPixelは1つにつき60mAを要すると書いてあります(資料11)。だから28個なら1.68Aになる可能性があります。64個なら3.84A。これが大きすぎるときは、最大輝度にしないように調整する必要があるそうです。

//-まず[資料1]でArduino IDEをインストール。Arduino UNO R4のボードマネージャーをIDE内でインストール。

** (3)
-必要なもの:
--Arduino UNO R3 (AmazonでUSBケーブル付きで1230円くらい・互換品)
--WS2812B 7LED (Amazonなら2個で550円くらい・互換品)
--300~500オームの抵抗(家にあったものを流用)
//--1000uFのコンデンサ(Amazonなら10個で500円くらい)
--結線用のジャンプワイヤ・はんだ
--(これでUSB電源だけでも合計500mA弱まではいける?)

-資料10を参考にして、Arduino側やNeoPixelを準備

~

-Arduino UNO R3側のコード(スケッチ)
 #include <Adafruit_NeoPixel.h>
 #ifdef __AVR__
  #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
 #endif
 
 #define Pin        6
 #define Pin        6  // (GP6 for RaspberryPiPico)
 #define NumPixels  7
 
 Adafruit_NeoPixel pixels(NumPixels, Pin, NEO_GRB + NEO_KHZ800);
 
 void setup() {
   Serial.begin(115200);
   pixels.begin();
 }
 
 void loop() {
   for (;;) {
     int c = Serial.read();
     if (c < 0) {
       delay(3);
       continue;
     }
     if (c == 0xf1) {
       pixels.clear();
       continue;
     }
     if (c == 0xf2) {
       pixels.show();
       continue;
     }
     if (c == 0xf3) {
       while (Serial.available() < 3) {}
       int i = Serial.read() << 8; i |= Serial.read(); // big endian.
       int n = Serial.read();
       while (n > 0) {
         while (Serial.available() < 3) {}
         int r = Serial.read();
         int g = Serial.read();
         int b = Serial.read();
         pixels.setPixelColor(i, pixels.Color(r, g, b));
         i++; n--;
       }
     }
   }
 }
-Arduinoでのシリアル通信の資料: https://miraiworks.org/?p=3688

~

-PC側のコード(ひとまずテスト用にC言語で書いています、まだeasy-C用ではありません)
 #include <stdio.h>
 #include <tchar.h>
 #include <windows.h>
 
 int main()
 {
     HANDLE comPort = CreateFile(_T("COM3"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
         // シリアルポートを開き、ハンドルを取得(※10番以上のCOMポート名は _T("\\\\.\\COM10") としないと認識してくれない)
     DCB dcb; // シリアルポートの構成情報が入る構造体
     GetCommState(comPort, &dcb); // 現在の設定値を読み込み
     dcb.BaudRate = 115200; // 速度
     dcb.ByteSize = 8; // データ長
     dcb.Parity = NOPARITY; // パリティ
     dcb.StopBits = ONESTOPBIT; // ストップビット長
     dcb.fOutxCtsFlow = FALSE; // 送信時CTSフロー
     dcb.fRtsControl = RTS_CONTROL_ENABLE; // RTSフロー
     SetCommState(comPort, &dcb); // 変更した設定値を書き込み
 
     Sleep(3000); // とりあえず安定させるために待つ.
 
     static unsigned char a[] = {
         0xf1, 0xf3, 0x00, 0x00, 3, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0xf2 // [1 0 0] [0 1 0] [0 0 1]
         // 電力さえ心配なければ[255 0 0]などでももちろんいいが、1でも十分に視認できるほど明るい.
     };
     DWORD n;
     WriteFile(comPort, a, sizeof a, &n, NULL);
     CloseHandle(comPort);
 }
-WindowsからCOMポートで通信する資料: https://www.saluteweb.net/~oss_winapi232.html
-Arduinoとの通信パラメータの資料: https://www.arduino.cc/reference/en/language/functions/communication/serial/begin/
--これでSerial.begin()のデフォルトパラメータが SERIAL_8N1 だとわかる。

** (4)
-上記のコードだと Arduino UNO R3 では問題なく動くけど、Raspberry Pi Pico では動かない(通信時にハングアップする)。
-原因は DCB の設定が足りてないこと。
--参考: https://ysin1128.hatenablog.com/entry/2021/08/25/143519
-ということで、DTRフローの設定もやる。このコードはたぶん Arduino UNO R3 でも動く。
 #include <stdio.h>
 #include <tchar.h>
 #include <windows.h>
 
 int main()
 {
     HANDLE comPort = CreateFile(_T("COM3"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
         // シリアルポートを開き、ハンドルを取得(※10番以上のCOMポート名は _T("\\\\.\\COM10") としないと認識してくれない)
     DCB dcb; // シリアルポートの構成情報が入る構造体
     GetCommState(comPort, &dcb); // 現在の設定値を読み込み
     dcb.BaudRate = 115200; // 速度
     dcb.ByteSize = 8; // データ長
     dcb.Parity = NOPARITY; // パリティ
     dcb.StopBits = ONESTOPBIT; // ストップビット長
     dcb.fOutxCtsFlow = FALSE; // 送信時CTSフロー
     dcb.fRtsControl = RTS_CONTROL_ENABLE; // RTSフロー
     dcb.fDtrControl = DTR_CONTROL_ENABLE; // DTRフロー ←ここを追加!
     SetCommState(comPort, &dcb); // 変更した設定値を書き込み
 
     Sleep(3000); // とりあえず安定させるために待つ.
 
     static unsigned char a[] = {
         0xf1, 0xf3, 0x00, 0x00, 3, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0xf2 // [1 0 0] [0 1 0] [0 0 1]
         // 電力さえ心配なければ[255 0 0]などでももちろんいいが、1でも十分に視認できるほど明るい.
     };
     DWORD n;
     WriteFile(comPort, a, sizeof a, &n, NULL);
     CloseHandle(comPort);
 }

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS