/* * geigerzaehler.c * * Created : 28.02.2019 09:07:22 * Author : John Ditgens, Alexander Brandscheidt * Git-Repository : https://gitea.Railduction.eu/JohnD/Geigerzaehler.git * * MController : AtMega328P * Board : Arduino Nano */ #define F_CPU 16000000UL // Clock speed: 16 MHz - Speed from onboard oscillator // Imports #include #include #include /* * Global variable declaration */ // Set frequencys and general stuff uint16_t boost_frequency = 10000; // 10kHz frequency uint16_t signalOutput_piezo_time = 200; // 200ms uint16_t signalOutput_led_time = 200; // 200ms // Used for execution-timing (with timer) [0 = disabled, >0 = nextTimerTick] (1 is next avaible execution) uint16_t boost_highVoltage_nextTick = 1; // Execute at start uint16_t signalOutput_piezo_nextTick = 0; uint16_t signalOutput_led_nextTick = 0; // Prescaling of timer [timer-speed: cpu-clock / prescaler] // Modes: [1, 8, 64, 256, 1024] uint16_t timer1_prescaler = 256; uint16_t timer1_overflow_value = 65535; // For calculations int main() { /* * Init */ // Inputs DDRD &= (0 << PORTD2); // Activate input PD2 DDRD &= (0 << PORTD3); // Activate input PD3 // Outputs DDRD |= (1 << PORTD4); DDRD |= (1 << PORTD5); DDRD |= (1 << PORTD6); DDRB |= (1 << PORTB5); // Onboard-Led // Interrupts // for INT0 Pin-D2 High-voltage check EICRA |= (0 << ISC01)|(1 << ISC00); // On at any edge [Code: 01] EIMSK |= (1 << INT0); // Activate Interrupt INT0 // for INT1 Pin-D3 Counter-click EICRA |= (1 << ISC11)|(1 << ISC10); // On rising edge [Code: 11] EIMSK |= (1 < 0) // If there is a nextTick { if((uint16_t)TCNT1 >= boost_highVoltage_nextTick && ((uint16_t)TCNT1-boost_highVoltage_nextTick) < (timer1_overflow_value/2)) // If we are on or after the tick it should be executed { // Flip pin state PORTD ^= (1 << PORTD4); // Calculate when next high/low should be set boost_highVoltage_nextTick = (uint16_t)TCNT1 + F_CPU/timer1_prescaler * 1/boost_frequency/2; // Half of time it should be high/low if(boost_highVoltage_nextTick == 0) boost_highVoltage_nextTick++; // If its 0, it stops, we dont want that } } /* * Signal output */ // Piezo if(signalOutput_piezo_nextTick > 0) // If there is a nextTick { if((uint16_t)TCNT1 >= signalOutput_piezo_nextTick && ((uint16_t)TCNT1-signalOutput_piezo_nextTick) < (timer1_overflow_value/2)) // If we are on or after the tick it should be executed { // Flip pin state PORTD ^= (1 << PORTD5); if(!(PIND & (1 << PORTD5))) { // We are on low (again), disable further execution signalOutput_piezo_nextTick = 0; } // When the signal should next flip signalOutput_piezo_nextTick = (uint16_t)TCNT1 + F_CPU/timer1_prescaler * signalOutput_piezo_time/1000; // Calculate nextTick based on time in ms if(signalOutput_piezo_nextTick == 0) signalOutput_piezo_nextTick++; // If its 0, it stops, we dont want that } } // LED if(signalOutput_led_nextTick > 0) // If there is a nextTick { if((uint16_t)TCNT1 >= signalOutput_led_nextTick && ((uint16_t)TCNT1-signalOutput_led_nextTick) < (timer1_overflow_value/2)) // If we are on or after the tick it should be executed { // Flip pin state PORTD ^= (1 << PORTD6); if(!(PIND & (1 << PORTD6))) { // We are on low (again), disable further execution signalOutput_led_nextTick = 0; } // When the signal should next flip signalOutput_led_nextTick = (uint16_t)TCNT1 + F_CPU/timer1_prescaler * signalOutput_led_time/1000; // Calculate nextTick based on time in ms if(signalOutput_led_nextTick == 0) signalOutput_led_nextTick++; // If its 0, it stops, we dont want that } } } sei(); // Activate global interrupts (after checks) [when an interrupt was fired, it will now be executed] } /* * Init timer1 (16-bit) in "normal mode" */ void timer1_init() { // set up timer with speed: cpu-clock / prescaler switch(timer1_prescaler){ // [CS12 CS11 CS10] default: case 1: TCCR1B |= (1 << CS10); // [0 0 1 ] break; case 8: TCCR1B |= (1 << CS11); // [0 1 0 ] break; case 64: TCCR1B |= (1 << CS10); // [0 1 1 ] TCCR1B |= (1 << CS11); break; case 256: TCCR1B |= (1 << CS12); // [1 0 0 ] break; case 1024: TCCR1B |= (1 << CS10); // [1 0 1 ] TCCR1B |= (1 << CS12); break; } // initialize counter TCNT1 = (uint16_t)0; } /* * ISR - Interrupt service routine */ // Address: 0x001 INT0 - On any edge [Code: 01] // Handles: Over/Below working voltage ISR(INT0_vect) { if(!(PIND & (1 << PORTD2))) // Falling edge { // Below ~400V, activate booster boost_highVoltage_nextTick = TCNT1; // Run as soon as possible PORTB |= (1 << PORTB5); // Onboard-Led PORTB |= (1 << PORTB5); // Onboard-Led } else // Rising edge { // Reached ~400V, deactivate booster boost_highVoltage_nextTick = 0; PORTB |= (0 << PORTB5); // Onboard-Led // reset state PORTD |= (0 << PORTD4); // pin on low } reti(); // Exit interrupt-handler } // Address: 0x002 INT1 - On rising edge [Code: 11] // Handles: Counter tube "tick" ISR(INT1_vect) { // Tick detected, signalOutput signalOutput_piezo_nextTick = TCNT1; // Run as soon as possible signalOutput_led_nextTick = TCNT1; reti(); // Exit interrupt-handler }