Forum: Mikrocontroller und Digitale Elektronik Btm-222 mit Nibobee verbinden


von daniel (Gast)


Lesenswert?

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... :/

von Stefan (Gast)


Lesenswert?

Ich habe keine Lust so viel Source Code zu überprüfen.

Du kannst auf meine Homepage ein funktionierendes Programm für genau 
diesen Zweck downloaden. Damit kannst Du sehr einfach verifizieren, ob 
Du ein Hardwareproblem hast.

Hammer Terminal sendet erst, wenn Du die Enter Taste drückst. Es sendet 
dann je nach Konfiguration nicht nur den Buchstaben "W", sondern auch 
ein oder zwei Bytes für den Zeilenumbruch. Das musst Du im Programm auf 
dem Roboter berücksichtigen (im einfachsten Fall alle unerwünschten 
Zeichen ignorieren).

Bedenke auch, dass das Modul eine "CONNECT" Meldung an den Roboter 
abgibt, wenn die Verbindung aufgebaut wurde. Entsprechend gibt es auch 
eine "DISCONNECT" Meldung und diverse Statusmeldungen, während keine 
Verbindung besteht. Diese Meldungen bestehen alle ausschließlich aus 
Großbuchstaben, es liegt daher nahe, die eigene Steuerung auf 
Kleinbuchstaben zu beschränken.

Der Bluetooth Stack von Microsoft (zumindest unter Windows Vista und 7) 
kommuniziert nicht sauber mit dem BTM-222. Zwar baut er eine Verbindung 
auf, sendet und empfängt dann aber meistens (manchmal geht es doch) 
keine Daten. Abhilfe schafft die Installation des Bluetooth Stacks von 
Windcomm, der in meinem Fall auf der Treiber-CD meines Laptops versteckt 
war und komischerweise nicht installiert war.

von daniel (Gast)


Lesenswert?

Vielen Dank für die Antwort. Hilft mir schonmal ein wenig weiter

Wie heißt Ihre HP denn?

von Stefan (Gast)


Lesenswert?

Google mal nach Stefan Frings

von daniel (Gast)


Lesenswert?

:D ich hatte schon per email Kontakt zu Ihnen.

Wo ist dort das Programm? Ich konnte bisher noch keines finden.

von Stefan (Gast)


Lesenswert?

http://stefanfrings.de/nibobee/index.html

prg_demo.c (benötigt die Libraries darüber).

von daniel (Gast)


Lesenswert?

Dieser Abschnitt ist mir ja völlig entgangen. Vielen Dank!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.