欢迎来到绘制光线这个项目!在这个项目中,我们将Arduino上读取的光线传感器数据实时传输到Processing中并实现其可视化。你将学习如何计算光线的平均值以减少噪声干扰。同时,你将在Processing中创建一个简单的界面,用于显示随着光线变化而起伏的光谱。现在,让我们开始这个有趣的旅程吧!
元件清单
硬件连接
请按照下图进行硬件连接。
图 1 绘制光线连线图
示例代码Processing 样例代码:
- //项目 - 绘制光线
- import processing.serial.*;
- int[] Ypoint; // 垂直方向上的坐标
- //int[] x = new int[0];
-
- Serial myPort; // 创建Serial类的对象
- int val; // 从串口接收到的数据
-
- void setup()
- {
- size(640, 360);
- colorMode(HSB,1000);
- Ypoint = new int[width];
- String portName = "COM6"; // 打开你正在使用的端口。
- myPort = new Serial(this, portName, 9600);
- print(portName);
- }
-
- void draw()
- {
- background(900); // 设置背景为灰色
-
- for (int i = 1; i < width; i++) { // 记录Ypoint
- Ypoint[i-1] = Ypoint[i];
- }
- if ( myPort.available() > 0) { // 如果有数据可用,
- val = myPort.read(); // 读取数据并存储在val中
- }
-
- Ypoint[width-1] = val;
- int x=1;
- for(int i = 1; i < width; i++) {
- // 绘制曲线
- x++;
- line(i, height, i, map(Ypoint[i], 0, 255, 0, height)); // 将光强转换为Ypoint
- stroke(x,800,800);
-
- }
-
- println(val);
-
- }
复制代码
Arduino IDE 样例代码:
- //项目 - 绘制光线
- #include <Arduino.h>
- int lightSensorPin;
- const int numReadings = 10;
- int readings[numReadings];
- 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[thisReading] = 0;
- }
-
- lightSensorPin = A0;
- pinMode(lightSensorPin, INPUT);
-
- }
-
- void loop() {
- int newReading = analogRead(lightSensorPin); // 读取新的光线传感器值
- total = total - readings[readIndex] + newReading;
- readings[readIndex] = 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[width];
复制代码
设置串口通信,并打印串口名称。
- String portName = "COM6";
- myPort = new Serial(this, portName, 9600);
- print(portName);
- }
复制代码
在draw()中:
将Ypoint数组中的元素向前移动一位,为新的数据腾出空间。
- for (int i = 1; i < width; i++) {
- Ypoint[i-1] = Ypoint[i];
- }
-
复制代码
如果串口有数据可读,从串口读取一个字节的数据,并存储在val变量中。
- if ( myPort.available() > 0) {
- val = myPort.read();
- }
复制代码
将最新读取的数值赋值给Ypoint数组的最后一个元素
复制代码
这段代码的目的是根据数组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[i], 0, 255, 0, height));
- stroke(x,800,800);
- }
-
复制代码
Arduino程序代码回顾
Arduino IDE代码
在setup()函数中,循环初始化readings数组,将所有元素设置为0。
- for (int thisReading = 0; thisReading < numReadings; thisReading++) {
- readings[thisReading] = 0;
- }
-
复制代码
在loop()中,
- int newReading = analogRead(lightSensorPin);
复制代码
读取当前光线的模拟值,将其存在readings数组的当前索引位置。
- total = total - readings[readIndex] + newReading;
复制代码
更新total的值,先减去要被替换的旧读数,再加上新的读数。
- readings[readIndex] = 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中的相关接收数据的语句来使用)。
附件下载:
示例程序.rar
|