2026年11月5日木曜日

シリアル制御フルカラーテープLEDを使う(その3)

発注していた基板が届き、組み立てた。

以前、超音波距離計のために作ったソフトを改造して書き込んでみた。いくつかのバグを修正して動いたがLEDが端から8~10個くらいしか光らない。オシロでLEDの制御波形を見ると単純なデータを出力させても1-LED内でのバイトデータ間の間隔が25μsもありLED間の間隔は更に大きく、SPIへの書き込み処理が間に合っていなくて、途中でリセット信号と判断されてしまうようだ。手っ取り早くCPUクロックを3MHzに落としたのが問題のようなので32MHzまで上げたい。しかし3MHz以外では波形を作るためのペリフェラルの構成を見付けつことが出来るだろうか?

とりあえずクロックを単純に32MHzまで上げてみたところ1-テープ(30-LED)全体を光らせる事は出来たが、(規格通りの波形ではないため当然だが)色のコントロールが全くできない。そこで回路をあれやこれや検討してみて、次の様に行う事とした。

最終的に生成するLEDの制御信号は1μs/bitとする。とするとSPIに与えるのクロックは1Mhzであるが、SPIのクロック選択にTME2-match/2が選べるのでTMR2で2Mhzを生成すればよい。TMR2の入力クロックはFosc/4固定、即ち8MHzだからTMR2で4分周すればよい。うまい事に8MHzを4分周するときにPWM5を組み合わせてで250nsのパルスを作る事が可能で、上手く収まる。そして出来上がったのが次の波形である。上のトレースがSPI1の出力即ちデータ(code)を表し、下のトレースがそれをLEDに与える制御信号である。データが1の時デューティサイクルが50%、データが0の時デューティサイクルが25%になっている事が分かる。

 

1-code = SDO1 & SCK1

0-code = /SDO1 & SCK1 & (T2-match + PWM5)    

PWMパルス = 0-code + 1-code 

 ここでSDO1はSPI1のデータ出力、SCK1はSPI1のクロック出力である。T2-matchはTMR2の出力で125nsの幅があり、PWM5はPWM5の出力で同じく125nsの幅がありこれら2つを合成して250nsとしている。最後のPWMパルスの合成(0-code + 1-code)にはDSMを使った。このための各ペリフェラルの初期化は次の様に行った。

// TMR2 - Fosc/4(8MHz)÷4 -> 2 MHz
// T2-match issued when PR2==TMR2; Pw is 125ns 
    PIE1bits.TMR2IE     = OFF;
    T2CONbits.T2CKPS    = 0x0;      // prescaler div by 1
    PR2                 = 3;        // devide by 4
    TMR2                = 0;
    T2CONbits.TMR2ON    = 1;
    //
// PWM5 - delayed T2-match(Pw 125ns)
    PWMTMRSbits.P5TSEL  = 01;       // TMR2
    PWM5DCH             = 1;        //
    PWM5DCLbits.PWM5DCL = 0;        //
    PWM5CONbits.PWM5POL = 0;        // 
    PWM5CONbits.PWM5EN  = 1;
    //
// SPI1
    SSP1CON1bits.CKP    = 0;        // IDLE Clock is Low
    SSP1CON1bits.SSPM   = 0x03;     // Master; CLK=T2-match / 2 = 1MHz
    SSP1STATbits.CKE    = 0;        // transition occurs when clk idl->actv 
    PIR1bits.SSP1IF     = 0;        //        
    SSP1CON1bits.SSPEN  = 1;
    //
// CLC1 for CARH = SCK1
    CLC1CONbits.LC1MODE = 2;        // 4-AND
    CLC1SEL0            = 0x12;     // SCK1
    CLC1GLS0            = 0x02;     // SEL0
    CLC1GLS1            = 0;        // T
    CLC1GLS2            = 0;        // T
    CLC1GLS3            = 0;        // T
    CLC1POL             = 0x0e;
    CLC1CONbits.EN      = 1;
    //
// CLC2- for CARL is SCK1 & (TMR2match | PWM6)
    CLC2CONbits.LC2MODE = 0x02;     // 4-AND
    CLC2SEL0            = 0x12;     // SCK1
    CLC2SEL2            = 0x1a;     // T2-match
    CLC2SEL3            = 0x10;     // PWM5
    CLC2GLS0            = 0x01;     // SEL0
    CLC2GLS1            = 0;        // T
    CLC2GLS2            = 0xA0;     // SEL2 + SEL3
    CLC2GLS3            = 0;        // T
    CLC2POL             = 0x0B;     // 
    CLC2CONbits.EN      = 1;       
    //
// DSM
    MDSRCbits.MDMS      = 0x08;     // MOD source is SDO1
    MDCARHbits.MDCH     = 0x0C;     // CarH src is CLC1
    MDCARHbits.MDCHPOL  = 0;
    MDCARHbits.MDCHSYNC = 0;
    MDCARLbits.MDCL     = 0x0D;     // CarL src is CLC2
    MDCARLbits.MDCLPOL  = 0;
    MDCARLbits.MDCLSYNC = 0;
    MDCONbits.MDOPOL    = 0;        // output is idle low (not invertd))
    MDCONbits.MDEN      = 1;

(続く) 

 

 

 

2026年10月24日土曜日

シリアル制御フルカラーテープLEDを使う(その2)

 さて、このSK6812にはどのような制御信号を与えれば良いのだろうか。仕様は次の様になっている。

 超音波距離計で使ったPL-9823と今回のSK6812の制御信号の違いは1を表すコードのデューティ比がPL-9823では75%(=3:1)だったのに対しSK6812では50%(=2:2)になっている点だ。この信号の生成には超音波距離計に準じて次の論理式で可能だろう。

    0 code = /SDO & SCK & Fosc/2

    1 code = SDO & SCK  

    PWMパルス = 0 code + 1 code 

ここでSDOはSPIの出力、SCKはSPIのクロック、そしてFosc/2はCLKRを使ってFoscを2分周して生成できる。 

このLEDを駆動する標準的なデータレートは800Kbpsだが、PIC16F18326で生成できるこれに近いデータレートは750Kbpsだ。1個のLEDに与えるデータは24bitなので1個駆動するのに32μsかかり、テープ1本即ち30個のLEDを駆動しようとすると1ms弱かかる。もしテープを10本繋げた場合でも(ソフトのオーバーヘッドを除けば)100回/秒の速度で書き換えが可能だ。

一方 ソフトを考えると1個のLEDに3バイト(=24bit)のデータバッファーが必要であり、30個なら90バイト、テープ10本なら900バイトが必要になる。PIC16F18326のスタティックメモリー(RAM)は2KBしかないのでこれくらいが限界と考えて良さそうだ。

 (続く)

 

シリアル制御フルカラーテープLEDを使う

知り合いから 店の前に置く看板を目立たせたいとの相談を受けた。色々考えたがシリアル制御のフルカラーテープLEDを使うのが応用範囲が広そうなので挑戦してみる事にした。要は前に作った「超音波距離計(その4)」に使ったフルカラーLEDの応用だ。

早速秋月に行って手頃なSK6812搭載の1mのテープを買ってみて超音波距離計に繋いでみた。

もちろん信号がLEDの仕様が合っていないので正常には動作しないがLEDの明るさや信号に応答する事は確認できた。

そこで早速回路を考えてみた。端子はそれほど必要ないので超音波距離計に使ったPIC16F18346 ではなく足しの数の少ない PIC16F18326 を使おう。この1mのテープの最大消費電力は6W/5Vなので最大1.2Aの電流が流れる。テープの両端には3端子のコネクタが接続されている。3端子の内訳は+/-の電源と制御用の信号だ。テープは直列に何本も繋げられるが、あまり長くすると最初のコネクタやテープに流れる電流が限界を超えるだろう。長く連結する場合は電源はテープごとに個別に与えるのが良さそうだ。

この回路で基板を起こした。大きさは5cm×5cm程度になった。
早速これを発注した。

(続く)

 

2026年9月17日木曜日

Arduino手習い(TFTディスプレイを使う)

 以前、PICに繋げるつもりで買ってデッドストックになっていたTFTディスプレイ(ILI9341)はESP32に繋げられそうなので試してみた。このTFTディスプレイにはタッチパネル(MSP2807)が付いている。次のWEBを参考にした。

ESP32 TFT with LVGL: Display Temperature on Line Chart (BME280)

プログラムをコンパイルしESP32に書込むとプログラムは何事も無く動いた。コンパイルにあたり1つ注意が必要なのはlvglライブラリーが最新バージョンの9.6.0ではなく9.2.xを選ぶ必要がある事だ。そうでないとコンパイルエラーで先へ進めない。

 上の写真を撮った時点ではタッチパネルは未配線であるが問題なく動いた。タッチパネルを配線してみたらタッチした反応が得られようになったが座標が正常には認識されていなかった。これはプログラム中305行目付近にある次の行のパラメータを2から0に変更したら正常になった(この事はプログラム中のコメントに記載されている)。

    touchscreen.setRotation(2);

 

TFTディスプレイが動いたことに気をよくしてプログラム(ウェザーステーション)にも挑戦した。

  ESP32 TFT with LVGL: Weather Station

これはインターネットから気象データを取得し気温や天気をグラフィックに表示するものだが、こちらは 、

最大1310720バイトのフラッシュメモリのうち、スケッチが1853116バイト(141%)を使っています。

 というフラッシュメモリーが足りないというエラーが出て実行できなかった。

最後に、TFTディスプレイに画像を表示させてみた。元ネタは次のWebだ。

    ESP32 with TFT: Display Image using LVGL – 2.8 inch ILI9341 240×320 

 指示に従って外部サイトを使って自分の画像データをプログラムで使える形に変換し image.h のファイル中に挿入、さらにimage.hの最後の方にある次の行に解像度を設定し、

        .w = 320,
        .h = 240,

プログラムと共にコンパイル・実行すると画像がTFTに表示された。


 参考までにESP32-DevKitC-32E、TFT(ILI9341)、BME280の接続関係は次図の通り。


 

 

 

2026年9月16日水曜日

フォノイコライザーを作る(その3)

 そうこうしている内に基板(PCB)の配達された。これまでの経験から、羽田で国内配送業者へ渡された翌日くらいには届く。

 早速、届いたPCBを組み立てた。

やはり220uFの電解コンデンサの大きさが際立っている。270Ωや270KΩはそのままの値が無かったので手持ちの抵抗を組み合わせて近い値を作った。

電源を入れ入力端子を解放したままで出力のレベルを測ると5mV程度出力がある。入力付近に指を近づけると出力が大きく増える。 一方入力端子を短絡すると出力は1mV以下まで下がる。入力回路にハムが乗っているようだ。

じっさい出力をオーディオアンプのAUX端子に入れ、入力側の10uFの無極性電解コンデンサの缶に触るとブーとハム音が出る。低周波のゲインが60dB近くあるので仕方ないが何とかしたい。シールドが必要だ。そこで0.2mm厚の銅板及び銅テープでシールドを作って入力部を覆うように組み付けた。


これにより無入力時のノイズ出力レベルは0.2mV以下まで下がった。60dBあるDCゲインを0dBに落とすための220uFのコンデンサを外してもDCのオフセットは0.1V程度だったので不要として取り外した。

とりえずこれで評価してもらおう。

 

 

 


 

 

 

 

 

 

2026年9月15日火曜日

Arduino手習い(WiFi WEBサーバ、気象データ(BME280)のグラフ表示)

 前回はBME280で測定した気象データ(気温、湿度、気圧)を数値で表示させたが、それらをグラフで表示させる事に挑戦した。参考にしたのは次のWEBページだ。

 ESP32/ESP8266 Plot Sensor Readings in Real Time Charts

 WEBページの指示通り予め表示用htmlファイルを作成し、ESP32 LittleFSファイルシステムアップローダ(ダウンロード&IDEへの追加が必要)を使ってESP32のフラッシュメモリーに書き込んだ。次にプログラム中にあるWiFiアクセスポイントのSSIDとパスワードを設定し、コンパイルすればそのまま動いた。 

ESP32に割り振られたIPアドレス(IDEのシリアルモニターに表示される)にPCや携帯のブラウザからアクセスすれば次のようなグラフが見られる。 



 グラフはサーバ側ではなくアクセスしたクライアント側で作成されるのでアクセスした時点ではスケールしか描画されておらず30秒~1分程度待たなければグラフにならないが、その後は30秒毎にデータが更新され3つのグラフが更新されていく。

データは小数点下2桁まで表示され、実用上はそのような分解能は必要ないが描画する上ではグラフに動きが出て面白い。 カーソルをプロット上に持っていくとそのデータ値と時刻が表示される。

とても面倒だと思っていたグラフ描画を簡単に実行できたので拍子抜けした。今回のプログラムを解析すれば今後のプログラミングに役立つだろう。今のところ時刻がUTCなのは良しとしよう。

 

2026年9月13日日曜日

Arduino手習い(WiFi WEBサーバ、気象データ(BME280)の表示)

 動的なWEBサーバを構築するに当たって、リアルタイムデータが欲しい。ネットで事例を当たっていると1個で気圧・温度・湿度が図れるBME280というのセンサーが便利なようだ。そういえば似たようなセンサー昔秋月で買ったことがあるぞ、と過去の未完成基板を引っ張り出してみたら上手い具合にBME280モジュールが載っていた。

早速、簡単な事例を探して動かしてみたら必要なライブラリーのインクルードと若干の修正で簡単に動いた。

PCからアクセスすると次のような表示になる。 

この元となったブログは「すっさんぽ」さんの、ESP32とBME280で、温湿度計を作った、だ。

このプログラムはネット経由で時刻を取得するのでESP32スタンドアローンでは動かせないが、一方mDNSの機能を搭載し、IPアドレスではなくホスト名(esp32.local)でアクセスできる所が優れている。

データは1分毎に更新されるが、それはクライアント側からリロードのリクエストを出す事で実現されているので、最終的に目標としているPUSH型ではない。 

ちなみに、ソースコードの変更点は次の通り。

  • 漢字コードがShift-JISだったのでUTF-8に変更
  • HTMLの定義の中の 
    <title></title>
    を
    <title>気温・湿度・気圧(BME280)</title>
    に変更(ブラウザのタブにタイトルが表示されるようになる)。
  • シリアル通信が初期化されていなかったので
    void setup() {
    の次の行に
    Serial.begin(115200);
    を挿入。
  •  setup()の最後に
    Serial.println("ESP32 Web Server(+BME280) Ready!");
    を挿入。   

 以上、