找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6248|回复: 1
收起左侧

arduino摩尔斯电报译码器制作

[复制链接]
ID:277903 发表于 2018-5-19 07:34 | 显示全部楼层 |阅读模式
部分_compressed.jpg

工作流程 流程图.png

自适应传输速率以及译码
传输速率:
M /--/
         MO的电码
O /---/


↓下图为MO的电码片段
小图.png

由图可见字母M是由 LL HL  LS  HL 组成,而LL是所谓的数据头(时间比较长的低电平状态)
为了识别出信号的长短,我们首先需要知道信号长短的时间,于是乎我们可以在开机时进行一定量的数据采样,因为每个完整的信号短都包含了长和短的情况,可以计算出长和短信号时间的平均值,根据这个平均值对长短信号分两个数列存储,最后用平滑算法算出大概的延迟时间,这样就做到自动确定通讯速率!

译码:
由上文可知,我们获取到了信号长短的延迟,并且能够对比长短和电平来识别出数据
当检测到数据头后假如存在上一个字符的缓存会进行翻译。
翻译过程就是根据LS,HS,HL状态分为0,1,2 然后对比码库

如果没有存在缓存,那么进行从检测到数据头开始把接收到的信号存储在缓存里

电路图
电路图_压缩.jpg



源码:
  1. /*=========================================================
  2.                          LHW开发
  3.     oled下半部分是留空的,计划用于显示数据图表,不过现在优化做的不太好,如果实时刷新数据图表会导致系统资源紧张,做不到实时采样,导致无法抄收完整数据,我很头疼,现在通讯速率收到这个限制,搞到每个字符传输速度不得快于60ms
  4.   如果有好的优化方案,欢迎联系

  5.   重要 开机的时候信号口必须有信号然后在开机,因为开机后会自动学习和分析信号并自动调整速率,否则输出会与发送的不符
  6.   =========================================================*/
  7. #include "U8glib.h"//引用U8G头文件
  8. U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);//设置设备名称:I2C-SSD1306-128*64(OLED)
  9. //如果屏幕不同请自行修改 如果第一次使用u8glib并且遇到显示不正确,请自行修改u8g配置
  10. /*=========================================================
  11.                          变量
  12.   =========================================================*/
  13. int x, y; int Buffer[128]; //
  14. int Time = 0; //计时
  15. int DPin = A0; //数据接收口
  16. byte RXB[10];  //接收缓冲区  0为中间间隔 1为短高 2为长高
  17. int SA[10]; //初始数据平均值
  18. int DA;
  19. int HH[10]; //平滑数据 最高的长度
  20. int AH, AL; //平滑后的数据
  21. byte TH, TT, TRX, MT; //位置
  22. bool ET = false; //电平是否变化
  23. byte BootOk = 0; //初始化阶段  0为学习通讯速率 1为计算基准值 2为完成通讯速率学习 3为检测到数据起始符 4为工作状态
  24. byte DFT = 35; //数据正方向容错值
  25. bool WI = false; //工作状态
  26. //码库
  27. long MH[36] = {
  28.   1020202020,
  29.   1010202020,
  30.   1010102020,
  31.   1010101020,
  32.   1010101010,
  33.   2010101010,
  34.   2020101010,
  35.   2020201010,
  36.   2020202010,
  37.   2020202020,
  38.   1020000000,
  39.   2010101000,
  40.   2010201000,
  41.   2010100000,
  42.   1000000000,
  43.   1010201000,
  44.   2020100000,
  45.   1010101000,
  46.   1010000000,
  47.   1020202000,
  48.   2010200000,
  49.   1020101000,
  50.   2020000000,
  51.   2010000000,
  52.   2020200000,
  53.   1020201000,
  54.   2020102000,
  55.   1020100000,
  56.   1010100000,
  57.   2000000000,
  58.   1010200000,
  59.   1010102000,
  60.   1020200000,
  61.   2010102000,
  62.   2010202000,
  63.   2020101000
  64. };
  65. char ME[36] = {
  66.   49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
  67. };
  68. char MS[32] = {49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,}; //信息显示区
  69. /*=========================================================
  70.                      只循环一次
  71.   =========================================================*/
  72. void setup()
  73. {
  74.   pinMode(DPin, INPUT); //初始化接收pin口
  75.   Serial.begin(115200);   //初始化串口比特率
  76.   u8g.setFont(u8g_font_04b_03r);
  77.   u8g.firstPage();
  78.   do {
  79.     u8g.setPrintPos(13, 33);
  80.     u8g.print("Automatic detection rate");
  81.   } while ( u8g.nextPage() );
  82. }

  83. /*=========================================================
  84.                      不停循环
  85.   =========================================================*/
  86. void loop()
  87. {
  88.   scanning(); //扫描

  89. }
  90. /*=========================================================
  91.                      显示
  92.   =========================================================*/
  93. void Draw() {
  94.   u8g.firstPage();
  95.   do {
  96.     int i = 0;
  97.     for (int py = 0; py < 2; py++) {
  98.       for (int px = 0; px < 16; px++) {
  99.         u8g.setPrintPos(px * 8 + 2, py * 8 + 6);
  100.         u8g.print((char)MS[i]);
  101.         i++;
  102.       }
  103.     }
  104.   } while ( u8g.nextPage() );
  105. }
  106. /*=========================================================
  107.                      清除数据缓冲
  108.   =========================================================*/
  109. void CM() {
  110.   for (int i = 0; i < 10; i++) RXB[i] = 0;
  111. }
  112. /*=========================================================
  113.                      起始符处理
  114.   =========================================================*/
  115. void Tse() {
  116.   //检测到数据起始符
  117.   String TXT;
  118.   for (int i = 0; i < 10; i++) {   //把接收区缓存合成字符串
  119.     TXT = TXT + RXB[i];
  120.   }
  121.   Serial.println(TXT);
  122.   for (int i = 0; i < 35; i++) {    //匹配数据库信号
  123.     if (String(MH[i]) == TXT) {
  124.       MS[MT] = ME[i]; //把信息写入 显示缓冲 区
  125.       MT++;
  126.       if (MT > 31) MT = 0;   //如果显示区溢出,覆盖旧的信息
  127.       Draw();
  128.     }
  129.   }
  130.   CM();   //清除接收区缓存
  131.   TRX = 0;  //接收区缓存地址重置
  132. }
  133. /*=========================================================
  134.                      译码
  135.   =========================================================*/
  136. void translation()
  137. {
  138.   if (Time >= AH - DFT && Time <= AH + DFT && !ET) {
  139.     Tse();

  140.   } else {
  141.     if (TRX > 9) TRX = 0;  //数据接收错误  初始化
  142.     if (!ET) { //低电平
  143.       if (Time >= AL - DFT && Time <= AL + DFT) {
  144.         RXB[TRX] = 0;
  145.         TRX++;
  146.       }
  147.     } else {
  148.       if (Time >= AL - DFT && Time <= AL + DFT) {
  149.         RXB[TRX] = 1;
  150.         TRX++;
  151.       } else {
  152.         if (Time >= AL + DFT && Time <= AH + DFT) {
  153.           RXB[TRX] = 2;
  154.           TRX++;
  155.         }
  156.       }
  157.     }
  158.   }



  159. }
  160. /*=========================================================
  161.                      扫描
  162.   =========================================================*/
  163. void scanning() {
  164.   if (digitalRead(DPin) != ET) {  //电平发生改变
  165.     Time = 0;  //重置计时
  166.     ET = digitalRead(DPin); //重置电平状态
  167.     while (digitalRead(DPin) == ET) { //检测电平是否再次改变
  168.       if (Time >= 10000) {   //大于10秒接收超时
  169.         /*    Serial.print(millis());
  170.             Serial.println(" : TimeOut !");*/
  171.         goto EndRx;  //超时
  172.       }
  173.       if (RXB[TRX - 1] != 0 && Time >= AH + 30) {
  174.         //可能是通讯结尾 并且不会再有数据传送
  175.         Tse();
  176.       }
  177.       Time++;  //增加计时
  178.       delay(1);  //延时1ms
  179.     }
  180. EndRx:
  181.     if (Time < 10000) {
  182.       //如果没有超时
  183.       Serial.print(millis());
  184.       Serial.print(" : ");
  185.       Serial.print(ET);
  186.       Serial.print(" ");
  187.       Serial.println(Time);
  188.       //学习波形
  189.       if (BootOk == 0) {
  190.         SA[TH] = Time;
  191.         if (TH > 8) {
  192.           BootOk = 1;
  193.         } else {
  194.           TH++;
  195.         }
  196.       } else {
  197.         if (BootOk == 1) {
  198.           //计算信号基准值
  199.           for (int i = 0; i < 10; i++) DA = DA + SA[i]; //相加
  200.           DA = float(DA / 10); //获取平均值
  201.           BootOk++;
  202.         } else {
  203.           if (BootOk == 2) {
  204.             if (Time > DA) {
  205.               HH[TT] = Time; //写入最高平滑
  206.               TT++;
  207.               if (TT > 9) {
  208.                 TT = 0;
  209.                 AH = 0;
  210.                 for (int i = 0; i < 10; i++) AH = AH + HH[i]; //相加
  211.                 AH = float(AH / 10); //获取平均值
  212.                 AL = float(AH / 3); //获取平均值
  213.                 BootOk++;
  214.               }
  215.             }
  216.           } else {
  217.             translation(); //译码
  218.           }
  219.         }
  220.       }
  221.     }
  222.   }
  223. }
复制代码

全部资料51hei下载地址:
RX.zip (2.6 KB, 下载次数: 39)

评分

参与人数 3黑币 +120 收起 理由
YJGG + 12 很给力!
wjwjwjwjwj + 8 很给力!
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:369694 发表于 2018-11-9 16:00 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表