Forum: Mikrocontroller und Digitale Elektronik Hilfe bei HC-06 Bluetooth


von xKilz (Gast)


Lesenswert?

Hi
ich möchte Daten von meinem PC auf mein µC - Board mit dem ATtiny2313 
schicken. Dazu habe ich mich für das Bluetooth Module HC-06 entschieden, 
welches, laut Datenblatt, mit einer Baudrate von 9600 läuft.
Deshalb hier meine UART Konfiguration beim µC (8MHz):
1
UBRRH = 0;             
2
UBRRL = 51;
3
UCSRA |= (1 << UDRE);   
4
UCSRB |= (1 << RXCIE);  
5
UCSRB |= (1 << RXEN);
6
UCSRB |= (1 << TXEN);   
7
UCSRC |= (1 << UCSZ1);  
8
UCSRC |= (1 << UCSZ0);

Dann hab ich das Modul so mit meinem Board verbunden: TX - Pin des HC-06 
mit Pin 2 vom ATtiny2313 und RX - Pin des HC-06 mit dem Pin 3 vom 
ATtiny2313. Zusätzlich noch 3.3V und GND.

Hier meine Interrupt-Routine für das Empfangen von Daten.
1
unsigned char rec_char = 0;
2
unsigned char rec_char_buffer1 = 0;
3
unsigned char rec_char_buffer2 = 0;
4
unsigned char i = 0;
5
6
SIGNAL (USART_RX_vect)
7
{
8
  if (i == 0)
9
  {
10
    rec_char_buffer1 = UDR; // erste 8 Bit
11
    i++;
12
  }
13
  if (i == 1)
14
  {
15
    rec_char_buffer2 = UDR; // zweite 8 Bit
16
    i = 0;
17
    rec_char = (rec_char_buffer2) && (4 << rec_char_buffer1); //Bit Operation => zusammenfügen
18
  }
19
  
20
  if (rec_char = 0x61)
21
  {
22
    Field[0]=0;
23
    Field[1]=255; //grün
24
    update_PWM();
25
    _delay_ms(1000);
26
  }
27
  else
28
  {
29
    Field[1]=0;
30
    Field[0]=255; //rot
31
    update_PWM();
32
    _delay_ms(1000);
33
  }
34
}
Meine denkweise: wenn ich mich über Putty mit der COM-Schnittstelle 
verbinde, sende ich ja ASCII-Zeichen, also in meinem Fall "a" => a=0x61
Also, falls ein "a" gesendet wird, soll meine RGB-Lichterkette auf Grün 
Schalten, ansonsten auf Rot.
1
Field[0]=0;
2
Field[1]=255; //grün
3
update_PWM();
4
_delay_ms(1000);
Wenn ich das in der while(1) setzte, wird die Lichterkette grün, 
ansonsten rot, d.h. die Umschaltung zwischen den Farben sollte klappen.

Eine Verbindung bekomme ich hin, also kann das Bluetooth-Gerät pairen in 
Windows und es werden die Treiber installiert. Ich verbinde mich dann 
mit der Baudrate von 9600 auf das Gerät mit Putty und sende dann ein a - 
Lichterkette wird zwar grün, aber es wechselt nicht und egal was ich 
sende, sie wird immer grün.
Habe ich irgendwo einen Denkfehler?
Ich würde das ganze mit einem Oszi überprüfen, habe aber momentan keine 
Möglichkeit, eines aufzutreiben.

Schöne Grüße

von Bernhard M. (boregard)


Lesenswert?

xKilz schrieb:
> if (rec_char = 0x61)

Das ist eine Zuweisung, da fehlt ein '=', also so:
1
if (rec_char == 0x61)

Gruß,
Bernhard

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bernhard M. schrieb:
> if (rec_char == 0x61)

Anstelle nichtssagender hexadezimaler Konstanten könnte man hier 
natürlich auch einfach 'a' schreiben:

 if (rec_char == 'a')

von Bernhard M. (boregard)


Lesenswert?

Hi nochmal,

der Code ist ja auch noch falsch, es müssen keine Nibble zusammengesetzt 
werden, besser:
1
SIGNAL (USART_RX_vect)
2
{
3
  rec_char = UDR;
4
  
5
  if (rec_char == 'a')
6
  {
7
    Field[0]=0;
8
    Field[1]=255; //grün
9
    update_PWM();
10
    _delay_ms(1000);
11
  }
12
  else
13
  {
14
    Field[1]=0;
15
    Field[0]=255; //rot
16
    update_PWM();
17
    _delay_ms(1000);
18
  }
19
}

Gruß,
Bernhard

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Bernhard M. schrieb:
> SIGNAL (USART_RX_vect)

Das ist ein Interrupthandler.

> _delay_ms(1000);

Das sollte besser nicht in einem Interrupthandler drinstehen.

von Bernhard M. (boregard)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Bernhard M. schrieb:
>> SIGNAL (USART_RX_vect)
>
> Das ist ein Interrupthandler.
>
>> _delay_ms(1000);
>
> Das sollte besser nicht in einem Interrupthandler drinstehen.

Das hätte ich mir nie ausgedacht, aber Du hast Recht, ich hätte es auch 
nicht vom Original kopieren sollen......

von xKilz (Gast)


Lesenswert?

Hi,
ok alles klar, habs nun probiert:
[c]
int d = 0;

SIGNAL (USART_RX_vect)
{
  rec_char = UDR;

  if (rec_char == 'a')
  {
    d = 1;
  }
}

int main(void)
{
  cli();
  UBRRH = 0;
  UBRRL = 51;
  UCSRA |= (1 << UDRE);
  UCSRB |= (1 << RXCIE);
  UCSRB |= (1 << RXEN);
  UCSRB |= (1 << TXEN);
  UCSRC |= (1 << UCSZ1);
  UCSRC |= (1 << UCSZ0);

  init_PWM();                  // Pulsweitenmodulation initialisieren
  sei();                    // Interrupts aktivieren
while(1)
{


  if (d == 1)
  {
    Field[2]=255; //blue
    update_PWM();
  }
  else
  {
    Field[0]=255; //red
    update_PWM();

  }
}
Habe mich mit dem Bluetooth-Modul verbunden, Windows zeigt mir an, dass 
es COM15 ist, gebe COM15 bei Putty ein und tippe ein a - doch nichts 
passiert - LED bleibt rot.
Hab ich noch einen Fehler?
mfg

von Bernhard S. (b_spitzer)


Lesenswert?

Wieso so viele hektische Umstellungen auf einmal??
Dein Flag d (wieso zum Henker 16 Bit für 0 oder 1 verschwenden??) wir 
höchstens einmal gesetzt, danach nie wieder zurückgesetzt.

Im ersten Programm setzt Du die PWM-Sollwerte der anderen Kanäle immer 
auf 0, das fehlt hier auch. Wenn das eine RGB-LED ist, dann siehst Du 
die zusätzlich eingeschaltete blaue LED kaum, wenn die rote voll 
leuchtet.

Hast Du irgend einen der Programmteile mal separat getestet? Also 
erstmal den UART-Empfang per Polling, empfangenes Zeichen auf 8 LEDs 
oder Display ausgeben. Dann umstellen auf Interrupt, danach die 
PWM-Erzeugung testen, dann.....

von xKilz (Gast)


Lesenswert?

Hi
nochmals ich
Ich habe es nun einmal mit senden probiert:
1
while(1)
2
{
3
UDR = 'a';
4
}

Bei Putty empfage ich nun aber nun irgendwelche Sonderzeichen, aber kein 
"a"
Könnte ein Problem bei der Übertragung vorliegen? Baudrate falsch?
Man, echt blöd ohne Oszi...
mfg

von xKilz (Gast)


Lesenswert?

Danke für deine Antwort!
Ich hab nun auf Polling umgestellt:
1
unsigned char USART_Receive( void )
2
{
3
  /* Wait for data to be received */
4
  while ( !(UCSRA & (1<<RXC)) )
5
  ;
6
  /* Get and return received data from buffer */
7
  return UDR;
8
}
9
10
int main(void)
11
{
12
  cli();
13
  UBRRH = 0;             
14
  UBRRL = 51;
15
  UCSRA |= (1 << UDRE);   
16
  UCSRB |= (1 << RXCIE);  
17
  UCSRB |= (1 << RXEN);
18
  UCSRB |= (1 << TXEN);   
19
  UCSRC |= (1 << UCSZ1);  
20
  UCSRC |= (1 << UCSZ0);
21
  DDRD |= (1 << PD6);
22
  init_PWM();                  // Pulsweitenmodulation initialisieren
23
  //sei();                    // Interrupts aktivieren
24
while(1)
25
{
26
  
27
  
28
  if (USART_Receive() == 'a')
29
  {
30
    Field[2]=255; //blau
31
    Field[0]=0;
32
    Field[1]=0;
33
    update_PWM();
34
    _delay_ms(1000);
35
  }
36
  else
37
  {
38
    Field[0]=255; //rot
39
    Field[1]=0;
40
    Field[2]=0;
41
    update_PWM();
42
43
    
44
  }
45
}
Wenn ich nichts sende, bleiben die LEDs schwarz, wenn ich was sende wie 
gewünscht rot, doch leider auch wenn ich 'a' sende, bleiben die LEDs 
rot.

LEDs setzten funktioniert, das habe ich bereits getestet, also rot, blau 
grün kann ich einsetzen und beliebig wechseln.

UART habe ich so noch nicht getestet
mfg

von Bernhard S. (b_spitzer)


Lesenswert?

Ich kenne den UART im Tiny nicht, aber musst Du nicht vor dem Versenden 
prüfen, ob der UART frei ist? Irgend ein Flag beachten?
Ein Zeichen bei 9600Baud benötigt immerhin knapp 1ms! (zur Not, nach der 
Zuweisung ein delay von einigen ms rein) Wenn das nix hilft, dann ist 
die Baudrate falsch.

von xKilz (Gast)


Lesenswert?

Hallo
Ich habe nun mal geschaut, ob die CPU-Frequenz richtig ist. Habe die 
Fuse auf 8MHz internen Clock geschalten (14CK_0MS) doch bei einem 
_delay_ms(1000); wird der Code nicht 1s angehalten, sondern 10.
#define F_CPU 8000000UL sollte auch passen.
Was könnte hier das Problem sein?
mfg

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.