2010年5月25日 星期二

新光保全機器人-馬達控制

把機構搞定了,接下來就是重點了


首先就是馬達控制,複製電腦鼠的經驗


果然還不錯


這次選的馬達扭力超強,所以,我參數亂調,好像結果都一樣


很好控


 


但有趣的地方又來了,不知道怎麼搞的,老是在1500ms 附近,右輪會產生一個很劇烈的振盪


又debug了一陣子


後來才發現,我用的encoder 接腳,剛好共接在控制板上的SPI介面的EEPROM上


可能這時候,EEPROM在送資料,QEI的資料就沒辦法送了,所以就不太正常



把EEPROM焊下來就正常了


控得很漂亮,不管加速或是減速都很NICE


當初選扭力大一點的決定是對的


和學弟討論的結果,速度和加速度就選用這組吧!


下一步,轉彎與運動控制


2010年5月24日 星期一

新光保全機器人-硬體

這次參加了新光保全機器人,剛好遇到我在玩STM32,所以就試著換換新口味吧。


這次是team work,所以很多都不是我做的,感謝在背後製作的學弟


 


和學弟討論了很久,當機器人發生問題時,一定要用硬體保護,因為開發板只有一塊,目前無力製作orz


呵呵,其實是懶得layout


這是主控板的開關,開關上都會附上保險絲。



這是整體外觀,因為比賽主題的關係,共有三層設計,基於比賽源由,不在此說明。



左邊是光藕合器,右邊是馬達驅動電路,本來是想這樣打發掉了,但學弟說配線很麻煩


orz~


只好重新設計了



為了學弟的要求,所以星期六趕工驅動板


很久沒有layout了,結果做了傻事


check 線路時,按到「x」,結果schematic沒存到檔,還好PCB的電路還在


焊接的時候,忘了這是手洗的,結果上層沒有焊,debug了一陣子,真的是老了


不過運氣不錯的是,功能正常


不然要改就很有趣了




因為主控制是開發板,所以要跳線


為了麻煩,所以重新設計一塊比較容易跳線的板子


星期日趕工


這板子很容易,超瞎,單面板就搞定了,比較適合我,簡單!


配線一團亂,和我想像的不一樣


美夢破滅


為了怕線亂跑,哈,這是???


沒錯!!!


因為線還沒整好,這個夾子方便多了!


嗯,回家時,測試正常


明天可以寫程式了~


2010年5月20日 星期四

關於程式優化的問題

這是昨天在教學弟的程式


我覺得挺有趣的


為了怕我忘了,所以記錄一下


以往我們的學習都是從範例開始


反正可以動就不管程式的寫法了


不過因為找工作的時候被電過


所以


一個好的程式設計者應該是要會試著如何把程式優化。


 


以下是幾種不同程式的寫法,一樣都是把數值轉換成ASCII code,有興趣的人,可以把程式拿回家compiler,執行看看不同的結果與差異性,這邊就不再介紹,給大家一點功課嘛


 


以下是使用MPLAB IDE,compiler 是使用 C30 V3.10


/*******************************************************************************
曾百由
dsPIC數位訊號控制器原理與應用-第一版
P12-18
宏友圖書
範例程式
*******************************************************************************/

void num2ascii (unsigned int Number,char *buff)
{
 unsigned int The_number_10000,The_number_1000,The_number_100,The_number_10,The_number ;
 char *temp = (char *)buff ;


 The_number_10000 = Number / 10000 ;
 temp[0] = The_number_10000 + 48 ;


 The_number_1000 = (Number - ( The_number_10000 * 10000 ) )/ 1000 ;
 temp[1] = The_number_1000 + 48 ;


 The_number_100 = (Number - ( The_number_10000 * 10000 + The_number_1000 * 1000 ) )/ 100 ;
 temp[2] = The_number_100 + 48 ;


 The_number_10 = (Number - ( The_number_10000 * 10000 + The_number_1000 * 1000 + The_number_100 * 100 )) / 10 ; 
 temp[3] = The_number_10 + 48 ;


 The_number = Number - ( The_number_10000 * 10000 + The_number_1000 * 1000 + The_number_100 * 100 + The_number_10 * 10 ) ;
 temp[4] = The_number + 48 ; 
}


 /*******************************************************************************
利用陣列的方式做處理
*******************************************************************************/

void num2ascii_2 (unsigned int Number,char *temp)
{
 temp[0] = (Number / 10000) + 48 ;
 temp[1] = (( Number % 10000 ) / 1000) + 48 ;
 temp[2] = (( Number % 1000 ) / 100) + 48 ;
 temp[3] = (( Number % 100 ) / 10) + 48 ;
 temp[4] = (Number % 10) + 48 ;
}
 /*******************************************************************************
利用指標的方式做處理
*******************************************************************************/

void num2ascii_3 (unsigned int Number,char *temp)
{
 *temp++ = (Number / 10000) + 48 ;
 *temp++ = (( Number % 10000 ) / 1000) + 48 ;
 *temp++ = (( Number % 1000 ) / 100) + 48 ;
 *temp++ = (( Number % 100 ) / 10) + 48 ;
 *temp   = (Number % 10) + 48 ;
}
 /*******************************************************************************
利用指標的方式做處理,並加入判斷式
*******************************************************************************/

void num2ascii_4 (unsigned int Number,char *temp)
{
 if(Number<10000) *temp++ =' ';
 else *temp++ = (Number / 10000) + 48 ;


 if(Number<1000) *temp++ =' ';
 else *temp++ = (( Number % 10000 ) / 1000) + 48 ;


 if(Number<100) *temp++ = ' ';
 else *temp++ = (( Number % 1000 ) / 100) + 48 ;


 if(Number<10)*temp++ = ' ';
 else *temp++ = (( Number % 100 ) / 10) + 48 ;


 *temp   = (Number % 10) + 48 ;
}


 /*******************************************************************************
主程式
******************************************************************************/

int main(void){
 char TXdata[6];
 unsigned int data;


 data=12345;
 num2ascii (data,TXdata);


 data=23456;
 num2ascii_2 (data,TXdata);
 
 data=34567;
 num2ascii_3 (data,TXdata);
 
 data=45678;
 num2ascii_4 (data,TXdata); 



 data=6;
 num2ascii_4 (data,TXdata); 


 return 0;
}


 


 


不知道是否還有其他更好的寫法?目前看起來num2ascii_4 這支副程式應該比較理想。


2010年5月19日 星期三

口試完了

終於口試完了


開心


果然口試的感覺就是不太一樣


還是會緊張


如果可以再熟練一點的話


應該會更好



ps:沒啥照片好挑的,學弟只幫我拍一張,太感謝他了。


2010年5月16日 星期日

指標與副程式

這是一個我以前不會的用法


如果副程式寫成


int (*ptr)(int a,int b); //ptr是一個函數


int add(int a,int b){
 return a+b;
}


int main(void){


int k1;


ptr=add;
k1=(*ptr)(2,2);
 
 }


這是副程式傳址的方式


int k1;
int *k2;
char test ;
char *test2;



int* add(int a, int b){
 k1=a+b;
 return &k1;
}


char* add2(char a, char b){
 k1=a+b;
 return (char*)&k1;
}


int main(void){


 k2=add(2,2);
 
 test2=add2(2,2);


}


 


其中


return (char*)&k1;  


我一開始的時候,我還搞不懂,這到底是什麼


&k1 是取址,而前面加了個(char *) 又是什麼


後來才知道


原來


(char*) 有點像是強制轉變數的感覺,只是轉的指標,但有趣的是,傳位置的時候,大小是不會變的


會變的是*ptr 的內容。


 


給大家做參考。


PS:書本寫的比較清楚,可以參考:蔡明志,指標的藝術,碁峰(這個字我打不出來,「山」字邊在上頭才對)。



 


列舉 enumeration

以前在學C語言的時候,一直覺得列舉(Enumration)的功能好像用不太到,而且也不常見


不過在看USB的範例程式時,真的是一個不錯的功能,假如把這功能套入電腦鼠的程式的話


那麼,程式就會變得更容易閱讀了


寫了一個簡單的程式,大至上可以這樣用


 


typedef enum _Motion_STATE
{
 right_turn=1,
 turn_back=3,
 left_turn=5,
 straight=7,
} Motion_STATE;



int k1=right_turn;



int main (void){



 while(1){
  switch (k1){
   case right_turn:
    k1=straight;
   break;
 
   case straight:
    k1=left_turn;
   break;
 
   case left_turn:
    k1=turn_back;
   break;
 
   case turn_back:
    k1=right_turn;
   break;
  }
 }



}


給大家做參考。


PS:書本寫的比較清楚,可以參考:洪錦魁,C語言密碼,文魁出版社。


2010年5月12日 星期三

幾種副程式的用法

因為有了Source Insight 的幫助,在看程式真的是快、狠、準


不過如果遇到不會的,還是無濟無事


最近在學USB,還沒學懂但已經賺到C語言的用法了


其中一個是我以前比較少用的方式,指標式的副程式(Master大大回應的很詳細)


USB裡面有幾個有趣的寫法,為了了解其運作,自己練習一般


#define  EP1_OUT_Callback   Process1
#define  EP2_OUT_Callback   Process2
#define  EP3_OUT_Callback   Process3
#define  EP4_OUT_Callback   Process4
#define  EP5_OUT_Callback   Process5
#define  EP6_OUT_Callback   Process6
#define  EP7_OUT_Callback   Process7



int k1;
void Process1(void)
{
 k1=1;
}
void Process2(void)
{
 k1=2;
}
void Process3(void)
{
 k1=3;
}
void Process4(void)
{
 k1=4;
}
void Process5(void)
{
 k1=5;
}
void Process6(void)
{
 k1=6;
}
void Process7(void)
{
 k1=7;
}


void (*pEpInt_OUT[7])(void) =
  {
    EP1_OUT_Callback,
    EP2_OUT_Callback,
    EP3_OUT_Callback,
    EP4_OUT_Callback,
    EP5_OUT_Callback,
    EP6_OUT_Callback,
    EP7_OUT_Callback,
  };



typedef struct _Task{
  void (*TASK1)(void);    
  void (*TASK2)(void);  
  void (*TASK3)(void);  
  void (*TASK4)(void);  
  void (*TASK5)(void);  
  void (*TASK6)(void);  
  void (*TASK7)(void);  
}Task;


Task ak =
  {
Process1,
Process2,
Process3,
Process4,
Process5,
Process6,
Process7
};



int EPindex=0;
Task *ak1 ;


int main(void){



/*
 while(1){
  if (EPindex>6)EPindex=0;
  (*pEpInt_OUT[EPindex])();
  EPindex++;

 }
*/


/*
 while(1){
  Process1( );
  Process2( );
  Process3( );
  Process4( );
  Process5( );
  Process6( );
  Process7( );

 }
*/


/*
 while(1){
  ak.TASK1( );
  ak.TASK2( );
  ak.TASK3( );
  ak.TASK4( );
  ak.TASK5( );
  ak.TASK6( );
  ak.TASK7( );


 }
*/
 ak1=&ak;
 while(1){
  ak1->TASK1( );
  ak1->TASK2( );
  ak1->TASK3( );
  ak1->TASK4( );
  ak1->TASK5( );
  ak1->TASK6( );
  ak1->TASK7( );

 }


}


 


上面有四種不同副程式的寫法,有興趣的人可以自行compiler,有問題可以請教Bee大大,應該會得到更滿意的答案。



 


2010年5月10日 星期一

熱鬧的實驗室

不知怎麼搞的,實驗室已經變網咖了


一到了晚上就超開心的


打電動或許是休閒


但應該要適可而止吧。


記得以前看過的文章在 Delphi K.Top 越來越難學到東西


現在的學弟習慣守成,換個MCU或許就怕了,擔心學長畢業了怎麼辦


也難怪在實驗室學東西愈來愈慢,要不是反骨的個性使然,不然我也守成好了


常常我也有這樣的問題:如何帶蔡鳥


可是如果學弟睡到中午才來,來了又不認真,周休好幾日,那麼又要別人如何認真帶?


有時候想想,我憑什麼要教你?


之前實驗室不會I2C、SPI,沒人會,所以只好自行研究,後來學弟知道我會I2C、SPI,和我要程式,我就直接給了,學弟把程式燒進去後,和我說了一句:「啊SPI就這麼簡單嘛……」,嗯。


好了,寫太多,只會讓自己的心情變BLUE。


吵雜的網咖聲,影響我平靜的生活,不開心


2010年5月9日 星期日

準備進軍USB

今天拉著國彥先生來教我USB,真抱歉讓他午餐沒吃陪我試USB


不過也拖了他的福,範例程式已經可以開始動了


可以模擬COM port了


該不多把USB的課本拿出來複習一下了


以前就很想玩USB,一直沒機會,但是透過這次的機會,好好的玩一下STM32的USB吧


期待我的好消息


 


2010年5月5日 星期三

制度

一間好的公司,一定有好的制度


那麼,一間好的實驗室,是否需要一個好的制度,才能永久生存


最近很久沒有焊接了


但誇張的是,焊接桌的垃圾桶滿了,竟然沒人要倒(裡面也有便當?!)


之前工具買了一堆,但SMD專用的攝子竟然沒一把是正常的


用了真的很另人生氣


難道,這些都需要講才會做嗎?


這是共同使用的區域的問題


 


我的筆桶放了一堆工具,每次我都要去找我的剪刀和釘書機,很不開心


上個月最蝦的事發生了,我找了一星期的剪刀,一星期過後,有個學弟說:「學長,我把你的剪刀弄不見了!」,說實在的,弄不見就算了,要生一把給我啊@@而且你借走了,又不說,一個星期後才和我說。您知道我找了一個星期嗎?(因為我用的工具都會選比較特別的,比較好認)


這是我的私人區域的問題


 


學弟在學習的時候,有時候,真的給一個完整的套件,好嗎?


想想,我在學習的時候,是每個實習都做,雖然無聊了點,但總是比較實在,至少對硬體、程式都比較熟悉


現在的學弟一遇到問題,就直接問學長,有能力解決的,好像還需要培養。


有人說:「興趣是可以培養的。」


嗯,但培養了興趣後,是不是要培養技術與技巧了呢?


這是專業的問題


 


常常有人說我很兇,嗯,但有時候,寫了blog,不看,同樣的問題一而再,再而三的被問起,真的是培養我的耐心。以前會盡量在實驗室的主機,寫著blog,寫了也不見得有人看,後來也放棄了,和外面的人做交流,我收穫反而比較大。


我準備要畢業了,看著一間實驗室建立的辛苦,再看看準備離開的實驗室,今天學弟說他們昨天在討論我走了怎麼辦,嗯,我也不知道該怎麼辦,因為一切都盡在不言之中!!!


2010年5月4日 星期二

終於完成選單了

這次的TFT因為顯示的螢幕夠大


所以在寫選單的時候,反而比以前4個BYTE的SLR2016來得複雜


為了讓選單可以像平常產品在用的選單一樣,所以花了幾天在想如何設計一定比較人性化的選單


但是卻苦了自己


在這幾天的努力下,終於完成了選單的設計了


接下來就只要等機構設計好,就可以做接下來的測試活動了



今天和學長要了一個不錯的程式-SOURCE INSIGHT


感覺超級方便的,有興趣的可以下載回來玩看看


我覺得是一套不錯用的程式。


2010年5月3日 星期一

尊重

有時候想想,人和人相處不就是互相尊重


或許我做的不是很好,講得不是很清楚,但如果我的好意被拿來當笑話,那麼心裡肯定不好受


嗯~這次或許是有經驗了,沒生氣,這也是一種學習吧!


當在批評別人時,請多想想自己是否做到了~


嗯~


對不起,這是一篇抱怨文!偶爾需要情緒發洩一下