Forum: Compiler & IDEs STM32F4 Zeichenfolge "herausfischen"


von Christoph H. (christoph_b)


Lesenswert?

Hallo

Nach längerer Zeit habe ich wieder einmal eine Frage in C ;-)
Da ich mich sonst seit ca 3 Jahren nur mit C# beschäftige fällt mir das 
progen in C extrem schwer

Nun meine Frage

Ich sende per UART an ein Bluethooth device folgende Zeichenfolge
INQUIRY 1

zurück bekomme ich z.B

INQUIRY 1
INQUIRY_PARTIAL 10:68:3f:24:6e:e2 5a020c "" -68
INQUIRY_PARTIAL 08:d4:2b:1e:40:40 1a010c "" -66
INQUIRY 2
INQUIRY 10:68:3f:24:6e:e2 5a020c
INQUIRY 08:d4:2b:1e:40:40 1a010c

jetzt brauche ich folgende Teile ( MAC Adresse) am besten in einem Array
10:68:3f:24:6e:e2,-68
08:d4:2b:1e:40:40,-66

Leider komme ich nicht dahinter wie ich das am besten auf einem STM32F4 
löse. Ich sollte die Werte im Ram zwischenspeichern. Maximal kommen so 
ca 200 Werte zusammen.

Dachte an ein Zweidimensionale char Array.

Vieleicht kann mir jemand auf die Sprünge helfen.

Gruß Christoph

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Folgt auf den Empfang von INQUIRY 2 immer die Liste der Adressen mit 
INQUIRY-Prefix? Was folgt auf die Adress-Liste? Leerzeile, Pause oder 
sind es immer zwei Zeilen? Mit welchen/welchen Zeilen sind die Zeilen 
abgeschlossen (CR, LF, CRLF)? Es bietet sich eine Zeilenweise 
Verarbeitung in einem Zustandsautomaten an, Pseudocode grob vereinfacht 
(ohne Timout-, Pufferüberlauf- und nur wenig Fehlerbehandlung):
1
rec = ""
2
state = 0
3
done = false
4
error = false
5
6
while !done
7
 if uart_hat_zeichen_empfangen then
8
  if empfangenes_zeichen = zeilenende then
9
    switch (state)
10
    case 0:
11
      if rec == "INQUIRY 2" then
12
        state = 1
13
        nmacs = 0
14
      endif
15
    case 1:
16
      if left(rec) == "INQUIRY" then
17
       mac[nmacs] = right(rec)
18
       nmacs++
19
       if nmacs = 2 then 
20
         done = true
21
       endif
22
      elseif
23
        error = true  // Fehler, INQUIRY erwartet, aber nicht erhalten
24
        done = true
25
      endif
26
      rec = ""
27
    endswitch
28
  else
29
    rec += empfangenes_zeichen
30
  endif
31
endwhile

Falls abweichende Antworten möglich sind, kann man diese in dem 
Zustandsautomaten mittels weiterer Fälle im "switch" unterbringen.

: Bearbeitet durch Moderator
von Christoph H. (christoph_b)


Lesenswert?

hallo

auf INQUIRY 1

folgt immer nochmals INQUIRY 1 als bestätigung

Danach kommen die Zeilen die ich benötige. Anzahl ist unbekannt und 
variert.
z.b
INQUIRY_PARTIAL 10:68:3f:24:6e:e2 5a020c "" -68
INQUIRY_PARTIAL 08:d4:2b:1e:40:40 1a010c "" -66
INQUIRY_PARTIAL 04:as:8d:1a:42:20 1a010c "" -51
....
Als nächstes kommt wieder der Befehl INQUIRY mit der Anzahl der Zeilen 
hier z.b 3 also
INQUIRY 3

der Rest kann weg vergessen werden.

Die Zeilen werden mit <\r><\n> abgeschlossen

: Bearbeitet durch User
von Christoph H. (christoph_b)


Lesenswert?

So habe es so weit hinbekommen
1
#include "string.h"
2
#include "stdlib.h"
3
#include "main.h"
4
#include "stm32_ub_udp_server.h"
5
#include "stm32_ub_led.h"
6
#include "stm32_ub_uart.h"
7
#include "stm32_ub_tim5.h"
8
9
int i=0;
10
char delimiter[]=" """;
11
char *ptr;
12
char output[30];
13
14
char output_array[10][25];
15
int array_help;
16
int e;
17
int d;
18
int f;
19
20
void UB_TIMER5_ISR_CallBack(void)
21
{
22
  i=0;
23
  UB_Led_Toggle(LED_GREEN);
24
  //UB_Uart_SendString(COM3,"AT",CRLF);
25
  UB_Uart_SendString(COM3,"INQUIRY 2",CRLF);
26
}
27
28
int main(void)
29
{
30
  int array_count=1;
31
  //char mac[20][20]={"10:68:3f:24:6e:d2","08:d4:2b:1e:40:05"};
32
  char mac[10][19];
33
  char t[10];
34
35
  UDP_INIT_STATUS_t init_check;
36
  UDP_RECEIVE_t rec_check;
37
  char rx_buf[UDP_RX_BUFFER_SIZE];
38
39
  char buf[RX_BUF_SIZE]; // puffer fuer Datenempfang UART
40
  UART_RXSTATUS_t check;
41
42
  SystemInit(); // Quarz Einstellungen aktivieren
43
44
  // LEDs initialisieren
45
  UB_Led_Init();
46
  UB_Uart_Init();
47
48
  // UDP-Server initialisieren
49
  init_check=UB_UDP_Server_Init();
50
  if(init_check==UDP_INIT_OK) {
51
    // wenn initialisierung ok
52
    UB_Led_On(LED_GREEN);
53
    // Server starten
54
    if(UB_UDP_Server_Connect()==UDP_CONNECT_OK) {
55
      // wenn der Server läuft
56
      // einmal einen Text per UDP senden
57
      UB_UDP_Server_SendString("UDP Server ok");
58
    }
59
  }
60
  else {
61
    // bei einem Fehler
62
    UB_Led_On(LED_RED);
63
  }
64
65
  UB_TIMER5_Init(8399,39996); // alle 4 sec
66
  UB_TIMER5_Start();
67
68
  while(1)
69
  {
70
    // UDP-Server zyklisch aufrufen
71
    // und check ob Daten empfangen wurden
72
    rec_check=UB_UDP_Server_Do(rx_buf);
73
    if(rec_check==UDP_SERVER_OFFLINE) {
74
      // UDP-Server ist Offline
75
      UB_Led_Off(LED_BLUE);
76
    }
77
    else {
78
      // UDP-Server ist Online
79
      //UB_Led_On(LED_BLUE);
80
      if(rec_check==UDP_RECEIVE_READY)
81
      {
82
        if(strcmp(rx_buf, "OK") == 0)
83
        {
84
          UB_Led_Toggle(LED_BLUE);
85
          for(d=0;d<=2;d++)
86
          {
87
            UB_UDP_Server_SendString(output_array[d]);
88
            UB_Led_Toggle(LED_BLUE);
89
          }
90
          //if(UB_UDP_Server_SendString(mac[1])==ERROR)
91
          //{
92
          //UB_Led_Toggle(LED_BLUE);
93
          //}
94
          }
95
96
      }
97
98
      check=UB_Uart_ReceiveString(COM3,buf);
99
      if(check==RX_READY) {
100
        UB_Led_Toggle(LED_RED);
101
        //i++;
102
        if(strlen(buf)>40)
103
        {
104
          //if(strncmp(buf,"INQUIRY_PARTIAL",15))
105
          //if(strncmp(buf,"INQUIRY 1",9))
106
          //{
107
          ptr=strtok(buf,delimiter);
108
          while(ptr!=NULL)
109
          {
110
            i++;
111
            sprintf(mac[i],"%s\n",ptr);
112
            //sprintf(mac[1],"%s\n",ptr);
113
            ptr=strtok(NULL,delimiter);
114
          }
115
          //strncpy(mac[0], buf, 35);
116
          strcpy(output,mac[2]);
117
          strncat(output,mac[5],30);
118
          //UB_UDP_Server_SendString(output);
119
          for (e=0;e<sizeof(output_array);e++)
120
          {
121
            if(strncmp(output,output_array[e],10)!=0)
122
            {
123
              UB_Led_Toggle(LED_BLUE);
124
              strcpy(output_array[array_count],output);
125
126
              array_count++;
127
            }
128
          }
129
        }
130
131
      }
132
    }
133
  }
134
}

im Array "output" finde ich folgenden Zeichenfolge "b4:b6:76:ea:f7:80
-62"

die letzen 3 zeichen gibt die Signalstärke an.

Nun wollte ich die Zeichenfolge in ein Array kopieren sofern sie noch 
nicht in im Array enthalten ist.
Leider hängt das Programm sich dabei auf.

Hier der auschnitt wo ich nicht weiterkomme
1
          for (e=0;e<sizeof(output_array);e++)
2
          {
3
            if(strncmp(output,output_array[e],10)!=0)
4
            {
5
              UB_Led_Toggle(LED_BLUE);
6
              strcpy(output_array[array_count],output);
7
8
              array_count++;
9
            }
10
          }

von jgdo (Gast)


Lesenswert?

Gibt es einen Grund dafür, warum du kein C++ nutzen möchtest? Der 
STM32F4 ist ja nicht gerade ein Controller, bei dem es auf jedes Byte 
ankommt.
Dann könntest du Regexe verwenden und das ganze wäre kein Problem mehr.

von Christoph H. (christoph_b)


Lesenswert?

ich kenn mich mit C++ gar nicht aus. Leider. ,-)

Habe es aber irgendwie mit C nun hinbekommen. Es geht ja nunr um einen 
Test einer Hardware.

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.