打印
[创业]

【21ic DIY秀】+DIY自己的数控系统

[复制链接]
6020|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
        写在前面的话:趁着二姨家的这次DIY活动,我也发一个前端时间自己DIY的简易数控系统吧,由一块数控主板和触摸屏构成,初步可以通过触摸屏控制主板的IO进行开关,以及显示主板采集的多路温度数据。
一,背景
      在数控这个行业呆了几年,最近感觉很迷茫。打工工资永远都是千年不变,消费(主要是物价和租房)越来越高,再加之年龄上也到了而立之年。感觉都不知道做什么了,看看周边的同事都陆续开始走自主创业之路,也最终我们这个职业是转行的**,所以提前给自己做些技术积累,做些准备工作,所以就利用空余的时间做了个简易的数控系统,再慢慢优化以便不时之需。




二,硬件介绍;(待更新)


三,触控屏;(待更新)


四,固件和上位机设计。(待更新)


相关帖子

沙发
王栋春| | 2019-3-9 21:37 | 只看该作者
这个围观一下  

使用特权

评论回复
板凳
飞扬自我|  楼主 | 2019-3-9 23:02 | 只看该作者
二,硬件介绍;硬件部分,主要是STM32F103加上IO模块,模拟量输入输出,通信接口,步进电机驱动等功能。
电源24V输入,共同在输入,输出和电机驱动部分使用。
5V电源在通信接口CAN和模拟量输出的滤波电路共用。
其余部分使用3.3V。


1,电源部分:24V输入,转5V和3.3V

2,MCU:stm32f103r8





,3,input
,
4,output



5,模拟输入/输出

6,通信接口

7,步进电机驱动




附件是全部电路原理图的PDF
stm32f103_can_1.pdf (192.48 KB)

水平有限,欢迎大家指点指点。


使用特权

评论回复
地板
taohairen| | 2019-3-10 15:06 | 只看该作者
你们一般用无源晶振,是吗?

使用特权

评论回复
5
飞扬自我|  楼主 | 2019-3-10 17:39 | 只看该作者
taohairen 发表于 2019-3-10 15:06
你们一般用无源晶振,是吗?

无源和有源都有人用啊。看成本和精度要求以及工作环境等情况。

使用特权

评论回复
6
飞扬自我|  楼主 | 2019-3-11 00:31 | 只看该作者
三,触控屏;
        触控屏选用的是北京迪文的DMT80480T070_18WT,7.0 英寸 800×480 图形点阵 K600+内核 65K 色 DGUS 屏,这个是咸鱼上面淘回来的,100块钱。
      迪文屏的好处就是开发周期很短,有点像做PPT一样,做好背景和内容布局就在软件里设置好寄存器和指令既可使用,把工程下载到SD卡中,重新启动触摸屏就可以进行操作。


开发环境如下图





最终效果图:













具体操作是触控了屏幕上面的按键就会下发一个串口指令,主板接收到串口数据进行解码从而控制外设的开关或者DAC的转换数据。数据的具体形式详情看接着更新的软件部分。



使用特权

评论回复
7
whtwhtw| | 2019-3-11 10:40 | 只看该作者
不错,尤其是这个屏的开发环境,看着很好用啊,比写gui方便多了

使用特权

评论回复
8
tvb2058| | 2019-3-11 13:31 | 只看该作者
不错,支持一下

使用特权

评论回复
9
飞扬自我|  楼主 | 2019-3-11 20:11 | 只看该作者
whtwhtw 发表于 2019-3-11 10:40
不错,尤其是这个屏的开发环境,看着很好用啊,比写gui方便多了

确实是很方便,但是对于我这种审美不足的人来说,做个界面就有点不是专业了。。。

使用特权

评论回复
10
飞扬自我|  楼主 | 2019-3-11 20:17 | 只看该作者
tvb2058 发表于 2019-3-11 13:31
不错,支持一下

支持我就帮帮点赞我吧。

使用特权

评论回复
11
飞扬自我|  楼主 | 2019-3-11 20:37 | 只看该作者
四。PCB截图更新     整个板尺寸10*10cm,为特殊尺寸特价板,打板费用60元/10pcs。自己DIY成本是必须要最低。
   PCB整体走线和布局。



PCB的敷铜


PCB板的正面丝印

板的gerber。


以下是BOM(仅供参考)



使用特权

评论回复
12
eydj2008| | 2019-3-12 08:08 | 只看该作者
飞扬自我 发表于 2019-3-11 20:37
四。PCB截图更新     整个板尺寸10*10cm,为特殊尺寸特价板,打板费用60元/10pcs。自己DIY成本是必须要最低 ...

我觉得你的思路是对的, 老了说不好就靠这点经验混点钱 养老呢

使用特权

评论回复
13
eydj2008| | 2019-3-12 08:08 | 只看该作者
飞扬自我 发表于 2019-3-11 20:37
四。PCB截图更新     整个板尺寸10*10cm,为特殊尺寸特价板,打板费用60元/10pcs。自己DIY成本是必须要最低 ...

我觉得你的思路是对的, 老了说不好就靠这点经验混点钱 养老呢

使用特权

评论回复
14
飞扬自我|  楼主 | 2019-3-13 23:35 | 只看该作者
本帖最后由 飞扬自我 于 2019-3-13 23:41 编辑

四,触控屏开发与下位机软件开发
   4.1触控屏开发。
     每个地方都是一个地址,所以后续的编程和显示都是按照设置的地址进行操作。具体操作设置见下图:













   4.2下位机软件开发
     通过上面的触控,每一次触控触摸屏都会自动下发一次指令,具体指令见表。
     

   

  对于本次的指令只要是0x80,0x81,0x82,0x83以及0x84指令。

SerialScreenData_TypeDef SerialScreenData; //定义串口屏结构组
/*********************************初始化结构体*************************************************/

void inint_SerialScreenData(void)
{
        //接收信息缓冲区
         u8 counter;
         for(counter=0;counter<9;counter++)
          SerialScreenData.ProcesData[counter]=0;        //串口屏下发信息缓冲区

        SerialScreenData.ProcesDataClear_flag=0;         //数据处理缓冲数组清除标志位 1允许清理
        SerialScreenData.Updata_flag=0x01;               //更新数据标志作为数据处理的判断标志        
         
        //输出IO设置相关
        SerialScreenData.OutputDataSet=0x00;             //用于存储Output的设置数据
        SerialScreenData.UartWrite82Input[0]=0x5A;       //串口用82指令写动态波形数据Buf 0 帧头
        SerialScreenData.UartWrite82Input[1]=0xA5;       //串口用82指令写动态波形数据Buf 1 帧头
        SerialScreenData.UartWrite82Input[2]=0x05;       //串口用82指令写动态波形数据Buf 2 操作码
        SerialScreenData.UartWrite82Input[3]=0x82;       //串口用82指令写动态波形数据Buf 3 发送字节数据
        SerialScreenData.UartWrite82Input[4]=0x01;       //串口用82指令写动态波形数据Buf 4 地址高位
        for(counter=5;counter<8;counter++)
         SerialScreenData.UartWrite82Input[counter]=0x00;   //串口用82指令写动态波形数据Buf        
         
        //DAC设置相关
        for(counter=0;counter<2;counter++)         
        SerialScreenData.DACData[counter]=0x00;          //用于存储串口屏下发的DAC输出电压值转换后的数据 DACData[0]--->DAC1;  DACData[1]--->DAC2
        SerialScreenData.DACChannel=0x00;                //设置DAC的通道    0x00000000----->DAC_Channel_1;  0x00000010----->DAC_Channel_2;
        
        //画图波形设置   adc
        for(counter=0;counter<8;counter++)         
        SerialScreenData.Channelflag[counter]=0x00;      //Channelflag[0]--->channel_1#;...........;Channelflag[7]--->channel_8#
        
        SerialScreenData.UartWrite84Buf[0]=0x5A;       //串口用84指令写动态波形数据Buf 0 帧头
        SerialScreenData.UartWrite84Buf[1]=0xA5;       //串口用84指令写动态波形数据Buf 1 帧头
        SerialScreenData.UartWrite84Buf[2]=0x12;       //串口用84指令写动态波形数据Buf 2 发送数量
        SerialScreenData.UartWrite84Buf[3]=0x84;       //串口用84指令写动态波形数据Buf 3 操作码
        SerialScreenData.UartWrite84Buf[4]=0xff;       //串口用84指令写动态波形数据Buf 4 通道标识
        for(counter=5;counter<21;counter++)
         SerialScreenData.UartWrite84Buf[counter]=0x00;   //串口用84指令写动态波形数据Buf        
         
        //工作状态标志位
        for(counter=0;counter<4;counter++)
        SerialScreenData.State[counter]=0x00;           // State[0]  运行;     State[1]  急停;     State[2]  报错;     State[3]  停止
        SerialScreenData.WarnningCode=0x00;             //0x00~0xff   运行报警代码
        
        //子站参数相关
        SerialScreenData.UartWrite82Node[0]=0x5A;       //串口用82指令写动态波形数据Buf 0 帧头      //设置的子站地址 16进制
        SerialScreenData.UartWrite82Node[1]=0xA5;       //串口用82指令写动态波形数据Buf 1 帧头
        SerialScreenData.UartWrite82Node[2]=0x04;       //串口用82指令写动态波形数据Buf 2 操作码
        SerialScreenData.UartWrite82Node[3]=0x82;       //串口用82指令写动态波形数据Buf 3 发送字节数据
        SerialScreenData.UartWrite82Node[4]=0x00;       //串口用82指令写动态波形数据Buf 4 地址高位
        SerialScreenData.UartWrite82Node[5]=0x6A;       //串口用82指令写动态波形数据Buf 4 地址低位        
  SerialScreenData.UartWrite82Node[6]=0x00;       //串口用82指令写动态波形数据Buf        
        
        //10ms定时计数器
                SerialScreenData.MsCounter=0;
}

主控程序的部分代码
  while(1)
  {  
                if(SerialScreenData.ProcesDataClear_flag)  //数据处理完,数据等待接收
                {
                        if(SerialScreenData.DACChannel==0x00) //DAC1
                          Dac_Set_Vol(SerialScreenData.DACData[0],SerialScreenData.DACChannel);
                        if(SerialScreenData.DACChannel==0x10)  //DAC2
                          Dac_Set_Vol(SerialScreenData.DACData[1],SerialScreenData.DACChannel);
                       
                        WriteByte595(~SerialScreenData.OutputDataSet);       
                        SerialScreenData.ProcesDataClear_flag=0x00;
                }               
               
                if(SerialScreenData.MsCounter==50)  //50ms
                {
                                u8 Inputdata=0x00;
                                u8 Nodestation=0x00;
                          u8 bitcouter=0;
                                // Input
                                GPIOInputdata=ReadWord165();
                                Inputdata=GPIOInputdata&0x00ff;
                          for(bitcouter=0;bitcouter<8;bitcouter++)
                            {
                                                if(Inputdata&(0x01<<bitcouter))                                                       
                                                   SerialScreenData.UartWrite82Input[7]=0x00;
                                                else
                                                   SerialScreenData.UartWrite82Input[7]=0x01;
                                                SerialScreenData.UartWrite82Input[5]=bitcouter*2;
                                    USART2Write(SerialScreenData.UartWrite82Input,8);
                                        }
                               
                               
                               
                                //Node station
                                Nodestation=(GPIOInputdata&0xff00)>>8;
                                SerialScreenData.UartWrite82Node[6]=Nodestation;
        USART2Write(SerialScreenData.UartWrite82Node,7);
                }
               
               
         if(SerialScreenData.MsCounter>100) // 100ms任务                         
                  {                               

                                //画图
                                if(SerialScreenData.Channelflag[0]==1)
                                  SerialScreenData.UartWrite84Buf[6]=125+125*sin(pi*(i0+= 2)/180+pi/24); //channel_0
                                else
                                        SerialScreenData.UartWrite84Buf[6]=0x00;
                               
                                if(SerialScreenData.Channelflag[1]==1)                               
                                  SerialScreenData.UartWrite84Buf[8] =125+125*sin(pi*(i1+= 4)/180+pi/12);  //channel_1
                                else
                                        SerialScreenData.UartWrite84Buf[8]=0x00;
                               
                                if(SerialScreenData.Channelflag[2]==1)
                                   SerialScreenData.UartWrite84Buf[10]=125+125*sin(pi*(i2+= 6)/180+pi/10);  //channel_2
                                else
                                        SerialScreenData.UartWrite84Buf[10]=0x00;
                                       
                                if(SerialScreenData.Channelflag[3]==1)
                                   SerialScreenData.UartWrite84Buf[12]=125+125*sin(pi*(i3+= 8)/180+pi/8);  //channel_3
                                else
                                        SerialScreenData.UartWrite84Buf[12]=0x00;

                                if(SerialScreenData.Channelflag[4]==1)
                                   SerialScreenData.UartWrite84Buf[14]=125+125*sin(pi*(i4+=10)/180+pi/6);  //channel_4
                                else
                                        SerialScreenData.UartWrite84Buf[14]=0x00;
                                       
                                if(SerialScreenData.Channelflag[5]==1)
                                   SerialScreenData.UartWrite84Buf[16]=125+125*sin(pi*(i5+=12)/180+pi/4);  //channel_5
                                else
                                        SerialScreenData.UartWrite84Buf[16]=0x00;
                                       
                                if(SerialScreenData.Channelflag[6]==1)                       
                                   SerialScreenData.UartWrite84Buf[18]=125+125*sin(pi*(i6+=14)/180+pi/3);  //channel_6
                                else
                                   SerialScreenData.UartWrite84Buf[18]=0x00;               
                               
                                if(SerialScreenData.Channelflag[7]==1)
                                   SerialScreenData.UartWrite84Buf[20]=125+125*sin(pi*(i7+=16)/180);  //channel_7
                                else
                                   SerialScreenData.UartWrite84Buf[20]=0x00;                                       
                                 if(i0==359)                         i0=0;
                                 if(i1==359)                         i1=0;
                                 if(i2==359)                         i2=0;
                                 if(i3==359)                         i3=0;
                                 if(i4==359)                         i4=0;
                                 if(i5==359)                         i5=0;
                                 if(i6==359)                         i6=0;
                                 if(i7==359)                         i7=0;               
                               
                   USART2Write(SerialScreenData.UartWrite84Buf,21);
                   SerialScreenData.MsCounter=0x00;
                         if((j++)%2==0)
                    GPIO_SetBits(GPIOC,GPIO_Pin_12);
                         else
                                 GPIO_ResetBits(GPIOC,GPIO_Pin_12);

                }                 



串口数据识别代码段:
/******************************接收中断服务程序************************************/
//迪文串口屏触控输出指令接收
//       帧头 数据长度 操作码   地址  寄存器数量   数值
//急停: 5A A5   06      83      00 55     01       00 01
//运行: 5A A5   06      83      00 55     01       00 80
//报警: 5A A5   06      83      00 55     01       00 08
//DAC1: 5A A5   06      83      00 61     01       00 01  (10mv)
//DAC2: 5A A5   06      83      00 65     01       00 01  (10mv)
//DAC1: 5A A5   06      83      00 6A     01       00 38  (十进制为65)
//通道: 5A A5   06      83      00 50     01       80 00  (1-7 的加权值为80 40 20 10 08 04 02 01 高8位)
//IN:     (无输出)
//OUT:   5A A5   06     83      00 5A     01       00 80  (1-7 的加权值为80 40 20 10 08 04 02 01 低8位)

void USART2_IRQHandler(void)
{
//        SerialScreenData_TypeDef  SerialScreenData;  //定义串口屏结构组
        u8 get_char;
        u16 time_out=10000; //等待超时
        u8 j=0;
        if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
        {        
          get_char=USART2->DR;
    if(GetFinish_flag==0) //不是接收数据状态
                {
                 if(State_flag==1)  //等待帧头 5A A5
                 {
                  DataReg[1]=DataReg[0];
                        DataReg[0]=get_char;    //接收的字节进行存储等待帧头校验
                         
                         if((DataReg[0]==0xa5)&&(DataReg[1]==0x5a))  //帧头校验
                         {
                                 State_flag=0x00;                       //帧头校验成功
                                 GetFinish_flag=1;          //接收数据标志物置1
                     Getdata[0]=DataReg[0];
                           Getdata[1]=DataReg[1];   //存储帧头到DataReg[]数组;                                       
                         }
                         else
                         {
                                 State_flag=0x01;                                        //帧头校验失败
                                 GetFinish_flag=0x00;          //接收数据标志物置0,继续等待帧头
                         }
                 }
         }
         else  //帧头校验成功开始接收数据
                {
                 if((++GetDataCounter)<7) //接收的数据计算器<数据长度 继续接收数据
                        {
//                                 GetDataCounter++;
                           Getdata[GetDataCounter+1]=get_char;                       

                        }
                        else  //接收数据结束
                        {
                          Getdata[GetDataCounter+1]=get_char;        //接收最后一个数据       
                                GetDataCounter=0;               
        GetFinish_flag=0;                               
        State_flag=0x01;
                                while(SerialScreenData.ProcesDataClear_flag)
                                {
                                 while(time_out--)
                                         ;
                                 SerialScreenData.WarnningCode=0x01;   //处理超时,接收数据丢失
                                 break;
                                }
        for(j=0;j<9;j++)
         SerialScreenData.ProcesData[j]=Getdata[j];
                                 SerialScreenData.Updata_flag=0x01;
                        }
                }
        }
}




使用特权

评论回复
评论
1781843394 2019-4-3 22:14 回复TA
老哥你这是成熟的产品展示啊,DGUS屏,加一些触控按钮等,这个屏开发还是挺方便的,单片机只要解析指令就可以 
15
springvirus| | 2019-3-15 08:26 | 只看该作者
来看看。。。

使用特权

评论回复
16
wwd8888| | 2019-3-17 17:52 | 只看该作者
支持楼主!

使用特权

评论回复
17
arima| | 2019-3-18 17:25 | 只看该作者
支持楼主!!!

使用特权

评论回复
18
taohairen| | 2019-3-20 20:32 | 只看该作者
飞扬自我 发表于 2019-3-10 17:39
无源和有源都有人用啊。看成本和精度要求以及工作环境等情况。

PCB板厂是哪家?推荐一下呗。

使用特权

评论回复
评论
飞扬自我 2019-3-21 22:05 回复TA
回复了,但是被管理员给灭了。。。你找这个***吧。胡蝶 135 1036 4750 
19
飞扬自我|  楼主 | 2019-3-21 22:04 | 只看该作者
上几个测试的相片
布局画板的痛苦。



画原理图不能一心多用,一不小心就成了飞线了,,看左下角。


触摸屏的测试。。可惜没有留下测试的数据。










使用特权

评论回复
20
飞扬自我|  楼主 | 2019-3-21 23:06 | 只看该作者
来点测试视频吧。。

DIY完成整机测试视频


输入检测测试视频


以前的测试视频


触摸屏测试视频,有点不够灵敏

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

495

帖子

4

粉丝