<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > Arduino通過(guò)太陽(yáng)能操作機器人割草機動(dòng)力

Arduino通過(guò)太陽(yáng)能操作機器人割草機動(dòng)力

作者: 時(shí)間:2023-08-31 來(lái)源:電子產(chǎn)品世界 收藏

這個(gè)機器人會(huì )修剪你花園里的草,呆在指定的區域內,避開(kāi)所有障礙,完全自主工作,用電池板自動(dòng)充電。

本文引用地址:http://dyxdggzs.com/article/202308/450104.htm

MowerFea2

在這篇文章中,我們介紹了一種機器人割草機,它由供電,能夠僅利用來(lái)自太陽(yáng)的清潔能源進(jìn)行操作;這與商業(yè)項目有很大的不同,商業(yè)項目需要一個(gè)連接到電網(wǎng)的充電站。在設計驅動(dòng)的割草機時(shí),至關(guān)重要的是,大部分能量來(lái)自太陽(yáng),當然,如果太陽(yáng)能足以為機器人完全供電,最終結果就會(huì )得到:然而,鑒于現有太陽(yáng)能電池板的低效率,這一目標將很難實(shí)現。在我們的項目中,機器人的整個(gè)表面都是太陽(yáng)能電池板,同時(shí)也是一個(gè)蓋子:只有側面是自由的,無(wú)論如何,它們在供應能源方面都不會(huì )發(fā)揮決定性作用。顯然,這種選擇對項目的其余部分構成了嚴重的限制,因為通過(guò)這種方式,我們已經(jīng)定義了可用的最大功率。

我們必須考慮到,太陽(yáng)能并不總是可用的,因為許多花園區域經(jīng)常處于陰涼處,或者無(wú)論如何都沒(méi)有被太陽(yáng)直接照射,所以我們必須考慮相當大的電力損失。只有當機器人有一個(gè)蓄能器,能夠在缺乏陽(yáng)光的情況下提供能量時(shí),才能彌補這些損失。在這種情況下,電池起到緩沖作用,在電量充足時(shí)積累能量,相反,在機器人處于陰影下時(shí)提供能量。從這個(gè)角度來(lái)看,鉛電池是最合適的電池,但沒(méi)有什么能阻止我們使用在重量和容量方面表現更好的電池,比如鋰電池。在陽(yáng)光充足的情況下,太陽(yáng)能電池板能夠用約0.6A的電流為內部電池充電,總功率約為8W,遠低于最高效的電動(dòng)割草機所使用的功率,功率為220Vac。這讓我們已經(jīng)明白,像我們在這些頁(yè)面中描述的產(chǎn)品不能完全取代手動(dòng)割草機,因為當草太高時(shí),應該不時(shí)使用最后一款。相反,機器人割草機可以用于連續穩定地修剪草坪。

MowerConnection

這種解決方案還提供了另一個(gè)優(yōu)勢,因為連續割草可以確保草始終年輕柔軟,而且當它被切成很小的碎片時(shí),它會(huì )在短時(shí)間內自行分解,從而為草坪施肥。你不應該指望被割下的草會(huì )被收集起來(lái):相反,它會(huì )沉積在剛剛割下的草葉中。

對于這種用途,所需的電力更少,并且可以使用電池供電系統輕松管理。游戲中的弱動(dòng)力說(shuō)服我們選擇一個(gè)牽引力和功率降低的切割發(fā)動(dòng)機。也許,它們可能不完全符合我們讀者的需求,他們可能會(huì )根據預算和個(gè)人需求選擇他們喜歡的引擎和結構。為了確定草坪上的切割區域,地下布線(xiàn)系統被證明是簡(jiǎn)單、準確和可靠的。它也是定義機器人工作區域的最佳系統。

一切都是基于一根簡(jiǎn)單電線(xiàn)的使用,電線(xiàn)鋪設在地上或其下,并連接到一個(gè)控制單元,用大約10V和34KHz頻率的交流電信號為電線(xiàn)本身供電。在機器人底盤(pán)的下部安裝了兩個(gè)小卷軸,一個(gè)在右側,另一個(gè)在左側,這兩個(gè)卷軸都是指由并聯(lián)的電容器形成的電路。由并聯(lián)電感和電容器形成的電路被稱(chēng)為并聯(lián)諧振電路,并且被計算為使得當磁場(chǎng)以34KHz的頻率變化時(shí),由外部磁場(chǎng)感應的其端部的張力處于最大值。

Mowerinside3

現在讓我們來(lái)更詳細地描述這個(gè)項目所采用的電氣部分。最重要的創(chuàng )新是采用了作為控制板,使你能夠獲得一個(gè)更用戶(hù)友好、更易于破解的項目,即使是經(jīng)驗不足的人。為了實(shí)現最大的使用靈活性,我們認為要實(shí)現特定的屏蔽,而不是實(shí)現特定的電子板。

這種選擇也決定了一個(gè)缺點(diǎn),即當板處于待機模式時(shí),電流的吸收,這種情況可能發(fā)生在夜間,機器人仍然沒(méi)有電源。在這種情況下,內部電池將不得不面對板和屏蔽的長(cháng)時(shí)間供電。

關(guān)于發(fā)動(dòng)機的管理,就牽引力而言,我們計算了商用護罩的使用情況,這是唯一一種可用于修改控制銷(xiāo)分配的商用護罩;為此,請使用表1正確分配引腳。發(fā)動(dòng)機護罩可管理兩臺發(fā)動(dòng)機,每臺發(fā)動(dòng)機的總最大吸收功率為2A,確保有足夠的動(dòng)力用于牽引。顯然,沒(méi)有什么可以禁止我們使用其他類(lèi)型的驅動(dòng)器來(lái)驅動(dòng)發(fā)動(dòng)機,從而增加功率;唯一重要的是,駕駛員為每臺發(fā)動(dòng)機提供兩個(gè)可用的控制信號,一個(gè)用于定義方向,另一個(gè)用于控制速度所需的PWM信號。

1143_Schema

該屏蔽是使用具有特定功能的最新組件設計的,因此需要使用高度集成的SMD組件,從而將所有東西都安裝到與 UNO兼容的屏蔽中。用于讀取地下線(xiàn)路的部分基于包含六個(gè)CD4069型NOT門(mén)的集成電路。使用這種集成電路,我們只需放大并平方并聯(lián)諧振電路頭部的弱信號。即使在這個(gè)項目中,我們也計算了激活或停用太陽(yáng)能電池板的可能性;為此,我們依靠集成電路ASSR1611,這是一種由光隔離器控制的固態(tài)開(kāi)關(guān)。如果使用的緩沖電池是鉛電池,則無(wú)需拆下面板,因為這種電池可以很好地支持過(guò)充電,但如果您使用更現代的鋰電池,則必須在達到極限電壓后暫停充電,否則您可能會(huì )導致電池損壞,或在最壞的情況下發(fā)生爆炸。

兩個(gè)名為ACS712的集成電路可以測量太陽(yáng)能電池板提供的電流和切割引擎吸收的電流:5A范圍的版本對我們來(lái)說(shuō)似乎綽綽有余。

這些集成電路使用霍爾效應技術(shù)來(lái)提供(作為輸出)與電源電路上的循環(huán)電流成比例的張力,從而與輸出級保持電流分離。測量太陽(yáng)能電池板電流的可能性將是檢測最適合給電池充電的區域的基礎。運行時(shí),實(shí)際上會(huì )存儲面板提供的電流水平,當割草機必須找到充電區時(shí),在電池電量接近低的情況下,會(huì )再次使用數據。機器人不知道真實(shí)的大氣情況(晴天或陰天),也不知道是否有陰影區域,甚至不知道它是否在變暗:它只會(huì )在上一次工作中檢測到的最大發(fā)光強度方面尋找一個(gè)足夠亮的區域。測量切割引擎吸收的電流將是了解切割過(guò)程中的作用力的基礎,也是計算在異常情況下何時(shí)停止切割的基礎。

為了完成關(guān)于屏蔽的討論,我們必須注意二極管D1,它是在電池電量不足的情況下避免電池在光伏面板上的張力所必需的;以及使I2C總線(xiàn)可用所需的兩個(gè)連接器。

1143_TopSilk

MowerShieldTop

還設計了三個(gè)通用按鈕,它們通過(guò)電阻網(wǎng)絡(luò )連接到模擬輸入A0;事實(shí)上,所有的數字引腳都已被占用。一個(gè)入口由一個(gè)簧片傳感器使用,該傳感器放置在非??拷髽休S輪的位置,并由一個(gè)小磁鐵操作,該磁鐵在每次旋轉時(shí)插入同一個(gè)輪中。有了這個(gè)傳感器,就可以確定機器人是否有規律地移動(dòng),或者一個(gè)或多個(gè)輪子是否被鎖住或徒勞地移動(dòng)。

Img6

我們增加了兩個(gè)數字輸入,您可以將前面的障礙物識別機械開(kāi)關(guān)連接到它們;除此之外,經(jīng)驗證的超聲波傳感器連接到I2C總線(xiàn)并檢測前方物體。

超聲波傳感器雖然性能非常好,但可能會(huì )被表面特別小的物體(如金屬網(wǎng))或一些非常不規則的表面(如灌木)所欺騙。

至于草坪修剪,我們依賴(lài)于航空建模領(lǐng)域使用的無(wú)刷電機,該電機與通過(guò)組合兩個(gè)刀片獲得的刀片相連。

Mowerinside

我們談?wù)摰氖且慌_200W的發(fā)動(dòng)機,但它的使用率不超過(guò)20%。發(fā)動(dòng)機控制分配給模型構建中使用的ESC(電子速度控制),并使用簡(jiǎn)單的PWM信號進(jìn)行操作,易于使用Arduino進(jìn)行管理,因為它已經(jīng)在系統庫中具有相關(guān)功能。

MowerPin

為了測量電池頭部的張力,我們將使用電機護罩中已有的分壓器。然而,需要修改軌道,將分配器輸出的張力從引腳A5帶到引腳A3,以便引腳A4和A5可用于I2C總線(xiàn)。兩條數字線(xiàn)路D0和D1用于與PC通信,但一旦對Arduino進(jìn)行了編程,它們就可以用于與GPS或藍牙等其他外圍設備通信。

Tab. 1 Mower Shield pin connect

Pin Arduino

   nameDescription
A0Button_pinPush button
A1ICut_pinMotor cut current
A2IPanel_pinSolar panel current
A3VBat_pinBattery voltage (from motorshield_FE)
A4SDA_pinI2C BUS
A5SCL_pinI2C BUS
D0RXD_pinGPS or bluetooth
D1TXD_pinGPS or bluetooth
D2Encoder_pinEncoder pivoting wheel
D3PWMA_pinPWM motor A motorshield_FE
D4DIRA_pinDirection motor A motorshield_FE
D5BWFR_pinBuried Wire Fence Right
D6BWFL_pinBuried Wire Fence Left
D7Panel_pinON/OFF pannel
D8ESC_pinESC cut motor signal
D9SWOL_pinObstacle switch Right
D10SWOR_pinObstacle switch Left
D11PWMB_pinPWM motor B motorshield_FE
D12DIRB_pinDirection motor B motorshield_FE
D13LCD_pinSerial LCD

硬件現在已經(jīng)相當完整,防護罩做得非常好,盡管還可以添加一些更多的功能,比如雨水傳感器,或者更好的是,草濕度傳感器,這將使機器人能夠停下來(lái)等待更好的切割條件。作為一種安全措施,我們在旋轉輪上安裝了一個(gè)編碼器,作為一種支撐,甚至可以在牽引輪上添加一個(gè)編碼器甚至可以添加一個(gè)傳感器來(lái)測量吸收的電流。

電氣部分還計算了用于調試功能且絕對不需要的綠色背景黑色文本串行顯示器的使用情況。

使用一個(gè)簡(jiǎn)單的Arduino板應該可以讓許多用戶(hù)嘗試實(shí)現電動(dòng)割草機,當然也不會(huì )缺少社區的貢獻,以及進(jìn)一步改進(jìn)的建議。

Mowerinside2

關(guān)于屏蔽的電氣連接,請參考下表:

表2–屏蔽連接器的鏈接

connector function

J1 Ignition switch

J2 Battery Power

J3 Photovoltaic panel

J4 Electronic speed control (ESC) for the cutting engine

J5 Obstacle detection Switch left

J6 Obstacle detection Switch right

J7 Cotrol signal for the speed control of the cutting engine

J8 LCD Display

J9 Reed contact for the rear pivoting wheel

J10 1mH Reel for underground wiring detection left

J11 1mH Reel for underground wiring detection right

J12 Ultrasonic Sensor SRF-02 right

J13 Ultrasonic Sensor SRF-02 left

J14 Buttons

我們將在下面列出本項目中使用的所有硬件組件:

N°2微電機齒輪箱RH-158-12-200

N°2輪轂

2號超聲波傳感器SRF02。

N°1鉛蓄電池2,1Ah NP21-12

N°1太陽(yáng)能電池板STP10M 10W 0,59A

用于診斷的N°1 LCD串行顯示器1446-LCDSER16X2NV

用于航空建模BMA20-22L的N°1無(wú)刷電機

ESC-18A無(wú)刷電機的N°1速度控制

1個(gè)用于報警系統的磁性傳感器(用作編碼器)

能量平衡使我們能夠了解有用的能量循環(huán)以及一天可以做多少工作:

切割發(fā)動(dòng)機吸收的電流,約1.4A

電子設備吸收的電流0,07A

發(fā)動(dòng)機吸收的電流0,4A

光伏板吸收的電流,約0.6A

根據測量數據(使用所述設置),我們可以推斷運行機器所需的電流是光伏板提供的電流的三倍,也就是說(shuō),一個(gè)小時(shí)的工作需要三個(gè)小時(shí)的充電,有用的使用百分比為30%??紤]到在夏天,在最佳條件下,大約有九個(gè)晴天,我們可能一天有大約三個(gè)小時(shí)的時(shí)間進(jìn)行修剪,這通常足以維持500平方米的花園秩序。

MowerMounting

BOM

R1: 10 Mohm (0805)
R2: 100 kohm (0805)
R3: 10 Mohm (0805)
R4: 100 kohm (0805)
R5: 390 ohm (0805)
R6: 4,7 kohm (0805)
R7: 2,2 kohm (0805)
R8: 6,8 kohm (0805)

C1: 100 μF 25 VL (D)
C2: 100 nF (0805)
C3: 470 nF (0805)
C4: 470 nF (0805)
C5: 100 nF (0805)
C6: 100 nF (0805)
C7: 22 nF (0805)
C8: 1 nF (0805)
C9: 1 nF (0805)
C10: 22 nF (0805)
C11: 1 nF (0805)
C12: 1 nF (0805)

U1: ACS712ELCTR-05B-T
U2: ACS712ELCTR-05B-T
U3: CD4069UBM
U4: ASSR-1611-301E

F1: RUEF300

D1: GF1M


固件

/*
  SolarMower V1.0
  SolarMower use mowershield_FE
  2014 Mirco Segatello
  For hardware see www.elettronicain.it
  
  Press PEN during power-on for ESC test  
  Press PUP during power-on for test motor
  Press PDW during power-on for test sensor
 */

#include <EEPROM.h>
#include <SoftwareSerial.h>
#include <Servo.h> 
#include "Wire.h"
#include "SRF02.h"
#include "Configuration.h"

Servo ESC;

//variables
float VBat;               // Battery voltage [V]
int VBatPC;               // Battery voltage percentage
float VBatScale=0.054;    // Battery scale for Volt converter
float IPanel;             // Panel current [A]
float IPanelOffset;       // Panel current offset
float IPanelScale=0.185;  // Panel current scale V/A
float ICut;               // Motor cut current [A]
float ICutOffset;         // Motor cut current offset
float ICutScale=0.185;    // Motor cut current scale V/A
int i;
int cutPower=0;           // Cut Power from 0%=ESC_MIN_SIGNAL to 100%=ESC_MAX_SIGNAL
int cutPower_uSec=ESC_MIN_SIGNAL;      // Cut Power from ESC_MIN_SIGNAL to ESC_MAX_SIGNAL
int oldSpeed=0;           // Speed of mower (0-255)
float IPanelMax=0;           // IPanel max current
unsigned long BWFL_count;
unsigned long BWFR_count;
unsigned long previousMillis = 0;
unsigned long currentMillis; 
volatile int mowerStatus=0; // 0=oncharge (press pen for run)
                            // 1=run
                            // 2=stuck
                            // 3=search
                            // 4=batlow
                            // 5=charge and restart when full
                            // 6=cuterror
volatile unsigned long wheelTime=0;

// LCD does not send data back to the Arduino, only define the txPin
SoftwareSerial LCD = SoftwareSerial(0, LCD_pin);
int LCD_Page = 0;         // Page to display

SRF02 US_SX(US_SX_address, SRF02_CENTIMETERS);
SRF02 US_DX(US_DX_address, SRF02_CENTIMETERS);




void setup() 
{
  Serial.begin(9600);
  Wire.begin();
  pinMode(Encoder_Pin, INPUT_PULLUP);
  pinMode(PWMA_pin, OUTPUT);
  pinMode(DIRA_pin, OUTPUT);  
  pinMode(BWFR_pin, INPUT);
  pinMode(BWFL_pin, INPUT);    
  pinMode(Panel_pin, OUTPUT);  
  pinMode(ESC_pin, OUTPUT);  
  pinMode(SWOR_pin, INPUT_PULLUP);
  pinMode(SWOL_pin, INPUT_PULLUP);       
  pinMode(PWMB_pin, OUTPUT);
  pinMode(DIRB_pin, OUTPUT);   
  pinMode(LCD_pin, OUTPUT);  

  digitalWrite(DIRA_pin, LOW); 
  digitalWrite(DIRB_pin, LOW);   
  analogWrite(PWMA_pin, 0);
  analogWrite(PWMB_pin, 0);  
  digitalWrite(Panel_pin, LOW);   

 
  // For SerialMonitor diagnostic 
  Serial.println("Solar Mower V1.0n"); 
  Serial.println("Init ESC..."); 
  ESC.attach(ESC_pin);
  cutOFF(); 
  
  Serial.println("Init SerLCD...");       
  serLCDInit();   
  clearLCD();
  lcdPosition(0,0);
  LCD.print("Solar Mower v1.0");
  lcdPosition(1,0);
  LCD.print("Init...");      
  

  Serial.println("Init Sensor");  
  sensorInit();  
  Serial.print("IPanelOffset= ");
  Serial.println(IPanelOffset);
  Serial.print("ICutOffset= ");
  Serial.println(ICutOffset);  
  Serial.println(); 


  // TEST MOTOR
  if (Button(Button_pin)==PUP) 
  {
    while(1)
    {
      clearLCD();
      lcdPosition(0,0);
      LCD.print("Test motor");
      lcdPosition(1,0);  
      LCD.print("PEN begin test  ");  
      Serial.println("Press PEN for begin motor test"); 
      while (Button(Button_pin)!=3) { }
      testMotor();
    }   
  }   
  
  //TEST SENSOR
  if (Button(Button_pin)==PDW) 
  { 
      clearLCD();
      lcdPosition(0,0);
      LCD.print("Test sensor");    
      Serial.println("Test sensor");
      delay(1000);
    while(1)
    {
      sensorReading();
      
      clearLCD();
      lcdPosition(0,0);
      LCD.print("VB=");
      LCD.print(VBat);
      
      lcdPosition(0,9); 
      if ((US_DX.read()>0) && (US_DX.read()<USdistance))   {
            LCD.print("UsDX ");
            Serial.println("UsDX");
      }      
      if ((US_SX.read()>0) && (US_SX.read()<USdistance)) {
            LCD.print("UsSX ");   
            Serial.println("UsSX");            
      }      
      if ( (BWFL_count>3000) && (BWFL_count<4000) ) {
            LCD.print("BWFL");
            Serial.println("BWFL");
      }      
      if ( (BWFR_count>2000) && (BWFR_count<4000) ) {
            LCD.print("BWFR");    
            Serial.println("BWFR");            
      }      
      if (digitalRead(Encoder_Pin)==0) {
            LCD.print("Encoder");
            Serial.println("Encoder");            
      }      
      if (digitalRead(SWOR_pin)==0) {
            LCD.print("SWOR");
            Serial.println("SWOR");            
      }      
      if (digitalRead(SWOL_pin)==0) {
            LCD.print("SWOL");       
            Serial.println("SWOL");            
      }      
      if (Button(Button_pin)==1) {
            LCD.print("PUP");
            Serial.println("PUP");            
      }      
      if (Button(Button_pin)==2) {
            LCD.print("PDW");  
            Serial.println("PDW");            
      }            
      if (Button(Button_pin)==3) {
            LCD.print("PEN");
            Serial.println("PEN");            
      }      
      
      lcdPosition(1,0);
      LCD.print("IC=");
      LCD.print(ICut);  
      Serial.print("IC=");     
      Serial.println(ICut);       
      lcdPosition(1,9);
      LCD.print("IP=");
      LCD.print(IPanel);  
      Serial.print("IP=");     
      Serial.println(IPanel);        

      delay(250);  
    }
  }    
  
  //TEST ESC
  if (Button(Button_pin)==PEN)   
  {
    Serial.println("Test ESC...");   
    clearLCD();
    lcdPosition(0,0);
    LCD.print("Test ESC");
    while(1)
    {
        sensorReading();
        cutPower = map(cutPower_uSec, ESC_MIN_SIGNAL, ESC_MAX_SIGNAL, 0, 100);
        lcdPosition(0,9);
        LCD.print("IC=");
        LCD.print(ICut);          
        lcdPosition(1,0);  
        LCD.print("cutPower="); 
        LCD.print(cutPower);
        LCD.print("%  ");
        Serial.print("cutPower=");
        Serial.print(cutPower);
        Serial.print("%   usec=");
        Serial.println(cutPower_uSec);
        
        if (Button(Button_pin)==2) 
           if (cutPower_uSec<ESC_MAX_SIGNAL) cutPower_uSec += 20;
        if (Button(Button_pin)==1) 
           if (cutPower_uSec>ESC_MIN_SIGNAL) cutPower_uSec -= 20;      
           
        ESC.writeMicroseconds(cutPower_uSec);
        delay(200);   
    } 
  } 
  attachInterrupt(0, rotate, FALLING);
}


void loop() 
{
  //main program
  digitalWrite(Panel_pin, HIGH);  

  main: 
  //wait for PEN press
  while(Button(Button_pin)!=3) 
  { 
    currentMillis = millis();
    if(currentMillis - previousMillis > timeClock) 
    {    
        sensorReading(); 
        LCDdebug();
    }  
  }  
  
  Serial.println("GO!");      
  mowerStatus=1;
  IPanelMax=0;
  LCDdebug();  
  cutON();
  setMowerSpeed(255);


  //main loop    
  while(1)
  { 
    
    //ferma tutto
    if (Button(Button_pin)==PUP || Button(Button_pin)==PDW)
    {
      cutOFF();  
      setMowerSpeed(0);
      mowerStatus=0;
      goto main; 
    }

    //if not an interrupt wheels occurs within 10 seconds, the robot is blocked
    if (millis()>wheelTime+10000)
    {
      cutOFF();  
      setMowerSpeed(0);
      mowerStatus=2;
      goto main;       
    }
    
    // gestione sensori ostacolo
    if (digitalRead(SWOL_pin)==LOW) obstacleAvoidSX();   
    if (digitalRead(SWOR_pin)==LOW) obstacleAvoidDX();       
       
    
    // reads the sensors every timeClock
    currentMillis = millis();
    if(currentMillis - previousMillis > timeClock) 
    {
      previousMillis = currentMillis; 

      sensorReading(); 
        
      if ((US_DX.read()>0) && (US_DX.read()<USdistance)) 
      {
            obstacleAvoidSX();  
            resetEncoder();
      }      
      if ((US_SX.read()>0) && (US_SX.read()<USdistance)) 
      {
            obstacleAvoidDX();      
            resetEncoder();
      }      
      if ((BWFL_count>3000) && (BWFL_count<4000))
      {
            obstacleAvoidSX();  
            resetEncoder();
      }      
      if ((BWFR_count>2000) && (BWFR_count<4000)) 
      {       
            obstacleAvoidDX();     
            resetEncoder();
      }      
      
      
      //**********************************************************************
      if (IPanel>IPanelMax) IPanelMax=IPanel; //memory to max current on panel
      
      //battery lower then 10% then searching the point to charge
      if (VBatPC<10) 
      {                
        mowerStatus=3;
        cutOFF();  //stop cut
      }  
      
      //continues to advance until it finds a light source at least 80% of the previous maximum.
      if (mowerStatus==3)
      {     
        if  (IPanel>IPanelMax*0.8) 
        {
          setMowerSpeed(0);
          mowerStatus=5; //charge with restart
        }    
      }
      //**********************************************************************
      
      if (mowerStatus==5)
      {
        resetEncoder();
        // full charge then restart
        if (VBatPC>=100)
        {
            mowerStatus=1;
            IPanelMax=0;
            cutON();
            setMowerSpeed(255);         
        }    
      }  
        
      if (VBat > VBat_Level_Max)
      {
         //lead battery never stop charge 
         //disable charge only for lipo battery
         //digitalWrite(Panel_pin, LOW); 
      } 
      
      //battery is completely discharged      
      if (VBat < VBat_Level_Min) 
      {
        cutOFF();  
        setMowerSpeed(0);
        digitalWrite(Panel_pin, HIGH); 
        mowerStatus=4;
        goto main;       
      } 
      
      // ICut too high 
      if (ICut > ICut_Max) 
      {
        cutOFF();  
        setMowerSpeed(0);
        digitalWrite(Panel_pin, HIGH); 
        mowerStatus=6;
        goto main;       
      }       
      
      serialDebug();      
      LCDdebug();    
      }
  }  
}

void rotate()
{
  wheelTime=millis();   
}

void resetEncoder()  //reset value for block wheels
{
  wheelTime=millis();   
}

void obstacleAvoidSX()
{
      // obstacle avoid
      setMowerSpeed(-PWMSpeed);
      delay(timeReverse);
      setMowerRotate(-PWMSpeed); //gira a sinistra
      delay(timeRotate);
      setMowerSpeed(PWMSpeed);
}

void obstacleAvoidDX()
{
      // obstacle avoid     
      setMowerSpeed(-PWMSpeed);
      delay(timeReverse);
      setMowerRotate(PWMSpeed);
      delay(timeRotate);
      setMowerSpeed(PWMSpeed);   
}


void setMowerRotate(int newSpeed)
{ 
  //rotate mower (first set speed at zero) 
  constrain(newSpeed, -255, 255);
    for (i=oldSpeed; i>=0; i--)
    {
       analogWrite(PWMA_pin, i);
       analogWrite(PWMB_pin, i);
       delay(accelerateTime);
    }      
    oldSpeed=0;
    
  if (newSpeed<0) 
  {  
    digitalWrite(DIRA_pin, HIGH); 
    digitalWrite(DIRB_pin, LOW);   
    newSpeed=-newSpeed;    
  }
  else
  {
    digitalWrite(DIRA_pin, LOW); 
    digitalWrite(DIRB_pin, HIGH);    
  }  
  
  for (i=0; i<=newSpeed; i++)
  {
       analogWrite(PWMA_pin, i);
       analogWrite(PWMB_pin, i);
       delay(accelerateTime);
  }  
  oldSpeed=newSpeed;
}


void setMowerSpeed(int newSpeed)
{
  //set new speed for mower (first set speed at zero) 
  constrain(newSpeed, -255, 255);
    for (i=oldSpeed; i>=0; i--)
    {
       analogWrite(PWMA_pin, i);
       analogWrite(PWMB_pin, i);
       delay(accelerateTime);
    }    
    oldSpeed=0; 
  
  if (newSpeed<0)
  {  
    digitalWrite(DIRA_pin, HIGH); 
    digitalWrite(DIRB_pin, HIGH);    
    newSpeed=-newSpeed;
  }
  else
  {
    digitalWrite(DIRA_pin, LOW); 
    digitalWrite(DIRB_pin, LOW);    
  }
  
  if (newSpeed > oldSpeed)
  {
    for (i=oldSpeed; i<=newSpeed; i++)
    {
       analogWrite(PWMA_pin, i);
       analogWrite(PWMB_pin, i);
       delay(accelerateTime);
    }   
  }
  else
  {
    for (i=oldSpeed; i>=newSpeed; i--)
    {
       analogWrite(PWMA_pin, i);
       analogWrite(PWMB_pin, i);
       delay(accelerateTime);
    }        
  } 
  oldSpeed=newSpeed; 
}

 
void cutON()
{
  //cutter ON
  for (cutPower_uSec=ESC_MIN_SIGNAL; cutPower_uSec<=ESC_MAX_SIGNAL; cutPower_uSec += 10)
  {
    ESC.writeMicroseconds(cutPower_uSec);
    delay(50); 
  }
  wheelTime=millis(); 
}

void cutOFF()
{
  //cutter OFF
  ESC.writeMicroseconds(ESC_MIN_SIGNAL);      
}

草圖被分為不同的文件,每個(gè)文件都有特定的用途,可以對功能進(jìn)行排序,使閱讀更容易;我們將在下面看到構成草圖的文件。

文件configuration.h包含用于設置Arduino的工作參數和所有引腳分配的所有定義指令。在所有參數中,最重要的是:

ESC_MAX_SIGNAL 2000:它定義了與ESC最大功率相關(guān)的信號的持續時(shí)間(以微秒為單位),與切割發(fā)動(dòng)機的控制有關(guān)。

#定義ESC_MIN_SIGNAL 1000:它定義與ESC停止有關(guān)的信號的持續時(shí)間(以微秒為單位),與切割發(fā)動(dòng)機的控制有關(guān)。

#define VBat_Level_Min 9.0:它定義電池的最小電壓:在此值下,除太陽(yáng)能電池板充電外,所有割草機功能都將停用。

#定義VBat_Level_Max:它定義電池的最大電壓:超過(guò)該值,太陽(yáng)能電池板的充電將中斷。最小值和最大值也用于確定蓄電池充電水平。

#define ICut_Min:它定義切割引擎吸收的最小電流:低于該值時(shí)會(huì )產(chǎn)生警報。

#define ICut_Max:它定義切割引擎吸收的最大電流:超過(guò)該值,前進(jìn)速度會(huì )降低。

#define accelerateTime:它定義了分配給運動(dòng)的發(fā)動(dòng)機的加速持續時(shí)間;總加速時(shí)間等于accelerateTime*255[msec]。

#定義Usdistance:檢測到障礙物并且機器人改變方向的距離(以厘米為單位)。

#定義時(shí)間反向:檢測到障礙物后,機器人反向運動(dòng)的持續時(shí)間(以毫秒為單位)。

#define timeRotate:檢測到障礙物后,在修改行進(jìn)方向的操作過(guò)程中,機器人旋轉的持續時(shí)間(以毫秒為單位)。

SerLCD.ino文件包含LCD顯示器的初始化和控制功能。debug.ino文件包含機器人運行過(guò)程中測量值在LCD顯示器上的初始化和可視化功能,還包含用于將測量數據發(fā)送到PC的功能。

sensor.ino文件包含讀取傳感器時(shí)使用的功能;為了便于比較,所有測量值都以安培和伏特為單位進(jìn)行轉換。特別有趣的是FreqCounter(int引腳,無(wú)符號長(cháng)gateTime)功能,它允許測量來(lái)自用于檢測地下線(xiàn)路的輸入的脈沖數量。

從用于檢測地下布線(xiàn)的電路獲得的方波信號僅在正確檢測到布線(xiàn)的情況下才呈現特定頻率。

參數gateTime顯示信號檢測的持續時(shí)間,也表示函數計數所需的時(shí)間,其默認值為100msec。文件TestMotor.ino包含牽引發(fā)動(dòng)機測試過(guò)程中使用的功能。

對于割草機的每一項功能,都會(huì )在LCD顯示屏上進(jìn)行確認,并向PC發(fā)送等效消息:LCD顯示屏為數據管理提供了更大的便利,無(wú)需PC連接。

主程序包含在文件SolarMower.ino中:它監督所有操作,并按正確順序調用所有功能。

一旦電氣部分完成,就需要正確驗證功能和接線(xiàn):為此,預先設置了三個(gè)特定的公用設施。我們要記住,割草的刀片非常危險,因此我們建議在結束所有測試之前移除刀片。

當點(diǎn)火時(shí),或按下Arduino的重置按鈕時(shí),或當重新啟動(dòng)串行監視器時(shí)(如果連接到Arduino),固件將開(kāi)始其細化;作為第一次操作,它將驗證是否按下了其中一個(gè)按鈕,在這種情況下,它將啟動(dòng)特定的設置程序,如下所示:

按下PUP按鈕,進(jìn)入傳感器測試;

按下PDW按鈕,進(jìn)入發(fā)動(dòng)機測試;

按下PEN按鈕,進(jìn)入ESC測試。

ESC測試程序允許校準最大值和最小值;這不是一個(gè)編程順序,相反,它需要參考正在使用的ESC的特定手冊。

1斷開(kāi)切割刀片和ESC電源連接器。

2為割草機和ESC測試條目供電。

3使用PUP 100%=2000usec按鈕將cutPower設置為最大值

4為ESC供電,等待最大點(diǎn)的配置(您將聽(tīng)到特定的聲學(xué)信號)。

5使用PDW按鈕將cutPower設置為最小值(您將聽(tīng)到特定的聲學(xué)信號)。

6現在將完成校準。電子穩定控制系統將自動(dòng)設置最小值在10-30%范圍內,最大值在70-100%范圍內的限值。通過(guò)操作PUP和PDW按鈕,可以修改cutPower的值,并驗證電機是否正確運行。

要驗證運動(dòng)發(fā)動(dòng)機,啟動(dòng)發(fā)動(dòng)機測試程序:它將通過(guò)逐漸加速和減速依次啟動(dòng)兩個(gè)電機。然后,您必須驗證旋轉方式是否與Arduino串行監視器或LDC顯示器上顯示的信息一致:如果旋轉方式不同,則足以反轉發(fā)動(dòng)機的導線(xiàn)。您還必須驗證DX引擎是否與正確的引擎匹配,反之亦然。

Img2

在啟動(dòng)傳感器測試程序之前,我們必須討論超聲波傳感器:由于它們都連接到同一個(gè)I2C總線(xiàn),因此需要用不同的地址對其中一個(gè)進(jìn)行編程。傳感器屬于SRF02類(lèi)型,在銷(xiāo)售時(shí)分配了值地址HEX0x70。因此,如果連接到同一個(gè)總線(xiàn),剛剛購買(mǎi)的兩個(gè)傳感器將發(fā)生沖突。我們將保留左側傳感器的默認地址0x70,并修改右側傳感器的地址。

要做到這一點(diǎn),請將屏蔽單獨連接到右側傳感器,并打開(kāi)SRF02_address.ino樣本,該樣本包含在SRF02庫中,與本文的文件一起提供,然后將其加載到Arduino上;地址將被自動(dòng)修改。您可以使用庫中包含的示例程序來(lái)驗證地址的更改是否正確。

通過(guò)啟動(dòng)傳感器測試程序,您將有機會(huì )驗證所有輸入外圍設備是否正確運行;在LCS顯示器(如果可用)和串行監視器(如果連接到Arduino)上,都可以看到從當前傳感器獲取的數據、數字條目的值以及檢測到的障礙物的存在與否。

一旦確定一切正常,您可以進(jìn)行第一次現場(chǎng)測試:按下主屏幕上的PEN按鈕即可啟動(dòng)割草機,同時(shí)按下PUP和PDW兩個(gè)按鈕之一即可立即停止。

無(wú)論如何,在提起或操作割草機之前,我們建議通過(guò)總開(kāi)關(guān)將其關(guān)閉:只有這樣,您才能保證任何機制都不會(huì )開(kāi)始工作。

在不輸入整個(gè)固件的詳細信息的情況下,現在讓我們看看在第一個(gè)versoin中實(shí)現的基本行;其思想是實(shí)現有限狀態(tài)自動(dòng)機,其操作狀態(tài)存儲在割草機狀態(tài)變量中。

當狀態(tài)變量取值為0時(shí),顯示屏上將顯示CHARGE(充電)字樣:這是點(diǎn)火后不久的初始狀態(tài),機器人仍在充電,等待按下PEN引導按鈕。

當狀態(tài)變量的值為1時(shí),顯示屏上將顯示RUN(運行)字樣:這是主要狀態(tài),機器人正在割草,同時(shí)驗證是否存在障礙物。在這種情況下,將啟動(dòng)一個(gè)簡(jiǎn)單的程序,該程序將修改行駛方向。

當狀態(tài)變量的值為2時(shí),顯示器上將顯示單詞STUCK:在這種狀態(tài)下,機器人被卡住了。由于后輪停止轉動(dòng)并且沒(méi)有向板發(fā)出任何信號,因此檢測到了這種情況。

當狀態(tài)變量取值3時(shí),顯示屏上將顯示單詞SEARCH:在這種狀態(tài)下,電池電量接近低,切割發(fā)動(dòng)機停止,機器人尋找發(fā)光的地方為自己充電。

當狀態(tài)變量的值為4時(shí),顯示屏上將顯示單詞BATLOW:在這種狀態(tài)下,電池電量不足,無(wú)法找到令人滿(mǎn)意的充電位置。甚至牽引電機也被停止,機器人仍處于充電模式。

當狀態(tài)變量取值5時(shí),顯示屏上將顯示CHARGE RS字樣:在這種狀態(tài)下,機器人處于充電位置,一旦電池完全充電,機器人將準備再次啟動(dòng)。

當狀態(tài)變量的值為6時(shí),顯示器上將顯示單詞CUTERROR:在這種狀態(tài)下,機器人靜止不動(dòng),因為它檢測到切割發(fā)動(dòng)機電流吸收異常。

為地下線(xiàn)路供電的電路

MowerGround

如前所述,地下布線(xiàn)需要形成一個(gè)閉環(huán),并由頻率為34Khz的交流信號供電。要做到這一點(diǎn),需要一個(gè)非常簡(jiǎn)單的不穩定電路。它是用一個(gè)NE555集成電路和幾個(gè)更多的組件創(chuàng )建的;該電路與以前的版本相同,并計算到具有9伏次級的變壓器的連接,該變壓器又以220Vac連接到電網(wǎng)。

0826_Schema

然而,根據該項目背后的理念,建議使用小型太陽(yáng)能電池板和緩沖電池,從電網(wǎng)中獨立供電。太陽(yáng)能電池板將是電路的主要電源,而12V電池(與C1電容器并聯(lián))將是在陽(yáng)光照射不足的情況下的主要電源。橋式整流器的存在將防止電池張力在低陽(yáng)光暴露期間進(jìn)入太陽(yáng)能電池板。為了正確平衡系統,需要確保在夜間電池能夠為電路供電而不會(huì )電量過(guò)低,而太陽(yáng)能電池板必須能夠為電路充電,同時(shí)在白天為電池充電。

0826_Silk

0826_03_montaggio

該系統與花園中的太陽(yáng)能燈沒(méi)有什么不同,它們不需要連接到家庭網(wǎng)絡(luò )的電線(xiàn)。地下布線(xiàn)將形成一個(gè)封閉的環(huán),以標記割草機工作區域的界限。由于車(chē)載傳感器,該區域內的任何其他障礙物都將得以避免。

唯一要進(jìn)行的校準涉及發(fā)送到地下線(xiàn)路的信號的頻率調節:將電纜靠近BWF傳感器的卷軸并旋轉微調器就足夠了,直到獲得盡可能好的讀數(為此,使用傳感器測試程序)。

BOM

R1: 3,3 kohm

R2: 12 kohm

R3: 100 ohm

R4: 4,7 kohm MV

C1: 1.000 μF 35 VL

C2, C4: 100 nF

C3: 1,2 nF 63 VL

C5: 1 μF 63 VL

PT1: W06M

U1: NE555

機械設計

Mechanical




評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>