я бы сделал так
каждая серва имеет следующие переменные (можно завести талички в проге на все серы сразу)
servo_zero_pwm - сигнал соответствующий нулю (это не всегда 1500)
servo_min_pwm - сигнал соответствующий минимальному углу наклона
servo_min_angle - минимальный угол
servo_max_pwm - сигнал максимального угла
servo_max angle - максимальный угол
сама калибровка следующая:
- серы развязываются механически , чтобы они были независимы
- на серву подается сигнал pwm (1500) и устанавливаются качалки близко к требуемому положению нуля
- на качалку крепится какой либо вспомогательный удлиннитель для более точного определения угла на большем расстоянии от центра.
Разумеется удлинитель не должен сам вносить искажения или сдвиг от направления задаваемого качалкой, тогда лучше вообще без него. я использовал щечку плеча манипулятора - изменением сигнала на серву добиваемся точного нуля градусов (изменение pwm -> 0 angle), запоминаем переменную servo_zero_pwm
- далее сняв сигнал с серы устанавливаем механически максимально возможный угол, замеряем его, заполняем переменную servo_max_angle
- подав сигнал на серву добиваемся повторения максимального угла (без натяга от упора в ограничители !). Запоминаем полученное значение управляющего сигнала (servo_max_pwm)
- пункты 5-6 повторяются для минимума
- и весь процесс калибровки (пункты 2-7) повторяются для всех серв. Разумеется сервы которые мы будем синхронизировать должны иметь одинаковые значения углов servo_max_angle и servo_min_angle
далее идет математика
заданный угол в значениях pwm:
target_pwm=target_angle*((servo_max_pwm - servo_min_pwm)/(servo_max_angle - servo_min_angle)) + servo_zero_pwm
видно что параметр ((servo_max_pwm - servo_min_pwm)/(servo_max_angle - servo_min_angle)) нет смысла вычислять каждый раз,
его нужно посчитать и сохранить как калибровачный коэффициент (тип float).
в итоге в результате калибровки для каждой сервы мы имеем пару значений : servo_zero_pwm (unsignet int) и некий коэффициент (float)
эта методика работает и на встречных осях серв, когда направление одной из них перевернуто. Все будет учтено автоматически, мы лишь получим отрицательный коэффициент и всё должным образом посчитается по тем же формулам:
target_pwm=target_angle*k + servo_zero_pwm
обычно коэффициент равен 10 - 12 с точностью 2-3 знака после запятой