5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AtTiny13Aでラジコンサーボのコントロール

Last updated at Posted at 2018-08-28

#はじめに
AtTiny13Aを使用してボリュームの角度に応じてラジコンサーボを動作させるだけのテスト回路を作成します。ラジコンサーボのちょっとしたテストに便利に利用可能です。
image.png

#用意するもの
##AtTiny13a開発環境
以下の4つです。詳しくはAtmelStudioとUSBtinyISPでAVR(AtMega, ATtin)の開発環境を作るを参照ください。

  1. Atmel Studio
  2. USBtinyISP
  3. AVR
  4. ArduinoIDE

#接続
ボリュームで電源を分圧しADC2に入力、PB0からサーボ出力するだけです。
image.png

#プログラム
高速モード(9.6MHz)で動作させ、100kHzで割り込みをかけます。割り込み100回で1msecとなります。ボリュームのADC読取データを100から210にスケーリングしています。

ServoControlByVolume.cpp
/*
 * ServoControl.cpp
 *
 * Created: 22-Aug-18 09:44:06
 * Author : ikeda
 */ 

// For delay.h
#ifndef F_CPU
#define	F_CPU	9600000UL		// 9.6MHz
#endif

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile unsigned int Tick;	// 100KHz pulse
volatile unsigned int sPulse;	// Servo pulse variable
volatile unsigned int Tick_20ms;	// Servo frame variable

unsigned char AnalogRead8bit(unsigned char Ch);
unsigned int AnalogRead(unsigned char Ch);


int main (void)
{
	sei(); //  Enable global interrupts
	DDRB |= (1<<PB0) | (1<<PB1); // PB0 and PB1 as outputs
	TCCR0A |= (1<<WGM01); // Configure timer 1 for CTC mode
	TIMSK0 |= (1<<OCIE0A); // Enable CTC interrupt
	OCR0A = 95; // Set CTC compare value
	TCCR0B |= (1<<CS00); // No prescaler
	Tick = 0;
	sPulse = 100;
	Tick_20ms = 0;

	unsigned long VolumeRead = 0;
	while(1)
	{
		VolumeRead = AnalogRead(2);
		
		// 1000 - 2100にスケーリング(1ms - 2.1ms)
		int setValue;
		setValue = 10 + (VolumeRead*2/10);
		sPulse = setValue ;
		_delay_ms(10);
	}
}

ISR(TIM0_COMPA_vect)	// 100 KHz interrupt frequency
{
	if(Tick >= 2000)	// One servo frame (20ms) completed
	{
		Tick = 0;
		Tick_20ms = Tick_20ms + 1;
	}

	Tick = Tick + 1;
	if(Tick <= sPulse)	// Generate servo pulse
	{
		PORTB |= (1<<PB0);	// Servo pulse high
	}
	else
	{
		PORTB &= ~(1<<PB0);	// Servo pulse low
	}
}

// https://blog.goo.ne.jp/paramako/e/aaea8ec6c7618ca6e083c95776c551d1
unsigned char AnalogRead8bit(unsigned char Ch)
{
	//8bit分解能で十分なのを前提に設定を行っている。
	
	//デジタル入出力からの切り離し
	DIDR0
	= (0<<ADC0D)	//ADC0ピンの切り離し。しかし、ADC0はリセット端子になってるから設定しちゃダメ
	| (0<<ADC1D)	//同ADC1
	| (1<<ADC2D)	//同・・
	| (0<<ADC3D);	//同・・
	
	ADMUX
	= (0<<REFS0)	//Reference: 0でVCC参照, 1で1.1V内部電圧源
	| (1<<ADLAR)	//ADC Left Adjust Result: 1にセットすると左詰で結果を出してくる
	| (Ch);			//ADMUX1, ADMUX0で入力チャンネルを選べる 00から11までADC0からADC3まで対応
	
	ADCSRA
	= (1<<ADEN)		//ADC enable
	| (1<<ADSC)		//ADC Start Conversion 1にすると変換開始
	| (0<<ADATE)	//ADC Auto Trigger Enable (for Continuous Conversion)
	| (0<<ADIF)		//ADC Interrupt Flag	変換完了すると1になるらしい
	| (0<<ADIE)		//ADC Interrupt Enable 変換完了したときに割り込み許可
	| (0b100);		//Clock Division: ADコンバータはクロック50-200kHzで性能がよい
	//分周は0のとき2、それ以上の時2^n分周	1.2MHz(Default)のとき16分周(100)で75kHz。9.6MHzのとき128分周(111)で75kHz
	loop_until_bit_is_set(ADCSRA,ADIF);	//ADIFビットが1になるまでムダループ
	return ADCH;
}



unsigned int AnalogRead(unsigned char Ch)
{
	//10bit分解能用ルーチン
	
	//デジタル入出力からの切り離し
	DIDR0
	= (0<<ADC0D)	//ADC0ピンの切り離し。しかし、ADC0はリセット端子になってるから設定しちゃダメ
	| (0<<ADC1D)	//同ADC1
	| (1<<ADC2D)	//同・・
	| (0<<ADC3D);	//同・・

	ADMUX
	= (0<<REFS0)	//Reference: 0でVCC参照, 1で1.1V内部電圧源
	| (0<<ADLAR)	//ADC Left Adjust Result: 1にセットすると左詰で結果を出してくる
	| (Ch);			//ADMUX1, ADMUX0で入力チャンネルを選べる 00から11までADC0からADC3まで対応
	
	ADCSRA
	= (1<<ADEN)		//ADC enable
	| (1<<ADSC)		//ADC Start Conversion 1にすると変換開始
	| (0<<ADATE)	//ADC Auto Trigger Enable (for Continuous Conversion)
	| (0<<ADIF)		//ADC Interrupt Flag	変換完了すると1になるらしい
	| (0<<ADIE)		//ADC Interrupt Enable 変換完了したときに割り込み許可
	| (0b100);		//Clock Division: ADコンバータはクロック50-200kHzで性能がよい

	//分周は0のとき2、それ以上の時2^n分周	1.2MHz(Default)のとき16分周(100)で75kHz。9.6MHzのとき128分周(111)で75kHz
	loop_until_bit_is_set(ADCSRA,ADIF);	//ADIFビットが1になるまでムダループ

	return ADC;

}

#Fuse設定
初期値はクロック設定が低速になっています(1.2MHz)ので、高速(9.6MHz)にする必要があります。

FUSE_INITIAL(LOWSPEED)
CKSEL1 = 1
CKSEL0 = 0 

これを高速に設定する必要があります。

FUSE_HIGHSPEED
CKSEL1 = 0
CKSEL0 = 1

#テスト
HDDのブラシレスモータをラジコン用ブラシレスモータコントローラで回してみました。最高速にするとちょっと怖いです。

image.png

#基板に
ユニバーサル基板に載せて完成です。
image.png

#おわりに
このようなツールを作っておくとデバッグに役に立つかと思います。

2018/08/28 Ikeda

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?