回路図
lighting_with_human_sensor人感センサー
このセンサーは、検知後 約22秒間 出力がhigh(1)となっていました
pyroelectric_detectorケース
IMG_1435-2.jpgソフトウエア(フローチャート)
ソースコード
/*********** 人感照明 ************
* File: main.c
* Author: masan
*
* Created on 2022/10/8, 19:10
*/
//------------ ハードウエア情報 -------------
// CPU PIC16F1705
// RA0(13) input ICSPDAT
// RA1(12) input ICSPCLK
// RA2(11) input KEY入力
// RA3(4) input MCLR
// RA4(3) output CLKOUT=Fosc/4
// RA5(2) input 人感センサー入力
// RC0(10) input 未使用
// RC1(9) input 未使用
// RC2(8) output リレーON
// RC3(7) output OPA2OUT/AN7(analog)
// RC4(6) output 未使用:TEST6
// RC5(5) input OPA2IN+(analog 光センサ接続)
//
// 光センサー (JRC)
// PIC16F1705 コンフィグレーション
// CONFIG1
#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = ON // Watchdog Timer Enable
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = ON // Clock Out Enable (CLKOUT function is enabled on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover Mode (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 PPS1WAY = ON // Peripheral Pin Select one-way control (The PPSLOCK bit cannot be cleared once it is set by software)
#pragma config ZCDDIS = ON // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR)
#pragma config PLLEN = OFF // Phase Lock Loop enable (4x PLL is enabled when software sets the SPLLEN bit)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
//************************ インクルードファイル ***********************
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
//******************* 関数定義 **************************************************
void init_OSC(void); //オシレータ初期設定
void init_PORT(void); //ポート初期設定
void init_OPamp(void); //OPamp初期設定
void init_ADC(void); //ADC初期設定
void init_Timer1(void); //Timer1初期設定
void init_Timer2(void); //Timer2初期設定
//******************* PORTの定義など ************************
#define _XTAL_FREQ 2000000 //2MHz
#define KEY_input PORTAbits.RA2 //常時点灯スイッチ
#define HUMAN_input PORTAbits.RA5 //人感センサー入力
#define LED_ON PORTCbits.RC2 //1でLED ON
#define TEST6 PORTCbits.RC4 //RC4(6):TEST6
//***************************** グローバル変数 **********************************
unsigned char human_flag = 0; //人検知 0:No,40:Yes
unsigned short adc_value = 0; //adc値
unsigned short illuminance = 1000; //照度
unsigned short pre1_illuminance = 1000; //1回前の照度
unsigned short pre2_illuminance = 1000; //2回前の照度
unsigned short pre3_illuminance = 1000; //3回前の照度
//************************ プログラム *****************************************
//******************** オシレータ初期設定 ***************************************
// 入力 なし
// 処理 内部オシレータ
// 出力 Fosc(2MHz)
//******************************************************************************
void init_OSC(void){ //オシレータ初期設定
OSCCONbits.SPLLEN = 0; //PLLを使用しない
OSCCONbits.IRCF = 0b1100; //2MHz選択
WDTCONbits.WDTPS = 14; //ウォッチドックタイマー16sec
}
//******************** ポート初期設定 ***************************************
// 入力 無し
// 処理 ポート初期設定
// RA0(13) input ICSPDAT
// RA1(12) input ICSPCLK
// RA2(11) input KEY入力
// RA3(4) input MCLR
// RA4(3) output CLKOUT=Fosc/4
// RA5(2) input 人感センサー入力
// RC0(10) input 未使用
// RC1(9) input 未使用
// RC2(8) output リレーON
// RC3(7) output OPA2OUT/AN7(analog)
// RC4(6) output 未使用:TEST6
// RC5(5) input OPA2IN+(analog 光センサ接続)
// 出力 無し
//******************************************************************************
void init_PORT(void){ //ポート初期設定
TRISA = 0x2f; ANSELA = 0; //all digital
TRISC = 0x23; ANSELC = 0x28; //RC5:analog_input,RC3:analog
}
//****************** OPamp初期設定 ******************************************
// 入力 OPA2+(RC5:5pin)
// 処理 OPamp初期設定(OPA2をフォロワー設定)
// 出力 OPA2OUT(RC3:7pin=AN7)
//******************************************************************************
void init_OPamp(void){ //OPamp初期設定
OPA2CONbits.OPA2UG = 1; //OPA2フォロワー設定
OPA2CONbits.OPA2SP = 1; //OPA2 high GBWP mode
OPA2CONbits.OPA2PCH = 0; //OPA2 +入力=OPA2IN+
OPA2CONbits.OPA2EN = 1; //OPA2 イネーブル
}
//**************************** ADC初期設定 **************************************
// 入力 AN7(RC3:7pin)
// 処理 ADC初期設定
// 出力 なし
//******************************************************************************
void init_ADC(void){ //ADC初期設定
ADCON0bits.CHS = 7; //analog input AN7
ADCON1bits.ADCS = 4; //Fosc/4=2MHz/4=500kHz(2uSec)=Tad
ADCON1bits.ADFM = 1; //output data is right justified
ADCON1bits.ADPREF = 0; //Vref+ = VDD(5V)
ADCON1bits.ADNREF = 0; //Vref- = GND
ADCON2bits.TRIGSEL = 4; //トリガーTimer1オーバーフロー
//割り込み設定
PIR1bits.ADIF = 0; //ADC割り込みフラグクリア
PIE1bits.ADIE = 1; //ADC割り込み許可
ADCON0bits.ADON = 1; //ADC enable
}
//********************** 割り込み処理 *******************************************
//---------------------- ADC割り込み処理 ----------------------------------------
// 入力 割り込み(17mSec毎)
// 処理 ADC割り込みでデータを入力
// 出力 ADC_value
//
//----------------------- Timer2割り込み処理 -----------------------------------
// 入力 割り込み(0.5Sec毎),人感センサー
// 処理 人感センサを検知しtらhuman_flagに40をセット
// 人感センサを検知しない場合 human_flag--
// 出力 human_flag
//******************************************************************************
void __interrupt(high_priority) ISR(void){
//---------------------- ADC割り込み処理(17Sec毎) ----------------------------------------
if(PIR1bits.ADIF == 1){ //--- ADC割り込み処理 ---
if(LED_ON == 0){ //LEDが点灯している時は、 何もしない。消灯時illuminanceを計算する
adc_value = ADRESH;
adc_value = (adc_value << 8) + ADRESL; //10bitデータをセット
illuminance = (adc_value + pre1_illuminance + pre2_illuminance + pre3_illuminance) / 4; //LEDが点灯していないとき計測する、データーの平均化をする
pre3_illuminance = pre2_illuminance; //保持データをセットする
pre2_illuminance = pre1_illuminance; //保持データをセットする
pre1_illuminance = illuminance; //保持データをセットする
}
asm("CLRWDT"); //ウォッチドックタイマークリア
PIR1bits.ADIF = 0 ; // ADC割り込みフラグをクリアする
}
//----------------------- Timer2割り込み処理(0.5Sec毎) -----------------------------------
if(PIR1bits.TMR2IF == 1){ //
//--- 人感センサー入力 ---
if(HUMAN_input == 1) human_flag = 40; //人検知 Yes 40*0.5sec=20sec
else{
if(human_flag >1) human_flag--; //human_flagを減算する
else human_flag = 0;
}
PIR1bits.TMR2IF = 0; //Timer2割り込みフラグクリア
}
}
//**************************** Timer1初期設定 **************************************
// 入力 LFINTOSC(31kHz)
// 処理 Timer1初期設定(ADC トリガー) 25uSec*2~16=16.9秒ごとにトリガー
// 出力 なし
//******************************************************************************
void init_Timer1(void){
T1CONbits.TMR1CS = 3; //LFINTOSC(31kHz)
T1CONbits.T1CKPS = 3; //プリスケーラ1/8=31kHz/8=3875Hz(258uSec)
T1CONbits.TMR1ON = 1; //Timer1 ON
}
//**************************** Timer2初期設定 **************************************
// 入力 fosc/4=2MHz/4=500kHz
// 処理 500kHz/64(prescaler)=7182.5Hz,7182.5/223+1(PR2)=32Hz,32Hz/16=2Hz(0.5Sec)
// 出力 0.5秒毎の割り込み発生
//******************************************************************************
void init_Timer2(void){
T2CONbits.T2CKPS = 7; //プリスケーラ1/64=500kHz/64=7182.5Hz
PR2 = 223; //7182.5Hz/(223+1)=32Hz
T2CONbits.T2OUTPS = 15; //32Hz/16=2Hz(0.5Sec)
//--- 割り込み設定 ---
PIR1bits.TMR2IF = 0; //Timer2割り込みフラグクリア
PIE1bits.TMR2IE = 1; //Timer2割り込み許可
T2CONbits.TMR2ON = 1; //Timer1 ON
}
//*********************** MAIN PROGRAM *****************************************
//******************************************************************************
void main(void) {
init_OSC(); //オシレータ初期設定(4MHz)
init_PORT(); //ポート初期設定
init_Timer1(); //Timer1初期設定
init_OPamp(); //OPamp初期設定
init_ADC(); //ADC初期設定
init_Timer2(); //Timer2初期設定
//--- 割込み許可 ---
INTCONbits.PEIE = 1 ; // 周辺装置割り込みを許可する
INTCONbits.GIE = 1 ; // 全割り込み処理を許可する
while(1){
//--- キー入力 ---
if(KEY_input == 0) LED_ON = 1; //キー入力(常に点灯)あり:LED ON
//--- 照光入力 ---
else if(illuminance > 100) LED_ON = 0; ////昼:LED OFF
//--- 人感センサー入力 ---
else if(human_flag == 0) LED_ON = 0; //人検知なし:LED OFF
else LED_ON = 1; //人検知あり :LED ON
}
}