1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <util/delay.h>
|
4 | #include <string.h>
|
5 | #include <stdlib.h>
|
6 |
|
7 |
|
8 | #define BAUD 9600
|
9 |
|
10 |
|
11 | #define MYUBRR ((uint16_t) ((F_CPU / ((BAUD) * 16.0)) + .5) - 1)
|
12 | #define LED1 PD6
|
13 | #define LED2 PD7
|
14 |
|
15 |
|
16 |
|
17 | // contains what the bluetooth module received
|
18 | uint8_t data;
|
19 |
|
20 |
|
21 | void USART_Init(unsigned int ubrr) {
|
22 | // set baud rate
|
23 | UBRRH = (unsigned char)(ubrr>>8);
|
24 | UBRRL = (unsigned char)(ubrr);
|
25 | // enable receiver, transmitter and interrupts for rx/tx
|
26 | //UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<RXCIE) | (1<< TXCIE);
|
27 | UCSRB = (1<<TXEN);
|
28 |
|
29 | // frame format: 8 bits data, 1 stop bit, no parity - these are the default settings for atmega168.
|
30 | // no change needed
|
31 | // could be changed here: //(0<<UPM00) not tested
|
32 | // UCSR0C = (1<<UCSZ00) | (1<<UCSZ01) | (0<<UPM00) | (0<<UPM01);
|
33 | }
|
34 |
|
35 |
|
36 |
|
37 | void USART_transmit(char c) {
|
38 | // the commented out test if we are ready to send should work too
|
39 | //while ((UCSR0A & (1 << UDRE0)) == 0) {};
|
40 | while ( !(UCSRA & (1<<UDRE)) ) {}
|
41 | UDR = c;
|
42 | }
|
43 |
|
44 |
|
45 |
|
46 |
|
47 | void send_string(char s[]) {
|
48 | int i =0;
|
49 |
|
50 | while (s[i] != 0x00) {
|
51 | USART_transmit(s[i]);
|
52 | i++;
|
53 | }
|
54 | USART_transmit('\r');
|
55 | USART_transmit('\n');
|
56 |
|
57 | }
|
58 |
|
59 |
|
60 |
|
61 |
|
62 | void InitADC(void) {
|
63 | // Select Vref=AVcc
|
64 | ADMUX |= ( 1 << REFS0);
|
65 |
|
66 | // old, clumsy code...to much at once
|
67 | //ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN);
|
68 |
|
69 | // ADEN = Enable ADC
|
70 | ADCSRA=(1<<ADEN);
|
71 |
|
72 | // prescalar FCPU/128 = 16000000 / 128 = 125khz
|
73 | ADCSRA=(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
|
74 | }
|
75 |
|
76 |
|
77 | uint16_t readADC(uint8_t ADCchannel) {
|
78 |
|
79 | // This is the code that selects the channel. AND out the entire mux area,
|
80 | // then OR in the desired analog channel.
|
81 | ADMUX &= ~((1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0));
|
82 | ADMUX |= ADCchannel;
|
83 |
|
84 | //ADMUX |= 0xb00000000;
|
85 |
|
86 | // single conversion mode
|
87 | ADCSRA |= (1<<ADSC);
|
88 |
|
89 | // ...if you block on ADSC rather than ADIF (wait while it's high rather than low) then it self clears (goes back to 0) so you don't need to manually clear it.
|
90 | // Wait for conversion to complete
|
91 | while(ADCSRA & (1<<ADSC));
|
92 |
|
93 | // second conversion, the first maybe off
|
94 | ADCSRA |= (1<<ADSC);
|
95 |
|
96 | while(ADCSRA & (1<<ADSC));
|
97 |
|
98 |
|
99 |
|
100 | return(ADC);
|
101 | }
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 | int main(void) {
|
110 | unsigned int adc_value;
|
111 | InitADC();
|
112 |
|
113 |
|
114 | DDRD |= (1 << LED1);
|
115 | DDRD |= (1 << LED2);
|
116 | // led test
|
117 | PORTD |= (1 << LED1); // Turn on LED1
|
118 | _delay_ms(1000);
|
119 | PORTD &= ~(1 << LED1); // Turn off LED1
|
120 |
|
121 |
|
122 | // this gives a buffer overflow, the range 0...1023 does not fit into 3
|
123 | //char output[3];
|
124 |
|
125 | char output[7];
|
126 |
|
127 | USART_Init(MYUBRR);
|
128 |
|
129 | sei();
|
130 |
|
131 | while(1){
|
132 | adc_value = readADC(0);
|
133 |
|
134 | if (adc_value > 10) {
|
135 | PORTD |= (1 << LED2); // Turn on LED1
|
136 | _delay_ms(1000);
|
137 | PORTD &= ~(1 << LED2); // Turn off LED1
|
138 | }
|
139 |
|
140 |
|
141 |
|
142 | // !!!
|
143 | // use stdoul as replacement for itoa
|
144 | // convert integer to string
|
145 | itoa(adc_value, output, 10);
|
146 |
|
147 | // send value via bluetooth
|
148 | send_string(output);
|
149 |
|
150 | // (I KNOW; _delay_ms is bad) wait for the next conversion, 3 seconds
|
151 | _delay_ms(3000);
|
152 |
|
153 | // show some activity to know that the chip didnt hang
|
154 | PORTD |= (1 << LED1); // Turn on LED1
|
155 | _delay_ms(1000);
|
156 | PORTD &= ~(1 << LED1); // Turn off LED1
|
157 |
|
158 | }
|
159 | }
|