TDC-GP22 rangerfinder using UNO

Hello all,

I am trying to implement TDC-GP22 time of flight sensor using Arduino UNO. I am using one Github code for this module, but SPI communication between the Arduino and GP22 does not work. The specific questions are after the code. The code link as follows:

I have already checked wiring between the Arduino and GP22, as following the configuration in the source code. Even if I am a newbie for the SPI coding, I tracked the code to narrow an error range, and found some weird things:

  1. The variable 'DEBUG' in the code is set '0', which means the serial baud rate should be 1000000, not 115200. So I myself change DEBUG from '0' to '1', but reading does not work. Should I set DEBUG to '0' back?

  2. Tracking the error, I found that 'tdc_testcommunication()' does not work. -> In testcommunication() function in GP22.cpp, 'readRegister' does not work. -> 'readNByte' does not work. -> 'SPI.transfer' does not work.
    Actually, SPI.transfer is an inherited function in the Arduino.ino library. To deep inside to this function, I realized that 'SPDR' variable does not change; it always set '0'. How can I solve this issue?

Since the datasheet is too large, I attach its link here:
TDC-GP22 datasheet link

I attach GP22 application and its source code. Thank you all!

TDC-GP22_AN000249_1-00.pdf (1.37 MB)

TDCtalk.ino (9.05 KB)

Hello there,

Have you solved this problem? I've got exactly the same issue with you, showing the messages like this:

attached pinChangeISR_debug
\Temp sensor: no addresses.
Starting up
/\/\/\Test took 248 us
Read/write test failed!

Hello,

I am still stuck in this problem now. You can change DEBUG value from '0' to '1' and follow up the error code through the .h and .cpp files. Please let me know if you find anything. Good luck!

Ted

Hi Ted,

Sorry that I just had a vacation...It seems that it still doesn't work. Have you tried to skip the step testcommunication()? With this, I got something like:

attached pinChangeISR_debug
/\/Temp sensor: no addresses.
Starting up
\/\/\/\/
Register 0:	0x00041223
Register 1:	0x0141000f
Register 2:	0xa0000000
Register 3:	0x20000000
Register 4:	0x20000000
Register 5:	0x00000041
Register 6:	0x00200000

Calibrating...
attached pinChangeISR_debug
\
Calibrating resonator. Theoretical: 1953.1250
/\/Failed to capture measurement. Resonator calibration failed.

Status = 0x0
ALU pointer 0
Hits (ch1, ch2) = 0,0


Calibrating TDC.
Failed to capture hits. Calibration failed.

Status = 0x0
ALU pointer 0
Hits (ch1, ch2) = 0,0
Cal: -2
Corr: inf
Cal freq: inf
attached ISR at 0x33D
Calibration failed.

The registers seem to be good, but I cannot read anything from them. All I got is 0. I saw you have done some tests so it is probably because of SPI between Uno and GP22 which doesn't work. Or maybe there are some problems while reading or writing in the registers?

And for the GP22, what do you use exactly to do the test? The CJMCU-22? The DEMO-KIT, or the EVA-KIT? At first I used CJMCU-22 but I can't find a place to connect the sensor... So now I use the GP22-DEMO-KIT which is connected to a 15-pin VGA connector. And I also put two ultrasonic sensors on it. By using the software offered with DEMO-KIT I can get some signals. But when back to UNO: Nothing!

Anyway, wish good luck to both of us,
Yinan

Hello Yinan,

I also got stuck in the testcommunication() function now. I am trying to make time-of-flight device using GP22 with my purchased laser diode and photodetector. My GP22 chip is somewhat soldered chip found here :
https://www.diymore.cc/search?type=product&q=gp22

Now I am pretty sure of the problem. I am trying to use a logic level converter(5V->3.3V) to operate UNO-GP22 interface. As you know, the operation voltage of GP22 is far below 5V. If you haven't tried this, try it!

Before the test, I also recommend you to test SPI.trasnfer function whether the UNO can get any signal from GP22. For example, you can type Serial.print(~~~) line in the SPI.transfer function in SPI.h file. The register value you got does not come from GP22, but from an inner code of your PC.

Once I fix this issue with the level converter, I will post about it also. Good luck

Ted

Hello Ted,

Yes, I know that the 'registers value' come from the function tdc.printConfigRegisters() now. And I tried the SPI.transfer and it sends '~~~' everywhere. I also tried with logic level converter, but only a few times at the beginning it returned some results, but still kinda strange: like 0x10101 or 0x3030303 by reading the registers using tdc.printOutputRegisters(). But what testcommunication() returned is always 0. And then even these results disappeared: all the things went back to 0.

With the help of oscilloscope the device seemed to work well, and the SPI is correctly at the mode 1. But just cannot get back any useful information from GP22. Really weird.

Anyway, good luck!

Yinan

Hello Ted,

Try to set the reset pin! For me, it's the pin RTN, try to set it to 1, and maybe you will get things right. Now I've got testcommunication() worked. It's really strange that no books no datasheets mention that.

Yinan

Hello Yinan,

I am so glad to hear that! Well, I am using the logic level converter but still not working haha.

  1. Are you using logic level converter still?
  2. What kind of GP22 device are you using?
  3. You are using the Arduino UNO, right?
  4. Is the RESET pin should be always '0'??

I hope that you are further doing this stuff! I appreciate your help as well.

Ted

Hi Ted,

In fact even if I managed to get testCommunication() worked, I still cannot send fire pulses correctly...

To answer your questions:

  1. Yes I'm still using the logic level converter, but only using the 'bi-directional channels' for INT and SO(MISO) PINs. The other 3 I made directly a voltage divider to simplify the work as they are 'uni-directional'.

  2. I think I'm using the same device as yours, CJMCU-22, which you will be able to find when you turn to the back of your device. And it's the first one on the website that you offered.

  3. Yes I'm using the Arduino UNO.

  4. No, on the datasheet you can find that the RSTN is 'low active', which means if it is set to be 0, it is always on reset! So only the first time set 0, then keep it to 1.

Wish you good luck!

Yinan

Hello Yinan,

I appreciate your help! What do you mean by sending wrong fire pulses? Are the pulses from the slave or UNO? Or if you are meaning the measurement fire signal, then you are almost close to being done I think! Using oscilloscope as you did, some pins of my logic level converter are not correctly working, so I used both voltage divider and converter. But still, the clock signal is not around 3.3V but 2.2V.

Even though the low CLK signal, I could also get OutputRegisters. But in testcommunication function, the numbers are very weird. These are the printed results

initialReg1 = 0
testInput = 122
testResult = 61

I also got some numbers from tdc.printOutputRegisters() as follows:

Read registers:
0: 65F98000 26105.500000
1: 7A0000 122.000000
2: 65F98000 26105.500000
3: 7A0000 122.000000

what numbers could you get??

Ted

*I realized that MISO waveform was falling-edge operation; so I changed SPI_MODE0 to SPI_MODE1 and testcommunication() worked well.

Hello Ted,

I got the different values of registers, but I think that doesn't matter as long as they are not 0 all the time.

For the SPI mode, if you have a look in the datasheet, it says:

The TDC-GP22 does only support the following SPI mode (Motorola specification) *:

Clock Phase Bit = 1 , Clock Polarity Bit = 0

SCK starts with LOW, data take over is with the falling edge of SCK. The timings are
shown in section 2.3. The interrupt pin is set back to INTN = 1 if:

  • SSN goes LOW
  • or, in case SSN is already LOW, with the first rising edge of SCK.

So I think we ought to use SPI_MODE1 as TDC-GP22 only supports that.

What I mean is the measurement fire signal, and I managed to get some signals like this:
signal

But it only sends once even if I put it into loop, so I'm going to find out how to send fire pulses continuously, and figure out how to read it correctly.

To test the register, maybe you can simply use this:

  byte a = tdc.readRegister(READ_REG_1);             
  Serial.println(a,HEX);

to see if the output equals to the first byte of what you write in the register 1.

Wish you good luck!

Yinan

Hello Yinan,

I am glad to see your proceeding project! Thanks to your help, testcommunication() also worked well for me, and now I am dealing with the calibration process. It seems that for the calibration, I need to set up a fire and stop signal.

  1. How did you deal with INT pin? In the GP22.cpp, init() code contains this line:

//digitalWrite(_pinInt, HIGH);

Did you keep it ineffective? And once I know its direction(whether from GP22 to UNO or from UNO to GP22), I can connect it correctly using a logic level converter or voltage divider.

  1. For your fire signal(it looks like an oscilloscope), did you also connect EN_START, EN_STOP1, EN_STOP2 pins to START, STOP1, STOP2 pins?

  2. I guess our TDCtalk.ino does not contain the continuous fire and detect function; it only contains literally 'talking' between UNO and GP22. Are you making your own code for this function?

Good luck your project :slight_smile: Keep fighting!
Ted

Hello Ted,

Glad to see you also managed to have something worked and we're both progressing.

  1. I also got some trouble with INT, but I think you can keep it ineffective as my problem is the interrupt is always at a high position. And the function waitForInterrupt() returns only '-1' indicating timeout for whatever I put. I saw in the GP22.cpp it has:
  int w = waitForInterrupt(1000000);

  // dirty debug: this just helps it run,
  // for some reason, while measurements are already running
  delay(10);

So I tried with a delay() as well, but it still didn't work.

  1. I didn't connect anyone of these pins. But I tried to connect the EN_START pin(DIS) to Vcc via a resistor:as far as I verified, the CJMCU-22 does have some parts missing(still don't know if we are using the same device). I checked the components one by one comparing to the datasheet(Page 86) and User Guide of DEMO-KIT (Page 43) and found out the EN_START pin should connect to Vcc via a resistor. Besides, it is 'HIGH active'. Unfortunately, it doesn't change much for me, but maybe you can try it.

  2. I simply sent the opcode 0x05(OPCODE_START_TOF_RESTART) to executes two subsequent flow measurements, starting with upstream measurement (Conf_Fire = 2). And I put it into the loop. According to the application note,

The end of each measurement cycle is indicated by an interrupt

but my interrupt never went to 0. I'm not pretty sure if this is correct.

I'm trying also to have the software offered with DEMO-KIT work, but the modifications and the results are a little bit strange...I cannot find much information about that neither.

Anyway, wish you have new progress!

Yinan

Hello Yinan,
I was wondering how you were able to fix the calibration, I found a auto-calibration and wrote down the settings, but i ended up getting this:

attached pinChangeISR_dibrating...
attached pinChangeISR_debug

Calibrating resonator. Theoretical: 488.2813
attached pinChangeISR_debug
Temp sensor: no addresses.
Starting up
Test took 112 us
Read/write test succeeded.

Register 0: 0x00242000
Register 1: 0x19490000
Register 2: 0xe0000000
Register 3: 0x00000000
Register 4: 0x20000000
Register 5: 0x10000000
Register 6: 0x00000000

Calibrating...
attached pinChangeISR_debug

Calibrating resonator. Theoretical: 488.2813
Failed to capture measurement. Resonator calibration failed.

Status = 0x0
ALU pointer 0
Hits (ch1, ch2) = 0,0

Calibrating TDC.
Failed to capture hits. Calibration failed.

Status = 0x0
ALU pointer 0
Hits (ch1, ch2) = 0,0
Cal: -2
Corr: inf
Cal freq: inf
attached ISR at 0x364
Calibration failed.

thanks

DYN:
Sorry that I just had a vacation...It seems that it still doesn't work. Have you tried to skip the step testcommunication()? With this, I got something like:

attached pinChangeISR_debug

//Temp sensor: no addresses.
Starting up
////
Register 0: 0x00041223
Register 1: 0x0141000f
Register 2: 0xa0000000
Register 3: 0x20000000
Register 4: 0x20000000
Register 5: 0x00000041
Register 6: 0x00200000

Calibrating...
attached pinChangeISR_debug

Calibrating resonator. Theoretical: 1953.1250
//Failed to capture measurement. Resonator calibration failed.

Status = 0x0
ALU pointer 0
Hits (ch1, ch2) = 0,0

Calibrating TDC.
Failed to capture hits. Calibration failed.

Status = 0x0
ALU pointer 0
Hits (ch1, ch2) = 0,0
Cal: -2
Corr: inf
Cal freq: inf
attached ISR at 0x33D
Calibration failed.

Hello,

Sorry that I'm doing other tests without calibration...And I didn't manage to get that neither...

Hello guys,

Thank you for participating in this forum!

@Yinan maybe we can try out auto-calibration stated in the datasheet. Please let me know if the kit-software product is going well. I am also thinking of purchasing it.

By the way, our source code may not contain real fire & stop code. You can try out this code from Russia I guess; it does not contain a header and cpp code, which looks more intuitive.

Russian code : https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=http%3A%2F%2Frefleader.ru%2Fjgebewrnarnajge.html

If there is an error to compile this, you can refer this page as well:
https://forum.arduino.cc/index.php?topic=495234.15

Ted

Hello Ted,

I saw that code as well, but in fact I'm doing the Ultrasonic Flow Meter so I think this code for laser rangefinder doesn't work for me. And the kit-software is not that easy to use, I didn't get the satisfied results. I guess it's better to keep working on the chip directly.

Besides I saw someone said that we need to modify one register each time when we want to calibrate, and it's what datasheet doesn't include, but he didn't mention which one. Maybe you can try it. I think it might be the register 1, the number of hit, but not sure.

Yinan

Hello Guys
I'm doing the Ultrasonic Flow Meter project and i'm using TDC-GP22 and Arduino Uno!
I'm also using that code in GitHub!
How did you solve the communication test problem?
I also have that problem:(
Someone please!HELP ME

has anyone got it to work?

can i use 3.3v arduino-pro directly without voltage divider with gp22?

mortenx:
can i use 3.3v arduino-pro directly without voltage divider with gp22?

Yes.