Forum: Compiler & IDEs UART Schleife MC stürzt ab


von Philipp P. (Gast)


Lesenswert?

Hallo,

ich habe hier ein Problem mit dem empfangen von Daten über Uart, die mir 
ein VB oder Terminal Programm liefert. Sobald das Startbyte kommt geht 
er in die Schleife rein um command zu füllen. Wenn dan mein 
Endbefehlsbyte kommt geht der MC entweder aus (Display wird schwarz und 
sendet keine Uart Daten mehr,
oder er startet einfach neu) komischerweise hat es gestern nach 
mehrmaligen neukompelieren und starten einwandfrei funktionier... Wo 
kann der Fehler sein? Vorallem lief es gestern und das einzige was ich 
verändert habe war der Teil nach der while Schleife..

MfG Philip P.

1
ci = 0;
2
c = uart_getc();
3
   
4
if( c != UART_NO_DATA  && c== 250)    
5
//Startbedingung für alle  Eingehenden Daten, wenn 250 gesendet wird und Daten vorhanden          
6
                                              
7
  
8
   { 
9
       //uart_putc( c );
10
while( c != 254 )                                
11
// Lese solange, bis von der anderen Seite 254 als Endbedingung kommt!
12
      
13
{
14
         if( c != UART_NO_DATA ) {
15
           command[ci++] = c;
16
           c = uart_getc();
17
     uart_putc(c);    // überprüfen am terminal
18
         }
19
     
20
      }
21
22
      int i;
23
for(i = 0; i > 9 ; i++)                           //Addiert Byte 0 - 9 zur Checksumme
24
            {            
25
ChecksummeBerechnet = ChecksummeBerechnet + command[i];
26
}
27
i = 0;
28
29
      
30
ChecksummePC = make_u16(command[10],command[11]);  // Checksumme zusammensetzen
31
  if (ChecksummePC == ChecksummeBerechnet)
32
    
33
    {
34
       //uart_putc(249);
35
       //uart_putc('W');
36
       //uart_putc('W');
37
    }
38
    else 
39
    {
40
     //uart_putc(249);
41
       //uart_putc('S');
42
       //uart_putc('S');
43
    }
44
45
46
47
   }
48
49
50
    ChecksummeBerechnet = 0;
51
52
      command[ci] = '\0';

von Philipp P. (Gast)


Lesenswert?

Hallo,

habe den Vergleich mal an anfang des Programm gesetzt:
Wenn ich die Berechnung ausklammere und über Uart die 250 sende, friert 
das Display ein. Bei 254, geht er aus der Schleife raus und arbeitet 
normal weiter. Sobald die Rechnung in der for Schleife ist startet er 
einfach neu. Was mach ich falsch?
command ist als unsigned char array deklariert
1
   if (command[0] == 250){
2
    int i;
3
    uint16_t ChecksummeBerechnet;
4
    uint16_t ChecksummePC;
5
    for(i = 0; i < 10 ; i++){
6
7
//addierwert = command[i];
8
ChecksummeBerechnet = ChecksummeBerechnet +                    command[i]          
9
}
10
i = 0;
11
12
      
13
ChecksummePC = make_u16(command[10],command[11]);  // Checksumme zusammensetzen
14
15
  if (ChecksummePC == ChecksummeBerechnet){
16
       uart_putc(249);
17
       uart_putc('W');
18
       uart_putc('W');
19
    }
20
    else {
21
     uart_putc(249);
22
       uart_putc('S');
23
       uart_putc('S');
24
    }
25
  command[0] = 0;
26
  ChecksummeBerechnet = 0;
27
  }

von Joe F. (easylife)


Lesenswert?

Philipp P. schrieb:
> command ist als unsigned char array deklariert

Mit welcher Größe?
Wie sieht make_u16() aus?

Mit deinen ausgewählten Codeschnipseln ist kein sinnvolles Debugging 
möglich. Poste das ganze Programm.

von Walter (Gast)


Lesenswert?

Philipp P. schrieb:
> i = 0;

für was ist das gut?
checksum wird nicht initialisiert und
das Programm stürzt in make_u16 ab

von Peter II (Gast)


Lesenswert?

Walter schrieb:
> checksum wird nicht initialisiert und
> das Programm stürzt in make_u16 ab

jede Variable hat irgendeinen wert. Egal ob initialisiert oder nicht. 
Wenn es nicht gerade ein Zeiger ist, ist das wohl kein Grund für ein 
Absturz.

von holger (Gast)


Lesenswert?

Vieleicht ist ja einfach nur das RAM voll.

von Philipp P. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

danke schonmal für die Antworten, im Anhang das derzeitige Programm.
Ich hab versucht das wichtigste zu kommentieren.
Manche kleine Fehler sehe ich noch nicht direkt.

MfG Philipp P.

von Joe F. (easylife)


Lesenswert?

Ziemlich sicher irgend eine Memory corruption.

1)
Du weist z.B. messwerte[20] (21. Eintrag) etwas zu, ob wohl messwerte[] 
(im include file(!?!?)) nur mit max. 20 Einträgen definiert wurde.
Den Sinn von include files solltest du nochmal nachlesen...

2)
1
command[ci++] = c;
2
(...)
3
command[ci+1] = '\0';

hier wird auch zu keiner Zeit geprüft, ob der index ci(+1) die Grenzen 
von command[] sprengt.


3)
1
sprintf(buffer1, "Zeit: %02x:%02x:%02x", time_h, time_m, time_s); //Zeit am LCD Ausgeben

wie groß ist buffer1[]?
wie viele bytes willst du da mit sprintf reinschreiben?
-> Memory corruption

von Philipp P. (Gast)


Lesenswert?

Hallo,

messwerte[20] hab ich auf 21 geändert ;)
Das andere Array ist buffer[10] -> hat bis jetzt immer funktioniert.
Und das mit command[ci+1] = '\0'; wird auch entfernt weil ich es nicht 
brauche. Die command[21] werden auch nicht voll weil ich maximal 13Bytes 
hintereinander sende.

MfG Philipp

von Joe F. (easylife)


Lesenswert?

Philipp P. schrieb:

> Das andere Array ist buffer[10] -> hat bis jetzt immer funktioniert.

OMG. mit sicherheit nicht.

von Philipp P. (Gast)


Lesenswert?

Ok stimmt sry, buffer[10] ist ein wenig zu klein für 14 Zeichen am Lcd.
Das habe ich jetzt auch vergrößert. Er hängt sich trozdem auf oder 
startet neu -.-


MfG Philipp

von Joe F. (easylife)


Lesenswert?

debugger ranhängen und gucken wo es und warum ea crashed...

von Walter (Gast)


Lesenswert?

Peter II schrieb:
> jede Variable hat irgendeinen wert. Egal ob initialisiert oder nicht.
> Wenn es nicht gerade ein Zeiger ist, ist das wohl kein Grund für ein
> Absturz.

habe ich nicht behauptet, aber es ist ein Fehler der sich noch bemerkbar 
machen wird

von Philipp P. (Gast)


Lesenswert?

Hallo,

@ Walter ja, den Fehler in der for Schleife habe ich entfernt


Hab jetzt die ganze Vergleichsroutine nochmal raus genommen bis auf:
Nach der Eingabe von 250 friert das Display ein. Dann nach 254 wirds 
dunkel und er verabschiedet sich.... Mit debuggen habe ich mich noch 
nicht auseinander gesetzt.
1
   ci = 0;
2
   c = uart_getc();
3
   
4
   if( c != UART_NO_DATA  && c == 250){          //Startbedingung für alle Eingehenden Daten, wenn 250 gesendet wird und Daten vorhanden
5
  
6
   
7
  while( c != 254 ){                                // Lese solange, bis von der anderen Seite 254 als Endbedingung kommt!
8
      
9
         if( c != UART_NO_DATA ) {
10
             command[ci++] = c;
11
             c = uart_getc();
12
    uart_putc(c);    // überprüfen am terminal
13
         }
14
     
15
        }
16
17
    command[ci+1] = '\0';
18
    }

von Joe F. (easylife)


Lesenswert?

Wieder nur Codeschnipsel...

Philipp P. schrieb:
> Mit debuggen habe ich mich noch
> nicht auseinander gesetzt.

Wäre dann ja jetzt eine gute Gelegenheit.

von Joe F. (easylife)


Lesenswert?

So, ich habe es für dich mal formatiert, damit man da durchblickt:
1
ci = 0;
2
c = uart_getc();
3
4
// Startbedingung für alle eingehenden Daten, 
5
// wenn 250 gesendet wird und Daten vorhanden
6
if( c != UART_NO_DATA  && c == 250)
7
{          
8
9
  // Lese solange, bis von der anderen Seite
10
  // 254 als Endbedingung kommt!  
11
  while( c != 254 )
12
  { 
13
    if( c != UART_NO_DATA )
14
    {
15
      command[ci++] = c;
16
      c = uart_getc();
17
      uart_putc(c);    // überprüfen am terminal
18
    }
19
  }
20
  command[ci+1] = '\0';
21
}

Überlege mal, was passiert wenn c == UART_NO_DATA ist.
Dann läuft die while Schleife ewig.

Ausserdem muss es nach der Schleife
1
command[ci] = '\0';
heissen, da ci ja schon inkrementiert wurde.

von Walter (Gast)


Lesenswert?

Joe F. schrieb:
> Überlege mal, was passiert wenn c == UART_NO_DATA ist.
> Dann läuft die while Schleife ewig.

fast, wenn c == UART_NO_DATA kommt er gar nicht ins if rein,
er kommt nur rein wenn c == 250 und dann hängt er sich in der Schleife 
auf

von Philipp P. (Gast)


Lesenswert?

Walter schrieb:
> fast, wenn c == UART_NO_DATA kommt er gar nicht ins if rein,
> er kommt nur rein wenn c == 250 und dann hängt er sich in der Schleife
> auf

Ja genau das soll er doch machen, bis mit dem Befehlsbyte mit Wert 254 
die Schleife verlassen wird. Sobald die Schleife verlassen wird macht 
der MC was er will.

von Joe F. (easylife)


Lesenswert?

In der while Schleife wird 254 allerdings nicht mehr empfangen, wenn c 
voher mal UART_NO_DATA wurde...

Du wolltest vermutlich eher sowas machen:
1
  while( c != 254 )
2
  { 
3
    c = uart_getc();
4
    if( c != UART_NO_DATA )
5
    {
6
      command[ci++] = c;
7
      uart_putc(c);    // überprüfen am terminal
8
    }
9
  }

von Philipp P. (Gast)


Lesenswert?

Joe F. schrieb:
> In der while Schleife wird 254 allerdings nicht mehr empfangen,
> wenn c
> voher mal UART_NO_DATA wurde...
>
> Du wolltest vermutlich eher sowas machen:  while( c != 254 )
>   {
>     c = uart_getc();
>     if( c != UART_NO_DATA )
>     {
>       command[ci++] = c;
>       uart_putc(c);    // überprüfen am terminal
>     }
>   }

So habe ich gerade versucht, allerdings gibt er wieder den Geist auf 
wenn ich 254 sende.
Baue ich aber delays ein, läuft alles so wie es soll.
1
if( c != UART_NO_DATA  && c == 250){          //Startbedingung für alle Eingehenden Daten, 
2
//wenn 250 gesendet wird und Daten vorhanden
3
  
4
   
5
while( c != 254 ){
6
//Lese solange, bis von der anderen Seite 
7
//254 als Endbedingung kommt!
8
      
9
if(c != UART_NO_DATA) {
10
command[ci++] = c;
11
  _delay_ms(5);
12
c = uart_getc();
13
  _delay_ms(5);
14
uart_putc(c);
15
  _delay_ms(5);  // überprüfen am terminal
16
  }
17
}
18
command[ci+1] = '\0';
19
}

von Joe F. (easylife)


Lesenswert?

Ja, super Lösung.
Es sind immer noch alle Fehler drin, auf die man dich hinweist, aber du 
ignorierst das einfach.
Die Delays sorgen lediglich dafür, dass es unwahrscheinlicher wird, dass 
sich dein Programm in der while Schleife aufhängt, da c weniger 
wahrscheinlich den Wert UART_NO_DATA annimmt.
Ist mir echt zu doof jetzt. Good luck.

von Philipp P. (Gast)


Angehängte Dateien:

Lesenswert?

Sry, wollte dich nicht verärgern und das soll auch keine Lösung sein!
Ich habs nochmal umgeschrieben ein, zweimal funktioniert es und dann 
hängt er sich wieder auf beim Schleifen austritt -.-

von Joe F. (easylife)


Lesenswert?

include file?

von Philipp P. (Gast)


Angehängte Dateien:

Lesenswert?

hier die includefile

von Joe F. (easylife)


Lesenswert?

Tja, also deine Arraygrößen stimmen jetzt, und die while() Schleife 
dürfte nicht mehr hängen.

In c steht nach der Schleife natürlich immer 254, insofern macht die 
nachfolgende switch/case struktur (noch) keinen Sinn, aber das Programm 
sollte zumindest stabil in der for(;;) Schleife sein.

Ich denke, es wird Zeit, dass du deinen Debugger kennenlernst, um 
herauszufinden, an welcher Zeile des Programmes der Absturz genau 
passiert.

Evtl. ist es auch gar nicht die Software, sondern du erzeugst durch 
irgend einen Output einen starken Strommpuls auf der 
Versorgungsspannung, und der Controller resettet deswegen...

: Bearbeitet durch User
von Philipp P. (Gast)


Lesenswert?

Danke nochmal für die Hilfestellung:) Ja, das mit dem Stromimpuls dacht 
ich mir auch schon, aber das einzige was am MC angeschlossen ist, sind 3 
I2C Chips das Display und der UART.
Dann werde ich mir die Tage mal einen AVR Dragon bestellen...

MfG Philipp P.

von Philipp P. (Gast)


Lesenswert?

Kann es sein das UART_NO_DATA zu spät, oder nicht dirkt den Wert zurück 
gibt ob neue Daten vorhanden sind? So bleibt er in der while Schleife 
und erfüllt die if Bedingung und treibt ci in die Höhe und läuft dann 
über?
1
ci = 0;
2
c = uart_getc();
3
if( c != UART_NO_DATA  && c == 250){          //Startbedingung für alle Eingehenden Daten, 
4
//wenn 250 gesendet wird und Daten vorhanden
5
  
6
   
7
while( c != 254 ){
8
// Lese solange, bis von der anderen 
9
//Seite 254 als Endbedingung kommt!
10
c = uart_getc();
11
if(c != UART_NO_DATA && ci < 21) {
12
command[ci++] = c;
13
uart_putc(c); // überprüfen am terminal
14
15
         }
16
     
17
        }
18
19
    command[ci] = '\0';
20
    }

So geht er in die Schleife und wieder raus, sendet aber nichts über 
Uart.

von Joe F. (easylife)


Angehängte Dateien:

Lesenswert?

Philipp P. schrieb:
> Kann es sein das UART_NO_DATA zu spät, oder nicht dirkt den Wert zurück
> gibt ob neue Daten vorhanden sind?

Das ist eine sehr abenteuerliche Theorie...
Der Fehler liegt mit Sicherheit an ganz anderer Stelle.

Um ein Problem einzugrenzen geht man üblicherweise folgendermaßen vor:
Grenze Stück für Stück ein, wo das Problem liegt.
Dazu kommentierst du z.B. mal allen Code aus, der mit dem Display 
kommuniziert, allen I2C code, und testest lediglich den UART code.
Wenn da kein Problem ist, kommentierst du den UART code aus, und testest 
den Display Code. Wenn der noch funktioniert, dann testest du die I2C 
Teile.

Damit du uns nicht immer mit vollkommen sinnfrei formatiertem Code 
(Einrückungen) das Lesen schwer machst, habe ich dir als Service deinen 
Code mal durch einen Formatter gejagt, und die Zeilen des sehr 
unsinnigen include files direkt in die .c Datei integriert.

von neuer PIC Freund (Gast)


Lesenswert?

command[21] = '\0';

schreddert dir irgendwas.

von Philipp P. (Gast)


Angehängte Dateien:

Lesenswert?

So habe vorhind mir ci mal ausgeben lassen NACHDEM die Schleife 
verlassen wurde. Er zählt ci kontinuirlich hoch, mit delays langsamer. 
Mit ci<21 verhindere ich, das er in der if abfrage weiter hoch zählt und 
sich dann aufhängt.

Nun frage ich nur UART_NO_DATA ab und die bleibt immer 0. Die Abfrage 
schaltet mir eine LED an und aus die am PCF hängt. Normal müsste die LED 
doch angehen wenn uart_getc keine neuen Daten bekommt?

Danke fürs formatieren ;)

von Joe F. (easylife)


Lesenswert?

ci<21
ist übrigens nicht ausreichend, denn das array ist 21 Einträge groß 
(0..20), d.h. hier:
command[ci] = '\0';
kracht's dann potentiell.

Philipp P. schrieb:
> Nun frage ich nur UART_NO_DATA ab und die bleibt immer 0. Die Abfrage
> schaltet mir eine LED an und aus die am PCF hängt. Normal müsste die LED
> doch angehen wenn uart_getc keine neuen Daten bekommt?

2 mögliche Gründe:
du nutzt eine andere/alte library version, die bei uart_getc() blockt,
oder der code für die LED funktioniert nicht.

Philipp P. schrieb:
> Danke fürs formatieren ;)

Ja, gerne. Du bist allerdings auch echt krass. Jetzt bekommst du 
formatierten Code, und schreibst deine Änderungen wieder mit genau der 
gleichen schluderigen Art wie zuvor da rein. Ich werde deinen Code nicht 
nochmal formatieren...

von Philipp P. (Gast)


Lesenswert?

Oh ja, vergrößer ich. Wenn ich die Abfrage mit (!( c & UART_NO_DATA)) 
negiere, leuchtet die LED... Hab mir gerade nochmal die aktuelle Lib 
runtergelden, alte gelöscht und neue rein gemacht. Muss ich in der Lib 
noch etwas eintragen?

von Joe F. (easylife)


Lesenswert?

achso.
1
unsigned char c;          //uart char

so kann das ja nicht gehen. Die Error-Flags sind in den oberen 8 bit.
uart_getc liefert einen "unsigned int" zurück.
1
unsigned int c;          //uart char + error flags

von Joe F. (easylife)


Lesenswert?

Und jetzt ist auch klar wo die Memory Corruption herkam.
UART_NO_DATA wurde in der while Schleife nie geprüft, und zusammen mit 
der fehlenden Begrenzung für ci wurde munter Speicher überschrieben.
Den Test, ob ein Zeichen gültig ist, würde ich übrigens nicht mit
1
if(c != UART_NO_DATA && ci < 20) {
machen, sondern mit
1
if( !(c & 0x0f00) && (ci<20) ) {
Damit reagierst du auf alle Fehler.

von MWS (Gast)


Lesenswert?

Joe F. schrieb:
> Ja, gerne. Du bist allerdings auch echt krass.

Nicht nur krass, der Herr fährt auch zweispurig, ohne es das jeweils 
andere Forum wissen zu lassen:
http://www.roboternetz.de/community/threads/66539-Uart-while-schleife-führt-zu-absturz
Ist einfach mieser Stil, mehrere Foren zu beschäftigen, anstatt die 
Birne anzustrengen und bei einem zu bleiben.

von Philipp P. (Gast)


Lesenswert?

Tatsache so funktionierts und UART_NO_DATA schaltet um und ci zählt 
immer um 1 pro empfangenem Byte hoch. Ganz großes Kino^^
Vielen Vielen Dank

Ich meine iwo im Forum gelesen zu haben das c ein unsigned char sein 
muss,
da sonst uart_getc() nicht richtig funktioniert..
1
if (!(c & UART_NO_DATA)) {          //Startbedingung für alle Eingehenden Daten, 
2
wenn 250 gesendet wird und Daten vorhanden
3
      
4
while( c != 254 ) {
5
// Lese solange, bis von der anderen 
6
Seite 254 als Endbedingung kommt!
7
c = uart_getc();
8
9
if(!(c & UART_NO_DATA )) {
10
command[ci++] = c;
11
uart_putc(c);
12
uart_putc(ci);
13
pcf_set(0);
14
}
15
else{
16
pcf_clear(0);
17
          
18
}
19
command[ci] = '\0';
20
}
21
}

von chris (Gast)


Lesenswert?

Philipp P. schrieb:
> Ich meine iwo im Forum gelesen zu haben das c ein unsigned char sein
> muss,
> da sonst uart_getc() nicht richtig funktioniert..

Bei Peter Fleurys UART-Lib ist doch extra ein Codebeispiel dabei, das 
die korrekte Verwendung zeigt.
Und mit ein bisschen Verständnis für die Lib (und das Verständnis 
sollte man sich aneignen), ist das auch klar, dass das ein uint16 sein 
muss

von Joe F. (easylife)


Lesenswert?

Na denn.

MWS schrieb:
> der Herr fährt auch zweispurig, ohne es das jeweils
> andere Forum wissen zu lassen

Kann er ja machen, ich habe auch mehrere Rechtsanwälte ;-)

@Philipp P.
Trauriger finde ich, dass bei dir eine ziemlich ausgeprägte 
Lernverweigerung zu erkennen ist.
Code formatieren heisst jetzt "ich schiebe einfach alles ganz nach 
links", und ci auf Array-Größe testen fliegt wieder raus. Geht ja 
jetzt...

von Philipp P. (Gast)


Lesenswert?

MWS schrieb:
> Joe F. schrieb:
>> Ja, gerne. Du bist allerdings auch echt krass.
>
> Nicht nur krass, der Herr fährt auch zweispurig, ohne es das jeweils
> andere Forum wissen zu lassen:
> http://www.roboternetz.de/community/threads/66539-...
> Ist einfach mieser Stil, mehrere Foren zu beschäftigen, anstatt die
> Birne anzustrengen und bei einem zu bleiben.

Ja, ich habe vorhind noch in einem anderem Forum gefragt und werde dort 
auch gerne berichten das mir hier sehr gut geholfen wurde.
Und ja ich habe meine Birne angestrengt nur wenn ich nicht weiter weiß 
und den Fehler nicht finde wende ich mich an ein Forum.
Ich denke es ist jedem selbst überlassen zu helfen und wenn meine sich 
meine Programmierkünste verbessert haben bin ich auch bereit anderen zu 
helfen...

C ist Neuland für mich. Trotz fast täglichem lesen und einarbeiten macht 
man da halt Fehler und ist für jede Hilfe Dankbar....

MfG Philipp

von Joe F. (easylife)


Lesenswert?

Philipp P. schrieb:
> Und ja ich habe meine Birne angestrengt nur wenn ich nicht weiter weiß
> und den Fehler nicht finde wende ich mich an ein Forum.
> Ich denke es ist jedem selbst überlassen zu helfen und wenn meine sich
> meine Programmierkünste verbessert haben bin ich auch bereit anderen zu
> helfen...

Richtige Einstellung.
Tip: Bestelle dir trotzdem den Debugger, der wird dir das Leben um 
einiges erleichtern.

von MWS (Gast)


Lesenswert?

Joe F. schrieb:
> Kann er ja machen, ich habe auch mehrere Rechtsanwälte ;-)

Die bezahlst Du auch (sinnvollerweise), freiwillige Helfer werden nicht 
bezahlt, deren Lohn ist bestenfalls ein gewisses Erfolgserlebnis. Das 
nimmt denen aber derjenige, der ohne es allen mitzuteilen, gleich 
mehrere Foren beschäftigt.

> @Philipp P.
> Trauriger finde ich, dass bei dir eine ziemlich ausgeprägte
> Lernverweigerung zu erkennen ist.
> Code formatieren heisst jetzt "ich schiebe einfach alles ganz nach
> links", und ci auf Array-Größe testen fliegt wieder raus. Geht ja
> jetzt...

Das konnte ich schon oft beobachten: diejenigen, die gleich einen ganzen 
Schwung Foren beschäftigten, also versuchten rücksichtslos eigenes Hirn 
durch copy/paste zu ersetzen, zeigten sich meist auch in jeglicher 
anderer Hinsicht rücksichtslos und verständnisbefreit.

von MWS (Gast)


Lesenswert?

Philipp P. schrieb:
> und den Fehler nicht finde wende ich mich an ein Forum.

Du hast Dich nicht an ein, sondern mehrere gewandt.

> Ich denke es ist jedem selbst überlassen zu helfen und wenn meine sich
> meine Programmierkünste verbessert haben bin ich auch bereit anderen zu
> helfen...

Das wäre richtig, wenn Du die Fairness besessen hättest, es dem jeweilig 
anderen Forum zu sagen. Denn dann kann jeder überlegen, ob er Dir helfen 
will, oder lieber wartet, ob woanders bereis ein Ergebnis rauskommt.

von Philipp P. (Gast)


Angehängte Dateien:

Lesenswert?

Joe F. schrieb:


> @Philipp P.
> Trauriger finde ich, dass bei dir eine ziemlich ausgeprägte
> Lernverweigerung zu erkennen ist.
> Code formatieren heisst jetzt "ich schiebe einfach alles ganz nach
> links", und ci auf Array-Größe testen fliegt wieder raus. Geht ja
> jetzt...

Um die formatierung kümmere ich mich morgen noch ;)
ci wird jetzt hoffentlich richtig abgefragt.

von Karl H. (kbuchegg)


Lesenswert?

Philipp P. schrieb:

> Um die formatierung kümmere ich mich morgen noch ;)

Falscher Ansatz.
Um Formatierungen kümmert man sich gleich. Denn Formatierungen helfen 
dir, unsinnigen Code zu erkennen. Genau die Sorte Codefehler, die du 
oben hattest. Denn wie soll sich denn der Abfrage Wert in der while 
Bedingung ändern, wenn gar keine Funktion aufgerufen wird, die ihn 
ändern könnte, weil der entsprechende Aufruf gar nicht erfolgt? Eine 
saubere Einrückung zeigt dir das.

Das hier
1
      while( c != 254 && ci < 20 ) {

formulierst du besser so
1
      while( c != 254 && ci < sizeof( command ) - 1 ) {

denn dann bist du die lästige Abhängigkeit dieser ominösen 20 von der 
Grösse des Arrays los, bzw. der Compiler kümmert sich darum, dass die 
Werte zusammenstimmen, wenn du die Größe des Arrays veränderst.

Deine ganze Abfragerei der erhaltenen Werte lässt sich auch so 
zusammenfassen
1
   if( c >= 0x32 && c <= 0x39 )
2
     pcf_set( c - 0x32 );
3
4
   if( c >= 0x40 && c <= 0x47 )
5
     pcf_clear( c - 0x40 );

Deine switch-case Lösung ist an sich nicht falsch, aber gegenüber dem 4 
Zeiler da oben recht geschwätzig und beim Tippen bzw. Copy/Paste auch 
recht fehleranfällig, da man beim Copy/Paste gerne mal vergisst, 
irgendeine der kritischen Zahlenwerte anzupassen.
Das ist das eine. Das andere ist, dass es da einen Zusammenhang gibt, 
zwischen dem gesendeten Kommando und dem zu schaltenden pcf. Der 4 
Zeiler zeigt diesen numerischen Zusammenhang viel besser als dein 
switch/case Konstrukt, bei dem man erst mal Zahlenwerte vergleichen muss 
um den Zusammenhang zu erkennen. Derartige Zusammenhänge sind auch oft 
einfache Regeln, die man sich gut merken kann. Anstatt 14 Wertpärchen 
braucht sich der Programmierer nur 2 einfache Regeln merken, wenn er den 
Datenfluss durch das Programm verfolgt.

: Bearbeitet durch User
von Joe F. (easylife)


Lesenswert?

Man müsste zusätzlich aber auch noch dafür sorgen, dass in "c" zum 
passenden Zeitpunkt etwas anderes drin steht als 254...

: Bearbeitet durch User
von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Philipp P. schrieb:
> Um die formatierung kümmere ich mich morgen noch ;)

Solch einen unformatierten Code hier hinzurotzen ist nur ein Zeichen 
mangelnden Respekts vor den Leuten, die bereit sind, Dir unentgeltlich 
zu helfen. Und den Programmcode, den jemand für Dich formatiert hat, 
erneut zu verunstalten, ist eine ganz massive Beleidigung.

Die korrekte Formatierung von Programmcode dient nicht dazu, das ganze 
nach Abschluss der Implementierung hübsch zu machen, sondern ist ein 
ganz wichtiges Instrument, Fehler frühzeitig zu erkennen.

Um Codeformatierung zu erlernen, solltest mal etwas in Python 
programmieren.

: Bearbeitet durch User
von Rolf Magnus (Gast)


Lesenswert?

Karl Heinz schrieb:
> formulierst du besser so
>      while( c != 254 && ci < sizeof( command ) > - 1 ) {

Ich würde auch die magische 254 da weghaben wollen und stattdessen ein 
Makro verwenden:
1
#define START  250
2
#define ENDE   254
3
//...
1
    while( c != ENDE && ci < sizeof( command ) > - 1 ) {

von Markus F. (mfro)


Lesenswert?

Rolf Magnus schrieb:
> while( c != ENDE && ci < sizeof( command ) > - 1 ) {

???

Jetzt hast Du's verhunzt.

--> while( c != ENDE && ci < sizeof( command ) - 1 ) {

von Rolf Magnus (Gast)


Lesenswert?

Markus F. schrieb:
> ???
>
> Jetzt hast Du's verhunzt.

lol... Ich hatte zuerst den Originaltext zitiert und dann angepasst. 
Dabei gab's einen Zeilenumbruch. Das reine Zitat sah so aus:

Karl Heinz schrieb:
> formulierst du besser so      while( c != 254 && ci < sizeof( command )
> - 1 ) {

Das '>' ist versehentlich drin geblieben.

von Philipp P. (Gast)


Angehängte Dateien:

Lesenswert?

Joe F. schrieb:
> Man müsste zusätzlich aber auch noch dafür sorgen, dass in "c" zum
> passenden Zeitpunkt etwas anderes drin steht als 254...

Was meinst du damit? Die 254 kann ruhig in dem Array stehen bleiben.
Ich habe meine wirren Code stellen mal durch einen source code formatter 
geschickt, ich hoffe jetzt siehts besser aus.

Karl Heinz schrieb:

> Deine ganze Abfragerei der erhaltenen Werte lässt sich auch so
> zusammenfassen
>    if( c >= 0x32 && c <= 0x39 )
>      pcf_set( c - 0x32 );
>
>    if( c >= 0x40 && c <= 0x47 )
>      pcf_clear( c - 0x40 );

Das is der Knaller da wär ich nie drauf gekommen das es so einfach zu 
formulieren ist ;)

Danke für die Hilfestellungen und Tipps.

MfG

von Joe F. (easylife)


Lesenswert?

Überlege einfach mal, welchen Inhalt die Variable "c" nach dem Verlassen 
der while Schleife hat...

von Philipp P. (Gast)


Lesenswert?

Joe F. schrieb:
> Überlege einfach mal, welchen Inhalt die Variable "c" nach dem
> Verlassen
> der while Schleife hat...

Wenn er die Schleife durch 254 verlässt steht in c die 254 solange bis 
er wieder die uart_getc() aufruft. Jedenfalls gibt er mir so c nach der 
Schleife aus.

MfG Philipp

von Joe F. (easylife)


Lesenswert?

So ist es. Findste gut so?

von Philipp P. (Gast)


Lesenswert?

Joe F. schrieb:
> So ist es. Findste gut so?

Wo drauf möchtest du hinaus? Bis zum nächsten Aufruf kann das c doch 
ruhig 254 bleiben? In dem command Array sollte es nicht stören oder wird 
c vorher nochmal abgefragt? Ich könnte es nach der Schleife 0 setzen?

von Joe F. (easylife)


Lesenswert?

oh mann.
wie sollen denn die Vergleiche nach der while Schleife, oder auch ein 
select auf c funktionieren, wenn c immer 254 enthält?
1
if( c >= 0x32 && c <= 0x39 )
2
(...)

von Philipp P. (Gast)


Lesenswert?

Achso das stimmt. Gar nicht mehr gesehen..^^ Das werde ich sowieso noch 
anpassen müssen.


MfG Philipp P.

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.