"-=" Will nur einmal, aber nicht 3 mal.

Gast #3213811
Hallo, ich habe mit folgender Codesequenz ein Problem:
1
          if(pulse_led[i].r_last != 0) pulse_led[i].r_last -= 1;   
2
          if(pulse_led[i].g_last != 0) pulse_led[i].g_last -= 1;
3
          if(pulse_led[i].b_last != 0) pulse_led[i].b_last -= 1;

Wenn r = 0, g = 0 und b > 0 ist, funktioniert das ganze Problemlos.
Wenn jetzt aber r = 0 g > 0 und b = 0 ist will das ganze Nicht mehr ( 
Das ... -= 1; um genauer zu sein).
Das Lustige ist, wenn ich den Code Debugge und die Zeile
1
          if(pulse_led[i].r_last != 0) pulse_led[i].r_last -= 1;
in
1
          if(pulse_led[i].r_last != 0) {
2
             pulse_led[i].r_last -= 1;
3
             serial.printf("%d", pulse_led[i].r_last);
4
          }
ändere, bleibt der Wert von pulse_led... konstant.

Woran könnte das liegen?

MfG
Gast #3213840
Das ganze Programm ist ein bisschen zu lang.
Prozessor ist ATMega328p
Der Variablen Typ in dem Fall ist uint8_t, spricht Wertebereich von 0 - 
255.
#3213842
Was gebnau funktioniert wann nicht mehr? Die Testausgabe oben ist 
sinnlos, da deiner Aussage nach ja im nicht funktionierenden Fall r==0 
ist.

Ansonsten erzeuten Assembler Code angucken. Welcher Compiler überhaupt, 
welches Zielsystem?
Gast #3213848
Das ganze Programm ist ein bisschen zu lang.
Prozessor ist ATMega328p
Der Variablen Typ in dem Fall ist uint8_t, spricht Wertebereich von 0 - 
255.

>;->>> schrieb:
> konstant auf 0 >;->>>

Nein, bspw. auf 127 ;)

Die Definition von pulse_led ist ein Struct:
1
typedef struct {
2
  uint8_t r, g, b;
3
  uint8_t speed; // 0 = slow 1 = normal 2 = fast
4
  uint8_t r_last, g_last, b_last;
5
  bool up;
6
  uint32_t lasttime;
7
} 
8
pulse;
Gast #3213864
Du testest in deiner if-Abfrage immer r_last, g_last und
b_last.

Kann es sein, dass die Dinger im Fall von  r = 0 g > 0 und b = 0 nicht 
richtig aktualisiert werden, um !=0 in der If-Bedingung zu sein ???
Gast #3213865
whatsmyname? schrieb:
> Das ganze Programm ist ein bisschen zu lang.

Schon wieder so ein "ich lasse es mir langsam aus der Nase ziehen" 
Beitrag. Am Ende ist es wieder eine übersehene Zuweisung oder anderer 
Fehler des Programmieres.

Also her mit dem vollständigen Code! Und zwar schnelle! :-)))
Gast #3213921
Klaus schrieb:
> Torsten C. schrieb:
>> also um Compiler-Fehler auszuschließen?
> DAS macht man als allerletztes. Gerade als Anfänger!

das ist doch Unsinn, als Anfänger erzeugt mal zu 99.9% den Fehler 
selber. Die Optimierung anzuschalten, führt dann zu fragen warum delay 
nicht stimmt.
Gast #3213991
Wowww, das Programm ist nicht groß sondern strange. ;->

Dir geht es um die Funktion led_pulse():
1
      switch (pulse_led[i].speed) {
2
      ...
3
      default:
4
        break;
auch bei default sollte wait gesetzt werden oder eine Fehlerroutine 
angesprungen werden.

Setze deine Ausgabe
1
serial.printf("%d", pulse_led[i].r_last);
2
serial.printf("%d", pulse_led[i].g_last);
3
serial.printf("%d", pulse_led[i].b_last);
an das Ende der for Schleife.
#3214309
volatile!

leo@cb:/tmp/sketch_jun22a$ grep led_pulse *
handle_threads.ino:    led_pulse();
led_funcs.ino:void led_pulse() {
leo@cb:/tmp/sketch_jun22a$ grep handle_timer1_interrupt *
handle_threads.ino:void handle_timer1_interrupt() {
sketch_jun22a.ino:  Timer1.attachInterrupt(handle_timer1_interrupt);
leo@cb:/tmp/sketch_jun22a$
Gast #3214346
@ThatsYourName

Ich habe wirklich keine Lust mich in Dein System und Deinen Code 
einzuarbeiten, aber Du zeigst da 3 Zeilen, die praktisch unabhängig von 
einander sind.
In diesem Falle gilt: Geht eine, gehen alle.

Wenn nicht gerade Deine Indizes (i) ausflippen, oder Du an anderer 
Stelle zu großzügig mit dem Speicher umgegangen bist, müsste das Ganz 
auch gehen.

Gibt Dein Compiler am Ende nicht eine Speicherbelegung aus?

Wenn das alles in Ordnung ist, liegt der Fehler an anderer Stelle.
Gast #3214363
Vlad Tepesch schrieb:
> klingt nach einem typischen volatile-vergessen-Fehler.

glaube ich nicht. Bei diesen 3 Zeilen ist es egal on der wert in einem 
Register zwischengespeichert wird oder nicht. Nach dem -=1 muss der Wert 
um ein kleiner sein. Wenn er jetzt ein volatile verwendet dann kann eine 
ISR den wert wieder um eins erhöhen. Ohne volatile kann das aber nicht 
passieren.
#3214380
Ist es auch nicht.
Das ganze wird aus einem Interrupt heraus aufgerufen.

Allerdings ist die ganze Interrupt Logik mit mehreren Tasks und 
gleichzeitigm UART Handling etwas 'verquert' und die UART Auswert ist 
komplett hinüber, so dass ich nicht ausschliessen möchte, dass er sich 
mit dem UART Handling die Variablenwerte zerschiesst.

Da ist wieder mal die Annahme, dass wenn man in der UART einen read() 
aufruft, dann kommt da irgendwie alles was die Gegenstelle schickt in 
einem Rutsch daher.
Pustekuchen
1
void update_serial() {
2
  uart_rec="";
3
  while(uart.available()) {
4
    uart_rec += (char)uart.read();
5
  }
6
}
7

8
void evaluate_serial_input() {
9

10
  String tmpstring0 = "";
11
  uint8_t cnum = 0;
12

13
  if(uart_rec != "") {
14
    // Detect ',' in received string
15
    for(int i = 0; i < uart_rec.length(); i++) {
16
      char 
17
      if(  ',') cnum++;
18
    }
19

20
  ....

eben das leidige Problem, dass Anfänger erst mal lernen müssen, was 
eigentlich ein Protokoll ist und wozu es dient, bzw. wie man sowas 
auswertet, das es unabdingbar ist, dass man mit der Gegenstelle eine 
End-Of-Message Kennung vereinbart, die dann auch ausgewertet werden muss 
und erst dann gilt eine Message als komplett übertragen, so dass man 
nicht 'noch nicht übertragene' Daten als gültig ansieht und mit denen 
arbeitet etc. etc.


Edit: Ich bin mir recht sicher, dass das eigentliche Problem irgendwo in 
diesem Bereich passiert. Den ganzen UART/Protokoll Teil müsste man neu 
machen. Das ist alles nicht tragfähig - und warum der UART Teil da in 
der Timer-Interrupt-Task-Scheduling Sache mit drinn hängen muss, ist mir 
auch nicht klar. Da würde ich erst mal ansetzen. Es gibt keinen Grund, 
warum der UART Teil da so verquert in die Timer-Interrupt Logik mit 
reingenommen werden muss. Die UART Abfrage bzw. Auswertung kann 
wunderbar in der Hauptschleife loop() bleiben. Aber als allererstes muss 
da mal ein die Übertragung steuerndes Protokoll mit einer Form der 
Message-Endekennung her.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 13 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.