Btm-222 mit Nibobee verbinden

Gast #2713454
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... :/
Gast #2713477
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren