ArduinoUno全彩呼吸灯三⾊LED灯串⼝控制⾼刷新率渐变实例
20210512更新串⼝。。。
点灯就是单⽚机界的hello world。说起点灯,我就会想三国⾥董卓被肚脐眼放灯芯燃烧脂肪,俗称点天灯。。。。。。。
正常的例⼦,这位朋友
现在我们想⽤串⼝控制三⾊灯的颜⾊。正好试下Arduino IDE 2.0  ⾃带代码补全。如果不能⾃动补全或者出现代码提⽰,先下载好core库。有时候需要保存下程序然后再重启下ide
第⼀个问题,串⼝⼀次只能传递⼀组数据,⽽三⾊灯亮需要三⾊参数,就需要把串⼝传递的参数按rgb拆成三个。(相当于⾃制⼀个通信协议)。我这⾥⽤r,g,b;这样的形式传递⼀个字符串表⽰rgb值,例如:“255,255,0;”  表⽰红255绿255蓝0.
太长不看直接复制粘贴代码版:
//良好习惯之代码⾥不要出现让⼈⽆法理解的魔法数字
int redPin = 11;
int greenPin = 10;
int bluePin = 9;
unsigned int red = 10;
unsigned int green = 10;
unsigned int blue = 10;
//颜⾊控制函数
void color(unsigned int red,unsigned int green,unsigned int blue){
analogWrite(redPin, 255- red);
analogWrite(bluePin, 255- blue);
analogWrite(greenPin, 255- green);
}
void setup() {
// put your setup code here, to run once:
pinMode(redPin,OUTPUT);
pinMode(greenPin,OUTPUT);
pinMode(bluePin,OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if(Serial.available()>0) {
delay(50);//  延时以确保完全接受串⼝数据,可以提⾼波特率,减⼩延时时间实现更⾼速响应
// Serial.adStringUntil(stopChar));
// Serial.adStringUntil(stopChar));
// Serial.adStringUntil(stopChar));
//adStringUntil可以⽴刻读取缓冲区数据。
red  = adStringUntil(',').toInt();//注意这⾥是单引号表⽰char类型,⽤作函数的读取终⽌符号,不能⽤双引号,那是字符串
green  = adStringUntil(',').toInt();//
  adStringUntil(',')读取多少字符就会⾃动清理多少缓冲区⾥的数据
   blue = adStringUntil(';').toInt();
   ad()>= 0){}//清空串⼝缓冲区,避免意外多余数据⼲扰运⾏
digitalWrite(LED_BUILTIN, HIGH); //这⾥⽤⾃带的脚13灯看程序是否运⾏
color(red, green, blue);
delay(5);
}
实际效果,⽤串⼝调试助⼿发送  255,0,0;三⾊灯⽴刻变红。
为什么这么写的原因(踩坑例程):⼀开始作为⽤惯了appinvnentor保姆式⽂本函数的⼈,此刻想起了被C语⾔字符数组指针⽀配的恐惧
(艹⽫艹)
第⼀步,⽤adSring()读取⼀个字符串
if(Serial.available()>0) {
delay(200);//  延时以确保完全接受串⼝数据
arduino字符串转数组rgb  = adString();
下⼀步是⽤符号分解字符串,作为懒⼈,在ide⾥搜索StringSplitt,还真有现成的(本来想⽤json,发现cJSON有点费内存)。
代码⽰范
StringSplitter *splitter = new StringSplitter(rgb, ',', 3);//c++中⽤new创建的对象返回的都是指针
red = splitter->getItemAtIndex(0);//⽤指针调⽤⽅法需要⽤->,new创建的对象不是⽤“*”或“.”来访问该对象的成员函数的
green = splitter->getItemAtIndex(1);
blue = splitter->getItemAtIndex(2);
实际效果,输⼊“255,0,0,”,灯等了⼀秒才变红,⽽且不⼀会程序就跑飞了(放飞⾃我)。
先说这个跑飞问题,单⽚机内存(RAM)很⼩,uno R3的atm328就2K(sram,静态内存,⽐dram快且不⽤刷新充电)。我把new对象写在loop()⽆限循环函数⾥,这⼀会就爆内存了(C++语⾔没有⾃动内存垃圾清理),所以需要添加⼀句    delete splitter释放内存
⾄于为啥会等⼀秒才变⾊,这是adString()的特点,解释来了
既然遇到终⽌符号后就返回数据了,那直接就有了分割字符串的办法了,那也不⽤⿇烦的调⽤⽹友的库了。于是有了最上边的代码。
只⽤⿊不溜秋的串⼝调试助⼿该颜⾊多不sexy,这⾥⽤wx ai2  做⼀个⼿机控制程序,基于wx  ai2⾥的串⼝调试例⼦,这⾥先感谢下原作者。加⼊如下代码块
测试如果在⽔平滑动条事件⾥直接发送数据,会导致发送过于频繁,单⽚机串⼝数据还没接受完就⼜收到数据,导致灯的变⾊过程不正常。可以把串⼝波特率改⾼缓解这种情况。这⾥只⽤了个定时程序固定时间刷新颜⾊,避免数据发送太频繁。实测可以不那么丝滑的变⾊。
终极更新,⽤串⼝事件来处理点灯,实测可以扛得住⾮常快速的发送数据.然后⼿机端终于可以⽤滑动条改变事件了,实测完全看不出来变⾊间隔
int redPin = 11;
int greenPin = 10;
int bluePin = 9;
unsigned int red = 10;
unsigned int green = 10;
unsigned int blue = 10;
//颜⾊控制函数
void color(unsigned int red,unsigned int green,unsigned int blue){  analogWrite(redPin, 255- red);
analogWrite(bluePin, 255- blue);
analogWrite(greenPin, 255- green);
}
void setup() {
// put your setup code here, to run once:
pinMode(redPin,OUTPUT);
pinMode(greenPin,OUTPUT);
pinMode(bluePin,OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
}
void serialEvent()
{ if (Serial.available() > 0)
  { red = adStringUntil(',').toInt();
  green = adStringUntil(',').toInt();
  blue = adStringUntil(';').toInt();
  color(red, green, blue);
  }
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。