This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Unexpected readings from tdcSetTriggers/tdcGetValue

Part Number: LP-CC2652RB
Other Parts Discussed in Thread: CC2652RB

Hi all,

I am connecting my Launchpad CC2652RB with an Ultrasonic HC-SR04 sensor. I am using Sensor Controller Studio for the code. The code I've used is below:

// sending the 10us trigger signal

timer0Start(TIMER0_MODE_SINGLE, 240,0);

gpioSetOutput(AUXIO_O_TRIGGER_PIN);

timer0Wait();

gpioClearOutput(AUXIO_O_TRIGGER_PIN);

//starting a 0.15s timer

timer0Start(TIMER0_MODE_SINGLE,367,12);

tdcSetCntSource(TDC_CNTSRC_96M_RCOSC);

tdcSetTriggers(TDC_STARTTRIG_AUXIO_HIGH_BASE + AUXIO_I_ECHO_PIN, TDC_STOPTRIG_AUXIO_LOW_BASE + AUXIO_I_ECHO_PIN,0);

tdcEnable();

tdcArm(TDC_START_ASYNC);

do {

U16 timerIsRunning;

timer0CheckState(timerIsRunning);

U16 timeout = timerIsRunning ^0x0001;

U16 checkEV;

tdcCheckDoneEv(checkEV);

U16 done = checkEV|timeout;

} while(done==0);

timer0Stop();

tdcGetValue(output.valueHigh, output.valueLow);

tdcDisable();

I am fairly certain that the first part of the code works (the 10ms trigger pin signal), because I am actually getting periodical readings from the sensor. However, I am not getting the readings I expect from the tdcGetValue procedure.

The Echo pin goes high when the bounce back ultrasound signal is received after it is triggered by the Trigger Pin. The time period for which it goes high is the time the ultrasound has travelled. Hence, I would like to read the duration of the Echo pin high signal with tdcSetTriggers. The output values for the high and low value for tdcGetValue are very inconsistent though. I can point the sensor around the room and it will stay around 7000, for example. At other times I can move an object very close and it will jump to 40000. Even if I cover both signals completely with my hand, which should result in a timeout, I get readings. 

I can't find the mistake in my code so if anyone is able to point me to it, I would appreciate all the help!

Thanks!

  • Hi,

    Thanks for sharing your code, I am able to follow the logic here.

    A few questions/points:

    1. For the second part of your code, have you considered replacing the loop with tdcWaitUs(x)? This can wait a maximum of 65534 uS. Max length of measurement recommended in the datasheet is 400 cm, which is less than 65534/58 cm (~1130 cm).

    2. Assuming the logic is flawless here, then the issue could be related to the sensor itself. Have you tested this sensor standalone? (E.g. signal generator output to Trig, logic analyzer input from Echo).

    3. The TDC pulse measurement requires that the measured signal must be idle when the TDC is enabled. Can you verify that this is the case?
    Else, you could potentially start the TDC before asserting Echo (this would reduce the probability that the Echo is "unstable" whenever TDC is enabled).

    4. Theoretically speaking, what happens if the timer0 expires (in second part of your code)? If it does, then this means that the TDC value should probably not be used. Perhaps have a flag which indicates that the TDC actually measured a pulse (e.g. tdcCheckDoneEv(isValid)).

    I can point the sensor around the room and it will stay around 7000, for example. At other times I can move an object very close and it will jump to 40000. Even if I cover both signals completely with my hand, which should result in a timeout, I get readings. 

    Understood here, that you are not seeing the expected correlation between value and distance.
    If you keep distance constant (e.g. stationary and pointing to a wall from a fixed position), do you get consistent readings?

    Thanks,
    Toby

  • Hi Toby,

    Thanks for the response. I don't have the sensor with me right now for the holiday weekend, but I will try some of your suggestions as soon as I can. I can already answer some of the questions you raised though:

    1. Yes I have tried the tdcWaitUs function, with the same result. changing it to my timer loop didn't change anything so I don't think the error was there. I will try both versions again with some of your other suggestions.

    2. I have ran the sensor standalone with an Arduino on a bread board and the measurements are very accurate and consistent, even with angled objects, etc. The sensors are very reliable.

    3. In previous versions of my code, I manually ran gpioClearOutput(AUXIO_O_ECHO_PIN) before the trigger signal to set ECHO pin low to get the opposing edge.

    4. Also in previous versions of my code, I used a flag to verify it was done and it would always return 1, even when the sensor is pointed into open space and shouldn't return a measurement, same with holding my hand over the sensor all together. 

    In regards to your last question, sometimes I will get consistent readings for fixed setup, but after letting it sit that way for a while, it will continue to produce that consistent value even after I change the distance. It's very confusing.

    Thanks for all the help, I will definitely try to start the TDC earlier in the code and see what happens.

  • Hi Toby,

    I have made some changes to the code and went back to a very generic version, which in theory should work. I have modified to tdcWaitUs instead of the timer loop and I also enable tdc at the beginning. Even if i manually set ECHO to low before enabling TDC, it does not make a difference.

    tdcSetCountSource(TDC_CNTSRC_96M_RCOSC);

    tdcSetTriggers(TDC_STARTTRIG_AUXIO_HIGH_BASE + AUXIO_I_ECHO_PIN,

    TDC_STOPTRIG_AUXIO_LOW_BASE + AUXIO_I_ECHO_PIN,0);

    tdcEnable();

    tdcArm(TDC_START_ASYNC);

    //sending the 10us trigger signal

    timer0Start(TIMER0_MODE_SINGLE, 240, 0);

    gpioSetOutput(AUXIO_O_TRIGGER_PIN);

    timer0Wait();

    gpioClearOutput(AUXIO_O_TRIGGER_PIN);

    tdcWaitUs(65534);

    tdcGetValue(output.valueHigh, output.valueLow);

    tdcCheckDoneEv(output.isValid);

    tdcDisable();

    These are the first 5 readings in a fixed position, ca 20 cm from a wall, 2 second intervals:

    isValid valueHigh valueLow
    1 34 9039
    1 34 30461
    1 86 20314
    1 1 57102
    1 1 64255

    And for good measure I covered the sensor so there shouldn't be any readings, but I got this instead:

    isValid valueHigh valueLow
    1 34 30461
    1 86 20314
    1 1 57102

    Looking at them written down, I now notice that some numbers repeat exactly. 

    I am thinking that SetTriggers does not read a high pulse. It can't, because the echo pin would never signal high when the sensor is covered. Somehow it is getting readings from within the functions and I can't figure out where. 

    Any ideas are appreciated!

  • Can you share any initialization block in your sensor controller code?
    May need to initialize the GPIOs (pins for TRIG and ECHO).
    May also need to enable the GPIO input (gpioEnableInputBuf).

    Are you able to hook up a logic analyzer to TRIG and ECHO?
    (at the same time these signals are connected to the MCU).

  • [deleted]
  • Hi Toby,

    Sorry for the delay, I had to get my hands on a logic analyzer. I just got today and it actually was very insightful. It looks like the Echo pin keeps going high and low in a 1 us interval (high for 1 us, then low for 1 us, then high for 1 us and so on). But the reading of the logic analyzer also shows a short period of consistent high readings, which is pretty accurately in line with the expected distance. Now my guess is that the problem is that the tdc tries to read the first occurrence of a rising edge, but it happens every microsecond so it's not helpful which goes back to your suspicion that the pins might not have been idle.

    Here is my initialization code:

    gpioCfgMode(AUXIO_I_ECHO_PIN,GPIO_MODE_INPUT);

    gpioCfgMode(AUXIO_O_TRIGGER_PIN,GPIO_MODE_OUTPUT);

    fwScheduleTask(1);

    I haven't figured out how to keep the ECHO pin on low/idle until the high pulse occurs.

    Thanks!

  • Can you test out gpioEnableInputBuf for the AUXIO_I_ECHO_PIN ?
    This can help check if the 1 usec toggles result from starting the TDC on this pin.

    If you don't see any toggles after gpioEnableInputBuf(AUXIO_I_ECHO_PIN ), then I'd try calling this just before tdcEnable.

  • Hi Toby,

    The command gpioEnableInputBuf(AUXIO_I_ECHO_PIN) worked for the logic analyzer. I've placed it right ahead of tdcEnable() and the pin now stays low and goes high for a duration that matches the distance. However, tdcSetTriggers() still does not read the echo pin correctly. I'm not sure why that is the case. I was hoping that the unstable echo pin was the problem but now that it is truly idle before the trigger signal happens and I get proper readings on the logic analyzer, it shouldn't be the case anymore. I even set the tdcWaitUs to 30000 and am still getting readings of 40000+ at times. I'm not sure if the error lies within tdcSetTriggers or tdcGetValue.

    Thanks again for the help!

  • I have changed my code to the following to do some more debugging:

    tdcSetCntSource(TDC_CNTSRC_96M_RCOSC);

    tdcSetTriggers(TDC_STARTTRIG_AUXIO_HIGH_BASE + AUXIO_I_ECHO_PIN, TDC_STOPTRIG_AUXIO_LOW_BASE + AUXIO_I_ECHO_PIN,0);

    gpioEnableInputBuf(AUXIO_I_ECHO_PIN);

    tdcEnable();

    tdcArm(TDC_START_ASYNC);

    fwDelayUs(2);

    gpioSetOutput(AUXIO_O_TRIGGER_PIN);

    fwDelayUs(10);

    gpioClearOutput(AUXIO_O_TRIGGER_PIN);

    timer0Start(TIMER0_MODE_SINGLE,367,10);

    do {

    U16 timerIsRunning;

    timer0CheckState(timerIsRunning);

    U16 timeout = timerIsRunning ^0x0001;

    U16 checkEV;

    tdcCheckDoneEv(checkEV);

    U16 done = checkEV|timeout;

    output.check=checkEV;

    output.tout=timeout;

    timer0GetValue(output.timer);

    } while(done ==0);

    timer0Stop();

    tdcGetValue(output.valueHigh, output.valueLow);

    tdcDisable();

    Everything works as expected, except for the values that tdcGetValue returns. The timeout only gets triggered when the sensor can't read (too far away or covered) and the timer shows 367, which is what I preset as the timeout. CheckEV returns 1 whenever I get a reading for timer <367, which also makes sense. The timer also stays very consistent and changes proportionally when I move the target to and from the sensor. The tdcGetValue function however still returns seemingly random values all the time.

    With the logic analyzer hooked up I can also see that the Echo pin stays low at all times, except during the pulse I am trying to measure. Since even the tdcCheckDoneEV function works properly and interrupts the loop, I don't understand where the wild tdc values are coming from.