/* Revision 1: 2024 - 01 - 29- 11:00 ################################ General Layout ############################################## # (PCINT5/!RESET/ADC0/dW) PB5 1 | AT | 8 VCC # (PCINT3/X<10TAL1/CLKI/!OC1B/ADC3) PB3 2 | TI | 7 PB2 (SCK/USCK/SCL/ADC/T0/INT0/PCINT2) # (PCINT4/XTAL2/CLKO/OC1B/ADC2) PB4 3 | NY | 6 PB1 (MISO/DO/AIN1/OC0B/OC1A/PCINT1) # ________________________________ GND 4 | 85 | 5 PBO (MOSI/DI/SDA/AIN0/OC0A/!OC1A/AREF/PCINT0) +++++++++++++++++++++++++++++++ Project Layout +++++++++++++++++++++++++++++++++++++++++++++++++ +--------+ Reset - 1 --+ +-- 8 - Vcc Vcc-R-Light_Sensor-GND - ADC3/PB3 - 2 --+ +-- 7 - PB2/ADC1 - Vcc-control, U_min 3,8V - ADC1 (GND-100k-100k-Vcc) Vcc-R-LED_Vcc_Warning (red on Breadboard)-GND - PB4 - 3 --+ +-- 6 - PB1 - 100k - Gate_nKanalMosfet - Drain-Katode_LED Christmas star (blue on Breadboard) - Anode - Vcc GND - 4 --+ +-- 5 - PB0/PCINT0 - +--------+ +++++++++++++++++++++++++++++++ Project Layout +++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++ Project Calculation ++++++++++++++++++++++++++++++++++++++++++++ Battery characteristic: LiPo - LiPO_V_max >=4,2 V - Lipo_V_min =3,5 V --> to activate battery warning signal --> V_min = 0,928571429% of V_max Reference voltage: Vref = 2,56V --> voltage divider 1:1 Warning threshold: 100 kO:100 kO --> U_R2/V_Ref = 68,36% --> Threshold for ADC-input 1,75 V = 0,6836 * Vref (2,56V) = 175 to activate battery warning signal Dark threshold: V threshold light sensor = 0,4V --> 0,4/2,56 = 0,15625 --> Light_sensor_threshold = 15 +++++++++++++++++++++++++++++++ Project Calculation ++++++++++++++++++++++++++++++++++++++++++++ https://symbl.cc/de/alt-codes/ ~ = Alt 126 { = Alt 123 } = Alt 125 ° - Alt 0176 µ - Alt 0181 | = Alt 0124 kO ! logic Negation ! b */ /* Excel file to calculate parameters: Weihnachtsstern-Berechnungen.xlsx */ /* -------------------- Literature ----------------- Interrupt-Taster INT0: (www.electronicwings.com) + https://www.electronicwings.com/avr-atmega/atmega1632-external-hardware-interrupts origin written for ATmega16 https://elektro.turanis.de/html/prj271/index.html http://www.technoblogy.com/show?KX0 ADC: https://www.marcelpost.com/wiki/index.php/ATtiny85_ADC Save Power: https://elektro.turanis.de/html/prj271/index.html Timer normal Mode with Interrupt https://www.gadgetronicx.com/attiny85-timer-tutorial-generating-time-delay-interrupts/ https://wolles-elektronikkiste.de/timer-und-pwm-teil-1 Timer compare Mode with Interrupt https://www.gadgetronicx.com/attiny85-compare-match-tutorial-interrupts/ */ #define F_CPU 1000000UL typedef enum { false, true} bool; #define Reset_Pin1 PB5 #define LED_Vcc_Warning PB4 // PIN3 - PB4 - LED_Vcc_Warning red --> output #define ADC3_Pin2_Rfoto PB3 #define ADC1_Pin7_Vcc PB2 #define LED_Christmas_Star PB1 // PIN6 - PB1 - LED_Light blue --> output #define PCINT0_Pin5 PB0 #include #include #include const int Light_sensor_threshold=198; // compare value to detect dark threshold const int Vcc_Warning_threshold=175; // compare value to detect low LiPo voltage const int Timer0_Startvalue = 12; // set start value Timer/Counter Register tor reach 250 ms const int Timer_Clocks_PerSecond = 4; // numbers of interrupts to reach delay of 1 sec if Timer delay 250 ms const int SwitchOn_hours = 0; // switch on Christmas Star in h ### for roll out 6 h const int SwitchOn_min = 1; // switch on Christmas Star in min ### for roll out 0 min const int SwitchOn_sec = 0; // switch on Christmas Star in sec ### for roll out 0 s unsigned long SwitchOn_Christmas_Star_TimerClocks; // switch on Christmas Star in total clocks const int SwitchOn_Vcc_Warning = 10; // switch on Christmas Star in sec if Vcc to low, then pause to signalize it int SwitchOn_Christmas_Star_Vcc_Warning; // switch on Christmas Star in total clocks if Vcc to low, then pause to signalize it const int LED_Christmas_Star_Pause = 250; // pause after LED_Christmas_Star was on in ms const unsigned long Darkness_Delay = 1000; // pause to repeat the darkness test in ms --> 1000 * (60 * delay [min] + delay [sec]) // ### for roll out 15 min = 900000 clocks int Timer0_Counter = 0; // variable to count Timer0 interrupts, all 250 ms one interrupt int i; // common variable int n; // common variable int z; // common variable bool Flag_Vcc_Warning; // true, if LiPo voltage to low bool Flag_Dark; // true, if darkness begins --> wait for 10 min to switch ChristmasStar on bool Flag_Dark_Consist; // true, if really dark --> ChristmasStar on bool Flag_ChristmasStar; // true, if ChristmasStar on void Init_IO_Ports(); void LED_Christmas_Star_On (); void LED_Christmas_Star_Off(); void LED_Vcc_Warnin_On(); void LED_Vcc_Warning_Off (); void Init_ADC1_Pin7_Vcc_8bit_256mV_prescaler16(); void read_ADC1_Pin7_Vcc(); void Init_ADC3_Pin2_Rfoto_8bit_256mV_prescaler16(); void read_ADC3_Pin2_Rfoto(); void Test_ADC3_1(); void Test_Interrupt_Routine (); void Timer0_Setup(); void Timer0_IR_On(); void Timer0_IR_Off(); ISR (TIMER0_OVF_vect) { //Interrupt vector for Timer0 TCNT0=Timer0_Startvalue; // set start value Timer/Counter Register ++Timer0_Counter; cli(); } int main(void) { Init_IO_Ports (); LED_Christmas_Star_Off (); Timer0_Setup(); Timer0_IR_Off(); Flag_Vcc_Warning = false; Flag_Dark=false; Flag_Dark_Consist = false; Flag_ChristmasStar = false; Timer0_Counter = 0; // to count Timer0 interrupts, all 250 ms one interrupt // to fix to fix "integer overflow in expression [-Woverflow] SwitchOn_Christmas_Star_TimerClocks = Timer_Clocks_PerSecond * 60*60*SwitchOn_hours; SwitchOn_Christmas_Star_TimerClocks = SwitchOn_Christmas_Star_TimerClocks + Timer_Clocks_PerSecond * 60 * SwitchOn_min ; SwitchOn_Christmas_Star_TimerClocks = SwitchOn_Christmas_Star_TimerClocks + Timer_Clocks_PerSecond * SwitchOn_sec; SwitchOn_Christmas_Star_Vcc_Warning = Timer_Clocks_PerSecond * SwitchOn_Vcc_Warning; n = 0; i = 0; z = 0; while(1) { //Test_ADC3_1(); // uncomment for ADC-Test and comment Test_Interrupt_Routine () //Test_Interrupt_Routine (); // uncomment for Interrupt test, ADC will be disabled read_ADC3_Pin2_Rfoto(); // uncomment for full code read_ADC1_Pin7_Vcc(); // uncomment for full code /* */ if (!Flag_Dark && !Flag_Dark_Consist) { // initialize if environment is bright again Flag_Dark_Consist = false; Flag_ChristmasStar = false; LED_Christmas_Star_Off (); Timer0_Counter = 0; n = 0; i = 0; z = 0; Timer0_IR_Off(); } if (Flag_Dark) { // environment is dark, test if there light glitches for Darkness_Delay //LED_Christmas_Star_On (); // to test _delay_ms(Darkness_Delay); // Darkness_Delay has to be 900000 for 15 min (Darkness_Delay) if (Flag_Dark) { // ? is still dark Flag_Dark_Consist = true; // it's really dark } } while (Flag_Dark_Consist) { // really dark Christmas star is illuminated until loop is finished if (!Flag_Vcc_Warning) { // Vcc ok if (Timer0_Counter >= SwitchOn_Christmas_Star_TimerClocks) { LED_Christmas_Star_Off(); Timer0_IR_Off(); Flag_Dark_Consist = false; } else{LED_Christmas_Star_On (); Timer0_IR_On(); //LED_Vcc_Warning_Off(); // uncomment for test } } else{ // LED_Vcc_Warning_Off(); // uncomment for test if (Timer0_Counter % SwitchOn_Christmas_Star_Vcc_Warning == 0) { Timer0_IR_Off(); LED_Christmas_Star_Off(); //LED_Vcc_Warning_Off(); // uncomment for test _delay_ms(LED_Christmas_Star_Pause); // LED_Christmas_Star_On(); Timer0_IR_On(); } if (Timer0_Counter >= SwitchOn_Christmas_Star_TimerClocks) { LED_Christmas_Star_Off(); Timer0_IR_Off(); Flag_Dark_Consist = false; } } } } return 0; } //###################################################### Functions ############################################################### void Timer0_IR_On() { sei(); } void Timer0_IR_Off() { cli(); } void Timer0_Setup() { // set prescaler 010 = 8 8us), 011 = 64 (64us); 100 = 256 (256us); 101 = 1024 (1,024 ms) --> 262,144 ms TCCR0B |= (1< 8 bit resolution ADMUX |= (1 << REFS2) | (1 << REFS1) | (0 << REFS0); // Sets ref. voltage to 2.56 V without capacitor - Vcc = 000; 2.56 V = 110; 1.1V = 010 ADMUX |= (0 << MUX3) | (0 << MUX2) | (1 << MUX1) | (1 << MUX0); // ADC3 for input (PB2) = 0010; ADC2 (PB4) = 0010; ADC1 (PB2) = 0001; ADC0 (PB5) = 0000 // frequency (delivery condition) 1MHz - preferred sample frequency 50 kHz-200 kHz --> prescaler 5-20 // prescaler 2 = 001 (500 kHz); 4 = 010 (250 kHz); 8 = 011 (125 kHz); 16 = 100 (62,5 kHz); 32 = 101 (31,25 kHz); 64 = 110 (15,625 kHz); 128 = 111 (7,8125 kHz) ADCSRA = (1 << ADPS2) | (1 << ADPS1) | (0 << ADPS0); // Prescaler = 64 --> 15.625 kHz ADCSRA |= (1 << ADEN); // Enable ADC } void read_ADC3_Pin2_Rfoto(){ Init_ADC3_Pin2_Rfoto_8bit_256mV_prescaler16 (); ADCSRA |= (1< Light_sensor_threshold){ Flag_Dark=true; // LED_Christmas_Star_On (); // uncomment for test } else { Flag_Dark=false; //LED_Christmas_Star_Off (); // uncomment for test } } // ADC1_Pin7_Vcc sensor void Init_ADC1_Pin7_Vcc_8bit_256mV_prescaler16() { ADMUX = (1 << ADLAR); // left shift result --> 8 bit resolution ADMUX |= (1 << REFS2) | (1 << REFS1) | (0 << REFS0); // Sets ref. voltage to 2.56 V without capacitor - Vcc = 000; 2.56 V = 110; 1.1V = 010 ADMUX |= (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (1 << MUX0); // ADC3 for input (PB2) = 0010; ADC2 (PB4) = 0010; ADC1 (PB2) = 0001; ADC0 (PB5) = 0000 // frequency (delivery condition) 1MHz - preferred sample frequency 50 kHz-200 kHz --> prescaler 5-20 // prescaler 2 = 001 (500 kHz); 4 = 010 (250 kHz); 8 = 011 (125 kHz); 16 = 100 (62,5 kHz); 32 = 101 (31,25 kHz); 64 = 110 (15,625 kHz); 128 = 111 (7,8125 kHz) ADCSRA = (1 << ADPS2) | (1 << ADPS1) | (0 << ADPS0); // Prescaler = 64 --> 15.625 kHz ADCSRA |= (1 << ADEN); // Enable ADC } void read_ADC1_Pin7_Vcc(){ Init_ADC1_Pin7_Vcc_8bit_256mV_prescaler16(); ADCSRA |= (1< Light_sensor_threshold){ // LED_Christmas_Star_On (); } else { LED_Christmas_Star_Off (); } Init_ADC1_Pin7_Vcc_8bit_256mV_prescaler16(); ADCSRA |= (1<