I'm starting this thread in order to begin a discussion on potential Governor systems for use with Arducopter.
Malcolm Churn started talking to me about it a few days ago and it seems like something that is worthwhile pursuing if the AC system is ever intended to be used for truly autonomous sUAS, particularly any Helis with engines. External systems are already available, but this seems like the perfect opportunity to use the power of the APM to build-in a dedicated system.
Currently, my thinking is to use a small Arduino board which will be connected to a hall effect sensor, and relay a speed signal back to the APM. The APM will take the speed feedback, and use a tunable PID loop, with feed-forward from the pitch control system. The reason that a seperate Arduino would be used is because I believe the sensing needs to be done on a very fast loop, and interupt driven. I'd rather not burden the APM with this.
I'd also like to add some functionality for automatic soft-start.
Other features would include rotor speed telemetry. And in the future, the possibility of rotor speed droop warnings and maybe even automatic auto-rotation (yeah, we can dream, right?)
One big question I have it how to get the signal between the Govern-Duino and the APM. Analog 0-5V would be easy and is somewhat of a standard in industrial use, but subject to noise. I'd prefer something like PWM. But I'd like to do it without "wasting" one of the 8 radio channel inputs, so need to investigate is there is an open PWM input we can use.
We may also discuss third-paryt governors already on the market for ideas, or potential use if they make sense.
Had some success tonight. I got the Uno to read the hall effect sensor.
The results are a little strange. When I tried it at my cottage, it's in a remote area, not too much around. I was working on my laptop plugged into AC. Uno was running off of USB power. I noticed that if left to float, the trigger pin would return a somewhat random RPM reading. However, if I used a jumper wire to either ground, or 5V, then the pulses would stop showing up entirely. Makes sense.
Tonight I'm on the same laptop, but in my basement, surrounded by flourescent lighting. When left to float, the pin measures 3600 rpm. 60 Hz. Huh. Interesting. However, if I use a jumper to ground, or power, the pulses keep coming in, but now are somewhat random.
Anyway, I used a pullup resistor between power and the signal pin. My research showed this is required as the Hall Effect Sensor actually has a transistor as a final output stage, and the signal pin gets pulled to ground. So the pullup resistor is required to bring the open circuit voltage to 5V, and then when the sensor detects the magnet, it drains it to ground, pulling the voltage to 0, triggering the interrupt.
I tested this by putting magnets on a drill bit and turning it in my drill. I was able to read up to 1350 rpm, quite stable, and was able to vary the drill speed and see the changes in the serial monitor.
But then I read that the Atmega has internal pullup resistors, which would stop the random flickering, and should also be eliminate the need for the external pullup resistor. But, neither worked. After disconnecting the external pullup, and modifying the code to connect the internal pullup, the flickering still happens, and the Hall sensor doesn't work.
Reconnect the external pullup and it's all good.
Anybody know anything about this?
Anyway, I have the basics of the rpm reading working now. I'll probably test it on a known rpm source, namely my mill with fixed RPM's, or relatively fixed... But I should be able to proceed with the rest of it soon.
Internal pull-ups aren't good for much, external pull-ups are usually recommended for just about everything. Most processor data sheets I've looked at mention this.
Could it be possible that you don't have them turned on correctly? Check the pin register and the PUD bit in MCUCR. PUD bit will disable all pullups.
You could also check the pins with a meter to see if they're actually on.
Jake, how do I check that? I'm simply using the standard Arduino pinMode and digitalWrite commands.
Also, if it makes any difference, I'm using attachInterrupt on this pin for the hardware interrupt. I just find it very strange that the signal is that noisy when left to float. And that it doesn't stabilize at all if I use a jumper to pull it to ground or 5V. Makes me think something is wrong.
Anyway, hopefully today I will be able to continue with the bulk of the motor control program. The plan is sof far that I will use a #define to set the target RPM. I will also use another input pin as the start/stop command. Just for simplicity at this point. Eventually I want to have bi-directional control between the APM and the governor.
I plan to run the main motor speed control loop at 50Hz, but may run the RPM sensor at 1000Hz, allowing for 20 samples to be used for each control loop run. But I also plan to take some standard deviation measurements so that I can publish a "signal quality" number, just to get some idea of what's going on. Ultimately I'd like to be able to warn the user if there's a sensor problem.
I'm a little unsure how to control the speed at this point. The output of the system will be a PWM that the ESC can use. And obviously I will have rotor speed feedback. PWM output to the ESC will roughly translate to motor torque, but not RPM in any way. But I don't have any torque feedforward. So if I'm using a PID loop to control it, it's going to have to be heavy on the I-term which will do the bulk of the work. Because obviously if the rotor speed reaches the target speed, P-term will give zero, but something has to hold the torque up.
I'll be having a closer look at the variable speed drive controllers I use at work for inspiration.
Duh, I sure won't get 20 samples in order to use to filter at 50Hz! Obviously 2000 RPM is only ~33rev/sec. So if the magnet is on the main shaft, you won't even get a single data point for every 50Hz loop run!
So the question will be, so we measure motor RPM? Or main shaft RPM? Ultimately what we're interested in is the rotor RPM. This is what we would want to control in a theoretical autorotation. But the rotor speed doesn't give us a lot of samples to work with.
Theoretically it's possible to run two RPM sensors, one on the rotor, and one on the motor, since we have two hardware interrupts. This would actually allow us to detect motor failure, before the rotor RPM becomes critical.
I had already thought about offering some options. You could set it up to monitor rotor rpm, motor rpm, or both. Or, twin motors. (you may now be seeing the linkage with my other post about twin motor helis ;) I think it would be impossible to run two ESC's in governor mode on a single shaft. So having an external twin-motor governor allows that. :)
Anyway, back to the PID stuff.
So I looked at the manual of an industrial speed controller, and it goes into detail on the main speed control loop. It's a basic PI loop, with a speed demand as the setpoint, and speed feedback. The error is multiplied by the Pterm, and then there is an I-term as well.
But where it's interesting, is that the output of the PI loop is summed with an Aux Torque Demand. The output of that is then the total torque demand. I think this is really interesting. I was already trying to figure out how I could use collective pitch input data as a feed-forward. And there it is, very simply.
At it's simplest, the Aux Torque Demand can be a fixed value, equal to whatever torque it takes to run the rotor at the target speed zero pitch. This could be tuned with a simple routine where the user straps the heli down, sets the collective pitch at zero, and runs it up to the target speed. Now it will have a base with which to start, so that we don't always have to wait for the I-term to ramp up. The PI loop will only have to respond to errors generated by collective pitch changes.
Ideally, I'd love to get to the point where we feed collective pitch data to the controller, to allow it to respond before the motor speed droops even a little bit. But we'll get to that later.