Hallo zusammen,
ich habe den Code des Datenloggers von Dipl.-Ing. Peter Niehues mal etwas erweitert. Erstmal danke an ihn und Stefan Heß für die Aufbereitung der Datenworte und den Grundcode des Datenloggers.
Hier der erweiterte Code, die Schaltung bleibt die selbe muss aber entsprechend bei eine 132 Bahn mit einem anderen Widerstand wie in dem Beitrag von mir beschrieben werden:
Code
/* Carrera DIGITAL 124/132/143 arduino protocol analyser: "The inspector"
*
* Dipl.-Ing. Peter Niehues CC BY-NC-SA 3.0
*
* This is an example software to decode carrera data protocol. For further information (german only)
* visit http://www.wasserstoffe.de/carrera/protocoll-analyser/
*
* This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/.
*
* This license allows you to remix, tweak, and build upon my work non-commercially, as long as
* you credit Peter Niehues and license the new creations under the identical terms.
*
*/
/* Update by druckgott, thx to Peter Niehues
*
* Ein Regler kann angewählt werden, damit wird nur für einen Regler die Ausgabe abgefangen
* Die Datenpackete der einzelnen Regler pro gesamtes Datenwort werden in Dezimalzahlen ausgegeben
* Das Programmierdatenwort wird zusaetzlich als Dezimalzahl ausgegeben und erhält ein X oder O je nach dem ob es zum vorheriegen wort anders ist
*/
//Binary split parallel zu Decimal Ausgabe
//#define DEBUG_1
//Binary Ausgabe
//#define DEBUG_2
const int dataPin = 2; // the number of the pin to read carrera racetrack data
int wordCount = 0; // counter
boolean wordChange = false; // indicates a new word is ready for further analysing
boolean flag_print = false;
long currentWord = 0; // assemble Bits to complete data words, used in interrupt routine
long Word = 0; // save data word for further computing, used in main loop and interrupt
long Words[11]; // store 10 datawords in array with counts 1..10
unsigned long intervalMicros = 0; // will store the time between two bit changes (microseconds)
unsigned long previousMicros = 0; // will store last time state when data signal has changed (microseconds)
unsigned long currentMicros = 0; // will store the current runtime (microseconds)
long oldWord = 0;
String readString;
void setup() {
Serial.begin(115200);
Serial.println("Start");
#ifdef DEBUG_1
Serial.println("DEBUG 1 ON");
#endif
#ifdef DEBUG_2
Serial.println("DEBUG 2 ON");
#endif
pinMode(dataPin, INPUT);
attachInterrupt(0, manchesterDecode, CHANGE);
} //////
void loop() {
if( wordChange == true ){
wordChange = false;
if( Word > 4000 )
wordCount = 1;
Words[ wordCount ] = Word;
wordCount++;}
if ( wordCount == 11 ){
flag_print = false;
for (wordCount=1; wordCount < 11; wordCount++){
if(wordCount == 1 ) {
String alles = String(Words[ wordCount ], BIN);
String regler = alles.substring(10,13);
//
if( regler == "000" ){
Serial.println("---------------------------");
Serial.print("Regler Nr.: ");
int value = bin_to_dec(regler);
Serial.println( value );
flag_print = true;
}
}
if(flag_print){
// print tab
if( wordCount == 4 || wordCount == 5 || wordCount == 6 || wordCount == 7 || wordCount == 8 || wordCount == 10 ) {
#ifdef DEBUG_2
Serial.print( wordCount, DEC );
Serial.print( "\t" );
Serial.print( alles );
Serial.print( "\t" );
#endif
String alles = String(Words[ wordCount ], BIN);
String regler_nr = alles.substring(1,4);
long value_regler_nr = bin_to_dec(regler_nr);
String spur_wechsel = alles.substring(4,5);
long value_spur_wechsel = bin_to_dec(spur_wechsel);
String speed_car = alles.substring(5,9);
int value_speed_car = bin_to_dec(speed_car);
String tank = alles.substring(9,11);
int value_tank = bin_to_dec(tank);
Serial.print( value_regler_nr ); // print number of dataword
#ifdef DEBUG_1
Serial.print( "|" );
Serial.print(regler_nr);
#endif
Serial.print( "\t" );
Serial.print( value_spur_wechsel );
#ifdef DEBUG_1
Serial.print( "|" );
Serial.print(spur_wechsel);
#endif
Serial.print( "\t" );
Serial.print( value_speed_car );
#ifdef DEBUG_1
Serial.print( "|" );
Serial.print(speed_car);
#endif
Serial.print( "\t" );
Serial.print( value_tank );
#ifdef DEBUG_1
Serial.print( "|" );
Serial.print(tank);
#endif
Serial.println( "\t" );
}else if ( wordCount == 1) {
Serial.print( wordCount, DEC ); // print number of dataword
Serial.print( "\t" );
Serial.print( Words[ wordCount ], BIN );
Serial.print( "\t" );
if(oldWord != Words[ wordCount ]){
Serial.print( "X" );
}else{
Serial.print( "O" );
}
Serial.print( "\t" );
Serial.println( Words[ wordCount ], DEC );
oldWord = Words[ wordCount ];
}else{
Serial.print( wordCount, DEC ); // print number of dataword
Serial.print( "\t" );
Serial.println( Words[ wordCount ], BIN );
}
}
if(wordCount == 10 ) {
flag_print = false;
}
}
wordCount = 1;
//delay( 500 );
}
}
//////
void manchesterDecode(){ //////
currentMicros = micros(); // get current runtime
intervalMicros = currentMicros - previousMicros; // calculate interval
if (intervalMicros > 75 && intervalMicros < 125){ // is full clock pulse?
previousMicros = currentMicros; // synchronise
currentWord = currentWord << 1; // shift bits left
if ( digitalRead( dataPin ) == LOW ) // is pin level LOW?
bitSet( currentWord,0 ); // received digital 1
return; } // leave interrupt
if ( intervalMicros > 6000 ) { // is word rate?
Word = currentWord; // save bits for main loop
currentWord = 0; // reset bits
bitSet( currentWord,0 ); // first bit is always 1
wordChange = true; // indicate a new word
previousMicros = currentMicros; // synchronise
return; } // leave interrupt
}
int bin_to_dec(String input_string ){
//String array Laenge erstellen
String myStra[input_string.length()+1];
//jedes Element dem array zuordnen
for (int y=0; y<input_string.length(); y++){
myStra[y] = input_string.substring(y, y+1) ;
}
//array abschliesen
myStra[input_string.length()] = "\0";
long int wert = 0;
int i = 0;
//loop ueber array um Dezimalzahl zu berechnen
for (wert=i=0; myStra[i] != '\0'; i++)
{
wert=wert*2+myStra[i].toInt();
}
//Serial.println(wert);
return wert;
}
/*
* End of "The Inspector" Carrera Decoding Sketch
*/
Alles anzeigen
Mein Ziel ist es ein eigenes Driver Display zu bauen, dazu sind aber natürlich erst mal die Datenwort nötig.
Im Anhang ist für einen Regler mal ein paar Runden gefahren, bis der Tank leer war (speed 10). Der code zum Tracken wurde genau so genutzt wie hier dargestellt