何か作った系

【自作】格安パーツで爆光LEDパネルを自作する(調光機能付き)

どうも、バイト戦士です。

撮影用にもっと強力なライトが欲しくなりました。

価格は三千円弱、明るさは抜群、調光機能付きのLEDパネルを自作していきます。

Youtubeやります

前も言ってましたが、Youtube始動します。

やりたいから。

話すのは得意、というわけではないですが興味があるのでやってみます。

コンテンツとして動画の方がわかりやすい、かもしれないね。

今回古いカメラでやったんですけど画質がク〇だったのでカメラを買ってきました。(5万デュワッ!!)

実際画質に関してはそこそこ満足だったんですけど、データのやり取りがかなり遅い+いろんなものを撮影したいのもあって購入に踏み切りました。

今週末あたりレビューします。

部屋が暗い

作業スペースが暗すぎます。以下のような感じです。

ここでは主にはんだ付けを行っていますが、作業するのには暗すぎます。なので今回は明るくするために照明を自作します。

照明の位置を移動したいことがあるのですが、ぶっちゃけ物理的に移動させるのがめんどいので点灯パターンとして用意します。

間接的に光の位置を調整できればいいなと思ったわけです。

全体的な仕様

まずは全体的な仕様を決めます。今回求めるのは以下のような条件。

・明るい
・安い
・調光機能付き
・光の位置調整ができる

この4つを満たせれば満足。

位置調整っていうのは言葉のままで、光の位置を調整できるようにという意味です。今回はかなり大きめの照明にするので机全体だけでなく一部だけ点灯、みたいなこともできるようにしたい。

具体的な動作

具体的な動作は以下のようにします。

点灯モードとしては10種類用意します。

横一行(位置移動)、縦一列(位置移動)、2列(両脇)、全部の計10コです。

今回は15個のモジュール(LEDを張り付けたやつ)をリレーを用いて操作します。一個一個操作しているとリレーの数がものすごく増えてしまうので、今回は横に関しては電源の+を共通に、縦に関してはGNDを共通にします。

ちょっと見にくいので図にしてみます。以下の通りです。

電源電圧とGNDを縦と横で共通化する

今回以下のようになってます。スイッチ8コで接続されています。

縦の列だけ点灯させる

以下のようにスイッチ①と⑧をONにすると、縦の列で点灯させることができます。

横の行だけ点灯させる

以下のように縦のスイッチを全部ONにして横のスイッチを選択してつけると以下のようになります。

こうすれば縦と横のリレーを掛け算でON・OFFさせることで一列ずつ、一行ずつの点灯が可能になると思います。やり方によってはもっといろいろな点灯パターンを用意できると思います。

また今回5Vリレー(接点容量3AMAX)の小型リレーしか手元にありませんでしたが、こうすることで電流がある程度分散するので使用可能になります。

回路図

次に回路図を作成していきます。手書きがめんどくさいので「KiCad」というフリーソフトを使いました。

全体像は以下のような感じです。PICマイコンでリレーを制御する。ただそれだけです。

左側では抵抗分圧した値を各地点から取り出し、ロータリースイッチに入力することで一本から出力を取り出せるようにしました。

こうすればPICに入力する端子が一つだけで済みます。

あとは出力を設定してトランジスタでリレーをドライブするだけです。

パーツ購入

次にパーツを購入していきます。今回使用したのは以下のパーツです。(一部互換)

今回使用したLEDチップは青白いやつですが、やっぱ暖色の方がいいと思います。(見栄え的に)

created by Rinker
マイクロチップ(Microchip)

購入した部品全部合わせるとまぁまぁな額になりますが、残りはストックです。

価格的にはMDFと合わせて3000円といったところ。

お好みの点灯パターンが作れるのでそれを考えれば安いと思います。

LEDを基板につける(モジュールっぽくする)

次にLEDを基板に取り付けていきます。

今回はリレーを用いて15コのLEDを制御しますが、さすがにチップ1個だけだと光量がたらなすぎるので、4個載せたモジュールを一つとして計60個点灯させます。

並列接続するのでそこそこ電流が流れるので(最大3A程度)、接続に使用するケーブルは2sqぐらいの太いものを用いました。
が、これはさすがに大げさでしたね。。。

太すぎて被覆が剥けない、向けても血豆ができる、はんだが融けない、融けたら融けたで鬼のように吸われる。。。。。

この後はモノタロウで購入した自動車用のケーブルを使いました。

自動車用の配線コードは一般的なものに比べて電流定格が大きいみたいです。

余談なんですけど、なんでAmazonの青い抵抗ってこんなに足細いんでしょうかね。。。。。

定格がちょっと心配です。

細すぎてつけにくいのでねじって付けたらいい感じにはんだを吸ってくれました。

制御回路を製作

次に制御に使う回路を作ります。論理回路とかいろいろ迷ったんですが、結果的にPICが一番安上がりになるので選びました。

PICマイコンはとんど使ったことがありませんでしたが、思ったほどは難しくありませんでした。
(浅い使い方しかしてないってのはある。。。。。)

制御回路は先ほどとおなじ「KiCad」を用いてパターンを作成しました。

このソフトは無料で3Dモデルの表示までできます。すげーわ。

ミラー印刷に対応しているので、頭の中で回路を反転させずに配線を行うことができます。

以下のように印刷したら、実際に配線を行っていきます。

実際に配線してみると以下のような感じです。

若干異なってますが、ほぼ見たまんま作れるのでマジで便利です。

それはそうと、今回中古の基盤(死んだFET焼き付いてた)をもらったので部品を取り外して再利用したんですが、まぁ、最悪でしたね。。
ランドが酸化しているので温度が上がってもはんだがのりにくいです。

加えて茶色くなっているので見にくくて仕方がない。。。

完成図は以下の通り。

割と3Dモデルのまんまになってると思います。

プログラムを作成する

設定を含めたプログラム全体を以下に示します。

こんなに簡単なのにどえらく時間かかったのだ。。。。(未熟だぜ)

/*
 * File:   main.c
 * Author: HGS01
 *
 * Created on 2023/04/23, 6:14
 */

// PIC16F1827 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>



#define _XTAL_FREQ 4000000



//プロトタイプ宣言
void init(void);
void ADConversion(void);

//ロータリースイッチの閾値判定
const float  VCC = 5;
const float Input_division = 10.0f;    //floatと一緒に計算したらfloat値として代入される(この変数自体はint範囲でよい.) -> X
const float Input_accuracy = 0.3f;
const float Input_resolution = Input_accuracy * 1.0f / Input_division;   //入力値の振れ幅設定.キャストが必要になるとconstが外れるので全部型は統一した方が良い. 

const float Vth1 = VCC * 1.0f / Input_division;
const float Vth2 = VCC * 2.0f / Input_division;
const float Vth3 = VCC * 3.0f / Input_division;
const float Vth4 = VCC * 4.0f / Input_division;
const float Vth5 = VCC * 5.0f / Input_division;             // = 2.5V
const float Vth6 = VCC * 6.0f / Input_division;
const float Vth7 = VCC * 7.0f / Input_division;
const float Vth8 = VCC * 8.0f / Input_division;
const float Vth9 = VCC * 9.0f / Input_division;
const float Vth10 = VCC * 10.0f / Input_division;           // = 5.0V

void main(void) {
    unsigned short Vin_ADRES=0;
    float Vin=0;
    int count=0;
    
    init();
    
    //main関数無限ループ
    while(1){
        ADConversion();                 //A/D変換実行
        Vin_ADRES = ADRESH;
        Vin_ADRES = (Vin_ADRES << 8) + ADRESL;      //ADRESHの内容を8bitシフトして16bitペアとして使う
        Vin = (float)Vin_ADRES / 1023.0f * 5.0f;           //実際の電圧値への変換
        
        
        //分岐設定
        if(Vin < Input_resolution ){                                     //case0
          //PORTA=0b76543210;   //RA1
            PORTA=0b00000000;   
          //PORTB=0b76543210;
            PORTB=0b00000000;
        }else if(Vin > (Vth1 - Input_resolution)  && Vin < (Vth1 + Input_resolution) ){                 //case1
          //PORTA=0b76543210;
            PORTA=0b00000010;
          //PORTB=0b76543210;
            PORTB=0b01110000;
        }else if(Vin > (Vth2 - Input_resolution)  && Vin < (Vth2 + Input_resolution) ){                 //case2
          //PORTA=0b76543210;
            PORTA=0b00000001;   //RA7
          //PORTB=0b76543210;
            PORTB=0b01110000;
        }else if(Vin > (Vth3 - Input_resolution)  && Vin < (Vth3 + Input_resolution) ){                 //case3
          //PORTA=0b76543210;
            PORTA=0b10000000;
          //PORTB=0b76543210;
            PORTB=0b01110000;
        }else if(Vin > (Vth4 - Input_resolution)  && Vin < (Vth4 + Input_resolution) ){                 //case4
          //PORTA=0b76543210;
            PORTA=0b01000000;
          //PORTB=0b76543210;
            PORTB=0b01110000;
        }else if(Vin > (Vth5 - Input_resolution)  && Vin < (Vth5 + Input_resolution) ){                 //case5
          //PORTA=0b76543210;
            PORTA=0b00000000;
          //PORTB=0b76543210;
            PORTB=0b11110000;
        }else if(Vin > (Vth6 - Input_resolution)  && Vin < (Vth6 + Input_resolution) ){                 //case6
          //PORTA=0b76543210;
            PORTA=0b11000011;
          //PORTB=0b76543210;
            PORTB=0b11000000;
        }else if(Vin > (Vth7 - Input_resolution)  && Vin < (Vth7 + Input_resolution) ){                 //case7
          //PORTA=0b76543210;
            PORTA=0b11000011;
          //PORTB=0b76543210;
            PORTB=0b10010000;
        }else if(Vin > (Vth8 - Input_resolution)  && Vin < (Vth8 + Input_resolution) ){                 //case8
          //PORTA=0b76543210;
            PORTA=0b11000011;
          //PORTB=0b76543210;
            PORTB=0b10100000;
        }else if(Vin > (Vth9 - Input_resolution)  && Vin < (Vth9 + Input_resolution) ){                //case9
          //PORTA=0b76543210;
            PORTA=0b11000011;
          //PORTB=0b76543210;
            PORTB=0b11100000;
        }else if(Vin > (Vth10 - Input_resolution) ){                              //case10
          //PORTA=0b76543210;
            PORTA=0b11000011;
          //PORTB=0b76543210;
            PORTB=0b11110000;
        }
        //__delay_ms(1000);
    }
}


void ADConversion(void){
    GO=1;                   //ここに記載すれば関数呼ばれた時しかA/D変換しない(ADRESH/Lがバグらない)
    while(GO==1);
}

void init(void){
    OSCCON = 0b01110000;   //datasheet_P678MHz
    
    ANSELA = 0b00000100;   //datasheet_P122
    ANSELB = 0b00000000;   //datasheet_P128
    TRISA  = 0b00100100;    //datasheet_P120
    TRISB  = 0b00000000;
    PORTA  = 0b00000000;    //datasheet_P119
    PORTB  = 0b00000000;    //PORTB
    
    ADCON0 = 0b00001001;    //datasheet_P143
    ADCON1 = 0b11010000;    //Device Frequency(FSOC)が4MHzの時は1.0us、2.0us、4.0usしか選択できない。
}

内容はいたって単純。入力される電圧を判別してLEDの点灯パターンを直打ちしただけです。誤差は30%程度で設定しました。

固定具の取り付け

次に固定具を取り付けていきます。

今回は天井に固定しますが、天井への穴あけが面倒なので洗濯物干し用のツッパリ棒を使うことにします。せめて白にすればよかった。。。

固定具は以下のように3Dプリンタで印刷しました。今更なんですけど、4ついっぺんに印刷できるってすごいよね。

QIDI Techという廉価帯の3Dプリンタメーカですが、ぶっちゃけNo.1の中華メーカだと思ってます。メールしたら2時間で返信来るし、サポート期限内なら無料で部品交換してくれます。

ヘッドの通信ケーブルが断線した時に連絡したら、ケーブルとユニット丸ごと送ってくれたのは今でも印象深いエピソードです。ヤバイね。

取り付けると以下のような感じ。

だいたい真ん中測って適当に固定。

動作テスト

作り終わったので次に動作テストを行います。

残念。うまく動きません。

なぜかリレーがめちゃめちゃかちゃかちゃいってます。

ばぁちゃんちのガスコンロ思い出したわ。

修理

思いつくところを修理してみます。

最初に入力電圧(ロータリースイッチの出力)をチェックしましたが、特に以上なし。

入力電圧のチェック

切り替わりの瞬間はいったん0に落ちる時がありますが、一度操作した後に値がふらつく、といったことはないです。原因はここじゃないみたいです。

プルアップ抵抗の接続

次はプルアップ抵抗。

今回リレードライブ用のPIC端子(トランジスタのベース)に抵抗を接続していなかったので追加します。

効果は特にありませんでした。内部的には安定、なんだとおもいます。

リレー用ダイオードの追加

次にリレーのサージ吸収用ダイオードを取り付けます。

本来リレーにはダイオードは必須です。理由としては、コイルのエネルギーが逆電圧として発生していろんなところに戻るためです。

これを貫通させて吸収する役割になってます。

ただ今回使ったトランジスタ(2SC1959)はVCEが30V程度で、発生しているサージはこの範囲内ぐらいだったのでつけていませんでした。

何らかの誤動作の原因になっているかも、、、と思ったんですが、PICの出力端子(トランジスタのベース)と電源電圧は以下の通り。

電源電圧は問題になるほど変動してないし、PICの出力が周期的に切り替わってるだけです。
こんな微細な電源電圧の変動でもPICが再起動するんですかね?
(PICのConfigでは保護全部切ってます)

天井に取り付け

理由がはっきりしませんでしたが、なぜか電源電圧を3V程度に低下させると安定して点灯します。

点灯中に操作したいわけではないので、スイッチ操作→電源ONという風にすれば問題なく使用できます。

なのでこれで行くことにしました。

天井への取り付けはツッパリ棒を使います。以下のような感じ。

適当に考えましたが、結構便利かもしれません。

いざ、点灯

全部できたので点灯させてみます。

クソまぶしいね。

さすがにやりすぎ感があります。ていうかもうちょい暖色入れればよかったよ。
まぁその辺は色補正とかでどうとでもなるのでとりあえず明るければ良しとします。

今回は2列だけ点灯するモードも用意してます。以下のような感じ。

ぶっちゃけこれぐらいでちょうどよかったので、今後はこれで使うことになりそうです。

過電流になるとはんだが融けて上から降ってくることになるので電圧固定の電源を用意しないとですね・・・・・(割とガチ)

改善点

取り合えずできましたが、問題も残りました。原因はわかっているので後で何とかします。現状としては以下のような感じ。

①リレーの動作が安定しない → マイコンが再起動してるのを直す
②白色光がややきつい → 暖色フィルムとかを張ってみる
③電源を工夫する → ①が改善しない場合、電源装置の方を工夫してみる(ソフトスタート)

こんな感じかな。

まとめ

今回はAmazonなどで購入できる格安パーツでLED照明を自作してみました。

次はずっとほしかった左手デバイスを自作してみます。

それでは、また。

-何か作った系