スマホで動くロボットアームを作る
続き
今回は回転方向の指定と連続的に受信しながらステッピングモーターの駆動をしていきます。
今回のプログラム
byte stepPins = {15, 0, 5, 19, 22, 32, 25, 27};
byte dirPins = {2, 4, 18, 21, 23, 33, 26, 14};
byte step_data1[10001] = {0};
byte step_data2[10001] = {0};
byte inData = 0;
int pos = 0;
int num = 1;
byte direction1 = 0;
byte direction2 = 0;
boolean toggle_set = true;
boolean toggle_get = false;
boolean start = false;
hw_timer_t * timer = NULL;
void IRAM_ATTR onTimer() {
if (!start)
return;
if (num == 1) {
if(toggle_set) // 初回 true
setDirection(direction1);
else
setDirection(direction2);
}
if(toggle_set) // 初回 true
rotation1(num);
else
rotation2(num);
num++;
if (num == 10001) {
num = 1;
toggle_set = !toggle_set;
}
}
void setup() {
for (int i = 0; i < sizeof(stepPins); i++) {
pinMode(stepPins[i], OUTPUT);
}
for (int i = 0; i < sizeof(dirPins); i++) {
pinMode(dirPins[i], OUTPUT);
}
Serial.begin(115200);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 100, true);
timerAlarmEnable(timer);
}
void loop() {
if (Serial.available() > 0) {
inData = Serial.read();
if (pos == 0) {
if(toggle_get) // 初回 false
direction2 = inData;
else
direction1 = inData;
pos++;
}
else {
if(toggle_get) // 初回 false
step_data2[pos++] = inData;
else
step_data1[pos++] = inData;
if (pos == 10001) {
pos = 0;
toggle_get = !toggle_get;
start = true;
}
}
}
}
void setDirection(byte d) {
digitalWrite(dirPins[0],d & 0x01);
digitalWrite(dirPins[1],d & 0x02);
digitalWrite(dirPins[2],d & 0x04);
digitalWrite(dirPins[3],d & 0x08);
digitalWrite(dirPins[4],d & 0x10);
digitalWrite(dirPins[5],d & 0x20);
digitalWrite(dirPins[6],d & 0x40);
digitalWrite(dirPins[7],d & 0x80);
}
void rotation1(int num) {
digitalWrite(stepPins[0],step_data1[num] & 0x01);
digitalWrite(stepPins[1],step_data1[num] & 0x02);
digitalWrite(stepPins[2],step_data1[num] & 0x04);
digitalWrite(stepPins[3],step_data1[num] & 0x08);
digitalWrite(stepPins[4],step_data1[num] & 0x10);
digitalWrite(stepPins[5],step_data1[num] & 0x20);
digitalWrite(stepPins[6],step_data1[num] & 0x40);
digitalWrite(stepPins[7],step_data1[num] & 0x80);
}
void rotation2(int num) {
digitalWrite(stepPins[0],step_data2[num] & 0x01);
digitalWrite(stepPins[1],step_data2[num] & 0x02);
digitalWrite(stepPins[2],step_data2[num] & 0x04);
digitalWrite(stepPins[3],step_data2[num] & 0x08);
digitalWrite(stepPins[4],step_data2[num] & 0x10);
digitalWrite(stepPins[5],step_data2[num] & 0x20);
digitalWrite(stepPins[6],step_data2[num] & 0x40);
digitalWrite(stepPins[7],step_data2[num] & 0x80);
}
改造点
step_dataを2セット用意して交互に受信したデータを書き込み対のデータでステッピングモーターを制御する。
onTimer()の割り込みを1ms → 0.1msに変更した。1秒ごとにシリアル通信で10001バイト受け取り(1バイトは回転方向の指示用)
1ms → 0.1msで情報量が一気に10倍になったが上手く通信できている。
と言っても2軸でしか確認出来ていない。早くゲタ来ないかなぁ
動作の様子
テスト用としては問題なく動いたが回転方向のデータが先頭に無くてはならず実際の制御には使えない。
ここが一番悩ましい所。
はて、どうしたものか?
また、更新します。