mit dieser Library kann ein Bluetooth-Modul mit RN42-Chip an die CPU angeschlossen werden.
Nach aufbauen einer Verbindung (von einem PC, Smartphone oder zweitem RN42-Modul) können dann Daten über Funk (Bluetooth) übertragen werden.
Das Modul wird an eine normale UART der CPU angeschlossen und verhält sich nach dem Verbindungsaufbau auch wie eine normale serielle Schnittstelle mit 115kBaud.
Es gibt mehrere Funktionen die benutzt werden können, aber es genügt eigentlich
diese Reihenfolge einzuhalten :
1. Init vom Modul (es wird geprüft ob das Modul an der UART angeschlossen ist)
2. Umschalten des Moduls in den Data-Mode (WICHTIG !!)
3. Am PC (oder Smartphone) das Bluetooth-Modul per “Scan” suchen und verbinden
4a. Daten vom PC/Smartphone per Bluetooth an das Modul senden und per
“UB_RN42_ReceiveString” auf der CPU empfangen
4b. Daten von der CPU per “UB_RN42_SendString” über Bluetooth an den PC/Smartphone senden.
Es gibt noch Funktionen um die 12-Stellige Adresse vom RN42-Modul auszulesen und um eine Pin-Nr und den Namen vom RN42-Modul einzustellen. (geht nur im CMD-Mode)
Falls eine Verbindung zu einem anderen RN42-Modul hergestellt werden soll, muss dessen Adresse per “UB_RN42_Set_BT_Adr” gesetzt werden und danach muss die Funktion ”UB_RN42_Connect” aufgerufen werden.
Hinweis : Diese Funktionalität habe ich nicht getestet !!
Hinweis zu Smartphones : der Übertragungsmode ist “SPP = SerialPortProfile” und muss vom Smartphone unterstützt werden. Als Anwendung gibt es dann z.B. für Android kostenlose APPs wie “BTerm oder Bluetooth Terminal”.
Schaltung und Modul :
im Beispiel wurde das RN42-Modul an die UART-3 angeschlossen :
1 2 | PC10 = CPU_TX > RN42_RX PC11 = CPU_RX < RN42_TX |
Voraussetzungen :
1 2 | Benutzte Module der CooCox-IDE : GPIO, USART, MISC Benutzte Librarys : keine |
Enumerationen :
1 2 3 4 5 6 7 | typedef enum { RN42_NONE = 0, // keine Endekennung RN42_LFCR, // LineFeed + CarriageReturn (0x0A,0x0D) RN42_CRLF, // CarriageReturn + LineFeed (0x0D,0x0A) RN42_LF, // nur LineFeed (0x0A) RN42_CR // nur CarriageReturn (0x0D) }RN42_LASTBYTE_t; |
:
1 2 3 4 5 | typedef enum { RN42_RX_EMPTY = 0, // nichts empfangen RN42_RX_READY, // es steht was im Empfangspuffer RN42_RX_FULL // RX-Puffer ist voll }RN42_RXSTATUS_t; |
Funktionen :
1 2 3 4 5 6 7 8 9 10 11 | ErrorStatus UB_RN42_Init(void); // init vom RN42 ErrorStatus UB_RN42_DATA_Mode(void); // schaltet RN42 in DATA-Mode ErrorStatus UB_RN42_CMD_Mode(void); // schaltet RN42 in CMD-Mode RN42_RXSTATUS_t UB_RN42_ReceiveString(char *ptr); // empfängt String per Bluetooth ErrorStatus UB_RN42_SendString(char *ptr, RN42_LASTBYTE_t last_byte); // sendet String per Bluetooth ErrorStatus UB_RN42_Get_BT_Adr(void); // auslesen der eigenen Adresse ErrorStatus UB_RN42_Set_BT_Adr(char *ptr); // setzen der Partner Adresse ErrorStatus UB_RN42_Set_BT_Pin(char *ptr); // setzen vom Pin ErrorStatus UB_RN42_Set_BT_Name(char *ptr); // setzen vom Name ErrorStatus UB_RN42_Connect(void); // verbinden mit Partner ErrorStatus UB_RN42_Disconnect(void); // trennen vom Partner |
Beispiel :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | //-------------------------------------------------------------- // File : main.c // Datum : 01.12.2013 // Version : 1.0 // Autor : UB // EMail : mc-4u(@)t-online.de // Web : www.mikrocontroller-4u.de // CPU : STM32F4 // IDE : CooCox CoIDE 1.7.4 // GCC : 4.7 2012q4 // Module : CMSIS_BOOT, M4_CMSIS_CORE // Funktion : Demo der RN42-Library // Hinweis : Diese zwei Files muessen auf 8MHz stehen // "cmsis_boot/stm32f4xx.h" // "cmsis_boot/system_stm32f4xx.c" //-------------------------------------------------------------- #include "main.h" #include "stm32_ub_led.h" #include "stm32_ub_rn42.h" int main(void) { ErrorStatus check; char buf[30]; SystemInit(); // Quarz Einstellungen aktivieren // init der LEDs UB_Led_Init(); // init vom RN42-Modul (an PC10,PC11) check=UB_RN42_Init(); if(check==SUCCESS) { UB_Led_On(LED_GREEN); // default Werte setzen UB_RN42_Set_BT_Adr("A1B2C3D4E5F6"); // nicht notwendig UB_RN42_Set_BT_Pin("1234"); UB_RN42_Set_BT_Name("RN42-Modul STM32F4"); // in Data-Mode umschalten UB_RN42_DATA_Mode(); } else { UB_Led_On(LED_RED); } while(1) { if(check==SUCCESS) { // check ob Daten per Bluetooth empfangen wurden if(UB_RN42_ReceiveString(buf)==RN42_RX_READY) { UB_Led_Toggle(LED_BLUE); // wenn ja, als Echo zurücksenden UB_RN42_SendString(buf,RN42_LFCR); } } } } |
Hier die Library zum Download :
Hier der komplette CooCox-Projektordner zum Download :
Hallo,
bezüglich des Bluetooth Projektes mit dem RN42 habe ich eine Frage. Ich habe alles soweit hinbekommen und kann mein Handy mit dem Modul koppeln. Allerdings kann ich mich in der App (Bluetooth Terminal) nicht verbinden. Also auch keine Nachrichten schicken. Haben Sie eine Idee woran das liegen könnte?
event. unterstützt dein Handy den SPP-Mode nicht. (geht bei meinem HCT Handy auch nicht)
Erstmal danke für die Lib, funktioniert soweit ganz gut, bis auf ein Problem:
Ich möchte gerne CAN-Nachrichten über Bluetooth weiterleiten, aber bei einem Byte mit Inhalt ’00′ schneidet er die Nachricht ab, weil das innerhalb eines Strings als Null-Termination interpretiert wird.
Von CAN zu BT konnte ich das Problem schon umgehen, indem ich mehrere einzelne Bytes sende und zum Schluss ein CR sende, aber andersherum (BT zu CAN) scheint das nicht so einfach zu sein…
Gibt es einen einfachen Weg, statt der String-Funktionen mit byte-Arrays zu arbeiten? Hast du einen Tipp, an welchen Stellen ich die Lib anpassen muss?
im H-File steht die Einschränkung der Zeichen die empfangen werden
RN42_RX_FIRST_CHR und RN42_RX_LAST_CHR
stell die mal auf 0 und 255 (damit sollten alle Zeichen im Puffer landen)
beim auslesen per “UB_RN42_ReceiveString” musst du dann aber aufpassen,
die übergebenen Daten sind KEIN String mehr…es können 0×00 mitten
im Array auftauchen. Du musst also die Endekennung von 0×00 abändern
um das Ende vom Array erkennen zu können.
Am einfachsten Änderst du die eine Zeile in “UB_RN42_ReceiveString” :
// Stringendekennung
ptr[n]=0x00;
in
// Stringendekennung
ptr[n]=RN42_RX_END_CHR;
damit ist die Endekennung eindeutig
(solannge RN42_RX_END_CHR nicht in deinen Daten vorkommt
Danke, das funktioniert tatsächlich! SendString kann ich zwar immer noch nicht verwenden, aber zumindest funktioniert meine Übertragung jetzt in beide Richtungen, das reicht mir erstmal
Das mit dem END_CHR könnte allerdings ein Problem werden, da ich nicht garantieren kann, dass der Wert nicht vorkommt. Ich glaube da werd ich nochmal ein wenig drüber grübeln. Vielleicht kann ich da mithilfe des DLCs was machen, dadurch weiß ich ja wieviele Daten kommen, bevor die Nachricht zu Ende sein kann.
Ich nochmal…
Kannst du bitte mal überprüfen, ob die Funktion RN42_DATA_Mode wirklich dazu führt, dass er in den DATA-Mode wechselt? Ich bin mir gerade nicht sicher ob das eventuell an einer Änderung liegt, die ich vorgenommen habe, aber mit einem Breakpoint auf der letzten Zeile der Funktion (“return(ret_wert);”) steht im Debugger noch ERROR in ret_wert und der RN42.mode noch auf CMD.
Bei mir schlägt anscheinend das strncmp fehl, da der Puffer mit “\nEND” beginnt. Ich bin aber dennoch in der Lage, manche Nachrichten zu verschicken (obwohl er im CMD-Mode ist!), deswegen kann es sein, dass dir das nie aufgefallen ist.
Wäre interessant das mit Sicherheit zu wissen, unter Umständen muss ich meine Änderungen nochmal zurückverfolgen oder sauber von vorne beginnen. Wenn der Fehler aber bei dir auch auftritt, dann ist das möglicherweise ein Bug in der Lib.
Danke schonmal im Voraus für deine Mühe!
Okay, ich habe das gerade selber mal Anhand deiner Demo überprüft, da klappt es, und der Buffer beginnt auch mit “END”. Ich nehme an das liegt an der Änderung von RN42_RX_FIRST_CHR und RN42_RX_LAST_CHR, die ich vorgenommen habe. Unter diesen Umständen müsste es aber funktionieren, wenn ich das strncmp entsprechend anpasse, oder? Also in dieser Form:
if(strncmp(RN42.buffer,”\nEND”,5)==0)
der Puffer ist KEIN String mehr !! (hab ich schon geschrieben)…
also funktioniert auch strncmp nicht !!
du musst mit einer For-n alle Zeichen bis zur Endekennung selbst prüfen
sonst ist das u.U. buggy.