Arduino入门教程29-调光面板
在这个项目中,我们将探索Processing与Arduino的联合编程魅力,通过简单的界面交互实现创意的RGB灯光控制。想象一下,只需轻点Processing界面上的按钮,就能远程操控Arduino板上连接的RGB LED灯打开和关闭。这不仅是一次编程技能的实践,更是将数字创意融入日常生活的有趣尝试。让我们一起动手,用代码点亮生活的色彩吧!元件清单
硬件连接按照下图进行硬件连接,RGB LED的引脚图请参考项目【炫彩LED】或【彩灯调光台】。
图 1 调光面板连线图
为了实现电脑上的Processing面板对Arduino控制的RGB炫彩灯进行颜色控制,首先需要确保安装了必要的软件。下面是Processing的详细安装步骤(由于版本更新等原因,以下步骤仅供参考)。
访问Processing的官方网站 https://processing.org/download
根据您的操作系统(Windows, macOS, Linux)选择合适的安装包进行下载。(以下安装步骤以windows为例)
(如果你是用的其他系统的计算机,请参考https://processing.org/tutorials/gettingstarted)
下载完成后,按照安装向导完成安装过程
将下载的文件解压缩
双击解压缩文件中的processing.exe文件以运行processing。
如果一切顺利,现在将可以看到主要的Processing窗口。每个人的设置都不同,因此,如果程序没有启动,或者你遇到了其他问题,请访问https://github.com/benfry/processing4/wiki/Troubleshooting页面查找可能的解决方案。
只需点击“Get Started”即可进入processing编程界面。
编写你的第一个Processing程序
你现在正在运行Processing开发环境(PDE)。界面功能如下所示:
在文本编辑器中,输入以下内容:ellipse(50, 50, 80, 80);
这行代码的意思是“绘制一个椭圆,其中心距离左边50像素,距离顶部50像素,宽度和高度均为80像素。”点击工具栏上的运行按钮(三角形按钮)。
如果你输入的所有内容都是正确的,那么你会在屏幕上看到一个圆。
如果你没有正确输入,消息区域会变成红色,并显示错误信息。
如果发生这种情况,请确保你已完全复制了示例代码:数字应包含在括号内,并且每个数字之间用逗号隔开,行尾应有一个分号。
简单了解Processing软件的使用规则后,你就可以参考下方的程序代码实现其与Arduino的互动效果啦!
示例代码Processing 样例代码:// 项目 - 调光面板
import processing.serial.*; // 导入串口通信库
Serial myPort; // 创建串口对象
int circleX, circleY; // 按钮的位置
int circleSize = 100; // 按钮的直径
color currentColor, baseOffColor, baseOnColor; // 颜色变量
color circleColor; // 颜色变量
color circleHighlight; // 颜色变量
boolean circleOver = false; // 判断鼠标是否在按钮上
PFont f; // 字体类型
void setup() {
size(600, 400); // 设置屏幕大小
background(200); // 背景颜色
circleColor = color(255, 30, 30); // 设置按钮原本颜色变量
circleHighlight = color(255, 100, 100); // 设置按钮高亮颜色变量
circleX = width / 4 * 2; // 设置按钮的X坐标
circleY = height / 2; // 设置按钮的Y坐标
printArray(PFont.list()); // 打印计算机上的字体列表
f = createFont("Ebrima Bold", 20); // 设置字体
textFont(f); // 应用字体
String portName = "COM3"; // 输入你的COM端口
myPort = new Serial(this, portName, 9600); // 选择第一个端口
print(portName); // 打印端口名
}
void draw() {
update(mouseX, mouseY); // 调用更新方法
if (circleOver) {
fill(circleHighlight); // 鼠标在按钮上时填充高亮颜色
} else {
fill(circleColor); // 鼠标不在按钮上时填充正常颜色
}
circle(circleX, circleY, circleSize); // 绘制圆形按钮
stroke(255); // 边框颜色
fill(140, 25, 25); // 文本颜色
textAlign(CENTER); // 文本对齐方式
text("RED", width / 4 * 2, height / 2 + 10); // 显示文本
}
void update(int x, int y) {
if (circleOver(circleX, circleY, circleSize)) {
circleOver = true; // 鼠标在按钮上
} else {
circleOver = false; // 鼠标不在按钮上
}
}
boolean circleOver(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter / 2) {
return true; // 鼠标在按钮上
} else {
return false; // 鼠标不在按钮上
}
}
int clicknumber; // 点击次数
void mousePressed() {
if (circleOver) {
clicknumber = clicknumber + 1;
if (clicknumber % 2 == 1) {
print("RedON"); // 打印信息"RedOn"
myPort.write('1'); // 发送值1
background(200); // 背景颜色
} else {
myPort.write('2'); // 发送值2
print("RedOff"); // 打印信息"RedOff"
background(50); // 背景颜色
}
}
}
Arduino IDE 样例代码:// 项目 - 调光面板
int redPin;
void setup() {
Serial.begin(9600); // 开启串口通信
redPin = 9;
pinMode(redPin, OUTPUT); // 设置Arduino引脚为输出
}
void loop() {
if (Serial.available() > 0) { // 检查串口是否有数据
char led = Serial.read(); // 读取串口数据
if (led == '1') { // 检查串口读取的数据
digitalWrite(redPin, HIGH); // 红灯亮
} else if (led == '2') { // 检查串口读取的数据
digitalWrite(redPin, LOW); // 红灯灭
}
}
}
代码回顾Arduino IDE与Processing的交互主要通过串口通信(Serial Communication)实现,使得Arduino可以控制硬件设备(如RGB LED)并将数据发送到计算机,而Processing则能接收这些数据并进行可视化处理或发送控制指令给Arduino。
Arduino通过接收到的指令不同,执行对应的操作。
虽然在代码示例部分Processing代码和Arduino代码是两组独立的代码程序。但两组代码不是完全割裂的,而是相互配合来运行和使用的。所以在下方的代码讲解过程中,虽然为了代码讲解的连续和完整性,不会把两个程序穿插进行讲解。但请将两组代码对照着理解,这有助于你更好的理解代码的逻辑原理。
Processing程序代码回顾
在setup()函数前,导入库和变量定义 import processing.serial.*;
Serial myPort;
int circleX, circleY;
int circleSize = 100;
color currentColor, baseColor;
color circlecolor;
color circleHighligh;
boolean circleOver = false;
PFont f;
这一部分导入了必要的库,定义了按钮的位置、大小、颜色,以及用于串行通信的Serial对象。同时,定义了字体和颜色变量。 在setup()函数中: size(600, 400);
circleColor = color(255, 100, 100);
circleHighlight = color(200, 50, 50);
baseColor = color(200);
currentColor = baseColor;
circleX = width / 4 * 2;
circleY = height / 2;
printArray(PFont.list());
f = createFont("Ebrima Bold", 20);
textFont(f);
String portName = "COM3";
myPort = new Serial(this, portName, 9600);
print(portName);
在setup()函数中,设置了屏幕大小、按钮位置、颜色和字体。
很重要的是建立了与Arduino的串口通信连接,使用String portName = "COM3";输入Arduino连接的设备端口号,并初始化了串行通信。 draw()函数用于在屏幕上绘制所有元素: update(mouseX, mouseY);
用于更新鼠标位置,update()函数用于判断鼠标是否停留在按钮上。
if (circleOver) {
fill(circleHighlight);
} else {
fill(circleColor);
}
用if-else进行判断来更新按钮颜色,当鼠标停留在按钮区域显示高亮颜色;否则显示按钮原本颜色。
circle(circleX, circleY, circleSize);
stroke(255);
fill(140, 25, 25);
textAlign(CENTER);
text("RED", width / 4 * 2, height / 2 + 10);
使用circle(x, y, d)函数绘制圆形(配合对应函数做按钮使用),其中x和y是圆形中心的位置,d对应的是圆形的直径。并绘制该圆形的边框,文本内容颜色和位置。
update()函数根据鼠标的当前位置(x, y)更新每个按钮的悬停状态。 void update(int x, int y) {
if (circleOver(circleX, circleY, circleSize)) {
circleOver = true; // 鼠标在按钮上
} else {
circleOver = false; // 鼠标不在按钮上
}
}
这里虽然名为update,但它实际上是draw()函数中调用的一个函数,用于更新悬停状态,并不直接绘制任何内容。该函数中circleOver(circleX, circleY, circleSize)为update()函数的一个辅助方法,用于判断鼠标是否停在按钮圆形区域内。
boolean circleOver(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter / 2) {
return true; // 鼠标在按钮上
} else {
return false; // 鼠标不在按钮上
}
}
这些辅助方法用于判断鼠标是否悬停在特定的圆形按钮上。
disX和disY是鼠标现在位置与按钮圆心横坐标和纵坐标的差值(这个差值有可能为正有可能为负,后续只使用该差值的平方值,所以正负无影响)。利用勾股定理a²+b²=c²,使用sqrt(sq(disX) + sq(disY))计算得出鼠标位置与按钮中心的距离,如果距离小于按钮半径,则返回true,表示鼠标悬停在该按钮上。否则返回false,表示鼠标悬停在按钮之外的位置。
最后,mousePressed()函数属于processing内置的事件处理函数,在用户点击鼠标时调用。
void mousePressed() {
if (circleOver) {
clicknumber = clicknumber + 1;
if (clicknumber % 2 == 1) {
print("RedON");
myPort.write('1');
background(200);
} else {
myPort.write('2');
print("RedOff");
background(50);
}
}
}
当用户点击鼠标时鼠标在mousePressed()函数内进行判断,当点击发生在圆形按钮内,则按下按钮次数clicknumber加1。接着对按下总次数进行判断,如果按下次数为奇数,向Arduino发送数字“1”,否则按下次数为偶数,向Arduino发送数字“2”。并在控制台输出对应的开关信息。
Processing程序不直接控制RGB LED的高低电平,而是通过发送数字信号给Arduino。Arduino根据接收到的数字信号,向RGB LED输出相应的高低电平,以控制其颜色和亮度。这样,Processing与Arduino协同工作,实现了对RGB LED的间接控制。
Arduino程序代码回顾在loop()函数中,if (Serial.available() > 0)检查串口是否有新的数据可读。如果有,就执行大括号内的代码。
if (Serial.available() > 0) {
}
在if执行块内,先将Processing发送的数字赋值给字符串型变量led,接下来的两个if语句检查读取的数据led。如果为'1',则通过digitalWrite(redPin, HIGH);打开LED;如果为‘2',则通过digitalWrite(redPin, LOW);关闭LED。
char led = Serial.read();
if (led == '1') { // 检查串口读取的数据
digitalWrite(redPin, HIGH); // 红灯亮
} else if (led == '2') { // 检查串口读取的数据
digitalWrite(redPin, LOW); // 红灯灭
}
课后练习使用多个按钮实现RGB LED的光线明暗度的调节,或者颜色的变化。发挥你的想象力,制作一个功能强大的调光面板,实现更绚丽多彩的灯光效果吧!(本项目附件程序中有多个按钮版本的程序供您参考)
附件下载:
页:
[1]