Leuchtturm Beispiel Arduino Due

Hallo community,

nachdem mir bei meinem ersten Teil der projektumsetzung super geholfen wurde habe ich gleich noch eine Frage zum nächsten :smiley:

Zum einen möchte ich mit dem Arduino Due ja die anlogen Eingänge lesen und auswerten, dieser Teil steht nun :slight_smile:

Zum anderen möchte ich über 4 digitale Ausgänge des Arduino Due einen jeweils unterschiedlichen Rechtecktakt mit einer Frequenz von 1Mhz ausgeben...

Dasganze wird benötigt, das mein Prüfling für den ich einen Prüfstand konzipieren soll über Lichtwellenleiter kommuniziert und angesteuert wird..

Eine Leiterkarte welche die Spannung der digitlen Asugäng in das benötigte optische Signal umwandelt habe ich schon...

Gebraucht wird nun eigentlich nur ein Programm für den Arduino Due mit dem ich ein bestimmtes Rechtecksignal von der Frequenz 1Mhz realisieren kann.

Ich möchte schlussendlich im Programm den gewünschten takt eintragen (dieser ist dann auch immer fest, ebenso wie die frequenz) ZB. 10111001 (1=high, 0=low)
sodass an 4 verschiedenen digitalen ausgängen des Arduino ein unterschiedlicher Rechtecktakt ausgegeben wird....

Hast jmd zufällig eine Ahnung wie man das am dümmsten umsetzen kann oder evtl sogar ein Beispielprogramm ? :slight_smile:

Habe beim uno mal was mit einem assembler befehl geamcth und den /nop befehlen...geht das beim Due auch ?

Ich hoffe ich konnte man Problem verständlich schildern und danke schonmal..

Gruß !

für mich klingt das wie das blink without delay beispiel.
pin an oder aus, ob lwl oder led ist ja am ende egal.

FlyingEagle:
für mich klingt das wie das blink without delay beispiel.
pin an oder aus, ob lwl oder led ist ja am ende egal.

aber das ist ja dann dort immer der selbe takt oder ? ich möchte den ja variabel haben…

zb auf dem
ersten digitlaen pin: 0101010101
auf dem zweiten: 0110110110
auf dem dritten: 0101101011
…usw.

und alles mit ner frequenz von 1mhz… is das mit dem normalen low und high setzen realisierbar ?
weil beim uno war das ja nur mit den assembler möglich…aber gut , der hatte auch selbst nur 16mhz :smiley:

nö, du musst das beispiel nur um die anzahl der gewünschten pins erweitern.
aber selbst wenn du die ports/pins per asm o.ä. steuerst, die methodik bliebe imho die gleiche.
pwm wäre ja auch noch eine idee.

schau dir das mal an: http://forum.arduino.cc/index.php?topic=4324.0

FlyingEagle:
nö, du musst das beispiel nur um die anzahl der gewünschten pins erweitern.
aber selbst wenn du die ports/pins per asm o.ä. steuerst, die methodik bliebe imho die gleiche.
pwm wäre ja auch noch eine idee.

schau dir das mal an: http://forum.arduino.cc/index.php?topic=4324.0

pwm hab ich ja glaub nur 2 ausgänge, also das ginge nicht, da ich ja 4 verschiedene takte zur gleichen zeit benötige :confused:
ach quatsch falsch geschaut, sind ja pins 2-13 pwm :smiley: mein fehler

It has 54 digital input/output pins (of which 12 can be used as PWM outputs)

https://www.arduino.cc/en/Main/ArduinoBoardDue

jop, hab mich schon berichtigt :smiley:

Also irgendwie komm ich mit dem Blinky without Delay Beispiel nicht hin :smiley:

hättest du mal ein Beispielprogramm für mich meinetwegen mit 2 Pins wo je ein 1 MHz Takt Rechteck mit unterschiedlicher Kodierung raus kommt ?

Bsp1: 0101
Bsp2: 0110

Gruß

Dann zeig mal deinen Code, vielleicht sieht man da ja was.
ich weiß aber nicht genau ob man 1MHz mit den boardmitteln so hinbekommt.
aber nicht blockierende ausgabe geht nun mit millis und nicht delay.
hast du pwm probiert?
da ich diesen anwendungsfall noch nicht hatte, habe ich auch nix fertiges o.ä. in der schublade.
kriegst du es denn wenigstens erstmal mit einem pin hin, das würde ja auch schon mal ne erkenntnis sein.

FlyingEagle:
Dann zeig mal deinen Code, vielleicht sieht man da ja was.
ich weiß aber nicht genau ob man 1MHz mit den boardmitteln so hinbekommt.
aber nicht blockierende ausgabe geht nun mit millis und nicht delay.
hast du pwm probiert?
da ich diesen anwendungsfall noch nicht hatte, habe ich auch nix fertiges o.ä. in der schublade.
kriegst du es denn wenigstens erstmal mit einem pin hin, das würde ja auch schon mal ne erkenntnis sein.

also ich hab das blinkywithout dealy programm mal genommen mit nur einem pin...

da bekomm ich max 100kHz hin...mehr sind da anscheinend nicht drin...

ich wollte das ganze dann nach folgendem code aufbauen....aber da ist dann das gleich problem, dass die 1Mhz leider nicht drin sind :confused:

// Leuchtturm LEDs schalten by Jurs im Arduino-Forum Deutsch
//
// LED: Pin-Nummer der zu schaltenden LED
// gesamt= Gesamtlänge aller Timings zusammen für einen Zyklus des Leuchtturms
// n= Anzahl der nachfolgenden ein/aus Timings
//                      LED gesamt  n   ein   aus   ein   aus   ein   aus   ein   aus
int Norderney_timing[]={ 2, 12000,  6,  200, 2800,  200, 2800, 200 , 5800};
int Pilsum_timing[]   ={ 3, 20500,  4, 3000, 3000, 3000,11500};
int Campen_timing[]   ={13, 15000,  8,  700, 2300,  700, 2300,  700, 2300,  700, 5300};
int Schillig_timing[] ={ 5, 12000,  2, 6000, 6000};
int Voslapp_timing[]  ={ 6,  9000,  2, 6000, 3000};
int Tossens_timing[]  ={ 7,  7000,  2, 6000, 1000};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  // define OUTPUT pins
  pinMode(Norderney_timing[0], OUTPUT);
  pinMode(Pilsum_timing[0], OUTPUT);
  pinMode(Campen_timing[0], OUTPUT);
  pinMode(Schillig_timing[0], OUTPUT);
  pinMode(Voslapp_timing[0], OUTPUT);
  pinMode(Tossens_timing[0], OUTPUT);
}


void TurmStatus(int* Turmdata)
{
  // Anfangs von eingeschaltetem Blinkstatus ausgehen
  boolean blinkStatusOn=true;
  // Zeit im Blinkzyklus per Modulo-Arithmetik 
  // aus millis() und der Gesamt-Zykluszeit des Turms errechnen
  long inCycleTime=millis() % Turmdata[1];
  int onoffCount=Turmdata[2]; // Anzahl der ein/aus Schaltungen
  while (onoffCount>0 && inCycleTime-Turmdata[3+Turmdata[2]-onoffCount]>0)
  {
    // bereits abgelaufene Blinkzeit abziehen
    inCycleTime-=Turmdata[3+Turmdata[2]-onoffCount];
    onoffCount--; // Anzahl der ein/aus Schaltungen vermindert
    blinkStatusOn=!blinkStatusOn; // Blinkstatus wechselt
  }
  // wenn alles durch, dann den errechneten Blinkstatus setzen
  digitalWrite(Turmdata[0], blinkStatusOn);
}

void loop() {
  TurmStatus(Norderney_timing);
  TurmStatus(Pilsum_timing);
  TurmStatus(Campen_timing);
  TurmStatus(Schillig_timing);
  TurmStatus(Voslapp_timing);
  TurmStatus(Tossens_timing);
  // put the rest of your loop code here
}

100Khz? :o
Das glaub ich nicht. eine Millisekunde ist nur 1/1000 Sekunde-wenn man diese als als Zeitbasis nimmt, kann man damit maximal 1KHz schaffen.

Rabenauge:
100Khz? :o
Das glaub ich nicht. eine Millisekunde ist nur 1/1000 Sekunde-wenn man diese als als Zeitbasis nimmt, kann man damit maximal 1KHz schaffen.

und wenn ich als zeitbasis 0.1 millisekunde nehme :wink:

Das soll funktionieren? :confused:

Ok, bei Arduino ist fast nix unmöglich, aber wenn ich eine Uhr habe, die einmal pro Sekunde tickt, ist es unmöglich, diese Zeiteinheit weiter zu unterteilen.

Aber da du selber nich drauf kommst: es gibt auch noch Microsekunden, und ja: kann nen Arduino auch....

ja also bei 0.1 hat er es gemacht, weiter runter wollte er nicht :smiley:

also wenn ich im obigen code in der zeile:

long inCycleTime=millis() % Turmdata[1];

micros() statt millis einsetze...arbeitet er automatiscvh mit mikrosekunden ?:o

..so ungefähr jedenfalls.
Ab und zu mal in die Arduino-Referenzen schauen, wär ne ziemlich gute Idee.

Gut möglich, dass der Compiler automatisch µs benutzt, wenn kleinere Zeiteinheiten gefordert werden (bei Arduino tun sich oft unter der Haube eigenartige Dinge). Dann sollte es aber in der Frequenz auch weiter rauf gehen.
Da du solche hohen Frequenzen offenbar messen kannst: wieso versuchst du es nicht einfach?

t0bsN:
ja also bei 0.1 hat er es gemacht, weiter runter wollte er nicht :smiley:

Eher nicht. millis() tickt alle mS, alle ca 40 41 mS um zwei Schritte (beim Due habe ich das bisher nicht getestet*).

Rabenauge:
Gut möglich, dass der Compiler automatisch µs benutzt, wenn kleinere Zeiteinheiten gefordert werden

Nein, tut er glücklicherweise nicht. Der Compiler weiss nichts von absoluter Zeit.


  • falls du das auf deinem Due testen willst (ich müsste meinen erst ausgraben)
unsigned long lastMillis;

void setup() {
  Serial.begin(115200);
  Serial.println(F("poll millis and print steps above 1"));
  lastMillis = millis();
}

void loop() {
  unsigned long currentMillis = millis();
  unsigned long difference = currentMillis - lastMillis;
  if (difference > 1) {
    Serial.print(lastMillis);
    Serial.write('-');
    Serial.print(currentMillis);
    Serial.write('-');
    Serial.println(difference);
  }
  lastMillis = currentMillis;
}
poll millis and print steps above 1
41-43-2
84-86-2
126-128-2
169-171-2
212-214-2
254-256-2
297-299-2
340-342-2
382-384-2
425-427-2
468-470-2
510-512-2
553-555-2
596-598-2
638-640-2
681-683-2
724-726-2
766-768-2
809-811-2
852-854-2
894-896-2
937-939-2
980-982-2

falls du das auf deinem Due testen willst (ich müsste meinen erst ausgraben)

ich werds gleich mal ausprobieren...

also hilft es nix einfach micros zu setzen anstatt millis ?

Hat niemand sonst eine Lösung für mein Problem ? :smiley:

Klar hilft das. Das war so selbstverständlich dass ich es nicht der Erwähnung wert fand.

micros() bewegen sich in 4er Schritten wenn ich mich recht erinnere.

okay, dann teste ich das mal :stuck_out_tongue:

das ergebnis zu deinem Programm:

427-428-1
428-429-1
429-430-1
430-431-1
431-432-1
432-433-1
433-434-1
434-435-1
435-436-1
436-437-1
437-438-1
438-439-1
439-440-1
440-441-1

Das kann mein Programm nicht ausgeben.

 unsigned long currentMillis = millis();
  unsigned long difference = currentMillis - lastMillis;
  if (difference > 1) {