Forum: Mikrocontroller und Digitale Elektronik Zeitverzögerung bei serieller Kommunikation


von Dirk B. (Gast)


Lesenswert?

Hallo,
ich habe mittels Node-red eine Verbindung zu einem Controllino (Arduino) 
hergestellt, um von dort Signale an den Arduino zu senden, die dann 
jeweils unterschiedliche Switch case Anweisungen auslösen. (bsp case 1: 
PIN 1000 ms HIGH 100 ms LOW , case 2: 1000 HIGH 300 LOW usw). Das 
funktioniert soweit auch sehr zufriedenstellend. Wenn ich jedoch über 
Node-Red das Signal gebe, dass ein anderer case ausgeführt werden soll, 
dauert es ca. 1 sek bis der Arduino die Änderung realisiert. Bsp( case 1 
ist aktiv, der PIN ist 1 sek HIGH und dann 100 ms LOW. Jetzt gebe ich 
über Node-Red das Signal zum umschalten in case 2. Es dauert dann ca. 
1,5 sek. bis der Änderung aktiv wird und der Arduino mit 1000HIGH und 
300LOW pulst. In der Zwischenzeit scheint der PIN Low zu sein. Meine 
Frage: Gibt es eine Möglichkeit diese "Zwischenzeit auf ein nicht 
merkbares Minimum zu reduzieren ?
Anbei der Arduino Code.
Gruß Dirk
1
#include <Controllino.h>
2
long strVar;
3
4
void setup() 
5
{
6
 pinMode(CONTROLLINO_D1, OUTPUT);
7
 Serial.begin(9600);
8
}
9
10
11
12
void loop() 
13
14
{
15
if(Serial.available())
16
{
17
strVar=Serial.parseInt();
18
}
19
 
20
   switch(strVar)
21
   {
22
    case 1:
23
    do 
24
    {
25
      digitalWrite(CONTROLLINO_D1, HIGH);     //Lastfall 1: sehr hoch 
26
      delay(1000);
27
      digitalWrite(CONTROLLINO_D1, LOW);
28
      delay(100);
29
    }while(strVar==0);
30
    break;
31
32
    case 2:
33
    do
34
    {
35
    
36
    digitalWrite(CONTROLLINO_D1, HIGH);         // Lastfall 2: hoch
37
    delay(1000);
38
    digitalWrite(CONTROLLINO_D1, LOW);
39
    delay(300);
40
    }
41
    while(strVar==0);
42
      break;
43
44
    case 3:
45
    do
46
    {
47
    
48
    digitalWrite(CONTROLLINO_D1, HIGH);         // Lastfall 3: mittel
49
    delay(1000);
50
    digitalWrite(CONTROLLINO_D1, LOW);
51
    delay(500);
52
    }
53
    while(strVar==0);
54
      break;
55
56
57
    case 4:
58
    do
59
    {
60
    
61
    digitalWrite(CONTROLLINO_D1, HIGH);         // Lastfall 4: niedrig
62
    delay(1000);
63
    digitalWrite(CONTROLLINO_D1, LOW);
64
    delay(700);
65
    }
66
    while(strVar==0);
67
      break;
68
69
    case 5:
70
    do
71
    {
72
    
73
    digitalWrite(CONTROLLINO_D1, HIGH);         // Lastfall 5: sehr niedrig
74
    delay(1000);
75
    digitalWrite(CONTROLLINO_D1, LOW);
76
    delay(2000);
77
    }
78
    while(strVar==0);
79
      break;
80
   }
81
   }

: Bearbeitet durch Moderator
von Kevin M. (arduinolover)


Lesenswert?

Code Formatieren ist eindeutig eine Wissenschaft.

Du hast in jedem Case zwei Delays die den Code Blockieren. In der Zeit 
tut er eben garnichts.

von Dirk B. (Gast)


Lesenswert?

Auch wenn ich einen Test Code ohne Delay (also einfach nur HIGH bzw LOW 
schalten ) hochlade kommt es zu einer Zeit Verzögerung beim Umschalten 
von HIGH auf LOW.

von Peter D. (peda)


Lesenswert?

Du solltest den Code auch mal gedanklich durchgehen. Wenn da im Case 
steht, 1,1s warten, dann wartet er eben 1,1s.
Die "while(strVar==0);" sind sinnlos, da strVar in der Schleife nie 
geändert wird.

Dirk B. schrieb:
> Gibt es eine Möglichkeit diese "Zwischenzeit auf ein nicht
> merkbares Minimum zu reduzieren ?

Sogar mehrere.
Man kann einen Scheduler nehmen, wo man entsprechende Callbacks 
einstellt.
Oder man macht ein festes Delay von z.B. 10ms in der Schleife und 
Zählvariablen, die man je nach Case auf n*10ms setzt.

Statt ner Unmenge an Case würde man in der Praxis ein einzelnes Kommando 
definieren, dem man 2 Argumente (T_on, T_off) übergibt und mit sscanf 
direkt in die Variablen einliest.

von J. V. (janvi)


Lesenswert?

node red im Speziellen und Ethernet im Allgemeinen hat kein Echtzeit 
Verhalten

von Dirk B. (Gast)


Lesenswert?

Peter D. schrieb:
> Die "while(strVar==0);" sind sinnlos, da strVar in der Schleife nie
> geändert wird.
Die While(strVar==0) Bedingung benötige ich das die  Schleife in 
Dauerschleife läuft, solange das Triggersignal sich nicht ändert.

Muss mir mal anschauen wie das mit dem Scheduler funktioniert. Danke für 
den Tipp.
Gruß Dirk

von Dirk B. (Gast)


Lesenswert?

J. V. schrieb:
> Ethernet im Allgemeinen hat kein Echtzeit
> Verhalten

Die Kommunikation erfolgt über ein USB Kabel

von Peter D. (peda)


Lesenswert?

Dirk B. schrieb:
> Die While(strVar==0) Bedingung benötige ich das die  Schleife in
> Dauerschleife läuft, solange das Triggersignal sich nicht ändert.

Nö.
Da Du case 0 nicht auswertest, ist strVar immer != 0.
Und damit ist das while sinnlos, es wird immer verlassen.

von Imperia (Gast)


Lesenswert?

Dirk B. schrieb:
> Ethernet im Allgemeinen hat kein Echtzeit
>> Verhalten
>
> Die Kommunikation erfolgt über ein USB Kabel

Dann gilt es auch für ein USB Kabel, samt der darüber liegenden 
Protokolle.

von Pandur S. (jetztnicht)


Lesenswert?

Es gibt die Verzoegerung des Kabels, wlche in diesem Fall 
vernachlaessigbar ist. Dann die Verzuegerung des Mediums, Seriell, mit 
Bit/sek, Des Betriebsystems, usw.
Allenfalls muss man die ausfuehrende Intelligenz verlagern. Anstelle von 
2 Commands fuer Ein & Aus zu senden, kann man allenfalls auch 
puls(laenge) senden, welches dann am anderen Ende ausgefuehrt wird.

von Wolfgang (Gast)


Lesenswert?

Dirk B. schrieb:
> Meine Frage: Gibt es eine Möglichkeit diese "Zwischenzeit auf ein nicht
> merkbares Minimum zu reduzieren ?

Bevor du die Zeit reduzieren kannst, musst du erstmal feststellen, wer 
dafür verantwortlich ist:
1. Node Red Overhead
2. Controllino
3. zeitweise Taubheit des Arduino durch delay()

Miss erstmal die Zeit zwischen Node Red Kommando und Eintreffen an der 
seriellen Schnittstelle des Arduino und die Zeit zwischen Eintreffen an 
der seriellen Schnittstelle bis zum Pin-Wackeln. Dann weißt du, wo deine 
Baustelle ist.
Du könntest dir auch die Funktion yield() mal ansehen. "Endlose" 
delay()-Blockaden sind nie förderlich.

Beitrag #6825524 wurde von einem Moderator gelöscht.
von Harry L. (mysth)


Lesenswert?

Delays sind grundsätzlich Mist!
Beschäftige dich mit StateMachines!
https://www.mikrocontroller.net/articles/Statemachine

von Prokrastinator (Gast)


Lesenswert?

Dirk B. schrieb:
> Auch wenn ich einen Test Code ohne Delay (also einfach nur HIGH bzw LOW
> schalten ) hochlade kommt es zu einer Zeit Verzögerung beim Umschalten
> von HIGH auf LOW.

digitalWrite ist eine arschlangsame Funktion, die eine schier 
unglaubliche Zeit mit sich selbst beschäftigt ist, bevor die was macht.
Ich glaube 1ms habe ich mal gemessen.
Wenn es schnell gehen soll, setzt Du Deine MCU Register, wie sie sein 
sollen und schreibst dann direkt ins Ausgangsregister Deine jeweils 
aktuellen Werte, ohne wildes brimborium, das erst von der Funktion 
interpretiert werden muss, die sich dann die Register raussucht, den 
Ausgang auf Ausgang setzt, was er schon lange ist und dann mal 
irgendwann auch mit dem Pin wackelt.

Der Arduino Krams ist übersichtlich, aber alles andere als schnell.

von EAF (Gast)


Lesenswert?

Prokrastinator schrieb:
> Ich glaube 1ms habe ich mal gemessen.
Irgendwas um 100 Takte.

Da bist du weit weit weg von deinen 1ms

von Prokrastinator (Gast)


Lesenswert?

EAF schrieb:
> Irgendwas um 100 Takte.

Bei high  low  high Wechsel summiert sich das auf.
Ich finde auch 100 Takte extrem lange für einen Vorgang der in 2 Takten 
mit SBI / CBI oder dem C Pendant 'PORTB &= ~(1<<PB0);' erledigt wäre, 
wenn man mal das schnarchlangsame Framework weglassen würde.

Dirk B. schrieb:
> Gibt es eine Möglichkeit diese "Zwischenzeit auf ein nicht
> merkbares Minimum zu reduzieren ?
Also es gibt diese Möglichkeit das aufs Minimum zu senken.
Was nicht merkbar ist, ist höchst individuell zu betrachten.

Ich finde 2 Maschinenzyklen durchaus merkbar.
Ob das störend ist, hängt davon ab.

von EAF (Gast)


Lesenswert?

Prokrastinator schrieb:
> Bei high  low  high Wechsel summiert sich das auf

Mag ja sein....
Fällt hier nur nicht ins Gewicht, da die Serielle langsamer ist. Und die 
ist ja schließlich die Kommandoquelle in diesem Fall.

Für die auffällige Verzögerung dürfte
https://www.arduino.cc/reference/de/language/functions/communication/serial/parseint/
verantwortlich sein.

Die hat halt einen Timeout, und bis der zuschlägt vergeht seine Zeit.

von Dirk B. (dirkb2)


Lesenswert?

Wofür ist das jeweils 2. delay in den case da?

Danach passiert doch nichts mehr an den Signalen.
Gerade im Fall 5 wird da 2 Sekunden Nichts getan.

Und wie schon geschrieben, die while sind nutzlos.

von Wolfgang (Gast)


Lesenswert?

Prokrastinator schrieb:
> digitalWrite ist eine arschlangsame Funktion, die eine schier
> unglaubliche Zeit mit sich selbst beschäftigt ist, bevor die was macht.
> Ich glaube 1ms habe ich mal gemessen.

Da hast du dich wohl kräftig vermessen oder den uC mit einem Uhrenquarz 
betrieben. Wenn einen die Nebentätigkeiten stören und man im Code 
unabhängig vom uC-Typ bleiben möchte, bietet sich eine Variante von 
digitalWriteFast() an.

von Max (Gast)


Lesenswert?

Dirk B. schrieb:
> Wofür ist das jeweils 2. delay in den case da?
>
> Danach passiert doch nichts mehr an den Signalen.
> Gerade im Fall 5 wird da 2 Sekunden Nichts getan.

Denk da nochmal genau darüber nach. Wenn über das SerialInterface nichts 
neues ankommt, bleibt 'strVar' auf seinem alten Stand, und das Programm 
läuft in der Schleife immer wieder durch die gleiche 'case' Verzweigung 
(= blinkende LED).

> Und wie schon geschrieben, die while sind nutzlos.

Das stimme ich dir zu.

von Dirk B. (dirkb2)


Lesenswert?

Max schrieb:
> Denk da nochmal genau darüber nach.

Danke für den Zaunpfahl.

von Stefan F. (Gast)


Lesenswert?

Sowohl die Ausführzeit von digitalWrite() als auch die Verzögerungen 
durch die serielle USB Schnittstelle sind hier mit Sicherheit nicht das 
Problem. Darüber könnte man sich Gedanken machen, wenn es um Zeiten < 10 
ms geht.

von Nosnibor (Gast)


Lesenswert?

EAF schrieb:
> Prokrastinator schrieb:
>> Bei high  low  high Wechsel summiert sich das auf
>
> Mag ja sein....
> Fällt hier nur nicht ins Gewicht, da die Serielle langsamer ist. Und die
> ist ja schließlich die Kommandoquelle in diesem Fall.
>
> Für die auffällige Verzögerung dürfte
> 
https://www.arduino.cc/reference/de/language/functions/communication/serial/parseint/
> verantwortlich sein.
>
> Die hat halt einen Timeout, und bis der zuschlägt vergeht seine Zeit.
Genau das.
Einfach (falls das mit Node Red einfach geht) mal nach der Zahl noch ein 
Leerzeichen oder Newline schicken, dann sollte es schneller gehen, weil 
parseInt() dann sofort weiß, dass die Zahl vollständig ist.

von EAF (Gast)


Lesenswert?

Oder wenn es wirklich nur einstellige ASCII Zahlen sind:
1
//#include <Controllino.h>
2
3
//const byte outPin = CONTROLLINO_D1;
4
const byte outPin = 13;
5
6
unsigned long auszeit    = 0;
7
unsigned long zeitmerker = 0;
8
unsigned statusmerker    = 0;
9
10
void lastfall() // eine einfache Schrittkette
11
{
12
  switch(statusmerker)
13
  {
14
    case 0 : // Startzustand
15
      if(auszeit) // wenn ungleich Null dann starten.
16
      {
17
        Serial.println("ein");
18
        zeitmerker = millis();
19
        statusmerker++;
20
        digitalWrite(outPin, HIGH);
21
      }
22
      break;
23
    case 1 : // ein phase
24
      if(millis() - zeitmerker >= 1000)
25
      {
26
        Serial.println("aus");
27
        zeitmerker = millis();
28
        statusmerker++;
29
        digitalWrite(outPin, LOW);
30
      }
31
      break;
32
    case 2 : // aus phase
33
      if(millis() - zeitmerker >= auszeit)
34
      {
35
        Serial.println("starte");
36
        statusmerker = 0;
37
      }
38
      break;
39
  }
40
}
41
42
void serialEvent()
43
{
44
  switch(Serial.read())
45
  {
46
    case '1': auszeit =  100; break;
47
    case '2': auszeit =  300; break;
48
    case '3': auszeit =  500; break;
49
    case '4': auszeit =  700; break;
50
    case '5': auszeit = 1000; break;
51
    case 'x': auszeit =    0; break;
52
  }
53
}
54
55
56
void setup()
57
{
58
  pinMode(outPin, OUTPUT);
59
  Serial.begin(9600);
60
}
61
62
void loop()
63
{
64
  lastfall();
65
}

Habe mir mal die Freiheit genommen und der Sache noch einen x 
Ausschalter verpasst.
Zudem kann man den Automaten sicherlich noch etwas hübscher gestalten...
So ist es eine Minimallösung, ohne delay()

von Dirk B. (Gast)


Lesenswert?

EAF schrieb:
> Oder wenn es wirklich nur einstellige ASCII Zahlen sind:
> [c]



Hallo EAF,
deine Code funktioniert super! Die Reaktion des Arduino nach der Eingabe 
ist zwar noch nicht instantan aber deutlich besser und nun auf einem 
akzeptablen Niveau. Da ich noch Anfänger bin kannte ich die Funktion 
Millis() bisher noch nicht. Ich versuche jetzt noch deinen Code komplett 
nachzuvollziehen und werde zukünftig auch Millis() anstelle von delay() 
verwenden.
Vielen Dank für deine Mühe. Auch danke an die Beiträger der anderen 
Teilnehmer.
Gruß Dirk

von EAF (Gast)


Lesenswert?

Dirk B. schrieb:
> Hallo EAF,
> deine Code funktioniert super!
Ich weiß!
Und danke für die Blumen.

Dirk B. schrieb:
> Die Reaktion des Arduino nach der Eingabe
> ist zwar noch nicht instantan aber deutlich besser
Es ist die 1 Sekunde Ein-Zeit, welche nicht abgekürzt wird.
Das kann man ändern.
Ansonsten erfolgen Änderungen so instantan, wie es überhaupt möglich 
ist.

Dirk B. schrieb:
> und werde zukünftig auch Millis() anstelle von delay()
> verwenden.
Das will ich doch hoffen!

In der Arduino Welt nennt es sich das "BlinkWithoutDelay" Prinzip. Die 
IDE hat dazu auch ein Beispiel im Lieferumfang. Auch könntest du im 
Arduinoforum nach der "Nachtwächter Erklärung" suchen. Das folgt auch 
diesem Prinzip und erklärt es etwas ausführlicher.


Vorschlag für eine Ein-Zeit Abkürzung:
1
// if(millis() - zeitmerker >= 1000)
2
// ersetzen durch 
3
if(millis() - zeitmerker >= (auszeit?1000:0))

von Dirk B. (Gast)


Lesenswert?

@EAF
ja du hast recht: Der Controller reagiert nun in Echtzeit. Ein Traum :D.
Jetzt habe ich nur noch ein kleines Problem.
Node-red gibt ja den aktuellen Lastfall als einstellige ASCII Zahl 
seriell an den Controller. Ich habe die cases nun erweitert und auch die 
Einzeit variabel gestalltet.
    case '0': auszeit =  300; einzeit = 3000; break;
    case '1': auszeit =  300; einzeit = 2500; break;
    case '2': auszeit =  300; einzeit = 2000; break;
    case '3': auszeit =  400; einzeit = 1500; break;
    case '4': auszeit =  400; einzeit = 1000; break;
    case '5': auszeit =  400; einzeit = 500; break;
    case '6': auszeit =  400; einzeit = 200; break;
    case '7': auszeit =  600; einzeit = 100; break;
    case '8': auszeit =  800; einzeit = 100; break;
    case '9': auszeit =  0  ; einzeit = 0;    break;
das funktioniert auch wunderbar. Jetzt möchte ich jedoch noch 
verschiedene Lastprofile erstellen, die vom Nutzer ausgewählt und 
ebenfalls von Node-red übergeben werden.

Lastprofil 1
    case '0': auszeit =  300; einzeit = 3000; break;
    case '1': auszeit =  300; einzeit = 2500; break;
    case '2': auszeit =  300; einzeit = 2000; break;
    case '3': auszeit =  400; einzeit = 1500; break;
    case '4': auszeit =  400; einzeit = 1000; break;
    case '5': auszeit =  400; einzeit = 500; break;
    case '6': auszeit =  400; einzeit = 200; break;
    case '7': auszeit =  600; einzeit = 100; break;
    case '8': auszeit =  800; einzeit = 100; break;
    case '9': auszeit =  0  ; einzeit = 0;    break;

Lastprofil 2
    case '0': auszeit =  1000; einzeit = 4000; break;
    case '1': auszeit =  1500; einzeit = 5000; break;
    case '2': auszeit =  2000; einzeit = 6000; break;
    case '3': auszeit =  3000; einzeit = 7000; break;
    case '4': auszeit =  4000; einzeit = 8000; break;
    case '5': auszeit =  5000; einzeit = 9000; break;
    case '6': auszeit =  6000; einzeit = 10000; break;
    case '7': auszeit =  7000; einzeit = 11000; break;
    case '8': auszeit =  8000; einzeit = 12000; break;
    case '9': auszeit =  0  ; einzeit = 0;    break;

Lastprofil 3
.... usw

da ich aber nun keine eistelligen ASCII Zahlen mehr habe, ist die Frage 
wie ich das dann seriell übergeben soll ohne das mein Code wieder 
langsam wird.
Ich habe versucht die Lastprofile über serial.Readstring() als String zu 
übergeben und die "switch case" Anweisung der aus und einzeiten dann in 
einer If Schleife zu machen also

if (übergabestring==Lastprofil1)
{
switch(Serial.read())
{
case '0': auszeit =  300; einzeit = 3000; break;
    case '1': auszeit =  300; einzeit = 2500; break;
    case '2': auszeit =  300; einzeit = 2000; break;
    case '3': auszeit =  400; einzeit = 1500; break;
    case '4': auszeit =  400; einzeit = 1000; break;
    case '5': auszeit =  400; einzeit = 500; break;
    case '6': auszeit =  400; einzeit = 200; break;
    case '7': auszeit =  600; einzeit = 100; break;
    case '8': auszeit =  800; einzeit = 100; break;
    case '9': auszeit =  0  ; einzeit = 0;    break;
}

else if (übergabestring==Lastprofil2)
{
switch(Serial.read())
{
 case '0': auszeit =  1000; einzeit = 4000; break;
    case '1': auszeit =  1500; einzeit = 5000; break;
    case '2': auszeit =  2000; einzeit = 6000; break;
    case '3': auszeit =  3000; einzeit = 7000; break;
    case '4': auszeit =  4000; einzeit = 8000; break;
    case '5': auszeit =  5000; einzeit = 9000; break;
    case '6': auszeit =  6000; einzeit = 10000; break;
    case '7': auszeit =  7000; einzeit = 11000; break;
    case '8': auszeit =  8000; einzeit = 12000; break;
    case '9': auszeit =  0  ; einzeit = 0;    break;
}

das hat aber leider nicht funktioniert :( also gar nicht. Habt ihr da 
noch eine Idee wie das ansonsten machen könnte ?
danke schonmal vorab.
Gruß Dirk

von Dirk B. (dirkb2)


Lesenswert?

Da würde ich die Ein und Auszeiten in ein Array schreiben.

Wenn die Lastprofile dazu kommen als 2D-Array.
Wenn du schon struct kennst, dann Ein- und Auszeit in der struct 
zusammen fassen.

Die Lastprofile würde ich dann über Buchstaben auswählen.
Beachte, dass 'a' != 'A' ist
1
int einzeit[][10] = { {  300,  300, 300, ..., 0},  // Lastprofil 1
2
                      { 1000, 1500,      ..., 0}   // Lastprofil 2
3
                    };
(statt der Punkte die anderen Werte)

von EAF (Gast)


Lesenswert?

Dirk B. schrieb:
> Ich habe versucht die Lastprofile über serial.Readstring() als String zu
> übergeben

Wir hatten doch schon das Problem mit dem Timeout, mit welchem du dir 
unerwünschte Verzögerungen eingehandelt hast.
Und jetzt wieder? Diese Blockade deines Timings?
Nee...

Dirk B. schrieb:
> Habt ihr da
> noch eine Idee wie das ansonsten machen könnte ?
Klar!
Wenn die übertragenen Daten komplexer werden, muss auch das Protokoll 
zwischen den Maschinen die Komplexität abhandeln können!
Also: Es wird komplexer.
Wie man Parser baut, ist sein Jahrzehnten bekannt. Dazu findest du viel 
Lesestoff.

Im einfachsten Fall könntest du einen fertigen Parser, mit seinem 
Protokoll verwenden.
https://github.com/thijse/Arduino-CmdMessenger
(nur ein Beispiel)

von Bernhard S. (b_spitzer)


Lesenswert?

Wie wäre es mit parseInt? Damit kannst du jede Zahl zwischen 1 und 65535 
einlesen. Die 0 muss man ausklammern, das ist bei parseInt ein 
Rückgabewert wenn nichts erkannt wurde.
Beispiel:
1
unsigned int Zahl, Zahl_neu;
2
void loop() {
3
  if (Serial.available() > 0) {   // ein oder mehrere Zeichen empfangen??
4
    Zahl_neu = Serial.parseInt(); // gibt 0 zurück, wenn kein gültiges Zeichen empfangen wurde => stört hier
5
    if(Zahl_neu !=0) {
6
      Zahl = Zahl_neu ;            // nur übernehmen, wenn der Wert nicht 0 ist.    
7
    }
8
    Serial.print("Neue Zahl: ");
9
    Serial.println(Zahl);
10
  }
11
}

: Bearbeitet durch User
von EAF (Gast)


Lesenswert?

Bernhard S. schrieb:
> Wie wäre es mit parseInt?
Hatten wir schon...
Macht sich störendes Timeout.

von W.S. (Gast)


Lesenswert?

Dirk B. schrieb:
> (bsp case 1:
> PIN 1000 ms HIGH 100 ms LOW , case 2: 1000 HIGH 300 LOW usw)

Und danach?
Was für einen Zustand nimmt der Pin nach diesem Procedere ein?
Und wie denkst du dir den Fall, daß du noch während dieses Procedere 
eine neue Ziffer von deinem Browser oder so abschickst?

Nein, deinem Unterfangen fehlt es an Planung.
Zunächst haben all die anderen dir versucht klarzumachen, daß es eine 
doch recht störende Sache ist, wenn man einen µC zum Nichtstun für 1 
Sekunde und mehr verdonnert, indem man schlichtweg blockierend 
programmiert.

Sodann fehlt es deinem Projekt an jeglicher Synchronisation zwischen dem 
µC und dem PC. Du schickst einfach eine Ziffer auf die Reise und willst 
das dann mittels einer Integer-Empfangsroutine empfangen, ohne jegliches 
Endekennzeichen. Normalerweise sind Zahlen nicht auf nur 1 Ziffer 
beschränkt. Dabei hast du noch Glück, daß im Arduino-Zeug eine 
Zeitbegrenzung eingebaut ist, so daß dein Programm dann trotzdem eine 
passende Integer-Zahl abkriegt. Aber wer kümmert sich um den PC, der ja 
nicht von selbst riechen kann, wann denn dein Arduino mit dem zuvor 
angesagten Zeug fertig ist? Niemand.

Kurzum, schon beim kurzen Blick auf dein Vorhaben offenbaren sich eine 
ganze Reihe elementarer Fehler im System.

Ich würde so etwas anders angehen:
- nicht blockierender Empfang von Zeichen vom PC
- ebenso nicht blockierendes Senden von Zeichen zum PC
- Auflaufen von Zeichen in einer Kommandozeile und Auswertung beim 
abschließenden CRLF (oder einem Teil davon je nach OS auf dem PC)
- nicht blockierendes Abhandeln der o.g. Pulslängen-Aufträge (setzt so 
etwas wie eine Systemuhr in der Firmware oder einen freien Timer voraus)
- Senden einer Quittung beim richtigen Erkennen des Kommandos
- Senden einer Endekennung, wenn der Auftrag komplett abgearbeitet ist.

Frag mich jetzt nicht, wie man das mit einem Arduino macht. Ich 
benutze diese Dinger nicht, aber bei meinem Zeugs ist so etwas mit nur 
wenigen Zeilen Quellcode erledigt. Das ist aber sehr wahrscheinlich 
nicht kompatibel mit Arduino, posten dürfte hier nix nützen.

W.S.

von EAF (Gast)


Lesenswert?

W.S. schrieb:
> Das ist aber sehr wahrscheinlich
> nicht kompatibel mit Arduino, posten dürfte hier nix nützen.

Wie kommst du darauf?
Niemand zwingt einen das Arduino Framework zu nuten.
ASM, C und C++ stehen zu deiner vollen Verfügung.

Sein Arduino Klon/Nachbau ist mit einem ATMega2560 bestückt.

von Rainer V. (a_zip)


Lesenswert?

Auch bei bestem Wohlwollen ist das hier doch nur ein weiteres 
Paradebeispiel für dummstöpselei ohne Sinn und Verstand. Der TO benutzt 
Funktionen, die er nicht verstanden hat und die Gemeinschaft "hilft" ihm 
mit Krücken, die ihm eben auch nur helfen könnten, wenn er etwas kapiert 
hätte! So wird das eben nix...
Gruß Rainer

von Einer (Gast)


Lesenswert?

Rainer V. schrieb:
> So wird das eben nix...

Bullshit.

Genau so wird es was. Learning by doing. Fail fast fail often.

Was glaubst Du, wie meine ersten Programme vor X-Jahre waren? Heute kann 
mir keiner so schnell das Wasser reichen.

Du bist so verbohrt und verbittert, dass Du nicht mal einem jungen 
Menschen gönnst dass er schnell und unkompliziert Hilfe bekommt und 
vorwärts kommt.

Während er mit Node-Red und Arduino zwei völlig unterschiedliche Welten, 
Sprachen und Runtimes parallel lernt und Erfolge hat, bastelst Du noch 
mit der einzigen Programmiersprache rum die Du nur halbwegs kannst, und 
hast vermutlich weder selbst jemals einen Arduino benutzt geschweige 
denn verstehst Du irgend etwas von Node-Red. Wahrscheinlich hast Du noch 
nie was von Node-Red gehört.

von Wolfgang (Gast)


Lesenswert?

Dirk B. schrieb:
> das hat aber leider nicht funktioniert :( also gar nicht. Habt ihr da
> noch eine Idee wie das ansonsten machen könnte ?

Lerne draus.
Grundlegende Änderung der Anforderungen an ein Projekt kann das ganze 
Konzept kippen. Überlege dir also rechtzeitig, was das Ding können soll, 
sonst kommt schnell ein größeres Re-Design auf dich zu oder das Ganze 
wird zu üblem Flickwerk.

von Stefan F. (Gast)


Lesenswert?

Rainer V. schrieb:
> So wird das eben nix...

Die IT ist eine Wissenschaft an der viele Menschen ihr Leben lang 
gelernt und gearbeitet haben, auch einige der hiesigen Mitglieder.

Und nun kommst du (Einer) und sagst:

Einer schrieb:
> Genau so wird es was. Learning by doing.

Du hast ja Recht. Nur fühlen sich da sicher einige der alten Hasen auf 
den Schlips getreten. Es darf in ihren Augen nicht sein, dass heute 
jemand die Lebenswerke anderer in 10 Minuten mal eben schnell schluderig 
benutzt, ohne sie entsprechend zu würdigen.

Die IT ist jedoch noch ein Teenager. Zu jung um ausgereift zu sein, hält 
sich aber für viel zu wichtig und unsterblich. Den gewünschten Respekt 
bekommt sie so nicht.

von W.S. (Gast)


Lesenswert?

Einer schrieb:
> Wahrscheinlich hast Du noch
> nie was von Node-Red gehört.

Ob das nun ein Node-Red oder ein Node-Blues ist, kann hier eigentlich 
egal sein. Ich geb dir mal ein Beipiel:

Kapitän zum Matrose: "Segel setzen"
Matrose zum Kapitän: "Ay, ay, Sir"
Matrose rennt davon, um das Segel zu setzen
Matrose kommt zurück
Matrose zum Kapitän: "Segel gesetzt, Sir"

So, das war etwas aus einer ganz anderen Gegend und hatte rein garnix 
mit Elektronik zu tun, aber wir können etwas daraus lernen.

Nämlich daß es da wie überall einer sinnvollen Konversation bedarf, um 
Handlungen korrekt durchzuführen. Dazu gehört eine Synchronisation auf 
dem Befehlsweg sowie eine Rückmeldung nach getaner Arbeit dazu.

So etwas sollte ein jeder Mensch begreifen, auch wenn er keine Ahnung 
von Elektronik hat. Deine Antwort hingegen "...Learning by doing. Fail 
fast fail often..." ist kein sinnvoller Beitrag, denn das Lernen durch 
Tun hat nur dann einen Sinn, wenn es in der zuvor richtig gelernten 
Weise erfolgt, so daß sich die einzelnen Abläufe einprägen können.

Wer nix weiß (insbesondere nicht, wie es richtig geht), wird "fail until 
eternity" tun und wird es sein Leben lang nicht lernen.

W.S.

von Rainer V. (a_zip)


Lesenswert?

W.S. schrieb:
> Wer nix weiß (insbesondere nicht, wie es richtig geht), wird "fail until
> eternity" tun und wird es sein Leben lang nicht lernen.

...aber er könnte in der Communicy nachsehen und sich was drucken 
lassen..z.B. einen Batteriehalter!

von Johannes S. (Gast)


Lesenswert?

SafeStringReader scheint eine gute Lib dafür zu sein,
https://www.google.de/amp/s/www.instructables.com/Arduino-Serial-IO-for-the-Real-World/%3famp_page=true

STEP 3: SAFESTRINGREADER FOR TEXT INPUT

Dann kann man auch die ein/aus Zeiten als Klartext in JSON schicken.

von Einer (Gast)


Lesenswert?

Rainer V. schrieb:
> W.S. schrieb:
>> Wer nix weiß (insbesondere nicht, wie es richtig geht), wird "fail until
>> eternity" tun und wird es sein Leben lang nicht lernen.
>
> ...aber er könnte in der Communicy nachsehen und sich was drucken
> lassen..z.B. einen Batteriehalter!

Hier kommt nur wieder Deine verachtende Attitüde zum spielerischen 
Zugang zu Technologien zum Vorschein.

Widerlich.


W.S. schrieb:
> Ob das nun ein Node-Red oder ein Node-Blues ist, kann hier eigentlich
> egal sein.

Ach ja. W.S. eben, ständig Schwierigkeiten mit dem Text-Verständnis. 
Kleiner Tipp: Sätze stehen in einem Kontext und beziehen sich auf jenen 
Kontext.


Nochmals in aller Deutlichkeit, für Dich:

Dirk B. schrieb:
> ich habe mittels Node-red eine Verbindung zu einem Controllino (Arduino)
> hergestellt,

Verstehst Du die Gesamtsituation? Der Fragesteller beackert zwei sehr 
unterschiedliche Plattformen parallel, gleichzeitig. Eine Leistung, die 
Deine Vorstellungskraft übersteigt. Und die von Rainer V.

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.