2024-11-24 18:05:01 [显示全部楼层]
382浏览
查看: 382|回复: 0

[入门] [入门教程]Arduino入门教程30-绘制光线

[复制链接]
欢迎来到绘制光线这个项目!在这个项目中,我们将Arduino上读取的光线传感器数据实时传输到Processing中并实现其可视化。你将学习如何计算光线的平均值以减少噪声干扰。同时,你将在Processing中创建一个简单的界面,用于显示随着光线变化而起伏的光谱。现在,让我们开始这个有趣的旅程吧!

元件清单
[入门教程]Arduino入门教程30-绘制光线图1


硬件连接
请按照下图进行硬件连接。
[入门教程]Arduino入门教程30-绘制光线图2

图 1 绘制光线连线图

示例代码Processing 样例代码:
  1. //项目 - 绘制光线
  2. import processing.serial.*;
  3. int[] Ypoint; // 垂直方向上的坐标
  4. //int[] x = new int[0];
  5. Serial myPort;  // 创建Serial类的对象
  6. int val;      // 从串口接收到的数据
  7. void setup()
  8. {
  9.   size(640, 360);
  10.   colorMode(HSB,1000);
  11.   Ypoint = new int[width];
  12.   String portName = "COM6"; // 打开你正在使用的端口。
  13.   myPort = new Serial(this, portName, 9600);
  14.   print(portName);
  15. }
  16. void draw()
  17. {
  18.   background(900);             // 设置背景为灰色
  19.   
  20.   for (int i = 1; i < width; i++) { // 记录Ypoint
  21.     Ypoint[i-1] = Ypoint[i];
  22.   }
  23.     if ( myPort.available() > 0) {  // 如果有数据可用,
  24.     val = myPort.read(); // 读取数据并存储在val中
  25.   }
  26.   Ypoint[width-1] = val;
  27.   int x=1;
  28.   for(int i = 1; i < width; i++) {
  29.     // 绘制曲线   
  30.     x++;
  31.     line(i, height, i, map(Ypoint[i], 0, 255, 0, height)); // 将光强转换为Ypoint
  32.     stroke(x,800,800);
  33.   }
  34.     println(val);
  35.    
  36. }
复制代码

Arduino IDE 样例代码:
  1. //项目 - 绘制光线
  2. #include <Arduino.h>
  3. int lightSensorPin;
  4. const int numReadings = 10;
  5. int readings[numReadings];
  6. int readIndex = 0;
  7. long total = 0;
  8. int average = 0;
  9. void setup() {
  10.   Serial.begin(9600);
  11.   for (int thisReading = 0; thisReading < numReadings; thisReading++) {//build the list
  12.     readings[thisReading] = 0;
  13.   }
  14.   lightSensorPin = A0;
  15.   pinMode(lightSensorPin, INPUT);
  16. }
  17. void loop() {
  18.   int newReading = analogRead(lightSensorPin); // 读取新的光线传感器值
  19.   total = total - readings[readIndex] + newReading;
  20.   readings[readIndex] = newReading;
  21.   readIndex = (readIndex + 1) % numReadings;
  22.   average = total / numReadings;
  23.   delay(50);
  24.   int mappedValue = map(average, 0, 1023, 0, 255); // 将平均值映射到0-255范围内
  25.   Serial.write(mappedValue);
  26. }
复制代码


上传Arduino的代码后需要关闭Arduino IDE,并打开processing软件点击运行。等待数据传输稳定(大约5秒钟),使用手电筒照射光敏传感器或移开,可以观察到电脑上的光谱曲线会根据光线强度进行调节。

代码回顾
本项目主要利用Arduino进行光线强度的接收与数据处理,并通过串口通信将处理后的亮度值发送给Processing进行可视化。具体来说,Arduino通过光线传感器实时捕捉环境中的光线亮度,并将其转换为数字值。随后,对这些亮度值进行必要的处理,以确保数据的准确性和可靠性。处理后的亮度值通过串口通信实时发送给Processing。在Processing中,根据接收到的亮度值,绘制一个动态的光谱区域,该区域的高低起伏直观地表示了光线亮度的实时变化情况,从而为用户提供了一个直观、实时的光线亮度变化监测工具。

Processing程序代码回顾
setup()中:
对窗口大小和颜色进行设置。并初始化Ypoint数组,长度为窗口的宽度(即640),用于绘制竖线。

  1. size(640, 360);
  2.   colorMode(HSB,1000);
  3.   Ypoint = new int[width];
复制代码

设置串口通信,并打印串口名称。

  1.   String portName = "COM6";  
  2.   myPort = new Serial(this, portName, 9600);
  3.   print(portName);
  4. }
复制代码

在draw()中:         
  
将Ypoint数组中的元素向前移动一位,为新的数据腾出空间。

  1.   for (int i = 1; i < width; i++) {
  2.     Ypoint[i-1] = Ypoint[i];
  3.   }
复制代码

如果串口有数据可读,从串口读取一个字节的数据,并存储在val变量中。

  1.     if ( myPort.available() > 0) {  
  2.     val = myPort.read();
  3.   }
复制代码

将最新读取的数值赋值给Ypoint数组的最后一个元素

  1.   Ypoint[width-1] = val;
复制代码

这段代码的目的是根据数组Ypoint[]中的每个元素值,绘制一系列竖直线条。这些线条的x坐标与它们在数组中的索引相对应,而y坐标则通过映射函数map()将Ypoint的值从0到255的范围转换到窗口的垂直范围(从0到height)。并利用x值的自增来实现每条竖线颜色的变化。

  1.   int x=1;
  2.   for(int i = 0; i < width-1; i++) {
  3.     x++;
  4.     line(i, height, i, map(Ypoint[i], 0, 255, 0, height));
  5.     stroke(x,800,800);
  6.   }
复制代码

Arduino程序代码回顾

Arduino IDE代码
setup()函数中,循环初始化readings数组,将所有元素设置为0。

  1. for (int thisReading = 0; thisReading < numReadings; thisReading++) {
  2.     readings[thisReading] = 0;
  3.   }
复制代码

loop()中,

  1. int newReading = analogRead(lightSensorPin);
复制代码

读取当前光线的模拟值,将其存在readings数组的当前索引位置。

  1.   total = total - readings[readIndex] + newReading;
复制代码

更新total的值,先减去要被替换的旧读数,再加上新的读数。

  1.   readings[readIndex] = newReading;
复制代码

将新的读数存储在readings数组的当前索引位置。

  1.   readIndex = (readIndex + 1) % numReadings;
复制代码

更新readIndex的值,使其指向下一个数组位置,如果到达数组末尾则循环回到开头。

  1.   average = total / numReadings;
复制代码

计算所有读数的平均值,并赋值给average变量

  1.   int mappedValue = map(average, 0, 1023, 0, 255);
  2. Serial.write(mappedValue);
复制代码

由于Serial.write只能写入8位的二进制,也就是0-255,所以使用map函数将平均值从0-1023范围映射到0-255范围,再通过串口发送mappedValue的整数部分(配合processing中的相关接收数据的语句来使用)。

附件下载:
下载附件示例程序.rar


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

本版积分规则

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

硬件清单

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

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

mail