Ein Programm Synchron auf 3 Ardinos laufen lassen.

Servus,

ich habe 3 Arduinos, mit jeweils 2 TLC5940. um LEDs an zu steuern.

Wenn ich jetzt auf allen 3 Arduinos das gleiche Programm lade und Zeitgleich starte. Laufen Alle 3 in Unterschiedlichen Zeiten.

Hat jemand hier für eine Idee und vor allem einen Lösungsansatz? Ich bin grad etwas überfragt.

Vielen dank für eure Hilfe.

Gruß

100% synchron laufen geht ohne Verbindung der Arduinos untereinander auf lange Zeit nicht, augrund der Abweichung des Resonators. Sinnvoll wäre es, ein Signal an alle Arduinos zu geben, "jetzt geht es los". Das kann evtl. sogar schon ein elektrisch (nicht mit Taster) geschalteter Kontakt sein an Reset

Brauchst du überhaupt 3 Arduinos? Eventuell kannst du das mit einem Arduino lösen und externer Peripherie lösen. Dann ginge es auch genau zeitgleich. Auf jeden Fall ist es etwas Aufwand.

Gruß

Hey,

ja müssen leider 3 Arduinos sein.

Ein Startsignal an alle 3 kommt. Taster an einem Eingang, Parallel an alle 3 Bords.

gruß

Dann zeig mal deinen Sketch dazu. Sicherlich irgendwo blockierend, so dass ein oder mehrere Arduinos das Signal zu spät bekommen. Wie lang ist die Leitung. Wird der Taster entsprechend software und oder Hardwaretechnisch entprellt?

Hey,

klar hier der Code, der kurz nach dem Start schon nicht mehr Synchron auf 3 Arduinos läuft.

Wenn man den einen Taster "Test" drückt, gehen Channel 13 und 14 an und wenn man gehen lässt, wieder aus. Wenn man den 2. Taster "Start" drückt läuft ein Programm los, in dem fall ein einfaches an/aus.

Das wird dann schon asynchron. Nach dem delay(4994) schalten Sie schon asynchron ein.

Auch kurios ist, wenn ich den delay(1), nach dem Start der "Startschleife" nicht setzte, werden die ersten Einschaltbefehle nicht ausgeführt.

#include "Tlc5940.h"

int testschalter = 7;
int startschalter = 6;

int zustandtestschalter;
int zustandstartschalter;

unsigned char channelchange[31]= {0,1,2,3,4,5,6,7,15,14,13,12,11,10,9,8,16,17,18,19,20,21,22,23,31,30,29,28,27,26,25};

int channel13 = channelchange[13];
int channel14 = channelchange[14];


int fadeein1;
int fadeaus1;

void setup()
{
  Tlc.init(0);
  pinMode(testschalter, INPUT); 
  digitalWrite(testschalter, HIGH);
  pinMode(startschalter, INPUT); 
  digitalWrite(startschalter, HIGH);
}

void loop()
{
  zustandtestschalter = digitalRead(testschalter);
  zustandstartschalter = digitalRead(startschalter);
  
  Tlc.clear();
  
  if (zustandtestschalter == 1)
  {
  Tlc.set(channel14, 0);
  Tlc.set(channel13, 0);
  Tlc.update();
  }
  if (zustandtestschalter == 0)
  {
  Tlc.set(channel14, 4095);
  Tlc.set(channel13, 4095);
  Tlc.update();
  }
    if (zustandstartschalter == 0)
  {
  Tlc.clear();                          // Beginn Kontrolle Start
  delay(1);
  Tlc.set(channel14, 4095);
  Tlc.set(channel13, 4095);
  Tlc.update();
  delay(1000);
  Tlc.set(channel14, 0);
  Tlc.set(channel13, 0);
  Tlc.update();
  
  delay(4994);                        // Beginn eigentliches Programm

  Tlc.set(channel14, 4095);
  Tlc.set(channel13, 4095); 
  Tlc.update();
  delay(250);
  Tlc.set(channel14, 0);
  Tlc.set(channel13, 0);
  delay(250)
  Tlc.set(channel14, 4095);
  Tlc.set(channel13, 4095); 
  Tlc.update();
  delay(250);
  Tlc.set(channel14, 0);
  Tlc.set(channel13, 0);
  delay(250)
  Tlc.set(channel14, 4095);
  Tlc.set(channel13, 4095); 
  Tlc.update();
  delay(250);
  Tlc.set(channel14, 0);
  Tlc.set(channel13, 0);
  delay(250)
  Tlc.set(channel14, 4095);
  Tlc.set(channel13, 4095); 
  Tlc.update();
  delay(250);
  Tlc.set(channel14, 0);
  Tlc.set(channel13, 0);
  delay(250)
  Tlc.set(channel14, 4095);
  Tlc.set(channel13, 4095); 
  Tlc.update();
  delay(250);
  Tlc.set(channel14, 0);
  Tlc.set(channel13, 0);
  delay(250)
  Tlc.set(channel14, 4095);
  Tlc.set(channel13, 4095); 
  Tlc.update();
  delay(250);
  Tlc.set(channel14, 0);
  Tlc.set(channel13, 0);
  delay(250)
  }
}

Die Programmierstrategie ist nicht sonderlich empfehlenwert. Zum einen sollte es reichen, wenn du eine Aktion ausführst, wenn sich der Pegel an Zustandtestschalter sich ändert. Sowas muss du nicht dauerhaft machen. Des weiteren sidn die Taster nicht entprellt.

Die delays solltest du auf jedenfall durch millis() ersetzen (blinkwithoutdelay).

Der Ablauf könnte so erfolgen.

1) Taster auslesen 2) Wenn Tasterstatus(Test) sich ändert, Funktion ausführen für Alle Leds an oder aus. 3) Wenn Start gedrückt einmal gedrückt wird, die Schritte nacheinander zB in einem Switch Case erledigen. -> FSM

Wofür nutzt du in der Schaltung eigentlich TLC5940? Du hast lediglich AUS und AN an den Leds.

daMeier: Hat jemand hier für eine Idee und vor allem einen Lösungsansatz?

Da ich mich derzeit sowieso mit der Wire-Bibliothek beschäftige, wäre mein Vorschlag: Verbinde die drei Arduinos zu einem I2C-Netz. Einer der Arduinos gibt den Takt vor, indem er den beiden anderen sagt, wann sie loszulegen haben. Mein Geschreibsel zum Thema findest Du hier: http://html.szaktilla.de/arduino-zeug/5.html

HTH

Gregor

Hey,

Die Programmierstrategie ist nicht sonderlich empfehlenwert. Zum einen sollte es reichen, wenn du eine Aktion ausführst, wenn sich der Pegel an Zustandtestschalter sich ändert.

Verstehe ich leider nicht. Wenn der Testschalter gedrückt wird, gehen die channel an. wenn ich dann keinen Änderung vornehme wenn er gehen gelassen wird, gehen die LEDs doch nicht mehr aus, was ich aber gerne hätte. Quasi ein/aus Taster oder was meinst du?

Wie entprelle ich einen Taster? geht das mit Code?

Wie funktioniert millis?

Das ist ein Beispiel Programm welches schon “schiefläuft”. Das spätere soll diverse Helligkeiten und Farben mit dem TLC mischen.

Eine Verbindung der 3 kommt leider nicht in Frage… (zu wire)

https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay http://playground.arduino.cc/Code/Bounce

Wie stark laufen die den unsynchron? Kann mir das nicht vorstellen, dass der Resonator bereits so schnell bei allen 3en unterschiedlich abdriftet.

merklich, schwer zu "stoppen" Gefühl schon ne sekunde oder mehr, also es ist schon so, das eine angeht, dann warten, warten und nächste geht an ... es ist schon zu erkenne, hab leider kein Video gemacht...

woran liegt das überhaupt?

Resonatoren (und Quarze) sind (elektro) mechanische (!!!) Bauteile. Und da hat man eben gewisse Toleranzen. Bei Resonatoren können die schon mal im Promille Bereich neben der Sollfrequenz liegen. Ist halt billiger als ein Quarz. Ein Quarz schafft normalerwise locker 0.1 Promille genaugikeit. Wenn man es entsprechend behandelt (kalibrieren, Temperatur stabilisieren, Spannung stabilisieren) dann sogar locker genauer als 1 / 1e9 (1 ppB). Je genauer Du es haben willst desto schwieriger wird alles. Und absolute Genauigkeit kannst Du vergessen. Kann Dir jeder Physiker erklären warum das so ist.

Morgen,

so, das entprellen hat gut funktioniert, die Taster laufen jetzt deutlich besser!

Vielen dank hierfür.

Mit dem Anpassen der Geschwindigkeitszeiten bin ich noch nicht weiter. Hier hätte ich mal noch Verständnis Fragen.

Der Befehl delay(1000); bedeutet was? das er 1000 milisekunden warten soll oder 1000 Einheiten warten soll?

Ihr habt mir "millis() ersetzen (blinkwithoutdelay)." Empfohlen, hat hier jemand ein gutes, deutsches, verständliches tutorial? Verstehe das noch nicht ganz. Wie funktioniert das? Arbeitet das jetzt mit Millisekunden?

Vielen Dank!

Gruß

delay(x) gibt die Zeit in ms an, die der µC wartet, ehe er weiterarbeitet. Zu millis gibt es genügend Info Material über Google.

daMeier: Morgen,

so, das entprellen hat gut funktioniert, die Taster laufen jetzt deutlich besser!

Vielen dank hierfür.

Mit dem Anpassen der Geschwindigkeitszeiten bin ich noch nicht weiter. Hier hätte ich mal noch Verständnis Fragen.

Der Befehl delay(1000); bedeutet was? das er 1000 milisekunden warten soll oder 1000 Einheiten warten soll?

Ihr habt mir "millis() ersetzen (blinkwithoutdelay)." Empfohlen, hat hier jemand ein gutes, deutsches, verständliches tutorial? Verstehe das noch nicht ganz. Wie funktioniert das? Arbeitet das jetzt mit Millisekunden?

Vielen Dank!

Gruß

Hier http://playground.arduino.cc/Learning/BlinkWithoutDelayDe ist es doch recht gut beschrieben.

daMeier:
Ihr habt mir “millis() ersetzen (blinkwithoutdelay).” Empfohlen, hat hier jemand ein gutes, deutsches, verständliches tutorial? Verstehe das noch nicht ganz. Wie funktioniert das? Arbeitet das jetzt mit Millisekunden?

Etwas Lesestoff von mir, ob es gut ist, mußt Du entscheiden:
Anleitung Endlicher Automat mit millis()
Anleitung Ein Endlicher Automat entsteht

Ich wünsche Dir den “Aha-Effekt”!

Und was wenn man aus einem ein Master mache der per MsTimer2 per Portmanipulation den Takt auf einem Pin vorgibt als Zeitquelle und die andern dann per Interrupt gesteuert werden. Dadurch dürftest du einen optischen Gleichlauf hinbekommen die paar Zylken die die Slaves hinterm Master hängen dürfte man nicht mehr mitbekommen. Gruß DerDani

Und wenn er doch keine Kabel will?

Dann wird das aufgrund der Drifts nie klappen. Alleine wenn du das am Anfang synchronisiert bekommst wirst du schon Drifts haben wenn sich die Arduinos nur minimal anders erwärmen. In der Audio/Video Technik macht man das mit Wordclock zum synchronisieren.

Wenn alle 3 Arduino von einem Taster gestartet werden gibt es ja schon eine Verbindung das wäre nur noch eine mehr.

Gruß DerDani

volvodani: Wenn alle 3 Arduino von einem Taster gestartet werden gibt es ja schon eine Verbindung das wäre nur noch eine mehr.

Dieser Punkt der Fragestellung liegt für mich im Dunkeln, denn so sehe ich das auch. Ein kürzlich Verstorbener, uns mit spitzen Ohren bekannt, hätte gesagt: "Das ist unlogisch!"

Möglicherweise könnte man den Starttaster nur mit Arduino1 verbinden, dann einen Ausgang mit Arduino2 und 3. Aus dem Startsignal könnte dann ein Synchronsignal werden. So brauchte man keine zusätzlichen Kabel.

Zur Asynchronität: Ich weiß, daß LCD.clear recht lange braucht. Hast Du mal gemessen, wie lange Tlc.init(0) und Tlc.clear() brauchen? Ist dies bei den drei Arduinos gleich? Verbanne Tlc.clear() mal nur nach Setup, in Loop wird es nicht gebraucht. Ist immer derselbe Arduino später oder ist das zufällig? Möglicherweise führen Dich die Fragen zu einer Antwort.