2024年1月17日 星期三

[Arduino] Arduino 開發板 Upload 問題的排除

有不少初學者因為不熟悉 Arduino 相關開發板,在 Upload 程式時出現許多問題,本文旨在提供一般的問題排除方案。


1. 有選對正確的 USB 傳輸線嗎?

玩家希望將程式由電腦 Upload 到開發板,需要有一條可以傳輸數據的 USB 線。

有些 USB 線只有提供電源的功能,並不具備能傳輸資料,您需要先確認您的 USB 線是可以傳輸資料的。


2. 請確認 USB 線的品質是否合乎開發板的需求?

有些開發板(例如 ESP32 ...)功能較多,他們可能需要同時作動 Wifi 和 BLE 功能,因此需要較穩定的電壓以及較大的電流。

有些品質不好的 USB 線無法提供較大的電流,或是沒有屏蔽電磁波功能,因此建議您選擇一條品質較好的 USB 線,如此對您在使用開發板方面是有幫助的。

另外,過長的 USB 線也會影響到開發板的使用,因為電線的電阻比較大會使電壓和電流降低,讓傳輸數據時產生不穩定的現象。


3. 請確認是否已使用 USB 線正確連接開發板和電腦?

有些開發板(例如 ESP32-S3)具有 2 個 USB 連接頭,其中一個是作為供電使用,並不具有傳輸資料的功能。


4. 是否已經安裝正確的 USB 驅動程式?

目前市面上最常見的有 CH340、CP2102、CH9102...這幾種 USB2TTL 晶片,請先確認您的開發板上的 USB2TTL 晶片是哪一款,並安裝正確的驅動程式。

如果已經安裝 USB 驅動程式,請用 USB 線連接開發板和電腦,並打開電腦的「裝置管理員」,查看是否有出現類似下面的連接埠畫面(您的連接埠可能跟我們的不一樣)。



值得一提的是,目前 CH34x 系列的晶片有許多款,例如 CH340E、CH340G、CH340T...,而他們也都已被使用在市面上各類的開發板上面。

在實務上,我們有遇到下列情況,已經安裝 CH340 驅動程式,也使用 USB 線正確連接 ESP32-CAM 開發板和電腦,Arduino IDE 裡的開發板型號和連接埠也選了,看似一切都沒問題,可是在 Upload 時卻發生錯誤。

經過反覆測試,最終發現是 CH340 驅動版本的問題,我們當時是重新安裝 CH341SER 這支驅動才解決了這個問題。


5. 是否已選擇正確的開發板型號和序列埠?

如果玩家不知道您的開發板該選擇哪一個型號,可以詢問您的賣家。

以 Arduinp Nano 開發板為例,開發板型號應該選擇「Arduino Nano」。

這裡要注意的是市售的 Arduino Nano 開發板處理器安裝有兩款 Bootloader,一款是 ATmega328P,另一款是 ATmega328P (Old Bootloader),您可以先試試選用 ATmega328P,如果 Upload 有錯誤時,可以再選擇 ATmega328P (Old Bootloader),如下圖所示。


還要提醒您的是,新版的 Arduino IDE 裡,或是其他開發平台,其處理器的選項並不明顯,如果您沒有辦法找到「處理器」這個選項,建議您使用 Arduino IDE version 1.8.19。

最後,則是需要選擇正確的序列埠。



2023年10月7日 星期六

[小車底盤] 58mm 麥克納姆輪小車底盤組裝

      這是一款直徑 58mm 的麥克納姆輪小車底盤,翠綠的麥輪讓人有一種跑車的感覺,是一款 CP 值蠻高的小車底盤套件。


組裝工具

1. M3 十字螺絲起子。

2. M3 扳手。

3. 尖嘴鉗。


組裝步驟

雖然本組裝說明的馬達並未焊上電源線,但我們強烈建議您在組裝前先焊好馬達電線。

Step1 取出材料包。



Step2 取出壓克力底板、馬達、馬達固定片、螺絲和螺帽。




將馬達固定到底板上,


總共需固定 4 組。


建議您:馬達電源銅片的方向最好是朝車體內部,請仔細觀察上圖。


Step3 取出麥輪、聯軸器和 細螺絲。


將聯軸器套入馬達軸,再將麥輪套入聯軸器。


最後插入細螺絲將麥輪鎖緊到馬達軸。



Step4 總共需固定 4 組。


提醒您:請注意麥輪的方向,如果方向錯誤車子就會不聽使喚亂跑。

下圖是俯瞰視角。


下圖是右側視角。


此小車底板是市售通用型壓克力底板,一般來說上面的空間已經足夠讓您放置開發板、傳感器和電池等裝置,但是如果還是不敷使用,您可以在上方再加上數片層板。


採購資訊

露天(S&R) 

露天(RWG)

蝦皮








2023年7月6日 星期四

[小車底盤] 科普小車底盤

許多學校在開設自走車課程時,費用通常是首要考量,為了達到降低成本這個需求,經過我多方嘗試,這個小車底盤終於誕生了。

本科普小車所有零組件皆採用市售成品,方便玩家可以自行採購或更換零組件。例如,使用一塊科普常見的洞洞板當作車子底板,3*75*90mm 的尺寸大小,足夠裝載 Arduino 或 ESP系列開發板和其他模組。



工具

1. M2十字螺絲起子
2. M2扳手


組裝步驟

強烈建議在組裝前先焊好馬達電源線。

Step1 取出螺絲2只、墊片4只、尼龍柱2支和滾珠輪,預組備用。


組裝後如下圖



Step2 取出 Step1 之預組件和小車底板,用螺絲2只固定。





Step3 取出螺絲8只、螺帽8只和固定器2只,將2只TT馬達分別固定到底板上。


固定後如下圖



Step4 取出輪框和胎皮,將胎皮安裝到輪框。


Step5 使用2只自攻螺絲將輪胎固定到馬達上。到此組裝完成。


這俯視視角


這是另一個角度



其它注意事項

1. 如果您覺得感測器、模組數量太多,單層底板空間不敷使用,可以加購底板和4只M2尼龍柱,這樣就有足夠的空間使用。

2. 底板的孔洞是間距10mm,孔徑是2mm,非常適合通用型科普塑料拼裝組合。


採購資訊

露天(S&R) https://www.ruten.com.tw/item/show?22327145934079

露天(RWG) https://www.ruten.com.tw/item/show?22327145963598

蝦皮 https://shopee.tw/-RWG-Arduino-%E8%87%AA%E8%B5%B0%E8%BB%8A-%E5%BE%AA%E8%B7%A1%E8%BB%8A-%E9%81%BF%E9%9A%9C%E8%BB%8A-%E5%B0%8F%E8%BB%8A%E5%BA%95%E7%9B%A4-i.14363185.20890490383?sp_atk=12d33500-bdb4-4e62-b146-31be61f188cd&xptdk=12d33500-bdb4-4e62-b146-31be61f188cd








2023年6月17日 星期六

[全向輪] Omni 全向輪小車底盤組裝說明

這款全向輪小車底盤是「給氣狼機器人聯盟」設計的,車體底盤採用 3mm 黑色壓克力,外觀質感佳。

本小車底盤採多功能目標設計,下層板可固定 3 只 TT 減速馬達或 370 減速馬達或 520 減速馬達。




準備工具

1. M2/M3 螺絲起子
2. 烙鐵和焊錫


組裝步驟

Step1



2023年5月29日 星期一

[TFT] 圓形TFT GC9A01指令摘要

本文只是作為暫時的筆記!

想了解 GC9A01 有哪些繪圖指令,可以參考 Adafruit_GC9A01A 的 graphicstest.ino 。



#include "SPI.h"

#include "Adafruit_GFX.h"
#include "Adafruit_GC9A01A.h"

#define TFT_DC 9
#define TFT_CS 10

// Hardware SPI on Feather or other boards
Adafruit_GC9A01A tft(TFT_CS, TFT_DC);

void setup() {

  tft.begin();

}


螢幕屬性

tft.width(); //取得螢幕寬度

tft.height(); //取得螢幕高度

tft.setRotation(uint8_t r); //旋轉螢幕 r=0~3


tft.invertDisplay(bool i); // 螢幕反色
tft.setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);


調色

tft.color565(i, i, i);


顏色定義


// Color definitions
#define GC9A01A_BLACK 0x0000 ///< 0, 0, 0
#define GC9A01A_NAVY 0x000F ///< 0, 0, 123
#define GC9A01A_DARKGREEN 0x03E0 ///< 0, 125, 0
#define GC9A01A_DARKCYAN 0x03EF ///< 0, 125, 123
#define GC9A01A_MAROON 0x7800 ///< 123, 0, 0
#define GC9A01A_PURPLE 0x780F ///< 123, 0, 123
#define GC9A01A_OLIVE 0x7BE0 ///< 123, 125, 0
#define GC9A01A_LIGHTGREY 0xC618 ///< 198, 195, 198
#define GC9A01A_DARKGREY 0x7BEF ///< 123, 125, 123
#define GC9A01A_BLUE 0x001F ///< 0, 0, 255
#define GC9A01A_GREEN 0x07E0 ///< 0, 255, 0
#define GC9A01A_CYAN 0x07FF ///< 0, 255, 255
#define GC9A01A_RED 0xF800 ///< 255, 0, 0
#define GC9A01A_MAGENTA 0xF81F ///< 255, 0, 255
#define GC9A01A_YELLOW 0xFFE0 ///< 255, 255, 0
#define GC9A01A_WHITE 0xFFFF ///< 255, 255, 255
#define GC9A01A_ORANGE 0xFD20 ///< 255, 165, 0
#define GC9A01A_GREENYELLOW 0xAFE5 ///< 173, 255, 41
#define GC9A01A_PINK 0xFC18 ///< 255, 130, 198

#define WHITE            0xFFFF
#define BLACK            0x0000  
#define BLUE             0x001F 
#define BRED             0XF81F
#define GRED             0XFFE0
#define GBLUE            0X07FF
#define RED              0xF800
#define MAGENTA          0xF81F
#define GREEN            0x07E0
#define CYAN             0x7FFF
#define YELLOW           0xFFE0
#define BROWN            0XBC40 //棕色
#define BRRED            0XFC07 //棕紅色
#define GRAY             0X8430 //灰色
#define DARKBLUE         0X01CF //深藍色
#define LIGHTBLUE        0X7D7C //淺藍色 
#define GRAYBLUE         0X5458 //灰藍色
#define LIGHTGREEN       0X841F //淺綠色
#define LGRAY            0XC618 //淺灰色(PANNEL),窗體背景色
#define LGRAYBLUE        0XA651 //淺灰藍色(中間層顏色)
#define LBBLUE           0X2B12 //淺棕藍色(選擇條目的反色)

螢幕填色

uint16_t color

tft.fillScreen(GC9A01A_BLACK);  yield();

tft.fillScreen(GC9A01A_WHITE);  yield();

tft.fillScreen(GC9A01A_RED);  yield();

tft.fillScreen(GC9A01A_ORANGE);  yield();

tft.fillScreen(GC9A01A_YELLOW);  yield();

tft.fillScreen(GC9A01A_GREEN);  yield();

tft.fillScreen(GC9A01A_BLUE);  yield();

tft.fillScreen(GC9A01A_CYAN);  yield();
tft.fillScreen(GC9A01A_MAGENTA);  yield();


寫字

tft.setCursor(0, 0); //指定游標位置
tft.setTextColor(GC9A01A_WHITE);  //指定字的顏色
tft.setTextSize(1);  //指定文字尺寸
tft.println("Hello World!");  //寫字
tft.println();  //換行


畫線

tft.drawLine(x1, y1, x2, y2, color);



快速畫線

tft.drawFastHLine(0, y, w, color1);
tft.drawFastVLine(x, 0, h, color2);


畫矩形

tft.drawRect(x, y, i, i, color);


畫矩形色塊

tft.fillRect(x, y, i, i, color);


畫圓

tft.drawCircle(x, y, radius, color);


畫圓形色塊

tft.fillCircle(x, y, radius, color);


畫三角形

tft.drawTriangle(
cx , cy - i, // peak
cx - i, cy + i, // bottom left
cx + i, cy + i, // bottom right
tft.color565(i, i, i));

畫三角形色塊

tft.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(0, i*10, i*10));
t += micros() - start;
tft.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
tft.color565(i*10, i*10, 0));

畫圓角矩形

tft.drawRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(i, 0, 0));


畫圓角矩形色塊

tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
yield();


#include <SPI.h>

#include "LCD_Driver.h"

#include "GUI_Paint.h"

#include "image.h"


void setup()

{

  Config_Init();

  LCD_Init();

  LCD_SetBacklight(1000);

  Paint_NewImage(LCD_WIDTH, LCD_HEIGHT, 0, BLACK);

  Paint_Clear(BLACK);

  Paint_DrawCircle(120,120, 120, BLUE ,DOT_PIXEL_2X2,DRAW_FILL_EMPTY);

  Paint_DrawLine  (120, 0, 120, 12,GREEN ,DOT_PIXEL_4X4,LINE_STYLE_SOLID);

  Paint_DrawLine  (120, 228, 120, 240,GREEN ,DOT_PIXEL_4X4,LINE_STYLE_SOLID);

  Paint_DrawLine  (0, 120, 12, 120,GREEN ,DOT_PIXEL_4X4,LINE_STYLE_SOLID);

  Paint_DrawLine  (228, 120, 240, 120,GREEN ,DOT_PIXEL_4X4,LINE_STYLE_SOLID);

  Paint_DrawImage(gImage_70X70, 85, 25, 70, 70); 

  Paint_DrawString_CN(56,140, "微雪电子",   &Font24CN,BLACK,  WHITE);

  Paint_DrawString_EN(123, 123, "WAVESHARE",&Font16,  BLACK, GREEN);

  Paint_DrawLine  (120, 120, 70, 70,YELLOW ,DOT_PIXEL_3X3,LINE_STYLE_SOLID);

  Paint_DrawLine  (120, 120, 176, 64,BLUE ,DOT_PIXEL_3X3,LINE_STYLE_SOLID);

  Paint_DrawLine  (120, 120, 120, 210,RED ,DOT_PIXEL_2X2,LINE_STYLE_SOLID); 

}

void loop()

{

  

}




/*********************************************************************************************************

  END FILE

*********************************************************************************************************/


Overlay parameters

The overlay support some optional parameters that allow changes in the default behavior and affects only the LCD display. They are key=value pairs, comma separated in no predefined order, as follow:

dtoverlay=gc9a01,speed=40000000,rotate=0,width=240,height=240,fps=50,debug=0
  • speed: max spi frequency to be used
  • rotate: image rotation (in degrees: 0, 90, 180, 270)
  • width: width of the display
  • height: height of the display
  • fps: max fps to be used
  • debug: debug level to be logged on boot process

Additional image orientation and resolution

Since fbcp is making a plain copy from HDMI to LCD, screen resolution may affect the final result. Additional settings can be added on the config.txt in order to adjust the resulting image to your needs. The full set of options can be checked at /boot/overlays/README.

Note that the following settings will be applied both to the HDMI and the LCD.

dtoverlay=gc9a01
hdmi_force_hotplug=1
hdmi_cvt=240 240 60 1 0 0 0
hdmi_group=2
hdmi_mode=87
hdmi_drive=2
display_rotate=2
  • hdmi_force_hotplug: force HDMI output rather than DVI
  • hdmi_cvt: adjusts de resolution, framerate and more. Format: <width> <height> <framerate> <aspect> <margins> <interlace>
  • hdmi_group: set DMT group (Display Monitor Timings: the standard typically used by monitors)
  • hdmi_mode: set DMT mode
  • hdmi_drive: force a HDMI mode rather than DVI
  • display_rotate: rotate screen 180 degrees

The display_rotate setting allows to rotate or flip the screen orientation to fit your needs. The default value is 0, possible values are:

  • 0 no rotation
  • 1 rotate 90 degrees clockwise
  • 2 rotate 180 degrees clockwise
  • 3 rotate 270 degrees clockwise
  • 0x10000 horizontal flip
  • 0x20000 vertical flip

This setting is a bitmask. So you can both flip and rotate the display at the same time. Example:

  • 0x10001 both do a horizontal flip and rotate 90 degrees clockwise (0x10000 + 1).
  • 0x20003 both do a vertical flip and rotate 270 degrees clockwise (0x20000 + 3).