Jane 发表于 2024-11-22 17:03:36

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]
查看完整版本: Arduino入门教程29-调光面板