光学传感器项目的实践思路
根据实验给出的相关代码和指导书,小组给出了传输信息率计算光源传感器的传输信息(数字)
大致思路:
- 发射机参考实验参考代码,设置0~开始和结束信号灯的90个数字和亮灭频率信息。
- 接收端根据光传感器的特点获取光强信息。鉴于光强受环境和传感器本身的影响较大,在每次测试前,首先调试稳定的光强信息,根据发射端光源的光强信息确定一般范围一般范围。接收端根据光强信息转换为高低电平,接收端的采集频率为发射端的4倍。四个亮灭信息构成一个完整的信号(开始/结束,1~9)
- 同步问题,现实调试中很容易遇到两个传感器不同步的问题
- 情况:一开始数据不对齐,主要是发射端快,接收端慢。除了调整两个传感器的频率外,还需要一些措施来处理数据不同步
- 解决思路:
- 当遇到跳变时,判断此时是否满足4个高低电平如果目前的亮灭信息采用前三个电平,并保留最新的电平。如果不满足4个,则保留最新的和其他丢弃
- 如果满足4个且未跳变,则亮灭信息采用当前电平
- 同步解决方案,如果发送端只是第一个收集频率,通过上诉思维可以实现同步,但如果更多,因为数据丢失,基于此,我们让发送端发送两个开始信号,然后接收端即使第一个开始信号没有完全读取,也不影响第二个开始信号读取,实现两个传感器的同步(如果没有其他干扰)
附关键源码
接收方
/********************************************************************************************* * 文件:main.c * 作者:Lixm 2017.09.25 * 说明:光照传感器实验 例程 * 环境光强度采用光强传感器,并打印光强信息PC上,1S更新一次 * 修改:zhoucj 2018.01.02 修改为串口一 * 注释: *********************************************************************************************/ /********************************************************************************************* * 头文件 *********************************************************************************************/ #include <ioCC2530.h> #include "clock.h" #include "delay.h" #include "uart1.h" #include "stdio.h" #include "string.h" #include "BH1750.h" int judge[2][4] = {
{1,0,1,0},{0,0,0,1}; int SE[2][4] = {
{1,1,1,0},{1,1,0,0}; // 滑动窗口函数 int left(int window[],int num) { window[0] = window[1]; window[1] = window[2]; window[2] = window[3]; window[3] = num; return 0; } // 将存储的高低电平值反向数字 int nums[10][4] = { {1, 0, 1, 0}, {0, 0, 0, 1}, {0, 0, 1, 0}, {0, 0, 1, 1}, {0, 1, 0, 0}, {0, 1, 0, 1}, {0, 1, 1, 0}, {0, 1, 1, 1}, {1, 0, 0, 0}, {1, 0, 0, 1} }; /********************************************************************************************* * 名称:main() * 功能:逻辑代码 * 参数:无 * 返回:无 * 修改: * 注释: *********************************************************************************************/ void main(void) { float light_data = 0; ///存储光照度数据变量 char tx_buff[64]; ///串口发送缓冲数组 memset(tx_buff, 0, 64); int windows[4] = { 0,0,0,0 }; int dianping[4]; xtal_init(); //系统时钟初始化 bh1750_init(); /// uart1_init(0x00,0x00); int bit = 0; int tp = 0; int begin = 0, end = 0; char rec_buff[64]; int rc = 0; memset(rec_buff, 0, 64); while (1) { if(end) { break; } light_data = bh1750_get_data(); sprintf(tx_buff, "当前光强%f\n", light_data); uart1_send_string(tx_buff); if (light_data > 25) { uart1_send_string("高电平\n"); dianping[bit ] = 1; } else { uart1_send_string("低电平\n"); dianping[bit ] = 0; } if (bit > 1 && dianping[bit - 1] != dianping[bit - 2]) { uart1_send_string("电平前后不同的亮灭跳变\n"); if (bit == 4) { uart1_send_string("移动窗口\n"); left(windows, dianping[bit - 2]); tp ; dianping[0] = dianping[bit - 1]; bit = 1; } else { dianping[0] = dianping[bit - 1]; bit = 1; } } else if (bit == 4) { uart1_send_string("移动窗口\n"); left(windows, dianping[bit - 1]); tp ; bit = 0; } if (tp == 4) { uart1_send_string("满窗判断\n"); tp = 0; for(int i = 0; i < 4; i) { memset(tx_buff, 0, 64); sprintf(tx_buff, "%d", windows[i]); uart1_send_string(tx_buff); } uart1_send_string("\n"); if (!begin) { uart1_send_string("\n"); int flag = 1; for (int j = 0; j < 4; j) { if (windows[j] != SE[0][j])
{
flag = 0;
break;
}
}
if (flag)
{
memset(tx_buff, 0, 64);
uart1_send_string("检测开始\n");
begin = 1;
continue;
}
}
if (!end)
{
int flag = 1;
for (int j = 0; j < 4; ++j)
{
if (windows[j] != SE[1][j])
{
flag = 0;
break;
}
}
if (flag)
{
memset(tx_buff, 0, 64);
uart1_send_string("检测结束\n");
end = 1;
break;
}
}
for (int i = 0; i < 10; ++i)
{
int flag = 1;
for (int j = 0; j < 4; ++j)
{
if (windows[j] != nums[i][j])
{
flag = 0;
break;
}
}
if (flag)
{
memset(tx_buff, 0, 64);
sprintf(tx_buff, "识别到数字%d\n", i);
rec_buff[rc++] = (char)(i + '0');
uart1_send_string(tx_buff);
}
}
}
delay_s(1);
}
uart1_send_string("检测结果:");
uart1_send_string(rec_buff);
uart1_send_string("\n");
return ;
}
发送方
/********************************************************************************************* * 文件:main.c * 作者:Lixm 2017.10.17 * 说明:声光报警实验 例程 * 上电后控制声光报警周期性开合1S一次,并将声光报警的
开关状态打印在PC上 * 修改:2017.11.08 chennian 将led文件替换为通用版驱动文件 * 2018.01.02 zhoucj 修改为串口一 * 注释: *********************************************************************************************/ /********************************************************************************************* * 头文件 *********************************************************************************************/ #include <ioCC2530.h> #include "clock.h" #include "delay.h" #include "alarm.h" #include "led.h" #include "uart1.h" #include "key.h" #include <stdio.h> #include <string.h> #define MINTIME 4 #define Ms 720 char SendData[20] = {0,1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1,0}; //char SendData[4] = {1, 0, 1,0}; void TurnLedON(); void TurnLedOff(); void Send0(); void Send1(); void Send2(); void Send3(); void Send4(); void Send5(); void Send6(); void Send7(); void Send8(); void Send9(); void StartSend(); void StopSend(); /********************************************************************************************* * 名称:main() * 功能:逻辑代码 * 参数:无 * 返回:无 * 修改: * 注释: *********************************************************************************************/ void main(void) { unsigned char alarm_flag = 0; //报警标志位 unsigned char num = 0; //计数 xtal_init(); //系统时钟初始化 alarm_init(); //声光报警初始化 uart1_init(0x00,0x00); //串口初始化 //TurnLedOff();//先关闭灯 //TurnLedON(); int DataLen = sizeof(SendData) / sizeof(char); StartSend(); for (int cnt = 0; cnt < DataLen; cnt++) { if (SendData[cnt] == 0) { Send0(); } else if (SendData[cnt] == 1) { Send1(); } else if (SendData[cnt] == 2) { Send2(); } else if (SendData[cnt] == 3) { Send3(); } else if (SendData[cnt] == 4) { Send4(); } else if (SendData[cnt] == 5) { Send5(); } else if (SendData[cnt] == 6) { Send6(); } else if (SendData[cnt] == 7) { Send7(); } else if (SendData[cnt] == 8) { Send8(); } else if (SendData[cnt] == 9) { Send9(); } } StopSend(); /* StopSend();*/ /* if(alarm_flag == 1){ RGB_R = !RGB_R; //RGB灯红色灯状态翻转 RGB_G = !RGB_G; RGB_B = !RGB_B; //RGB_G = OFF; //RGB灯绿色灯关闭 //RGB_B = OFF; //RGB灯蓝色灯关闭 //BEEP = !BEEP; //蜂鸣器状态翻转 } else{ RGB_G = ON; //RGB灯绿色灯打开 RGB_R = ON; RGB_B = ON; //BEEP = OFF; //蜂鸣器关闭 } delay_ms(2000); //延时250毫秒 num++; //计数 if(num > 0){ alarm_flag = !alarm_flag; //标志位翻转 num = 0; //计数清零 if(alarm_flag == 1){ uart1_send_string("ALARM ON! \r\n\r\n"); //串口打印提示信息 //alarm_init(); //声光报警初始化 } else{ ; //串口初始化 uart1_send_string("ALARM OFF! \r\n\r\n"); //串口打印提示信息 //alarm_init(); //声光报警初始化 // BEEP = OFF; //蜂鸣器关闭 } }*/ // } } void TurnLedON() { RGB_G = ON; //RGB灯绿色灯打开 RGB_R = ON; RGB_B = ON; //BEEP = ON; //声音也有 delay_s(MINTIME); delay_ms(Ms); } void TurnLedOff() { RGB_G = OFF; //RGB灯绿色灯打开 RGB_R = OFF; RGB_B = OFF; //BEEP = OFF; //关闭蜂鸣器 delay_s(MINTIME); delay_ms(Ms); } void StartSend() { TurnLedON(); TurnLedON(); TurnLedON(); TurnLedOff(); } void StopSend() { TurnLedON(); TurnLedON(); TurnLedOff(); TurnLedOff(); } void Send0() { TurnLedON(); TurnLedOff(); TurnLedON(); TurnLedOff(); } void Send1() { TurnLedOff(); TurnLedOff(); TurnLedOff(); TurnLedON(); } void Send2() { TurnLedOff(); TurnLedOff(); TurnLedON(); TurnLedOff(); } void Send3() { TurnLedOff(); TurnLedOff(); TurnLedON(); TurnLedON(); } void Send4() { TurnLedOff(); TurnLedON(); TurnLedOff(); TurnLedOff(); } void Send5() { TurnLedOff(); TurnLedON(); TurnLedOff(); TurnLedON(); } void Send6() { TurnLedOff(); TurnLedON(); TurnLedON(); TurnLedOff(); } void Send7() { TurnLedOff(); TurnLedON(); TurnLedON(); TurnLedON(); } void Send8() { TurnLedON(); TurnLedOff(); TurnLedOff(); TurnLedOff(); } void Send9() { TurnLedON(); TurnLedOff(); TurnLedOff(); TurnLedON(); }
方案评价
优点其实就是通过高延时带来降低按键以及操作带来的负面影响
缺点就是延时太高,虽然准确传输,但是却导致需要的时间过长。