欢迎来到绘制光线这个项目!在这个项目中,我们将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 
 
 
 |