Forum: Mikrocontroller und Digitale Elektronik Serielle Daten zerhacken, anschließende Array to float Umwandlung?


von Sven (Gast)


Lesenswert?

Hallo Zusammen,

ich empfange serielle daten (Koordinaten) über den UART, diese werden in 
einem array gespeichert und liegen dann wie folgt vor.
1
char buffer[BYTES]={'X','-', 1, 2, '.', 2, 3, ';', 'Y', '+', 1, 2, '.', 3, 4,';','Z',  '+', 1, 2, 0,'.', 0, 5, ';'};

Das senden funktioniert wunderbar per Interrupt. Mit einem Echo konnte 
ich das ganze testen und die daten werden auch wieder sauber an den PC 
geschickt.

Mein Problem ist es nun die Daten aufzuteilen. Hierfür habe ich bereits 
mit der Funktion strtok() herumexperimentiert, bin jedoch zu keinem 
Ergebnis gekommen. Hier der Programmcode. Ich möchte die Daten an den 
';' zerteilen.
1
//******************************    
2
// Header includes
3
//******************************    
4
#include <stdlib.h> 
5
#include <stdio.h> 
6
#include <stdint.h>
7
#include <string.h>
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <math.h>
11
#include <stdbool.h>
12
13
//******************************    
14
// constants
15
//******************************
16
17
#define F_CPU     20000000UL  // Systemtakt in Hz (=20 MHz)
18
#define BYTES 28
19
// variables
20
//******************************    
21
char buffer[BYTES]={'X','-', 1, 2, '.', 2, 3, ';', 'Y', '+', 1, 2, '.', 3, 4,';','Z',  '+', 1, 2, 0,'.', 0, 5, ';'};
22
char TmpBuffDelim[10];
23
char String[BYTES];
24
char Delimiter[]= ";";
25
char *ptoken;
26
int i=0;
27
28
// Function Prototypes
29
//******************************    
30
void StringToken(void);
31
32
//°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
33
//  MAIN PROGRAMM
34
//°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
35
36
int main(void) 
37
38
{
39
  while(1)
40
  {
41
  StringToken();
42
  }
43
}
44
45
void StringToken(void)
46
{
47
memcpy(String, buffer, sizeof(buffer));   // kopiert die eingelesenen Daten zunächst in einen String zurweiterverarbeitung
48
  
49
ptoken = strtok(String, Delimiter);     // get pointer to first token found and store in 0
50
  
51
  while(ptoken != NULL)              // ensure a pointer was found
52
    {    
53
    TmpBuffDelim[i]= *ptoken;
54
        ptoken = strtok(NULL, Delimiter);     // continue to tokenize the string
55
    i++;
56
   }
57
}

Das nächste Problem ist es dann aus diesem Array eine Floatzahl zu 
erhalten!
Weiß jemand Rat oder hat sowas ähnliches schonmal gemacht?
Besten Dank im voraus!

von cskulkw (Gast)


Lesenswert?

Konvertieren von Ascii to Float geht hier mit.

double  atof (const char *__nptr)

von Sven (Gast)


Lesenswert?

Hier mein Minimal-Beispiel! Was mach ich falsch?
1
//******************************    
2
// Header includes
3
//******************************    
4
#include <stdlib.h> 
5
#include <stdio.h> 
6
#include <stdint.h>
7
#include <string.h>
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <math.h>
11
#include <stdbool.h>
12
13
//******************************    
14
// constants
15
//******************************
16
17
#define F_CPU     20000000UL  // Systemtakt in Hz (=20 MHz)
18
19
// variables
20
//******************************    
21
char Array[5]={1,2,'.',1,2};
22
double XValue=0;
23
24
// Function Prototypes
25
//******************************    
26
27
//°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
28
//  MAIN PROGRAMM
29
//°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
30
31
int main(void) 
32
33
{
34
  XValue = atof(Array);
35
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Sven schrieb:
> Was mach ich falsch?
Probier das:
   char Array[6]={'1','2','.','1','2',0};

Und wenn das geht, dann mach dich mal zum Thema ASCII und Zeichenketten 
in C schlau. Insbesondere die Null am Zeichenkettenende bewahrt so 
manches Programm vor einem Amoklauf quer durch den Speicher...

> double XValue=0;
LOL...
Double auf dem AVR mit dem GCC?

von Nico S. (nico22)


Lesenswert?

Und natürlich müssen deine echten Daten auch nullterminiert werden:
1
char buffer[BYTES]={'X','-', '1', '2', '.', '2', '3', ';', 'Y', '+', '1',
2
'2', '.', '3', '4',';','Z',  '+', '1', '2', '0','.', '0', '5', ';', 0};

Ich hab auch mal geändert, dass die Ziffern natürlich ASCII-Werte sind 
und nicht Zahlen. Darum auch jene in Anführungszeichen. Das 
String-Endzeichen ist allerdings die 0 ohne Anführungszeichen.

von Sven (Gast)


Lesenswert?

Vielen Dank!
Also das Minimalbeispiel zu atof funktioniert nun mit beiden der 
folgenden Deklarationen:
1
char Array[6]={'1','2','.','1','2',0};
2
// char Array[6]={'1','2','.','1','2','\0'};

Double hatte ich zuvor verwendet da, die Funktion atof ja mit einem 
double als Übergabewert deklariert ist, soll aber da es sich um nen 
8biter uC handelt dann wohl float sein, oder wie? Funzt übrigens auch 
mit beiden Arten der Deklaration (double und float)!

Gruß Sven

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Sven schrieb:
> Also das Minimalbeispiel zu atof funktioniert nun mit beiden der
> folgenden Deklarationen:
Ist ja klar.
Da steht ja auch das selbe da, eine '\0' ist das selbe wie eine 0...

Wie gesagt mein Hinweis:
Lothar Miller schrieb:
> Und ... mach dich mal zum Thema ASCII ... in C schlau.

> Funzt übrigens auch
> mit beiden Arten der Deklaration (double und float)!
Es gibt kein double mit dem GCC auf dem AVR. Das ist beide Male ein 
ordinäres 32-Bit float...

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.