Hallo liebe Elektronikfreunde, ich bin ein kompletter Neuling auf dem Gebiet, der seit einem Jahr in der Schule Informatik hat. Wir haben nun als Projekt den Nibobee mit einem BTM-222 mit dem Computer zu verbinden und ihm per Tastatur Signale zu senden. Verbindung läuft auch soweit. Ich kann die serielle Schnittstelle auswählen bei Bluetooth und auch darauf zugreifen. Nun möchte ich jedoch dem Nibobee sagen, dass er bei W vorwärts fahren sollen etc. Dies klappt jedoch nicht. Ich habe versucht dem Nibo über hterm Signale zuzusenden, ist das überhaupt richtig? zB hex 57 Ich kann aber bei hterm auch nur COM6 statt COM5 auswählen. Also immer den COM(X+1). Der Nibobee besitzt ja einen ATmega16. Den habe ich folgendermaßen programmiert. Ich denke da liegt der Fehler, weil dies ist wirklich nicht meine Stärke... Hauptprogramm:
1 | #include "nibolibbtm.c" |
2 | |
3 | #include "projekt.h" |
4 | |
5 | #include <avr/io.h> |
6 | |
7 | #include "uart.h" |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | int main() |
14 | |
15 | {
|
16 | |
17 | char c=getchar(); |
18 | |
19 | uart_init(); |
20 | |
21 | motoren_init(); // motoren initialisieren |
22 | |
23 | led_init(); |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | while(1) |
32 | |
33 | {
|
34 | |
35 | c = uart_receive(); |
36 | |
37 | switch(c) |
38 | |
39 | {
|
40 | |
41 | case 'w': |
42 | |
43 | led_set(0,1); |
44 | |
45 | motor_setPower(70,70); |
46 | |
47 | _delay_ms(1000); |
48 | |
49 | motor_setPower(0,0); |
50 | |
51 | break; |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | case 's': |
58 | |
59 | led_set(1,1); |
60 | |
61 | motor_setPower(-70,-70); |
62 | |
63 | _delay_ms(1000); |
64 | |
65 | motor_setPower(0,0); |
66 | |
67 | |
68 | |
69 | break; |
70 | |
71 | case 'a': |
72 | |
73 | led_set(2,1); |
74 | |
75 | motor_setPower(30,70); |
76 | |
77 | _delay_ms(1000); |
78 | |
79 | motor_setPower(0,0); |
80 | |
81 | |
82 | |
83 | break; |
84 | |
85 | case 'd': |
86 | |
87 | led_set(3,1); |
88 | |
89 | motor_setPower(70,30); |
90 | |
91 | _delay_ms(1000); |
92 | |
93 | motor_setPower(0,0); |
94 | |
95 | |
96 | |
97 | break; |
98 | |
99 | case 'q': |
100 | |
101 | led_set(0,0); |
102 | |
103 | led_set(1,0); |
104 | |
105 | led_set(2,0); |
106 | |
107 | led_set(3,0); |
108 | |
109 | |
110 | |
111 | motor_setPower(0,0); |
112 | |
113 | |
114 | |
115 | break; |
116 | |
117 | |
118 | |
119 | default:
|
120 | |
121 | motor_setPower(0,0); |
122 | |
123 | }
|
124 | |
125 | }
|
126 | |
127 | |
128 | |
129 | }
|
projekt.h:
1 | #include <avr/io.h> |
2 | |
3 | #include <stdlib.h> |
4 | |
5 | |
6 | #define BAUD 19200UL // Baudrate
|
7 | |
8 | |
9 | |
10 | #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
|
11 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
|
12 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // 1000 = kein Fehler.
|
13 | |
14 | // Odometrie Zähler
|
15 | volatile int16_t odometer_links; |
16 | volatile int16_t odometer_rechts; |
17 | |
18 | volatile int8_t richtung_links; |
19 | volatile int8_t richtung_rechts; |
20 | |
21 | // Analoge Referenz Werte (VCC oder 2.56V)
|
22 | #define REF_VCC (1<<REFS0) // Batteriespannung als Referenzspannung
|
23 | #define REF_256 ((1<<REFS0) | (1<<REFS1)) // interne 2,56 V als Referenzspannung
|
24 | |
25 | #define LINE_L ((1<<MUX0) | (1<<MUX2)) // ADC5
|
26 | #define LINE_C ((1<<MUX1) | (1<<MUX2)) // ADC6
|
27 | #define LINE_R ((1<<MUX0) | (1<<MUX1) | (1<<MUX2)) // ADC7
|
28 | |
29 | // Funktionsdeklarationen
|
30 | |
31 | //Initialisierung der LEDs.
|
32 | |
33 | void led_init(void); |
34 | |
35 | void led_set(uint8_t led, uint8_t status); |
36 | |
37 | //Initialisieren
|
38 | |
39 | void motoren_init(void); |
40 | void motor_setPower(int8_t power_links, int8_t power_rechts); |
41 | void power_rechts(int8_t value); |
42 | void power_links(int8_t value); |
43 | |
44 | |
45 | |
46 | void PrintInt(uint16_t wert); |
47 | |
48 | void SerPrint(char *data); |
49 | |
50 | void UartPutc(uint8_t zeichen); |
51 | |
52 | void SerRead(uint8_t *data, uint8_t length, uint16_t timeout); |
53 | |
54 | // Linienverfolgung
|
55 | |
56 | void line_init(); |
57 | |
58 | /*Liefert den Wert an den Linien(L/C/R) */
|
59 | uint16_t line_get(uint8_t idx); |
60 | |
61 | /*Führt AD-Wandlung durch und liefert einen Wert*/
|
62 | uint16_t ReadADC(uint16_t mux); |
63 | |
64 | void uart_putc(unsigned char c); |
65 | |
66 | void uart_puts(char* string); |
67 | |
68 | void uart_puti(int32_t integer); |
69 | |
70 | unsigned char uart_receive(void); |
71 | |
72 | void uart_gets(char* buffer, uint8_t maxlen); |
73 | |
74 | void uart_init(void); |
uart:
1 | void uart_putc(unsigned char c) // einzelnen wert abfragen 1 byte |
2 | |
3 | {
|
4 | |
5 | while(!(UCSRA & (1<<UDRE))) |
6 | |
7 | {
|
8 | |
9 | }
|
10 | |
11 | |
12 | |
13 | UDR = c; |
14 | |
15 | }
|
16 | |
17 | |
18 | |
19 | void uart_puts(char* string) // zeichenkette zb. gradeaus links |
20 | |
21 | {
|
22 | |
23 | while(*string) |
24 | |
25 | {
|
26 | |
27 | uart_putc(*string); |
28 | |
29 | string++; |
30 | |
31 | }
|
32 | |
33 | }
|
34 | |
35 | |
36 | |
37 | unsigned char uart_receive( void ) // warten bis byte gesendet wurde |
38 | |
39 | {
|
40 | |
41 | |
42 | |
43 | while ( !(UCSRA & (1<<RXC)) ); |
44 | |
45 | return UDR; // zeichen zurück geben |
46 | |
47 | }
|
48 | |
49 | |
50 | |
51 | void uart_init(void) |
52 | |
53 | {
|
54 | |
55 | UCSRB = (1<<TXEN) | (1<<RXEN); |
56 | |
57 | UCSRC = (1<<URSEL) | (3<<UCSZ0); |
58 | |
59 | UBRRH = (unsigned char)UBRR_VAL >> 8; |
60 | |
61 | UBRRL = (unsigned char)UBRR_VAL & 0x0FF; |
62 | |
63 | }
|
64 | |
65 | void uart_puti(int32_t integer) |
66 | |
67 | {
|
68 | |
69 | char temp[9]; |
70 | |
71 | itoa(integer, temp, 10); |
72 | |
73 | uart_puts(temp); |
74 | |
75 | |
76 | |
77 | }
|
78 | |
79 | |
80 | |
81 | void uart_gets(char* buffer, uint8_t maxlen) |
82 | |
83 | {
|
84 | |
85 | uint8_t next; |
86 | |
87 | uint8_t strlen = 0; |
88 | |
89 | |
90 | |
91 | next = uart_receive(); |
92 | |
93 | while(next != '\n' && strlen < maxlen - 1) |
94 | |
95 | {
|
96 | |
97 | *buffer++ = next; |
98 | |
99 | strlen++; |
100 | |
101 | next = uart_receive(); |
102 | |
103 | }
|
104 | |
105 | *buffer = '\0'; |
106 | |
107 | |
108 | |
109 | }
|
nibolibbtm.c:
1 | #include <avr/io.h> |
2 | |
3 | #include <stdlib.h> |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | #include <util/delay.h> |
17 | #include <avr/interrupt.h> |
18 | |
19 | |
20 | volatile int16_t odometer_links; |
21 | volatile int16_t odometer_rechts; |
22 | volatile int8_t richtung_links=1; |
23 | volatile int8_t richtung_rechts=1; |
24 | |
25 | |
26 | |
27 | #define F_CPU 15000000
|
28 | /*Das Schlüsselwort volatile teilt dem Compiler mit, dass die Variablen
|
29 | durch Ereignisse außerhalb der Kontrolle des Programms verändert werden kann.
|
30 | Der Wert der Variablen muss deshalb vor jedem Zugriff neu aus dem
|
31 | Hauptspeicher eingelesen werden, d.h. er darf nicht in einem Register des
|
32 | Prozessors zwischengespeichert werden. */
|
33 | |
34 | void led_init() |
35 | |
36 | {
|
37 | // Datenrichtungsregister für LED 0 bis LED 4 setzen und PB4 für LINE_EN
|
38 | DDRB |= (1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3) | (1 << PB4); |
39 | }
|
40 | |
41 | |
42 | void led_set(uint8_t led, uint8_t status) |
43 | {
|
44 | if(led == 0) |
45 | {
|
46 | if(status == 0) |
47 | {
|
48 | PORTB &= ~(1<<PB0); |
49 | }
|
50 | else
|
51 | {
|
52 | PORTB |= (1<<PB0); |
53 | }
|
54 | }
|
55 | if(led == 1) |
56 | {
|
57 | if(status == 0) |
58 | {
|
59 | PORTB &= ~(1<<PB1); |
60 | }
|
61 | else
|
62 | {
|
63 | PORTB |= (1<<PB1); |
64 | }
|
65 | }
|
66 | if(led == 2) |
67 | {
|
68 | if(status == 0) |
69 | {
|
70 | PORTB &= ~(1<<PB2); |
71 | }
|
72 | else
|
73 | {
|
74 | PORTB |= (1<<PB2); |
75 | }
|
76 | }
|
77 | if(led == 3) |
78 | {
|
79 | if(status == 0) |
80 | {
|
81 | PORTB &= ~(1<<PB3); |
82 | }
|
83 | else
|
84 | {
|
85 | PORTB |= (1<<PB3); |
86 | }
|
87 | }
|
88 | }
|
89 | |
90 | |
91 | void motoren_init() |
92 | {
|
93 | // Datenrichtungsregister für Motoren:
|
94 | DDRD |= (1<<PD4) | (1<<PD5) | (1<<PD6) | (1<<PD7); |
95 | // PWM Register setzen:
|
96 | TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<WGM10); |
97 | TCCR1B |= (1<<CS10); // Prescale = 1 und Start Timer/Counter1AB |
98 | OCR1AL=255; //Motoren aus |
99 | OCR1BL=255; |
100 | }
|
101 | |
102 | void motor_setPower(int8_t power_links, int8_t power_rechts) |
103 | {
|
104 | |
105 | if(power_links < 0) { |
106 | PORTD &= ~(1<<PD6); //Motorendrehrichtungen auf rückwärts |
107 | OCR1AL=255+255*power_links/100; |
108 | richtung_links=-1; |
109 | }
|
110 | else { |
111 | PORTD |= (1<<PD6); //Motorendrehrichtungen auf vorwärts |
112 | OCR1AL=255-255*power_links/100; |
113 | richtung_links=1; |
114 | |
115 | }
|
116 | if(power_rechts < 0) { |
117 | PORTD |= (1<<PD7); //Motorendrehrichtungen auf rückwärts |
118 | OCR1BL=255+255*power_rechts/100; |
119 | richtung_rechts=-1; |
120 | |
121 | }
|
122 | else { |
123 | PORTD &= ~(1<<PD7); //Motorendrehrichtungen auf vorwärts |
124 | OCR1BL=255-255*power_rechts/100; |
125 | richtung_rechts=1; |
126 | |
127 | }
|
128 | |
129 | |
130 | }
|
131 | |
132 | void sens_init(void){ |
133 | DDRC &= ~0xF0; // PC4-PC7 als Eingang |
134 | PORTC |= 0xF0; // Pullup aktivieren |
135 | }
|
136 | |
137 | int sens_getRechts(void){ |
138 | if(!(PINC & 0b10000000)) return 1; |
139 | if(!(PINC & 0b01000000)) return -1; |
140 | return 0; |
141 | }
|
142 | int sens_getLinks(void){ |
143 | if(!(PINC & 0b00100000)) return 1; |
144 | if(!(PINC & 0b00010000)) return -1; |
145 | return 0; |
146 | }
|
147 | |
148 | void odometry_init() |
149 | {
|
150 | // Die Odometrie Sensoren erzeugen ca. 172 Unterbrechungen pro Meter,
|
151 | MCUCR |= (1<<ISC11) | (1<<ISC01); // INT0 und INT1 auf fallende Flanke konfigurieren |
152 | GICR |= (1<<INT1) | (1<<INT0); // INT0 und INT1 aktivieren |
153 | odometer_links = 0; |
154 | odometer_rechts = 0; |
155 | sei(); |
156 | }
|
157 | |
158 | void odometer_set(int16_t links,int16_t rechts) |
159 | {
|
160 | odometer_links = links; |
161 | odometer_rechts = rechts; |
162 | }
|
163 | |
164 | // Unterbrechung vom linken Odometrie Sensor
|
165 | ISR(INT0_vect) |
166 | {
|
167 | if(richtung_links ==1) |
168 | {
|
169 | odometer_links++; |
170 | }
|
171 | else
|
172 | {
|
173 | odometer_links--; |
174 | }
|
175 | }
|
176 | // Unterbrechung vom rechten Odometrie Sensor
|
177 | ISR(INT1_vect) |
178 | {
|
179 | if(richtung_rechts ==1) |
180 | {
|
181 | odometer_rechts++; |
182 | }
|
183 | else
|
184 | {
|
185 | odometer_rechts--; |
186 | }
|
187 | }
|
188 | |
189 | void USART_Init( unsigned int ubrr) |
190 | {
|
191 | /*Set baud rate */
|
192 | UBRRH = (unsigned char)(ubrr>>8); |
193 | UBRRL = (unsigned char)ubrr; |
194 | /*Enable receiver and transmitter */
|
195 | UCSRB = (1<<RXEN)|(1<<TXEN); |
196 | /* Set frame format: 8data, 1stop bit */
|
197 | UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0); |
198 | }
|
199 | |
200 | void USART_Transmit( unsigned char data ) |
201 | {
|
202 | /* Wait for empty transmit buffer */
|
203 | while ( !( UCSRA & (1<<UDRE)) ); |
204 | /* Put data into buffer, sends the data */
|
205 | UDR = data; |
206 | }
|
207 | |
208 | |
209 | void SerPrint (char *data) |
210 | {
|
211 | unsigned char i = 0; |
212 | |
213 | while (data [i] != 0x00) |
214 | USART_Transmit(data [i++]); |
215 | }
|
216 | |
217 | void PrintInt (uint16_t wert) |
218 | {
|
219 | char text [7]; |
220 | itoa (wert, text, 10); |
221 | SerPrint (text); |
222 | }
|
223 | |
224 | void PrintFloat(float wert, char vorkomma, char nachkomma) |
225 | {
|
226 | // vorkomma + nachkomma max 7
|
227 | char text [10]; |
228 | dtostrf(wert, vorkomma, nachkomma, text); |
229 | SerPrint(text); |
230 | }
|
Ich hoffe ihr könnt mir weiter helfen... :/