-
Test-run my new Saleae logic analyzer
05/08/2017 at 21:32 • 0 commentsTest-running my new purchase, my logic analyzer Saleae. Red edition :-)
The intention is to use it to test the 7 stepper motor driver signals when I develop the code for the movement. To prevent damage to the mechanism during development I prefer to record the signal and compare it to the desired programmed output.
Up till now I actually used the debug LED for debugging the motor driver code. Slowed down to to very slow speeds but I could only test one motor channel at one time. With the analyzer I can now run at full speed and measure the real data easily.
As discussed in my previous blogs, the intention is to control the motors in parallel just like a mechanical organ playbook. I will use 8 bits where 7 bits are connected to every stepper motor pules. Because I have very limited memory and not a lot of processing power I will use pointers. To prevent bugs in the pointers I will also include safety features to detect wrong data to be executed. I can only guarantee reliable code when I can measure it and verify that it stops the robot when it gets corrupted data.
When that is checked then I can test run the code with the real motors.
Under the Seleae is the is my $10 Chinese clone, that actually works great but can only show digital signals.
Test-run on I2C protocol below (clock and data signal, both analog and digital).
Example of the I2C frame where I get my PS3 communication.
Zoomed in the last part where I request the last 7 bytes. This is the situation where I clearly see a firmware bug in action. It repeats the first 7 bytes and should have ben all "0"
Zoomed in even more to show the analog signals measured by the logic analyzer with the digital output just above.
Interesting is that I have spikes at the rate of the clock in my analog signal.
-
PS3 controller: Hunting down the I2C issue
04/17/2017 at 14:34 • 0 commentsThings that don't work, I love them! It challenges you to dig in deeper and make them work.
But first is to identify the issue, make it visible and learn how to repeat the test setup.
So I ordered a DSO138 self build telescope and a cheap logic analyzer. I never heard about Saleae before so I thought I bought a official product. I will definitely buy an official one soon.
The oscilloscope (up right) shows the I2C communication. That oscilloscope does not match up to a real one but it shows something. It shows noise levels and voltage levels. They are all withing normal range.
This is the trace (last 7 bytes to read) when I start up the Arduino motherboard (2 different motherboards I tested on) but did not pair the PS3 controller yet.
These values should be "0" not "@ = 64). It is erratic as far as I can see above
Once I pair the PS3 controller then the erratic behavior stops but once in a while I values that should be 0 or 1 but in reality their value reflect the first 7 bytes instead.
These values are not random as they can be induced by noise, they are exactly the same as the first 7 bytes.
When I look at the complete signal then I can see the 35 bytes transmitted into 28 first bytes and then the last 7 bytes 29-35. (Gap 7-8 is interesting it it always is there)
The freeze seems also very interesting. The I2C communication just stops. Just let the controller run and it will freeze at random times. Sometimes it can take several minutes, sometimes it is instantly
void loop() { unsigned char i; currentTime = millis(); if(currentTime >= (ps3ReadTime + 50)){ // Get data from PS3 Controller every 50ms get_ps3(); if (ps3.btn_triangle) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } ps3ReadTime = currentTime; // Updates ps3ReadTime } if(currentTime >= (ps3PrintTime + 200)) { // Print out our data to serial port every 200ms // print_ps3(); ps3PrintTime = currentTime; // Updates ps3PrintTime } }
The code used for this setup.ps3.btn_trialnge is located in the last 7 bytes retrieved. When you press it then the on board LED activates. It is a very easy way see if the PS3 data is still receiving without a logic analyzer os oscilloscopic.
My conclusion it is a firmware bug, probably something very tiny and easily fixed.
-
PS3 controller I2C issue visable
04/14/2017 at 18:05 • 0 commentsI received my Saleae logic analyzer and can now see clearly what is happening on the I2C bus.
PS3 controller: Compensating for errors
Trace below is when the PS3 USB hub has been paired with a PS3 controller
This snapshot represents the last 7 bytes I read from the PS3 USB hub controller. This is not random noise data but a repeat of the first 7. These 7 values should be either 0 or 1.
Below is data grabbed when I power on the Arduino and USB hub controller but did not pair the PS3 controller yet.
All these values should be either 0 or 1, not "@" (64)
To be continued. -
Ps3 controller: Compensating for errors
04/09/2017 at 21:06 • 0 commentsFor 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 contacted Hobbytronics telling them that their firmware may have an issue.
I can wait for them to fix a firmware, OR I can find a workaround.
I prefer to find a workaround because this device is going to control a hardware that can hurt people when it suddenly gets an erratic command to start moving.
Even if it is not a firmware bug, it could be because of faulty wiring or some other I2C device adding data noise.
Trace example.
When you look at the trace then the first 6 numbers can be between 0 and 255., however the next 29 are only true or false.
So I can disregards the 35 byte command received when the numbers above position 6 is something else than 0 or 1. I wait for the next received data stream.
But I could also have the frozen bytes issue that I have on the Arduino Due. I still receive correct 35 bytes but the bytes are repeated from the last transmitted ones. However byte 5 and 6 comes from an accelerometer and I assume that the operator will hold it into his hand. So these 1 values will change slightly. The variation these 2 bytes indicate a human operator. I actually wonder if I can use these 2 values telling the robot that a user has taken up the controller. So it may turn on a red warning light.
Finally if the robot gets in values that seems to be frozen or when the accelerometer don't move too much like it is sitting on a table. I am thinking to make the robot come to a standstill if it is in manual mode.
Example below represents thee received data from the USB host controller v2.4 (code comes from Hobbytronics)
typedef struct ps3_data { unsigned char joy_left_x; unsigned char joy_left_y; unsigned char joy_right_x; unsigned char joy_right_y; unsigned char accel_x; unsigned char accel_y; unsigned char press_up; unsigned char press_right; unsigned char press_down; unsigned char press_left; unsigned char press_lb; unsigned char press_rb; unsigned char press_lt; unsigned char press_rt; unsigned char press_triangle; unsigned char press_circle; unsigned char press_x; unsigned char press_square; unsigned char btn_left; unsigned char btn_down; unsigned char btn_right; unsigned char btn_up; unsigned char btn_start; unsigned char btn_joy_right; unsigned char btn_joy_left; unsigned char btn_select; unsigned char btn_square; unsigned char btn_x; unsigned char btn_circle; unsigned char btn_triangle; unsigned char btn_rt; unsigned char btn_lt; unsigned char btn_rb; unsigned char btn_lb; unsigned char btn_ps3; };
-
PS3 controller, identifying the issue.
04/08/2017 at 19:20 • 0 commentsFor 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
-
PS3 controller I2C concerns
04/02/2017 at 01:00 • 5 commentsWhen testing the PS3-controller USB 2.4 Host I discovered 2 concerns in using to control a robot that could mess up the safety
http://www.hobbytronics.co.uk/ps3-controller-bluetooth
I originally thought that my Ultratronics board (Arduino due) was freezing when I was reading in variable from the PS3-controller USB 2.4 Host.
But it turns out that the the firmware for the I2C may be freezing and not return data anymore when I2C is being used.
The code to retrieve the data is 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++; } }
It is split into 2 parts.
- Read the first 28 bytes
- Read the last 7 bytes
Using that code I starts to fail receiving correct data when I have to read the second 7 bytes.
The number of bytes received is still correct, but the contents of the data coming from the PS3 controlled does not change anymore and returns the last known values.
Now when I modify the code that I only read in 28 bytes
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++; } return ; ... }
I now get more stability but the locking still happens at random. Less likely but unacceptable on a robot in regard of safety.
I revert the change to read 35 bytes but now slow down the number of times per second I read in the p3 settings.
void loop() { unsigned char i; currentTime = millis(); if(currentTime >= (ps3ReadTime + 50)){ // Get data from PS3 Controller every 50ms get_ps3(); if (ps3.btn_up) { digitalWrite(LED_BUILTIN, HIGH); } else { digitalWrite(LED_BUILTIN, LOW); } ps3ReadTime = currentTime; // Updates ps3ReadTime } if(currentTime >= (ps3PrintTime + 200)) { // Print out our data to serial port every 200ms //print_ps3(); ps3PrintTime = currentTime; // Updates ps3PrintTime } delay(200); }
This delay(200) appears to make the ps3 controller also stable but still the issue persists if you try long enough..My direct guess is that we have an firmware "locking" issue.
There is another thing that gives a clue that there is a bug in the firmware. When you power on the Ultratronics board but do not pair yet the USB host controller to a PS3. I receive random values. (I notice these values clearly when I connect one button to the debug LED).
The debug LED finally comes to rest once paired to a PS3 controller never giving any random value anymore.
The danger here is that the robot may come into action when the controller freezes or when the robot receives random commands. This cannot be accepted.
-
PS3 controller I2C hookup
03/28/2017 at 20:37 • 0 commentsI finally managed to make the PS3 controller function with the USB Host controller v2.4 through I2C
http://www.hobbytronics.co.uk/ps3-controller-bluetooth
The issue is that the Ultratronics pro v1.0 board is an Arduino Due in disguise. This PS3 controller functioned normally on my Arduino mega but failed on the Due.
The first mistake seems to be that I used the 2x4 pin headers I2C on the Ultratronics board. Only later I realized that there was another one on the analog 2x6 pins.
It is not marked on the board only to be found on its documentation.
The analog 2x6 header is found here SDA0 pin 2, SCL0 pin 4.However the story is incomplete since I did try these pins and I had no working PS3
Danny gave me the final clue that it was missing a pull up resistor of 1.5K for SDA0 and SCL0.Temporarily I have stuck them into the header (hidden in the blue plastic so they don't cause shortcuits)
I also had a 0.5 second response time when I pressed the controller and received the command but that was resolved by hooking it up to a USB to serial adapter, (Rx to Tx and Tx to Rx) and send the command "SERIAL OFF".
The lagging was probably because of the 9600 baud data transmission. It was sending the data both to the Serial and the I2C.
Still one mystery left that only seems to exist when I use this USB Hub controller. The code that pulls the I2C data may cause hangs of the ultrasonics board. It is unclear because without the controller it appears to function normally.
To be resolved....
-
Controlling the robot using Bluetooth
03/21/2017 at 21:31 • 0 commentsI saw that Danny had a way to control his Thor with a PS3 controller and a Bluetooth so I decided to try it too.
I took a HC-05 Bluetooth controller that I purchased some time ago and make it operate via an Arduino nano (left in the picture). But I never managed to detect that HC-05, I am wondering if it is defective.
(The right is an ESP8266 - ESP12 I am toying with, but will not be part of the Thor project)
I got feedback from Danny to get this USB Host controller board 2.4 http://www.hobbytronics.co.uk/usb-host-board-v2 (17.89€)
This USB host controller board that operates on I2C and Rx/Tx seems to contain a firmware to connect to my PS3 controllers that I still have here.
You also need to purchase a Bluetooth dongle 4.0 http://www.hobbytronics.co.uk/wireless/bluetooth-4-dongle (6.46€) separately
If I can find free time from my other priorities I will definately love to try it this weekend.
-
Standing Controller box, warping issues
02/12/2017 at 03:00 • 1 commentThis weekend I finalize the Standing Controller box 3D printing from Danny. I love the design and he demonstrated a lot of creativity. This print took 13h26 min.
But my 3D printer and ABS plastic had a lot of warping issues.I will look out for other ABS plastic that may have less warping issues. Or maybe next time I just use PLA instead.
It started like it would print normally. I took special precautious to make it was extra sticky to the heat bed by pouring a bit of acetone on it and then scrub it with leftover ABS. That plastic melted on the heat-bed and created a better sticking layer.
The first 5 mm went perfect with solid sticking on the bed. But as the print grew it actually started to pull the plastic from the heat-bed. And the fact that I also have splits in the layers in between means that I probably need a temperature controlled enclosure.
I can also repair the holes with some pasture or ABS hiding.
Side view to show the ventilator hole
Top view with the Ultratronic v1.0 pro board inserted to see if it did fit. It appears that the box will be just right.
Partially assembled with the parts I printed last week. Missing in this view are these cool strips that can be colored differently and then inserted into the groves.
The lid on the right, I printed yesterday and was a 7 hour job. It also had warping issues.
Back view showing the ventilator hole.
I am wondering if the box will be better upside down. I probably want to blow the heat outside the box. But in that case the ventilator needs to be at the top.
Scale comparison with the Thor robot base.
-
Thor statistics/pricing
02/08/2017 at 21:54 • 0 commentsI have just being verifying my statistics on my 3D printer.
This Thor project already has taken 174 hour print and 3 roles of ABS plastic of 0.75 Kg (21 Euro's each).
This is 2.21 Kg plastic and my cost around €50.After next weekend I need to add 20H printing so the total will become 194 hours.
The 7 stepper motors costed me around €140.
The Ultratronics v1.0 pro board €150
The big ball bearing was €50 if I recall.
100W power supply was €100.
The total cost at this moment seems to be >€500 at this moment probably around €600 so far.
Total waste is €50 (plastic) €550 total reusable.But every cent is worth the experience I get back and all components can be recycled for newer projects. Not to say the enormous joy you get when you build it with your own hands.