Jane 发表于 2024-11-24 18:05:01

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

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

元件清单


硬件连接
请按照下图进行硬件连接。

图 1 绘制光线连线图
示例代码Processing 样例代码:
//项目 - 绘制光线
import processing.serial.*;
int[] Ypoint; // 垂直方向上的坐标
//int[] x = new int;

Serial myPort;// 创建Serial类的对象
int val;      // 从串口接收到的数据

void setup()
{
size(640, 360);
colorMode(HSB,1000);
Ypoint = new int;
String portName = "COM6"; // 打开你正在使用的端口。
myPort = new Serial(this, portName, 9600);
print(portName);
}

void draw()
{
background(900);             // 设置背景为灰色

for (int i = 1; i < width; i++) { // 记录Ypoint
    Ypoint = Ypoint;
}
    if ( myPort.available() > 0) {// 如果有数据可用,
    val = myPort.read(); // 读取数据并存储在val中
}

Ypoint = val;
int x=1;
for(int i = 1; i < width; i++) {
    // 绘制曲线   
    x++;
    line(i, height, i, map(Ypoint, 0, 255, 0, height)); // 将光强转换为Ypoint
    stroke(x,800,800);

}

    println(val);
   
}
Arduino IDE 样例代码:
//项目 - 绘制光线
#include <Arduino.h>
int lightSensorPin;
const int numReadings = 10;
int readings;
int readIndex = 0;
long total = 0;
int average = 0;

void setup() {
Serial.begin(9600);

for (int thisReading = 0; thisReading < numReadings; thisReading++) {//build the list
    readings = 0;
}

lightSensorPin = A0;
pinMode(lightSensorPin, INPUT);

}

void loop() {
int newReading = analogRead(lightSensorPin); // 读取新的光线传感器值
total = total - readings + newReading;
readings = newReading;
readIndex = (readIndex + 1) % numReadings;
average = total / numReadings;
delay(50);
int mappedValue = map(average, 0, 1023, 0, 255); // 将平均值映射到0-255范围内
Serial.write(mappedValue);
}

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

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

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

size(640, 360);
colorMode(HSB,1000);
Ypoint = new int;
设置串口通信,并打印串口名称。

String portName = "COM6";
myPort = new Serial(this, portName, 9600);
print(portName);
}
在draw()中:         

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

for (int i = 1; i < width; i++) {
    Ypoint = Ypoint;
}

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

    if ( myPort.available() > 0) {
    val = myPort.read();
}

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

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

int x=1;
for(int i = 0; i < width-1; i++) {
    x++;
    line(i, height, i, map(Ypoint, 0, 255, 0, height));
    stroke(x,800,800);
}

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

for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings = 0;
}

在loop()中,

int newReading = analogRead(lightSensorPin);
读取当前光线的模拟值,将其存在readings数组的当前索引位置。

total = total - readings + newReading;
更新total的值,先减去要被替换的旧读数,再加上新的读数。

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

readIndex = (readIndex + 1) % numReadings;
更新readIndex的值,使其指向下一个数组位置,如果到达数组末尾则循环回到开头。

average = total / numReadings;
计算所有读数的平均值,并赋值给average变量

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

附件下载:



页: [1]
查看完整版本: [入门教程]Arduino入门教程30-绘制光线