2024-11-22 17:03:36 [显示全部楼层]
304浏览
查看: 304|回复: 0

[入门教程] Arduino入门教程29-调光面板

[复制链接]
在这个项目中,我们将探索Processing与Arduino的联合编程魅力,通过简单的界面交互实现创意的RGB灯光控制。想象一下,只需轻点Processing界面上的按钮,就能远程操控Arduino板上连接的RGB LED灯打开和关闭。这不仅是一次编程技能的实践,更是将数字创意融入日常生活的有趣尝试。让我们一起动手,用代码点亮生活的色彩吧!
元件清单

Arduino入门教程29-调光面板图1

硬件连接
按照下图进行硬件连接,RGB LED的引脚图请参考项目【炫彩LED】或【彩灯调光台】。

Arduino入门教程29-调光面板图2
图 1 调光面板连线图

为了实现电脑上的Processing面板对Arduino控制的RGB炫彩灯进行颜色控制,首先需要确保安装了必要的软件。下面是Processing的详细安装步骤(由于版本更新等原因,以下步骤仅供参考)。

访问Processing的官方网站 https://processing.org/download

Arduino入门教程29-调光面板图3

根据您的操作系统(Windows, macOS, Linux)选择合适的安装包进行下载。
(以下安装步骤以windows为例)

Arduino入门教程29-调光面板图4

(如果你是用的其他系统的计算机,请参考https://processing.org/tutorials/gettingstarted

下载完成后,按照安装向导完成安装过程

将下载的文件解压缩
Arduino入门教程29-调光面板图5

双击解压缩文件中的processing.exe文件以运行processing。

Arduino入门教程29-调光面板图6
如果一切顺利,现在将可以看到主要的Processing窗口。每个人的设置都不同,因此,如果程序没有启动,或者你遇到了其他问题,请访问https://github.com/benfry/processing4/wiki/Troubleshooting页面查找可能的解决方案。

只需点击“Get Started”即可进入processing编程界面。

Arduino入门教程29-调光面板图7

编写你的第一个Processing程序

你现在正在运行Processing开发环境(PDE)。界面功能如下所示:


Arduino入门教程29-调光面板图8

在文本编辑器中,输入以下内容:
ellipse(50, 50, 80, 80);

Arduino入门教程29-调光面板图9

这行代码的意思是“绘制一个椭圆,其中心距离左边50像素,距离顶部50像素,宽度和高度均为80像素。”点击工具栏上的运行按钮(三角形按钮)。

Arduino入门教程29-调光面板图10

如果你输入的所有内容都是正确的,那么你会在屏幕上看到一个圆。

Arduino入门教程29-调光面板图11

如果你没有正确输入,消息区域会变成红色,并显示错误信息。

Arduino入门教程29-调光面板图12

如果发生这种情况,请确保你已完全复制了示例代码:数字应包含在括号内,并且每个数字之间用逗号隔开,行尾应有一个分号。

简单了解Processing软件的使用规则后,你就可以参考下方的程序代码实现其与Arduino的互动效果啦!

示例代码
Processing 样例代码:
  1. // 项目 - 调光面板  
  2. import processing.serial.*; // 导入串口通信库  
  3.   
  4. Serial myPort; // 创建串口对象  
  5.   
  6. int circleX, circleY; // 按钮的位置  
  7. int circleSize = 100; // 按钮的直径  
  8.   
  9. color currentColor, baseOffColor, baseOnColor; // 颜色变量  
  10. color circleColor; // 颜色变量  
  11. color circleHighlight; // 颜色变量  
  12.   
  13. boolean circleOver = false; // 判断鼠标是否在按钮上  
  14.   
  15. PFont f; // 字体类型  
  16. void setup() {  
  17.   size(600, 400); // 设置屏幕大小
  18.   background(200); // 背景颜色
  19.   
  20.   circleColor = color(255, 30, 30); // 设置按钮原本颜色变量  
  21.   circleHighlight = color(255, 100, 100); // 设置按钮高亮颜色变量  
  22.   circleX = width / 4 * 2; // 设置按钮的X坐标  
  23.   circleY = height / 2; // 设置按钮的Y坐标  
  24.   
  25.   printArray(PFont.list()); // 打印计算机上的字体列表  
  26.   f = createFont("Ebrima Bold", 20); // 设置字体  
  27.   textFont(f); // 应用字体  
  28.   
  29.   String portName = "COM3"; // 输入你的COM端口  
  30.   myPort = new Serial(this, portName, 9600); // 选择第一个端口  
  31.   print(portName); // 打印端口名  
  32. }  
  33.   
  34. void draw() {  
  35.   update(mouseX, mouseY); // 调用更新方法   
  36.   
  37.   if (circleOver) {  
  38.     fill(circleHighlight); // 鼠标在按钮上时填充高亮颜色  
  39.   } else {  
  40.     fill(circleColor); // 鼠标不在按钮上时填充正常颜色  
  41.   }  
  42.   circle(circleX, circleY, circleSize); // 绘制圆形按钮  
  43.   stroke(255); // 边框颜色  
  44.   fill(140, 25, 25); // 文本颜色
  45.   textAlign(CENTER); // 文本对齐方式
  46.   text("RED", width / 4 * 2, height / 2 + 10); // 显示文本  
  47.   
  48. }  
  49.   
  50. void update(int x, int y) {  
  51.   if (circleOver(circleX, circleY, circleSize)) {  
  52.     circleOver = true; // 鼠标在按钮上  
  53.   } else {  
  54.     circleOver = false; // 鼠标不在按钮上  
  55.   }  
  56. }  
  57.   
  58. boolean circleOver(int x, int y, int diameter) {  
  59.   float disX = x - mouseX;  
  60.   float disY = y - mouseY;  
  61.   if (sqrt(sq(disX) + sq(disY)) < diameter / 2) {  
  62.     return true; // 鼠标在按钮上  
  63.   } else {  
  64.     return false; // 鼠标不在按钮上  
  65.   }  
  66. }
  67. int clicknumber; // 点击次数  
  68. void mousePressed() {  
  69.   if (circleOver) {  
  70.   
  71.     clicknumber = clicknumber + 1;  
  72.     if (clicknumber % 2 == 1) {  
  73.       print("RedON"); // 打印信息"RedOn"
  74.       myPort.write('1'); // 发送值1  
  75.       background(200); // 背景颜色
  76.     } else {  
  77.       myPort.write('2'); // 发送值2  
  78.       print("RedOff"); // 打印信息"RedOff"
  79.       background(50); // 背景颜色
  80.     }  
  81.   }  
  82. }  
复制代码

Arduino IDE 样例代码:
  1. // 项目 - 调光面板  
  2. int redPin;  
  3. void setup() {  
  4.   Serial.begin(9600); // 开启串口通信  
  5.   redPin = 9;  
  6.   pinMode(redPin, OUTPUT); // 设置Arduino引脚为输出  
  7. }  
  8. void loop() {  
  9.   if (Serial.available() > 0) { // 检查串口是否有数据  
  10.     char led = Serial.read(); // 读取串口数据  
  11.     if (led == '1') { // 检查串口读取的数据  
  12.         digitalWrite(redPin, HIGH); // 红灯亮  
  13.     } else if (led == '2') { // 检查串口读取的数据  
  14.         digitalWrite(redPin, LOW); // 红灯灭  
  15.     }  
  16.   }  
  17. }
复制代码


代码回顾
Arduino IDE与Processing的交互主要通过串口通信(Serial Communication)实现,使得Arduino可以控制硬件设备(如RGB LED)并将数据发送到计算机,而Processing则能接收这些数据并进行可视化处理或发送控制指令给Arduino。

Arduino通过接收到的指令不同,执行对应的操作。

虽然在代码示例部分Processing代码和Arduino代码是两组独立的代码程序。但两组代码不是完全割裂的,而是相互配合来运行和使用的。所以在下方的代码讲解过程中,虽然为了代码讲解的连续和完整性,不会把两个程序穿插进行讲解。但请将两组代码对照着理解,这有助于你更好的理解代码的逻辑原理。

Processing程序代码回顾
在setup()函数前,导入库和变量定义
  1. import processing.serial.*;  
  2. Serial myPort;  
  3. int circleX, circleY;  
  4. int circleSize = 100;  
  5. color currentColor, baseColor;  
  6. color circlecolor;  
  7. color circleHighligh;  
  8. boolean circleOver = false;  
  9. PFont f;
复制代码

这一部分导入了必要的库,定义了按钮的位置、大小、颜色,以及用于串行通信的Serial对象。同时,定义了字体和颜色变量。
在setup()函数中:
  1. size(600, 400);  
  2.   circleColor = color(255, 100, 100);  
  3.   circleHighlight = color(200, 50, 50);  
  4.   baseColor = color(200);  
  5.   currentColor = baseColor;  
  6.   circleX = width / 4 * 2;  
  7.   circleY = height / 2;
  8.   printArray(PFont.list());  
  9.   f = createFont("Ebrima Bold", 20);
  10.   textFont(f);  
  11.   String portName = "COM3";
  12.   myPort = new Serial(this, portName, 9600);  
  13.   print(portName);
复制代码

在setup()函数中,设置了屏幕大小、按钮位置、颜色和字体。

很重要的是建立了与Arduino的串口通信连接,使用String portName = "COM3";输入Arduino连接的设备端口号,并初始化了串行通信。
draw()函数用于在屏幕上绘制所有元素:
  1. update(mouseX, mouseY);
复制代码

用于更新鼠标位置,update()函数用于判断鼠标是否停留在按钮上。

  1. if (circleOver) {  
  2.     fill(circleHighlight);
  3.   } else {  
  4.     fill(circleColor);   
  5.   }
复制代码

用if-else进行判断来更新按钮颜色,当鼠标停留在按钮区域显示高亮颜色;否则显示按钮原本颜色。

  1.   circle(circleX, circleY, circleSize);
  2.   stroke(255);
  3.   fill(140, 25, 25);
  4.   textAlign(CENTER);
  5.   text("RED", width / 4 * 2, height / 2 + 10);   
复制代码

使用circle(x, y, d)函数绘制圆形(配合对应函数做按钮使用),其中x和y是圆形中心的位置,d对应的是圆形的直径。并绘制该圆形的边框,文本内容颜色和位置。

update()函数根据鼠标的当前位置(x, y)更新每个按钮的悬停状态。
  1. void update(int x, int y) {  
  2.   if (circleOver(circleX, circleY, circleSize)) {  
  3.     circleOver = true; // 鼠标在按钮上  
  4.   } else {  
  5.     circleOver = false; // 鼠标不在按钮上  
  6.   }  
  7. }
复制代码

这里虽然名为update,但它实际上是draw()函数中调用的一个函数,用于更新悬停状态,并不直接绘制任何内容。该函数中circleOver(circleX, circleY, circleSize)为update()函数的一个辅助方法,用于判断鼠标是否停在按钮圆形区域内。

  1. boolean circleOver(int x, int y, int diameter) {  
  2.   float disX = x - mouseX;  
  3.   float disY = y - mouseY;  
  4.   if (sqrt(sq(disX) + sq(disY)) < diameter / 2) {  
  5.     return true; // 鼠标在按钮上  
  6.   } else {  
  7.     return false; // 鼠标不在按钮上  
  8.   }  
  9. }
复制代码

这些辅助方法用于判断鼠标是否悬停在特定的圆形按钮上。

disX和disY是鼠标现在位置与按钮圆心横坐标和纵坐标的差值(这个差值有可能为正有可能为负,后续只使用该差值的平方值,所以正负无影响)。利用勾股定理a²+b²=c²,使用sqrt(sq(disX) + sq(disY))计算得出鼠标位置与按钮中心的距离,如果距离小于按钮半径,则返回true,表示鼠标悬停在该按钮上。否则返回false,表示鼠标悬停在按钮之外的位置。

最后,mousePressed()函数属于processing内置的事件处理函数,在用户点击鼠标时调用。

  1. void mousePressed() {  
  2.   if (circleOver) {  
  3.     clicknumber = clicknumber + 1;  
  4.     if (clicknumber % 2 == 1) {  
  5.       print("RedON");
  6.       myPort.write('1');   
  7.       background(200);
  8.     } else {  
  9.       myPort.write('2');   
  10.       print("RedOff");
  11.       background(50);
  12.     }  
  13.   }  
  14. }  
复制代码

当用户点击鼠标时鼠标
在mousePressed()函数内进行判断,当点击发生在圆形按钮内,则按下按钮次数clicknumber加1。接着对按下总次数进行判断,如果按下次数为奇数,向Arduino发送数字“1”,否则按下次数为偶数,向Arduino发送数字“2”。并在控制台输出对应的开关信息。

Processing程序不直接控制RGB LED的高低电平,而是通过发送数字信号给Arduino。Arduino根据接收到的数字信号,向RGB LED输出相应的高低电平,以控制其颜色和亮度。这样,Processing与Arduino协同工作,实现了对RGB LED的间接控制。

Arduino程序代码回顾
在loop()函数中,if (Serial.available() > 0)检查串口是否有新的数据可读。如果有,就执行大括号内的代码。

  1. if (Serial.available() > 0) {
  2.   }  
复制代码

在if执行块内,先将Processing发送的数字赋值给字符串型变量led,接下来的两个if语句检查读取的数据led。如果为'1',则通过digitalWrite(redPin, HIGH);打开LED;如果为‘2',则通过digitalWrite(redPin, LOW);关闭LED。

  1. char led = Serial.read();
  2. if (led == '1') { // 检查串口读取的数据  
  3.         digitalWrite(redPin, HIGH); // 红灯亮  
  4.     } else if (led == '2') { // 检查串口读取的数据  
  5.         digitalWrite(redPin, LOW); // 红灯灭  
  6.     }  
复制代码

课后练习
使用多个按钮实现RGB LED的光线明暗度的调节,或者颜色的变化。
发挥你的想象力,制作一个功能强大的调光面板,实现更绚丽多彩的灯光效果吧!(本项目附件程序中有多个按钮版本的程序供您参考)

附件下载:
下载附件示例代码.rar

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail