|
| 1 | +#include "LinearHall.h" |
| 2 | + |
| 3 | +// This function can be overridden with custom ADC code on platforms with poor analogRead performance. |
| 4 | +__attribute__((weak)) void ReadLinearHalls(int hallA, int hallB, int *a, int *b) |
| 5 | +{ |
| 6 | + *a = analogRead(hallA); |
| 7 | + *b = analogRead(hallB); |
| 8 | +} |
| 9 | + |
| 10 | +LinearHall::LinearHall(int _hallA, int _hallB, int _pp){ |
| 11 | + centerA = 512; |
| 12 | + centerB = 512; |
| 13 | + pinA = _hallA; |
| 14 | + pinB = _hallB; |
| 15 | + pp = _pp; |
| 16 | +} |
| 17 | + |
| 18 | +float LinearHall::getSensorAngle() { |
| 19 | + ReadLinearHalls(pinA, pinB, &lastA, &lastB); |
| 20 | + //offset readings using center values, then compute angle |
| 21 | + float reading = _atan2(lastA - centerA, lastB - centerB); |
| 22 | + |
| 23 | + //handle rollover logic between each electrical revolution of the motor |
| 24 | + if (reading > prev_reading) { |
| 25 | + if (reading - prev_reading >= PI) { |
| 26 | + if (electrical_rev - 1 < 0) { |
| 27 | + electrical_rev = pp - 1; |
| 28 | + } else { |
| 29 | + electrical_rev = electrical_rev - 1; |
| 30 | + } |
| 31 | + } |
| 32 | + } else if (reading < prev_reading) { |
| 33 | + if (prev_reading - reading >= PI) { |
| 34 | + if (electrical_rev + 1 >= pp) { |
| 35 | + electrical_rev = 0; |
| 36 | + } else { |
| 37 | + electrical_rev = electrical_rev + 1; |
| 38 | + } |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + //convert result from electrical angle and electrical revolution count to shaft angle in radians |
| 43 | + float result = (reading + PI) / _2PI; |
| 44 | + result = _2PI * (result + electrical_rev) / pp; |
| 45 | + |
| 46 | + //update previous reading for rollover handling |
| 47 | + prev_reading = reading; |
| 48 | + return result; |
| 49 | +} |
| 50 | + |
| 51 | +void LinearHall::init(int _centerA, int _centerB) { |
| 52 | + // Skip configuring the pins here because they normally default to input anyway, and |
| 53 | + // this makes it possible to use ADC channel numbers instead of pin numbers when using |
| 54 | + // custom implementation of ReadLinearHalls, to avoid having to remap them every update. |
| 55 | + // If pins do need to be configured, it can be done by user code before calling init. |
| 56 | + //pinMode(pinA, INPUT); |
| 57 | + //pinMode(pinB, INPUT); |
| 58 | + |
| 59 | + centerA = _centerA; |
| 60 | + centerB = _centerB; |
| 61 | + |
| 62 | + //establish initial reading for rollover handling |
| 63 | + electrical_rev = 0; |
| 64 | + ReadLinearHalls(pinA, pinB, &lastA, &lastB); |
| 65 | + prev_reading = _atan2(lastA - centerA, lastB - centerB); |
| 66 | +} |
| 67 | + |
| 68 | +void LinearHall::init(FOCMotor *motor) { |
| 69 | + if (!motor->enabled) { |
| 70 | + SIMPLEFOC_DEBUG("LinearHall::init failed. Call after motor.init, but before motor.initFOC."); |
| 71 | + return; |
| 72 | + } |
| 73 | + |
| 74 | + // See comment in other version of init for why these are commented out |
| 75 | + //pinMode(pinA, INPUT); |
| 76 | + //pinMode(pinB, INPUT); |
| 77 | + |
| 78 | + int minA, maxA, minB, maxB; |
| 79 | + |
| 80 | + ReadLinearHalls(pinA, pinB, &lastA, &lastB); |
| 81 | + minA = maxA = centerA = lastA; |
| 82 | + minB = maxB = centerB = lastB; |
| 83 | + |
| 84 | + // move one mechanical revolution forward |
| 85 | + for (int i = 0; i <= 2000; i++) |
| 86 | + { |
| 87 | + float angle = _3PI_2 + _2PI * i * pp / 2000.0f; |
| 88 | + motor->setPhaseVoltage(motor->voltage_sensor_align, 0, angle); |
| 89 | + |
| 90 | + ReadLinearHalls(pinA, pinB, &lastA, &lastB); |
| 91 | + |
| 92 | + if (lastA < minA) |
| 93 | + minA = lastA; |
| 94 | + if (lastA > maxA) |
| 95 | + maxA = lastA; |
| 96 | + centerA = (minA + maxA) / 2; |
| 97 | + |
| 98 | + if (lastB < minB) |
| 99 | + minB = lastB; |
| 100 | + if (lastB > maxB) |
| 101 | + maxB = lastB; |
| 102 | + centerB = (minB + maxB) / 2; |
| 103 | + |
| 104 | + _delay(2); |
| 105 | + } |
| 106 | + |
| 107 | + //establish initial reading for rollover handling |
| 108 | + electrical_rev = 0; |
| 109 | + prev_reading = _atan2(lastA - centerA, lastB - centerB); |
| 110 | +} |
0 commit comments