2014-03-31 34 views
0

所以我有這個舊的摩托輪椅,我試圖轉換成一個機器人。我用sabertooth 2x12取代了原來的電機驅動器,並且我正在使用Arduino micro與它交談。馬達軸一直往下扔,所以我在背面附加了磁鐵和霍爾效應傳感器,以充當旋轉編碼器。我目前的目標是能夠告訴機器人前進一定程度的腳然後停止。我寫了一些代碼來線性地做到這一點,但是這並沒有那麼好。然後我瞭解了中斷,聽起來正是我所需要的。所以我嘗試了一下,在幾個不同的層面上出現了問題。中斷是否適合我的機器人使用?

LEVEL ONE:我似乎從來沒有能夠正確地驅動電機,就好像任何時候我把命令放在循環內部,或者如果他們決定做他們想做的事情並且偶爾移動它們,不可預知

LEVEL TWO:我覺得中斷正在中斷,我設置的東西阻止輪子向前移動,因爲我可以告訴它移動14個旋轉編碼器向前點擊,一個輪子將繼續向前移動1000點擊,而其他站點

級別三:幾次我猜我把我的中斷錯誤,因爲當我上傳代碼窗口會停止識別g Arduino和我的驅動程序會中斷,直到我按了重新啓動按鈕之後上傳了閃爍草圖,同時重新加載並修復了我的驅動程序。然後如果我刪除了一箇中斷,它會正常上傳。

級別四:當電機打開時,我的霍爾效應傳感器似乎無法正常工作。他們傾向於在幾秒鐘內從1次跳躍到200次點擊。這反過來又淹沒了我的串口並使Arduino IDE崩潰。

因此,您可以看到系統中存在多處漏洞,無論是硬件還是軟件,我都不知道。我以正確的方式接近這個方向,還是有一些我不知道的Arduino祕密會讓我的生活變得更輕鬆?如果我正在接近這個權利,你可以看看我的代碼,看看我做錯了什麼。

#include <Servo.h>//the motor driver uses this library 

Servo LEFT, RIGHT;//left wheel right wheel 

int RclickNum=0;//used for the rotory encoder 
int LclickNum=0;//these are the number of "clicks" each wheel has moved 

int D =115;//Drive 
int R =70;//Reverse 
int B =90;//Break 

int Linterrupt = 1;//these are the interrupt numbers. 0 = pin 3 and 1 = pin 2 
int Rinterrupt = 0; 

int clickConvert = 7;// how many rotery encoder clicks equal a foot 

void setup() 
{ 
    Serial.begin(9600); //starting serial communication 
    LEFT.attach(9, 1000, 2000);//attaching the motor controller that is acting like a servo 
    RIGHT.attach(10, 1000, 2000); 
    attachInterrupt(Linterrupt, LclickCounter, FALLING);//attaching the rotory encoders as interrupts that will 
    attachInterrupt(Rinterrupt, RclickCounter, FALLING);//trip when the encoder pins go from high to low 


} 
void loop() 
{//This is for controling the robot using the standard wasd format 
    int input= Serial.read(); 
    if(input == 'a') 
    left(2); 
    if(input == 'd') 
    right(2); 
    if(input == 'w') 
    forward(2); 
    if(input == 's') 
    backward(2); 
    if(input == 'e') 
    STOP(); 
} 

void forward(int feet)//this is called when w is sent threw the serial port and is where i am testing all of my code. 
{ 
    interrupts(); //turn on the interrupts 
    while(RclickNum < feet * clickConvert || LclickNum < feet * clickConvert)// while either the left or right wheel hasnt made it to the desired distance 
    { 
    if(RclickNum < feet * clickConvert)//check if the right wheel has gone the distance 
     RIGHT.write(D); //make the right wheel move 
    else 
     RIGHT.write(B);//stop the right wheel 

    if(LclickNum < feet * clickConvert) 
     LEFT.write(D); 
    else 
     LEFT.write(B); 
    } 
    noInterrupts();//stop the interrupts 
    resetCount();//set the click counters back to zero 
} 

//once i have the forward function working i will implament it through out the other functions 
//---------------------------------------------------------------------- 

void backward(int feet) 
{ 
    RIGHT.write(R); 
    LEFT.write(R); 
} 

void left(int feet) 
{ 
    RIGHT.write(D); 
    LEFT.write(R); 
} 

void right(int feet) 
{ 
    RIGHT.write(R); 
    LEFT.write(D); 
} 

void STOP() 
{ 
    resetCount(); 
    RIGHT.write(B); 
    LEFT.write(B); 
} 

void LclickCounter()//this is called by the left encoder interrupt 
{ 
    LclickNum++; 
    Serial.print("L"); 
    Serial.println(LclickNum); 
} 

void RclickCounter()//this is called by the right encoder interrupt 
{ 
    RclickNum++; 
    M Serial.print("R"); 
    Serial.println(RclickNum); 
} 


void resetCount() 
{ 
    RclickNum=0; 
    LclickNum=0; 
} 
+1

一般的建議:保持中斷處理器很小,並且不會產生其他活動,這意味着刪除那些Serial.println()。如果你需要echo'd,在循環()中執行它,編碼器總是計數,不要打開和關閉中斷,如果我向上走,並推動機器人,編碼器仍應該計數,類似的,如果它停在山上,你希望它保持它的位置,作爲開/關的替代:當你開始移動時, curr的快照確定位置並計算目標。達到目標時可以停止。最後:不要在沒有頭盔的情況下騎這樣的東西:) – jdr5ca

回答

1
  1. 不使用interrupt()nointerrupt()(或cli()sei()),因爲它們將停止定時器,串行中斷,打破了很多東西。只需設置爲0的計數變量或使用detachInterrupt和attachInterrupt。

  2. 在中斷內部使用的變量AND正常執行流程應該聲明爲volatile,或者它們的值我可以不同步。所以聲明它們就像volatile int RclickNum=0;

  3. 中斷應該執行得很快,因爲默認情況下其他中斷不會在中斷內執行。

  4. 從不使用串行內部中斷;如果串行緩衝區滿了,它會調用Serial.flush(),這將等待寫入字節的串行中斷,但是因爲你在一箇中斷內的alreadi永遠不會發生......死鎖也就是你的代碼永遠掛起!

  5. 因爲你的「移動」功能需要相當長的時間來執行,如果多個命令到達串行,那麼它將保持isnode緩衝區直到被發現。因此,如果在終端中寫入「asd」,然後是「e」,則會看到機器人向左,向後,向右,停止(是的,實際上停止功能並非有用,因爲它不起作用,因爲「移動」功能是「堵」,這意味着他們不會返回,直到他們結束,所以循環()代碼(的讀‘E’),將不執行,直到連續的緩衝區已經被處理

相關問題