2020年5月28日 星期四

[Arduino] 與 Arduino nano 相容的開發板 --- LGT8F328P-LQFP32 MiniEVB

對岸 LogicGreen 公司開發一款與 Arduino nano V3 相容的開發板 LQFP32,MCU 使用 LGT8F328P 晶片, USB2TTL 使用盛群 (HOLTEK)公司的 HT42B534-1 晶片。這款開發板功能跟 nano 相仿,但價位比 nano 更加實惠,是值得大家關注的一塊開發板,接下來我們就來認識它並看看如何使用它。

產品特點

  1. 自帶USB,使用更方便。
  2. 8F328P可以使用3V3與5V供電運行於16M頻率,電平兼容性極佳。
  3. 內置高精度RC,無需外部晶振即可穩定運行。
  4. 外圍零件少,電路設計簡單。
  5. 12位ADC(模數轉換)
  6. 自帶DAC
  7. 自帶GUID(唯一ID)可以用於芯片程序加密
  8. 自帶內部 1.024V/2.048V/4.096V ±1%可校准參考電壓源

參數

MCULGT8F328P
FLASH32Kbytes
SRAM2Kbytes
E2PROM可配置為 0K/1K/2K/4K/8K(與FLASH共享)
PWM8路
主頻16MHz(最大32MHz)
ADC6通道12位
DAC1通道8位
UART1路
SPI
TWI(I2C)
GUID(全局設備號)
內部基準1.024V/2.048V/4.096V ±0.5%
系統邏輯電平出廠5V(可以通過焊盤切換到3V3)
3V3最大輸出電流500MA
PCB尺寸50.8mmX25.4mm
引腳間距ALPHA引腳標准
VIO通訊電平輸入


安裝 USB2TTL 驅動程式

對岸生產的 nano 開發板的 USB2TTL 大都使用 CH340X 晶片,而 LQFP32 開發板使用的是 HT42B534-1 晶片,因此我們需要另外安裝 HT42B534-1 USB2TTL 驅動程式。

Step1 首先下載驅動程式,如果您的作業系統是 Windows 10/Macintosh OSX 則免安裝驅動程式,如果是 Windows 7, 8, 8.1 則需點擊右側網址下載 http://wiki.ocrobot.com/lib/exe/fetch.php?media=learing:star:usbbridgesetup_ca.zip (註1)

Step2 下載後解壓縮,並執行 USBBridgeSetup_CA.exe。

Step3 出現下列視窗後,一直點擊 [Next],最後點擊 [Finish]。


註1:
我的作業系統是 Windows 8.1 64bit,下載這個原廠驅動會出現下圖之問題,無法正確安裝驅動。


後來經過盛群公司黃大哥鼎力相助,終於正確安裝驅動程式,本人在此對黃大哥表示感激。

另外,對於 USB 晶片是 HT42B534-1 的用戶而言,如果你使用的是精簡版 Windows 7 系統,安裝驅動時,可能會遇到“系統找不到指定文件”這個問題。 這是因為精簡版的 Window 7 系統刪掉了一些不常用的驅動信息引起的。遇到這種情況請重裝系統,安裝完整版 Windows 7(微軟官方版)。

Step4 如果有正確安裝,您的裝置管理員應該會出現「Holtek USB To UART Bridge (COM?)」。




使用 Arduino IDE

Step1 下載 LQFP32 LGT8F328P 開發板硬件資料,https://github.com/donly/Larduino_HSP#installation

Step2 下載後解壓縮,並將 <hardware> 資料夾內的 <LGT> 資料夾複製到 Arduino 的 <hardware> 資料夾內。

Step3 啟動 Arduino IDE,點擊下拉功能表 [工具] > [開發板],然後就可以看到如下畫面,選擇 [LGT8F328P-LQFP32 MiniEVB]板子。


Step4 選擇正確的 COM port,我的在這裡是 COM8。


Step5 點擊下拉功能表 [檔案] > [範例] > [01.Basics] > [Blink],開啟範例程式 Blink.ino 並上傳程式。你可能會發現出問題了


這個問題是 Arduino 編譯器不懂 LED_BUILTIN 這個變數。

Step6 我們在程式碼前面加入這一行就可以解決這個問題

static const uint8_t LED_BUILTIN = 13;

如下圖



結論

感覺 LQFP32 這塊板子還有許多功能和問題尚待發掘,我們日後將會持續探討。



相關連結

http://wiki.ocrobot.com/doku.php?id=ocrobot%3Aalpha%3A8f328p-u%3Amain
https://magicalboy.com/lgt8f328p_nano3_compatible_board.html
https://www . youtube . com/watch?v=Myfeqrl3QP0


採購資訊

LGT8F328P-LQFP32 MiniEVB 開發板 https://goods.ruten.com.tw/item/show?22022616370203




2020年5月18日 星期一

[USB Driver] PL2303HXA USB2TTL 出現異常訊息

今天將 PL2303 USB2TTL 模組插入電腦,感覺有點怪怪的,於是打開裝置管理員,竟然發現裝置管理員的連接埠項目不是出現 COM?,而是出現

「PL2303HXA自2102已停產,請聯繫您的購買廠商。」

心想這下糟了,手裡一堆模組莫非要變成磚塊了?

於是打開 Arduino IDE 想再次確認是否有讀到 COM Port,

很幸運地,有連到,詳下圖。




雖然如此,但還是想是不是有辦法解決這個問題,於是谷歌搜尋到小狐狸事務所的一篇文,依照內文說明,下載 2009 以前的驅動程式,總算順利解決這個問題。


PS. 經過多次試驗,發現如果電腦有連網,還是會被自動改回

「PL2303HXA自2102已停產,請聯繫您的購買廠商。」









2020年4月14日 星期二

[Mecanum] 手機藍芽遙控麥克納姆輪車

本篇文在介紹如何使用手機藍芽遙控時下最夯的麥克納姆輪車。




開始組裝

Step1 使用 M3*8 螺絲和螺帽將電池盒鎖到小車底盤背面(有字那面是正面)。


這是正面


Step2 先將 4 個 TT 馬達焊上電線。
提醒您:建議您紅黑線的位置最好跟圖片上的一致。


Step3 將馬達依圖中位置擺放。
提醒您:電線的位置最好跟圖片上的一致(靠內側)。


Step4 用 M3 長螺絲鎖上鐵片。
提醒您:
1. 鐵片有螺絲孔那面須朝上,螺帽須在鐵片那一側。
2. 使用扳手,務必將螺絲鎖緊。


Step5 用 M2.3 自攻螺絲將麥克納姆輪鎖到 TT 馬達,計 4 組。
提醒您:輪子有 2 種,請您依下下圖鎖上輪子。

直徑 60mm 的輪子:直接把 TT 馬達軸小心插到輪子,並鎖上螺絲。



Step6 用 M3 短螺絲將整組馬達輪子鎖到小車底盤。
再次提醒您:檢查輪子是否如同圖中所示。


Step7 在 "a" 字上面放墊圈,計 3 個。


Step8 用 M3*12 螺絲和螺帽鎖緊 Uno 板。


Step9 將馬達驅動板插到 Uno 板上,並鎖上馬達電線和電池盒電線。
提醒您:紅黑電線的位置最好跟圖片上的一致。


Step10 用母母頭杜邦線4P連接藍芽板和馬達驅動板。至此完成。

藍芽板     馬達驅動板
Vcc           Vcc
Gnd           Gnd
Tx              Servo2
Rx              Servo1



馬達驅動板

在使用馬達驅動板之前,建議您先了解一下它的電路圖。


這是接線方式。



下載馬達驅動板程式庫

Step1 點擊下拉功能表 [工具] > [管理程式庫...],出現視窗。

Step2 在視窗右上角落欄位內輸入 "Adafruit Motor Shield",選取 "Adafruit Motor Shield library"項目並點擊 [安裝]。



Step3 安裝完後點擊 [關閉]。


上傳 Arduino 程式

打開「Mecanum01.ino」,將程式上傳到 Uno 板。


使用手機

Step1 開啟藍芽裝置並搜尋藍芽與配對。

Step2 安裝手機程式,將「Mecanum01.apk」複製到手機裡,並安裝它。

Step3 啟動 APP「Mecanum01」,可以看到如下畫面。



Step4 點擊 [Connect] 按鈕,會出現已配對之藍芽清單,如下圖。


Step5 點擊您的藍芽裝置,會出現如下畫面。


Step6 如果顯示「Connected」表示手機已連接到小車上的藍芽,此時您可以逐一點擊方向按鈕並觀察輪子轉動的方向是否正確。


Step7 如果以上都沒問題,那麼您可以移除 USB 數據線,裝上 18650 電池,然後開始玩麥克納姆輪車了。




meArm.Dynamic 小車底盤其他功能介紹

可以固定伺服馬達


超音波避障固定架套件


將超音波避障組件安裝到伺服馬達,成為麥克納姆輪避障車。



相關資訊

百度百科 https://baike.baidu.com/item/%E9%BA%A6%E5%85%8B%E7%BA%B3%E5%A7%86%E8%BD%AE/3827219

維基百科 http://wiki.seeedstudio.com/4WD_Mecanum_Wheel_Robot_Kit_Series/

ITREAD01 https://www.itread01.com/content/1549544428.html

http://html.rhhz.net/yykj/html/201701003.htm


採購資訊

麥克納姆輪車套件 https://goods.ruten.com.tw/item/show?21947912188743



2020年3月1日 星期日

[水彈槍] 自製上供彈彈倉

水彈槍的供彈方式有上面供彈和下面供彈兩種,而這裡面又有重力供彈、機械供彈和馬達供彈等方式。



由於我目前手上的水彈槍都是採上供彈方式,因此想要發揮創客精神來土泡一個上供彈彈倉。考慮經費、重量...等因素,選了隨手可得的寶特瓶來改裝,改裝過程如下:

Step1 取一支瓶裝水寶特瓶,洗淨陰乾。


Step2 使用美工刀將瓶身頭尾切開。


Step3 使用膠帶將頭尾黏合。


Step4 取出瓶蓋,使用工具將瓶蓋挖洞。水彈直徑有 6~8mm、9~11mm和11~13mm 三種,洞的大小依據你的水彈直徑而定,可稍微大 1mm。



Step5 使用美工刀和挫刀將洞口修飾整平。


Step6 使用熱熔膠將瓶蓋固定到水彈槍上。




Step7 裝上水彈,蓋上瓶身就完成了。





後記:

還有更好的供彈方式嗎?




2020年2月9日 星期日

[R/C] 用 Arduino 讀取 R/C Recever 訊號

使用遙控器搖桿可以很容易操控遙控車、船,但遙控器每一個頻道只能控制(對應)一個動作,同時操控兩個頻道也只能控制(對應)兩個動作。



坦克車左側和右側各有 1 只馬達,我們可以使用遙控器的左、右搖桿來控制坦克車的行走方向。如果想用單一搖桿來控制坦克車的行走方向,好像沒辦法做到,更別說是要去控制麥克納姆輪車可以獨立運作的 4 個輪子了。

有鑑於此,我們想出一個解決的辦法,就是利用 Arduino 讀取接收器的訊號後,做一些整合式的處理(註1),然後再下指令給馬達驅動模組或其它周邊模組作動。

註1:此處所謂的整合式處理,是指把一個以上的訊號指定為一組指令。例如我們想用一只搖桿(有2個頻道的訊號)控制麥克納姆輪車(4個馬達)的行進方向。

本章僅在說明如何解譯搖控接收器的訊號,如何將訊號作整合式應用會另篇說明。


電路接線

Arduino       R/C Recever
5V               VCC
GND           GND
D2               Channel 1




程式

#define THROTTLE_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
#define THROTTLE_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead

#define NEUTRAL_THROTTLE 1500 // this is the duration in microseconds of neutral throttle on an electric RC Car

volatile int nThrottleIn = NEUTRAL_THROTTLE; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
volatile unsigned long ulStartPeriod = 0; // set in the interrupt
volatile boolean bNewThrottleSignal = false; // set in the interrupt and read in the loop
// we could use nThrottleIn = 0 in loop instead of a separate variable, but using bNewThrottleSignal to indicate we have a new signal
// is clearer for this first example

void setup()
{
  // tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 2) changes from HIGH to LOW or LOW to HIGH
  // catching these changes will allow us to calculate how long the input pulse is
  attachInterrupt(THROTTLE_SIGNAL_IN,calcInput,CHANGE);

  Serial.begin(9600);
}

void loop()
{
 // if a new throttle signal has been measured, lets print the value to serial, if not our code could carry on with some other processing
 if(bNewThrottleSignal)
 {

   Serial.println(nThrottleIn); 

   // set this back to false when we have finished
   // with nThrottleIn, while true, calcInput will not update
   // nThrottleIn
   bNewThrottleSignal = false;
 }

 // other processing ...
}

void calcInput()
{
  // if the pin is high, its the start of an interrupt
  if(digitalRead(THROTTLE_SIGNAL_IN_PIN) == HIGH)
  {
    // get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its
    // easy to understand and works very well
    ulStartPeriod = micros();
  }
  else
  {
    // if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the
    // start time ulStartPeriod from the current time returned by micros()
    if(ulStartPeriod && (bNewThrottleSignal == false))
    {
      nThrottleIn = (int)(micros() - ulStartPeriod);
      ulStartPeriod = 0;

      // tell loop we have a new signal on the throttle channel
      // we will not update nThrottleIn until loop sets
      // bNewThrottleSignal back to false
      bNewThrottleSignal = true;
    }
  }
}


觀察訊號數據

Step1 打開 Serial Monitor,並將鮑率調到 9600。

Step2 輕輕搖動遙控器上面的搖桿,觀察 Selial Monitor 內的數值(註2)。置中時約為 1500,側邊時約為 1250 和 1750。

註2:如果搖桿置中時數值不為 1500,您可以使用遙控器上面的微調按鍵將它調整到接近 1500。



參考網頁

Instructables https://www.instructables.com/id/Rc-Controller-for-Better-Control-Over-Arduino-Proj/














2020年1月28日 星期二

[RF] nRF24L01 2.4GHz 無線通訊(二) -- 加入兩個雙軸按鍵搖桿

本文旨在說明於 nRF24L01 的發射端加入兩個雙軸按鍵搖桿。我想使用左搖桿來控制水彈槍的 2 個伺服馬達和 1 個發射按鈕,使用右搖桿來控制小車的 4 個麥克納姆輪。



如果您還不熟悉 nRF24L01 模組基本的收發運作,請詳

[RF] nRF24L01 2.4GHz 無線通訊(一) -- 基本發射與接收



電路接線

發射端電路接線:

Arduino     nRF24L01    左搖桿     右搖桿
5V                                   5V            5V
3.3V           VCC
GND          GND            GND        GND
A0(註1)                          VRY     
A1(註1)                          VRX
A2(註1)                                           VRY
A3(註1)                                           VRX
D0                                   SW
D1                                                    SW
D7              CE
D8              CSN
D11            MOSI
D12            MISO
D13            SCK
(不接)        IRQ

註1:由於雙軸按鍵搖桿擺放的方式不同,會影響X軸與Y軸的配置,因此此處的腳位您需要配合自己的需求來調整。



接收端電路接線:

Arduino     nRF24L01
3.3V           VCC
GND          GND
D7              CE
D8              CSN
D11            MOSI
D12            MISO
D13            SCK
(不接)        IRQ



程式

發射端程式:

//RF_Transmitter01.ino
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>

// Define the digital inputs
#define jB1 0  // Joystick button 1
#define jB2 1  // Joystick button 2

unsigned long currentTime, previousTime;
unsigned long elapsedTime = 100;

RF24 radio(7, 8);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001"; // Address

// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
};

Data_Package data; //Create a variable with the above structure

void setup() {
  Serial.begin(9600);

  // Define the radio communication
  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);

  // Activate the Arduino internal pull-up resistors
  pinMode(jB1, INPUT_PULLUP);
  pinMode(jB2, INPUT_PULLUP);
 
  // Set initial default values
  data.j1PotX = 127; // Values from 0 to 255. When Joystick is in resting position, the value is in the middle, or 127. We actually map the pot value from 0 to 1023 to 0 to 255 because that's one BYTE value
  data.j1PotY = 127;
  data.j2PotX = 127;
  data.j2PotY = 127;
  data.j1Button = 1;
  data.j2Button = 1;

  previousTime = currentTime;
}

void loop() {
  // Read all analog inputs and map them to one Byte value
  data.j1PotX = map(analogRead(A1), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
  data.j1PotY = map(analogRead(A0), 0, 1023, 0, 255);
  data.j2PotX = map(analogRead(A3), 0, 1023, 0, 255);
  data.j2PotY = map(analogRead(A2), 0, 1023, 0, 255);

  // Read all digital inputs
  data.j1Button = digitalRead(jB1);
  data.j2Button = digitalRead(jB2);

  // Send the whole data from the structure to the receiver
  currentTime = millis();
  if (currentTime - previousTime > elapsedTime) {
    radio.write(&data, sizeof(Data_Package));
    previousTime = currentTime;
  }
}


接收端程式:

//RF_Receiver01.ino
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long previousTime = 0;
unsigned long currentTime = 0;
unsigned long elapsedTime = 100;

// Max size of this struct is 32 bytes
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
};

Data_Package data; //Create a variable with the above structure

int  PotX1, PotY1, PotX2, PotY2;
byte But1, But2;

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver
  resetData();
}

void loop() {
   // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package));

    PotX1 = data.j1PotX;
    PotY1 = data.j1PotY;
    But1 = data.j1Button;
    PotX2 = data.j2PotX;
    PotY2 = data.j2PotY; 
    But2 = data.j2Button; 
 
    Serial.print(PotX1); Serial.print(" ");
    Serial.print(PotY1); Serial.print(" ");
    Serial.print(But1);  Serial.print(" ");
    Serial.print(PotX2); Serial.print(" ");
    Serial.print(PotY2); Serial.print(" ");
    Serial.println(But2); 
  }
}

void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  data.j1PotY = 127;
  data.j2PotX = 127;
  data.j2PotY = 127;
  data.j1Button = 1;
  data.j2Button = 1; 
}

在上傳發射端和接收端的程式之後,您可以打開接收端的 Serial Monitor(註2),您就可以看到如下圖所示。

註2:在打開 Serial Monitor 之前,或許您需要讓接收端成為目前的 COM Port。


理想中雙軸按鍵搖桿在置中時(不搖動它)所呈現的數值應該是 127,但由上圖我們可以觀察到它並非是這個值。雖然如此,它對於我們在控制伺服馬達和麥克納姆輪上面的影響似乎不大。

您可以搖動搖桿或按下搖桿上的按鍵,觀察 Serial Monitor 上的數值是否符合您的期望,如果不是,您可能要稍微調整一下電路接線(註1)。


相關網頁

https://lastminuteengineers.com/nrf24l01-arduino-wireless-communication/
https://howtomechatronics.com/projects/diy-arduino-rc-transmitter/


採購資訊

1100M nRF24L01+PA+LNA無線模組 https://goods.ruten.com.tw/item/show?21934545524992

雙軸按鍵搖桿 https://goods.ruten.com.tw/item/show?21628077440247

多功能雙軸按鍵搖桿固定板 https://goods.ruten.com.tw/item/show?21805664364959