カウントアップ人感センサ付きライトを作ってみる

# はじめに

タイトルの通りで，マイコン・ハードウェアの勉強をしようということで，カウントアップ人感センサ付きライト作ってみました．
作ったものは以下のような人感センサ付きライトで，手をかざすとライトが点灯し，さらに同時にセグメントLEDがカウントアップするというものです．これが何の役に立つかと言われるとわかりませんが，色々と勉強になったので，備忘録的に記録として残しておきたいと思います．

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/bf74afab-be5c-3cb9-1a67-406825d16ba3.gif)

# 必要なもの

今回は人感センサからの信号を受信したらライトを点灯し，そのライトが点灯する度にセグメントLED（デジタルの数字を表示できるライト）をカウントアップする（謎）仕様のため，プログラム内で現在の数字の状態を保持する必要があります．そのため，PICマイコンを使用し，その辺りをプログラムで処理するようにしました．

## ハードウェア

ハードウェアは以下のものを使用しました．

- PIC12F629
    - マイコン
    - 参考：[超入門PICマイコンの使い方](https://www.marutsu.co.jp/pc/static/large_order/begin_pic)
- AMN34111
    - 人感センサ
- TC4511BP
    - セグメントデコーダ
    - セグメントLED用のデコーダ．2進数を利用して4個のピンから0〜9を点灯させることができる．
- C-551SRD
    - セグメントLED
- KSC1815YTA
    - NPNトランジスタ

データシートは検索すれば出てきますが，念のため[こちら](https://github.com/jjjkkkjjj/counter-hw/tree/master/docs)にアップしました．

ちなみにAMN34111の検出範囲は10mでかなり広範囲です．価格も1,000円超で，明らかにオーバースペックですね．．．

### 回路図

回路図は以下のようにしました．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/09d2d428-ff9e-0838-cd91-3c7ab2448cbf.png)

今回使用するマイコンのPIC12F629は合計で8つのピンがあり，VDD，VSSを除く6つがGPIOになります．GP0，1，2，4をセグメントデコーダへの出力，GP3を人感センサからの入力，GP5はライトへの出力になります．（GP5については，今回はVDDが共通なので，本来であればトランジスタは不要ですかね．）

人感センサからの入力は，データシートによるとOUTがVDD-0.5[V]が入ってきます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/88a496bf-ba6d-5b72-5f7f-1c0a12f8141b.png)

PIC12F629の仕様では，この入力電圧であればHighとして認識してくれそうです．（データシートのこの部分かわからない．どこをみて良いかわからなかった．）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/6aa50043-ef38-4623-b275-b529b7502c2d.png)


## ソフトウェア

PIC12F629へのコーディング，書き込みは公式IDEであるMPLabXを使います．

### インストール〜プロジェクト作成

#### MPLABX（IDE）インストール

[公式サイト](https://www.microchip.com/en-us/tools-resources/develop/mplab-x-ide)からIDEをインストールします．

※今のところ大人しく公式のIDEを使ったほうが良さげ．

参考：[【備忘録】Visual Studio CodeでPICマイコン開発をする方法](https://www.mass-site.work/blog/b20220507.html)

#### コンパイラのインストール

[公式サイト](https://www.microchip.com/en-us/tools-resources/develop/mplab-xc-compilers)からCPUのbit数に応じたコンパイラをインストールします．特にPATH設定などはせず，Defaultのままで良さげです．


#### プロジェクトの作成

先にPicKitを接続しておきます．File > New Projectを選択すると，以下の画面になり，接続したPicKitが表示されていれば認識されます．書き込みたいマイコンを選び，Next．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/df410deb-da9d-671e-369a-14692d86f00e.png)

Debugをするか否か？適宜選びます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/2e570f8b-f0fe-71d1-997b-de1741c24ff9.png)


コンパイラを選びます．ここから選択できない場合は，正しくコンパイラをインストールされていない可能性が高いです．Tools > Options > Embbeded > Build Tools > Toolchainでコンパイラが選ばれているか要確認です．なければ，[コンパイラのインストール](#コンパイラのインストール)を再度行います．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/cc48caa2-bd5a-6f79-970c-7bc23000a276.png)


フォルダの場所を適宜設定します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/d6ea79fc-3410-9365-c5a0-2caff7b62747.png)

#### main.cファイルの作成

mainファイルをSource Files > New Filesをクリックすると，以下の画面になるので，コンパイラを適宜設定し，`main.c`を選択しNext．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/c41ba3ee-34a6-60f8-0aee-710dbfb7280a.png)

File Nameを適宜設定し，Finishで`main.c`を生成できます．

#### Bit（レジスタ）設定でソースコードを自動生成

Production > Set Configuration Bitsを選ぶと，下側のタブが生成されるので，適宜設定し，Generate Source Codfe to Outputをクリックします．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/f35c7815-e946-b22d-1e1e-995448f86797.png)


すると，コードが生成されるので，それを`main.c`にコピペします．


## PICコーディング

最終的なコーディングは以下のようにしました．

```c:main.c
/*
 * File:   main.c
 * Author: Hoge
 *
 * Created on November 23, 2022, 12:23 AM
 */



// PIC12F629 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTRCIO     // Oscillator Selection bits (RC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, RC on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = ON      // Power-Up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF       // GP3/MCLR pin function select (GP3/MCLR pin function is GP3)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

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

#include <stdio.h>
#include <stdlib.h>
#include <pic.h>
#include <xc.h>

#define _XTAL_FREQ 4000000 // for delay

/**
 * Initialize PIC
 */
void PIC_init(){
    OSCCAL = 0x80; //oscillator center
    PCON &= 0x00; //enable POR BOD
    
    CMCON = 0x07; //disable comparator
    
    TRISIO = 0b0001000; //Set 0001000. This means GP3 is input, the others are output.
    
    return;
}

int main(int argc, char** argv) {
    
    // Initialize PIC
    PIC_init();
    /*
     * GP0: B
     * GP1: C
     * GP2: D
     * GP4: A
     * Comment: 2104 => DCBA => e.g) LLLL
     */
    unsigned char gpio[10] = {
        0b000000, // LLLL => 0
        0b010000, // LLLH => 1
        0b000001, // LLHL => 2
        0b010001, // LLHH => 3
        0b000010, // LHLL => 4
        0b010010, // LHLH => 5
        0b000011, // LHHL => 6
        0b010011, // LHHH => 7
        0b000100, // HLLL => 8 Note: GP3 is input
        0b010100, // HLLH => 9
    };
    unsigned int counter = 0;
    GPIO = gpio[counter];
    
    while(1){
        if (GP3 == 1){
            counter = (counter + 1) % 10;
            GPIO = gpio[counter];
            GPIO += 0b100000; // Set GP5 = H means turn on the external light
            // delay for the next detection
            __delay_ms(5000);
        }
        else{
            GPIO = gpio[counter];
            __delay_ms(100);
        }
   }
    return (EXIT_SUCCESS);
}
```

`TRISIO = 0b0001000;`でGPIO3を入力に設定しています．コード自体は単純ですが，注意点として機能のバッティングがあります．PICは多機能なので，機能がバッティングして，意図した機能を実現できないことがあります．実際，私もここでハマり，入力電圧を読み込めないことに悩まされました．結論，Configuration Bitの定義部分で`#pragma config MCLRE = ON`としていたのが原因で，GPIOとしてでなくMCLRとして機能していたようでした．やっぱりデータシートはしっかりと読まないといけないですね．．．

# ブレットボードでの実装

まずは[回路図](#回路図)をブレッドボードで実装しました．紆余曲折がありましたが，何とか実現できました．

![output-bb.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/09d760e9-72fc-c96e-7f71-ac95c2de6aec.gif)

## PICへの書き込み

PICへの書き込みは，ブレッドボードに実装した段階でPICKit3を用いて書き込みました．接続は以下のようにして書き込みました（接続部分のみ抜粋）．なお，今回は全てのピンを使用するので，プルダウンの10kΩは使用していません．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/6c7ef069-86ad-b51f-2647-e75378406a09.png)

書き込み時にも何点か注意すべき点がありました．

- PicKitの接続
    - PicKitを接続してからMPLABXを起動しないと`Failed to program device`と出るかも
- プログラムの修正・再書き込み
    - 電圧が足りないと，プログラムの再書き込み時に`Failed to program device`と出る可能性がある．
- プログラムの規模によって，必要な電圧が変わるっぽい．
    - PiCKitからの供給電圧を適宜探すしかなさそう．．．
    - 外部電圧供給の方が安定するっぽい．今回は外部電圧供給するようにした．

# 基盤への実装

せっかくなので，基盤に実装することまで行いました．今回は以下のように15x25のユニバーサル基盤に実装しました．（グレーコードが裏側の配線になります．色付きはやむを得ず表側の配線になります．）ご覧のようにまあまあ複雑な回路になりました．．．もう少し大きいサイズの基盤に実装すれば良かったです．

![diagram_bb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/abde8e1f-9c35-543a-45f7-7241af5e2cb9.png)

# 完成

基盤に実装することでかなりスリムになりました．

![IMG_5936.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/daf6e3a0-f46f-75ec-b2e9-8be4293a00f8.jpeg)

裏側です．半田づけは不器用なのでまあまあ大変でした．いつショート等してもおかしくないですが，まあ動いたのでよしとします．

![IMG_5937.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/39af60e6-d625-f232-0d1f-4781fbbd1904.jpeg)

ちなみにコネクタ部分はEHのハウジングコネクタをしようしています．

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253935/bf74afab-be5c-3cb9-1a67-406825d16ba3.gif)

# おわりに

実用性は置いといて，初心者なりにそれなりのものができたかなと思います．この作成を通じて，データシートは必ず読むということと，確認できる部分はサボらず丁寧に確認する（ソフトウェアのデバッグと似ている）ことを徹底すべきということを学べたと思います．今回実装した知見を活かして，いろいろなものを作って行けたらなと思います．

# 参考

- [超入門PICマイコンの使い方](https://www.marutsu.co.jp/pc/static/large_order/begin_pic)
- [MPLAB XC8のインストール(Windows編)](https://sanuki-tech.net/pic/development/install-mplab-xc8/)
- [第12回 PICKIT3書き込み回路を設計する](https://tool-lab.com/macpic-startup-12/)
- [PIC12F629デジタル入力について](https://oshiete.goo.ne.jp/qa/5129153.html)