Robi用的伺服馬達,除了和其他伺服馬達一樣,可使用單向的PWM控制之外,
還可以使用雙向的TTL Packet控制,可以詢問馬達,目前的溫度,位移量等等,詳情請參考伺服馬達說明書
http://www.futaba.co.jp/en/dbps_data/_material_/radicon_eng/Robot/RS303MR_RS304MD_EN_112.pdf

不過Futaba只幫伺服馬達LAY了一個三孔插座,那TX/RX勢必就要用同一隻腳了,針對這個問題,日本網友有做了一個半雙工切換器,不過我個人試不出來,所以這裡就先不談,先來談怎樣利用Arduino+ software Serial讓伺服馬達轉動。

一開始我是使用Arduino的數位0 & 1支針腳,也就是Arduino原生的Serial訊號腳,來送出TTL Packet,可惜試了Serial.Print(),和Serial.Write()都無法讓馬達轉動。
幸好有熱心網友的程式碼,了解到還有一種稱為Software Serial的方法,才順利完成這個程式。

※因改造引起的Robi故障,本人及本站都不負賠償任,進行改造前需有小朋友出走的覺悟。

Demo 影片

 

[伺服馬達]S接Arduino Digital 3。電源就接+5V&GND。不曉得S、+、-三隻腳位的,可以看一下第三期的控制機板,上面有印。

程式碼部份如下,程式嗎下載處https://box.nctu.edu.tw/public.php?service=files&t=496b5e004e98e645e44fee9e15826e5a

// for RS308MD(Robi) singl servo test

#include 

SoftwareSerial robi = SoftwareSerial(2,3);    //RX , TX  pin D3 for tranfer DATA

byte set[]={0X01,0x00,0X1E,0X02,0X01};        //ID,Flag,Adress,Length,Count,cacu(sum)
byte Sum;
byte on[]={0x01,0x00,0x24,0x01,0x01,0x01,0x24};       //Torque Enable DATA

byte Head_H=0XFA;
byte Head_L=0XAF;

byte CheckSum=0;
void setup()
{
        robi.begin(115200);
        delay(500);
        Torque_on();
}
void loop()
{
        move_s(0);
        delay(500);
        move_s(450);
        delay(500);
        move_s(900);
        delay(1000);
        move_s(0);
        delay(500);
        move_s(-450);
        delay(500);
        move_s(-900);
        delay(1000);
}


void Servo_Send_Short_Pkt(byte Pkt_Head_H, byte Pkt_Head_L, byte Servo_ID, byte Flag, byte Address, byte Length,byte Count, int Data)
{
        byte Pkt_Data[Length];
        
        for (int i=0;i<Length;i++)
        {
          Pkt_Data[i]=lowByte(Data);
          Data=Data>>8;
        }

        robi.write(Pkt_Head_H);
        robi.write(Pkt_Head_L);
        robi.write(Servo_ID);        
        robi.write(Flag);
        robi.write(Address);
        robi.write(Length);
        robi.write(Count);
        //robi.write(Data);
        CheckSum= Servo_ID ^ Flag ^ Address ^ Length ^ Count;
        for (int i=0;i<Length;i++)
        {
          robi.write(Pkt_Data[i]);
          CheckSum=CheckSum^Pkt_Data[i];
        }
        robi.write(CheckSum);
    
        
}


void Torque_on()
{
  Servo_Send_Short_Pkt(Head_H,Head_L,on[0],on[1],on[2],on[3],on[4],on[5]);
}

void move_s(int pos)
{
        Servo_Send_Short_Pkt(Head_H,Head_L,set[0],set[1],set[2],set[3],set[4],pos);
     
}

qmaw 發表在 痞客邦 留言(2) 人氣()