LaQで調光機能付きLEDデスクランプ
・電極(ゼムクリップ)に触れると明るさの変わるタッチセンサ式調光機能付きのLEDデスクランプを作った。
・筐体はヨシリツの立体面ブロックLaQを使っている。
調光機能付きLEDデスクランプ全体図
調光機能付きLEDデスクランプ、点灯
横と後ろから見ると
電子回路
・高輝度LEDは大電流の流せるMOS-FETに接続し、そのON/OFFをマイコンでコントロールしている。
・明るさの調節は、高速でLEDの点灯と消灯を繰り返すPWM方式を採用。点灯している時間に比べて消灯の時間を長くすると、暗く見えるというカラクリだ。
・PIC12F1822の静電容量式のタッチセンサ機能を素直に使用して、調光切り替えスイッチとしている。
回路図
・LEDはコネクタを介して接続する。
・タッチセンサの電極(PAD0)には、ゼムクリップにリード線をハンダ付けしたものを使用した。
使用部品
PICマイコン PIC12F1822-I/P
ICソケット 8ピン用
高輝度LED 白色、VF=2.0〜3.0V程度のもの
NチャネルMOS-FET 2SK2231 (ドレイン電流5A, 許容損失20W)
カーボン抵抗器 1/4W, 150Ω
積層セラミックコンデンサ 0.1uF
圧電サウンダ (13mm)PKM13EPYH4000-A0
バッテリスナップ
単3電池ボックス(3本用)
ユニバーサル基板 70mm x 45mm
スライドスイッチ
配線材
ピンヘッダ 6本用
ピンヘッダ/ソケット 2本用
LaQ 必要なだけ
ファームウェア (XC8 Compiler 用ソースコード)
・スライドスイッチをONにすると、ブザがピッと鳴る。LEDは消灯している。
・1度タッチセンサに触ると、ピーーッと長くブザが鳴りLEDが最高輝度で点灯する。
・2度目にタッチセンサに触ると、LEDが中間輝度で点灯する。
・3度目のタッチで、LEDが最も暗くなる。
・4度目のタッチで、LEDが消灯する。
・次のタッチでは、1度目のタッチと同じ動作に戻り、以後繰り返す。
/*
* File: touch-led-light-12f1822.c
* Author: kaimu
*
* Touch Sensor LED Light
*
* Created on 2013/07/27, 10:30
*/
/*
* target deveice : PIC12f1822
* I/O
* ( INPUT )
* PIN7 : RA0 / PAD0 : Capacitive Sensing Pad
*
* ( OUTPUT )
* PIN2 : RA5 : LED : 1=ON, 0=OFF
* PIN3 : RA4 : Piezo Sounder ( Speaker )
*
*/
/*
* Reboot System Once, After Programming/Verify complete.
*/
#include <xc.h>
#define led() ( RA5 ^= 1 )
#define ledOn() ( RA5 = 1 )
#define ledOff() ( RA5 = 0 )
#define buz() ( RA4 ^= 1 )
#define buzIn() ( TRISA4 = 1 )
#define buzOut() ( TRISA4 = 0 )
__CONFIG(
FOSC_INTOSC & WDTE_OFF & PWRTE_ON & MCLRE_OFF & CP_OFF
& CPD_OFF & BOREN_ON & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF
);
__CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & BORV_HI & LVP_OFF);
void wait(volatile unsigned long t)
// Delay
{
while(t-- > 0) NOP();
}
volatile unsigned int CPSV[3]; // Capacitive Sensing parameter Threshold value for CPS0,1,2
#define CPSPERIOD 10 // Capacitive sensing Counting period
void initCPSV(void)
// Initialize Touch ON/OFF threshold value to 95% of Initial CPS value
{
volatile unsigned int i;
unsigned int cpsv0;
// CaPacitive Sensing settings
CPSCON0 = 0b00001000; // Oscillator is in Medium Range. Charge/Discharge Current is nominally 1.2uA
// Timer1 settings
T1CON = 0b11000001 ; // TIMER1 clock source is CAPOSC. Prescaler 1:1, TIMER1 ON
TMR1H = 0 ; // Initialize TIMER1
TMR1L = 0 ;
PEIE = 1 ; // Peripheral Interrupt Enable
GIE = 1 ; // General Interrupt Enable
CPSON = 1 ; // CPS module ON
for (i = 0; i < 3; i++) {
CPSON = 0; // CPS module off
CPSCON1 = i; // CPS channel 0,1,2 select.
CPSON = 1; // CPS module on
TMR1H = 0; TMR1L = 0; // Initialize TIMER1
wait(CPSPERIOD);
cpsv0 = (TMR1H<<8) + TMR1L; // Get CPS Counted value
CPSV[i] = (unsigned int)((float)cpsv0 * 0.95); // When pad is touched, under 95% of initial value
}
}
int isTouch(unsigned int padno)
// Touch Sensor using Capacitive Sensing module
// RETURN VALUE:
// 0 : Pad is NOT touched.
// -1 : Pad is TOUCHED.
{
unsigned int v; // CPS module output value
int touched;
CPSON = 0; // CPS module off
if (padno > 2) {
return 0; // Invalid port no
} else {
CPSCON1 = padno; // CPS channel 0,1,2 select.
}
CPSON = 1; // CPS module on
TMR1H = 0; TMR1L = 0; // Initialize TIMER1
wait(CPSPERIOD);
v = (TMR1H<<8) + TMR1L; // Get CPS Counted value
if (v < CPSV[padno]) {
touched = -1;
} else {
touched = 0;
}
return touched;
}
void alarmBeep(void)
{
volatile unsigned int i, j;
buzOut(); // Buzzer OUTPUT mode
for ( j = 0; j < 4000; j++) {
buz();
wait(8);
}
buzIn();// Buzzer INPUT mode
}
int main(void) {
volatile int i;
volatile unsigned int touchCount = 3; // How frequentry touched
unsigned int duty[] = { 200, 50, 5, 0}; // Duty cycle parameter
//Initialization
OSCCON = 0b01111010; // PLL disable, 16MHz internal clock
GIE = 1; //Interrupt enable
ANSELA = 0b00000111; // RA012 analog port, others digital port
CM1CON0 = 0x00; //Comparator disable
// 76543210
TRISA = 0b00001111; //I/O Direction. RA0-3:input, RA4-5 : output
LATA = 0b00000000; // PORTA Latch Settings
initCPSV();
alarmBeep();
while (1) {
if (touchCount == 3) {
ledOff();
} else {
ledOn(); wait(duty[touchCount]);
ledOff(); wait(duty[0] - duty[touchCount]);
}
if (isTouch(0)) {
touchCount++;
if (touchCount > 3) {
touchCount = 0;
alarmBeep();
}
alarmBeep();
while (isTouch(0));
}
}
return 0;
}