项目设计完结总结

2018级西电通院微控制项目设计

  • 1. 简要说明
  • 2.项目内容
    • 2.1项目要求
    • 2.2我的想法
    • 2.3电子设计
      • STM32
      • 传感器
        • 光敏传感器
        • 距离传感器
        • 颜色传感器
      • 身份识别(非接触识别)
      • 维护模式

1. 简要说明

项目设计是西电通院的特色课程,自从16级首次开始做这个,到我们18级现在已经是第三代了。
这个项目是以小组为单位的,一般是5-6人小组,全院打乱随机分组(据说是会按成绩区间分配)。由于工作量特别大,所以是要给每个人分配工作,然后最后再完成成品(今年是交的报告和视频成果)。

2.项目内容

2.1项目要求

要求如下
项目设计完结总结_第1张图片
项目设计完结总结_第2张图片
项目设计完结总结_第3张图片
项目设计完结总结_第4张图片
项目设计完结总结_第5张图片

刚开始看这个项目:wdnmd,这也太难了吧,爷要挂科了。
之后赶紧联系了学长,学长大概和我解释了下这个项目是如何云云,我稍微对项目该如何完成稍微有一点了解了。然后又仔细看了项目设计的设计指南好几遍,总结出了一下几个工作:
1.电子:STM32以及传感器编程
2.数字电路设计:verilog,主要是驱动伺服电机
3.软件设计:java语言,做程序的主界面以及里面的操作内容
4.文案:最终报告整合、专利申请书等文案工作
5.网页设计:做一个静态web介绍你的公司和产品
6.组装:应该是所有人一起做,但是今年没有
7.机械设计:画机械图,一共三个,工作大不大
总的来说,前三项任务是比较重的,其他的相对压力较轻。在第一次会议时,我主动承担了电子设计以及经理的任务。接下来组里其他同学也确认了自己的任务。

2.2我的想法

作为经理,我当时构思的产品,如下:
1.模块化功能:即触摸界面显示几个按键,表示不同的功能。
项目设计完结总结_第6张图片
2.具体功能:(中英双语)
2.1学科:语数外物化等,分为网课学习,教材查看,习题练习等
2.1.1网课学习:视频(缓存到本地,点开可以放)
2.1.2教材查看:内容意思一下
2.1.3习题练习(重点):全是选择题,通过不同色块代表选项,用RGB颜色检测器探测,与真实答案比较。成功了发语音(交互),失败了机械臂挥动
2.2外语:可添加口语功能(如果可实现):用户可跟读单词
2.3学习监督:设置开启和关闭,自主设定学习时长,若在规定时长内离开(激光测距仪检测),则机器人挥手,发出警告
2.4智能护眼:设置开启和关闭,超过限定学习时间,亮灯,发出休息提醒
3.维护模式:
3.1验证管理员账号
3.2验证机器人的各部分是否可以正常工作
3.2.1指定部位机械臂转动
3.2.2指定部位亮灯
3.2.3读取激光测距仪数据
3.2.4读取颜色传感器数据

网页设计相关:
1.总体框架按xxx的想法,基本是把内容都填充进去就好
2.需要美工,设计logo,海报,视频剪辑

FPGA:
主要是舵机控制,即机械臂挥动
FPGA (XC7A35T-1CSG324C)

关于非接触验证:
使用多个光敏传感器和卡插,卡插带缺口,嵌到传感器上,缺口可以将光遮挡住,从而输出0,反之输出1。由0,1的组合可以确定不同玩家或管理员,0000~1111
这个东西套件里没有,但是必要,去年不少组都采用此种方式
(我已购买)
关于答题:
选项ABC对应RGB三种色块,我不太清楚具体如何操作啊。选某个选项肯定是在上位机的屏幕上操作,那么直接在上位机上进行结果判定并反馈不就可了么?(最后压根没用这个)

关于交互:
1.stm32给fpga “go”指令,控制电机运行的模式(IO口电平控制)
相当于fpga作用是驱动电机做任意角度转动(自定),在vivado中封装好固定的运行状态,通过stm32电平的组合控制选择电机运行状态
DigitalOut(选电机,选模式)
2.stm32给上位机反馈传感器结果
上位机给stm32输入指令(COM串口通讯)
3.颜色、距离传感器都接I2C(I2C通讯)
4.光敏传感器接AO(数字信号)
DigitalIn(判断身份)
5.串口助手(USART)

而我技术部分负责的是电子设计,下面我来详细说明这部分

2.3电子设计

电子设计分为两部分,一个是STM32,另一个是传感器设计

STM32

本次项目中使用的是STM32L476单片机,是一款低功耗型的单片机
其中接口如下
项目设计完结总结_第7张图片
1.有两类接口,一类是arduino配套的,一类是一般的,到时候需要哪个管脚就直接用杜邦线连接
2.所有管脚都有其相对应的功能,例如串口收发/AO/DO/电源等,按照要求连接即可
接着给出微控制器总体运行流程
项目设计完结总结_第8张图片
主函数编写规范:
int main(){1
中断
while(1){2
while(1){3
插卡检测
if 失败:返回检测
if 成功:继续执行
while(1){4
if 学习模式 :
while(1){5
switch(各种功能)
5}
else if 维护模式:
while(1){6
switch(各种功能)
6}
else
4}
3}
2}
1}
调用函数:
颜色判断函数
颜色返回函数
距离返回函数
选项判断函数
插卡识别函数
电机控制函数

传感器

传感器分为三种,分别为:光敏、距离、颜色传感器

光敏传感器

光敏电阻是用硫化隔或硒化隔等半导体材料制成的电阻器,其工作原理是基于内光电效应。随着光照强度的升高,电阻值迅速降低,由于光照产生的载流子都参与导电,在外加电场的作用下作漂移运动,电子奔向电源的正极,空穴奔向电源的负极,从而使光敏电阻器的阻值迅速下降。其在无光照时,几乎呈高阻状态,暗电阻很大。
项目设计完结总结_第9张图片
用这个传感器,主要是把它作为插卡来进行身份识别的

测试结果如下:
项目设计完结总结_第10张图片
项目设计完结总结_第11张图片
注意:光敏传感器输出的是光强度数值,所以接支持模拟输出的AO口

距离传感器

VL6180是飞行时间测距传感器。传感器包含一个非常小的激光源和一个匹配的传感器。VL6180X可以检测飞行时间,或激光恢复传感器所需的时间从而计算出距离。因此VL6180X的准确度高。由于传感器模块体积小,易于在任何机器人或交互式项目中使用。可以将它与任何3-5V电源或逻辑微控制器一起使用。
项目设计完结总结_第12张图片
用它来检测用户距离机器人的距离,若距离适当且超过一定时间,则开启身份识别界面

颜色传感器

TCS34725芯片提供红、绿、蓝(RGB)以及明光感应的数字返回值。TCS34725彩色传感器有着广泛的应用,包括RGB LED背光控制、固态照明、健康产品、工业过程控制和医疗诊断设备等。

传感器返回四个参数值,分别为颜色参数中的 R, G, B 以及 C 值,根据说明以及我们的测试,由于距离,环境光线,测量物体的放反光程度等细微差异,输出的数据会产生一定量的误差或者偏差,因此在使用本传感器的过程中,需要对使用环境和处理数据的过程进行一定的调整及优化,以保证最后识别的结果有较高的精度保证。
项目设计完结总结_第13张图片
测试结果如下:
项目设计完结总结_第14张图片
项目设计完结总结_第15张图片

身份识别(非接触识别)

项目设计完结总结_第16张图片
机器人拥有非接触验证身份功能,故身份识别全部采用硬件完成。

需要使用VL6180x距离传感器、一个TCS34725颜色传感器以及四个光敏传感器组合完成。

我们使用专用的卡插和颜色挡板,光敏传感器检测到遮挡物时返回为0,未检测到时为1,从而不同卡插可以代表不同身份的用户。为了验证管理员身份,我们使用红色挡板遮盖颜色传感器,否则其余时刻用蓝色遮挡

进行身份验证时,用户首先将代表身份的卡插和颜色挡板插入机器人指定位置,然后等待距离传感器判断用户是否在机器人面前,等待3s后,微控制器根据传感器读取的数据进行身份验证,从而进入应用界面(学习界面/维护界面)。

下面给出微控制器布线结果:
项目设计完结总结_第17张图片
距离传感器和颜色传感器连线图
项目设计完结总结_第18张图片
光敏传感器连线图

维护模式

当成功验证管理员身份后,用户可以进入维护模式,检验各传感器、led灯、伺服电机的运转情况。对于fpga,是由微控制提供指令驱动的,故我们给出fpga不同功能对应的电平组合。

对应指令如下:
a:颜色传感器读取
b:距离传感器读取
c:光敏传感器读取
d:led闪烁
e:fpga“00”控制电平
f:fpga“01”控制电平
g:fpga“10”控制电平
h:fpga“11”控制电平

该部分代码如下:

#include "mbed.h"
#include "stdint.h"
#include <VL6180x.h>
#define VL6180X_ADDRESS 0x29
VL6180xIdentification identification;
// mbed uses 8bit addresses shift address by 1 bit left
VL6180x sensor(A4, A5, VL6180X_ADDRESS<<1);//距离传感器

Serial pc(SERIAL_TX, SERIAL_RX);
AnalogIn switch1(PA_0); //光敏传感器

I2C i2c(I2C_SDA, I2C_SCL); //颜色传感器
int sensor_addr = 41 << 1;
DigitalOut green(LED1);

void ret_rgb(int r,int g,int b) //该函数用于返回颜色值
 {
     
 
 if (r > g*1.3 && r > b*1.3)
 {
     
 pc.printf("red\n");
 }
 else if (g > r*1.3 && g > b*1.3)
 {
     
 pc.printf("green\n");
 }
 else if (b > r*1.3 && b > g*1.3) 
 {
     
 pc.printf("blue\n");
 }
 else
 pc.printf("no\n");
 wait(0.1);
 }
 
 void color_read()
 {
     
  //打开颜色传感器
    int r,g,b;
    green = 1; // off
    pc.baud(9600);
    // Connect to the Color sensor and verify whether we connected to the correct sensor. 
    
    i2c.frequency(100000);
    
    char id_regval[1] = {
     146};
    char data[1] = {
     0};
    i2c.write(sensor_addr,id_regval,1, true);
    i2c.read(sensor_addr,data,1,false);
    
    if (data[0]==68) {
     
        green = 0;
        wait (2); 
        green = 1;
        } else {
     
        green = 1; 
    }
    
    // Initialize color sensor
    
    char timing_register[2] = {
     129,0};
    i2c.write(sensor_addr,timing_register,2,false);
    
    char control_register[2] = {
     143,0};
    i2c.write(sensor_addr,control_register,2,false);
    
    char enable_register[2] = {
     128,3};
    i2c.write(sensor_addr,enable_register,2,false);
    
    // Read data from color sensor (Clear/Red/Green/Blue)
    
    while (true) {
      
        char clear_reg[1] = {
     148};
        char clear_data[2] = {
     0,0};
        i2c.write(sensor_addr,clear_reg,1, true);
        i2c.read(sensor_addr,clear_data,2, false);
        
        int clear_value = ((int)clear_data[1] << 8) | clear_data[0];
        
        char red_reg[1] = {
     150};
        char red_data[2] = {
     0,0};
        i2c.write(sensor_addr,red_reg,1, true);
        i2c.read(sensor_addr,red_data,2, false);
        
        int red_value = ((int)red_data[1] << 8) | red_data[0];
        
        char green_reg[1] = {
     152};
        char green_data[2] = {
     0,0};
        i2c.write(sensor_addr,green_reg,1, true);
        i2c.read(sensor_addr,green_data,2, false);
        
        int green_value = ((int)green_data[1] << 8) | green_data[0];
        
        char blue_reg[1] = {
     154};
        char blue_data[2] = {
     0,0};
        i2c.write(sensor_addr,blue_reg,1, true);
        i2c.read(sensor_addr,blue_data,2, false);
        
        int blue_value = ((int)blue_data[1] << 8) | blue_data[0];
        
        // print sensor readings
        
        //pc.printf("Clear (%d), Red (%d), Green (%d), Blue (%d)\n", clear_value, red_value, green_value, blue_value);
        wait(0.5);
    
         //颜色传感器显示数据
         r = red_value;
         g = green_value;
         b = blue_value;
         pc.printf("R %d G %d B %d\n ",r,g,b);
         //ret_rgb(r,g,b);
   }   
     }

void light_read(){
     
    float s1; 
    pc.baud(9600);   
    while(1) 
    {
     
        
        s1 = switch1.read(); 
        s1 = s1*5000;       
        pc.printf("measure = %.0f\n",s1);        
        wait(0.3);
            
    }
    }
    
void distance_read(){
     
  uint8_t retaddr;
  pc.baud(9600);
  wait_ms(100); // delay .1s
  sensor.getIdentification(&identification); // Retrieve manufacture info from device memory
    if(sensor.VL6180xInit() != 0) {
     
        printf("FAILED TO INITALIZE\n"); //Initialize device and check for errors
    };

    sensor.VL6180xDefautSettings(); //Load default settings to get started.

    wait(1);
    retaddr=sensor.changeAddress(0x29,0x27);
    sensor.getIdentification(&identification); // Retrieve manufacture info from device memory

    wait(1);
    retaddr=sensor.changeAddress(0x27,0x29);
    sensor.getIdentification(&identification); // Retrieve manufacture info from device memory

    while(1) {
     

 
  //Get Distance and report in mm
      printf("Distance measured (mm) = ");
      printf("%d\n", sensor.getDistance() ); 
 
      wait_ms(500); 
 
    }
    
    }

int main(){
     
char order = pc.getc();
    printf("welcome to the matainance system :\n");
    switch(order){
     
        case 'a'://颜色传感器
        color_read();
        break;
        
        case 'b'://距离传感器
        distance_read();
        break;
        
        case 'c'://光敏传感器
        light_read();
        break;
        
        case 'd'://led闪烁
        for(int p=0;p<10;p++){
     
            green = ~green;
            }
        break;
        
        case 'e':
        pc.printf("00\n");
        break;
        
        case 'f':
        pc.printf("01\n");    
        break;
        
        case 'g':
        pc.printf("10\n");
        break;
        
        case 'h':
        pc.printf("11\n");    
        break;
        
        }
}

代码思路比较简单,主要是定义几个传感器如何读取,并将数据显示(print)出来,然后主函数用case调用即可。FPGA与的stm32交互是用电平控制的,而我们是线上完成,所以无法与FPGA连接,用输出电平代替给的指令。

当然驱动传感器这方面有一些麻烦的驱动函数,不过网上都有库,如看懂函数输入输出,直接调用即可,自己写应该不太可能。。。

你可能感兴趣的