Stringauswertung Problem

Gast #1864026
Lesenswert?

Hallo,

ich habe ein kleines Problem beim Auswerten eines Strings.
Der String sieht folgendermaßen aus: 1.f.0.0.0.1.$

Diesen String möchte ich gern mit folgendem Code auswerten und die 
einzelnen Zahlenwerte in ein Array schreiben:
1
long eingang[10];
2
char *ptr;
3
char delimiter[] = ".";
4

5
ptr = strtok(empfang,delimiter);
6
for(x=0;x<=6;x++){
7
eingang[x] = strtol(ptr, NULL, 16);
8
ptr = strtok(NULL, delimiter);
9
}

Die einzelnen Teilstücke die durch strtok erzeugt werden funktionieren 
soweit einwandfrei, doch die Umwandlung mit strtol funktioniert leider 
nicht und ich weiß nicht warum. Kann mir jemand von euch vielleicht 
weiterhelfen?
Gast #1864062
Lesenswert?

Danke für die schnelle Antwort ich habe es gleich mal ausprobiert doch 
leider ist eingang immer 0.
Hier mal mein geänderter Code:
1
eingang[0] = strtol (empfang,&pEnd,16);
2
for(x=1;x<=6;x++){
3
  eingang[x] = strtol (pEnd,&pEnd,16);
4
  pEnd++;
5
  PRINT("Zahl%d:  %ld\r\n",x,eingang[x]);
6
}
#1864078
Lesenswert?

Stefan schrieb:
> Danke für die schnelle Antwort ich habe es gleich mal ausprobiert doch
> leider ist eingang immer 0.
> Hier mal mein geänderter Code:
>
>
1
> eingang[0] = strtol (empfang,&pEnd,16);
2
>

hier fehlt das anschliessende pEnd++ um den darauffolgenden '.' zu 
überspringen. Die nachfolgenden strtol verweigern daher alle, weil sie 
mit einem '.' nichts anfangen können.

>
1
> for(x=1;x<=6;x++){
2
>
Wenn ich ein <= in der Abbruchbedingung einer for-Schleife sehe, 
klingeln bei mir alle Alarmglocken.

Diese Schleife wird 7 mal durchlaufen. Du hast aber in deinem String nur 
6 Zahlen. Der letzte Bestandteil deines Strings "1.f.0.0.0.1.$" ist ein 
$ und das ist keine Zahl mehr.
Gast #1864083
Lesenswert?

Ich hab den Code auf deine Einwände geändert doch leider funktioniert er 
immer noch nicht, ich weiß nicht woran es noch liegen kann. Hier nochmal 
der aktuelle Code:
1
eingang[0] = strtol (empfang,&pEnd,16);
2
pEnd++;
3
for(x=1;x<=5;x++){
4
  eingang[x] = strtol (pEnd,&pEnd,16);
5
  pEnd++;
6
  PRINT("Zahl%d:  %ld\r\n",x,eingang[x]);
7
}
#1864092
Lesenswert?

Stefan schrieb:
> Ich hab den Code auf deine Einwände geändert doch leider funktioniert er
> immer noch nicht, ich weiß nicht woran es noch liegen kann.

Hast du dein PRINT kontrolliert?

Du musst das 'funktioniert nicht' an anderer Stelle suchen, der 
Codeausschnitt an sich ist jetzt ok.

(Auch wenn du das for falsch rum geändert hast. Schreibs als x < 6 und 
nicht als x <= 5. Kommt hier aufs selbe raus, d.h. das ist jetzt nicht 
das Problem)

Übrigens: Dein Originalcode war ebenfalls ok.

Wo kommt "empfang" her?
Gast #1864125
Lesenswert?

Karl heinz Buchegger schrieb:
> Hast du dein PRINT kontrolliert?

Ich weiß nicht wo da der Fehler liegen sollte.

Karl heinz Buchegger schrieb:
> Wo kommt "empfang" her?

empfang kommt aus der Interruptroutine vom UART
Hier der Code dazu:
1
empfang[count]=data;
2
count++;
3
if (data=='$'){
4
 empfang[count]='\0';
5
 count=0;
6
 new_ms=1;
7
}

Wenn ich mir in der Schleife die Einzelnen Teile von pEnd ausgeben 
lassen sehe ich auch das dies alles wunderbar funktioniert doch in der 
eingang-variable ist leider nur 0.
Gast #1864145
Lesenswert?

Karl heinz Buchegger schrieb:
> Datentypen.
> Zeig doch endlich mal ein wenig mehr!

Kein Problem hier sind die verwendeten Datentypen:
1
int x;
2
long eingang[10];
3
char *pEnd;
4
volatile uint8_t new_ms, count;
5
volatile char empfang[30];

Und hier mal meine komplette Main.c:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <avr/pgmspace.h>
4

5
#include <util/delay.h>
6
#include <stdio.h>
7
#include <inttypes.h>
8

9
#include "uart.h"
10
#include "global.h"
11
#include "defaults.h"
12
#include "pwm.h"
13
// ----------------------------------------------------------------------------
14

15
#define  PRINT(string, ...)    printf_P(PSTR(string), ##__VA_ARGS__)
16

17
static int putchar__(char c, FILE *stream) {
18
  uart_putc(c);
19
  return 0;
20
}
21

22
static FILE mystdout = FDEV_SETUP_STREAM(putchar__, 0, _FDEV_SETUP_WRITE);
23

24
// ----------------------------------------------------------------------------
25

26
// ----------------------------------------------------------------------------
27
// Hauptprogram
28

29
int main(void)
30
{
31
 id_set=0x01;
32
 DDRC=0xBF;
33
 DDRB=0xC3;
34
 DDRD=0xF4;
35
  // Initialisiere die UART Schnittstelle
36
  uart_init(UART_BAUD_SELECT(9600UL, F_CPU));
37
  // Umleiten der Standardausgabe => ab jetzt koennen wir printf() verwenden
38
  stdout = &mystdout;
39
    // Timer 1 OCRA1, als variablen Timer nutzen
40
  OCR1A = 255;
41
  TIMSK = (1 << OCIE1A) | (1 << OCIE1B);
42
  TCCR1B = (1 << WGM12) | 4;
43
  
44
  // Aktiviere Interrupts
45
  sei();
46

47
  for(uint8_t i=0; i<CHANNELS; i++){
48
    pwm_queue[i] = i;
49
  }
50
  for (uint8_t i = 0; i <= 15; i++) {
51
    PWM[i]=0;
52
  }
53
  pwm_update();
54

55
  int x, id, dimmwert[10], channel, action;
56
  long eingang[10];
57
  char *ptr;
58
  while (1) {
59
     if (new_ms){
60
      new_ms=0;
61
            empfang[count+1]='\0';
62
      count=0;
63
      PRINT("Eingang: %s\r\n", empfang);
64
      eingang[0] = strtol (empfang,&pEnd,16);
65
      pEnd++;
66
      for(x=1;x<6;x++){
67
        eingang[x] = strtol (pEnd,&pEnd,16);
68
        PRINT("Zahl%d:  %ld\r\n",x,eingang[x]);
69
        pEnd++;
70
      }
71
      id=eingang[0];
72
      if (id==id_set){
73
        channel=eingang[1];
74
        action=eingang[2];
75
        if (action==0){
76
          PWM[channel-15]=eingang[3];
77
          PWM[channel-14]=eingang[4];
78
          PWM[channel-13]=eingang[5];
79
        }
80
        if (action==1){
81
          for (uint8_t i=0; i<15; i=i+3){  
82
            PWM[i]=inhalt[2];
83
            PWM[i+1]=inhalt[3];
84
            PWM[i+2]=inhalt[4];
85
          }
86
        }
87
        pwm_update();
88
      }
89
    }  
90
  }
91
return 0;
92
}
Gast #1864386
Lesenswert?

Da hast du natürlich recht das die Schleife einmal zu oft durchlaufen 
wird, dies habe ich geändert doch mein Problem das nur 0 in der variable 
eingang ist, bleibt weiterhin bestehen und ich weiß nicht warum.
#1864390
Lesenswert?

Stefan schrieb:
> Da hast du natürlich recht das die Schleife einmal zu oft durchlaufen
> wird, dies habe ich geändert doch mein Problem das nur 0 in der variable
> eingang ist, bleibt weiterhin bestehen und ich weiß nicht warum.

Mach mal deinen String konstant.
Du ´zeigst nicht, wo der String herkommt, auch da könnte noch was sein. 
Wenn im String noch irgendwelche Leerzeichen oder so rumlungern, dann 
sieht man die manchmal bei Kontrollausdrucken nur schwer.

1
 while (1) {
2
     if (new_ms){
3
      new_ms=0;
4
            empfang[count+1]='\0';
5
      count=0;
6

7
      strcpy( empfang, "1.f.0.0.0.1.$" );
8

9
      PRINT("Eingang: %s\r\n", empfang);
10
      eingang[0] = strtol (empfang,&pEnd,16);
11
      pEnd++;
12
      for(x=1;x<6;x++){
13
        eingang[x] = strtol (pEnd,&pEnd,16);
14
        PRINT("Zahl%d:  %ld\r\n",x,eingang[x]);
15
        pEnd++;
16
      }
17

18
....
Gast #1865003
Lesenswert?

Karl heinz Buchegger schrieb:
> Mach mal deinen String konstant.

Hab ich gemacht leider gleiches Ergebniss wie vorher. Im Array sind 
leider nach wievor nur Nullen.

Karl heinz Buchegger schrieb:
> Du ´zeigst nicht, wo der String herkommt, auch da könnte noch was sein.

Hier mal der Code vom UART-Interrupt wo der String gebildet wird:
1
SIGNAL(UART0_RECEIVE_INTERRUPT)
2
/*************************************************************************
3
Function: UART Receive Complete interrupt
4
Purpose:  called when the UART has received a character
5
**************************************************************************/
6
{
7
  unsigned char tmphead;
8
  unsigned char data;
9
  unsigned char usr;
10
  unsigned char lastRxError;
11

12

13
  /* read UART status register and UART data register */ 
14
  usr  = UART0_STATUS;
15
  data = UART0_DATA;
16
  empfang[count]=data;
17
  count++;
18
  if (data=='$'){
19
    new_ms=1;
20
  }
21
  /* */
22
#if defined( AT90_UART )
23
  lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
24
#elif defined( ATMEGA_USART )
25
  lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
26
#elif defined( ATMEGA_USART0 )
27
  lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
28
#elif defined ( ATMEGA_UART )
29
  lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
30
#endif
31
    
32
  /* calculate buffer index */ 
33
  tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
34
  
35
  if ( tmphead == UART_RxTail ) {
36
    /* error: receive buffer overflow */
37
    lastRxError = UART_BUFFER_OVERFLOW >> 8;
38
  }else{
39
    /* store new index */
40
    UART_RxHead = tmphead;
41
    /* store received data in buffer */
42
    UART_RxBuf[tmphead] = data;
43
  }
44
  UART_LastRxError = lastRxError;   
45
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren