這個問題算是一個小麻煩, 在LINUX上的VPN設定大致照官方網頁執行即可
居易官方VPN設定教學
連上之後的麻煩就是, 『無法連到VPN內部IP』
假設我從外面連回公司, 公司的內部IP是192.168.0.X的話
那麼我其實在接上VPN之後,在第一 時間內無法連上公司的其它IP
假設我在星巴克, 星巴克給我的IP 是192.168.43.160
連回公司後取到的IP是192.168.1.79
但此時我無法連上我公司內的192.168.1.22 的FTP SERVER
這邊的問題出在連上VPN後預設的路由並沒有改變,
可以經由以下的指令查看
$ ip route
這邊是我的結果
所以必須加入公司內部路由才可以
$sudo ip route add 192.168.1.0/24 via 192.168.1.1
加完後就可以連了
---------------------------------------------------------------------------------------------------------
但問題又來, 如果你中途把VPN斷開, 會變成在星巴克的網路無法出去的情況
因為你為了VPN有加了一個路由的關係, 所以理論上那個路由應該被刪除後才能正常
ip route del .... 請自行上網google怎麼刪路由, 我這邊提供一個方便的方法
打以下指令即可
$sudo dhclient
這樣網路就會變正常了
以上的網路請依照你的IP網段進行變更
jquery
2019年11月11日 星期一
2019年9月11日 星期三
資訊系統 該自行開發 或 對外採購?
這個話題是老生長談了,但最近碰到客戶的情況,還是來寫一篇自己的看法
這個客戶是醫療業的醫院,在二年前我們去介紹我們的軟體系統後,該醫院決定自行開發系統,理由是資訊室的人員認為他們有能力自行開發。
好,其實面對到這樣的客戶我們也只有祝福,不便多說什麼,當了這麼多年的工程師,我很清楚資訊人員的思維,為什麼這樣說我下面會提。
事情就這樣過了二年多,從同行的消息中得知,為了開發這些資訊系統,該醫院增聘了三位有開發經驗的工程師,這約二年半中共開發了2套小型系統。
但由於某些問題,最近又對外要購買,而且要購買的是當初原本要買的系統。
也就是說他們自行開發的系統決定要放棄不使用,而要對外買新的。
問題來了, 為什麼???
以台灣的資訊人員的能力,要開發出堪用的系統並不難,決定放棄一定是有什麼重大的理由。
我們先從上面所說「資訊室的人員認為他們有能力自行開發」說起,這句話沒有錯,但只說了一半,後半句通常是「但可能無力處理系統維護」。
問題又來了,自行開發的系統卻無力處理,為什麼?
除了系統設計能力問題,另一個重大原因是經營成本
我們要賣給他們的系統,二百多萬一套,第二年開始維護費用10%,所以維護費是20多萬一年
但他們為了此系統找了三個有經驗的工程師,我們以一般工程師約70萬年薪來算 ,
光是這三位的薪資,一年210萬,也就是說他們在剛好一年內就開發出可運作的系統,成本就是210萬,這個價和我們賣給他們的售價差不多
但,第二年問題就來了,如果第二年開始這三位沒有再開發一些有價值的系統,對醫院而言這套系統的維護費用就是210萬。
再以經驗來說,開發一年多完成,要實際佈署在醫療作業裡大概要花上半年到一年,
也就是說原本200多萬跟廠商買就解決的事,醫院卻繞了一大圈。(廠商通常經驗豐富,小型系統導入不用半年)
所以, 醫院花了超過二倍的時間和價格弄了一套系統
也因為這樣,成本太高被迫要減少資訊人員的數量, 但減少了的後果就是少數人在維護 ,時間一久,工作壓力大的情形下,走的走,逃的逃。
以上是自行開發成功,但卻放棄的案例, 自行開發失敗的案例就更多了....。
這個客戶是醫療業的醫院,在二年前我們去介紹我們的軟體系統後,該醫院決定自行開發系統,理由是資訊室的人員認為他們有能力自行開發。
好,其實面對到這樣的客戶我們也只有祝福,不便多說什麼,當了這麼多年的工程師,我很清楚資訊人員的思維,為什麼這樣說我下面會提。
事情就這樣過了二年多,從同行的消息中得知,為了開發這些資訊系統,該醫院增聘了三位有開發經驗的工程師,這約二年半中共開發了2套小型系統。
但由於某些問題,最近又對外要購買,而且要購買的是當初原本要買的系統。
也就是說他們自行開發的系統決定要放棄不使用,而要對外買新的。
問題來了, 為什麼???
以台灣的資訊人員的能力,要開發出堪用的系統並不難,決定放棄一定是有什麼重大的理由。
我們先從上面所說「資訊室的人員認為他們有能力自行開發」說起,這句話沒有錯,但只說了一半,後半句通常是「但可能無力處理系統維護」。
問題又來了,自行開發的系統卻無力處理,為什麼?
除了系統設計能力問題,另一個重大原因是經營成本
我們要賣給他們的系統,二百多萬一套,第二年開始維護費用10%,所以維護費是20多萬一年
但他們為了此系統找了三個有經驗的工程師,我們以一般工程師約70萬年薪來算 ,
光是這三位的薪資,一年210萬,也就是說他們在剛好一年內就開發出可運作的系統,成本就是210萬,這個價和我們賣給他們的售價差不多
但,第二年問題就來了,如果第二年開始這三位沒有再開發一些有價值的系統,對醫院而言這套系統的維護費用就是210萬。
再以經驗來說,開發一年多完成,要實際佈署在醫療作業裡大概要花上半年到一年,
成本 | 第一年維護 | 第二年維護 | 耗時 | 合計 | |
自建 | 210萬 | 210萬 | 210萬 | 2年 | 630萬 |
外購 | 250萬 | 25萬 | 25萬 | 約3~6個月 | 300萬 |
也就是說原本200多萬跟廠商買就解決的事,醫院卻繞了一大圈。(廠商通常經驗豐富,小型系統導入不用半年)
所以, 醫院花了超過二倍的時間和價格弄了一套系統
也因為這樣,成本太高被迫要減少資訊人員的數量, 但減少了的後果就是少數人在維護 ,時間一久,工作壓力大的情形下,走的走,逃的逃。
以上是自行開發成功,但卻放棄的案例, 自行開發失敗的案例就更多了....。
2019年5月22日 星期三
ubuntu 筆電 耗電問題
ubuntu裝在筆電上已經用一 陣子了,但總覺得異常的吃電
我的電池在windows的模式下可以用1.5小時左右
但在ubuntu上只能使用大概四十分鐘
這個吃得有點多 ,所以裝了powertop這個工具查看了一下
#powertop --html
他會把檢測結果發在一個HTML檔,用chrome打開即可
檢測結果我的apt-check異常的吃電,cpu 才吃0.2%,他要吃8.2%
所以動手調整了預設啟動, 把apt-check關閉
調整此檔/etc/xdg/autostart/update-notifier.desktop
進去把X-GNOME-Autostart-Delay=60 砍掉
換上X-GNOME-Autostart-enabled=false
我的電池在windows的模式下可以用1.5小時左右
但在ubuntu上只能使用大概四十分鐘
這個吃得有點多 ,所以裝了powertop這個工具查看了一下
#powertop --html
他會把檢測結果發在一個HTML檔,用chrome打開即可
檢測結果我的apt-check異常的吃電,cpu 才吃0.2%,他要吃8.2%
所以動手調整了預設啟動, 把apt-check關閉
調整此檔/etc/xdg/autostart/update-notifier.desktop
進去把X-GNOME-Autostart-Delay=60 砍掉
換上X-GNOME-Autostart-enabled=false
之後重開機一次,耗電檢測好像有正常了 ,再來實際觀察看看
2019年5月17日 星期五
如何在電腦上 開二個Line
line 在台灣是很多人用的通訊軟體
像我本身是雙槍俠,手機有二枝 ,所以自然而然的我的line有二個
一般 在電腦上你如果想要使用line,可以到官方下載程式進行安裝
網址如下↓
https://line.me/zh-hant/download
但如果你想在電腦上裝第二個line要如何做呢?
又或者你想在Linux的電腦上裝line的話要如何做呢?
line有推出一個在chrome上的extension
準備好chrome瀏覽器,到底下網址安裝chrome extension
https://chrome.google.com/webstore/detail/line/ophjlpahpchlmihnnnihgmmeilfjmjjc
裝好之後在右上角就可以看到line了
點下之後就可以輸入並登入了
像我本身是雙槍俠,手機有二枝 ,所以自然而然的我的line有二個
一般 在電腦上你如果想要使用line,可以到官方下載程式進行安裝
網址如下↓
https://line.me/zh-hant/download
但如果你想在電腦上裝第二個line要如何做呢?
又或者你想在Linux的電腦上裝line的話要如何做呢?
line有推出一個在chrome上的extension
準備好chrome瀏覽器,到底下網址安裝chrome extension
https://chrome.google.com/webstore/detail/line/ophjlpahpchlmihnnnihgmmeilfjmjjc
裝好之後在右上角就可以看到line了
2019年4月7日 星期日
FANCL 手元のピント調節力にえんきん 芳珂的遠近護眼 Asahi提高睡眠
由於長期打電腦造成肩、頸酸,然後最近出現乾眼、畏光,有時還會頭暈頭痛
之前頭暈頭痛時跑去看眼科,擔心自己的眼壓太高,結果一量是正常的
但我就是頭頸酸痛,眼乾畏光,所以醫生幫我做了淚液測試
結果我的眼睛,淚液少得可以,醫生的診斷結果。。。。俺有嚴重的乾眼症
最後,給了一瓶人工淚液叫我回家多熱敷,3C用品少用就自然好了,這是文明病
沒有藥醫。。。乾霖老濕勒。。。
那我認真的施行了一個月,改善確實有一點點效果,但因為我是工程師,沒辦法完全不用電腦,所以還是覺得.。。。另行他法
所以我打算買一些保健食品來嚐試,
我常日本出差,也知道日本是保健食品的大國,所以我比較了日本市面上和台灣市面上的幾項產品
決定之後買了常見的日本通販品牌「DHC」的護眼系列,買了葉黃素、藍莓花青素、蝦紅素
又認真吃了半年,改善效果。。。。 ,我是有感覺眼睛沒有那麼乾了
因為我原本一個早上要點超過四次人工淚液,吃了之後不知道是不是改善的關係,到現在一天大概2~3次,
總體來說有改善,但我覺得效果不好,而且三種,每種一包,一次要吞五顆,實在有點受不了
這次2019-04-03清明連假又被叫到日本出差,經過藥妝店進去逛了一下,發現另一個大牌子FANCL芳珂,也有在賣
主要成份除了上面買的那三種,還多了DHA,然後背後的說明寫得好像有那麼一回事
說明如下,礙於台灣法津,這張圖的右邊的內容我不能說,看不懂日文的朋友請自行找人翻譯吧
成份的部分在左下
然後又看到一個Asahi出的提高睡眠品質的健康食品,。。。。一起買了
因為我其實懷疑我的症狀是因為睡眠品質不好而引起,我常日本的工程師處理客戶的問題到半夜二點(和日本人工作真的很操...)
所以這些頭暈和乾眼搞不好都是睡不好引起的, 所以就一併買來試了
我再來認真的吃個半年看看。。。希望可以改善啊
之前頭暈頭痛時跑去看眼科,擔心自己的眼壓太高,結果一量是正常的
但我就是頭頸酸痛,眼乾畏光,所以醫生幫我做了淚液測試
結果我的眼睛,淚液少得可以,醫生的診斷結果。。。。俺有嚴重的乾眼症
最後,給了一瓶人工淚液叫我回家多熱敷,3C用品少用就自然好了,這是文明病
沒有藥醫。。。乾霖老濕勒。。。
那我認真的施行了一個月,改善確實有一點點效果,但因為我是工程師,沒辦法完全不用電腦,所以還是覺得.。。。另行他法
所以我打算買一些保健食品來嚐試,
我常日本出差,也知道日本是保健食品的大國,所以我比較了日本市面上和台灣市面上的幾項產品
決定之後買了常見的日本通販品牌「DHC」的護眼系列,買了葉黃素、藍莓花青素、蝦紅素
又認真吃了半年,改善效果。。。。 ,我是有感覺眼睛沒有那麼乾了
因為我原本一個早上要點超過四次人工淚液,吃了之後不知道是不是改善的關係,到現在一天大概2~3次,
總體來說有改善,但我覺得效果不好,而且三種,每種一包,一次要吞五顆,實在有點受不了
這次2019-04-03清明連假又被叫到日本出差,經過藥妝店進去逛了一下,發現另一個大牌子FANCL芳珂,也有在賣
主要成份除了上面買的那三種,還多了DHA,然後背後的說明寫得好像有那麼一回事
說明如下,礙於台灣法津,這張圖的右邊的內容我不能說,看不懂日文的朋友請自行找人翻譯吧
成份的部分在左下
然後又看到一個Asahi出的提高睡眠品質的健康食品,。。。。一起買了
因為我其實懷疑我的症狀是因為睡眠品質不好而引起,我常日本的工程師處理客戶的問題到半夜二點(和日本人工作真的很操...)
所以這些頭暈和乾眼搞不好都是睡不好引起的, 所以就一併買來試了
我再來認真的吃個半年看看。。。希望可以改善啊
2019年3月30日 星期六
Arduino 自走車(智能小車)超音波偵測碰撞 改良無法走直線(2)
使用紅外線進行控制,進行了左右輪調速,並加入超音波碰撞偵測
拿廠商給的程式改的
超音波偵測感測器為 HC-SR04
//------------------------------------程式碼開始---------------------------------------------
#include//红外線函式庫
int RECV_PIN = A4;//宣告紅外線 PIN腳
IRrecv irrecv(RECV_PIN); //創建一個紅外線
decode_results results;//這個用來解析你的紅外線是哪一牌
int on = 0;//标志位
unsigned long last = millis();
//底下為超音波偵測器的設定,超音波裝置有主要二個PIN腳,echo 和trig
int echo=7;
int trig=12;
int distance=0; //用來記錄超音波裝置偵測到的距離
int dangerDistance=30; //自訂危險距離,我設30, 也就是偵測到小於三十公分,自走車強制停止前進,避免撞牆
//-------------------
long run_car = 0x00FF629D;//按键CH
long back_car = 0x00FFA857;//按键+
long left_car = 0x00FF22DD;//按键<<
long right_car = 0x00FFC23D;//按键>||
long stop_car = 0x00FF02FD;//按键>>|
long left_turn = 0x00ffE01F;//按键-
long right_turn = 0x00FF906F;//按键EQ
//==============================
int Left_motor_go=8; //左馬達前進(IN1)
int Left_motor_back=9; //左馬達後退(IN2)
int Right_motor_go=10; // 右馬達前進(IN3)
int Right_motor_back=11; // 右馬達後退(IN4)
int runCount=0;
void setup()
{
//初始化馬達的IO方式
pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
pinMode(Left_motor_back,OUTPUT); // PIN 9 (PWM)
pinMode(Right_motor_go,OUTPUT);// PIN 10 (PWM)
pinMode(Right_motor_back,OUTPUT);// PIN 11 (PWM)
pinMode(13, OUTPUT);////端口模式,输出
pinMode(trig, OUTPUT);
pinMode(echo,INPUT);
Serial.begin(9600); //波特率9600
irrecv.enableIRIn(); // Start the receiver
}
void Distance_test(){
//底下為超音波測距離的標準寫法
digitalWrite(trig,LOW);
delayMicroseconds(2);
digitalWrite(trig,HIGH);
delayMicroseconds(10); //最小為10,小於此值,偵測易失敗
digitalWrite(trig, LOW);
float Fdistance = pulseIn(echo, HIGH); // 讀取返回時間(單位:微秒)
Fdistance= Fdistance/58; //除以58等於公分, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》公分=微秒/58
distance = Fdistance;
}
void Distance_display(){
Serial.print("Distance is: ");
Serial.println(distance);
}
void brake() //停車
{
digitalWrite(Right_motor_go,LOW);
digitalWrite(Right_motor_back,LOW);
digitalWrite(Left_motor_go,LOW);
digitalWrite(Left_motor_back,LOW);
runCount=0;
//delay(time * 100);//執行時間,可以调整
}
void run() // 前進
{
if(runCount ==0){
analogWrite(Right_motor_go,250);
runCount=1;
}else{
digitalWrite(Right_motor_go,HIGH);
}
// digitalWrite(Right_motor_go,HIGH); // 右馬達前進
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,200);//PWM比例0~255调速,如果左右輪不平均(例如無法走直線),可以改用此函數,調整值即可
//analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,LOW); // 左馬達前進
digitalWrite(Left_motor_back,HIGH);
//analogWrite(Left_motor_go,0);//PWM比例0~255调速,
//analogWrite(Left_motor_back,200);
//delay(time * 100); //執行時間,可以调整
}
void left() //左轉(左輪不動,右輪前進)
{
digitalWrite(Right_motor_go,HIGH); // 右馬達前進
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,200);
//analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW); //左輪後退
digitalWrite(Left_motor_back,LOW);
//analogWrite(Left_motor_go,0);
//analogWrite(Left_motor_back,0);//PWM比例0~255调速
//delay(time * 100); //執行時間,可以调整
}
void spin_left() //左轉(左輪後退,右輪前進)
{
digitalWrite(Right_motor_go,HIGH); // 右馬達前進
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,200);
//analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH); //左輪後退
digitalWrite(Left_motor_back,LOW);
//analogWrite(Left_motor_go,200);
//analogWrite(Left_motor_back,0);//PWM比例0~255调速
//delay(time * 100); //執行時間,可以调整
}
void right() //右轉(右輪不动,左輪前進)
{
digitalWrite(Right_motor_go,LOW); //右电机後退
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,0);
//analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左馬達前進
digitalWrite(Left_motor_back,HIGH);
//analogWrite(Left_motor_go,0);
// analogWrite(Left_motor_back,200);//PWM比例0~255调速
// delay(time * 100); //執行時間,可以调整
}
void spin_right() //右轉(右輪後退,左輪前進)
{
digitalWrite(Right_motor_go,LOW); //右电机後退
digitalWrite(Right_motor_back,HIGH);
//analogWrite(Right_motor_go,0);
//analogWrite(Right_motor_back,200);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左馬達前進
digitalWrite(Left_motor_back,HIGH);
//analogWrite(Left_motor_go,0);
//analogWrite(Left_motor_back,200);//PWM比例0~255调速
//delay(time * 100); //執行時間,可以调整
}
void back() //後退
{
digitalWrite(Right_motor_go,LOW); //右輪後退
digitalWrite(Right_motor_back,HIGH);
//analogWrite(Right_motor_go,0);
//analogWrite(Right_motor_back,150);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH); //左輪後退
digitalWrite(Left_motor_back,LOW);
//analogWrite(Left_motor_go,150);
//analogWrite(Left_motor_back,0);//PWM比例0~255调速
//delay(time * 100); //執行時間,可以调整
}
void dump(decode_results *results)
{
int count = results->rawlen;
if (results->decode_type == UNKNOWN)
{
//Serial.println("Could not decode message");
brake();
}
//輸出你使用的遙控器的編碼,但此段程式會影響程式執行速度,除了測試之外建議註解掉
/*
else
{
if (results->decode_type == NEC)
{
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY)
{
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5)
{
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6)
{
Serial.print("Decoded RC6: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
}
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++)
{
if ((i % 2) == 1)
{
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else
{
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
*/
}
void loop()
{
Distance_test();
delay(100);
if(distance < dangerDistance){
brake();
}
//Distance_display();
if (irrecv.decode(&results)) //解碼
{
// If it's been at least 1/4 second since the last
// IR received, toggle the relay
if (millis() - last > 250) //確定接收到訊號
{
on = !on;//標記位置反
digitalWrite(13, on ? HIGH : LOW);//收到訊號後閃一下LED
// dump(&results);//解碼紅外線訊號,看是哪一家(sony,NEC...)
}
if (results.value == run_car )//按键CH
run();//前進
if (results.value == back_car )//按键+
back();//後退
if (results.value == left_car ){//按键<<
left();//左轉
delay(300);
brake();
}
if (results.value == right_car ){//按键>||
right();//右轉
delay(300);
brake();
}
if (results.value == stop_car )//按键>>|
brake();//停車
if (results.value == left_turn )//按键-
spin_left();//左旋轉
if (results.value == right_turn )//按键EQ
spin_right();//右旋轉
last = millis();
irrecv.resume(); // Receive the next value
}
}
拿廠商給的程式改的
超音波偵測感測器為 HC-SR04
//------------------------------------程式碼開始---------------------------------------------
#include
int RECV_PIN = A4;//宣告紅外線 PIN腳
IRrecv irrecv(RECV_PIN); //創建一個紅外線
decode_results results;//這個用來解析你的紅外線是哪一牌
int on = 0;//标志位
unsigned long last = millis();
//底下為超音波偵測器的設定,超音波裝置有主要二個PIN腳,echo 和trig
int echo=7;
int trig=12;
int distance=0; //用來記錄超音波裝置偵測到的距離
int dangerDistance=30; //自訂危險距離,我設30, 也就是偵測到小於三十公分,自走車強制停止前進,避免撞牆
//-------------------
long run_car = 0x00FF629D;//按键CH
long back_car = 0x00FFA857;//按键+
long left_car = 0x00FF22DD;//按键<<
long right_car = 0x00FFC23D;//按键>||
long stop_car = 0x00FF02FD;//按键>>|
long left_turn = 0x00ffE01F;//按键-
long right_turn = 0x00FF906F;//按键EQ
//==============================
int Left_motor_go=8; //左馬達前進(IN1)
int Left_motor_back=9; //左馬達後退(IN2)
int Right_motor_go=10; // 右馬達前進(IN3)
int Right_motor_back=11; // 右馬達後退(IN4)
int runCount=0;
void setup()
{
//初始化馬達的IO方式
pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)
pinMode(Left_motor_back,OUTPUT); // PIN 9 (PWM)
pinMode(Right_motor_go,OUTPUT);// PIN 10 (PWM)
pinMode(Right_motor_back,OUTPUT);// PIN 11 (PWM)
pinMode(13, OUTPUT);////端口模式,输出
pinMode(trig, OUTPUT);
pinMode(echo,INPUT);
Serial.begin(9600); //波特率9600
irrecv.enableIRIn(); // Start the receiver
}
void Distance_test(){
//底下為超音波測距離的標準寫法
digitalWrite(trig,LOW);
delayMicroseconds(2);
digitalWrite(trig,HIGH);
delayMicroseconds(10); //最小為10,小於此值,偵測易失敗
digitalWrite(trig, LOW);
float Fdistance = pulseIn(echo, HIGH); // 讀取返回時間(單位:微秒)
Fdistance= Fdistance/58; //除以58等於公分, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》公分=微秒/58
distance = Fdistance;
}
void Distance_display(){
Serial.print("Distance is: ");
Serial.println(distance);
}
void brake() //停車
{
digitalWrite(Right_motor_go,LOW);
digitalWrite(Right_motor_back,LOW);
digitalWrite(Left_motor_go,LOW);
digitalWrite(Left_motor_back,LOW);
runCount=0;
//delay(time * 100);//執行時間,可以调整
}
void run() // 前進
{
if(runCount ==0){
analogWrite(Right_motor_go,250);
runCount=1;
}else{
digitalWrite(Right_motor_go,HIGH);
}
// digitalWrite(Right_motor_go,HIGH); // 右馬達前進
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,200);//PWM比例0~255调速,如果左右輪不平均(例如無法走直線),可以改用此函數,調整值即可
//analogWrite(Right_motor_back,0);
digitalWrite(Left_motor_go,LOW); // 左馬達前進
digitalWrite(Left_motor_back,HIGH);
//analogWrite(Left_motor_go,0);//PWM比例0~255调速,
//analogWrite(Left_motor_back,200);
//delay(time * 100); //執行時間,可以调整
}
void left() //左轉(左輪不動,右輪前進)
{
digitalWrite(Right_motor_go,HIGH); // 右馬達前進
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,200);
//analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW); //左輪後退
digitalWrite(Left_motor_back,LOW);
//analogWrite(Left_motor_go,0);
//analogWrite(Left_motor_back,0);//PWM比例0~255调速
//delay(time * 100); //執行時間,可以调整
}
void spin_left() //左轉(左輪後退,右輪前進)
{
digitalWrite(Right_motor_go,HIGH); // 右馬達前進
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,200);
//analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH); //左輪後退
digitalWrite(Left_motor_back,LOW);
//analogWrite(Left_motor_go,200);
//analogWrite(Left_motor_back,0);//PWM比例0~255调速
//delay(time * 100); //執行時間,可以调整
}
void right() //右轉(右輪不动,左輪前進)
{
digitalWrite(Right_motor_go,LOW); //右电机後退
digitalWrite(Right_motor_back,LOW);
//analogWrite(Right_motor_go,0);
//analogWrite(Right_motor_back,0);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左馬達前進
digitalWrite(Left_motor_back,HIGH);
//analogWrite(Left_motor_go,0);
// analogWrite(Left_motor_back,200);//PWM比例0~255调速
// delay(time * 100); //執行時間,可以调整
}
void spin_right() //右轉(右輪後退,左輪前進)
{
digitalWrite(Right_motor_go,LOW); //右电机後退
digitalWrite(Right_motor_back,HIGH);
//analogWrite(Right_motor_go,0);
//analogWrite(Right_motor_back,200);//PWM比例0~255调速
digitalWrite(Left_motor_go,LOW);//左馬達前進
digitalWrite(Left_motor_back,HIGH);
//analogWrite(Left_motor_go,0);
//analogWrite(Left_motor_back,200);//PWM比例0~255调速
//delay(time * 100); //執行時間,可以调整
}
void back() //後退
{
digitalWrite(Right_motor_go,LOW); //右輪後退
digitalWrite(Right_motor_back,HIGH);
//analogWrite(Right_motor_go,0);
//analogWrite(Right_motor_back,150);//PWM比例0~255调速
digitalWrite(Left_motor_go,HIGH); //左輪後退
digitalWrite(Left_motor_back,LOW);
//analogWrite(Left_motor_go,150);
//analogWrite(Left_motor_back,0);//PWM比例0~255调速
//delay(time * 100); //執行時間,可以调整
}
void dump(decode_results *results)
{
int count = results->rawlen;
if (results->decode_type == UNKNOWN)
{
//Serial.println("Could not decode message");
brake();
}
//輸出你使用的遙控器的編碼,但此段程式會影響程式執行速度,除了測試之外建議註解掉
/*
else
{
if (results->decode_type == NEC)
{
Serial.print("Decoded NEC: ");
}
else if (results->decode_type == SONY)
{
Serial.print("Decoded SONY: ");
}
else if (results->decode_type == RC5)
{
Serial.print("Decoded RC5: ");
}
else if (results->decode_type == RC6)
{
Serial.print("Decoded RC6: ");
}
Serial.print(results->value, HEX);
Serial.print(" (");
Serial.print(results->bits, DEC);
Serial.println(" bits)");
}
Serial.print("Raw (");
Serial.print(count, DEC);
Serial.print("): ");
for (int i = 0; i < count; i++)
{
if ((i % 2) == 1)
{
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else
{
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("");
*/
}
void loop()
{
Distance_test();
delay(100);
if(distance < dangerDistance){
brake();
}
//Distance_display();
if (irrecv.decode(&results)) //解碼
{
// If it's been at least 1/4 second since the last
// IR received, toggle the relay
if (millis() - last > 250) //確定接收到訊號
{
on = !on;//標記位置反
digitalWrite(13, on ? HIGH : LOW);//收到訊號後閃一下LED
// dump(&results);//解碼紅外線訊號,看是哪一家(sony,NEC...)
}
if (results.value == run_car )//按键CH
run();//前進
if (results.value == back_car )//按键+
back();//後退
if (results.value == left_car ){//按键<<
left();//左轉
delay(300);
brake();
}
if (results.value == right_car ){//按键>||
right();//右轉
delay(300);
brake();
}
if (results.value == stop_car )//按键>>|
brake();//停車
if (results.value == left_turn )//按键-
spin_left();//左旋轉
if (results.value == right_turn )//按键EQ
spin_right();//右旋轉
last = millis();
irrecv.resume(); // Receive the next value
}
}
2019年3月28日 星期四
Arduino, Raspberry pi 自走車(智能小車) 無法走直線(1)
為了迎接未來物聯網的時代,身為一個軟體工程師的我也開始學起IOT
在芒茫網海搜尋後,敗入了一台Arduino自走車,
紅外線避障+藍芽版本的一台才650塊新台幣 ,為了讓運費划算一點
買了樹莓派3 B+(含電源、殼、hdmi線),這個比台灣便宜很多,台幣1300左右,台灣這樣買要破二千
買來興高采列的組起小車
但組完之後發現這傢伙沒辦法走直線....等等,這是不是有什麼誤會Orz
一台車耶,沒辦法走直線
再上網問狗之後,發現這個不是個案
網路上找到的問題點
1.馬達有公差,,即使二顆馬達全力輸出,,轉速也不可能一模一樣
2.Arduino是單晶片,速度不快所導致
這二個問題點都可以透過調整馬達的速度(PWM)進行改善。
但除此之外呢? 沒有其它辦法嗎
因為據我觀察這台車的結果,給我的直覺就是
他是先啟動其中一輪所導致的
這台車是按下直走後,往左邊轉了約30度後再走直線
往左邊轉就是右輪先啟動,那程式裡剛好就是右輪先走
rightWheel()
leftWheel()
在這個情形下,先啟動的那邊會先走當然不奇怪,自然就歪一邊
所以身為專業的軟體工程師,我直覺的就想到, 用fork() 做multithread不就好了...?
做法很容易
1. 啟動右輪進背景
2. 馬上暫停右輪約1/3秒 (為了等左輪啟動)
3.啟動左輪
但白痴如我,單晶片不支援多工
所以...身為一個專業的軟體工程師,我決定改車....
我就像軌道車那樣,用一顆馬達做四輪傳動就好了
就憑你這種小車也想玩我,我操!!!
在芒茫網海搜尋後,敗入了一台Arduino自走車,
紅外線避障+藍芽版本的一台才650塊新台幣 ,為了讓運費划算一點
買了樹莓派3 B+(含電源、殼、hdmi線),這個比台灣便宜很多,台幣1300左右,台灣這樣買要破二千
買來興高采列的組起小車
但組完之後發現這傢伙沒辦法走直線....等等,這是不是有什麼誤會Orz
一台車耶,沒辦法走直線
再上網問狗之後,發現這個不是個案
網路上找到的問題點
1.馬達有公差,,即使二顆馬達全力輸出,,轉速也不可能一模一樣
2.Arduino是單晶片,速度不快所導致
這二個問題點都可以透過調整馬達的速度(PWM)進行改善。
但除此之外呢? 沒有其它辦法嗎
因為據我觀察這台車的結果,給我的直覺就是
他是先啟動其中一輪所導致的
這台車是按下直走後,往左邊轉了約30度後再走直線
往左邊轉就是右輪先啟動,那程式裡剛好就是右輪先走
rightWheel()
leftWheel()
在這個情形下,先啟動的那邊會先走當然不奇怪,自然就歪一邊
所以身為專業的軟體工程師,我直覺的就想到, 用fork() 做multithread不就好了...?
做法很容易
1. 啟動右輪進背景
2. 馬上暫停右輪約1/3秒 (為了等左輪啟動)
3.啟動左輪
但白痴如我,單晶片不支援多工
所以...身為一個專業的軟體工程師,我決定改車....
我就像軌道車那樣,用一顆馬達做四輪傳動就好了
就憑你這種小車也想玩我,我操!!!
訂閱:
文章 (Atom)