DCC Signal Analyse

This is a very simple "offline" decoder for the analysis of DCC signals. It needs sampling of the signal on the rails every 10 microseconds, low=0 and high=1 (or vice versa, because the signal is symmetric), one line per sample. (Language "Processing"). The sampling was done with the help of a PC-USB logic analyser.
!!! the program is written in the "processing" language !! see 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 GNU 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. 
*/

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