Bluetooth HC-05 Softserial Arduino Nano

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Bluetooth HC-05 Softserial Arduino Nano

      Hallo Forumgemeinde,

      nach ewiger Pause mit den AVR wollte ich wieder mal was probieren.
      Richtige Projekte hab ich leider nicht, sind mehr Spielereien zum lernen.

      Hardwareinfo vorab:
      Bascom Version 2.0.83

      Arduino Nano ATMega328P @ 16MHz (Programierung über USB-Bootloader) -> Funktioniert
      I2C OLed Display (erst seit kurzem) -> läuft dank euren Codeschnipseln (Suche genutzt)


      HC-05 läuft über SW-Uart (lief mit Empfang und Senden (Einzelnes Zeichen als Befehl)) LED blinkt langsam. Hab das in den AT-Modus geschickt.


      Ich wollte die AT Kommandos an das HC-05 schicken und die Antwort auf das Display schreiben.
      Leider weiß ich nicht wie ich die AntwortDaten des HC-05 einlese
      Mit AT+Name? frage ich den Namen ab, zurück müsste dann HC-05 kommen
      Das Modul hängt an einer Soft UART.

      Das aktuelle Programm:

      BASCOM Source Code

      1. $regfile = "m328pdef.dat"
      2. $crystal = 16000000
      3. $hwstack = 64
      4. $swstack = 64
      5. $framesize = 64
      6. '$baud = 9600
      7. Open "comd.3:9600,8,N,1" For Output As #1
      8. Open "comb.2:9600,8,N,1" For Input As #2
      9. Config Portb.5 = Output
      10. 'Config Portc.1 = Output
      11. LED Alias portb.5
      12. 'A5 = SCL PC.5
      13. 'A4 = SDA PC.4
      14. '--------------------------------------------------------'
      15. ' I2C Definieren '
      16. '--------------------------------------------------------'
      17. Config Clockdiv = 1 ' make sure the chip runs at 8 MHz
      18. Config Scl = Portc.5 ' used i2c pins
      19. Config Sda = Portc.4
      20. Config Twi = 400000 ' i2c speed
      21. I2cinit
      22. $lib "i2c_twi.lbx" ' we do not use software emulated I2C but the TWI
      23. $lib "glcdSSD1306-I2C.lib"
      24. '--------------------------------------------------------'
      25. ' Interrupts einschalten '
      26. '--------------------------------------------------------'
      27. Enable Interrupts
      28. '--------------------------------------------------------'
      29. ' Funktionen und Subs declarieren '
      30. '--------------------------------------------------------'
      31. '--------------------------------------------------------'
      32. ' Variablen und Array definieren '
      33. '--------------------------------------------------------'
      34. Dim Test As Word
      35. Dim Zeilen As Byte
      36. Dim X As Byte
      37. dim y as byte
      38. Dim Speed as Byte
      39. Dim Dummy as string * 1
      40. 'Dim Antwort as string * 25
      41. Dim Antwort as byte
      42. Speed = 100
      43. Test = 0
      44. 'For Zeilen = 1 To 10
      45. ' Print #1 , ""
      46. ' Next
      47. Print #1 , "Arduino Nano mit HC-05 Bluetooth und I2C-OLED-Display in Bascom!"
      48. Print #1 , "" : Print #1 , "" : Print #1 , ""
      49. Print #1 , "Warte auf Eingaben :-)"
      50. #if _build < 20784
      51. Dim ___lcdrow As Byte , ___lcdcol As Byte ' dim these for older compiler versions
      52. #endif
      53. waitms 200
      54. Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306"
      55. Cls
      56. waitms 200
      57. Setfont Font8x8tt ' select font
      58. Lcdat 1 , 1 , "I2C-OLED und HC-05"
      59. Lcdat 2,1,"in Bascom"
      60. LED =1
      61. 'Lcdat 2 , 10 , "Company"
      62. 'Lcdat 8 , 5 , "Schöneberg 2021" , 1 'invers
      63. Waitms 3000
      64. LED = 0
      65. 'Showpic 0 , 0 , Markus
      66. ' Print #1, "AT+UART?" + CHR(13) + CHR(10)
      67. Dim A As String * 2
      68. Dim B As Integer
      69. Print #1, "AT+NAME?" + CHR(13) + CHR(10) ' Name abfragen
      70. ' Bis "Wend" Schnipsel aus dem Forum, geht leider nicht
      71. Input #2 , A
      72. B = Val(A)
      73. While B > 0
      74. Input #2 , A
      75. B = Val(A)
      76. LCDat 3,1,B,0
      77. Wend
      78. 'Programm scheint zu hängen, der Text unten erscheint nicht wenn input "Scharf" ist
      79. LCDat 8,1,"Bluetooth!",1
      80. do
      81. Loop
      82. End
      83. $include "font8x8TT.font" ' this is a true type font with variable spacing
      Display All
      Könnt ihr mir erklären wie ich die Antwort vom Bluetooth Modul erhalte?

      Grüße Counter
      Files
      Grüße
      Counter

      The post was edited 1 time, last by Counter: Info ergänzt das das Modul im AT-Modus ist ().

    • Also erstens muss der HC-05 wissen, dass ein AT-Kommando kommt. Es könnte ja auch sein, dass das Modul die Zeichenfolge "AT+Name?" einfach nur übertragen soll. Okay - nicht besonders wahrscheinlich, aber damit der HC-05 überhaupt erstmal in den AT-Modus geht, muss PIn 1 ("Enable") auf High gelegt werden. Das sehe ich in Deinem Code schon mal nicht.

      Zweitens ist es nicht nötig, einen Print-Befehl mit CHR(13) und CHR(10) abzuschließen. Bascom macht das bei jedem Print-Befehl am Ende automatisch, solange die Befehlszeile nicht mit einem Semikolon abgeschlossen wird. In Zeile 104 würde also Print #1, "AT+UART?" ausreichen.

      Drittens musst Du dem Modul schon etwas Zeit zum Antworten lassen! Nach dem Befehl "Print #1, "AT+UART?" schickt das Modul in etwa folgende Antwort zurück: +UART: 9600,0,0 cr lf. Das sind 17 Bytes, die bei einer Übertragungsrate von 9600 Baud mehr als 10 Millisekunden benötigen. Das klingt nicht viel, aber wenn Du dem Modul ein paar Prozessortakte später gleich den nächsten AT-Befehl AT+NAME? reinschiebst, könnte das zu Kollisionen führen ;)

      Und für das Empfangen von Strings unterschiedlicher Länge (und nichts anderes sind die Antworten des HC-05) kannst Du entweder mit einem Empfangspuffer arbeiten (das habe ich noch nie gemacht, das können aber bestimmt andere Leute aus dem Forum erklären). Ich habe den Empfang von AT-Antworten dagegen schon mehrfach erfolgreich Interrupt-basiert gelöst: Bei jedem empfangenen Zeichen wird eine ISR aufgerufen, in der das gerade empfangene Zeichen an einen String (lang genug dimensionieren!!) drangehängt wird. Wenn das empfangene Zeichen eine 13 ist (=CR), ist der String fertig. In diesem Fall wird in der ISR ein Flag gesetzt, in der Hauptroutine kann der fertige String dann weiterverwurstet und für die nächste Runde resettet werden.
    • Hi Einzeller,

      Danke für deine schnelle und so ausführliche Antwort.
      Hab so ein HC05 mit Trägerplatine.
      So eins...HC-05 Externer Link
      Leg ich EN auf 5V passiert mit der LED nichts.
      Das Modul hab ich manuell in den AT-Modus gebracht.
      Manuell muss ich den Taster drücken und dann das Modul einschalten. Dann blinkt die Langsam.

      Das mit der gebufferten Schnittstelle such ich mir mal zusammen.
      Grüße
      Counter
    • Hallo Pac-Man,

      Danke. War verkehrte Reihenfolge von mir. Kein Wunder das das dann nicht so funktioniert.
      Wenn das andere Funktioniert mach ich das Einschalten und umschalten des Moduls vieleicht über Transistor bzw Port.

      Hab mich durchs Forum gesucht und das Programm mal angepasst bzw. mir die Routine zum Einlesen zusammengestückelt.
      Aktuell läuft das Praogramm:

      BASCOM Source Code

      1. $regfile = "m328pdef.dat"
      2. $crystal = 16000000
      3. $hwstack = 64
      4. $swstack = 64
      5. $framesize = 64
      6. '$baud = 9600
      7. Open "comd.3:9600,8,N,1" For Output As #1
      8. Open "comb.2:9600,8,N,1" For Input As #2
      9. Config Portb.5 = Output
      10. LED Alias portb.5
      11. 'A5 = SCL PC.5
      12. 'A4 = SDA PC.4
      13. '--------------------------------------------------------'
      14. ' I2C Definieren '
      15. '--------------------------------------------------------'
      16. Config Clockdiv = 1 ' make sure the chip runs at 8 MHz
      17. Config Scl = Portc.5 ' used i2c pins
      18. Config Sda = Portc.4
      19. Config Twi = 400000 ' i2c speed
      20. I2cinit
      21. $lib "i2c_twi.lbx" ' we do not use software emulated I2C but the TWI
      22. $lib "glcdSSD1306-I2C.lib"
      23. '--------------------------------------------------------'
      24. ' Interrupts einschalten '
      25. '--------------------------------------------------------'
      26. ' Enable Interrupts
      27. '--------------------------------------------------------'
      28. ' Funktionen und Subs declarieren '
      29. '--------------------------------------------------------'
      30. '--------------------------------------------------------'
      31. ' Variablen und Array definieren '
      32. '--------------------------------------------------------'
      33. Print #1 , "Arduino Nano mit HC-05 Bluetooth und I2C-OLED-Display in Bascom!"
      34. Print #1 , "Warte auf Eingaben..."
      35. #if _build < 20784
      36. Dim ___lcdrow As Byte , ___lcdcol As Byte ' dim these for older compiler versions
      37. #endif
      38. waitms 200
      39. Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306"
      40. Cls
      41. waitms 200
      42. Setfont Font8x8tt ' select font
      43. Lcdat 1 , 1 , "I2C-OLED und HC-05"
      44. Lcdat 2,1,"in Bascom"
      45. Waitms 1000
      46. ' Print #1, "AT+UART?" + CHR(13) + CHR(10)
      47. ' Print #1, "AT+NAME?" + CHR(13) + CHR(10) ' Name abfragen
      48. 'Programm scheint zu hängen, der Text unten erscheint nicht wenn input "Scharf" ist
      49. ' Anfang Schnipsel aus Forumsbeitrag
      50. 'https://bascomforum.de/index.php?thread/2175-soft-uart/&postID=35609&highlight=software%2Buart#post35609
      51. Dim A As String * 30
      52. Dim Int0_flag As Bit
      53. Dim C As String * 25
      54. Enable Int0
      55. On Int0 Serielle_lesen
      56. 'Config Int0 = Rising
      57. 'Config Int0 = Falling
      58. Enable Interrupts
      59. ' Ende Schnipsel aus Forumsbeitrag
      60. Do
      61. ' Anfang Schnipsel aus Forumsbeitrag
      62. 'https://bascomforum.de/index.php?thread/2175-soft-uart/&postID=35609&highlight=software%2Buart#post35609
      63. 'Toggle Led:Waitms 100 'Brauch ich hier nicht
      64. If Int0_flag = 1 Then Gosub Daten_einlesen
      65. ' Ende Schnipsel aus Forumsbeitrag
      66. Loop
      67. End
      68. $include "font8x8TT.font" ' this is a true type font with variable spacing
      69. ' Anfang Schnipsel aus Forumsbeitrag
      70. 'https://bascomforum.de/index.php?thread/2175-soft-uart/&postID=35609&highlight=software%2Buart#post35609
      71. Daten_einlesen:
      72. Disable Int0
      73. Print #1,"Int0_flag: ";Int0_flag
      74. Led = 1
      75. 'DO
      76. Input #2,c
      77. IF C = "CLS" then : CLS : C = "" : end if
      78. Print #1,"C: ";c;" ";Len(c)
      79. ' If C <= CHR(13) Then Exit Do
      80. 'Loop
      81. LCDat 5,5,c,0
      82. Int0_flag = 0
      83. Enable Int0
      84. LED = 0
      85. Return
      86. Serielle_lesen:
      87. Int0_flag = 1
      88. Return
      89. ' Ende Schnipsel aus Forumsbeitrag
      Display All
      von der AT-Abfrage bin ich mal weg. Erstmal schauen ob das anders überhaupt funktioniert.
      Aktuell verbinde ich mich mit HTert 0.8.5 und sende Buchstaben und Zeichen (irgendwas, egal)
      Der Aruino schickt dann in der Sub die Zeichen mit der Länge zurück.
      Allerdings kommt der scheinbar nicht mehr aus der Sub raus.
      Mit oder ohne der If Abfrage. Egal was ich einstelle am HTerm.
      Muss mal ausprobieren ob ich ein eigenes Zeichen zum Austritt einfügen kann. Eins wo ich normalerweise nicht nutze.
      Grüße
      Counter
    • Also erstmal zu den beiden "Reihenfolgen":
      Erst Spannung anlegen, dann Taster drücken: HC-05 ist so lange im AT-Modus, wie der Taster gedrückt wird. Kann unbequem werden, wenn man den Baustein länger im AT-Modus halten möchte. Dann hilft Variante 2: Erst Taster drücken, dann Spannung anlegen: Baustein bleibt bis zum Abschalten der Spannung dauerhaft im AT-Modus - auch wenn der Taster losgelassen wird.

      Wenn Du das UART-Signal nicht nur auf B.2, sondern auch auch auf den INT0-Eingang (D.2) gelegt hast, könnte es mit der INT0-ISR klappen.

      Eine Do-Loop-Schleife in einer ISR ist aber keine so gute Idee! Und außerdem kann auch immer nur ein einziges Zeichen empfangen werden!

      Source Code

      1. Input #2,c
      2. IF C = "CLS" then : CLS : C = "" : end if
      Das wird nicht gehen, denn C ist ein einziges Byte, der String "CLS" besteht aber aus drei Bytes (C=67, L=76 und S=83)

      Für dem Empfang der Zeichenfolge "CLS" (also 67, 76 und 83) muss die ISR also drei mal angesprungen werden. Wenn ein neu empfangenes Zeichen NICHT 13 ist, wird es an einen String angehängt (Strings kann man einfach "addieren"!) - und raus aus der ISR. Wenn das empfangene Zeichen 13 ist (= CR) ist die Übertragung fertig. Dann wird die 13 nicht an den String gehängt, sondern ein Flag gesetzt - und ebenfalls raus aus der ISR.

      In der Hauptschleife wird das Flag abgefragt; wenn es 1 ist kann irgendeine Aktion erfolgen, und der Ziel-String auf "" zurückgesetzt werden.

      Aber ganze Zeichetketten in EINER ISR zu empfangen, das klappt nicht!
    • Hi,

      @Pac-ManBei deiner Antwort: "Franz schrieb..." stand und saß ich komplett auf dem Schlauch...
      Dann hab ich nachgeschaut aber wusste nicht wo das rein muss. Naja, wie gesagt, mach das zu wenig...

      HW-Uart dachte ich auch schon. Aber stört das Modul nicht beim Schreiben über den Bootloader?
      Die nutzen doch dann die gleichen PINs?
      Nicht das das Modul denkt "das ist für mich" und dreht dann durch...

      @Einzeller In Zeile 81 Hab ich c als String definiert -> Dim C As String * 25
      Das CLS versteht er. Aber die LED geht nicht aus. Was bedeutet das der "dauernd" in der ISR sein müsste.

      Mit Hardware Uart wäre das einfacher?
      AT Modus stell ich erstmal zurück Ausgabe müsste dann auf Display erfolgen.
      Grüße
      Counter
    • Das modul ist da recht geduldig. Es antwortet einfach Error wenn es was nicht versteht. Der Bootlader erwartet seine Sequenz. (Die sollte natürlich nicht "ERROR" sein :D ) Bekommt er was anderes startet er das normale Programm. Der HW Uart wäre erheblich einfacher. Er gibt einen Interrupt wenn ein Byte komplett ist. Und dann hat man Zeit bis das nächste Byte da um es abzuholen. Den SW Uart über den Int zu betreiben ist eine gute Idee aber dann muß es schnell gehen: das Einlesen muß gestartet werden bevor das erste Bit (startbit) vorbei ist. Also sofort in der ISR. Vor deren Return muß das EIFR.INTF0 = 1 stehen da bei jeden Wechsel (falling) ein neuer Interupt ausgelöst wird.

      Source Code

      1. Serielle_lesen:
      2. U_Byte=inkey#2
      3. If U_Byte = 10 then
      4. Int0_flag = 1
      5. else
      6. c = c + chr(u_byte)
      7. end if
      8. EIFR.INTF0 = 1
      9. Return
      so würde c gefüllt bis ein Lf gesendet wird.
      Leider ist hier die Suchfunktion nicht so prickelnd. Zuletzt? war es bei einem Sim Modul Thema.
      Die ESP sprechen ähnlich. Da sind auch verschiedene Möglichkeiten des Uart Empfangs besprochen.

      The post was edited 1 time, last by Pluto25 ().

    • Counter wrote:

      @Pac-ManBei deiner Antwort: "Franz schrieb..." stand und saß ich komplett auf dem Schlauch...
      Dann hab ich nachgeschaut aber wusste nicht wo das rein muss. Naja, wie gesagt, mach das zu wenig...

      HW-Uart dachte ich auch schon. Aber stört das Modul nicht beim Schreiben über den Bootloader?
      Die nutzen doch dann die gleichen PINs?
      Nicht das das Modul denkt "das ist für mich" und dreht dann durch...
      Ich verstehe das jetzt nicht ganz aber...

      Du must die Versorgungsspannung ja sowieso schalten um in den AT Modus zu kommen. Das heißt dass Dein Modul nach Reset ohne Power ist und erst wenn alles initialisiert ist die Spannung zu geschaltet wird. Da ist die Arbeit des Bootloaders schon erledigt. Bei mir gab es keine Probleme mit dem Bootloader.
    • Hallo Pluto25,
      Hallo Pacman,

      @Pacman : Ich meinte damit das ich das nicht gelesen hatte. "Zu Ende lesen" hätte ich tun sollen. Sorry
      Das mit der HW-Uart probier ich demnächst aus.

      Ich hab mich anderweitig nochmal über das Modul eingelesen.
      Also, das mit dem Pin mag mein Modul nicht. Egal. Wird Taster halt gedrückt und dann eingeschalten.
      Neues gelernt hab ich auch... a_67_e210de67 AT-Modus hat eine andere Baudrate 38400 ich war mit 9600 unterwegs.
      AT+Name geht nur im 2. AT-Modus, der Taster muss dazu gedrückt sein.
      Ich hab das Programm so eingekürzt das es im Moment so geht.

      BASCOM Source Code

      1. $regfile = "m328pdef.dat"
      2. $crystal = 16000000
      3. $hwstack = 64
      4. $swstack = 64
      5. $framesize = 64
      6. '$baud = 9600
      7. Open "comd.3:38400,8,N,1" For Output As #1
      8. Open "comb.2:38400,8,N,1" For Input As #2
      9. Config Portb.5 = Output
      10. LED Alias portb.5
      11. 'A5 = SCL PC.5
      12. 'A4 = SDA PC.4
      13. '--------------------------------------------------------'
      14. ' I2C Definieren '
      15. '--------------------------------------------------------'
      16. Config Clockdiv = 1 ' make sure the chip runs at 8 MHz
      17. Config Scl = Portc.5 ' used i2c pins
      18. Config Sda = Portc.4
      19. Config Twi = 400000 ' i2c speed
      20. I2cinit
      21. $lib "i2c_twi.lbx" ' we do not use software emulated I2C but the TWI
      22. $lib "glcdSSD1306-I2C.lib"
      23. '--------------------------------------------------------'
      24. ' Interrupts einschalten '
      25. '--------------------------------------------------------'
      26. ' Enable Interrupts
      27. '--------------------------------------------------------'
      28. ' Funktionen und Subs declarieren '
      29. '--------------------------------------------------------'
      30. '--------------------------------------------------------'
      31. ' Variablen und Array definieren '
      32. '--------------------------------------------------------'
      33. Print #1 , "Arduino Nano mit HC-05 Bluetooth und I2C-OLED-Display in Bascom!"
      34. Print #1 , "Warte auf Eingaben..."
      35. #if _build < 20784
      36. Dim ___lcdrow As Byte , ___lcdcol As Byte ' dim these for older compiler versions
      37. #endif
      38. waitms 200
      39. Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306"
      40. Cls
      41. waitms 200
      42. Setfont Font8x8tt ' select font
      43. Lcdat 1 , 1 , "I2C-OLED und HC-05"
      44. Lcdat 2,1,"in Bascom"
      45. Waitms 1000
      46. ' Print #1, "AT+UART?" + CHR(13) + CHR(10)
      47. ' Print #1, "AT+NAME?" + CHR(13) + CHR(10) ' Name abfragen
      48. 'Programm scheint zu hängen, der Text unten erscheint nicht wenn input "Scharf" ist
      49. ' Anfang Schnipsel aus Forumsbeitrag
      50. 'https://bascomforum.de/index.php?thread/2175-soft-uart/&postID=35609&highlight=software%2Buart#post35609
      51. Dim A As String * 30
      52. Dim C As String * 25
      53. ' Ende Schnipsel aus Forumsbeitrag
      54. cls
      55. Dim befehl as String * 15
      56. Dim Zeile as Byte
      57. Befehl = "AT"
      58. Zeile = 1
      59. Gosub Daten_einlesen
      60. if c = "OK" Then : LED=0 : C="" : End if
      61. Zeile = 2
      62. Befehl = "AT+pswd" 'Command 12
      63. Gosub Daten_einlesen
      64. Zeile = 3
      65. Befehl = "AT+ADDR" 'Command 5
      66. Gosub Daten_einlesen
      67. Zeile = 4
      68. Befehl = "AT+UART" 'Command 13 Baudrate für BT-Verbindung
      69. Gosub Daten_einlesen
      70. If C="+UART:9600,0,0" Then Print#1,"AT+UART=38400,0,0"
      71. Zeile = 5
      72. Befehl = "AT+CMODE" 'Command 14 1 = Egal 0 = festgelegtes End Gerät zb. nur Smartphone
      73. Gosub Daten_einlesen
      74. Zeile = 6
      75. Befehl = "AT+bind" 'Command 15
      76. Gosub Daten_einlesen
      77. 'Zeile = 7
      78. 'Befehl = "AT+NAME" 'Command 6 Geht nur wenn Taster Dauerhaft gedrückt
      79. 'Gosub Daten_einlesen
      80. Do
      81. ' Anfang Schnipsel aus Forumsbeitrag
      82. 'https://bascomforum.de/index.php?thread/2175-soft-uart/&postID=35609&highlight=software%2Buart#post35609
      83. 'Toggle Led:Waitms 100 'Brauch ich hier nicht
      84. ' Ende Schnipsel aus Forumsbeitrag
      85. Loop
      86. End
      87. $include "font8x8TT.font" ' this is a true type font with variable spacing
      88. ' Anfang Schnipsel aus Forumsbeitrag
      89. 'https://bascomforum.de/index.php?thread/2175-soft-uart/&postID=35609&highlight=software%2Buart#post35609
      90. Daten_einlesen:
      91. Led = 1 : C =""
      92. Print #1, Befehl
      93. Input #2,c
      94. LCDat Zeile,3,c,0
      95. LED = 0
      96. Return
      97. ' Ende Schnipsel aus Forumsbeitrag
      Display All
      Hier noch ein Bild vom Drahtverhau und der Ausgabe des Programms.20210211_194448.jpg


      Danke für eure Tipps und Zeit!
      Grüße
      Counter