タッチすると音楽が流れ出す。または、明るくなると音楽が流れ出す。
音楽が流れているときにLEDが点滅する。
曲は「富士山(文部省唱歌)」のように聞こえるもの。
ブレッドボード
マイコン Microchip PIC12F1822
カーボン抵抗器 1/4W 150Ω、1/4W 100kΩ
フォトトランジスタ NJL7502L
ジャンパ線 2本
圧電サウンダ (13mm)PKM13EPYH4
LED φ5mm
電池ボックス(単3型×3本用)、バッテリースナップ
曲は「富士山(文部省唱歌)」のように聞こえる。const配列 melody[]に曲データが記録されている。
※プログラムを書き込んだ直後に電源を一度切り、もう一度電源を入れるとタッチセンサが動作し始める。
/* * File: melody-box-12f1822.c * Author: kaimu * * Created on 2014/02/11 - 02/15 *//* * Input * RA3 [PIN4] : Opt-transistor ( Dark...1, Blight...0 ) * CPS0 [PIN7] : Capasitive Sensing * Output * RA5 [PIN2] : LED (1...OFF, 0...ON) * CCP1 (RA2) [PIN5] : piezo buzzer */#include <xc.h>#define buz() ( RA2 ^= 1 )#define ledOn() ( RA5 = 0 )#define ledOff() ( RA5 = 1 )#define led() ( RA5 ^= 1 )#define isBright() ( RA3 == 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); // VDD High__CONFIG(PLLEN_OFF & STVREN_ON & WRT_OFF & BORV_LO & LVP_OFF); // VDD LOWvoid wait(volatile unsigned long t)// Delay{while(t-- > 0) NOP();}void initIo(void){ //OSCCON = 0b01111010; // PLL disable, 16MHz internal clock //OSCCON = 0b01100010; // PLL disable, 8MHz internal clock OSCCON = 0b01101010; // PLL disable, 4MHz internal clock //OSCCON = 0b01011010; // PLL disable, 1MHz internal clock //OSCCON = 0b00111010; // PLL disable, 500kHz internal clock GIE = 1; //Interrupt Enable ANSELA = 0b00000001; //RA0 Analog port, others digital port CM1CON0 = 0x00; //Comparator disable TRISA = 0b00001001; //I/O Direction. RA1,2,4-5 : output, RA0,3 : Input LATA = 0b00000000; // PORTA Latch Settings}void initPwm(void){ //Timer2 settings for PWM standard mode PR2 = 0; // PWM Period = [(PR2) +1 ]*4*(1/FOSC)*(Timer2 Prescale value) T2CON = 0b00000010; //00 = Prescaler is 1, 01 = Prescaler is 4 10 = Prescaler is 16 11 = Prescaler is 64 //CCP1 function is on RA2 APFCON &= ~(1<<CCP1SEL); CCP1CON = 0b00001100; //PWM mode: P1A, P1C active-high; P1B, P1D active-high CCPR1L = 64; // PWM Duty Cycle (CCPR1L:CCP1CON<5:4>)*(1/FOSC)*(TMR2 Prescale Value) //Start PWM TMR2 = 0; TMR2ON = 1;}void sound(unsigned char melody)// Melody format/* * (example) 0x12 ... first '1' is 'C', second '2' is length of sound * first digit : 1 2 3 4 5 6 7 8 0 * sound name : C D E F G A B C rest */{ unsigned int freq[] = {0, 238, 212, 188, 178, 158, 141, 125, 118}; volatile unsigned int oto, nagasa; oto = (int)(melody & 0xf0)>>4; nagasa = (int)( melody & 0x0f); PR2 = freq[oto]; wait((long)nagasa * 10000);}void soundLed(unsigned char melody)// Melody format/* * (example) 0x12 ... first '1' is 'C', second '2' is length of sound * first digit : 1 2 3 4 5 6 7 8 0 * sound name : C D E F G A B C rest */{ unsigned int freq[] = {0, 238, 212, 188, 178, 158, 141, 125, 118}; volatile unsigned int oto, nagasa; oto = (int)(melody & 0xf0)>>4; nagasa = (int)( melody & 0x0f); PR2 = freq[oto]; led(); wait((long)nagasa * 10000);}volatile unsigned int CPSV[4]; // Capacitive Sensing parameter Threshold value for CPS0,1,2,3#define CPSPERIOD 10 // Capacitive sensing Counting periodvoid 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,3 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 > 3) { 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 main(void){ volatile unsigned int i; // "Fujisan" const unsigned char melody[] = { 0x53, 0x51, 0x62, 0x52, 0x32, 0x11, 0x21, 0x32, 0x02, 0x23, 0x51, 0x52, 0x41, 0x31, 0x25, 0x02, 0x53, 0x51, 0x32, 0x12, 0x63, 0x71, 0x82, 0x62, 0x53, 0x61, 0x51, 0x41, 0x31, 0x21, 0x15, 0x02, 0x23, 0x21, 0x22, 0x22, 0x11, 0x21, 0x31, 0x41, 0x52, 0x02, 0x63, 0x71, 0x82, 0x62, 0x55, 0x02, 0x84, 0x62, 0x42, 0x34, 0x62, 0x52, 0x42, 0x32, 0x23, 0x11, 0x15, 0x02, 0x04, 0xff }; //Initialization initIo(); initPwm(); initCPSV(); while(1){ if ( isTouch(0) || isBright()) { for (i = 0; melody[i] != 0xff; i++) { soundLed( melody[i] ); } } else { ledOff(); } }}