DCC Signal Analyse

Hier ein simpler Decoder für die DCC Pakete (Language "Processing"), als Input muss ein Sampling des Signals auf dem Gleis alle 10 Mikrosekunden vorliegen (als File, mit 0=low oder 1=high als Ascii-Text, 1 Zeile pro Sampling). Das Sampling habe ich mit einem einfachen PC-USB Logic-Analyser gemacht.
!! Achtung, das Programm ist in "Processing" geschrieben, auch wenn's ziemlich "C-mässig" aussieht, siehe www.processing.org !!
/* Detect_dcc_signal

This "processing" program analyses a "DCC" signal (see NMRA pages).
As input it needs a number of lines with the info "0" (signal low on rails) or "1" (signal high on rails), sampled every 10 microseconds 

one line per sample like:
1
1
0
1
0
......


the output is the DCC packets binary info, "S" denoting Startbit, "E" denoting Endbit
for example
(22ms)  S 11111111 S 00000000 S 11111111 E 
(32ms)  S 00101000 S 00111111 S 01111111 S 01101000 E 
          BYTE1      BYTE2      BYTE3      CHECKSUM  (=XOR of the other BYTES)
          
Copyright (C) 2009 Michael Blank

This program is free software; you can redistribute it and/or modify it under the terms of the G
NU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, see .
*/

int timer=0;
String infile="c:\\users\\mblank\\dcc7-smax-f0f1.csv";

void setup()  {
  ;
 
}

boolean step_down(String d[], int n)  {
   // detect HIGH to LOW transition
   if ((d[n].charAt(0) =='0') && (d[n-1].charAt(0) == '1'))  {
      return true;
   }  else  {
      return false;
   }
}

boolean step_up(String d[], int n)  {
   // detect LOW to HIGH transition
   if ((d[n].charAt(0) =='1') && (d[n-1].charAt(0) == '0'))  {
      return true;
   }  else  {
      return false;
   }
}
   

void draw() {
   String data[]= loadStrings(infile);
   // load input file into String array, input is 1=high, 0=low
   
   boolean flag = false;
   boolean d_flag = false;  // used within data packet
   
   int count = 0;
   int count_bytes = 0;
   int count_ones = 0; // used for detecting the preamble (count_ones >10)

   println("sampling rate must be 10us !!");
   println("no of samples is: "+data.length);
    
   for (int i=1; i< data.length; i++)  {
      timer++;
      // detect high->low steps only, then count until 0->1
      if (step_down(data,i))  {
         flag = true;
      }
      
      if (flag == true)  {  // increase counter when last input was LOW
         count++;
      }
      
      // check for end of LOW, decide whether 0 (=long) or 1 (=short) was detected
      if (step_up(data,i)) {
         flag = false;  // don't count LOWs any longer
         // end of pulse reached
        
         if (count > 8) {
            // this is a logical ZERO 
            if (count_ones >10)   {  // then preamble just ends
               print("("+timer/100+"ms) "); 
               print(" S ");
               count_ones =0; //reset
               count_bytes =0; // start counting databytes
               d_flag = true;
               
            }  else  if (count_bytes == 8) { // then data packet ends!!!
               print(" S ");
               count_bytes = 0;
               count_ones =0; //reset
                              
            }  else   {   // in the middle of data packet
               print("0");
               count_bytes++;
               count_ones =0; //reset
            }

         }  else  {
            // this is a "1", so determine whether part of data packet or part of preample
            if (d_flag == true )  {
               if (count_bytes == 8) { // then data packet ends!!!
                  println(" E ");
                  count_bytes = 0;
                  count_ones =0; //reset
                  d_flag = false; // last data packet was sent
               }  else  {  // not the last bit
                  print("1");
                  count_bytes++;
               }
            }  else  { 
               //print("P");
               ; // don't print the simple preamble packets
            }
            count_ones++;
         }
         count = 0;
      }
   }
   exit();
}

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer