スマホで動くロボットアームを作る

スマホで動くロボットアームを作る

 

続き

今回は回転方向の指定と連続的に受信しながらステッピングモーターの駆動をしていきます。

 

今回のプログラム

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軸でしか確認出来ていない。早くゲタ来ないかなぁ

 

動作の様子


www.youtube.com

 

テスト用としては問題なく動いたが回転方向のデータが先頭に無くてはならず実際の制御には使えない。

 

ここが一番悩ましい所。

 

はて、どうしたものか?

 

また、更新します。