bin neu in diesem Forum habe in sachen Arduino schon ein bisschen Erfahrung gesammelt und schon einige kleine Projekte realisiert
aktuell möchte ich gerne für die Carrera Digital meine eigene CU basteln
und zwar möchte ich gene die Funktion void manchesterEncode() in einen interrupt setzen
sie soll alle 7500 microsekunden ausgeführt werden habe schon einiges probiert aber es hat nichts funktioniert vl kann mir ja jemand helfen
const int dataOutPin = 3; // connection to MOSFET driver circuit
const long wordRateMicros = 7500; // send a new data word every 7,5 ms
unsigned long intervalWordMicros = 0; // will store the time difference to last word(microseconds)
unsigned long previousWordMicros = 0; // will store last time when a word has been send (microseconds)
unsigned long currentMicros = 0; // will store the current runtime (microseconds)
void setup() { //////
Serial.begin(115200); // initialize serial bus
pinMode(dataOutPin, OUTPUT); // initialize the dataPin as an output
digitalWrite( dataOutPin, HIGH ); // set output Pin to HIGH, racetrack voltage is default 20 V
} //////
void loop() { //////
currentMicros = micros(); // store current runtime
intervalWordMicros = currentMicros - previousWordMicros; // calculate interval
if (intervalWordMicros > wordRateMicros) { // is time to start a new data word?
previousWordMicros = currentMicros; // new data word starts
manchesterEncode( 648 );} //binary:0000001010001000,controller2,
}
void manchesterEncode(word dataWord){ //////
const int halfClockMicros = 40; // experimental value for half clock rate of 50 microseconds on 16 MHz Arduino Uno
int bitPos = 13; // bit counter for position of bit in dataWord
int currentBit = 0; // store current bit
while ( !currentBit ){ //
currentBit = ( dataWord >> bitPos ) & 1; // store bit on position bitPos in currentBit, currentBit becomes 0 or 1
bitPos--;} // switch to next postion
bitPos++; // get back to start bit
do{ //
currentBit = ( dataWord >> bitPos ) & 1; // store bit on position bitPos in currentBit, currentBit becomes 0 or 1
if ( currentBit == 1 ){ //
digitalWrite( dataOutPin, HIGH ); //
delayMicroseconds ( halfClockMicros ); //
digitalWrite( dataOutPin, LOW); //
delayMicroseconds ( halfClockMicros );} //
else{ //
digitalWrite( dataOutPin, LOW ); //
delayMicroseconds ( halfClockMicros ); //
digitalWrite( dataOutPin, HIGH ); //
delayMicroseconds ( halfClockMicros );} //
bitPos --; // goto next bit
} while ( bitPos >= 0 ); // until all bits are processed
digitalWrite(dataOutPin, HIGH ); // make sure to leave subroutine always with digital level HIGH
}
also das Programm läuft aber ich möchte den loop teil ja noch erweitern und dazu muss ich um einen zuverlässigen Ablauf zu gewährleisten die Funktion manchesterEncode() in einen Interrupt setzen welcher alle 7500 ms ausgelöst wird ! nun kenne ich mich mit interrupts nicht aus ich weis nur das eine Funktion im Interrupt sehr kurz sein muss und auch keine delays enthalten darf da hätte ich gene einen Lösungsansatz wie ich das machen kann ...
Wie genau müssen diese 7500ms (?? 7,5 Sek, vorhin eher 7,5µs) eingehalten werden?
7,5µs (7500ns) ist aber schon 'echt kurz' - da bleibt nicht viel Zeit für großartig Befehle zwischen drin.
Pro µs 16 Takte (bei 16MHz) - macht knapp 100 1-Takt-Befehle in einer Hochsprache - ich habe Da Bedenken.
die 7500 microsekunden entsprechen den Zeitabstand zwischen zwei Datenwörtern wie genau diese eingehalten werden müssen kann ich nicht sagen da die Carrera Autos die Datensätze dekodieren .
müsste man testen ..
ok also wenn das so schwierig ist dann werde ich einen zweiten Arduino weitere berechnungen machen lassen und die Datenwörter dann Seriell an meinen Codierer senden
Danke für die Antworten und den interessanten Link
Mit einem Interrupt alle 7,5ms wirst Du nicht auskommen.
Du willst 16Bit in Manchestercodierung rausschieben, wobei pro Bit 80µs benötigt werden. Das macht insgesamt 1280µs für die Übertragung des Datenwortes. So lange darf keine Interruptroutine dauern.
Ich habe etwas ähnliches mal für die Erzeugung eines Digitalsignals bei der Modellbahn (DCC) gemacht. Da ist die Codierung aber etwas einfacher. Du wirst einen Timer benötigen, mit dem Du das Signal erzeugst, und eher einen Interrupt pro Bit. Wenn Dein Loop schnell genug ist, kannst Du das Ganze alle 7,5ms aus dem Loop heraus anstoßen.
Ein Interrupt pro Taktflanke wäre alle 40µs ein Interrupt, das ist für einen ATMega schon recht sportlich. Aber an jeder Taktflanke ( halfClockMicros ) könnte ja eine Flanke im Ausgangssignal auftreten.
Beim Decodieren meines DCC-Signals gab es während der Präambel kurzzeitig ca. alle 60µs einen Interrupt - das ging noch.
Mit weniger Interrupts kommst Du aus, wenn Du das Signal über die PWM-Funktion des Timers erzeugst. Dann brauchst Du pro Impuls einen Interrupt. Den Timer musst Du dann aber nach jedem Impuls umprogrammieren. Um den Interrupt kurz zu halten, sollten die Daten schon passend für die Timerprogrammierung vorbereitet werden. Damit sollte es auch möglich sein, das Timing recht exakt - unabhängig von kurzen IRQ-Verzögerungen - zu erzeugen.
Sind erstmal alles nur so Gedanken aus meiner Erfahrung heraus, ohne dass ich da irgendetwas schon probiert hätte.
P.S. vielleicht solltest Du auch mal mehr Info's zu dem Carrera-Digitalsignal geben - oder einen Link, wo das beschrieben ist.
Hier noch zwei Links für die Datenübertragung der Carrera Digital falls da jemand Interesse hat
Ich habe es jetzt so gelöst indem ich die Datenworte von einem zweiten Arduino an meinen Codierer schicke und meine Funktionen mit den zweiten Arduino berechne
Hört sich so an, als ob das Zeug läuft
Dabei war ich mir jetzt noch unsicherer, als je zuvor, da jetzt erneut von 7,5ms geschrieben wurde - dabei kann der Arduino noch nebenbei Kaffee machen und die Bude saugen.
Auch habe ich in den beiden Links beim Überfliegen keine Info zum Protokoll und/oder zur Bitzeit gefunden.
(Das macht selbst der ATtiny45 mit Seinen 1MHz RC-Takt noch mit - mit 7500 Takten sollte man die 80Bit wohl raus bekommen)
Würdest Du Deine Erkenntnisse hier zur Verfügung stellen?
Vll. gibt's ja noch weitere Slot-Car-Fahrer (oder wie Ihr Euch nennen mögt)
wenn ich mit dem Projekt fertig bin stelle ich natürlich alles zur verfügung wird aber eine Zeit dauern da ich noch nicht sehr viel Erfahrung habe in der Programmierung aber ich kämpfe mich durch
die Autos habe ich schon zum laufen gebraucht mit Geschwindigkeitreglung; Weichenstellung
und die Programmierung er Autos für den jeweiligen Regler Tank und Bremsverhalten läuft auch schon ...