-
Works fine, but what do I know?
03/16/2015 at 04:14 • 0 commentsFinally.
The weather was nice enough yesterday to try autotuning outside. The battery held out for about a minute each of pitch and roll tuning and long enough to write the results to EEPROM to dump out at home. I ended up with PIDs that seem to work great for my Q4 as defaults in the code. It flies just about as well as I remember the stock firmware behaving, which given my untrained thumbs is like saying Apple earbuds sound as good as $30k Sennheiser Orpheus headphones. It even works with the original remote.
There's still work to be done: change PID tuning TX channel to something less destructive, more code cleanups (most importantly pull from victzh's latest commit), better documentation, test unlock procedure on a new Q4.
-
Recap #6: Moving slowly
03/16/2015 at 04:03 • 0 commentsI went a few rounds with PID autotuning in the living room after the kids were asleep. It's been constant nasty weather for the last few weeks, so I couldn't get outside so the Q4 could have more room for its autotuning dance.
Meanwhile I discovered the LED mappings for both the X4 and Q4 weren't right, I merged Q4 and X4 configurations together as much as possible, and found the right scaling factor for the battery voltage.
-
Recap #5: Abusing the debug port
03/16/2015 at 03:50 • 0 commentsSo it turns out BradWii can do autotuning of the PID coefficients. It pitches and rolls +/- 15 degrees, systematically varying each coefficient until it converges. Once the tuning is done, the new coefficients can be saved to EEPROM. Autotune is started, stopped, and parameters saved using an extra TX channel so that it can be started when the quad is hovering in an open space. The consensus is that the BradWii autotuning is very effective as long as the initial PIDs are good enough to get into a hover.
I planned to use autotuning to find workable PID coefficents and pull them out of the EEPROM with the debugger. I bought a Hubsan X4 for its remote (now I'm in deep...) which is compatible with the Q4 but has a couple of pushbutton channels, one of which I'd use to control the autotuning. But not long after I started playing with autotune I realized that the battery voltage ADC wasn't tripping the low battery detection at all. I needed to know what the ADC was reading, and while it could be done with memory inspection it would be easier if I had a stdout to printf to...
Fortunately ARM specifies a standard for "semihosting", or sending arbitrary data between the debug host and target applications via the debug port. The standard specifies fairly straightforward stdio and file operations that the target application can ask the debug host to perform. One of these prints a null-terminated string to the debug console. This was exactly what I needed.
I added some inline assembly functions to the serial driver so I could later pipe the UART configuration protocol over SWD. But for now printfs to the screen would be enough. I also had to make the breakpoint ISR check that the breakpoint was for semihosting so it could continue execution if the debugger wasn't attached.
Semihosting works ok in practice if you know the limitations. Or limitation. Semihosting is incredibly slow. It's transferring a 1k file over a 300 baud modem slow. But it's enough to print the autotuned PID parameters from EEPROM on power-up and to print the ADC raw value for debug.
This was the last piece in making BradWii autotuning work and find the right mapping of battery voltage to ADC counts.
-
Recap #4: Flying
03/16/2015 at 02:50 • 0 commentsI ran into a couple of roadblocks in the week since barely getting Bradwii loaded:
BradWii for X4 was configured to arm the motors if the yaw is all the way to the right and the throttle at 0. The stock TX has a range too narrow to hit the default thresholds. The stock TX's case has rounded edges in the stick cutout so the values at the corners are lower than at the extreme of one axis. To get around this I changed the arming combination to low throttle + high pitch and decreased the thresholds until they worked reliably.
I got the Q4 to arm, and the props turned at low throttle. But trying to fly resulted in an instant barrel roll. It took a few days of trial and error, but I eventually realized I had mapped the motor PWM channels 180 degrees from the orientation of the sensors. With fixed motor channels I got the Q4 to hover for a few seconds, but then the shakes set in and ultimately it would power dive into the floor. I hadn't changed the PID coefficients from the X4 defaults so I'm not surprised.
On more formal quadcopters, the PID settings are tuned remotely during flight with a sideband channel, or with a serial cable on a fixture that allows the quad to rotate on one axis on the bench. BradWii has a feature to change certain parameters in realtime and save them to on-chip EEPROM, using the micro's UART for communication. Unfortunately the Q4 has no other external interface but the ARM SWD debug port and is too small to use the usual tricks for running tethered anyway.
The pin map I made showed that the UART pads on the Mini54 were being used for radio SPI framing and the interrupt from the accelerometer, so I couldn't blue wire out the UART. One alternative I considered was using unused bytes in the Hubsan protocol and modifying the TX somehow. The Hubsan TX uses an STM8 micro, but even that board has its UART pins committed to other peripherals. It would also mean a descent into yak shaving as I would have to write my own replacement TX firmware. I also considered using [alvaro]'s work in putting the TX under PC control, but being a relative noob to flying RC things I didn't want to stray far from the handheld transmitter.
-
Recap #3: Bringing up BradWii
03/15/2015 at 05:45 • 0 commentsI spent a few lunch hours poking at BradWii. Usually the ARM fork of BradWii is built in Keil, but TheLastMutt had added project files for Eclipse and GCC. I don't care for Eclipse, but for a small project I'd deal with it. I couldn't get the OpenOCD integration to work. But I discovered that Eclipse can convert its project format into Makefiles, so with exported Makefiles in hand I got the Hubsan X4 build of BradWii to build.
But before any code could be written, I would need to know the pin mapping for the Mini54 to the peripherals. I traced out the pins mapping to the motors, LEDs, battery voltage monitor, gyro, accelerometer, and radio. I forked BradWii on github and made changes to the Hubsan X4 config and support sources to work with that pin map. Along the way I added a target in the main Makefile to erase flash and call OpenOCD for flashing.
Good news is the LEDs blink on power up and change pattern when the TX is turned on, so at least the RX section and the LEDs work. Bad news is that's all it can do right now.
-
Recap: early work #2
03/15/2015 at 05:22 • 1 commentAfter a few iterations of the OpenSCAD model and a week of waiting for the pogo pins I ordered from Sparkfun to come in, I have a working jig. It turns out my photogrammetry was a little off, since it took a couple of iterations of the model to dial in the pin locations. This likely comes from parallax error since I didn't remove the motors when I scanned the board. I also had some problems getting the hole sizes right for the pins since the C and D pins are so close to each other that they wind up a little narrower than the other two.
Next up I soldered wires to the pogo pins and hooked them to the STLink/V2 debugger on a STMicro STM32F0 eval board I had on hand. I found this guide by TheLastMutt for flashing and erasing the contents to remove the flash read/write lock on the Mini54 under OpenOCD.
So what's with the flash lock? Like most micros the Mini54 has a similar feature, preventing most debug port operations including writing flash unless a bulk erase is performed first. Hubsan's firmware is written to the Q4 with this lock enabled.
The code in the guide didn't work without some changes, one being the transport settings needed changing for STLink/V2, and the OpenOCD patch didn't have the right mask for the part ID. My changes in gist form.
After I got OpenOCD and the part to talk, I erased the original firmware to get rid of the flash lock. Unfortunately the lock also prevents reading out the existing contents, so I was stuck with a dead toy until I could get some alternate firmware working. This is the part of the movie where the scientist infects themselves with the deadly mystery virus for motivation to find a cure. I knew that the BradWii firmware supported very similar quads but getting this to work would be a learning experience.
-
Recap: early work #1
03/14/2015 at 15:18 • 0 commentsI bought a Q4 on a whim while browsing the local hobby shop. $30 is impressive given the individual components: CPUs in both the TX and RX, gyro, accelerometer, LiPo battery, motors, and 2-way 2.4GHz radios in the TX and RX. Add to that the part where it flies and it was an easy decision. I also remembered [Alvaro's] deep dive into the TX protocol on this model a couple of months back.
Of course I had to take it apart when I got home. The Q4 is nothing more than a flying PCB with a battery and motors to keep a workable power/weight ratio. The only unnecessary component is the plastic canopy over the battery. This also covers the ICs on the top of the PCB, but leaves the bottom side exposed, including a number of test pads. Fortunately Hubsan was kind enough to label some of these "+", "-", "C", "D". Some Googling revealed that the "HBS002" CPU is really a Nuvoton MINI54 ARM Cortex-M0 CPU. I beeped out the pads, following the "C" and "D" pads to the SWCLK and SWDIO pins on the micro. "+" goes to the 3.3V output rail of what looks like a linear regulator.
I had to go further. I considered soldering to the pads, but thought that even a small header dangling off this copter would affect flight performance. Given the ease of getting to the pads, I decided to make a pogo pin jig using my go-to physical toolchain of a 3D printer and OpenSCAD.
I started on this by getting the positions of the pad centers. The pads aren't evenly spaced, so I needed to measure positions for each relative to a central point. I scanned the bottom of the Q4 on a flatbed scanner and used Gimp and calipers to turn the scan into distances relative to one of the corners.