How to detect length of circuit?

Kind of difficult to explain what I'm thinking, but basically - what's the easiest way to detect how long a path of circuit is?

Basically, if I wanted to put wire on, say, Jenga blocks, and then be able to tell how many jenga blocks are ontop of eachother, what would be a solution? Hope that makes sense.

If the wire has a known resistance per unit length then you could measure the resistance and calculate the length from that. To be usable in practice, the resistance would need to be fairly high so you'd need to use resistive wire, not ordinary copper wire. If the wire is connected in discrete segments you could use an ordinary resistor in series with each segment to give you the known resistance.

Are you approaching this problem the right way.

Is the primary objective to determine how many items are stacked on top of each other ?

Or stacked next to each other.

I can see a lot of issues of connectivity between items if you are intending to use this as a way to count blocks

I suspect using weight would be a better metric

You could send a signal through the circuit, and time how long it takes to get back to the other side.

You'd need pretty long circuits in order for the Arduino to detect the difference, though. In the neighborhood of 18 meters per clock cycle. That's some serious Jenga blocks!

In the neighborhood of 18 meters per clock cycle.

Where you assuming one instruction per clock cycle, ?

I suspect you;d need to allow at least 2 cycles per counter++ so you'd only be able to get 30+ m accuracy.

And with all the over variable overhead, thats just not going to work.

You'd need an external clock and set of counters running at 1Ghz or more to get the sort of accuracy you need

As I understand it, using the input capture unit, you can get single clock cycle accuracy.

OK.

I wasn't aware of that feature, can you post a link, it sounds interesting

Let's assume for now we don't have blocks that are several metres in height each :slight_smile:

Are we talking the normal stack where there can be different numbers of blocks per level? If so weight won't work and I can't see any way it can work.

Or is this some different application?


Rob

what's the easiest way to detect how long a path of circuit is?

There is no easy way to do this. All the ways are hard.

Basically, if I wanted to put wire on, say, Jenga blocks, and then be able to tell how many jenga blocks are ontop of eachother, what would be a solution?

There would be no solution that you could do with an Arduino.
The best way is with time domain reflectometry:-

But not with a Uno. you can't.

Grumpy_Mike:
The best way is with time domain reflectometry:-
Time-domain reflectometer - Wikipedia
But not with a Uno. you can't.

But the UNO can control and read results from a dedicated chip that can do 45ps time readings.

Nick Gammon has done some work with the input capture unit, of course. You would need to mess with it to get single clock cycle accuracy, and I don't know if that's even possible, but his tests got less than 2 clocks accuracy. Which is pretty darn good.

Riva, could you tell me more (or point me to somewhere I could read) about these dedicated chips that can do 45 ps readings? Specifically, what are they called, and how much do they cost?

TanHadron:
Riva, could you tell me more (or point me to somewhere I could read) about these dedicated chips that can do 45 ps readings? Specifically, what are they called, and how much do they cost?

The chip I am talking about is the TDC-GP22 and you can see some incomplete testing with one here.

That was some interesting reading! This interests me because I'm always looking for new ways to do distance measuring. One of my long term projects is the autonomous lawn mower, but so far accurate positioning is still too expensive. That's a subject for another thread.

But this TDC-GP22 chip: The source link you put on your other thread is outdated. I had a chat session with the only distributor in the US, and the price they quoted me was a bit more than what you posted back in February. Is the place where you got yours still available?

For the OP:
The best way would be to have each block have a little arduino in it that reports its size to the one below it along a common serial line.

For example:
The base sends a command saying "report your height!" If it hears nothing come back, the height is zero. If one block is there, when it gets the "report your height!" command it sends the command on up the chain. If it hears nothing, it reports its own height. If it gets a number back, it adds its height to it and sends it on back the chain.

You could also send back a string of numbers, one for each block, to know the number of blocks and the aggregate height.

As is often the case we need further information but the OP has disappeared.

If it's the normal random stack of blocks I think this will be very difficult, something like what KeithRB is proposing I guess but the logistics of powering all the CPUs and making reliable connections will be a drama.

But until we know more I'm out.


Rob

TanHadron:
But this TDC-GP22 chip: The source link you put on your other thread is outdated. I had a chat session with the only distributor in the US, and the price they quoted me was a bit more than what you posted back in February. Is the place where you got yours still available?

The 2K1 site is still listed on the ACAM website as the only UK supplier but the link seems dead. I do recall getting an email from some company a few weeks ago saying they had taken over 2K1 but I just deleted it as spam. :blush:
Maybe worth trying here but I have never used Aliexpress to comment if they are any good.
If you don't mind me asking what was the US site quoting?

Just over $20 USD each if I get 10.

IF the blocks were to be stacked serially, a small resistor in each would add up.

Perhaps a small inductor in each would slow a pulse?

old post.PNG

:slight_smile:

old post.PNG

rogerClark:
OK.

I wasn't aware of that (Input Capture Register) feature, can you post a link, it sounds interesting

Here is an example sketch that I wrote:

// Measures the HIGH width, LOW width, frequency and duty-cycle of a pulse train
// on Arduino UNO Pin 8 (ICP1 pin).
// Should work up to 65535 clock cycles (4095 microseconds)
// Note: Since this uses Timer1, Pin 9 and Pin 10 can't be used for 
// analogWrite().
void setup()
{
  Serial.begin(115200);
  // For testing, uncomment one of these lines and connect
  // Pin 3 or Pin 5 to Pin 8
  //analogWrite(3, 64);  // 512.00, 1528.00, 2040.00, 25.10%, 490.20 Hz
  //analogWrite(5, 64);  // 260.00, 764.00, 1024.00, 25.39%, 976.56 Hz
  noInterrupts ();  // protected code
  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  TIFR1 |= (1 << ICF1); // clear Input Capture Flag so we don't get a bogus interrupt
  // start Timer 1, no prescaler
  TCCR1B |= (1 << CS10); // plus Input Capture Edge Select (rising on D8)
  TCCR1B |= (1 << ICES1); // Input Capture Edge Select (1=Rising, 0=Falling)
  TIMSK1 |= (1 << ICIE1); // Enable Timer 1 Input Capture Interrupt Enable
  interrupts ();
}
volatile uint16_t PulseHighTime = 0;
volatile uint16_t PulseLowTime = 0;
ISR(TIMER1_CAPT_vect)
{
  static uint16_t firstRisingEdgeTime = 0;
  static uint16_t fallingEdgeTime = 0;
  static uint16_t secondRisingEdgeTime = 0;
  if (PulseLowTime == 0)
  {
    if (TCCR1B & (1 << ICES1))
    {
      // Rising Edge
      if (firstRisingEdgeTime)
      {
        secondRisingEdgeTime = ICR1;
        PulseLowTime = secondRisingEdgeTime - fallingEdgeTime;
        firstRisingEdgeTime = 0;
      }
      else
      {
        firstRisingEdgeTime = ICR1;
        TCCR1B &= ~(1 << ICES1); // Switch to Falling Edge
      }
    }
    else
    {
      // Falling Edge
      fallingEdgeTime = ICR1;
      TCCR1B |= (1 << ICES1); // Switch to Rising Edge
      PulseHighTime = fallingEdgeTime - firstRisingEdgeTime;
    }
  }
}
void loop()
{
  noInterrupts();
  uint16_t pulseHighTime = PulseHighTime;
  uint16_t pulseLowTime = PulseLowTime;
  interrupts();
  // If a sample has been measured
  if (pulseLowTime)
  {
    // Display the pulse length in microseconds
    Serial.print("High time (microseconds): ");
    Serial.println(pulseHighTime / 16.0, 2);
    Serial.print("Low time (microseconds): ");
    Serial.println(pulseLowTime / 16.0, 2);
    Serial.print("Cycle time (microseconds): ");
    Serial.println((pulseHighTime / 16.0) + (pulseLowTime / 16.0), 2);
    uint32_t cycleTime = pulseHighTime + pulseLowTime;
    float dutyCycle = pulseHighTime / (float)cycleTime;
    Serial.print("Duty cycle (%): ");
    Serial.println(dutyCycle * 100.0, 2);
    float frequency = 16000000.0 / cycleTime;
    Serial.print("Frequency (Hz): ");
    Serial.println(frequency, 2);
    Serial.println();
    delay(1000);  // Slow down output
    // Request another sample
    noInterrupts();
    PulseLowTime = 0;
    interrupts();
  }
}