雪犁機器人的設計與實施
就在幾周前,我們在這個博客中展示了電動掃雪機的制造商版本,類似于許多小商店里的那種。事實上,我們的機器人是一種特殊的履帶,是傳統掃雪機的縮小版,但可以通過索尼PS2控制器輕松進行無線電控制。在第一篇文章中,我們描述了該項目的硬件,即機械和電子控制器,并解釋說它完全基于Arduino Uno。在這篇文章中,我們將描述要加載到Arduino上的固件,以執行所有所需的功能,操作驅動電機,控制刀片,并根據通過無線電接收的命令打開/關閉前投影儀。
本文引用地址:http://cqxgywz.com/article/202308/450054.htm
簡要概述
掃雪機的電氣和電子部分基于Arduino Uno Rev.3,它擁有三個護罩和與這些卡的接口:
PCBWAY
電機驅動器DRI0018;
繼電器電路RELAY1CH;
DC/DC轉換器升壓STEPUP30VADJ。
安裝在Arduino上的防護罩是控制三個線性電機的電機防護罩,用于管理刀片的移動,以及允許您與控制臺PlayStation 2(PS2)接口的PS2SHIELD;后一種屏蔽要求通過將其插入連接器來安裝RX-PS2,它是一個2.4 GHz的無線電接收器,用于接收來自上述控制臺的特定命令。
電路中使用的所有電路板和元件都可以在我們的商店購買。電源由兩個7.2 Ah的鉛凝膠電池組成:我們在兩者的中點取12伏,而在該系列的負極和正極之間取24伏。
使用12伏電壓,我們為Arduino供電,Arduino將通過其引腳條為屏蔽的邏輯供電;LED(內部配備限制電阻器)將指示Arduino何時開啟。
12伏電壓也用于馬達護罩的電源部分;事實上,考慮到三個線性執行器的高吸收,直接從Arduino獲得12V是不明智的:您必須選擇將外部電源連接到適當的端子PWR。
每個線性致動器由一個12 Vdc的齒輪電機組成,該電機使用蝸桿沿其長度來回移動軸(最大偏移5 cm)。致動器的動態負載為50 kg,最大速度為1.3 cm/s。在不移動時,它最多可支撐約250公斤,扭矩螺釘確保即使在沒有動力的情況下也能保持軸的位置。
當發動機達到最大伸展和收縮時,兩個限位開關會停止發動機,而二極管在達到極限點后允許反向。執行機構由金屬制成,并進行密封,以防止灰塵和水進入,這是在雪地中操作的強制性條件。
24V電源線用于為掃雪機的部分供電,即牽引和投影(可選)部分:第一部分基于電源電機驅動器DRI0018,用四根電線連接到相應的Arduino數字線。模塊的輸出端子連接用于牽引的兩個24伏馬達。
除了發動機控制器外,24伏還為LED投影儀的部分供電,無論您是否安裝,其照明都會根據我們掃雪機電子設備中的光刻膠檢測到的環境照明條件進行調整。
投影儀設計為在220 Vac下工作,然而,由于機器人上沒有此電壓,為了避免使用逆變器,我們對投影儀進行了修改,打開投影儀,移除AC/DC,并將電源LED的兩根電線連接到DC/DC轉換器(代碼:STEPUP30VADJ);后者是一個開關可調輸出電壓調節器,應該對其進行調諧,以提供合適的電流,使LED在大約10瓦的功率下工作。
從遙控器接收數據是分配給屏蔽PS2SHIELD的任務,為此,制造商提供了我們在Arduino草圖中集成的特定庫。屏蔽執行命令接收和解碼;2.4GHz無線電單獨提供(RX_PS2),必須插入屏蔽的連接中。
// Sketch Open Source Snow Plow Robot
// by Vittorio Loschiavo
#include <Shield_PS2.h>
//declare class objects
PS2 ps2=PS2(); //PS2 class object: ps2
int FOTORES = A0;
int RELAY = 13;
int sensorValue = 0;
int ALZAPALA = 12;
int ONALZAPALA = 11;
int RUOTAPALA = 2;
int ONRUOTAPALA = 3;
int E1 = 5; //MOTORE 1 SPEED CONTROL M1_PWM
int E2 = 6; //MOTORE 2 SPEED CONTROL M2_PWM
int M1 = 4; //MOTORE 1 DIRECTION CONTROL M1_EN
int M2 = 7; //MOTORE 2 DIRECTION CONTROL M2_EN
int counter=0;
int stato=0;
int val=0;
int velo=0;
int motori=0;
void setup()
{
Serial.begin(9600);
ps2.init(9600, 8, 9); //initialize the main board to use desired (baudrate, rx, tx)
//for Arduino Mega use RX:10, TX: 11 for software serial
//for Arduino Leonardo use pin 8, 9, 10, 11 as RX and TX for software serial
pinMode (FOTORES, INPUT);
pinMode (RELAY, OUTPUT);
pinMode (RUOTAPALA, OUTPUT);
pinMode (ALZAPALA, OUTPUT);
pinMode (ONRUOTAPALA, OUTPUT);
pinMode (ONALZAPALA, OUTPUT);
pinMode (E1, OUTPUT);
pinMode (M1, OUTPUT);
pinMode (E2, OUTPUT);
pinMode (M2, OUTPUT);
stato=0;
}
void loop(){
motori=0;
if( ps2.getval(p_up)==0 || ps2.getval(p_joy_lu)==100) {
Serial.println("AVANTI"); //
analogWrite (E1,velo); //PWM Speed Control
digitalWrite(M1,HIGH); //
analogWrite (E2,velo); //
digitalWrite(M2,HIGH); ///
motori=1;
}
if (ps2.getval(p_down)==0 || ps2.getval(p_joy_ld)==100) {
Serial.println("INDIETRO");
analogWrite (E1,velo);
digitalWrite(M1,LOW);
analogWrite (E2,velo);
digitalWrite(M2,LOW);
motori=1;
}
if (ps2.getval(p_right)==0 || ps2.getval(p_joy_lr)==100){
Serial.println("DESTRA");
analogWrite (E1,velo);
digitalWrite(M1,HIGH);
analogWrite (E2,velo);
digitalWrite(M2,LOW);
motori=1;
}
if (ps2.getval(p_left)==0 || ps2.getval(p_joy_11)==100) {
Serial.println("SINISTRA"); //
analogWrite (E1,velo); //
digitalWrite(M1,LOW); //
analogWrite (E2,velo); //
digitalWrite(M2,HIGH); //
motori=1; //
}
if (ps2.getval(p_triangle)==0) {
Serial.println("TRIANGOLO"); //
if (velo<250) //
{ //
velo=velo+25; //
} //
else //
{ //
ps2.vibrate(2, 255); //
delay(500); // 500 ms
ps2.vibrate(2,0); //
} //
analogWrite (M1, velo); //
analogWrite (M2, velo); //
Serial.println(velo);
}
if (ps2.getval(p_cross)==0) { //
Serial.println("X"); //
if (velo>0 && velo<=250) //
{ //
velo=velo-25; //
}
else
{
//non fa niente
}
analogWrite (M1, velo);
analogWrite (M2, velo);
Serial.println(velo);
}
if (ps2.getval(p_circle)==0) {
Serial.println("CERCHIO");
if (stato==0)
{ //
stato=stato+1;
delay(100);
Serial.println(stato);
digitalWrite(RELAY, HIGH);
ps2.vibrate(2, 255); //
delay(500); // 500 ms
ps2.vibrate(2,0); //
delay(500);
ps2.vibrate(2,255);
delay(500);
ps2.vibrate(2,0);
}
else
{
stato=0;
delay(100);
Serial.println(stato);
digitalWrite(RELAY, LOW);
ps2.vibrate(2, 255); //
delay(500); // 500 ms
ps2.vibrate(2,0); //
}
}
if (ps2.getval(p_square)==0) { //
Serial.println("QUADRATO");
digitalWrite(E1,0);
digitalWrite(M1,LOW);
digitalWrite(E2,0);
digitalWrite(M2,LOW);
velo=0;
}
if (ps2.getval(p_l1)==0) {
Serial.println("L1");
digitalWrite (ONALZAPALA, HIGH); //
digitalWrite (ALZAPALA, LOW); //
}
if (ps2.getval(p_l1)==1) {
Serial.println("L1");
digitalWrite (ONALZAPALA, LOW); //
digitalWrite (ALZAPALA, LOW); //
}
if (ps2.getval(p_l2)==0) {
Serial.println("L2");
digitalWrite (ONRUOTAPALA, HIGH); //
digitalWrite (RUOTAPALA, LOW); //
}
if (ps2.getval(p_l2)==1) {
Serial.println("L2");
digitalWrite (ONRUOTAPALA, LOW); //
digitalWrite (RUOTAPALA, LOW); //
}
if (ps2.getval(p_r1)==0) {
Serial.println("R1");
digitalWrite (ONALZAPALA, HIGH); //
digitalWrite (ALZAPALA, HIGH); //
}
if (ps2.getval(p_r2)==0) {
Serial.println("R2");
digitalWrite (ONRUOTAPALA, HIGH); //
digitalWrite (RUOTAPALA, HIGH); //
}
if (ps2.getval(p_start)==0) {
Serial.println("START");
}
if (ps2.getval(p_select)==0) {
Serial.println("SELECT");
}
if (motori==0) { //
analogWrite (E1,0);
digitalWrite(M1,LOW);
analogWrite (E2,0);
digitalWrite(M2,LOW);
}
sensorValue = analogRead(FOTORES);
Serial.println(sensorValue);
if (sensorValue<30 || stato==0) {
// {
digitalWrite(RELAY, HIGH);
}
else
{
digitalWrite(RELAY, LOW);
delay(100);
{
//non fa niente
}
}
}好吧,在總結了掃雪機的制作和特性后,我們可以繼續討論你最感興趣的東西:固件,也就是要上傳到Arduino Uno中的草圖,這樣它就可以控制掃雪機,并將PlayStation 2控制器發送的命令傳給他。
機器人的固件相對簡單;為了理解它的結構是合適的,首先,花幾個字在受控屏蔽上,特別是在PS2屏蔽上。事實上,關于馬達屏蔽,我們在其他文章中已經講了很多,因為我們在各種項目中都使用過它,所以我們只想說,它的管理涉及我們已經計劃在草圖中包括的特殊庫,需要PWM信號和“啟用”邏輯級別。我們介紹了Shield PS2的相關功能以及專用庫的主要功能。
該屏蔽允許您使用Playstation 2的無線控制器(或有線控制器),允許遠程控制機器人或其他設備;因為它的設計,可以與Arduino Uno Rev 3、Duemilanove、Mega和Leonardo一起使用。它配備了一個重置按鈕來鏡像Arduino的,帶有跳線來設置各種波特率(9600、57600、115200 bps),以及一個狀態LED和跳線來選擇用于TX和RX數據的引腳,以替代UART默認值。
我們說Arduino Uno引腳D0和D1與硬件串行匹配,它們的含義分別是TX和RX。但是,可以通過軟件重新分配TX和RX線路,通過加載適當的庫New software Serial將它們分配給其他引腳(TX:引腳1、3、9、11–RX:0、2、8、10),這允許在其他硬件資源(或其他屏蔽)尚未使用的其他數字I/O對上模擬串行端口。
請注意,如果您使用串行硬件(D0,D1)的引腳,請記住在開始對Arduino Uno進行編程之前,將PS2連接器從Shield上拔下。

PS2屏蔽能夠通過適當的庫識別和管理PS2控制器的所有按鈕和模擬棒。每個模擬操縱桿(左和右)有兩個軸(X和Y)和兩種輸出格式:模擬1和2。在“模擬輸出1”格式中,每個操縱桿有兩個變量:X軸和Y軸。根據操縱桿的移動方式,您可以得到一個從0到255的輸出值,對應于操縱桿的位置。
Y軸:
?中心位置(中性),值為128。
?向上推,數值從128變為0
?按下,數值從128變為255。
X軸:
?中心位置(中性),值為128。
?向左推,數值從128變為0。
?向右推,數值從128變為255。

在“輸出模擬2”中,每個操縱手柄有四個變量(上、下、左和右)。當用戶在一個方向上移動操縱桿時,4個變量的值從0變為100。左右操縱手柄各有四個獨立變量。
對于PS2控制器按鈕管理,只需檢查我們感興趣的按鈕的狀態并讀取返回值,即可:
?如果按下按鈕,則為0;
?如果未按下按鈕,則為1。
例如,如果我們想知道您是否按下了“UP”按鈕,我們必須編寫以下聲明:
ps2.getval(p_up)==0
也可以將“p_up”替換為相應的十進制值,在本例中為“4”。
屏蔽PS2還能夠處理PS2控制器中的兩個小型發動機,這兩個發動機決定振動(左和右):相關命令需要兩個字節的數據,第一個字節指示哪個電機必須振動,而下一個字節(第二個字節)指示發動機狀態或速度。
為了使用處理來自PS2控制器的命令的屏蔽,我們使用了shield_PS2.h庫。在草圖的開頭,我們包含了語句“#include<shield_PDS2.h>”,該庫需要正確控制屏蔽。
讓我們繼續看LED投影儀的控制,它通過Arduino Uno Rev3模擬引腳A0進行操作,該引腳連接到檢測環境光的光刻膠;當照明低于閾值時,草圖激活投影儀,或者更確切地說,它向卡RELAY1CH提供高邏輯狀態,該卡包含由邏輯電平激活的繼電器。在我們的項目中,我們使用閉合和常開之間的交換,并通過它觸發為投影儀供電的DC/DC轉換器的電源,因此當Arduino Uno(通過其數字引腳13)進入邏輯狀態1時,繼電器發出咔噠聲并閉合上述觸點,打開LED投影儀。











評論