サーボの駆動 / パン・チルト機構にサーボを組み込んでジョイスティックで動かす


f:id:ti-nspire:20190912145302p:plain:h270

プログラムは前回とほぼ同じ。x軸は動きを逆にした。

#include <avr/io.h>
#include <util/delay.h>
#include "mylib.h"

// パルス幅の範囲を決めておく。
#define PULSE_MID         1500
#define PULSE_RANGE_FULL  800
#define PULSE_RANGE_HALF (PULSE_RANGE_FULL / 2)
#define PULSE_MIN        (PULSE_MID - PULSE_RANGE_HALF)
#define PULSE_MAX        (PULSE_MID + PULSE_RANGE_HALF)

// ジョイスティックの実測値
#define X_MIN 254
#define X_MID 523
#define X_MAX 782
#define Y_MIN 244
#define Y_MID 518
#define Y_MAX 791

void initTimer1Servo(){
    TCCR1A |= (1 << WGM11);
    TCCR1B |= (1 << WGM12) | (1 << WGM13);   // 16ビット、Fast PWMモード
    TCCR1B |= (1 << CS11);                   // 8MHzを8分周してカウント
    ICR1    = 20000;                         // TOP値。Timer1の周期を20000usecにする。
    TCCR1A |= (1 << COM1A1) | (1 << COM1B1); // PB1、PB2の両端子からPWM波を出力する。
    OCR1A   = PULSE_MID;
    OCR1B   = PULSE_MID;
}

void enableServo(){
    while(TCNT1 < 3000){;}           // 制御パルスの途中で何かが始まらないようにする。
    DDRB |= (1 << PB1) | (1 << PB2); // 当該ピンのIOをOUTにしてPWMを出力
}

void initADC(){
    ADMUX  |= (1 << REFS0);                // AVCCを基準電圧として使うことにする。
    ADCSRA |= (1 << ADPS2) | (1 << ADPS0); // ADCへ供給するクロックの分周比を決める。ここでは32分周にしておく。
    ADCSRA |= (1 << ADEN);                 // ADCを有効化する。
}

uint16_t readADC(uint8_t ch){
    ADMUX   = ((0xF0 & ADMUX) | ch);       // チャンネル選択ビットを全部一旦クリアしてから目的のチャンネルをセットして、
    ADCSRA |= (1 << ADSC);                 // AD変換を開始して、
    loop_until_bit_is_clear(ADCSRA, ADSC); // AD変換が終わるのを待って、
    return ADC;                            // 10ビット値を返す。
}

int main(){
    initTimer1Servo();
    initADC();

    while(1){
        enableServo();

        // パルス幅が範囲外の値にならないよう念のためcontain()函数を適用しておく。
        OCR1A = contain(map(readADC(PC4), X_MAX, X_MIN, PULSE_MIN, PULSE_MAX), PULSE_MIN, PULSE_MAX); // x-axis, pan
        OCR1B = contain(map(readADC(PC5), Y_MIN, Y_MAX, PULSE_MIN, PULSE_MAX), PULSE_MIN, PULSE_MAX); // y-axis, tilt
        _delay_ms(50);
    }

    return 0;
}

※ テキストは全然別のもっと手の込んだ工作とプログラミングをしているがそれは今後の課題としてChapter11: Driving Servo Motorsはこのへんでやめておく。