2007年4月30日 星期一

Amigo 03 and AmigoCOM


我把 AmigoCOM 稍為修改了一下,變成一個非常簡單的馬達控制工具。AmigoCOM General 可以控制十六個馬達,基本上由我所製作的機體都支援這個版本的 AmigoCOM。雖然現在能控制到馬達的動作,但某些馬達的活動範圍只有九十度,還有需要研究及除錯的地方。

另外,今天向 Victor 請教了關於馬達跟鋰電的問題。由於 S3003 的電壓範圍是 4V~6V,但鋰電是 7.4V,多出了 1.4V。按 Victor 所說是會影響馬達的性能,甚至會燒掉,所以建議加入電壓控制線路。我也正在參考日本方面的設計,他們看來沒有使用這樣的線路。

2007年4月29日 星期日

Amigo 03 Test


今天為 Amigo 03 製作了新主板。主板非常簡單,只有 ATmega-128、八個 PWM 輸出口、12A 烏絲。經過多次檢查後,我先用兩組充電電池作測試,程式則是之前做出來的 0-180 度正轉及反轉循環。基本上測試成功,只是當中有三個馬達沒有動起來,經查證後,發現原來是接線錯誤。之後,便用上鋰電來推動馬達,發覺力量是大很多!可能是 4.8v 及 7.4v 的差別吧。不過,在接上鋰電時發現不解的事情,當鋰電接上馬達,而 ATmega-128 卻沒有接電時,ATmega-128 竟然亮起燈來了,不過就沒有產生 PWM,亦即是就 ATmega-128 應該沒有運行起來。

2007年4月28日 星期六

PlayStation 插頭入手

放工後,我到了黃金商場,花了 $29 購買了一條 PlayStation 轉 USB 線。在包裝盒上標明是在 Windows 內使用,但老闆聲稱除了在 Windows 上使用之外,也可以在 PS3 上使用。我購買這條線的原因是取其 PlayStation 手掣的插頭,用在機體上作為輸入裝置的接口。既然老闆這樣說,回到家後,我當然立即試試!在 Windows 上沒有問題,所有按鍵都能檢測得到。然後試了 PS3 也沒有問題!我順便也試了在接口上接上 PS2 的一出四分插,結果是分插只能插一個手掣...v_v
如果一出四是行得通的話,那我就可以剪掉 USB 線的其中一個插口並拿給機體用,可是我又有一點捨不得,不竟現在可以在 PS3 上實現三人對戰...,唯有再買多一條線回來吧。
之後,我到了華輝購買了一些部件,當中有 32.768kHz 的晶振,只賣 $3。這顆晶振主要是給 NEC V750 之用。順帶一提,前幾天我在網上終於找到了 V850 Flash 的重寫次數。竟然跟 CQ7144A 一樣,只有 100 次!我又要再一次節檢地編程了~

2007年4月27日 星期五

Alibre Design Xpress

發現了一個很不錯的 3D 繪圖軟件,而且還是免費的!它叫 Alibre Design Xpress,可以在 http://www.alibre.com/xpress/software/alibre-design-xpress.asp 下載。

2007年4月26日 星期四

鋰電入手

晚上的時候,R大人為我送來了三排鋰電、二個之前交給 Dr.Victor 修理的火牛、一個差電器。鋰電是 2 Cell 7.4V 1200mAh,價值 HK$80;而差電器也是價值 HK$80,實在很便宜。
現在有三排鋰電在手,便可以著手調校 Amigo-03 的動作,以及編寫相應程序。過去兩天本來打算把我的遙控直昇機的發射與接收器拆出來給機體之用,但最後都因為不捨得(性能良好,還可以飛)而沒有這樣做。看來星期六都要到黃金商場一轉,購買那昂貴的無線 PS2 手掣!沒錯,是無線 PS2 手掣!我打算利用它來操控機體。因為這個對我來說是最有把握製作,以及最方便的控制方法。

2007年4月24日 星期二

在鋰電還未到手之前,唯有先研究購買已久的兩個檢測器:Sharp GP2D12 PSD 素子距離檢測器、ACA302 三軸加速度檢測器。今次的開發比想像中容易,只是在程式中增加了「類比轉數碼」部份就可以了。

從相片中可以看出從兩個檢測器讀取的數值。基本上 ACA302 的數值範圍是 0-130 左右;而 GP2D12 的數值範圍是 0-650 左右。

現在,手頭上可以測試的東西都已經做過了,希望能快點把鋰電拿到手!在這之前,相信我會向同事請教關於超聲波檢測器的控制方法。

2007年4月23日 星期一

Interface 2007 年 5 月號(二)

今日去了數碼港開會途經了銅鑼灣,於是便到崇光的旭屋書店訂購 Interface 五月號。職員說大約兩三個星期便會運到,真的很期待!今次的折算一本大約為 HK$176 連運費,雖然每本比日本本土買貴了 HK$60,但也沒有辦法,最多都是下次去智源訂購。雖然便宜一點,但服務及時間就差一點了。

2007年4月22日 星期日

ATmega-128 的 16-Channels PWM 輸出(五)


今日我懷著滿腔熱誠去智源,打算訂購 Interface 五月號,可惜白行了一趟...,原來智源是逢星期日休息!激死!唯有明天順道到旭屋訂購!智源今次走寶,我可是訂購很多本的,呵呵~

今天R大人跟我提過有同好能利用 8051 作為馬達控制器,而 PWM 的輸出解像度為 200,亦即是說每一步少於一度!可是我找了很久也找不到這個消息的來源。

回到家,我把期待已久的設計實現出來。整個過程沒有甚麼困難,編程時也很順暢,到執行時亦達到預期的目標。在數值上,我只把 PWM 的輸出解像度提升四倍,原因是提升八倍的話,ATmega-128 便沒有時間處理其他工作,如:檢測器、邏輯...等等。出來的結果是解像度從原來的 29 個習次,提升到 90 個層次,亦即是說每加一步,角度便增加二度。這個數值已經是不錯的水平。不過,仍會看看有沒有能改進的空間。好,現在就講解「四倍提升術」的秘密吧!

這個技術的要點是每次的處理數量!在上一個版本的程式中,中斷是每 20ms 發生一次;而每次就處理十六個 PWM 訊號,迴圈共 34 次。這項工作對 ATmega-128 來說是有點吃力,使得結果出來是一步 6.2 度。基於以上原因,我把過往的設計合併,變成中斷每 5ms 發生一次;而每次就只處理四個 PWM 訊號。於是乎,在 20ms 裡使能完成 4x4 共十六個 PWM 訊號輸出!就算迴圈也是 34 次,但由於由十六個訊號減為四個,速度就會因此而提升。當然,同樣地循環 34 次是會令 PWM 訊號的時間改變,所以我也要相應地作出改變,最終數值是 60 至 149。現在,解像度便提升至一步增加二度!

由於 Amigo Striker 的程式也是同 ATmega-128 的上一個版本相同,所以,要是把這個技術也套用到 CQ7144A 上,相信速度也會有明顯的改進!至少是三倍吧!呵呵~

ATmega-128 的 16-Channels PWM 輸出(四)

關於現時程式的設計,PWM 的輸出解像度達 6.2 度之多,實在是很難接受!但皇天真是不負有心人,我想出了一個能大大改善的方法。這個設計應該可以提升八倍之多,真想快點編程試試!不過,現在要到尖沙咀訂購 Interface 五月號,唯有今晚才把設計實現!

Interface 2007 年 5 月號

好消息!Interface 五月號又有主板附送!我不會像上年一樣只買兩本,令到自己後侮!今次我要買多幾本!
隨五月號附送的基板是 NEC V850,是一顆 32-bits RISC 20MHz MCU,內含 256KB Flash ROM 及 24KB SRAM;而且還有 CP2102 USB 轉 RS232 介面(需另購插頭)。看來很吸引!雜誌售價是 1680yen,大概是 HK$114 一本,但如果去智源或旭屋買,就要成 HK$170 本...。
 
參考(4 月 6 日)

PSD 素子測距 Sensor (GP2D12)

在鋰電還沒有買到的時候,那就先研究一下手上的各個檢測器。我選擇了 Sharp 的 PSD 素子測距 Sensor (GP2D12)。

由於我沒有關於它的文獻,於是在網上找了它的規格書,然後做了個簡單的測試。發現它會不停發出固定而細小的訊號,而當有物件突然接近時,便會產生一個很強大的訊號。我也試過把物件慢慢地接近它時,訊號反而沒有改變。但是,PSD Sensor 是能檢測出自身與物體間之距離,所以,還是要詳細看清楚規格書的內容。


購買的地方
http://robot.tsukumo.co.jp/goods/2340102865984/702020000000000

連接方法參考
http://lets-robot.com/modules/bluesbb/thread.php?thr=37&sty=1&num=l50

2007年4月21日 星期六

ATmega-128 的 16-Channels PWM 輸出(三)

問題終於解決了!原來又是自己一時大意...。在程式中,我設定 PWM 的範圍是從 21 到 34,亦即是 1543us 到 2272us。問題就是 21 這個數值是等如移動到中間位置,難怪移到一半便回轉...。把 21 改為 6 之後,便完全正常了!哈哈!

不過,由 6 到 34 當中只有 29 個層次,以 180/29 來計算,數值加一便會增加 6.2 度,是一個很大的數值。按R大人所說,這樣大的數值是很難做出順暢的動作,甚至有些高難度的動作也做不來...。看來又要想想辦法了...。

ATmega-128 的 16-Channels PWM 輸出(二)


新增了 delay 部份後,情況得以改善。下一步便是鋰電了!要找 Dr.Victor 老師幫忙!

以下是我的原碼:

//=============================================//
// Robot Amigo Main Program - Ver.2.00 //
// Copyright Pacess HO, 2007. //
// File : Amigo.c //
// Platform : ATmega-128 (BestTechnology) //
// Last update : 21-April-2007 //
//=============================================//

// History:
// 1.00 - Control 4 servos at the same time
// 1.10 - Fix counter bug on 1.00
// - Can control 4 servos now
// - Use PB as LED output ports
// 1.20 - Try to control 8 servos at the same time by setting TIMER-1 from 5ms to 2.5ms
// 2.00 - Use new technology to control over 8 servos at the same time

// PULSE SIGNAL:
// __
// | | Pulse width = 0.6ms = Left most
// __| |_____...
// ___
// | | Pulse width = 1.5ms = Center
// __| |____...
// ____
// | | Pulse width = 2.4ms = Right most
// __| |___...

// TIMER 0: Signal pulse width control
// __
// | |
// ___| |____________...

// TIMER 1: Generate a signal every 5ms (4 signals within 20ms)
// __ __ __
// | | | | | |
// ___| |__| |__| |__...

// TIMER 2: Use for time counter
// /| /| /| /|
// / | / | / | / |
// / |/ |/ |/ |....

#include < avr/io.h >
#include < avr/interrupt.h >
#include < rs.h >

#define SERVO_MAX 16

//====================//
// Global variables //
//====================//
char pTransfer[10], pReceive[10]; // RS-232 data buffers

// From real measurement:
// Value 20 = 1481us
// Value 21 = 1543us
// Value 34 = 2272us
char g_pServoData[16] = { // Current position of servos
35, 34, 34, 33, 21, 21, 20, 21, // Value from 8.2 -> 20.5 -> 32.8
35, 34, 34, 33, 21, 21, 20, 21};
char g_pServoLast[16] = { // Last position of servos
35, 34, 34, 33, 21, 21, 20, 21, // Value from 8.2 -> 20.5 -> 32.8
35, 34, 34, 33, 21, 21, 20, 21};
char g_pServoNext[16] = { // Next position of servos
1, 1, 1, 1, 1, 1, 1, 1, // Value from 8.2 -> 20.5 -> 32.8
1, 1, 1, 1, 1, 1, 1, 1};
unsigned char g_iCurrentStep, g_iTotalStep;
int iLED = 0;

//=============================================================================
// Servo pulse output
//=============================================================================
void ServoOut(unsigned char *pServoData, int iLoop) {
unsigned int iPortData;
int iChannel;

// The following while loop takes 73us for 1 loop when SERVO_MAX = 16 //
while (iLoop > 0) {
iPortData = 0;
for (iChannel=0; iChannel < SERVO_MAX; iChannel++) {

// Set bit on/off of each channel //
iPortData = ((iPortData<<1) | (pServoData[iChannel] >= iLoop));
}

// Output to PA0~PA7 and PC0~PC7 //
PORTA = (unsigned char)(iPortData&0xff);
PORTC = (unsigned char)((iPortData>>8)&0xff);

iLoop--;
}

// Set PA0~PA7 and PC0~PC7 to LOW(0) //
PORTA = 0x00;
PORTC = 0x00;
}

//==================================//
// Wait for specified mini second //
//==================================//
void wait_ms(int iMSecond) {
int iCount;

TCCR2 |= ((1 << CS21)|(1 << CS20)); // Counter 2 / 64 section

for (iCount=0; iCount < iMSecond; iCount++) {
TCNT2 = 0x00; // Clear counter 2
while (TCNT2 < 250); // Wait for 1 mini second
}
}

//======================================//
// Counter 1 (8-bits) match interrupt //
//======================================//
SIGNAL(SIG_OUTPUT_COMPARE1A) {
// From real measurement:
// Loop 10 = 730us, thus loop 35 = 2555us = 2.555ms
// Loop 35 = 2760us
TCNT1 = 0x00; // Clear counter 1
ServoOut(g_pServoData, 30);
}

//=============================================================================
// Update servos position
//=============================================================================
void UpdateAllServo(void) {
char i;

for (i=0; i < SERVO_MAX; i++) {
g_pServoData[i] += g_pServoNext[i];
if (g_pServoData[i] == 21) {g_pServoNext[i] = 1;}
if (g_pServoData[i] == 34) {g_pServoNext[i] = -1;}
}
}

//=====================//
// Main program flow //
//=====================//
void main(void) {
int iLED, iCount, i;

//--------------------------//
// Init. system variables //
//--------------------------//
g_iTotalStep = 13;
g_iCurrentStep = g_iTotalStep;

// Set PA0~PA7 and PC0~PC7 as OUTPUT port //
DDRA = 0xff;
DDRC = 0xff;

// Set PA0~PA7 and PC0~PC7 to LOW(0) //
PORTA = 0x00;
PORTC = 0x00;

// Set PB0~7 LED as OUTPUT port //
DDRB = 0xff;
PORTB = 0x00;

// Counter 1 setup //
TIMSK |= (1 << OCIE1A); // Enable compare A interrupt
TCCR1A |= (1 << WGM12); // Set counter 1 to CTC mode
OCR1A = 40000; // 40000 / 8 section = 20ms

// Initialize COM port and baud rate 115200 bps //
rs0_init(br115200, pTransfer, sizeof(pTransfer), pReceive, sizeof(pReceive));
fdevopen(rs0_putchar, rs0_getchar);

// Enable interrupt //
SREG |= (1 << SREG_I);
TCCR1B |= (1 << CS11);

// Display connecting message //
rs0_puts("========================================\n");
rs0_puts("== AMIGO-003 Ver 2.00.070421-67 ==\n");
rs0_puts("== Copyrights Pacess HO, 2006-2007. ==\n");
rs0_puts("========================================\n\n");

iLED = (0-1);
while(1) {
// Set PB0~7 LED on and off //
iLED = (iLED+1)&7;
PORTB = ~(1 << iLED);

// Update position of all servos //
UpdateAllServo();

for (iCount=0; iCount < 1000; iCount++) {
for (i=0; i < 100; i++) {
PORTB = PORTB;
}
}
}
}

ATmega-128 的 16-Channels PWM 輸出


今天我終於完成一直以來的短期目標,把 ATmega-128 的程式改為支援 16-Channels!現在透過 PORTA 及 PORTC 把訊號輸出。雖然程式能輸出正常的 PWM,但現時訊號改變得很快,導致馬達只能做出抽搐的動作。下一步便是把這個錯誤更正!

2007年4月20日 星期五

烏龍訊號

經歷過幾次的失敗後,我終於把以前利用兩個計時器控制八個馬達的程式下載到 ATmega-128。然後用示波器量度一下訊號輸出,竟發現綠色訊號的電壓下降至 2.4V,而且訊號也不正確...。檢查過後,才發現原來自己的接線不是順序的,因此綠色的訊號是其他沒有處理的接線,嚇了我一跳~ :P

2007年4月19日 星期四

Soundcard Oszilloscope

今日試了第二個音效卡示波器工具。這個工具的外觀比較好,而且也很易用。它那個量度電壓及時間的功能也很好,十分像一個真正的示波器!

最近在研究示波器的時候,發現原來有人把 Gameboy Pocket 改裝成手提示波器,而且功能可以媲美真正的示波器,甚至更好!加上它的價錢便宜,又有強勁的可攜性,真想買一個回來!

2007年4月17日 星期二

方波輸出

晚上在測試 ATmega-128 時,本來想試試雙頻輸入的,可是始終也做不出來,但卻無意中做出了方波的設定來!

自製示波器(二)

由於昨天造的示波器線路不太理想,容易導致短路,所以我搜集了一些零件,製作多一個示波器。
上星期六,我買了 NDSL 回來,當中的 R4 卡附帶的卡盒十分精美,而且全是塑膠製成,很適合作為新示波器線路之用!現在的成品十分美觀,而且又沒有電線外露,是一件很滿意的作品。

奇怪的訊號

今天,我把程式修改了一下,將 ServoOut 放到 Main 函,目的是要量度輸出的訊號,以及觀看經由 RS232 傳回的除錯資料。
資料顯示 ServoOut 得出的數值十分正確,可是當我量度輸出腳時,訊號卻是十分奇怪...。

2007年4月16日 星期一

自製示波器

今天,我按照 irobot 提供的示波器線路把它造了出來。我家裡沒有 20K Ohm 的電阻,於是便利用兩個 10K Ohm 串聯起來。在電腦上利用 Visual Analyser 9.0 來測試,結果成功能顯示出訊號!雖然訊號不是完全正確,但至少能看到訊號的大概。希望這個工具能對日後的機體開發有幫助啦。

2007年4月15日 星期日

USB -> RS232 線

昨天放工後,我到了黃金商場買了一台 NDSL,也順道買了一條價值 $45 的 USB -> RS232 線。記得 Victor 曾經跟我說過,USB -> RS232 是可行的,但一定需要使用附送的驅動程式。我試過在我的 Fujitsu 手提電腦上使用,完全沒有問題。

由於我在公司是使用 DELL 手提電腦的,這樣,就可以方便我日後修改及下載程序到 MCU 了。

2007年4月14日 星期六

ATmega-128 Pulse V...

兩日來,我都測試不到 ATmega 輸出的訊號,原因可能是程式跑得快,所以無法量度出所花的時間。
今天,我便改為量度輸出口的訊號。我在程式中硬性設定了兩隻腳輸出高位,然後利用一個 for loop 去做二十次,然後把其中一隻腳設定為低位,再重複 for loop。得出來的結果是 46us 及 23us,意味著 for loop 二十次大約花掉 23us。
測驗了這麼久都沒有甚麼改進,看來我還是用回之前的設計好了,反正 Amigo 03 剛剛好是八個馬達...。那麼,我先要買鋰電回來!

2007年4月11日 星期三

ATmega-128 Pulse IV...

今天,我利用公司的示波器檢查 ATmega-128 的訊號,發現機乎十六隻輸出腳的訊號都是 2.760ms,超出了馬達訊號的範圍。正常來說,我是設定了三個不同的闊度...。最奇怪的是,原先迴圈十次使用了 730us 的時間出現不準確的情況。從今次迴圈三十五次所得出的 2760us,可以計出每一次迴圈會花上 78.85714us,比起之前 73us 每次多了 5us。真的不知道那個才是準確...。

2007年4月10日 星期二

ATmega-128 Pulse III...

今天吃午飯的時候,我拿出已修改好的 ATmega-128 出來,並利用示波器檢查輸出訊號的數值。出來的訊號很好,每個訊號訊號之間相距正正 20ms。這是由於使用計時器所做出來的準確數值。而訊號闊度為 730us;在程式中利用 10 個循環所做出來的,亦即是說每個循環是 73us。以正常馬達的訊號為例,從 0.6ms 到 2.4ms 的話,就等如 8.2 個循環到 32.8 個循環。數值之小意味著 Resolution 也很小,這樣所做出來的角度便不夠流暢。儘管如此,現在 ATmega-128 只用在小型機體,情況也不太嚴重。

不過,當程式下載後,馬達卻不能轉動到正常的位置...,這有待明天回公司用示波器檢查一下。

2007年4月5日 星期四

ATmega-128 Pulse II...

今天,我把 ATmega-128 程式修改了,從 LED 燈顯示,輸出的訊號比較正常了!但仍有待復活節假期後回公司利用示波器來做檢測。

2007年4月4日 星期三

2007年4月2日 星期一