2018年8月6日 星期一

青少年班

彰化縣政府107年度青少年職業探索營
機械手臂自動控制設計班

機器手臂簡介ppt
材料:meArm組件,馬達建議使用MG90S,不要選用SG90

下載一
下載二

0.依照教材進行組裝
1.使用可變電阻操控伺服馬達轉動角度
   馬達接在數位腳位第9腳、可變電阻中間腳接類比腳位A0。
   小心轉動可變電阻,透過監控視窗,逐一測試所有伺服馬達的可轉動範圍,並紀錄上下限。
#include <Servo.h>
Servo myservo;
int potpin = 0;
int val;
void setup()
{
  Serial.begin(9600);// 開啟 Serial Port,通訊速率為 9600
  myservo.attach(9);  // Servo 接在 pin 9
}
void loop()
{
  val = analogRead(potpin);  
  val = map(val, 0, 1023, 0, 179);
  Serial.println(val);  
  myservo.write(val);                  // 設定 Servo 旋轉角度
  delay(100);                           // 等待
}

2.使用單顆可變電阻測試操控四顆伺服馬達轉動角度
   夾爪馬達接在數位腳位第2腳,底部馬達、左馬達、右馬達分別接在3、4、5腳,可變電阻中間腳接類比腳位A0。
   將步驟1所量測到的馬達轉動範圍填入程式中,利用可變電阻測試四顆馬達的轉動順暢性。
#include <Servo.h>
Servo myservo_B;
Servo myservo_L;
Servo myservo_R;
Servo myservo_H;
int potpin = 0;
int val,val_B,val_L,val_R,val_H;
int B_min=10;//底部馬達最小角度
int B_max=175;//底部馬達最大角度
int L_min=110;//左馬達最大角度 (此處反著寫)
int L_max=40;//左馬達最小角度 (此處反著寫)
int R_min=60;//右馬達最小角度
int R_max=160;//右馬達最大角度
int H_min=80;//夾爪馬達最小角度
int H_max=145;//夾爪馬達最大角度
int dt=50;
void setup()
{
  //Serial.begin(9600);// 開啟 Serial Port,通訊速率為 9600
  //myservo_B.attach(3);  // Servo 接在 pin 3
  myservo_L.attach(4);  // Servo 接在 pin 4
  myservo_R.attach(5);  // Servo 接在 pin 5
  myservo_H.attach(2);  // Servo 接在 pin 2 
}
void loop()
{
  val = analogRead(potpin);  
  val_B = map(val, 0, 1023, B_min, B_max);
  val_L = map(val, 0, 1023, L_min, L_max);
  val_R = map(val, 0, 1023, R_min, R_max);
  val_H = map(val, 0, 1023, H_min, H_max); 
  //Serial.println(val);  
  myservo_B.attach(3);  // Servo 接在 pin 3
  myservo_B.write(val_B);                  // 設定 Servo 旋轉角度
  myservo_L.write(val_L);                  // 設定 Servo 旋轉角度
  myservo_R.write(val_R);                  // 設定 Servo 旋轉角度
  myservo_H.write(val_H);                  // 設定 Servo 旋轉角度
  delay(dt);                           // 等待
  myservo_B.detach(); 
  delay(100-dt);
}

3.使用雙搖桿測試操控四顆伺服馬達轉動角度
   左搖桿的S-X接A0,控制底部馬達,S-Y接A1,控制左馬達。

   右搖桿的S-X接A2,控制夾爪馬達,S-Y接A3,控制右馬達。
   預設馬達角度為為最大與最小的平均值。當搖桿移動時,馬達就跟著轉動到對應角度,放開時回復到預設角度。
#include <Servo.h>
Servo myservo_B;
Servo myservo_L;
Servo myservo_R;
Servo myservo_H;
int B = 0;//左S-X接A0,控制底部馬達
int L = 1;//左S-Y接A1,控制左馬達
int H = 2;//右S-X接A2,控制夾爪馬達
int R = 3;//右S-Y接A3,控制右馬達
int val,val_B,val_L,val_R,val_H;
int B_min=10;//底部馬達最小角度
int B_max=175;//底部馬達最大角度
int L_min=110;//左馬達最大角度 (此處反著寫)
int L_max=40;//左馬達最小角度 (此處反著寫)
int R_min=60;//右馬達最小角度
int R_max=160;//右馬達最大角度
int H_min=80;//夾爪馬達最小角度
int H_max=145;//夾爪馬達最大角度
int dt=50;
void setup()
{
  //Serial.begin(9600);// 開啟 Serial Port,通訊速率為 9600
  //myservo_B.attach(3);  // Servo 接在 pin 3
  myservo_L.attach(4);  // Servo 接在 pin 4
  myservo_R.attach(5);  // Servo 接在 pin 5
  myservo_H.attach(2);  // Servo 接在 pin 2 
}
void loop()
{
  val = analogRead(B);  
  val_B = map(val, 0, 1023, B_min, B_max);
  val = analogRead(L);
  val_L = map(val, 0, 1023, L_min, L_max);
  val = analogRead(R);
  val_R = map(val, 0, 1023, R_min, R_max);
  val = analogRead(H);
  val_H = map(val, 0, 1023, H_min, H_max); 
  //Serial.println(val);  
  myservo_B.attach(3);  // Servo 接在 pin 3
  myservo_B.write(val_B);                  // 設定 Servo 旋轉角度
  myservo_L.write(val_L);                  // 設定 Servo 旋轉角度
  myservo_R.write(val_R);                  // 設定 Servo 旋轉角度
  myservo_H.write(val_H);                  // 設定 Servo 旋轉角度
  delay(dt);                           // 等待
  myservo_B.detach(); 
  delay(100-dt);
}

4.使用雙搖桿操控meArm
   與步驟3接法一致,但搖桿偏移時,馬達逐步轉動,搖桿回復時,馬達停止轉動。
#include <Servo.h>
Servo myservo_B;
Servo myservo_L;
Servo myservo_R;
Servo myservo_H;
int B = 0;//左S-X接A0,控制底部馬達
int L = 1;//左S-Y接A1,控制左馬達
int H = 2;//右S-X接A2,控制夾爪馬達
int R = 3;//右S-Y接A3,控制右馬達
int val_b,val_l,val_r,val_h,val_B,val_L,val_R,val_H;
int db,dl,dr,dh;
int B_min=30;//底部馬達最小角度
int B_max=160;//底部馬達最大角度
int L_min=40;//左馬達最小角度
int L_max=110;//左馬達最大角度
int R_min=50;//右馬達最小角度
int R_max=150;//右馬達最大角度
int H_min=60;//夾爪馬達最小角度
int H_max=150;//夾爪馬達最大角度
int dt=15;
void setup()
{
  //Serial.begin(9600);// 開啟 Serial Port,通訊速率為 9600
  myservo_B.attach(3);  // Servo 接在 pin 3
  myservo_L.attach(4);  // Servo 接在 pin 4
  myservo_R.attach(5);  // Servo 接在 pin 5
  myservo_H.attach(2);  // Servo 接在 pin 2
  val_B=(B_min+B_max)/2;
  val_L=(L_min+L_max)/2;
  val_R=(R_min+R_max)/2;
  val_H=(H_min+H_max)/2;
  myservo_B.write(val_B);                  // 設定 Servo 旋轉角度
  myservo_L.write(val_L);                  // 設定 Servo 旋轉角度
  myservo_R.write(val_R);                  // 設定 Servo 旋轉角度
  myservo_H.write(val_H);                  // 設定 Servo 旋轉角度
  delay(dt);                           // 等待
  myservo_B.detach(); 
  delay(dt);   
}
void loop()
{
  val_b = analogRead(B);  
  if (val_b >= 912)
     db=1;
  else if (val_b <= 312)
     db=-1;
  else
     db=0;
  val_l = analogRead(L);
   if (val_l >= 912)
     dl=-1;
  else if (val_l <= 312)
     dl=1;
  else
     dl=0;
  val_r = analogRead(R);
  if (val_r >= 912)
     dr=1;
  else if (val_r <= 312)
     dr=-1;
  else
     dr=0;  
  val_h = analogRead(H);
  if (val_h >= 912)
     dh=5;
  else if (val_h <= 312)
     dh=-5;
  else
     dh=0;
  if ((val_B+db)>= B_min && (val_B+db)<= B_max)
     val_B=val_B+db;
  if ((val_L+dl)>= L_min && (val_L+dl)<= L_max)
     val_L=val_L+dl;
  if ((val_R+dr)>= R_min && (val_R+dr)<= R_max)
     val_R=val_R+dr;
  if ((val_H+dh)>= H_min && (val_H+dh)<= H_max)
     val_H=val_H+dh;
  //Serial.println(val);  
  myservo_B.attach(3);  // Servo 接在 pin 3
  myservo_B.write(val_B);                  // 設定 Servo 旋轉角度
  myservo_L.write(val_L);                  // 設定 Servo 旋轉角度
  myservo_R.write(val_R);                  // 設定 Servo 旋轉角度
  myservo_H.write(val_H);                  // 設定 Servo 旋轉角度
  delay(dt);                           // 等待
  myservo_B.detach(); 
  delay(dt);
}
5.音效下載
6. 0810-1
7. 0810-2

2017年4月30日 星期日

C# IPCAM

D-Link 931L
尚未使用emgu(open cv)進行影像處理





using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.Util;

namespace test
{
    public partial class Form1 : Form
    {
        //IPCAM:D-Link 931L 
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }
       
        private void button1_Click(object sender, EventArgs e)
        {
           timer1.Enabled = false;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            string sourceURL = "http://"+textBox1.Text+"/image/jpeg.cgi";

            // create HTTP request
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sourceURL);

            //add id,password
            req.Credentials = new NetworkCredential("ooo", "xxx");//ooo為帳號,xxx為密碼

            // get response
            WebResponse resp = req.GetResponse();

            // get response stream
            Bitmap bmp = new Bitmap(resp.GetResponseStream());

            //show image in picturebox
            pictureBox1.Image = bmp;

        }
    }
}


2017年4月29日 星期六

DTR控制



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace DTR1060330_1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.PortName = "COM1";
            serialPort1.BaudRate = 9600;
            serialPort1.Parity = Parity.None;
            serialPort1.DataBits = 8;
            serialPort1.StopBits = StopBits.One;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = true;
            serialPort1.Open();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.DtrEnable = true;
            button3.Enabled = false;
            button4.Enabled = true;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.DtrEnable = false;
            button4.Enabled = false;
            button3.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;
            serialPort1.Close();
        }
    }
}

UDP單向資料傳送

UDPserver

使用計時器,每隔1毫秒接收資料



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace udpsever
{
    public partial class Form1 : Form
    {
     
        string text2;
        public delegate void AddDataDelegate();
        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 5555);

        UdpClient uc;
     
        public Form1()
        {
            InitializeComponent();
        }

        private void addData()
        {
            label1.Text = "Waiting for a client...";
        }
        private void addData_1()
        {
            label1.Text = text2;
        }
     
        private void button1_Click(object sender, EventArgs e)
        {
            uc = new UdpClient(5555);
            this.Invoke(new AddDataDelegate(addData));
            timer1.Enabled = true;  
        }

        private void button2_Click(object sender, EventArgs e)
        {

            timer1.Enabled = false;
            uc.Close();
            text2 = "Stop.....";
            this.Invoke(new AddDataDelegate(addData_1));
         
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            uc.Close();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (uc.Available != 0)
            {
                text2 = System.Text.Encoding.UTF8.GetString(uc.Receive(ref ipep));
                this.Invoke(new AddDataDelegate(addData_1));
            }          
        }
    }
}

UDPclient
單向傳送資料

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace udpclient
{
    public partial class Form1 : Form
    {
        IPEndPoint ipep;
        Socket server;
        string ip;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ip = textBox1.Text;
            ipep = new IPEndPoint(IPAddress.Parse(ip), 5555);
            server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ip="127.0.0.1";
            textBox1.Text = ip;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            string text = textBox2.Text;
            byte[] sendByte = Encoding.UTF8.GetBytes(text);
            server.SendTo(sendByte, ipep);
        }
    }
}

2016年3月21日 星期一

C# 控制 Arduino 2個LED

C#
加入
using System.IO.Ports;
程式碼
        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.PortName = "COM10";
            serialPort1.BaudRate = 9600;
            serialPort1.Parity = Parity.None;
            serialPort1.DataBits = 8;
            serialPort1.StopBits = StopBits.One;
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;
            button5.Enabled = false;
            button6.Enabled = false;
           
            label1.Text="斷線中";
        }
        private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = false;
            button5.Enabled = true;
            button6.Enabled = false;
            label1.Text = "連線中";
        }
        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Write("b");
            serialPort1.Write("d");
            serialPort1.Close();
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            button4.Enabled = false;
            button5.Enabled = false;
            button6.Enabled = false;
            label1.Text = "斷線中";
        }
        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Write("a");
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = false;
            button4.Enabled = true;
            label1.Text = "LED1 ON";
        }
        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.Write("b");
            button1.Enabled = false;
            button2.Enabled = true;
            button3.Enabled = true;
            button4.Enabled = false;
            label1.Text = "LED1 OFF";
        }
        private void button5_Click(object sender, EventArgs e)
        {
            serialPort1.Write("c");
            button1.Enabled = false;
            button2.Enabled = true;
            button5.Enabled = false;
            button6.Enabled = true;
            label1.Text = "LED2 ON";
        }
        private void button6_Click(object sender, EventArgs e)
        {
            serialPort1.Write("d");
            button1.Enabled = false;
            button2.Enabled = true;
            button5.Enabled = true;
            button6.Enabled = false;
            label1.Text = "LED2 OFF";
        }


Arduino程式
void setup() {
    Serial.begin(9600);     // 開啟 Serial port, 通訊速率為 9600 bps
    // 初始化 LED 接腳
   pinMode(12, OUTPUT);
   pinMode(11, OUTPUT);
 }       
 void loop() {
    // 檢查是否有資料可供讀取
   if (Serial.available() > 0) {
      // 讀取進來的 byte
      int inByte = Serial.read();
      // 根據收到的字元決定要打開或關掉 LED
      switch (inByte) {
      case 'b':    
        digitalWrite(12, LOW);
        break;
      case 'a': 
        digitalWrite(12, HIGH);
        break;
      case 'd':    
        digitalWrite(11, LOW);
        break;
      case 'c': 
        digitalWrite(11, HIGH);
        break; 
      default:
        // 關掉所有的 LED
        digitalWrite(12, LOW);
      }
    } 
 } 

2015年5月31日 星期日

C#控制Arduino LED、Arduino傳送超音波測距數值至C#

本篇文章為C#傳送字元至Arduino、Arduino回傳字串至C#續文
修改串列埠連線設定方式,取消連線按鈕,改為直接由下拉式選單選擇後連線
新增Arduino回傳超音波測距數值至C#的功能

C#
程式碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;


namespace _0150531
{
    public partial class Form1 : Form
    {
        string dis, text2;
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.BaudRate = 9600;
            serialPort1.Parity = Parity.None;
            serialPort1.DataBits = 8;
            serialPort1.StopBits = StopBits.One;
            button1.Enabled = false;
            button2.Enabled = false;
            button3.Enabled = false;
            comboBox1.Items.AddRange(SerialPort.GetPortNames());
            label1.Text = "PC狀態:尚未連線";
        }
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            serialPort1.PortName = comboBox1.Text;
            serialPort1.Open();
            comboBox1.Enabled = false;
            button1.Enabled = true;
            button2.Enabled = true;
            button3.Enabled = true;
            timer1.Enabled = true;
            label1.Text = "PC狀態:連線中";
        }
        private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Write("0");           
            comboBox1.Enabled =true;
            button1.Enabled = false;
            button2.Enabled = false;
            button3.Enabled = false;
            timer1.Enabled = false;
            label1.Text = "PC狀態:斷線中";
            label2.Text = "Arduino回傳:";
            serialPort1.Close();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Write("1");
            button3.Enabled = true;
            button2.Enabled = false;
            label1.Text = "送出指令:LED ON";
        }
        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Write("0");
            button2.Enabled = true;
            button3.Enabled = false;
            label1.Text = "送出指令:LED OFF";
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            label2.Text = text2;
        }
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            dis = serialPort1.ReadLine();
            if (dis.IndexOf('C') == 0)
                text2 = "Arduino回傳:" + dis;
            else
                text2 = "wrong";
        }
    }
}

Arduino
這裡不用 Arduino 內建的 Ping 範例,而是使用 HC-SR04 Ultrasonic Sensor Library
這個 library把測距的公式都包成了函式庫,較方便使用
使用時必須先將下載的壓縮檔解壓縮
將 HCSR04Ultrasonic整個檔案夾複製到Arduino的libraries

#include <Ultrasonic.h>
#define TRIGGER_PIN  11
#define ECHO_PIN     12
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN);
String dis;
void setup() {
   Serial.begin(9600);     // 開啟 Serial port, 通訊速率為 9600 bps
   // 初始化 LED 接腳
   pinMode(13, OUTPUT);
}      
void loop() {
   // 檢查是否有資料可供讀取
   if (Serial.available() > 0) {
     char inByte = Serial.read();
     switch (inByte) {
     case '0':   
       digitalWrite(13, LOW);
       break;
     case '1':
       digitalWrite(13, HIGH);
       break;
     default:
       digitalWrite(13, LOW);
     }    
   }
   else{
     distance();
   }  
}
void distance()
{
  float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); // 計算距離,單位: 公分
  dis=String(cmMsec);
  Serial.println("CM:"+dis);
  delay(50);
}

結果

上述的作法有一些問題存在
C#的計時器用來每隔一段固定時間顯示label2.Text
即表單上變更顯示Arduino回傳字串的時間間隔是由C#的計時器來決定
並非是串列埠收到data即變更顯示label2.Text
另外 當按下斷線按鈕時 很可能 serialPort1_DataReceived還在執行
(??不確定 但的確出現當掉的狀況)

因此變更作法
不再使用計時器固定時間變更顯示label2.Text
直接當串列埠收到資料時 即變更顯示label2.Text
但是 在serialPort1_DataReceived中採用透過 delegate 及 Invoke 來執行 addData()
這是因為 Windows Forms 是 Multi-threading 的機制
如果不這麼寫,直接在 serialPort1_DataReceived 把資料給label2
會遇到「跨執行緒作業無效」的錯誤
另外將計時器的角色做修改
利用 test2作為判斷 當test2=1時 addData()可執行
test2=0 則否
當按下斷線按鈕時 令test2=0 且啟動計時器
此時  addData()便不再執行
直到計時器時間到 再執行斷線serialPort1.Close();

結果
(1)當C#收到data即變更顯示
(2)解決按下斷線按鈕時出現當掉的狀況

修正後程式碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;


namespace _0150531
{
    public partial class Form1 : Form
    {
        int test = 1;
        string dis, text2;
        public delegate void AddDataDelegate();
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            serialPort1.BaudRate = 9600;
            serialPort1.Parity = Parity.None;
            serialPort1.DataBits = 8;
            serialPort1.StopBits = StopBits.One;
            button1.Enabled = false;
            button2.Enabled = false;
            button3.Enabled = false;
            comboBox1.Items.AddRange(SerialPort.GetPortNames());
            label1.Text = "PC狀態:尚未連線";
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            test = 1;
            serialPort1.PortName = comboBox1.Text;
            serialPort1.Open();
            comboBox1.Enabled = false;
            button1.Enabled = true;
            button2.Enabled = true;
            button3.Enabled = true;
            label1.Text = "PC狀態:連線中";
        }

        private void button1_Click(object sender, EventArgs e)
        {
                serialPort1.Write("0");
                comboBox1.Enabled = true;
                button1.Enabled = false;
                button2.Enabled = false;
                button3.Enabled = false;
                timer1.Enabled = true;
                test = 0;               
        }

        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Write("1");
            button3.Enabled = true;
            button2.Enabled = false;
            label1.Text = "送出指令:LED ON";
        }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Write("0");
            button2.Enabled = true;
            button3.Enabled = false;
            label1.Text = "送出指令:LED OFF";
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            serialPort1.Close();
            timer1.Enabled = false;
            label1.Text = "PC狀態:斷線中";
            label2.Text = "Arduino回傳:";
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (test==1)
                this.Invoke(new AddDataDelegate(addData));           
        }
        private void addData()
        {
            dis = serialPort1.ReadLine();
            if (dis.IndexOf('C') == 0)
                text2 = "Arduino回傳:" + dis;
            else
                text2 = "wrong";
            label2.Text = text2;
        }
    }
}

Arduino另一個程式
 #define trigPin  11
 #define echoPin  12

 float echotime, distance;
float obs_dis()
{
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(15);
  digitalWrite(trigPin, LOW);
  echotime=pulseIn(echoPin, HIGH);
  distance=echotime/2/29.1; 
}


 String dis;
 void setup() {
    Serial.begin(9600);     // 開啟 Serial port, 通訊速率為 9600 bps
    // 初始化 LED 接腳
   pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
   pinMode(13, OUTPUT);
 }      
 void loop() {
    // 檢查是否有資料可供讀取
   if (Serial.available() > 0) {
      char inByte = Serial.read();
      switch (inByte) {
      case '0':   
        digitalWrite(13, LOW);
        break;
      case '1':
        digitalWrite(13, HIGH);
        break;
      default:
        digitalWrite(13, LOW);
      }    
    }
    else{
      obs_dis();
      dis=String(distance);
   Serial.println("CM:"+dis);
   delay(50);
    }  
 }

蛙式運動車機構模擬(2006?)

2006(或2005?)的學生專題作品
利用SolidWorks畫出元件並組合
再以visual Nastran Desktop進行機構模擬
作的蠻好的,不過沒有完全成功
下坡模擬還OK,平地和上坡就做模擬不出來
visual Nastran Desktop作機構模擬只能假設成剛體碰撞
實際上輪子和地面接觸不會是剛體接觸
實際地面給輪子的作用力可能是一個重要模擬因素
其實我們也可做一些人工的假設條件,讓平地和上坡模擬可以成功
不過加入這種難以確認是否有意義的人工條件
就算讓模擬成功,也只是騙騙外行人
所以,最後就只做下坡模擬

機構爆炸圖
模擬結果