//----------------------------------------------------------------------------- // Note // 熱中症の度合いで旗上げをする // PICの周波数を32Mhzに設定 //----------------------------------------------------------------------------- #include #include #include // コンフィグレーションBIT1 設定 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled) #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled) // コンフィグレーションBIT2 設定 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = ON // PLL Enable (4x PLL enabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) #define _XTAL_FREQ 32000000 #define SERVO_IO RA5 #define SENSOR_IO RA4 #define UPPER_LIMIT_IO RA0 #define LOWER_LIMIT_IO RA1 #define DHT11_IO 0b00010000 #define SERVO_IO_ON 1 #define SERVO_IO_OFF 0 #define TMR1_OFFSET 25536 // 割り込みを20msecに設定 #define SERVO_STOP_N 3180 // サーボの停止PLS値(下降時の基準) #define SERVO_STOP_P 3100 // サーボの停止PLS値(上昇時の基準) unsigned short next = 0; unsigned char dht11_data[5] = {0}; short temperature; short humidity; void get_dht11( void ); char get_level(char, char); void interrupt isr_ctrl( void ) { // タイマ1割り込み処理 if( TMR1IF ) { if( next != 0 ) SERVO_IO = SERVO_IO_ON; // コンペアマッチの時間を設定 CCPR1 = next; // タイマ1のカウンタを初期化 TMR1 = TMR1_OFFSET; TMR1IF = 0; } // CCP1割り込み処理 if( CCP1IF ) { SERVO_IO = SERVO_IO_OFF; CCP1IF = 0; } } int main(int argc, char** argv) { char aaa = 0; short level = 0,old_level = 0; short move = 0,wait; OSCCON = 0b01110000 ; // 内部クロック8MHz OPTION_REG = 0b00000000 ;// 7bit目が0でプルアップ抵抗が有効 ANSELA = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISA = 0b00011011 ; // RA0,1,3,4を入力,他を出力に設定 PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) WPUA = 0b00010011 ; // RA0,1,4をプルアップ抵抗に設定 CCP1CON = 0b00001010 ; // コンペアモード T1CON = 0b00100100 ; // 分周1/4 クロック同期有効 TMR1 = TMR1_OFFSET; TMR1IE = 1; // タイマ1割り込み有効 CCP1IE = 1; // コンペアマッチ割り込み有効 TMR1ON = 1; // タイマ1 開始 // 初期設定 next = 0; TRISA |= DHT11_IO; TMR1IF = 0; CCP1IF = 0; PEIE = 1; GIE = 1; // 全割り込み有効 // 温度/湿度センサの稼働待ち __delay_ms(1000); // 電源ON時、下限移動 for(;;) { if( LOWER_LIMIT_IO == 0 ) { // 停止指示 next = 0; break; } else { // 下降指示 next = TMR1_OFFSET + SERVO_STOP_N + 50; } __delay_ms(100); } for(;;) { get_dht11(); level = get_level( temperature, humidity); if( level != old_level ) { move = level - old_level; if( move < 0 ) wait = move*-1; else wait = move; // 移動時間作成 wait *= 13; } if( move < 0 ) { // 下降 while( wait > 0 ) { if( LOWER_LIMIT_IO == 0 ) { // 停止指示 next = 0; wait = 0; } else { // 下降指示 next = TMR1_OFFSET + SERVO_STOP_N + 50; } wait--; __delay_ms(100); } } else { // 上昇 while( wait > 0 ) { if( UPPER_LIMIT_IO == 0 ) { // 停止指示 next = 0; wait = 0; } else { // 上昇指示 next = TMR1_OFFSET + SERVO_STOP_P - 50; } wait--; __delay_ms(100); } } next = 0; old_level = level; __delay_ms(5000); } return (EXIT_SUCCESS); } void get_dht11( void ) { unsigned char i,j,b; // Low 出力 TRISA &= ~DHT11_IO; PORTA &= ~DHT11_IO; __delay_ms(20); // Hi 出力 TRISA |= DHT11_IO; // Low信号の確認開始を遅延する __delay_us(10); // Lowになるまで待つ while( (PORTA & DHT11_IO) != 0 ) { // Hiの間処理無し } // Hi になるのを待つ while( (PORTA & DHT11_IO) == 0 ) { // Lowの間処理無し } for(i=0; i<5; i++) { b = 0; for(j=0; j<8; j++) { // Lowになるまで待つ while( (PORTA & DHT11_IO) != 0 ) { // Hiの間処理無し } // Hi になるのを待つ while( (PORTA & DHT11_IO) == 0 ) { // Lowの間処理無し } // 50usec wait __delay_us(50); // データをシフト b = b << 1; // IOがHiなら1をセット if( (PORTA & DHT11_IO) != 0 ) b |= 0x01; } // データをセット dht11_data[i] = b; } // 温度湿度のデータをセット temperature = dht11_data[2]; humidity = dht11_data[0]; } char get_level(char temp, char humi) { char level = 0; if( temp <= 21 ) { level = 0; } else if( temp == 22 ) { if( humi >= 100 ) level = 1; else level = 0; } else if( temp == 23 ) { if( humi >= 90 ) level = 1; else level = 0; } else if( temp == 24 ) { if( humi >= 85 ) level = 1; else level = 0; } else if( temp == 25 ) { if( humi >= 100 ) level = 2; else if( humi >= 75 ) level = 1; else level = 0; } else if( temp == 26 ) { if( humi >= 90 ) level = 2; else if( humi >= 70 ) level = 1; else level = 0; } else if( temp == 27 ) { if( humi >= 85 ) level = 2; else if( humi >= 60 ) level = 1; else level = 0; } else if( temp == 28 ) { if( humi >= 100 ) level = 3; else if( humi >= 75 ) level = 2; else if( humi >= 55 ) level = 1; else level = 0; } else if( temp == 29 ) { if( humi >= 90 ) level = 3; else if( humi >= 70 ) level = 2; else if( humi >= 50 ) level = 1; else level = 0; } else if( temp == 30 ) { if( humi >= 85 ) level = 3; else if( humi >= 65 ) level = 2; else if( humi >= 45 ) level = 1; else level = 0; } else if( temp == 31 ) { if( humi >= 80 ) level = 3; else if( humi >= 60 ) level = 2; else if( humi >= 40 ) level = 1; else level = 0; } else if( temp == 32 ) { if( humi >= 70 ) level = 3; else if( humi >= 50 ) level = 2; else if( humi >= 30 ) level = 1; else level = 0; } else if( temp == 33 ) { if( humi >= 65 ) level = 3; else if( humi >= 45 ) level = 2; else if( humi >= 25 ) level = 1; else level = 0; } else if( temp == 34 ) { if( humi >= 60 ) level = 3; else if( humi >= 40 ) level = 2; else level = 1; } else if( temp == 35 ) { if( humi >= 55 ) level = 3; else if( humi >= 35 ) level = 2; else level = 1; } else if( temp == 36 ) { if( humi >= 50 ) level = 3; else if( humi >= 30 ) level = 2; else level = 1; } else if( temp == 37 ) { if( humi >= 45 ) level = 3; else if( humi >= 25 ) level = 2; else level = 1; } else if( temp == 38 ) { if( humi >= 40 ) level = 3; else level = 2; } else if( temp == 39 ) { if( humi >= 35 ) level = 3; else level = 2; } else if( temp == 40 ) { if( humi >= 30 ) level = 3; else level = 2; } else { level = 3; } return level; }