在这个项目中,我们将探索Processing与Arduino的联合编程魅力,通过简单的界面交互实现创意的RGB灯光控制。想象一下,只需轻点Processing界面上的按钮,就能远程操控Arduino板上连接的RGB LED灯打开和关闭。这不仅是一次编程技能的实践,更是将数字创意融入日常生活的有趣尝试。让我们一起动手,用代码点亮生活的色彩吧!
元件清单
硬件连接按照下图进行硬件连接,RGB LED的引脚图请参考项目【炫彩LED】或【彩灯调光台】。
图 1 调光面板连线图
为了实现电脑上的Processing面板对Arduino控制的RGB炫彩灯进行颜色控制,首先需要确保安装了必要的软件。下面是Processing的详细安装步骤(由于版本更新等原因,以下步骤仅供参考)。
根据您的操作系统(Windows, macOS, Linux)选择合适的安装包进行下载。 (以下安装步骤以windows为例)
下载完成后,按照安装向导完成安装过程
将下载的文件解压缩
双击解压缩文件中的processing.exe文件以运行processing。
只需点击“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()函数用于判断鼠标是否停留在按钮上。
- 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的光线明暗度的调节,或者颜色的变化。 发挥你的想象力,制作一个功能强大的调光面板,实现更绚丽多彩的灯光效果吧!(本项目附件程序中有多个按钮版本的程序供您参考)
附件下载:
示例代码.rar
|