USB shield to MTi-G 28A53G35 IMU

I have a USB Shield, sparkfun DEV- 09947. I have an Arduino Uno. I have managed to successfully connect my shield but now wish to get information off of the IMU. The IMU has a USB connector in which it can connect to a PC by using MT Manager.

I am curious, is there anything in the USB Host Library 2.0 that would assist in collecting data off of this IMU, I haven't found anything yet? I essentially just need to write to it for configuration, receive data and place it in a buffer, and then parse it. Xsens gives some custom code, but I do not know how difficult it would be to talk through the shield without the library.

Any help would be appreciated!

If you want to read an IMU with an Arduino I strongly suggest you use an IMU with an I2C or SPI interface. Although you can connect your PC IMU to the USB Host shield you probably won't get a driver for it and writing one yourself is not as straight-forward as you might think.

If you provide a link to that IMU you're using we might suggest you some alternatives or alternative ways to access your's.

I will eventually be using such an IMU, but it was requested I make it work first with this IMU, they said they wish to calibrate the other IMU off of this one. I believe that this IMU also has a rs-232 connector that can be attached. That might be a much better option. That combined with a level shifter for the TTL voltages.

Here is the link: https://www.xsens.com/products/mti-g/

We unfortunately already bought the shield, although I have not yet soldered it on as I wanted it working before I did. I know USB protocol is difficult and was hoping for something in the USB Host Library 2.0 that would assist, but it seems that all the functionality is very specific. This might be to much of a niche request.

To connect to an AVR processor you want 5V TTL signals. Sounds like you do not want the USB or the RS-232 converters on the IMU. But you might need 3.3V <-> 5V logic level shifters. The datasheet should explain the logic levels for the IMU.

If you want to do it the hard way using USB, look at the USB host library for the USB to serial drivers it supports. I think FTDI, PL2303, and CDC ACM are supported. If your USB serial converter uses a different chip, you will have write a driver for it which is difficult.

Hey gbafamily, there is only three options the connection coming out of the IMU. There is USB, the hard option as you put it. There is a Rs-232 I could buy. OR I can do a little splicing. The information coming out of the IMU is serial and is in the form of 8 wires, those 8 wires going into a board with a few chips that transfers it into USB(Power, Ground D+, D-).

I do already have a 3.3-5.0 converter.

If the USB Host Library does have drivers, wouldn't that become the easier option once again?

If the USB Host Library does have drivers, wouldn't that become the easier option once again?

Yes and it would be safer. Probing around the header pins without proper documentation may destroy the device. The IMU looks like it is much more expensive than the usual hobby grade junk.

That combined with a level shifter for the TTL voltages.

You don't need a level shifter but a driver chip. As that device also supports RS-485 I would use that interface and add a corresponding driver board to the Arduino.

Here is the link: https://www.xsens.com/products/mti-g/

This is not what we usually think about when someone writes about an IMU. That's more a GPS receiver.

We unfortunately already bought the shield, although I have not yet soldered it on as I wanted it working before I did. I know USB protocol is difficult and was hoping for something in the USB Host Library 2.0 that would assist, but it seems that all the functionality is very specific. This might be to much of a niche request.

If you're not very experienced with USB development I would recommend against writing your own driver. As the linked page says that the USB interface is just an external converter to one of the other interface variants you might be lucky that they used a familiar chip such as the FTDi232R in which case the host shield software already supports it.

This is not what we usually think about when someone writes about an IMU. That's more a GPS receiver.

You are correct that it has that capability, but it also can be used as just another IMU with calibrated or raw data. Either way it is overkill, and is over complicating this task to some extent.

If you're not very experienced with USB development I would recommend against writing your own driver. As the linked page says that the USB interface is just an external converter to one of the other interface variants you might be lucky that they used a familiar chip such as the FTDi232R in which case the host shield software already supports it.

I looked into the hardware guide and found that it is indeed using a FT232. So I am attempting to use the send and receive commands that was given in the USBFTDIloopback code. I am having difficulty and am wondering if there are better examples out there or people I can ask how to correctly send and take in data.

I am able to receive and send but am not receiving what I should be based upon the low level communication guide from xsens. So the data I may be sending might not being sent correctly to configure the IMU. I looked on this forum for the USB host library 2.0, and it seems like the creator used to be very involved in answering but no longer.

Posting examples of the expected values versus the received values might be helpful.

The USB host library github.com repo is where the real experts are. Check the issues first before posting. Your question may have already been asked and answered.

I also think I might just be having a disconnect on how to use the Ftdi.SndData and the Ftdi.RcvData functions. The example isn’t working correctly that they give, I just continually get “.” after I run it.

I assumed this was because my IMU requires specific arrays of bytes to be sent to it for it to start outputting data correctly, and doesn’t just start outputting data. After messing with it, I received nothing but zeros, which were not expected.

The low level communication protocol is attached. I am essentially trying to send and receive the byte arrays in the picture.

I have found only two or so people on the forum or github that also have been trying to use the FTDI USB too Serial library. Seems rarer then I expected it to be, and neither example have been helpful.

MT Low-Level Communication Protocol Documentation.pdf (846 KB)

USBFTDILoopback_ForForum.ino (2.11 KB)

Plug the device into a computer and see what comes out. You may have to install an FTDI driver. Also you need a program that dumps serial data in HEX. Ubuntu Linux (and maybe other distros) come with FTDI drivers pre-installed. Install a program named cutecom (sudo apt install cutecom). cutecom is a terminal program but it works in binary/HEX. Very handy for troubleshooting serial devices with binary protocols. Or write a program in some easy scripting language such as Python to read/write the serial port.

If other attempts have been made to configure the device, it may be stuck at a baud rate other than 115200. See if the device has a factory reset button. The last resort is to try every available baud rate until some reasonable data comes out.

The sketch you posted is not very useful because it sends an invalid command “DEADBEEF” that might confuse the device. I suggest not sending anything and just see what comes back. The device is supposed to send measurements if it does not receive any commands. The protocol is in binary so print HEX.

Something like this might show measurements.

void loop()
{
	Usb.Task();

	if( Usb.getUsbTaskState() == USB_STATE_RUNNING )
	{
		uint8_t buf[64];
		uint16_t rcvd = sizeof(buf);
		uint8_t rcode = Ftdi.RcvData(&rcvd, buf);
		if (rcode && rcode != hrNAK)
			ErrorMessage<uint8_t>(PSTR("Ret"), rcode);

		// The device reserves the first two bytes of data
		//   to contain the current values of the modem and line status registers.
		for (uint8_t i = 2; i < rcvd; i++) {
			// Show data in HEX
			Serial.print(buf[i], HEX);
			Serial.print(' ');
		}
		Serial.println();
	}
}

Plug the device into a computer and see what comes out. You may have to install an FTDI driver. Also you need a program that dumps serial data in HEX. Ubuntu Linux (and maybe other distros) come with FTDI drivers pre-installed. Install a program named cutecom (sudo apt install cutecom). cutecom is a terminal program but it works in binary/HEX. Very handy for troubleshooting serial devices with binary protocols. Or write a program in some easy scripting language such as Python to read/write the serial port.

Luckily the IMU comes with a "Manager" MT Manager. It lets me see the output from the IMU on a GUI interface. It also lets me change the configuration without having to do it manually by sending bytes. So you may be right in saying that I might just be able to listen, once configured correctly in the manager.

Another aspect of the manager is the ability to send arrays of bytes, like I am attempting to do over the arduino. I am attempting to send and the receive. It works on the PC. I know that the chip is a FT232, so the drivers should work.

If other attempts have been made to configure the device, it may be stuck at a baud rate other than 115200. See if the device has a factory reset button. The last resort is to try every available baud rate until some reasonable data comes out.

Per the documentation the baud rate is automatically set at 115200 unless I change it. I also placed it there in the manager. I did try the other baud rates, and received nothing.

The sketch you posted is not very useful because it sends an invalid command "DEADBEEF" that might confuse the device. I suggest not sending anything and just see what comes back. The device is supposed to send measurements if it does not receive any commands. The protocol is in binary so print HEX.

I understand, that was not my attempt. That was the starting example given by the creators of the library. Was simply giving it so you could see the functions he implemented and maybe knew how to correctly use them, since its possible I am just using them incorrectly.

Unfortunately your code did now work even after configuring the IMU to output in the MT manager. I feel like either I am having a huge mishap with using the drivers correctly, or what I am doing is not possible with my current library.

If someone knew enough to simply explain the functions that would be enough for me to realize If I am using them correctly or not, and then to move on to another option if they are simply not working. Any help would be greatly appreciated, on top of the help you guys have already given me.

Thanks!

It is possible the USB host shield is not working which seems to happen a lot based on messages on this board. If you see "OSC did not start" message, the shield is not working. You might have to try the RS232 converter.

Do not post code you are not actually using. Post the code you have tried with the IMU.

SndData first parameter is the number of bytes to send. The second is a point to an array of uint8_t to send. The example uses a NULL terminated string instead.

uint8_t command[]={0xFA, 0xFF};

rcode = Ftdi.SndData(sizeof(command), command);

It is possible the USB host shield is not working which seems to happen a lot based on messages on this board. If you see “OSC did not start” message, the shield is not working. You might have to try the RS232 converter.

The board works correctly. I have tested other functions, such as the MIDmouse and MIDkeyboard. I can also gather information off of the IMU through USB-desc and board_qc. Both our functions meant to check connection and gather information on the device.

Sorry about that this is some code I have tried.

if (rcode && rcode != hrNAK)
ErrorMessage<uint8_t>(PSTR(“Ret”), rcode);

What does this portion of the code do?

If I leave the if statements open and allow the for loops to be inside them, the if statements never occur and the loops don’t run. If I close the if statements make them separate, loops run and I do not get “…”(stuck in the first if statement) but the buf variable is never assigned anything other than zero, so I am receiving nothing. Obviously this if statement is important, but it is never true.

FDTICommunication.ino (2.93 KB)

This may be hardware.

The shield and arduino uno does not have a FTDI chip. I saw on data sheet that this IMU did indeed have a FTDI implimented…but I think it is already being driven.

The data coming out of the IMU is serial. It has a small box in the middle which I took apart today. It has a board that is taking the serial data and turning it into USB d+/d-. See pictures.

I am assuming that it is not possible to drive this FTDI chip, since its being driven by the MAXIM1103?

Board.PNG

I am assuming that it is not possible to drive this FTDI chip, since its being driven by the MAXIM1103?

I do not think this is a hardware problem with the IMU since it works with the PC USB host port.

You might consider making a lateral shift by considering aspberry Pi instead of Arduino. USB FTDI driver support is included. A Pi is smaller and maybe cheaper than an Uno+USB Host shield. The Pi Zero is even smaller and cheaper than the Pi 3.

The code in the previous message prints an error message if the code is non-zero and is not equal to hrNAK. If the message does not appear, everything is fine.

The last idea is the IMU may require RTS and/or DTR high. If this does not work, I would take a look at a Raspberry Pi.
SetModemControl should set DTR and RTS HIGH. Some serial devices require RTS and DTR control. Some ignore them. Are you sure the IMU does not need flow control? The example program is for a generic device. It must be customized to the requirements of the IMU.

    rcode = pftdi->SetFlowControl(FTDI_SIO_DISABLE_FLOW_CTRL);

    if (rcode)
        ErrorMessage<uint8_t>(PSTR("SetFlowControl"), rcode);

    rcode = pftdi->SetModemControl(FTDI_SIO_SET_DTR_HIGH|FTDI_SIO_SET_RTS_HIGH);

    if (rcode)
        ErrorMessage<uint8_t>(PSTR("SetModemControl"), rcode);

Comments regarding the posted code. This is wrong in many ways. You need more coding skills for this task.

It is not necessary to zero the buffer.

RevData can return up to 64 bytes so do not put it in a loop running 64 times. The number of bytes actually read is returned in rcvd.

   uint16_t rcvd = 64;
   rcode = Ftdi.RcvData(&rcvd, buf);
   if (rcode && rcode != hrNAK){
     ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
   }

Print the number of bytes actually returned, which is probably less than 64. Printing all 64 bytes is confusing because only the first rcvd bytes contains valid data.

Print a space between numbers (or a comma) because running the digits together makes the value ambiguous. Print the buf in HEX, not decimal. Do not put a delay(10) in this loop.

for (uint8_t i = 2; i < rcvd; i++) {
     // Show data in HEX
     Serial.print(buf[i], HEX);
     Serial.print(' ');
}

gbafamily. You are correct my coding skills are mostly in MATLAB and have only taken embedded systems just last term, in which it went over basics of C and Assembly with a PIC.

I have started to understand the code better from your comments and others that I have found. I believe now I am correctly using these drivers. My IMU does not require any flow control or Parity bits. Its default Serial is below in the picture. I did try driving RTS and DTR high, as well as several other different possible setups were than tried.

Is there any other device that would be a easy check the drivers to determine its just the IMU that is a problem? I have a Leonardo, but I USB CDC I am assuming would require completely different drivers to send or receive info from to test the uno and the board. Another FTDI device that would either be cheap or something that is common in a house hold I am not thinking of?

I would have to buy a Rasberry pie, but I do own a BeagleBone Black. I could probably find some drivers for its USB host port, or use a connector/adapter to hook into its serial ports, which I know have ready drivers/code.

DefaultSerialMTi-G.PNG

In your other message, a Leonardo USB port is a CDC ACM so it should work with the USB host shield CDC ACM driver.

As for FTDI, I have used the Adafruit FTDI breakout boards. Many companies make similar ones. Shorting Tx and Rx on the board should allow for easy testing. Data send from the USB host shield should be echoed back.