jquery

2019年11月11日 星期一

Linux 連居易的VPN (Linux connect to Draytek vpn)

這個問題算是一個小麻煩, 在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網段進行變更

2019年9月11日 星期三

資訊系統 該自行開發 或 對外採購?

這個話題是老生長談了,但最近碰到客戶的情況,還是來寫一篇自己的看法

這個客戶是醫療業的醫院,在二年前我們去介紹我們的軟體系統後,該醫院決定自行開發系統,理由是資訊室的人員認為他們有能力自行開發。

好,其實面對到這樣的客戶我們也只有祝福,不便多說什麼,當了這麼多年的工程師,我很清楚資訊人員的思維,為什麼這樣說我下面會提。

事情就這樣過了二年多,從同行的消息中得知,為了開發這些資訊系統,該醫院增聘了三位有開發經驗的工程師,這約二年半中共開發了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


之後重開機一次,耗電檢測好像有正常了 ,再來實際觀察看看












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了

點下之後就可以輸入並登入了



2019年4月7日 星期日

FANCL 手元のピント調節力にえんきん 芳珂的遠近護眼 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
  }
}

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.啟動左輪

但白痴如我,單晶片不支援多工

所以...身為一個專業的軟體工程師,我決定改車....

我就像軌道車那樣,用一顆馬達做四輪傳動就好了

就憑你這種小車也想玩我,我操!!!