Vol.766 12.Apr.2019

高機能な8ビットPIC(5)〜パソコンでPICのカラーLED制御 トレース台

P 高機能な8ビットPIC(5) 〜パソコンでPICのカラーLED制御〜

by fjk

ラズパイやPIC単独でもIOTを実現できるが、高速動作や非同期のセンサー入力やモーター制御はハードに強いPICで行い、ラズパイではシステム全体の制御、ネットアクセス、データの解析や分析・判断を行う分業システム構築のために、パソコン(TeraTerm使用)にUSB接続し、予備通信テストを行う。
 具体的には、

@AD変換データをLCDに表示後、パソコンにシリアル通信(USART)で1秒おきに送信・表示
A パソコンで”0”〜”7”のデータを入力しシリアル通信でPICに送る
B PICで受信したデータからカラーLEDを点灯

今回、3つのLED(PWM)、ADCとI2Cも同時に利用するので、PWMが4つ使える14ピンPICの16F15325を使う(PWMが2以下で良い場合は同ピン配置の16F1824/5や16F1764/5等も利用可)。

1.ステップ1(PWM制御無し)
パソコンから送られた値でLEDを7色に点灯。
 @MCC設定(abc764abc765を参考に)
  ・クロック設定(32MHz)
  ・LEDは単にデジタル出力に設定
  ・ADC設定(TAD:1〜9μS)
  ・EUSART設定(ボーレート設定)
  ・MSSP設定(I2Cクロック:100kHz)
 Aスケッチ
  ・LCDライブラリの読込
  ・TMR2に追加(abc763参照)
  ・EUSARTの修正・追加(abc764参照)
  ・main.cの作製

※ コンパイル時にI2Cでエラー
 前回は i2c.hとi2c.cだったが、今回はi2c1.hとi2c1.cとファイル名および関数名が変わっていた。そこで、この名称の変更を行うと、正常にコンパイルされた。eusartもeusart1にしなければならないが、標準入出力を使ったのでエラーとならなかった。デバイスを変える場合、名前に注意が必要。

2.ステップ2(PWM制御有り)
 各カラー毎に”0”〜”7”の3文字を送り、
カラーLEDの明るさを制御。
 @MCC設定(abc763を参考に)
 ・各LEDをPWM出力に設定
   {赤(A4):PWM_3、緑(C3):PWM_4、青(C2):PWM_5}
 ・TMR2はPWMで使うので1秒割込にはTMR0利用
Aスケッチ
 ・TMR0の設定
 ・TMR2の修正
 ・main.cで受信データの出力部(青字部)を変更

※ ステップ@で使ったTMR2の割込はAでは不要なのでチェックを外したところ、コンパイル時に「割込設定ハンドラーが無い」というエラーが出た。仕方が無いので、割込有りのままにした。
 ・MCCでは、一度設定した設定を変更しGenerateしても、変更が反映されないことがあるので注意!
 ・設定変更が上手く反映されない場合、新規にプロジェクトを新設定で作り直した方がベター。

回 路 図 試作テスト回路
(LCD、USB給電)
通信テスト風景
”621”の場合
SystemModule Timer 2 MSSP(I2C)
Timer 0 EUSRAT Pin Module
        
AD_Coverter       PWM3         PWM4          PWM5

PWM無し   PWM有り
#include "stdio.h"
#include "mcc_generated_files/mcc.h"
#include "lcd_lib.h"

unsigned char sBuf[16];
unsigned char rBuf[16];
char Flag, mFlag;
int Index, Val, LedCol, RedC, BluC, GrnC;

void main(void){
    SYSTEM_Initialize();
    mFlag = 0;
    Flag = 0;
    Index = 0;
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
    Lcd_init();
    Lcd_str("Hellow"); 
    LED_A2_SetHigh();
    puts("Hellow");

    while (1){
        Val = ADC_GetConversion(ANA5);
        if(mFlag){
            LED_A2_Toggle();
            mFlag = 1;
            sprintf(sBuf,"AD=%4d\n\r", Val);
            Lcd_cmd(Lcd_L2);
            Lcd_str(sBuf);
            printf("%s",sBuf);
        }
        if(Flag){
            Flag = 0;
            Lcd_clear();
            Lcd_str(rBuf);
            printf("%s",rBuf);
            LedCol = atoi(rBuf[0]);
            RedC = LedCol % 2;
            GrnC = (LedCol / 2) % 2;
            BluC = (LedCol / 4) % 2;
            if(RedC){
                RED_4_SetHigh();
            }else{
                RED_4_SetLow();
            }
            if(GrnC){
                GRN_8_SetHigh();
            }else{
                GRN_8_SetLow();
            }            
            if(BluC){
                BLU_7_SetHigh();
            }else{
                BLU_7_SetLow();
            }            
        }
    }
}
 
#include "stdio.h"
#include "mcc_generated_files/mcc.h"
#include "lcd_lib.h"

unsigned char sBuf[16];
unsigned char rBuf[16];
char Flag, mFlag;
int Index, Val, LedCol, RedC, BluC, GrnC;

void main(void){
    SYSTEM_Initialize();
    mFlag = 0;
    Flag = 0;
    Index = 0;
    INTERRUPT_GlobalInterruptEnable();
    INTERRUPT_PeripheralInterruptEnable();
    Lcd_init();
    Lcd_str("Hellow"); 
    LED_A2_SetHigh();
    puts("Hellow");

    while (1){
        Val = ADC_GetConversion(ANA5);
        if(mFlag){
            LED_A2_Toggle();
            mFlag = 0;
            sprintf(sBuf,"AD=%4d\n\r", Val);
            Lcd_cmd(Lcd_L2);
            Lcd_str(sBuf);
            printf("%s",sBuf);
        }
        if(Flag){
            Flag = 0;
            Lcd_clear();
            Lcd_str(rBuf);
            RedC = rBuf[0] - 0x30;
            GrnC = rBuf[1] - 0x30;
            BluC = rBuf[2] - 0x30;
            if((RedC >= 0)&&(RedC < 8))
            {
               PWM3_LoadDutyValue(RedC * 64);
            }
            if((GrnC >= 0)&&(GrnC < 8))
            {
               PWM4_LoadDutyValue(GrnC * 64);
            }
            if((BluC >= 0)&&(BluC < 8))
            {
               PWM5_LoadDutyValue(BluC * 64);
            }
        }
    }
}


T トレース台

by fjk

風景画を模した編み物用の型紙を、女房が作りたいというので、5mmメッシュの用紙をエクセルで印刷し、印刷した写真を下に敷き、トレースして型紙を作ることにした。しかし、2枚の紙を重ねただけでは下の図柄は見えないので、むかし、蛍光灯で作ったトレース台を利用することにした。しかし、この蛍光灯はさすがに古く、明るさがかなり低下していた。
 そこで、LEDを使って自作しようと、必要な材料を調べてみると、数万円も必要なことが判った。自作は、明るさやサイズを自由に設計できるが、もっと安価に出来ないか、「トレース台」で検索してみると、A4サイズのものが2000円程度で売られていることが判り、アマゾンで即ポチリ。
 入手したトレース台(Seebaby)は4mm厚のアクリル製で、液晶パネルのバックライトのような導光板を使ったLEDエッジライト方式のものだった。USB電源が必要で、電源は付属しておらず、別途準備する必要がある(USBケーブルは付属)。電源のON/OFFはタッチ式で、ボタンを長押しすると明るさを変えることが出来る(明るくなったり暗くなったり、適当なところでボタンを離す)。
 厚手のコピー用紙を重ねると、明るい環境では非常に見づらくなるが、作業環境を暗くすると綺麗にトレースすることが出来た(鉛筆でおおよそを下書き後、色鉛筆で色塗り)。暗がりでは色鉛筆の選択など作業時の手元がつらいので、LEDライトスタンドで筆記用具などを部分的に照らした。
 このトレース台はA4サイズ+αのアクリルボードなので、USBケーブルを外すと、下敷きやバインダーのような使い方も出来るし、出っ張りもほとんど無く、収納も容易である
古いトレース台(ミニ蛍光灯3本) 新しいトレース台(LED+導光板)
印刷した写真と方眼用紙を置くと 作成した型紙の例(下敷き?付)


高機能な8ビットPIC(5)〜パソコンでPICのカラーLED制御 トレース台