Close

PS3 controller, identifying the issue.

A project log for Building the Thor robot

Building a 6-axis robot based on the Thor robot. When size DOES matter!

olaf-baeyensOlaf Baeyens 04/08/2017 at 19:200 Comments

For Thor I want to use a USB host controller that connects to PS3 but I ended up having a issue that may become dangerous when operated on machinery: ps3-controller-i2c-concerns

I was wondering if the issue was because I used a Arduino Due and 3.3v (Ultratronics board for the Thor project) but I can now repeat it also on a Arduino Mega in both 5V and 3.3V.

The original test has a blinking LED when I press a certain button so I am sure that it is not the serial stream that is causing the issue.

Grabbing a trace shows this results and it is clearly a firmware issue.

The PS3 data is 35 bytes long so it must be read into 2 parts. First the 28 bytes, then the next 7 bytes.

What we observe here in the tracing is that the next 7 bytes sometimes are actually part of the first 28 bytes.

The rectangle button is part of the second 7 bytes and I have now an explanation why I had more stable functioning when I only used a button in the first 28 bytes.

Executing code below.

void get_ps3()
{
	int bytesToRead = 28;

	// Get data from PS3 DualShock Controller
	// We only want single byte values (0 to 255)
	// We use a pointer to the ps3 struct we defined so we can populate the data in sequence

	uint8_t *ps3Ptr = (uint8_t *)&ps3;    // Create pointer to ps3 struct

	unsigned char data_values_rcvd = 0;     // keep track of how many characters received    
	Wire.beginTransmission(I2C_ADDRESS);  // transmit to device
	Wire.write(0);                        // Start receiving data from register 0
	Wire.endTransmission();               // end transmission

										  // To retrieve all data we need 35 bytes, but restriction in Arduino means
										  // we can only get 32 bytes at one go, so we split it into 2 reads

	Wire.requestFrom(I2C_ADDRESS, bytesToRead);    // request 28 bytes from PS3 
	data_values_rcvd = 0;
	while (Wire.available())
	{
		*ps3Ptr++ = Wire.read();            // receive a byte and increment pointer address
		data_values_rcvd++;
	}

	Wire.beginTransmission(I2C_ADDRESS);  // transmit to device
	Wire.write(28);                       // Start receiving data from register 28
	Wire.endTransmission();               // end transmission  
	Wire.requestFrom(I2C_ADDRESS, PS3_DATA_SIZE - bytesToRead);    // request outstanding bytes from PS3 
	while (Wire.available())
	{
		*ps3Ptr++ = Wire.read();            // receive a byte and increment pointer address
		data_values_rcvd++;
	}

}

Interesting is that when I pull the blue-tooth transmitter from the USB host controller the random data data goes away.


UPDATE:

It was suggested that in the trace lines I grabbed there was a missing CR+LF. But it is not. If you count the number of values than they are 35. It is just that value [29] and higher contains values that should be 0 or 1 but never higher. The offset you see is the fact that some numbers are 3 characters wide

Discussions