04藍芽傳送Slider數值來控制 Arduino LED 漸明漸暗

參考「[雙A計劃] Part2:App Inventor 經由藍牙控制 Arduino LED 漸明漸暗」

註:這一部份可以不用看,直接看第二種方法!

App inventor端的程式

Arduino 端的程式

#include <SoftwareSerial.h>#include <Wire.h>//引用二個函式庫SoftwareSerial及Wire SoftwareSerial I2CBT(2,3);//定義PIN10及PIN11分別為RX及TX腳位 byte cmmd[20];int insize, a;void setup() { Serial.begin(9600); //Arduino起始鮑率:9600 I2CBT.begin(9600); //藍牙鮑率:57600(注意!鮑率每個藍牙晶片不一定相同,請務必確認 pinMode(9, OUTPUT); //請注意您使用的Arduino 該腳位是否支援 PWM (會有~符號),否則會看不到效果 }

void loop() {while(1){//讀取藍牙訊息 if ((insize=(I2CBT.available()))>0){ Serial.print("input size = "); Serial.println(insize);for (int i=0; i<insize; i++){ Serial.print(cmmd[i]=char(I2CBT.read())); Serial.print(" ");}//此段請參考上一篇解釋 }if(insize==4){ //不懂 a = (cmmd[0]-48)*10; a=a+(cmmd[1]-48);}if(insize==3){ a=(cmmd[0]-48);} Serial.println(a); //a值一直傳出到serial monitor顯示,導致arduino板的TX燈一直亮著analogWrite(9,map(a,0,80,0,255)); //使用 a 變數控制 LED 亮度 } //while }

//用法 map(val, 0, 1023, 0, 179); // 把 0 - 1023 的數值按比例縮放為 0 - 180 的數值

以上測試起來都怪怪的

-------------------------------------------

第二種方法:參考App Inventor, Bluetooth and Arduino Part 3; Android Slider controls LED brightness

For use in controlling an LED, try setting Minimum 0, Maximum 255 and initial setting 100.

We should also make the Slider wider - I set it to 250 Pixels wide.

However there are 2 serious problems with this simple approach:

1.The thumbPosition property is a floating point number which is sometimes displayed to several decimal places - an integer value will be fine!

2.As Slider1 is moved, updates occur very rapidly; this has the potential to overflow the Arduino input buffer.

What we need is a code Block which will set a Flag and capture the current value of thumbPosition :

when Slider1.PositionChanged

{

set myFlag = TRUE;

set myValue = Slider1.thumbPosition;

}

This should be followed by a second code Block which will be executed each time a Timer or Clock ticks:

when Clock1.Timer

{

do

{

if (myFlag)

{

set Label1.Text = myValue;

set myFlag = FALSE;

}

}

}

程式有改變的地方如下:

This is simply a matter of adding a component to the Clock Block to send out the value of myValue as a 1 Byte number (maximum unsigned value 255)

round :回傳指定數字四捨五入到整數位的運算結果

Arduino 端的程式

更簡單易懂

#include <SoftwareSerial.h>

SoftwareSerial BT(2,3);//定義PIN2及PIN3分別為RX及TX腳位

int ledPin = 9; // Needs to be a pin supporting PWM

int value = -1;void setup() { Serial.begin(9600); //Arduino起始鮑率:9600 BT.begin(9600); //藍牙鮑率:9600(注意!鮑率每個藍牙晶片不一定相同,請務必確認 pinMode(ledPin, OUTPUT); //請注意您使用的Arduino 該腳位是否支援 PWM (會有~符號),否則會看不到效果 }

void loop()

{

while (BT.available()) // Read while there is data in the buffer

{

value = BT.read();

if (value >= 0) //If we have meaningful data

{

Serial.println(value); // Debug - double check it make sense?

analogWrite(ledPin,value); // set PWM for LED brightness

value = -1;

}

}

}

此方法測試成功!!!

--------------------------------------

方法三:APP Inventor 2 藍芽傳送Slider數值至Arduino

此處仍然使用readString()來讀取字串

存放在myString

其資料型態是String

處理方法(一)

以c_str()將他轉成char[]

將它複製到newString[]

最後以atoi轉成int

while (I2CBT.available()) {

myString=I2CBT.readString();

strcpy(newString,myString.c_str());

inSlider=atoi(newString);

方法(二)

直接使用Arduino的toInt()

將String轉整數

while (I2CBT.available()) {

myString=I2CBT.readString();

inSlider=myString.toInt();

為何不在App inventor就直接用成INT??測試成功!

此寫法,如果同時要使用2個SLIDER,要如何寫?

Arduino程式同上方法2的寫法

-------------------

測試用兩條Slider來控制兩燈

#include <SoftwareSerial.h>

SoftwareSerial BT(0,1);//定義PIN2及PIN3分別為RX及TX腳位

int ledPin1 = 10; // Needs to be a pin supporting PWM

int ledPin2 = 11; // Needs to be a pin supporting PWM

String mystring,val; //設了二個字串

int value = -1;

void setup() {

Serial.begin(9600); //Arduino起始鮑率:9600

BT.begin(9600); //藍牙鮑率:9600(注意!鮑率每個藍牙晶片不一定相同,請務必確認

pinMode(ledPin1, OUTPUT); //請注意您使用的Arduino 該腳位是否支援 PWM (會有~符號)

pinMode(ledPin2, OUTPUT); //請注意您使用的Arduino 該腳位是否支援 PWM (會有~符號)

Serial.println("Hello"); //測試用

}

void loop()

{

while (BT.available()) // Read while there is data in the buffer

{

mystring = BT.readString();

val=mystring.substring(0,1); //取字串的第一個字

value=mystring.substring(1).toInt(); //取字串的第2個字以後的字,並再轉成整數

if (value >= 0) //If we have meaningful data

{

if (val=="A"){ //第一個slider , "字串"(string用雙引號)、 '字元'(char用單雙引號)

analogWrite(ledPin1,value); // set PWM for LED brightness

value = -1;

}

if (val=="B"){ //第二個slider

analogWrite(ledPin2,value); // set PWM for LED brightness

value = -1;

}

} //if

} //while

}

反應的速度比較慢