說明:
(1)使用serialPort,
(2)使用二個GroupBox,分別各含三個RadioButton,依序代表"1"、"0"、"2",用以傳送至Arduino控制pin13 LED、pin 9LED
(3)使用二個trackBar,其對應數值傳送至Arduino控制pin13 LED閃爍速度、pin 9LED的亮度
(4)將欲傳送之字串與數值組成字串,並以逗點分開。例如13thLED選擇Blink、9thLED選擇ON(調光),二個trackBar的數值分別為100、23,組成字串"2,2,100,23,"
(5)Arduino接收字串後,將字串分開成"2"、"2"、"100"和"23"四個字串,再分別轉成整數
(6)採用計時器,當RadioBox被點選或trackBar被捲動,啟動計時器,計時時間到傳送字串,並關閉計時器。計時器之功能在此主要作為delay使用,避免trackBar被捲動傳送資料太快,Arduino端接收字串太慢,會導致接收到2組甚至3組字串
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 _0150525
{
public partial class Form1 : Form
{
string LED13 = "0";
string LED9 = "0";
int LED13_delay = 100;
int LED9_bright = 0;
string send;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
serialPort1.PortName = "COM18";
serialPort1.BaudRate = 9600;
serialPort1.Parity = Parity.None;
serialPort1.DataBits = 8;
serialPort1.StopBits = StopBits.One;
groupBox1.Enabled = false;
groupBox2.Enabled = false;
trackBar1.Enabled = false;
trackBar2.Enabled = false;
button2.Enabled = false;
}
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Open();
groupBox1.Enabled = true;
groupBox2.Enabled = true;
trackBar1.Enabled = false;
trackBar2.Enabled = false;
button1.Enabled = false;
button2.Enabled = true;
timer1.Enabled = true;
}
private void radioButton1_Click(object sender, EventArgs e)
{
LED13 = "1";
trackBar1.Enabled = false;
timer1.Enabled = true;
}
private void radioButton2_Click(object sender, EventArgs e)
{
LED13 = "0";
trackBar1.Enabled = false;
timer1.Enabled = true;
}
private void radioButton3_Click(object sender, EventArgs e)
{
LED13 = "2";
trackBar1.Enabled = true;
timer1.Enabled = true;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
LED13_delay = trackBar1.Value;
timer1.Enabled = true;
}
private void radioButton4_Click(object sender, EventArgs e)
{
LED9 = "1";
trackBar2.Enabled = false;
timer1.Enabled = true;
}
private void radioButton5_Click(object sender, EventArgs e)
{
LED9 = "0";
trackBar2.Enabled = false;
timer1.Enabled = true;
}
private void radioButton6_Click(object sender, EventArgs e)
{
LED9 = "2";
trackBar2.Enabled = true;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = LED13;
label2.Text = LED9;
label3.Text = LED13_delay.ToString();
label4.Text = LED9_bright.ToString();
send = label1.Text + "," + label2.Text + "," + label3.Text + "," + label4.Text + ",";
label5.Text = "傳送字串: " + send;
serialPort1.Write(send);
timer1.Enabled = false;
}
private void trackBar2_Scroll(object sender, EventArgs e)
{
LED9_bright = trackBar2.Value;
timer1.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
send = "0,0,100,0";
serialPort1.Write(send);
serialPort1.Close();
groupBox1.Enabled = false;
groupBox2.Enabled = false;
trackBar1.Enabled = false;
trackBar2.Enabled = false;
button2.Enabled = false;
button1.Enabled = true;
}
}
}
Arduino程式碼
int inSlider1=100;
int inSlider2=0;
int Position1,Position2,Position3,Position4;
int R1,R2;
String myString,tempString;
void setup() {
Serial.begin(9600); //Arduino起始鮑率:9600
Serial.setTimeout(10);
pinMode(13,OUTPUT);
pinMode(9,OUTPUT);
}
void loop() {
// 檢查是否有資料可供讀取
Serial.flush();
while (Serial.available()) {
myString=Serial.readString();
split();
if (R1 !=2)
{
digitalWrite(13,R1);
}
else
{
digitalWrite(13,1);
delay(inSlider1);
digitalWrite(13,0);
delay(inSlider1);
}
if (R2 !=2)
{
digitalWrite(9,R2);
}
else
{
analogWrite(9,inSlider2);
}
}
}
void split(){
Position1=myString.indexOf(',');
Position2=myString.indexOf(',',Position1+1);
Position3=myString.indexOf(',',Position2+1);
Position4=myString.indexOf(',',Position3+1);
tempString=myString.substring(0,Position1);
R1=tempString.toInt();
tempString=myString.substring(Position1+1,Position2);
R2=tempString.toInt();
tempString=myString.substring(Position2+1,Position3);
inSlider1=tempString.toInt();
tempString=myString.substring(Position3+1,Position4);
inSlider2=tempString.toInt();
}
說明
(1)為了避免暫存器中有多組資料,使用Serial.flush();清空暫存器
(2)參考藍芽傳送字串,此處仍然使用readString()來讀取字串,存放在myString,其資料型態是String
(3)split()用來分離字串,在split()中,採用indexOf()來找出逗點的位置,indexOf()是Arduino中String class的函數
(4)Position1=myString.indexOf(',');找出第一個逗點的位置並存放在Position1。(註:位置編號是由0開始,即第一個字元是0,第二個字元是1.....)
Position2=myString.indexOf(',',Position1+1);找出第二個逗點的位置並存放在Position2,依此類推
(4)tempString=myString.substring(0,Position1);利用substring()分離出第一個逗點前的字串,並暫時存放tempString,此資料型態為String
(5)利用toInt()將字串轉為整數,toInt()是Arduino中String class的函數
結果
問題:
(1)13thLED的閃爍不固定
(2)當13thLED閃爍時,控制有lag現象
原因:
(1)使用while (Serial.available()),當尚未有新資料進來時,LED13不會改變,錯誤寫法
(2)Arduino端採用delay形成LED閃爍,當delay()在計時程式停在此處,無法多工
修改如下:
(1)將while改成if,當尚未有新資料進來時,LED13可持續狀態或閃爍
(2)採用millis()擷取時間,利用時間來判斷LED13在閃爍時,應亮或暗
程式碼
int inSlider1=100;
int inSlider2=0;
int Position1,Position2,Position3,Position4;
int R1,R2, R1_last;
int LED13_prev=0;
long time_cur,time_prev;
String myString,tempString;
void setup() {
Serial.begin(9600); //Arduino起始鮑率:9600
Serial.setTimeout(10);
pinMode(13,OUTPUT);
pinMode(9,OUTPUT);
}
void loop() {
// 檢查是否有資料可供讀取
//Serial.flush();
if (Serial.available()) {
myString=Serial.readString();
split();
if (R1 !=2)
digitalWrite(13,R1);
else
{
if (R1_last != R1)
{
digitalWrite(13,LED13_prev);
time_prev=millis();
}
else
blink_13();
}
R1_last=R1;
if (R2 !=2)
digitalWrite(9,R2);
else
analogWrite(9,inSlider2);
}
else
{
if (R1 ==2)
blink_13();
}
}
void split(){
Position1=myString.indexOf(',');
Position2=myString.indexOf(',',Position1+1);
Position3=myString.indexOf(',',Position2+1);
Position4=myString.indexOf(',',Position3+1);
tempString=myString.substring(0,Position1);
R1=tempString.toInt();
tempString=myString.substring(Position1+1,Position2);
R2=tempString.toInt();
tempString=myString.substring(Position2+1,Position3);
inSlider1=tempString.toInt();
tempString=myString.substring(Position3+1,Position4);
inSlider2=tempString.toInt();
}
void blink_13(){
time_cur=millis();
if (time_cur - time_prev > inSlider1)
{
if (LED13_prev == 0)
LED13_prev=1;
else
LED13_prev=0;
digitalWrite(13,LED13_prev);
time_prev=time_cur;
}
}
int inSlider2=0;
int Position1,Position2,Position3,Position4;
int R1,R2, R1_last;
int LED13_prev=0;
long time_cur,time_prev;
String myString,tempString;
void setup() {
Serial.begin(9600); //Arduino起始鮑率:9600
Serial.setTimeout(10);
pinMode(13,OUTPUT);
pinMode(9,OUTPUT);
}
void loop() {
// 檢查是否有資料可供讀取
//Serial.flush();
if (Serial.available()) {
myString=Serial.readString();
split();
if (R1 !=2)
digitalWrite(13,R1);
else
{
if (R1_last != R1)
{
digitalWrite(13,LED13_prev);
time_prev=millis();
}
else
blink_13();
}
R1_last=R1;
if (R2 !=2)
digitalWrite(9,R2);
else
analogWrite(9,inSlider2);
}
else
{
if (R1 ==2)
blink_13();
}
}
void split(){
Position1=myString.indexOf(',');
Position2=myString.indexOf(',',Position1+1);
Position3=myString.indexOf(',',Position2+1);
Position4=myString.indexOf(',',Position3+1);
tempString=myString.substring(0,Position1);
R1=tempString.toInt();
tempString=myString.substring(Position1+1,Position2);
R2=tempString.toInt();
tempString=myString.substring(Position2+1,Position3);
inSlider1=tempString.toInt();
tempString=myString.substring(Position3+1,Position4);
inSlider2=tempString.toInt();
}
void blink_13(){
time_cur=millis();
if (time_cur - time_prev > inSlider1)
{
if (LED13_prev == 0)
LED13_prev=1;
else
LED13_prev=0;
digitalWrite(13,LED13_prev);
time_prev=time_cur;
}
}
結果:
大幅改善,但C#的計時器時間不可設太小,當設太小時(例如5),trackBar2滑動時(即LED9調光),傳送資料太頻繁,會使得LED13閃爍受到干擾,設成50 OK
另外Serial.flush()可不使用
沒有留言:
張貼留言