女人自慰AV免费观看内涵网,日韩国产剧情在线观看网址,神马电影网特片网,最新一级电影欧美,在线观看亚洲欧美日韩,黄色视频在线播放免费观看,ABO涨奶期羡澄,第一导航fulione,美女主播操b

電子發燒友App

硬聲App

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
電子發燒友網>電子資料下載>電子資料>機器人割草機開源分享

機器人割草機開源分享

2023-06-15 | zip | 0.00 MB | 次下載 | 2積分

資料介紹

描述

概述

讓你的草坪在夏日的陽光下煥然一新對于房主來說通常是一件可怕的家務事。機器人割草機可以消除夏季最令人生畏的家務之一。它看起來類似于機器人吸塵器。你可以看著它在你的草坪上飛來飛去,讓你的草坪保持最佳狀態。為割草機配備支持物聯網的功能,例如藍牙Wi-Fi 連接、GPS 導航和靈活的調度功能,可以讓您在任何地方使用移動應用程序控制割草機并跟蹤割草進度。

特征

  • 割草機由鋰電池供電,非常安靜,可以發送低電量警報。
  • 測量割草路徑。
  • 調整切割高度。
  • 自動路線規劃。
  • 使用移動應用程序進行遠程控制。

?

腳步

第 1 步:硬件設計

割草機包括四個硬件部件。

  • 無線連接系統:涂鴉的網絡模塊允許在任何地方在移動應用程序上遠程控制和查看割草機狀態。
  • 動力系統:12V鋰電池組配合減速電機推動橡膠輪胎車輪前進。
  • 割草控制系統:兩個伺服系統可調節切割高度,切割刀片和驅動輪采用無刷直流電機。
  • 定位導航系統:集成GNSS模塊和磁傳感器,實現導航定位能力。

無線連接系統

將您的 MCU 與涂鴉的網絡模塊對接,讓您的產品支持物聯網并連接到云端。

涂鴉提供一站式物聯網開發服務,包括典型物聯網產品的三大要素,即網絡模塊、移動應用和云服務。借助涂鴉MCU SDK、一體機APP和控制面板,您可以輕松專注于應用開發,輕松將您的產品接入涂鴉IoT平臺,快速享受云服務。

MCU SDK 是根據您在涂鴉物聯網平臺上定義的產品特性自動生成的。為了方便與協議的接口,MCU SDK 內置了對通信和協議解析的支持。您可以將此 SDK 添加到現有項目中并完成所需的配置以實現 MCU 程序開發。

pYYBAGNodJeAVc-RAABpxyjY7sU261.png
?

硬件資源要求

MCU 的 SDK 要求如下。如果你的 MCU 沒有足夠的資源,你可以參考 SDK 中的函數來對接涂鴉的協議。

  • 內存:4 KB
  • RAM:需要大約 100 字節的 RAM,具體取決于數據點 (DP) 的數據長度。如果啟用 OTA 更新,它必須大于 260 字節。
  • 嵌套函數:9 級。

選擇網絡模塊

涂鴉針對物聯網項目的各種需求,提供了一系列不同協議的模塊,如Wi-Fi 模塊Wi-Fi 和藍牙 LE 模塊

為了簡化開發過程,您可以選擇涂鴉三明治評估套件

電源系統

電源

通常,市場上的割草機由氣體或電池供電。

燃氣割草機只要有足夠的燃料并且比電池供電的割草機更強大,就可以跑很遠。然而,它比電池選項產生更多的噪音,并在整個氣體燃燒過程中產生排放。

我們選擇環保鋰電池組為我們的割草機供電,以減輕噪音和污染影響。

電池

建議使用 3S 或 4S 12V 鋰離子電池鋰離子電池的充放電倍率可以達到15C甚至超過20C,保證了強大的動力推動車輪前進。如果您不選擇鋰離子電池,請選擇使用壽命長且最大輸出電流大于 5A 的電池。

pYYBAGNodJuAPMdOAADJTE7zzPI096.png
?

降壓轉換器

我們需要一個降壓轉換器來為不同的系統提供輸出電壓。

降壓轉換器LM2596提供 3.3V、5V、12V 的固定輸出電壓和可調輸出版本。它具有以下特點。

  • 輸入電壓范圍高達 40 V。
  • 可調版本輸出電壓范圍:在線路和負載條件下最大為 1.2V 至 37V ±4%。
  • 3A 輸出負載電流。
  • 高效率。
  • 熱關斷和限流保護。
poYBAGNodJ6AKBULAABxTV0hKDY081.png
?

齒輪馬達

減速電機可以定義為直流電機的延伸。它有一個連接到電機的齒輪組件,以增加扭矩并降低速度。

減速電機的額定電壓必須與電池的額定電壓相匹配。12V 電機的電源電壓范圍為 11V 至 16V。

我們選用MG513直流12V減速電機,額定輸出電流0.36A。其減速比為1/60,空載轉速為183 RPM。電機可提供 2 kgf.cm 的扭矩和 6 kg 的最大負載。使用 65 mm 橡膠輪,割草機的速度可以達到 0.5 m/s。

電機具有內置霍爾效應傳感器。基于磁感應,我們可以得到電機的轉速,然后測量所經過的速度和距離。

poYBAGNodKGAeSzkAAA3VZotJyc396.png
?

電機驅動器

東芝TB6612FNG驅動器是一款基于 MOSFET 的雙通道 H 橋集成電路它具有以下特點。

  • 電源電壓:VM = 15V(最大值)。
  • 輸出電流:I = 1.2A(平均)/3.2A(峰值)。
  • 輸出低導通電阻:0.5Ω。
  • 內置熱關斷電路和低電壓檢測電路。
  • PWM信號的開關頻率:100 kHz。

TB6612FNG 不需要散熱器,因為它比基于雙極結型晶體管 (BJT) 的驅動器(如 L298N)效率更高。外圍電路簡單,加電源濾波電容即可驅動電機。

TB6612FNG有一對驅動器,可以獨立控制兩個電機。因此,四個電機只需要兩個 TB6612FNG IC

STBY引腳為高電平時,兩個輸入信號IN1IN2可以是順時針(CW)、逆時針(CCW)、短制動和停止模式等四種模式之一。

pYYBAGNodKOAWoS5AAAPMg_kloQ958.png
?

示意圖如下。

?
pYYBAGNodKaAFmJYAACYo1T2mgM831.png
?

割草控制系統

割草控制系統可以調節割草高度并控制割草操作。

無刷直流電機

無刷電機沒有電刷,因此在有刷電機運行時不會產生電火花,大大降低了電火花對射頻遙控設備的干擾。無刷,運行時摩擦力大大降低,運行平穩,噪音低很多。這一優勢是對穩定性和長使用壽命的巨大支持。

pYYBAGNodKmAXezxAACUe9_bq7M652.png
?

我們使用 900 Kv 的無刷電機。選擇電機時,請考慮 Kv 額定值和扭矩兩個因素。無刷電機的 Kv 額定值是電機的空載轉速與連接到線圈的導線上的峰值電壓之比。一般來說,電機的Kv越大,電機所能產生的扭矩就越小。

尺寸方面,推薦使用2212電機。

電子速度控制器 (ESC)

電子速度控制器 (ESC) 是一種控制和調節電動機速度的電子電路。

poYBAGNodKuARHZkAAAiNAVxQ70403.png
?

我們使用 20A 電調。確保 ESC 的輸出電流與無刷電機的輸出電流匹配。

它具有以下特點。

  • 用于多旋翼控制器的特殊核心程序大大提高了油門響應。
  • 特別優化的軟件,與盤式電機具有出色的兼容性。
  • 除定時外的所有設置都是預設的,使用簡單,高度智能,自適應。
  • 油門信號線采用雙絞線設計,有效降低信號傳輸中產生的串擾,使飛行更加平穩。
  • 專用驅動芯片的MOSFET驅動效果比由分立元件組成的普通驅動電路要好得多。
  • 具有超低電阻的 MOSFET 帶來高性能和大電流耐受性。

伺服

伺服系統包含直流電機、控制電路、減速器、反饋機構和其他電路它可以根據輸入信號轉到特定位置。其內部的電位器或角度傳感器可以感應輸出軸的位置,從而使控制板據此準確控制輸出軸的轉動。

pYYBAGNodK2AM13XAACAB4HnkVs428.png
?

通常,舵機有三根線:棕色或黑色一根是地線,紅色一根是電源線,橙色或白色一根是信號線。

舵機可以工作在 4V 到 6V 之間,推薦使用 5V 電壓。伺服旋轉的角度是通過調整PWM信號的占空比來實現的。標準 PWM 信號的周期固定為 20 ms (50 Hz)。脈沖寬度在 0.5 ms 到 2.5 ms 之間,對應伺服旋轉角度 0° 到 180°。

兩個舵機和一些金屬圓盤組成一個升降結構來調整切割高度。

pYYBAGNodLCAMqjPAAFt5YBzXds574.png
?

定位導航系統

定位導航系統可實現定位和定向。

全球導航衛星系統定位

全球導航衛星系統 (GNSS) 是一個衛星網絡,用于廣播時間和軌道信息,用于導航和定位測量。目前,美國的全球定位系統(GPS)、俄羅斯的全球導航衛星系統(GLONASS)、中國的北斗衛星導航系統(BDS)和歐盟的伽利略系統都是全面運行的全球導航衛星系統。

pYYBAGNodLOAaJvPAACwouzwh6M259.png
?

我們使用涂鴉的GUC300 GNSS 模塊進行定位和導航。

  • GUC300由高度集成的GNSS芯片UFirebird-UC6226NIS和外圍電路組成。它具有內置SAW濾波器、低噪聲放大器(LNA)、26 MHz溫度補償晶體振蕩器(TCXO)等元件。它同時支持 GPS 和 BDS 衛星導航系統。

GUC300 具有以下特點。

  • 定位引擎:

64個同步跟蹤通道

熱啟動時間:<1.2秒

冷啟動靈敏度:-145 dBm。跟蹤靈敏度:-158 dBm

數據更新率:高達 10 Hz

  • 定位引擎:

RF子系統采用寬帶設計。輸入信號的中心頻率約為 1575 MHz。

接收和跟蹤 GPS 的 1575.42 MHz L1 信號

接收和跟蹤北斗衛星導航系統1561.098 MHz B1信號

GUC300默認接收GPS和BDS信號,可定制為GPS+BDS、GPS+GLONASS或單GNSS系統。您可以提交服務單以請求所需的 GNSS 固件。

poYBAGNodLWAf5W-AABXjI-kJu0940.png
?

GUC300 默認每秒輸出$GNRMC, $GNGGA, 和$GPGSV句子。串口波特率為9600。我們可以解析$GNGGA句子。

$GNGGA,071520.00,3018.12971,N,12003.84423,E,1,20,1.47,60.5,M,,M,,\*61

上述句子的字段描述如下。$GNGGA, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>, <9>, M, <10>, M, <11> , <12>*xx

  • \$GNGGA:句子類型標識符。此示例指示 GGA 協議頭。
  • <1>:UTC時間,格式為hhmmss.sss.
  • <2>:緯度,格式為ddmm.mmmm. 插入前導零。
  • <3>:緯度半球,N或S(北緯或南緯)。
  • <4>:經度,格式為dddmm.mmmm. 插入前導零。
  • <5>:半球經度,E或W(東經或西經)。
  • <6>:GPS定位狀態。0: 初始化。1: 單點定位。2: 差別。3: 無效的 PPS。4: 固定解決方案。5: 浮點解。6: 估計。7:手動輸入的固定值。8模擬模式。9: WAAS different.xx: 從$to開始的所有 ASCII 字符的 XOR 校驗值\*
  • <7>:使用的衛星數,范圍從00到12。插入前導零。
  • <8>:水平精度稀釋度(HDOP),范圍從0.5到99.9。HDOP越小,衛星分布越好。
  • <9>:海平面高度,范圍從-9999.9到9999.9。
  • 以米為單位。
  • <10>:地球橢球體相對于大地水準面的高度,范圍從-9999.9到9999.9。
  • 以米為單位。
  • <11>:距離上次接收到差分 GPS 信號的秒數。如果不采用差分定位,則該字段為空。
  • <12>:差分參考基站標簽,范圍從0000到1023。插入前導零。
  • :回車,結束標記。
  • :換行,結束標簽。

電路原理

GUC300原理圖

GUC300 電路板

電子羅盤傳感器

我們選擇了 3 軸電子羅盤傳感器QMC5883L

poYBAGNodLmAYom1AADxNKn769Y336.png
?

電子羅盤由一個 3D 磁阻傳感器、一個 2 軸傾角儀和一個 MCU 組成。3D磁阻傳感器用于監測地磁場的變化,傾角儀可以測量感應方向與地平面之間的角度(相對于重力)。MCU 處理輸入信號并輸出??數據以補償硬鐵和軟鐵失真。磁力計包括 x、y 和 z 方向的三個磁阻傳感器,以相應地測量地磁場強度。傳感器在每個方向上的靈敏度已根據地磁場矢量進行了最佳校準。交叉軸靈敏度已降至最低。來自傳感器的模擬輸出信號將被放大,然后發送到 MCU 進行處理。

我們可以使用下面的公式來計算方向。

方向.x=atan2((double)Mag_data.y, (double)Mag_data.x)*57.3+180;

Mag_data.x分別是 X 軸和Mag_data.yY 軸的數據。atan2是平面的正 x 軸與其上坐標 (x, y) 給定的點之間的弧度角。將弧度值乘以 57.3 以將弧度轉換為度數。最后,將轉換后的值加上 180 度。

對于計算結果,真南為0或360,西為90,北為180,東為270。

組裝設備

設計一個安裝輪子、伺服系統和其他組件的底板。下載底板結構文件

pYYBAGNodLuAU-AJAABRjS-tIKA936.png
?

整個組件看起來像這樣。

我們需要設計一個PCB布局來放置電機驅動器和電源等組件。確保為舵機、電機和電子羅盤的接口預留空間,以保持項目整潔。您還可以添加一些功能,例如用于警報的蜂鳴器和用于信號的 LED

?
poYBAGNodL6AIN3hAAGfAKx2X5Y814.png
?

電路原理圖

原理圖,示意圖

印刷電路板

最后,將 GPS、微控制器和電源單元安裝在 PCB 上,PCB 組裝完成。

第 2 步:創建產品

1.登錄涂鴉IoT平臺。

2.點擊創建

?
pYYBAGNodMCABRgEAABn9EEWG-Q831.png
?

3.向下滾動頁面并單擊找不到類別?在左下角。

4.填寫所需信息并點擊創建

  • Product Name Product DescriptionProduct Model是用戶定義的。
  • 選擇Wi-Fi-Bluetooth作為協議,然后單擊Create
?
poYBAGNodMSAHpPtAACLHM8oWb4237.png
?

5.在自定義函數部分,單擊添加以創建所需的函數。函數定義步驟中,您可以根據需要添加標準函數或創建自定義函數。

我們設置了以下功能。

  • 標準功能:方向控制
  • 自定義功能:刀片位置、刀片轉速、切割長度、切割寬度、鋸齒割草模式。
?
poYBAGNodMaAHVzsAABFhZkGQdM639.png
?

6. 在設備面板選項卡的第二步中,選擇所需的面板。在設備面板的第二步,可以選擇調試友好的DIY風格面板。

7.在硬件開發的第三步,選擇涂鴉標準模塊SDK

?
pYYBAGNodMmALx2fAABrSbjvILs361.png
?

8.向下滾動頁面并找到下載文檔點擊全部下載,下載MCU SDK開發所需的全部文件。

?
poYBAGNodMuAJO6QAAA3lMfN09k784.png
?
  • 平臺上的操作就完成了。您可以使用涂鴉智能 App 使用虛擬設備進行遠程控制。
?
pYYBAGNodM-AcYnyAAA3oEDeWFw109.png
?

第 3 步:固件開發

在應用程序開發之前,您需要將 MCU SDK 移植到您的項目中。

然后將通用固件和涂鴉的授權刷入網絡模塊。這樣,割草機就可以與云進行通信。

演示例程還包括 FreeRTOS,以方便您的開發。

以上準備工作完成后,就可以進行應用開發了。

下載示例代碼:tuya-iotos-embeded-mcu-demo-wifi-ble-samrt-lawn-mower

電機、伺服和電調驅動器

將四個電機連接到每個車輪以進行運動。兩個舵機用于控制 ESC 以及連接到 ESC 的刀片的位置。ESC 控制和調節刀片旋轉的速度。

編寫上述組件的初始化程序,在servo_motor.c.

  • 為輸出 GPIO 定義宏。
#define MOTOR_PORT_1                        GPIOA
#define MOTOR_PIN_1                         GPIO_PIN_15
#define MOTOR_PORT_1_P                      GPIOD
#define MOTOR_PIN_1_P                       GPIO_PIN_0
#define MOTOR_PORT_1_N                      GPIOD
#define MOTOR_PIN_1_N                       GPIO_PIN_7
#define MOTOR_PORT_2                        GPIOB
#define MOTOR_PIN_2                         GPIO_PIN_9
#define MOTOR_PORT_2_P                      GPIOD
#define MOTOR_PIN_2_P                       GPIO_PIN_1
#define MOTOR_PORT_2_N                      GPIOD
#define MOTOR_PIN_2_N                       GPIO_PIN_2
#define MOTOR_PORT_3                        GPIOB
#define MOTOR_PIN_3                         GPIO_PIN_10
#define MOTOR_PORT_3_P                      GPIOD
#define MOTOR_PIN_3_P                       GPIO_PIN_3
#define MOTOR_PORT_3_N                      GPIOD
#define MOTOR_PIN_3_N                       GPIO_PIN_4
#define MOTOR_PORT_4                        GPIOB
#define MOTOR_PIN_4                         GPIO_PIN_11
#define MOTOR_PORT_4_P                      GPIOD
#define MOTOR_PIN_4_P                       GPIO_PIN_8
#define MOTOR_PORT_4_N                      GPIOD
#define MOTOR_PIN_4_N                       GPIO_PIN_9
#define MOTOR_CHANNEL_1                     TIMER_CH_0
#define MOTOR_CHANNEL_2                     TIMER_CH_1
#define MOTOR_CHANNEL_3                     TIMER_CH_2
#define MOTOR_CHANNEL_4                     TIMER_CH_3
#define SERVO_PORT_1                        GPIOC
#define SERVO_PIN_1                         GPIO_PIN_6
#define SERVO_PORT_2                        GPIOC
#define SERVO_PIN_2                         GPIO_PIN_7
#define BLADE_MOTOR_PORT                    GPIOC
#define BLADE_MOTOR_PIN                     GPIO_PIN_8
  • 調用初始化接口開啟GPIO時鐘,指定輸出GPIO為普通模式或PWM模式。然后,調用timer_config設置 PWM 參數
void servo_motor_init(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
rcu_periph_clock_enable(RCU_GPIOD);

/*Configure PD1~8 Output motor Positive and Negative pin to drive wheels_1~4*/
gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MOTOR_PIN_1_P | MOTOR_PIN_1_N | MOTOR_PIN_2_P | MOTOR_PIN_2_N | MOTOR_PIN_3_P | MOTOR_PIN_3_N | MOTOR_PIN_4_P | MOTOR_PIN_4_N);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MOTOR_PIN_1_P | MOTOR_PIN_1_N | MOTOR_PIN_2_P | MOTOR_PIN_2_N | MOTOR_PIN_3_P | MOTOR_PIN_3_N | MOTOR_PIN_4_P | MOTOR_PIN_4_N);
gpio_bit_reset(GPIOD, MOTOR_PIN_1_P | MOTOR_PIN_1_N | MOTOR_PIN_2_P | MOTOR_PIN_2_N | MOTOR_PIN_3_P | MOTOR_PIN_3_N | MOTOR_PIN_4_P | MOTOR_PIN_4_N);

/*Configure PA15(TIMER1_CH0) Output PWM pulse to drive wheels_1*/
gpio_mode_set(MOTOR_PORT_1, GPIO_MODE_AF, GPIO_PUPD_NONE, MOTOR_PIN_1);
gpio_output_options_set(MOTOR_PORT_1, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MOTOR_PIN_1);
gpio_af_set(MOTOR_PORT_1, GPIO_AF_1, MOTOR_PIN_1);
/*Configure PB9(TIMER1_CH1) Output PWM pulse to drive wheels_2*/
gpio_mode_set(MOTOR_PORT_2, GPIO_MODE_AF, GPIO_PUPD_NONE, MOTOR_PIN_2);
gpio_output_options_set(MOTOR_PORT_2, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MOTOR_PIN_2);
gpio_af_set(MOTOR_PORT_2, GPIO_AF_1, MOTOR_PIN_2);
/*Configure PB10(TIMER1_CH2) Output PWM pulse to drive wheels_3*/
gpio_mode_set(MOTOR_PORT_3, GPIO_MODE_AF, GPIO_PUPD_NONE, MOTOR_PIN_3);
gpio_output_options_set(MOTOR_PORT_3, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MOTOR_PIN_3);
gpio_af_set(MOTOR_PORT_3, GPIO_AF_1, MOTOR_PIN_3);
/*Configure PB11(TIMER1_CH3) Output PWM pulse to drive wheels_4*/
gpio_mode_set(MOTOR_PORT_4, GPIO_MODE_AF, GPIO_PUPD_NONE, MOTOR_PIN_4);
gpio_output_options_set(MOTOR_PORT_4, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,MOTOR_PIN_4);
gpio_af_set(MOTOR_PORT_4, GPIO_AF_1, MOTOR_PIN_4);
/*Configure PC6(TIMER2_CH0) Output PWM pulse to drive servo no.1*/
gpio_mode_set(SERVO_PORT_1, GPIO_MODE_AF, GPIO_PUPD_NONE, SERVO_PIN_1);
gpio_output_options_set(SERVO_PORT_1, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,SERVO_PIN_1);
gpio_af_set(SERVO_PORT_1, GPIO_AF_2, SERVO_PIN_1);

/*Configure PC7(TIMER2_CH1) Output PWM pulse to drive servo no.2*/
gpio_mode_set(SERVO_PORT_2, GPIO_MODE_AF, GPIO_PUPD_NONE, SERVO_PIN_2);
gpio_output_options_set(SERVO_PORT_2, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,SERVO_PIN_2);
gpio_af_set(SERVO_PORT_2, GPIO_AF_2, SERVO_PIN_2);

/*Configure PC8(TIMER2_CH2) Output PWM pulse to drive blade motor*/
gpio_mode_set(BLADE_MOTOR_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, BLADE_MOTOR_PIN);
gpio_output_options_set(BLADE_MOTOR_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,BLADE_MOTOR_PIN);
gpio_af_set(BLADE_MOTOR_PORT, GPIO_AF_2, BLADE_MOTOR_PIN);

timer_config();
}
void timer_config(void)
{
uint16_t i = 0;

/* TIMER1 configuration: generate PWM signals with different duty cycles:
TIMER1CLK = SystemCoreClock / 120 = 1MHz */
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER1);
rcu_periph_clock_enable(RCU_TIMER2);
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
timer_struct_para_init(&timer_initpara);
timer_deinit(TIMER1);
timer_deinit(TIMER2);
/* TIMER1 configuration */
timer_initpara.prescaler         = 119;
timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection  = TIMER_COUNTER_UP;
timer_initpara.period            = 500; /* 500*(1/1MHZ) = 500us */
timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER1,&timer_initpara);
/* TIMER2 configuration */
timer_initpara.prescaler         = 119;
timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection  = TIMER_COUNTER_UP;
timer_initpara.period            = 20000; /* 20000*(1/1MHZ) = 20ms */
timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2,&timer_initpara);
timer_channel_output_struct_para_init(&timer_ocintpara);
timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
for(i = 0; i < 4; i++) {

timer_channel_output_config(TIMER1,i,&timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER1,i,0);
timer_channel_output_mode_config(TIMER1,i,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER1,i,TIMER_OC_SHADOW_DISABLE);
}
for(i = 0; i < 3; i++) {

timer_channel_output_config(TIMER2,i,&timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER2,i,0);
timer_channel_output_mode_config(TIMER2,i,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER2,i,TIMER_OC_SHADOW_DISABLE);
}
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER1);
timer_auto_reload_shadow_enable(TIMER2);
/* TIMER enable */
timer_enable(TIMER1);
timer_enable(TIMER2);
}
  • 調整電機和舵機的PWM占空比,將占空比調整的操作封裝為通用接口。以連接到車輪的電機為例。car_moving用于根據輸入方向和速度調整正負電平和占空比,從而控制車輪。
void car_moving(MOVING_DIRECTION direction, uint16_t speed_value)
{
uint8_t i;
switch(direction) {

case forward:

gpio_bit_set(GPIOD, MOTOR_PIN_1_P | MOTOR_PIN_2_P | MOTOR_PIN_3_P | MOTOR_PIN_4_P);
gpio_bit_reset(GPIOD, MOTOR_PIN_1_N | MOTOR_PIN_2_N | MOTOR_PIN_3_N | MOTOR_PIN_4_N);

for(i = 0; i < 4; i++) {
timer_channel_output_pulse_value_config(TIMER1,i,speed_value);
}
break;
case right:

gpio_bit_set(GPIOD, MOTOR_PIN_1_P | MOTOR_PIN_2_P | MOTOR_PIN_3_P | MOTOR_PIN_4_P);
gpio_bit_reset(GPIOD, MOTOR_PIN_1_N | MOTOR_PIN_2_N | MOTOR_PIN_3_N | MOTOR_PIN_4_N);

//Since the two sets of wheels on the right are always faster than the left in the actual commissioning process, 60 is added to compensate
timer_channel_output_pulse_value_config(TIMER1,MOTOR_CHANNEL_1,speed_value + 60);
timer_channel_output_pulse_value_config(TIMER1,MOTOR_CHANNEL_3,speed_value + 60);

timer_channel_output_pulse_value_config(TIMER1,MOTOR_CHANNEL_2,speed_value);
timer_channel_output_pulse_value_config(TIMER1,MOTOR_CHANNEL_4,speed_value);
break;
case left:

gpio_bit_set(GPIOD, MOTOR_PIN_1_P | MOTOR_PIN_2_P | MOTOR_PIN_3_P | MOTOR_PIN_4_P);
gpio_bit_reset(GPIOD, MOTOR_PIN_1_N | MOTOR_PIN_2_N | MOTOR_PIN_3_N | MOTOR_PIN_4_N);
timer_channel_output_pulse_value_config(TIMER1,MOTOR_CHANNEL_1,speed_value);
timer_channel_output_pulse_value_config(TIMER1,MOTOR_CHANNEL_3,speed_value);

timer_channel_output_pulse_value_config(TIMER1,MOTOR_CHANNEL_2,speed_value + 50);
timer_channel_output_pulse_value_config(TIMER1,MOTOR_CHANNEL_4,speed_value + 50);
break;
case backward:

gpio_bit_reset(GPIOD, MOTOR_PIN_1_P | MOTOR_PIN_2_P | MOTOR_PIN_3_P | MOTOR_PIN_4_P);
gpio_bit_set(GPIOD, MOTOR_PIN_1_N | MOTOR_PIN_2_N | MOTOR_PIN_3_N | MOTOR_PIN_4_N);

for(i = 0; i < 4; i++) {
timer_channel_output_pulse_value_config(TIMER1,i,speed_value);
}
break;
case stop:

gpio_bit_reset(GPIOD, MOTOR_PIN_1_P | MOTOR_PIN_2_P | MOTOR_PIN_3_P | MOTOR_PIN_4_P);
gpio_bit_reset(GPIOD, MOTOR_PIN_1_N | MOTOR_PIN_2_N | MOTOR_PIN_3_N | MOTOR_PIN_4_N);

for(i = 0; i < 4; i++) {
timer_channel_output_pulse_value_config(TIMER1,i,speed_value);
}
break;
default:
break;
}
}

用于線性運動校正的比例積分微分 (PID) 算法

由于四個輪子由獨立的電機控制,即使 PWM 輸出設置為相同的占空比,錯誤和其他因素也會導致割草機偏離線性運動。因此,我們使用PID算法來動態調整每個車輪的實際轉速。直線運動表示四個輪子同時移動相同的距離。由于四個輪子的直徑相同,因此每個輪子的轉速應該相同。因為電機轉速直接決定了電機編碼器輸出的脈沖數,所以我們以電機編碼器單位時間內實時輸出的脈沖數作為PID算法的輸入,占空比增量作為控制對象。我們可以不斷微調脈沖,使四個電機達到相同的值。

  • 通過外部中斷對脈沖進行計數,收集電機編碼器輸出脈沖的單位時間增量。中的movement_system_init()函數movement.c包括外部中斷的配置。
void movement_system_init(void)
{
rcu_periph_clock_enable(RCU_SYSCFG);

gpio_mode_set(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
nvic_irq_enable(EXTI0_IRQn, 2U, 0U);
syscfg_exti_line_config(EXTI_SOURCE_GPIOC, EXTI_SOURCE_PIN0);
exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_flag_clear(EXTI_0);

gpio_mode_set(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
nvic_irq_enable(EXTI1_IRQn, 2U, 0U);
syscfg_exti_line_config(EXTI_SOURCE_GPIOC, EXTI_SOURCE_PIN1);
exti_init(EXTI_1, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_flag_clear(EXTI_1);
gpio_mode_set(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_2);
nvic_irq_enable(EXTI2_IRQn, 2U, 0U);
syscfg_exti_line_config(EXTI_SOURCE_GPIOC, EXTI_SOURCE_PIN2);
exti_init(EXTI_2, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_flag_clear(EXTI_2);

gpio_mode_set(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_3);
nvic_irq_enable(EXTI3_IRQn, 2U, 0U);
syscfg_exti_line_config(EXTI_SOURCE_GPIOC, EXTI_SOURCE_PIN3);
exti_init(EXTI_3, EXTI_INTERRUPT, EXTI_TRIG_RISING);
exti_interrupt_flag_clear(EXTI_3);
}

void EXTI0_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_0)){
move_state.encoder_pulse[0]++;
}
exti_interrupt_flag_clear(EXTI_0);
}
void EXTI1_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_1)){
move_state.encoder_pulse[1]++;
}
exti_interrupt_flag_clear(EXTI_1);
}
void EXTI2_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_2)){
move_state.encoder_pulse[2]++;
}
exti_interrupt_flag_clear(EXTI_2);
}
void EXTI3_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_3)){
move_state.encoder_pulse[3]++;
}
exti_interrupt_flag_clear(EXTI_3);
}
  • 實現forward_correction()接口,將收集到的脈沖pulse_num、最后一個脈沖pulse_num_old和所需的脈沖增量standard_increment傳遞給 PID 控制函數。調用single_motor_speed_set()根據計算結果調整各電機的PWM占空比。
int e[4]={0},e1[4]={0},e2[4]={0}; // PID offset
float uk[4]={0.0},uk1[4]={0.0},duk[4]={0.0}; // PID output
float Kp=0.8,Ki=0.3,Kd=0.9; // PID control factors.
int out[4] = {0};
static void forward_correction(uint32_t *pulse_num, uint32_t *pulse_num_old, uint32_t standard_increment)
{
uint8_t i = 0;

for(i = 0;i < 4;i++) {
e[i] = standard_increment - (pulse_num[i] - pulse_num_old[i]);
duk[i] = (Kp*(e[i]-e1[i])+Ki*e[i])/100;
uk[i] = uk1[i] + duk[i];
out[i] = (int)uk[i];
uk1[i] = uk[i];
e2[i] = e1[i];
e1[i] = e[i];
single_motor_speed_set(i, (uint16_t)(200+(out[i]*5)));
}
return;
}
  • 當運動輪詢處理程序進入switch直線運動的分支時,您可以調用forward_correction()來調整電機速度,然后將 分配encoder_pulseencoder_pulse_old
void movement_logic_handle(void)
{
MOVE_STATE_T *p = NULL;
p = &move_state;
uint8_t i = 0;
MOVING_DIRECTION turning_state;

switch(p->todo_type) {

......
case on_the_move:

if(forward_sampling_time_flag == 20) { //20*20ms = 400ms
for(i = 0;i < 4;i++) {
pulse_test[i] = p->encoder_pulse[i]-p->encoder_pulse_old[i];
}
forward_correction(p->encoder_pulse,p->encoder_pulse_old,390);

for(i = 0;i < 4;i++) {
p->encoder_pulse_old[i] = p->encoder_pulse[i];
}
forward_sampling_time_flag = 0;
}
forward_sampling_time_flag++;

todo_judge();

break;
......
default:
break;
}

}

讓割草機旋轉 90 度

以之字形割草模式為例。當割草機到達直線運動的終點時,它必須轉動 90 度。todo_judge功能用于確定旋轉運動,該運動也基于來自電機編碼器的脈沖數。將長度轉換為脈沖數。當脈沖達到規定值時,割草機將轉動 90 度。割草機需要確定從長邊或寬邊轉向以及向左或向右轉向。todo_judge()函數有判斷switch分支指示割草機是case從長邊轉向還是從寬邊轉向。case用于判斷直線運動中的割草機是否應轉彎如果是,則轉彎狀態將更改(change_to_do(turning);),并且案例分支p->run_step_flag = width_right;將在割草機在下一個行駛階段進入此功能時更改。如果寬度達到規定值,則表明曲折割草作業完成。

static void todo_judge(void)
{
MOVE_STATE_T *p = NULL;
p = &move_state;

switch(p->run_step_flag) {

case length_right:
if(pulse_to_distance(p->encoder_pulse[0]) >= (p->range_length_mm - 10)) {
if((p->current_angle + 900) > 3600) {
p->target_angle = p->current_angle + 900 - 3600;
}else{
p->target_angle = p->current_angle + 900;
}
change_to_do(turning);
p->run_step_flag = width_right;
}
break;
case width_right:
if(pulse_to_distance(p->encoder_pulse[0]) >= 100) {
if((p->current_angle + 900) > 3600) {
p->target_angle = p->current_angle + 900 - 3600;
}else{
p->target_angle = p->current_angle + 900;
}
change_to_do(turning);
p->run_step_flag = length_left;
width_remain_mm -= 100;
}
break;
case length_left:
if(pulse_to_distance(p->encoder_pulse[0]) >= (p->range_length_mm - 10)) {
if(p->current_angle < 900) {
p->target_angle = 3600 - (900 - p->current_angle);
}else{
p->target_angle = p->current_angle - 900;
}
change_to_do(turning);
p->run_step_flag = width_left;
}
break;
case width_left:
if(pulse_to_distance(p->encoder_pulse[0]) >= 100) {
if(p->current_angle < 900) {
p->target_angle = 3600 - (900 - p->current_angle);
}else{
p->target_angle = p->current_angle - 900;
}
change_to_do(turning);
p->run_step_flag = length_right;
width_remain_mm -= 100;

}
break;
default:
break;
}

if(width_remain_mm <= 0) {
change_to_do(to_stop);
move_state.bow_mode_switch = pdFALSE;
}
}
  • 上述例程中,p->target_angle是目標方位角,p->current_angle是當前方位角,用于控制割草機的轉向角。目標方位角是割草機即將轉彎時的方位角加減90度得到的。并且當前方位角是根據地磁傳感器的數據計算得出的。QMC5883L.c文件包含 I2C QMC5883L 的驅動程序代碼。在這里,我們使用QMC5883L_GetAngle()來獲取當前方位角。
void move_control_task(void *pvParameters)
{
float_xyz Mag_angle;
uint8_t test_flag = 50;
vTaskDelay(200);
QMC_Init();
QMC5883L_GetAngle(&Mag_angle);
move_state.current_angle = (int16_t)Mag_angle.x;
vTaskDelay(500);
while(1) {

if(test_flag){
vTaskDelay(20);
test_flag--;
}else if(test_flag == 0) {
vTaskDelay(20);
movement_logic_handle();
}
QMC5883L_GetAngle(&Mag_angle);
move_state.current_angle = (int16_t)Mag_angle.x;
}
}
  • 方位角可用于確定轉彎操作。angle_correction()界面可以確定割草機應該左轉還是右轉或直行。angle_correction()接口在移動輪詢處理程序turningcase分支中調用。
static MOVING_DIRECTION angle_correction(void)
{
int16_t target,current = 0;
target = move_state.target_angle;
current = move_state.current_angle;
if(target < current) {
if(current - target <= 20) {
return forward;
}
if(current - target <= 1800) {
return left;
}else{
return right;
}
}else if(target > current) {
if(target - current <= 20) {
return forward;
}
if(target - current <= 1800) {
return right;
}else{
return left;
}
}else if(current == target) {
return forward;
}
}
void movement_logic_handle(void)
{
MOVE_STATE_T *p = NULL;
p = &move_state;
uint8_t i = 0;
MOVING_DIRECTION turning_state;

switch(p->todo_type) {

......
case on_the_move:

if(forward_sampling_time_flag == 20) { //20*20ms = 400ms
for(i = 0;i < 4;i++) {
pulse_test[i] = p->encoder_pulse[i]-p->encoder_pulse_old[i];
}
forward_correction(p->encoder_pulse,p->encoder_pulse_old,390);

for(i = 0;i < 4;i++) {
p->encoder_pulse_old[i] = p->encoder_pulse[i];
}
forward_sampling_time_flag = 0;
}
forward_sampling_time_flag++;

todo_judge();

break;
case turning:

turning_state = angle_correction();
if(turning_state == right) {
car_full_turn(right,150);
turning_sampling_time_flag = 0;
}else if(turning_state == left) {
car_full_turn(left,150);
turning_sampling_time_flag = 0;
}else if(turning_state == forward) {
car_moving(stop,0);
turning_sampling_time_flag++;
}

if(turning_sampling_time_flag >= 25) {
p->todo_type = on_the_move;
car_moving(forward,200);
forward_sampling_time_flag = 0;
turning_sampling_time_flag = 0;
for(i = 0;i < 4;i++) {
p->encoder_pulse[i] = 0;
p->encoder_pulse_old[i] = 0;
}
}
break;
......
default:
break;
}

}

設置刀片位置和速度

刀片位置由兩個伺服系統控制。如果要在刀片上下移動時保持刀片的水平位置不變,則兩個舵機必須在相反的方向上改變相同的角度。兩個舵機的相反方向的角度變化必須相同。封裝一個用于設置刀片位置的接口,以位置枚舉值作為輸入。

void blade_position_set(BLADE_POSITION value)
{
switch(value) {

case low:

timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,3100);
timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_1,3000);
break;

case medium:

timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,2800);
timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_1,2700);
break;

case high:

timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,2600);
timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_1,2500);
break;

default:
break;
}
}

葉片速度由 ESC 控制并封裝在blade_speed_set();.

void blade_speed_set(BLADE_SPEED speed)
{
switch(speed) {

case init:

timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,1500);
break;

case off:

timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,0);
break;

case low_speed:

timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,1800);
break;

case medium_speed:

timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,1900);
break;

case high_speed:

timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,2000);
break;

default:
break;
}
}

5.接收GNSS數據

涂鴉 GNSS 模塊 GUC300 模塊通過串口通信向 MCU 發送 GNSS 數據。我們使用USART1MCU的來接收數據,因為USART0已經用于與Wi-Fi模塊的串行通信。

  • 初始化串口:
void uart_init(void)
{
/* USART interrupt configuration */
nvic_irq_enable(USART0_IRQn, 0, 0);
nvic_irq_enable(USART1_IRQn, 1, 1);
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART0);

/* connect port to USART0_Tx */
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);
/* connect port to USART0_Rx */
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);

/* configure USART Tx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_9);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
/* configure USART Rx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_10);
/* USART configure */
usart_deinit(USART0);
usart_baudrate_set(USART0,115200U);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);

/* enable USART clock */
rcu_periph_clock_enable(RCU_USART1);

/* connect port to USART0_Tx */
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_5);
/* connect port to USART0_Rx */
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_6);

/* configure USART Tx as alternate function push-pull */
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_5);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_5);
/* configure USART Rx as alternate function push-pull */
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_6);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6);
/* USART configure */
usart_deinit(USART1);
usart_baudrate_set(USART1,9600U);
usart_receive_config(USART1, USART_RECEIVE_ENABLE);
usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
usart_enable(USART1);

/* enable USART0 receive interrupt */
usart_interrupt_enable(USART0, USART_INT_RBNE);

/* enable USART1 receive interrupt */
usart_interrupt_enable(USART1, USART_INT_RBNE);
}
  • 初始化 USART 中斷處理函數。GUC300 默認每秒輸出$GNRMC, $GNGGA, $GPGSV, 和$GPGGA句子。我們可以解析$GPGGA句子。
  • $GPGGA句子包含17個字段:標題,位置的UTC時間狀態,緯度,緯度方向,經度,經度方向,定位質量,正在使用的衛星數量,精度水平稀釋,天線高度高于/低于平均海平面,天線高度單位、起伏(大地水準面和WGS84橢球的關系)、起伏的單位、校正數據的年齡、差分基站ID、校驗和、句子終止符。
  • 例子:$GPGGA,014434.70,3817.13334637,N,12139.72994196,E,4,07,1.5,6.571,M,8.942,M,0.7,0016*79
  • 按照上述格式處理串行數據。
#define USART_FH_len 6  // The length of the header.
char USART_FH[USART_FH_len]={'$','G','N','G','G','A'}; // Header
#define USART_FT_len 2  // The length of the trailer.
uint8_t USART_FT[USART_FT_len]={0X0D,0X0A}; // Frame trailer
uint8_t data_buf[128] = {0};
uint8_t rx_buf[128] = {0};
uint8_t buff_len = 0;
void USART1_IRQHandler(void)
{
if((RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE)) &&
(RESET != usart_flag_get(USART1, USART_FLAG_RBNE))){

rx_buf[buff_len++] = (uint8_t)usart_data_receive(USART1);
if(rx_buf[0] != USART_FH[0]) {
rx_buf[0] = 0;
buff_len = 0;
}
if(buff_len >= USART_FH_len) {
if(strncmp((char*)rx_buf,USART_FH,USART_FH_len) == 0) {
if(strncmp(&rx_buf[buff_len-2],(char*)USART_FT,USART_FT_len) == 0) {
memcpy(data_buf,rx_buf,buff_len);
memset(rx_buf,0,buff_len);
buff_len = 0;
}
}else {
memset(rx_buf,0,USART_FH_len);
buff_len = 0;
}
}
}
}
void gps_data_task(void *pvParameters)
{
MAP_POINT_t *p;
p = &map_point[point_1];
uint8_t data_len = 0;
while(1) {
vTaskDelay(100);

data_len = strlen((char*)data_buf);
if(data_len != 0){
gps_data_pick(point_1, data_buf, data_len);
memset(data_buf,0,data_len);
}
}
}

概括

恭喜!您已經成功地制作了機器人割草機的原型。您可以添加更多酷炫和有用的功能來制作功能齊全的割草機。涂鴉物聯網平臺提供便捷的物聯網開發工具和服務,旨在讓您的物聯網項目更輕松、更高效。查看并發現更多很棒的想法

?


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數據手冊
  2. 1.06 MB  |  532次下載  |  免費
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費
  5. 3TC358743XBG評估板參考手冊
  6. 1.36 MB  |  330次下載  |  免費
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費
  9. 5元宇宙深度解析—未來的未來-風口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費
  11. 6迪文DGUS開發指南
  12. 31.67 MB  |  194次下載  |  免費
  13. 7元宇宙底層硬件系列報告
  14. 13.42 MB  |  182次下載  |  免費
  15. 8FP5207XR-G1中文應用手冊
  16. 1.09 MB  |  178次下載  |  免費

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費
  3. 2555集成電路應用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費
  7. 4開關電源設計實例指南
  8. 未知  |  21549次下載  |  免費
  9. 5電氣工程師手冊免費下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費
  11. 6數字電路基礎pdf(下載)
  12. 未知  |  13750次下載  |  免費
  13. 7電子制作實例集錦 下載
  14. 未知  |  8113次下載  |  免費
  15. 8《LED驅動電路設計》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費
  3. 2protel99se軟件下載(可英文版轉中文版)
  4. 78.1 MB  |  537798次下載  |  免費
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費
  11. 6電路仿真軟件multisim 10.0免費下載
  12. 340992  |  191187次下載  |  免費
  13. 7十天學會AVR單片機與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費
  15. 8proe5.0野火版下載(中文版免費下載)
  16. 未知  |  138040次下載  |  免費