1 | /*
|
2 | * Sauhandy.c
|
3 | *
|
4 | * Created: 22.08.2013 20:02:46
|
5 | * Author: Gerald
|
6 | */
|
7 | #include <avr/io.h>
|
8 | #define F_CPU 128000UL //CKSEL Fuses to 0100 --> slow ISP down
|
9 |
|
10 | #include <util/delay.h>
|
11 | #include <avr/sleep.h>
|
12 | #include <avr/interrupt.h>
|
13 | #include <avr/wdt.h>
|
14 |
|
15 | #define ADCPort PB5 // _____________
|
16 | #define ADCReg DDB5 // (PCINT5/RESET/ADC0/dW) PB5 - - VCC
|
17 | #define Bleeder PB3 // | |
|
18 | #define BleederReg DDB3 // (PCINT3/XTAL1/CLKI/OC1B/ADC3) PB3 - - PB2 (SCK/USCK/SCL/ADC1/T0/INT0/PCINT2)
|
19 | #define PowerSwitch PB0 // | |
|
20 | #define PowerSwitchReg DDB0 // (PCINT4/XTAL2/CLKO/OC1B/ADC2) PB4 - - PB1 (MISO/DO/AIN1/OC0B/OC1A/PCINT1)
|
21 | #define CallSwitch PB1 // | |
|
22 | #define CallSwitchReg DDB1 // GND - - PB0 (MOSI/DI/SDA/AIN0/OC0A/OC1A/AREF/PCINT0)
|
23 | #define HangupSwitch PB2 // _____________
|
24 | #define HangupSwitchReg DDB2
|
25 | #define Sensor PB4
|
26 | #define SensorReg DDB4
|
27 | #define SensorPin PINB4
|
28 | #define Port PORTB
|
29 | #define PortReg DDRB
|
30 | #define PIN PINB
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | void initADC(void){
|
39 | uint16_t erase;
|
40 | ADMUX = (1<<REFS1) ; //interne 1,1Volt
|
41 | //ADCSRA = //(1<<ADPS1) | (1<<ADPS2);//prescaler zw. 50 und 200 kHz, hier also 2
|
42 | ADCSRA |= (1<<ADEN); //ADC ENable
|
43 | ADCSRA |= (1<<ADSC); //ADc Single Conversion
|
44 | while (ADCSRA & (1<<ADSC) ) //warte bis fertig
|
45 | {
|
46 | }
|
47 | erase = ADCW; //auslesen (löscht auch)
|
48 | }
|
49 |
|
50 | void enablewatchdog(void){
|
51 | MCUSR = 0x00; // clear watchdog
|
52 | WDTCR |= (1<<WDCE) | (1<<WDE) ; // Enable watchdog
|
53 | WDTCR |= (1<<WDIE) | (1<<WDP1); // Watchdog interrupt instead of reset with 60ms timeout;
|
54 | WDTCR &= ~(1<<WDE); // halte WDIE geespeichert
|
55 |
|
56 | }
|
57 |
|
58 | void disablewatchdog(void){
|
59 | MCUSR = 0x00; // clear watchdog
|
60 | WDTCR |= (1<<WDCE) | (1<<WDE); // bereitmachen zum löschen
|
61 | WDTCR = 0x00; //löschen
|
62 | }
|
63 |
|
64 | void watchdogreset(void){
|
65 | MCUSR = 0x00; // clear watchdog
|
66 | }
|
67 |
|
68 |
|
69 | void wait(uint16_t timein60ms){ //in 60ms schritten
|
70 | for (uint16_t i = 0; i<timein60ms; i++ ){
|
71 | disablewatchdog();
|
72 | watchdogreset();
|
73 | enablewatchdog();
|
74 | sei();
|
75 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
76 | sleep_mode();
|
77 | cli();
|
78 | disablewatchdog();
|
79 | }
|
80 | }
|
81 |
|
82 | void waitlong(uint16_t timein2s){ //in 2s schritten
|
83 | for (uint16_t i = 0; i<timein2s; i++ ){
|
84 | disablewatchdog();
|
85 | MCUSR = 0x00; // clear watchdog
|
86 | WDTCR = (1<<WDCE) | (1<<WDE) ; // Enable watchdog
|
87 | WDTCR |= (1<<WDIE) | (1<<WDP0) | (1<<WDP1) | (1<<WDP2); // Watchdog interrupt instead of reset with 8s timeout;
|
88 | WDTCR &= ~(1<<WDE); // halte WDIE geespeichert
|
89 | sei();
|
90 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
91 | sleep_mode();
|
92 | cli();
|
93 | disablewatchdog();
|
94 | }
|
95 | }
|
96 |
|
97 | void domagic(void){
|
98 | PortReg |= (PowerSwitchReg); //lege als Ausgang fest
|
99 | Port &= ~(1<<PowerSwitch); //Hold PowerSwitch for 2 Sec
|
100 | waitlong(1);
|
101 | PortReg &= ~(1<<PowerSwitchReg); //Als Eingang
|
102 | Port |= (1<<PowerSwitch); //Pullup
|
103 | waitlong(5); //let it boot
|
104 | Port |= (1<<CallSwitch);
|
105 | wait(1); //push Call Button for 60ms
|
106 | Port &= ~(1<<CallSwitch);
|
107 |
|
108 | wait(1);
|
109 |
|
110 | Port |= (1<<CallSwitch);
|
111 | wait(1); //push Call Button for 60ms
|
112 | Port &= ~(1<<CallSwitch);
|
113 |
|
114 | waitlong(3); //ring 6 seconds
|
115 |
|
116 | Port |= (1<<HangupSwitch);
|
117 | wait(1); //push Hangup Button for 60ms
|
118 | Port &= ~(1<<HangupSwitch);
|
119 |
|
120 | wait(20);
|
121 | PortReg |= (PowerSwitchReg); //lege als Ausgang fest
|
122 | Port &= ~(1<<PowerSwitch); //Hold PowerSwitch for 2 Sec
|
123 | waitlong(1);
|
124 | PortReg &= ~(1<<PowerSwitchReg); //Als Eingang
|
125 | Port |= (1<<PowerSwitch); //Pullup
|
126 |
|
127 | }
|
128 |
|
129 | void lowbattery(void){
|
130 | PortReg |= (PowerSwitchReg); //lege als Ausgang fest
|
131 | Port &= ~(1<<PowerSwitch); //Hold PowerSwitch for 2 Sec
|
132 | waitlong(1);
|
133 | PortReg &= ~(1<<PowerSwitchReg); //Als Eingang
|
134 | Port |= (1<<PowerSwitch); //Pullup
|
135 | waitlong(2); //let it boot
|
136 | Port |= (1<<CallSwitch);
|
137 | wait(1); //push Call Button for 60ms
|
138 | Port &= ~(1<<CallSwitch);
|
139 |
|
140 | wait(5);
|
141 |
|
142 | Port |= (1<<CallSwitch);
|
143 | wait(1); //push Call Button for 60ms
|
144 | Port &= ~(1<<CallSwitch);
|
145 |
|
146 | waitlong(2); //ring 4 seconds
|
147 |
|
148 | Port |= (1<<HangupSwitch);
|
149 | wait(1); //push Hangup Button for 60ms
|
150 | Port &= ~(1<<HangupSwitch);
|
151 |
|
152 | waitlong(1); // kurze Pause zwischen Anrufen
|
153 | Port |= (1<<CallSwitch);
|
154 | wait(1); //push Call Button for 60ms
|
155 | Port &= ~(1<<CallSwitch);
|
156 |
|
157 | wait(5);
|
158 | Port |= (1<<CallSwitch);
|
159 | wait(1); //push Call Button for 50ms
|
160 | Port &= ~(1<<CallSwitch);
|
161 |
|
162 | waitlong(2); //ring 4 seconds
|
163 |
|
164 | Port |= (1<<HangupSwitch);
|
165 | wait(1); //push Hangup Button for 60ms
|
166 | Port &= ~(1<<HangupSwitch);
|
167 |
|
168 | wait(20);
|
169 | PortReg |= (PowerSwitchReg); //lege als Ausgang fest
|
170 | Port &= ~(1<<PowerSwitch); //Hold PowerSwitch for 2 Sec
|
171 | waitlong(1);
|
172 | PortReg &= ~(1<<PowerSwitchReg); //Als Eingang
|
173 | Port |= (1<<PowerSwitch); //Pullup
|
174 | }
|
175 |
|
176 |
|
177 | uint16_t ReadADC(void){
|
178 | initADC();
|
179 | //ADMUX |= (1<<MUX0) | (1<<MUX2); //Nehme PIN adc0
|
180 | ADCSRA |= (1<<ADSC); //ADc Single Conversion
|
181 | while (ADCSRA & (1<<ADSC) ) {
|
182 | }
|
183 | ADCSRA &= ~(1<<ADEN); //disable adc
|
184 | return ADCW;
|
185 | }
|
186 |
|
187 |
|
188 |
|
189 | int main(void)
|
190 | {
|
191 | PortReg |= (1<<CallSwitchReg) | (1<<HangupSwitchReg) | (1<<BleederReg) | (1<<ADCReg) | (1<<SensorReg) ; //output
|
192 | Port |= (1<<ADC) | (1<<Bleeder) | (1<<PowerSwitch); // auf High setzen
|
193 | uint16_t Spannungswert=1023*1.1*2.9/(13.3/3.3); //1024 bit * 1,1V Gap * 2.9V BatterieSpannung / Spannungsteiler
|
194 | uint32_t messungcounter=1;
|
195 | GIMSK = (1<<PCIE); //Enable PCINT as InterruptReg
|
196 | PCMSK = (1<<PCINT0); //Maske auf PCINT0
|
197 | sei();
|
198 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
199 | sleep_mode(); //erkenne handy einschalten
|
200 | cli();
|
201 | //Port |= (1<<HangupSwitch); for debugging
|
202 | PCMSK &= ~(1<<PCINT0); //keine interrupts mehr
|
203 | waitlong(4);
|
204 | PCMSK = (1<<PCINT0); //Maske auf PCINT0
|
205 | //Port &= ~(1<<HangupSwitch); for debugging
|
206 | sei();
|
207 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
208 | sleep_mode(); //erkenne handy ausschalten
|
209 | cli();
|
210 | //Port |= (1<<HangupSwitch); for debugging
|
211 | PCMSK &= ~(1<<PCINT0); //keine interrupts mehr
|
212 | waitlong(4);
|
213 | //Port &= ~(1<<HangupSwitch); for debugging
|
214 | GIMSK &= ~(1<<PCIE);
|
215 | PCMSK &= ~(1<<PCINT0); //keine interrupts mehr
|
216 | waitlong(8); //warte 16 Sekunden bis zur scharfschaltung
|
217 | watchdogreset();
|
218 | enablewatchdog();
|
219 | sei();
|
220 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
221 | sleep_mode();
|
222 | //uint8_t test =0; for debugging
|
223 |
|
224 | while(1){
|
225 | cli();
|
226 | disablewatchdog();
|
227 | /*test++;
|
228 | if (test==50){
|
229 | Port ^= (1<<CallSwitch);
|
230 | test=0;
|
231 | } // for debugging */
|
232 |
|
233 |
|
234 | PortReg &= ~(1<<SensorReg); //Eingang
|
235 | Port |= (1<<Sensor); // Pullup
|
236 | //Port ^= (1<<HangupSwitch); for debugging
|
237 | if (PINB & (1<<SensorPin)){
|
238 | Port &= ~(1<<Sensor);
|
239 | PortReg |= (1<<SensorReg); //Wieder als Ausgang
|
240 | domagic();
|
241 | watchdogreset();
|
242 |
|
243 | waitlong(450); //warte 15mins bis wieder scharf
|
244 |
|
245 | }
|
246 | Port &= ~(1<<Sensor);
|
247 | PortReg |= (1<<SensorReg); //Wieder als Ausgang (wenn nicht shcon passert)
|
248 |
|
249 |
|
250 | if (messungcounter==6000000){ // ca. alle 4 Tage messen
|
251 | watchdogreset();
|
252 | disablewatchdog();
|
253 | messungcounter=0;
|
254 | PortReg &= ~(1<<ADCReg); //Lege ADC als Eingang fest;
|
255 | Port &= ~(1<<Bleeder) ; // aktiviere Spanungsteiler
|
256 | Port &= ~(1<<ADC); //Pullup runter
|
257 | uint16_t ADCresult=ReadADC();
|
258 | PortReg |= (1<<ADCReg); //Lege ADC als Ausgang fest;
|
259 | Port |= (1<<ADC) | (1<<Bleeder) ; // auf High setzen
|
260 | if (ADCresult <= Spannungswert){
|
261 | lowbattery();
|
262 | }
|
263 | }
|
264 | messungcounter++;
|
265 | sei();
|
266 | enablewatchdog();
|
267 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
268 | sleep_mode();
|
269 |
|
270 | }
|
271 | }
|
272 |
|
273 | ISR(PCINT0_vect){
|
274 | }
|
275 |
|
276 | ISR(WDT_vect){
|
277 | }
|