Programming of built in timer of arduino

Hello Everyone , I am new to programming in IDE. I am using built-in timer of arduino.I am using TDR method to capture reflection from fault location in cable and for that I am using timer.Timer should start as soon as output is send and stop at reflection. I have a reference code for it but I dont able to understand it, so if anyone know about it , it would be great.

// Time domain reflectometer

const int stepPin = 4;       // digital output pin we generate the step on. Later in the code, we assume this is port D bit 4.
const int refPin = 11;       // PWM output pin that we use to generate the comparator reference voltage. Must be on timer 2.
const int shutdownPin = 7;   // digital output port used to put comparator in shutdown mode - drive HIGH before sleeping

const int maxSteps = 4;      // maximum number of steps in each direction that we capture

// Define the fraction of the speed of light at which waves propagate in the cable
// Some typical values;
//  cat 5 cable 68%
//  RG58 or RG213 coax (solid polyethylene dieletric) 66%
//  Airspaced coax up to 92%
const float propagationFactor = 0.68;  // fraction of speed of light that waves travel in the cable under test

void setup()
{
  pinMode(stepPin, OUTPUT);
  pinMode(refPin, OUTPUT);
  pinMode(shutdownPin, OUTPUT);
  
  TCCR1A = 0;
  TCCR1B = (1 << ICNC1);   // input capture noise canceller enabled, capture on falling edge
  TIMSK1 = 0;              // timer 1 interrupts disabled
  ACSR = 0;                // input capture from ICP1 pin
  
  TCCR2B = (1 << CS20);    // change timer 2 PWM frequency to 31.25kHz because we're using pin 11 as a DAC
  
  Serial.begin(19200);
}

struct Step
{
  unsigned int time;
  unsigned int amplitude;
};

// Take a single measurement, using either a positive or negative edge from the comparator.
// The comparator reference voltage must have been set up and allowed to stablise before calling this.
unsigned int takeMeasurement(bool posEdge)
{
  byte reg1b = (posEdge) ? 0 : (1 << ICES1);    // input capture noise canceller csdisabled, set up input capture polarity, stop timer
  reg1b |= (1 << CS10);
  TCCR1B = reg1b;
  TCNT1H = 0;
  TCNT1L = 0;              // clear timer
  unsigned int capture = 0;
  unsigned long start = micros();  // get the time
  
  cli();
  TCNT1H = 0;
  TCNT1L = 0;              // clear timer
  TIFR1 = (1 << ICF1);     // clear timer 1 input capture bit
  PORTD |= (1 << 4);       // set output high
  sei();

  do
  {
    if ((TIFR1 & (1 << ICF1)) && capture == 0)
    {
      byte temp = ICR1L;
      capture = (ICR1H << 8) | temp;
    }
  } while (micros() - start < 100);
  
  PORTD &= ~(1 << 4);          // set output low
  return capture;
}

size_t findSteps(bool positive, struct Step *results, size_t maxResults)
{
  byte amplitude = (positive) ? 5 : 250;
  analogWrite(refPin, amplitude);
  delay(100);      // wait 100ms for the output to stabilise
  unsigned int lastReading = 0;
  size_t numResults = 0;
  unsigned int stepSize = 0;        // 0 means not in a step
#ifdef DEBUG  
  Serial.print((positive) ? "pos " : "neg ");
#endif
  for (int i = 0; i < 50; ++i)
  {
    analogWrite(refPin, amplitude);
    delay(10);
    unsigned int currentReading = takeMeasurement(positive);
    unsigned int currentDiff = currentReading - lastReading;    // diff since start of possible step
    if (stepSize == 0)
    {
      // Not currently in a step
      if (i != 0 && currentReading != 0 && currentDiff == 0)
      {
        // Found the start of a possible step
        ++stepSize;
      }
      lastReading = currentReading;
    }
    else
    {
      if (currentDiff > 2 || i + 1 == 50)
      {
        // Step has endeed, so record it if it is big enough
        if (stepSize >= 2)
        {
          results->time = lastReading;
          results->amplitude = amplitude - 5;
          ++results;
          ++numResults;
          if (numResults == maxResults) break;
        }
        stepSize = 0;
        lastReading = currentReading;
      }
      else if (currentDiff == 0)
      {
        ++stepSize;
      }
    }
#ifdef DEBUG    
    if (i != 0) Serial.write(',');
    Serial.print(currentReading);
#endif    
    if (positive)
    {
      amplitude += 5;
    }
    else
    {
      amplitude -= 5;
    }
  }
#ifdef DEBUG  
  Serial.println();
#endif
  return numResults;
}

// Convert a number of clocks delay to a cable length in metres
float clocksToMetres(unsigned int clocks)
{
  float delayTime = (float)clocks/(float)F_CPU;    // delay in seconds
  float distance in metres= (delayTime * 3.0e8 * propagationFactor)/2.0;
  
  Serial.print("distance in metres: ");
  return (distance in metres);
}

// Diagnose the cable condition. We have the following common possibilities:
// 1. No cable connected, or a very short open-circuit cable connected.
//    In this case we should see the original positive step, very close to zero delay, with amplitude nearly 5V.
// 2. Direct short, or very short cable with shorted end.
//    In this case, we will not even see the original positive-going step, or it will have a very low amplitude.
// 3. Cable with open circuit.
//    We see the original positive step close to zero delay, and a further positive step going to nearly twice the amplitude later.
// 4. Cable with short circuit.
//    We see the original positive step close to zero delay, and a negative step going back down to nearly zero later.
// 5. Correctly terminated cable.
//    We see only the original positive step, with amplitudfe well below 5V.
void loop()
{
  Step posSteps[maxSteps], negSteps[maxSteps];
  size_t numPosSteps = findSteps(true, posSteps, maxSteps);
  size_t numNegSteps = findSteps(false, negSteps, maxSteps);
  if (numPosSteps == 0)
  {
    Serial.print("Direct short");
  }
  else if (numPosSteps == 1 && numNegSteps == 0)
  {
    if (posSteps[0].amplitude >= 200)
    {
      Serial.print("No cable connected");
    }
    else
    {
      Serial.print("Cable correctly terminated");
    }
  }
  else if (numPosSteps >= 2 && numNegSteps == 0)
  {
    Serial.print("Open at ");
    Serial.print(clocksToMetres(posSteps[1].time - posSteps[0].time), 1);
  }
  else if (numPosSteps == 1 && numNegSteps == 1)
  {
    Serial.print("Short at ");
    Serial.print(clocksToMetres(negSteps[0].time - posSteps[0].time), 1);
  }
  else
  {
    Serial.print("Failed to diagnose fault");
  }

#ifdef DEBUG
  Serial.print(" (pos=");
  for (size_t i = 0; i < numPosSteps; ++i)
  {
    if (i != 0)
    {
      Serial.write(',');
    }
    Serial.print(posSteps[i].time);
    Serial.write('|');
    Serial.print(posSteps[i].amplitude);    
  }
  Serial.print(" neg=");
  for (size_t i = 0; i < numNegSteps; ++i)
  {
    if (i != 0)
    {
      Serial.write(',');
    }
    Serial.print(negSteps[i].time);
    Serial.write('|');
    Serial.print(negSteps[i].amplitude);    
  }
  Serial.println(")");
#else
  Serial.println();
#endif
}

Hi, @abhivani1411

To add code please click this link;

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Thanks

You can't have a variable with spaces in the name. Try distance_in_metres or distanceInMetres.

Am I correct in guessing you are using an Arduino UNO or Nano (ATmega328P processor)? Since you use hardware registers it is important.

Yes I have corrected it and I am using Arduino Uno.

about this code:

Writing any non-zero CSxx bits to the TCCRnB register will start the timer immediately, so I think this should be done as last line of timer setup process, AFTER all other settings...

What external circuits are used? The sketch is using Pin 11 as an analog output and talk about a reference voltage but that would have to be done with an external comparator.

Where did you find this code?

Analog comparator is used externally. It is used to compare the reflection from fault in cable.

@abhivani1411

It is required to study/analyze the codes of your sketch of post #1 in the light of the working principle of TDR Method (Fig-1) for Cable Fault Location. The Fig-1 shows the instant (say: t0) of injected pulse from transmitter (transceiver), time of arrival (say: t1) of the injected pulse at the fault point, time (say: t2) of arrival of the reflected signal from the fault point to the transmitter (transceiver). The t2 time is to converted into distance considering various cable characteristics.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.