云天 发表于 2025-1-28 19:43:41

光电编码项目:行空板K10与数据编码的跨学科实践

本帖最后由 云天 于 2025-1-29 12:13 编辑

项目来源
为满足《义务教育信息科技课程标准(2022年版)》中对数据编码内容的要求,结合数学、物理和音乐等学科知识,设计了“光电编码项目”。本项目利用行空板K10连接光电传感器,读取圆盘上的编码信息,实现数据的采集、处理和应用,旨在通过实践活动加深学生对信息编码的理解。

项目简介
在“光电编码项目”中,学生将使用行空板K10连接7个光电传感器,这些传感器间隔开,在一条直线上与行空板K10的引脚(P0, P1, P2, P8, P12, P13, P14)连接。项目包括两个实验,分别涉及数字编码和简谱编码,通过读取圆盘上的编码信息,学生将学习如何将模拟信号转换为数字信号,并了解编码的原理。

实验一数字编码实验
方法1:使用圆盘底色为白色,光电传感器读取圆盘上的黑色方块。圆盘上分十个分区,每个分区代表一个数字,数字用七位编码,每一位对应行空板K10的屏幕上模拟显示数码管的一个图形方块。黑色表示1,白色表示0。学生将学习如何通过光电传感器读取这些编码,并在行空板K10的屏幕上模拟显示数码管的图形方块。
方法2:在圆盘上扣孔,光电读取时,有孔表示0,无孔表示1。学生可以使用美工刀按照画好的编码图进行切孔。
数字用七位编码,与七个光电传感器一一对应,读取到黑色表示0,白色表示1。然而,光电传感器在读取信息时,可能会受到环境光线和圆盘上色块或孔的边缘影响,从而识别出错误的编码。

实验二简谱编码实验
实验一的编码方法存在浪费“位”的问题,10个数字只需要四位就能表示,因为2的4次方是16。实验二中,简谱使用7个音节,采用二进制编码,所以只需要3位,即3个光电传感器。简谱编码实验二在圆盘上画颜色块实现对简谱编码,传感器读取后,行空板K10解码进行播放。学生将学习如何通过颜色块或扣孔的编码来表示简谱,并实现音乐的播放。

项目知识点
本项目核心教学以下知识点:

[*]数据编码:了解如何使用二进制编码表示数字,以及如何通过光电传感器读取编码信息。
[*]光电传感器原理:学习光电传感器的工作原理,以及如何将光信号转换为电信号。
[*]编程基础:使用Mind+编程软件,掌握基本的编程逻辑和结构。
[*]数学知识:在绘制圆盘分区和编码过程中,了解等分圆的发展史和数学知识。
[*]音乐基础:在简谱编码实验中,学习简谱的基本知识和音乐理论。
[*]跨学科融合:通过项目实践,体验信息科技与其他学科如数学、音乐的融合。

项目原理
项目通过行空板K10的光电传感器读取圆盘上的编码信息,然后将这些信息转换为数字信号,最后在行空板K10的屏幕上模拟显示数码管的图形方块。学生将学习如何通过编程控制这些过程,并理解数据编码的基本原理。

硬件介绍

在“光电编码项目”中,使用以下硬件:

[*]主控器:行空板K10,负责读取传感器数据和控制显示。
[*]传感器:7个光电传感器,用于读取圆盘上的编码信息。
[*]显示模块:行空板K10的显示屏,用于显示数码管图形方块。

硬件接线
行空板K10通过引脚(P0, P1, P2, P8, P12, P13, P14)与7个光电传感器相连,实现数据的读取和处理。

编码盘制作
实验一编码:
数码管的显示编码通常用于将数字或字符转换为对应的段码,以便在数码管上显示。
数字对应的7位字符串编码:

"1111110"      A, B, C, D, E, F       点亮0
"0110000"      B, C                     点亮1      
"1101101"      A, B, G, E, D          点亮2      
"1111001"      A, B, G, C, D          点亮3      
"0110011"      F, G, B, C               点亮4      
"1011011"      A, F, G, C, D          点亮5      
"1011111"      A, F, G, E, C, D       点亮6      
"1110000"      A, B, C                   点亮7      
"1111111"      A, B, C, D, E, F, G    点亮8
"1111011"      A, B, C, D, F, G      点亮9
实验二编码:
简谱的数字表示方法,其中数字代表音符,即简谱中的“哆(1)、来(2)、咪(3)、发(4)、嗦(5)、拉(6)、西(7)”。
《小星星》(儿歌版本)的简谱:
1 1 | 5 5 | 6 6 | 5 - |
4 4 | 3 3 | 2 2 | 1 - |
第一句歌词:
一闪一闪亮晶晶
满天都是小星星。数字1到7的二进制编码:

数字1的二进制编码是 001。
数字2的二进制编码是 010。
数字3的二进制编码是 011。
数字4的二进制编码是 100。
数字5的二进制编码是 101。
数字6的二进制编码是 110。
数字7的二进制编码是 111。《小星星》第一句的二进制表示为:
001 001 101 101 110 110 101
100 100 011 011 010 010 001
制作码盘
1.使用黑白颜色块,绘制编码盘。

2.绘制时可使用尺规作图十等分圆

使用圆规和直尺绘制
要将一个圆十等分,最简单且经典的方法是使用圆规和直尺。以下是详细的步骤:
‌(1)作互相垂直的直径‌:
在圆中作出两条互相垂直的直径MN和AP,它们相交于圆心O。‌
‌(2)平分半径‌:
平分半径OM于点K,使得OK=KM。
‌(3)画弧确定正五边形的边长‌:
以K为圆心,KA为半径画弧,这条弧与直径ON交于点H。此时,线段AH即为正五边形的边长。
‌(4)在圆周上截点‌:
以AH为弦长,在圆周上依次截得A、B、C、D、E各点。
‌(5)连结各点‌:
顺次连结A、B、C、D、E各点,这样你就得到了一个正五边形。由于正五边形的每个内角都是108度,通过连结圆心O与正五边形的每个顶点,可以将圆进一步划分为10个相等的部分。‌
3.刻孔可手工或激光切割



学生实际操作

1.内容编码与绘制:
(1)学生可以自己对数字、音节、图像等内容进行编码,如数字、音节等,并使用纸盘进行绘制。例如,黑色表示1,白色表0。
(2)也可以在纸盘上扣孔,有孔表示1,无孔表示0,通过这种方式进行编码。


(3)对于更高级的操作,可以使用激光切割机完成以上操作,提高精度和效率。
2.圆盘等分与绘制:
(1)在绘制圆盘时,学生可以学习使用尺规作图法,将圆盘等分成多个分区,如十等分。
通过这种方式,学生不仅能够掌握编码的基本原理,还能深入了解等分圆的数学知识,实现数学学科与信息科技的融合。
(2)电机驱动与变速箱:
圆盘由电机驱动旋转,学生可以使用乐高元件齿轮组合成变速箱,降低圆盘转速,以匹配行空板K10屏幕显示和声音播放速度。
同时,利用行空板K10的人工智能功能,通过语音识别功能开启和关闭电机运转。

流程图

在“光电编码项目”中,行空板K10的界面与系统控制流程图如下:

[*]初始化:启动行空板K10,加载Mind+编程软件。
[*]读取传感器:等待光电传感器读取圆盘上的编码信息。
[*]数据处理:将读取的编码信息转换为数字信号。
[*]显示数字:在行空板K10的屏幕上模拟显示数码管的图形方块。

重点程序
实验一:[*]光电传感器读取程序:实现光电传感器数据的读取和处理。
[*]数码管显示程序:根据处理后的编码信息,在屏幕上显示相应的数字。

#include "unihiker_k10.h"
#include <Microbit_Motor.h>
#include "asr.h"
ASR          asr;
// 创建对象
Microbit_Motor motorbit;
// 创建对象
UNIHIKER_K10 k10;
uint8_t screen_dir = 2;

// 定义每段的坐标和尺寸
struct Segment {
int x, y; // 左上角坐标
int w, h; // 宽度和高度
};

Segment segments = {
{60, 40, 120, 20},    // A
{180, 60, 20, 100},   // B
{180, 180, 20, 100},// C
{60, 280, 120, 20},   // D
{40, 180, 20, 100},   // E
{40, 60, 20, 100},    // F
{60, 160, 120, 20}    // G
};

// 绘制函数,参数是一个7位的字符串
void drawDigit(const char* pattern) {
static String lastPattern = "";
// 清空画布
if (String(pattern) != lastPattern) {// 只有当内容变化时才刷新屏幕
    k10.canvas->canvasClear();
    Serial.println(pattern);
    lastPattern = String(pattern);
    // 遍历字符串的每一位
   
    for (int i = 0; i < 7; i++) {
   if (pattern == '1') {// 如果字符是 '1',则绘制对应的段
      int x = segments.x;
      int y = segments.y;
      int w = segments.w;
      int h = segments.h;

      // 绘制矩形
      k10.canvas->canvasRectangle(x, y, w, h, 0x0000FF, 0xFF0000, true);
      }
    }
   
    // 更新画布
    k10.canvas->updateCanvas();
}
}

// 读取光电传感器状态并生成7位字符串
String readSensorPattern() {
static String lastCorrectPattern = "";
String pattern = "";
pattern += digital_read(eP14) == HIGH ? '0' : '1';
pattern += digital_read(eP13) == HIGH ? '0' : '1';
pattern += digital_read(eP12) == HIGH ? '0' : '1';
pattern += digital_read(eP8) == HIGH ? '0' : '1';
pattern += digital_read(eP2) == HIGH ? '0' : '1';
pattern += digitalRead(P1) == HIGH ? '0' : '1';
pattern += digitalRead(P0) == HIGH ? '0' : '1';

// 检查是否匹配正确的7位字符串
if (pattern == "1111110" || pattern == "0110000" || pattern == "1101101" ||
      pattern == "1111001" || pattern == "0110011" || pattern == "1011011" ||
      pattern == "1011111" || pattern == "1110000" || pattern == "1111111" ||
      pattern == "1111011") {
    if (pattern != lastCorrectPattern) {
      lastCorrectPattern = pattern;
      return pattern;
    }
} else {
    lastCorrectPattern = "";
}
return lastCorrectPattern;

}

// 主函数
void setup() {
Serial.begin(9600);
// 初始化屏幕
k10.begin();
k10.initScreen(screen_dir);
k10.creatCanvas();
k10.setScreenBackground(0x000000);
k10.canvas->updateCanvas();
          asr.asrInit(CONTINUOUS, CN_MODE, 6000);
      while(asr._asrState == 0){delay(100);}
      asr.addASRCommand(0+1, "kai shi");
      asr.addASRCommand(0+1, "ting zhi");

}

void loop() {
// 读取传感器状态并生成7位字符串
String pattern = readSensorPattern();

// 显示对应的数字
drawDigit(pattern.c_str());
      if (asr.isDetectCmdID(0+1)) {
motorbit.motorRun(M1, CW, 25);
      }
      if (asr.isDetectCmdID(1+1)) {
motorbit.motorRun(M1, CW, 25);
      }
// 延迟一段时间
delay(5);
}

实验二:
光电传感器读取程序:实现光电传感器数据的读取和处理。音节播放程序:根据处理后的编码信息,通过蜂鸣器播放。为增加识别准确度,在最外圈增加了一个光电传感器,圆盘上最外圈相邻两个分区绘制成“黑-白-黑-白……”或刻制作成“有孔-无孔-有孔-无孔……”
#include "unihiker_k10.h"
#include "asr.h"
ASR          asr;
#include <Microbit_Motor.h>
// 创建对象
Microbit_Motor motorbit;

// 创建对象
UNIHIKER_K10 k10;
Music music;
int lastvalue=-1;
// 读取光电传感器状态并生成3位字符串
String readSensorPattern() {
String pattern = "";
pattern += digitalRead(P1) == LOW ? '1' : '0';
pattern += digital_read(eP8) == LOW ? '1' : '0';
pattern += digital_read(eP13) == LOW ? '1' : '0';
return pattern;
}
void setup() {
// 初始化串口通信
Serial.begin(9600);
k10.begin();
k10.initScreen(2);
k10.creatCanvas();
k10.setScreenBackground(0x000000);
k10.canvas->updateCanvas();
asr.asrInit(CONTINUOUS, CN_MODE, 6000);
   while(asr._asrState == 0){delay(100);}
   asr.addASRCommand(0+1, "kai shi");
   asr.addASRCommand(0+1, "ting zhi");

}

void loop() {
int nowvalue=digitalRead(P0);
if(nowvalue!=lastvalue){
    lastvalue=nowvalue;
// 读取传感器状态并生成3位字符串
String pattern = readSensorPattern();
drawDigit(pattern.c_str());
      if (asr.isDetectCmdID(0+1)) {
motorbit.motorRun(M1, CW, 25);
      }
      if (asr.isDetectCmdID(1+1)) {
motorbit.motorRun(M1, CW, 25);
      }
// 根据传感器状态播放对应的音符
if (pattern == "001") {
    music.playTone(262, 1000); // Do
} else if (pattern == "010") {
    music.playTone(294, 1000); // Re
} else if (pattern == "011") {
    music.playTone(330, 1000); // Mi
} else if (pattern == "100") {
    music.playTone(349, 1000); // Fa
} else if (pattern == "101") {
    music.playTone(392, 1000); // Sol
} else if (pattern == "110") {
    music.playTone(440, 1000); // La
} else if (pattern == "000") {
    music.playTone(494, 1000); // Ti
}
}
// 延迟一段时间
delay(5);
}


外观结构设计
为了便于课堂教学和项目展示,可利用激光切割技术为“光电编码项目”设计外观结构。示例结构设计图和安装完成图如下:

[*]结构设计图:展示圆盘和光电传感器的布局设计。
[*]安装完成图:展示圆盘和传感器的最终组装效果。



演示视频
https://www.bilibili.com/video/BV1uHFheFEqZ/?share_source=copy_web
通过以上增加的内容,学生不仅能够更好地理解数据编码和光电传感器的工作原理,还能通过实际操作提高动手能力和创新思维。同时,结合数学、物理和音乐等学科知识,实现跨学科融合,为学生提供更丰富的学习体验。







ki123456 发表于 2025-2-26 14:26:20

大佬呀,教学案例非常有趣
页: [1]
查看完整版本: 光电编码项目:行空板K10与数据编码的跨学科实践