適当に書いたスケッチです。正しくないかも知れません。無保証です。
Aruduino nanoとステッピングモータドライバ、タクトスイッチ、小型LCDの接続はスケッチの先頭に#defineしています。スイッチの反対側のピンはGNDです。
時計の秒針のように精確な1rpm(回転/60秒)を実現するために、Timer1割り込みでパルスを作って回転/5秒(12rpm)を基準にしています。1回転4秒でも回りましたが、5秒の倍数にしたほうがrpmを細かく分けられたのでこうしました。
//------------------------------------------------------------------
// 21.07.07 naka
// ステッピングモータのテスト
// P1-P4: ステッピングモータのドライバの各ピン
// SW1 : タクトスイッチ(アクティブLow) 回転方向切り替え
// SW2 : タクトスイッチ(アクティブLow) 回転角度切り替え(+90度)0度は連続回転
// SW3 : タクトスイッチ(アクティブLow) 回転RPM切り替え(1~12)
// SW4 : タクトスイッチ(アクティブLow) Start/Stop
// SDAPIN,SLCPIN : 小型液晶ディスプレイのI2C
//
// Timer1割り込みで5秒/回転(2,048Step)するパルス409.6Hzを生成
//------------------------------------------------------------------
#define P1 2
#define P2 3
#define P3 4
#define P4 5
#define SW1 6
#define SW2 7
#define SW3 8
#define SW4 9
#define SDAPIN A4
#define SCLPIN A5
#include <FaBoLCDmini_AQM0802A.h>
FaBoLCDmini_AQM0802A lcd;
#define steps_per_rotation 2048
volatile int timer1_flag;
volatile int ph_cnt,rpm_cnt,deg_cnt;
int rpm_i,rpm_mag,dir;
long deg,deg_step;
int run_flag;
int rpm_tbl[6][2] = {1,12, // 1rpm, 5秒を12倍
2,6, // 2rpm
3,4, // 3rpm
4,3, // 4rpm
6,2, // 6rpm
12,1}; //12rpm, 1: 5秒/回転(これが基準)
void setup() {
pinMode(P1, OUTPUT);
pinMode(P2, OUTPUT);
pinMode(P3, OUTPUT);
pinMode(P4, OUTPUT);
pinMode(SW1, INPUT_PULLUP);
pinMode(SW2, INPUT_PULLUP);
pinMode(SW3, INPUT_PULLUP);
pinMode(SW4, INPUT_PULLUP);
motor_off();
ph_cnt = 0;
// Timer1設定
TCCR1A = 0;
TCCR1B = 0;
// 5秒/回転 2048/5 = 409.6Hz
// 1/409.6 = 0.00244140625 sec
// 0.00244140625*16MHz = 39,062.5 (0.5は割り込み交互に吸収)
TCNT1 = 26474; // offset 65536-39062 = 26474 と
// 65536-39063 = 26473 を交互
TCCR1B |= (1 << CS10); // プリスケーラ 1
// モニタLCD設定
SetupLCD();
dispLCD_start();
rpm_cnt = 0;
rpm_i = 0;
rpm_mag = rpm_tbl[rpm_i][1]; // 基準5秒/回転の倍数
dir = 0; // 右回転
deg = 0; // 90度
deg_step = steps_per_rotation * deg / 360; // ステップ数
deg_cnt = 0;
dispLCD();
run_flag = 0;
TIMSK1 |= (1 << TOIE1); // Timer1イネーブル
}
byte ph1[4][4] = { // 1相励磁
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
};
ISR(TIMER1_OVF_vect) {
if (timer1_flag==1)
TCNT1 = 26474;
else
TCNT1 = 26473;
timer1_flag ^= 1;
rpm_cnt+=1;
if(run_flag==1 && rpm_cnt==rpm_mag) {
if (deg_cnt<deg_step || deg_step==0) {
digitalWrite(P1,ph1[ph_cnt][0]);
digitalWrite(P2,ph1[ph_cnt][1]);
digitalWrite(P3,ph1[ph_cnt][2]);
digitalWrite(P4,ph1[ph_cnt][3]);
if (dir==0)
ph_cnt = (ph_cnt+1)%4;
else {
ph_cnt -= 1;
if(ph_cnt<0) ph_cnt = 3;
}
rpm_cnt = 0;
deg_cnt++;
}
else if (deg_cnt == deg_step) { // 規定数回転したのでstop
run_flag = 0;
motor_off();
}
}
}
void loop() {
checkSW(); // タクトスイッチ状態確認
}
void checkSW() {
if (digitalRead(SW1)==LOW) { // direction
dir ^= 1; // 回転方向逆転
dispLCD();
while(digitalRead(SW1)==LOW);
}
else if (digitalRead(SW2)==LOW) { // rpm
rpm_i = (rpm_i+1)%6;
rpm_mag = rpm_tbl[rpm_i][1];
rpm_cnt = 0;
dispLCD();
while(digitalRead(SW2)==LOW);
}
else if (digitalRead(SW3)==LOW) { // degree
deg += 45;
if (deg>360) deg = 0;
deg_step = steps_per_rotation * deg / 360;
deg_cnt = 0;
dispLCD();
while(digitalRead(SW3)==LOW);
}
else if (digitalRead(SW4)==LOW) { // Start/Stop
run_flag ^= 1;
if (run_flag==0) motor_off();
deg_cnt = 0;
rpm_cnt = 0;
while(digitalRead(SW4)==LOW);
}
delay(10); // チャタリング回避
}
void motor_off() {
digitalWrite(P1,LOW);
digitalWrite(P2,LOW);
digitalWrite(P3,LOW);
digitalWrite(P4,LOW);
}
void dispLCD_start() {
lcd.clear();
lcd.print("STEPPING");
lcd.setCursor(0, 1); // Col,Raw
lcd.print(" MOTOR");
delay(1000);
dispLCD();
}
void dispLCD() {
char buff[10];
char dir_txt[2];
if (dir) strcpy(dir_txt,"L");
else strcpy(dir_txt,"R");
lcd.clear();
lcd.setCursor(0, 0); // Col,Raw
sprintf(buff,"%s %3dDEG",dir_txt,deg);
lcd.print(buff);
lcd.setCursor(0, 1); // Col,Raw
sprintf(buff," %2dRPM",rpm_tbl[rpm_i][0]);
lcd.print(buff);
}
void SetupLCD() {
lcd.begin();
lcd.command(0x38);
lcd.command(0x39);
lcd.command(0x14);
lcd.command(0x73);
lcd.command(0x51); // 5V
// lcd.command(0x56); // 3.3V
delay(2);
lcd.command(0x6c);
delay(300);
lcd.command(0x38);
delay(1);
lcd.command(0x01);
delay(2);
lcd.command(0x0c);
delay(2);
}
//------------------------------------------------------------------
// EOF
//------------------------------------------------------------------
0 件のコメント:
コメントを投稿