PR 記事には広告が含まれています
スポンサーリンク
Translate

七色に色が変化するLEDを白色点滅させてみました

スポンサーリンク

電源をつなぐだけで様々な色に変化するLEDを、白色点滅させることができました。

スポンサーリンク

七色変色LED

電源を入れると自動で様々な色に変化するLEDです。入手したLEDは電源投入時に白色(やや黄色)に光ることがわかりました。

そこで、上の図のように、短い時間で電源をON,OFFすれば、白色の点滅になるのではないかと考えました。

スポンサーリンク

Padaukマイコンでプログラム

ただ単にLEDの点滅をしたいだけなので、安価なPadaukマイコンが最適です。

インサーキット書き込み機の組み立て

インサーキット書き込み機は、書き込みの度にマイコのを書き込み機に接続することが不要で、ブレッドボードで回路を組んだまま書き込むことができる装置です。

PCBgogoに発注していた基板が届いたので、組み立てたいと思います。

PCBgogoでいいなと思うところがありました。基板には通常、製造番号が印刷されてしまいます。PCBgogoはその製造番号を、スイッチでちょうど隠れるところに印字してくれました。こういうちょっとした心配りをしてくれるって嬉しいですね。

組み立てて、書き込み機と接続するとこんな感じになります。

セットアップ

ゼロプレッシャーソケットにPFS154をセットします。

ブレッドボードにLEDを刺し、ジャンパワイヤーで書き込み機と接続します。

これで、書き込み機のスイッチを「WRITE」にすると書き込みができて、「RUN」にすると動作を開始します。とっても開発が捗ります。

書き込んでみる

とりあえず、LEDが点滅するだけのプログラムを書き込んでみます。

ところが書き込めません。

何度やっても書き込めません。

接続は上の図のようになっています。マイコンで書き込みに必要なピンは、スイッチで回路から切り離されて、書き込み機に接続されます。

ブレッドボードに刺さっているLEDを一つ一つ抜いていくと、書き込めない原因がわかりました。

書き込みに関係ないピンが書き込みに影響

なんと、書き込みに必要のないピンに接続されたLEDが原因でした。このLEDを取り除くと書き込みに成功します。LEDを通してプルアップされてしまうことが、悪さをしているようです。

なんということでしょう。Padaukマイコンは、書き込みに関係ないピンでも、何かしら回路がつながっていると、書き込みができなくなってしまうということがわかりました。

インサーキット書き込み機は、回路を考え直さないといけません。

仕方がないので、プログラムを書き込む度に、ブレッドボードからマイコンを取り外し、書き込み機に接続するという従来の方法でプログラムを開発しようと思います。

スポンサーリンク

プログラム

乱数の発生

LEDがキラキラとランダムな間隔で点滅して欲しいので乱数を作りたいと思います。

uint16_t xs = 17;
uint16_t rand(){
    xs ^= xs << 7;
    xs ^= xs >> 9;
    xs ^= xs << 8;
    return xs;
}

XORを上記のように演算することで、16bitの乱数が得られるようです。完璧な乱数ではなく、値が循環はしてしまいますが、とりあえずバラバラな値が得られます。

光り方

光り方は、上の図のような感じにしようと思います。最初ランダムにピカピカしていて、何回か光ったら七色に光ります。

プログラム

#include <pdk/device.h>
#include <stdint.h>
#include "auto_sysclock.h"
#include "delay.h"

#define LED1_BIT         0
#define LED2_BIT         4
#define LED3_BIT         3
#define LED4_BIT         6
#define LED5_BIT         7

#define LED1_ON()     PA &= ~(1 << LED1_BIT)
#define LED1_OFF()    PA |= (1 << LED1_BIT)
#define LED2_ON()     PA &= ~(1 << LED2_BIT)
#define LED2_OFF()    PA |= (1 << LED2_BIT)
#define LED3_ON()     PA &= ~(1 << LED3_BIT)
#define LED3_OFF()    PA |= (1 << LED3_BIT)
#define LED4_ON()     PA &= ~(1 << LED4_BIT)
#define LED4_OFF()    PA |= (1 << LED4_BIT)
#define LED5_ON()     PA &= ~(1 << LED5_BIT)
#define LED5_OFF()    PA |= (1 << LED5_BIT)
#define LED_NUM 5

#define DELAY_TIME_MS 3
#define ON_TIME_S 8
#define COUNTUP_MAX 60

unsigned short xs = 17;
char rand(){
    xs ^= xs << 7;
    xs ^= xs >> 9;
    xs ^= xs << 8;
    return ( (char)xs )/2;
}

char setCountdown()
{
    char temp = rand();
    temp = temp/2 + 5;
    return temp;
}

void main() {
    PDK_USE_FACTORY_IHRCR_16MHZ();
    PDK_USE_FACTORY_BGTR();
    AUTO_INIT_SYSCLOCK();
    CLKMD &= ~CLKMD_ENABLE_WATCHDOG;  // Disenable WDT

    PAC |= (1 << LED1_BIT);          // Set LED pin as output
    PAC |= (1 << LED2_BIT);          // Set LED pin as output
    PAC |= (1 << LED3_BIT);          // Set LED pin as output
    PAC |= (1 << LED4_BIT);          // Set LED pin as output
    PAC |= (1 << LED5_BIT);          // Set LED pin as output
  
    LED1_OFF();
    LED2_OFF();
    LED3_OFF();
    LED4_OFF();
    LED5_OFF();

    int LEDCountdown[LED_NUM];
    int LEDCountup[LED_NUM];
    while(1)
    {
       for( int i=0 ; i<LED_NUM ; i++)
        {
            LEDCountdown[i] = setCountdown();
            LEDCountup[i] = 0;
        }

        while(1)
        {
            for( int i=0 ; i<LED_NUM ; i++)
            {
                LEDCountdown[i]--;
                if( LEDCountdown[i] <= 0)
                {
                    switch(i){
                        case 0:
                            LED1_ON();
                            break;
                        case 1:
                            LED2_ON();
                            break;
                        case 2:
                            LED3_ON();
                            break;
                        case 3:
                            LED4_ON();
                            break;
                        case 4:
                            LED5_ON();
                            break;
                        default:
                            break;
                    }
                    LEDCountdown[i] = setCountdown();
                    LEDCountup[i]++;
                }
            }
            _delay_ms(DELAY_TIME_MS);
            if( LEDCountup[0] < COUNTUP_MAX)
                LED1_OFF();
            if( LEDCountup[1] < COUNTUP_MAX)
                LED2_OFF();
            if( LEDCountup[2] < COUNTUP_MAX)
                LED3_OFF();
            if( LEDCountup[3] < COUNTUP_MAX)
                LED4_OFF();
            if( LEDCountup[4] < COUNTUP_MAX)
                LED5_OFF();

            if( LEDCountup[0] > COUNTUP_MAX && LEDCountup[1] > COUNTUP_MAX && LEDCountup[2] > COUNTUP_MAX && LEDCountup[3] > COUNTUP_MAX && LEDCountup[4] >COUNTUP_MAX ) 
            break;
        }

        for(int i=0 ; i<ON_TIME_S ; i++)
            _delay_ms(1000);
        LED1_OFF();
        LED2_OFF();
        LED3_OFF();
        LED4_OFF();
        LED5_OFF();
    }
}

完成したプログラムです。LEDは3msだけ点灯し、次の点灯まではrand関数で生成された値だけ待ちます。rand関数は元々は16bitの乱数を発生させますが、点滅の最大周期を短くしたいことから、128までに制限しました。

60回点滅すると、常時ONの状態になります。常時ONが8秒経ったら、またランダムに光という処理になっています。

参考までに、プログラムの全体を貼っておきます。

動作結果

白色の点滅LEDかなと思いきや、七色に色が変化するという、ユニークな光り方となりました。

PSF154は安価なので、LEDを点滅させるのに最適なマイコンですね。