1. 程式人生 > >基於arduino 6自由度機械臂舵機控制程式

基於arduino 6自由度機械臂舵機控制程式

//直接可以通過上位機或者藍芽模組實現機械臂的控制,只需要把每個舵機轉動角度傳送過來即可

#include <Servo.h> 
Servo myservo[6]; //定義一個comdata字串變數,賦初值為空值

String comdata = "";
//numdata是分拆之後的數字陣列,對應介面的引腳號
int numdata[6] = {0}, PWMPin[6] = {3, 5, 6, 9, 10, 11}, mark = 0;
void setup()
{
//定義0~6腳是輸出
  for(int i = 0; i < 6; i++)  
  {
    //pinMode(PWMPin[i], OUTPUT);
    myservo[i].attach(PWMPin[i]); 
    myservo[i].write(90);        // 指定舵機轉向的角度
    delay(15);                 // 等待15ms讓舵機到達指定位置
  }
                      
  Serial.begin(9600);
}

void loop()
{
//j是分拆之後數字陣列的位置記數
  int j = 0;
  
  //不斷迴圈檢測串列埠快取,一個個讀入字串,
  while (Serial.available() > 0)
  {
  //讀入之後將字串,串接到comdata上面。
    comdata += char(Serial.read());
      //延時一會,讓串列埠快取準備好下一個數字,不延時會導致資料丟失,
    delay(2);
    //標記串列埠讀過資料,如果沒有資料的話,直接不執行這個while了。
    mark = 1;
  }
    
  if(mark == 1)  //如果接收到資料則執行comdata分析操作,否則什麼都不做。
  {
  //顯示剛才輸入的字串(可選語句)
    Serial.println(comdata);
      //顯示剛才輸入的字串長度(可選語句)
    Serial.println(comdata.length());
    
/*******************下面是重點*******************/
//以串列埠讀取字串長度迴圈,
    for(int i = 0; i < comdata.length() ; i++)
    {
    //逐個分析comdata[i]字串的文字,如果碰到文字是分隔符(這裡選擇逗號分割)則將結果陣列位置下移一位
    //即比如11,22,33,55開始的11記到numdata[0];碰到逗號就j等於1了,
    //再轉換就轉換到numdata[1];再碰到逗號就記到numdata[2];以此類推,直到字串結束
      if(comdata[i] == ',')
      {
        j++;
      }
      else
      {
         //如果沒有逗號的話,就將讀到的數字*10加上以前讀入的數字,
         //並且(comdata[i] - '0')就是將字元'0'的ASCII碼轉換成數字0(下面不再敘述此問題,直接視作數字0)。
         //比如輸入數字是12345,有5次沒有碰到逗號的機會,就會執行5次此語句。
         //因為左邊的數字先獲取到,並且numdata[0]等於0,
         //所以第一次迴圈是numdata[0] = 0*10+1 = 1
         //第二次numdata[0]等於1,迴圈是numdata[0] = 1*10+2 = 12
         //第三次是numdata[0]等於12,迴圈是numdata[0] = 12*10+3 = 123
         //第四次是numdata[0]等於123,迴圈是numdata[0] = 123*10+4 = 1234
         //如此類推,字串將被變成數字0。
        numdata[j] = numdata[j] * 10 + (comdata[i] - '0');
      }
    }
    //comdata的字串已經全部轉換到numdata了,清空comdata以便下一次使用,
    //如果不請空的話,本次結果極有可能干擾下一次。
    comdata = String("");


    //迴圈輸出numdata的內容,並且寫到PWM引腳
    for(int i = 0; i < 6; i++)
    {
      Serial.print("Pin ");
      Serial.print(PWMPin[i]);
      Serial.print(" = ");
      Serial.println(numdata[i]);
      //analogWrite(PWMPin[i], numdata[i]);
      myservo[i].write(numdata[i]);        // 指定舵機轉向的角度
      numdata[i] = 0;
    }
    //輸出之後必須將讀到資料的mark置0,不置0下次迴圈就不能使用了。
    mark = 0;
  }
}