2019年11月1日金曜日

LED8x8x8 デモ展示



1. 500個のLED
 今年の4月大阪 日本橋の電子パーツ屋のレジ横に、LEDキューブ(5✖5✖5)の展示が目につきました。ロジックIC等の会計をしている間、青く光る125個のLEDが綺麗に点滅しているのに目を奪われました。過去にCEATEC等の電子デバイスの展示会等で何回も目にしていたとは思うのですが、その時はあまり興味がわきませんでした。なぜかレジ横のLEDキューブが目に付いたのでした。会計を済ませ、店を出る間際、特売ワゴンの中に500個千円の赤LEDを発見、咄嗟にLED8X8X8が作れるかもと思い、それを手にとりレジに逆戻り。

2. 256個のロジックICの妄想
 帰りの電車の中、さてLEDキューブどうやって組み上げるかいろいろ考え、、ほぼ妄想レベル。。。 マイコンとのインターフェイスは XYZの3次元指定とし、8ピン×3 + GND で 25ピン。 LEDのON/OFFはANDのロジックICを2段で、、、と思いつきのままあれやこれやと考え、最終的には、ロジックIC幾つ使うのか、ANDのロジックICは4回路入りなので256個必要になると思い至り、こりゃ無理、絶対無理。帰宅早々 500個のLEDは、ストックBOXに。

3.トラ技5月号 PSoc付録基板 その2
74HC595によるシリアル/パラレルの信号変換の検証に、お題は8✖8のLEDの表示をマイコンの4ピン(SI✖2、RCK、SCK)で実現させること。マイコンは、直近で扱っていたトラ技のPSoc基板を使い。LED8x8は自作(市販で300円程度で買えるのですが、あいにく手元に無かったので)
 まず表示を 行(ROW)/列(COL) 指定で1つのLEDを点灯、これを64回繰り返して1面の表示を考えたが、輝度は1/64で暗く、かなりちらつくと予想されるのでNG、次に列(COL)ごとに8つのLEDを点灯、8列分繰り返しての表示を行うことにしました。
PSocで1列毎の表示データ(8ビット)を1面分8列、これを8面分持たせ8X8の8コマの動画の表示を行いました。






4.LED8x8x8
 さて、LED8x8の表示を実現すると、このLED8x8を8枚重ねれば、諦めていたLEDキューブ(8x8x8)ができると思い。ストックBOXから、半年ぶりに500個のLEDを取り出し、(不足分12は別の赤LED)8枚のLED8x8をはんだ付けで作成これを積み重ねてLEDキューブらしきものが出来上がりました。
 原理は、LED8x8の アノード(+)側 8ビットを64ビットにし LED64✖8 マイコン側のプログラムを 8ビットデータを64ビットに拡張しただけ、原理的には LED8x8とほぼ同じ思考で組み上げました。
 ただ、512個のLED、9個の74HC595、2個の74HC126(カソード側(-)反転用)
と配線のはんだ付けが大変でした。

2019年6月14日金曜日

トラ技PSoc基板をためしました。

トランジスタ技術5月号付録のPSoc基板を入手、この2か月あれやこれやといじっています。今回74HC595によるシリアル/パラレル変換をテストしました。

1.LCDディスプレイ表示
キャラクタLCDディスプレイ(SC1602)表示

キャラクタLCDディスプレイの表示にはPSoc Creatorで提供されるサンプルコードを利用します。










サンプルコード選択

〇プロジェクト新規作成
・プロジェクトテンプレート選択で「Code example」を選択。

・サンプルコード(code example)選択で「Char_LCD_Horizontal_Bar_Graph」を選択。


Bootladableコンポーネント追加

・Bootladableコンポーネントを追加(トラ技 Lチカプロジェクト(LEDBLINK) 参考)





〇このサンプルプロジェクトをビルド後PSoc基板に書き込む。
       ※書き込み後 サンプルプログラムが動き出す。
〇このプロジェクトのデモ表示部を削除して、LDC表示のみを残しベースプロジェクトとします。

2.GPIO割り込みの実装
操作SW用 Digital Input Pin コンポーネント追加
テスト基板の3つの操作スイッチの割り込みを実装します。
〇Digital Input Pinコンポーネントの追加
・Number Of Pinsを3に
・Interruptの設定



〇main.cの編集
・CY_ISR_PROTOマクロを使用してGPIO割り込み関数を宣言
  CY_ISR_PROTO(GPIO_ISR);
・CY_ISRマクロを使用してGPIO割り込み関数を定義
  CY_ISR(GPIO_ISR)
   {
       uint8 InterruptState = SW_ClearInterrupt();
      ・・・・・・・・
             ※InterruptStateにPinのIDが格納
・main()に初期処理を追加
     isr_1_StartEx(GPIO_ISR);  ・・・・GPIO割り込み関数を登録
     CyGlobalIntEnable;     ・・・・・割り込みを許可

3.74HC595のテスト
今回は、74HC595(シリアル/パラレル変換)のテストを行った。
74HC595テスト構成


・操作スイッチSW1~3でLEDの点灯パターンを切り替え。
・PSoc4100S ==> 74HC595 はシリアル。
・74HC126は今回のテストでは不要
(ほぼ無意味)
・PSoc4100S<==>LCDキャラクタLCDディスプレイの接続はP0をP2に変更
   






74HC595テスト




















※※※※※main.c※※※※※※

#include
#include

/* The LCD format in characters */
#define LCD_ROWS                (2u)
#define LCD_COLUMNS             (16u)

/* The delay between displaying bar graphs */
#define BARGRAPH_DELAY_MS       (15u)

CY_ISR_PROTO(GPIO_ISR);

int iPtn = 0;

void fnc_595(int ic){
    int i;
    int j;
    int k;
    k = 128;
    j = ic;
    RCK_Write(0);
    for(i=0;i<8 i="" p="">        if( k & j){
            SI_Write(1);
        } else {
            SI_Write(0);
        }
        SCK_Write(1);   
        CyDelay(10u);
        SCK_Write(0);
        k = k >> 1;
    }
    RCK_Write(1);
return;
}

int main()
{
    int idat = 1;
   
    /* Start the LCD */
    LCD_Start();

    /* Show the demo start message */
    LCD_Position(0u, 0u);
    LCD_PrintString("Test 74HC595");
    LCD_Position(1u, 0u);
    LCD_PrintString("#####05######");
    SI_Write(0);
    RCK_Write(0);
    SCK_Write(0);
    CyDelay(1000u);

    isr_1_StartEx(GPIO_ISR);
    CyGlobalIntEnable;
   
    for(;;)
    {
        if(iPtn == 0){
            idat++;
        }else if(iPtn ==1){
            if(idat == 0) idat = 1;
            else idat = idat << 1;
        }else if(iPtn ==2){
            if(idat == 0) idat = 128;
            else idat = idat >> 1;
            }
        idat = idat & 0xFF;
        fnc_595(idat);
        CyDelay(100u);
    }
}

CY_ISR(GPIO_ISR)
{
    uint8 InterruptState = SW_ClearInterrupt();
    char cbuff[8];
   
    itoa(InterruptState,cbuff,10);
   
    LCD_Position(1u, 0u);
   
    if (InterruptState == 1){
      LCD_PrintString("##Key1##");
       iPtn =0;

    }else if (InterruptState == 2){
     LCD_PrintString("##Key2##");
       iPtn =1;
 
    }else if (InterruptState == 4){
      LCD_PrintString("##Key3##"); 
       iPtn =2;
 
    }else {
      LCD_PrintString("##KeyX##");
   }
     LCD_Position(1u, 9u);
     LCD_PrintString(cbuff);
}
※※※※※※※※※※※※※※※※※※

GPIO割り込み時の押されたスイッチの識別は
 uint8 InterruptState = SW_ClearInterrupt();
の InterruptState  に格納される値で行いました。
Digital Input PinコンポーネントのSWのピンIDで
SW[0]の場合 1
SW[1]の場合 2
SW[2]の場合 4  となるようです。