/* * File: nachtlicht.c * Author: joachim * * Created on 07. November 2025 */ //This uses PIC12F509 //MPLAB X IDE //XC8 C compiler (free) /*------------------------------< Includes >----------------------------------*/ #include #include /*------------------------------< Defines >-----------------------------------*/ #define _XTAL_FREQ 4000000 #define LED_HEAD GPIObits.GP0 //active low #define LED_FLOOD GPIObits.GP1 //active low #define INP_AMB GPIObits.GP2 //active high #define INP_MAINS GPIObits.GP3 //active low #define INP_SW GPIObits.GP4 //active low #define INP_SENS GPIObits.GP5 //active low #define WAITTIME_SW 50 // 0-255 #define WAITTIME_MOVE 10 // 0-255 #define WAITTIME_MAINS 100 // 0-255 #define ONTIME_LED 3000 // 0-65535 #define ON 1 #define OFF 0 #define LED_ON 0 #define LED_OFF 1 /*------------------------------< Typedefs >----------------------------------*/ /*------------------------------< Constants >---------------------------------*/ /*------------------------------< Compiler pragmas >--------------------------*/ #pragma config OSC = IntRC // Oscillator Selection bits (external RC oscillator) #pragma config WDT = ON // Watchdog Timer Enable bit (WDT disabled) #pragma config CP = OFF // Code Protection bit (Code protection off) #pragma config MCLRE = OFF // GPIObits.GP3/MCLR Pin Function Select bit (GPIObits.GP3/MCLR pin function is MCLR) /*------------------------------< Variables >---------------------------------*/ uint8_t switch_pressed; uint8_t mains_down; uint8_t move_detected; uint8_t switch_state = 1; uint16_t timer_light; /*------------------------------< Prototypes >--------------------------------*/ /*------------------------------< Macros >------------------------------------*/ /*------------------------------< Functions >---------------------------------*/ /*-------------------------------------------------------------------------*//*! \fn setLight(uint8_t on_off) \brief sets light on/off depending on current state \param on_off \return - \remarks - *//*--------------------------------------------------------------------------*/ void setLight(uint8_t on_off) { if (on_off) { switch (switch_state) { case 1: LED_HEAD = LED_OFF; LED_FLOOD = LED_ON; break; case 2: LED_HEAD = LED_ON; LED_FLOOD = LED_OFF; break; case 0: default: LED_HEAD = LED_OFF; LED_FLOOD = LED_OFF; break; } } else { LED_HEAD = LED_OFF; LED_FLOOD = LED_OFF; } } /*-------------------------------------------------------------------------*//*! \fn detectSwitch(void) \brief detect pressed switch \param - \return - \remarks - *//*--------------------------------------------------------------------------*/ void detectSwitch(void) { static uint8_t count_sw; if (INP_SW == 0) { if (count_sw > WAITTIME_SW) { switch_pressed = 1; count_sw = 0; } else { ++count_sw; } } else { count_sw = 0; } } /*-------------------------------------------------------------------------*//*! \fn detectMove(void) \brief detect signal from PIR detector \param - \return - \remarks - *//*--------------------------------------------------------------------------*/ void detectMove(void) { static uint8_t count_led; if (INP_AMB == 1 && INP_SENS == 0) { if (count_led > WAITTIME_MOVE) { move_detected = 1; } else { ++count_led; } } else { count_led = 0; move_detected = 0; } } /*-------------------------------------------------------------------------*//*! \fn detectMains(void) \brief detect mains off \param - \return - \remarks - *//*--------------------------------------------------------------------------*/ void detectMains(void) { static uint8_t count_mains;; if (INP_MAINS == 1) { if (count_mains > WAITTIME_MAINS) { mains_down = 1; } else { ++count_mains; } } else { count_mains = 0; mains_down = 0; } } /*-------------------------------------------------------------------------*//*! \fn main(void) \brief main loop \param - \return - \remarks - *//*--------------------------------------------------------------------------*/ void main(void) { /*OPTION * bit 7 GPWU: Enable Wake-up on Pin Change bit (GP0, GP1, GP3) * 1 = Disabled * 0 = Enabled * bit 6 GPPU: Enable Weak Pull-ups bit (GP0, GP1, GP3) * 1 = Disabled * 0 = Enabled * bit 5 T0CS: Timer0 Clock Source Select bit * 1 = Transition on T0CKI pin (overrides TRIS on the T0CKI pin) * 0 = Transition on internal instruction cycle clock, FOSC /4 * bit 4 T0SE: Timer0 Source Edge Select bit * 1 = Increment on high-to-low transition on the T0CKI pin * 0 = Increment on low-to-high transition on the T0CKI pin * bit 3 PSA: Prescaler Assignment bit * 1 = Prescaler assigned to the WDT * 0 = Prescaler assigned to Timer0 * bit 2-0 PS<2:0>: Prescaler Rate Select bits * Bit Value Timer0 Rate WDT Rate * 000 1 : 2 1 : 1 * 001 1 : 4 1 : 2 * 010 1 : 8 1 : 4 * 011 1 : 16 1 : 8 * 100 1 : 32 1 : 16 * 101 1 : 64 1 : 32 * 110 1 : 128 1 : 64 * 111 1 : 256 1 : 128 */ OPTION = 0x87; /* TRISGPIO = 00111100 * Configured GP0 and GP1 as output, all others input * (GP3 is always input) */ TRISGPIO = 0x3C; // Set output pins to LED off state GPIObits.GP0 = LED_OFF; GPIObits.GP1 = LED_OFF; while (1) { CLRWDT(); __delay_ms(10); detectSwitch(); if (switch_pressed) { ++switch_state; if (switch_state > 2) { switch_state = 0; } switch_pressed=0; } detectMains(); if (mains_down) { setLight(ON); } else { detectMove(); if (move_detected) { timer_light = ONTIME_LED; } if(timer_light > 0){ --timer_light; setLight(ON); }else{ setLight(OFF); } } } }