| 自制电动滑板.作者:herr_kun 
 
 
     工科男就应该拥有这样一个电动滑板,可以出行代步,解决最后一公里的难题。 
 由于在学校寝室离实验室的距离太远了(女朋友),所以想着做一个代步工具,前一段时间一直在和女朋友玩滑板,就想着能不能把滑板做成电动的,就像是市面上的那种,本科一直在飞思卡尔实验室待着,在做小车平时也做电赛之类的,这样的一个控制系统做起来应该不难,总的来说就是单片机控制电调从而控制无刷电机,说做就做,经过多种方案的对比和处于经济实用型以及后面可改装性出发,设计如下:   1、遥控器的选择:手机APP遥控        (弃用:红外遥控:不稳定,遥控距离短,自制模块做遥控(蓝牙,nrf2401等):女朋友天天拿着过于麻烦,要想好看点还得设计外壳,不如手机便捷)        这个APP是当时随便找的只要可以进行蓝牙发送数据,重点是自己写一个简单的接受发送协议就行。        通过界面可以进行相应速度的控制(当人站在上面的话会自动使能启动,人一旦下了滑板会自动停车,防止发生滑板乱跑,该方案通过一个红外对管就可以实现,后续会有介绍) 
 
     
 
   2、滑板主要模块的设计: 下图是滑板的内部图,一块锂电池,一个电调,一个最小系统(KL26),外设:蜂鸣器,红外遥控模块(后面改为了手机蓝牙遥控),红外对管.......     
 
 
 
   自制电动滑板主要涉及到:1、主要设备(功率无刷电机以及电调、电池)的规格选取,2、控制系统的设计与制作(搭建电路以及元器件(霍尔测速、光电感应、蜂鸣提示等)的选择),3、后期的调试与创新(手机端协议、单片机端控制程序以及如何利用加速度计陀螺获得体感进行创新设计等)。      像这样(外壳是博主自己用开关电源的壳子手锯的) 
 
   
 
   实测电动滑板按照如下配置,可以达到150min的续航,40公里左右的里程,远超同价格配置,并且外围可开发空间巨大。 
      第一部分  主要设备的规格选取。       1、板子:小鱼板或者长板等大家按照偏好来,个人觉得小鱼板适合女生实用,小巧精致。2、电机:功率无刷电机比较合适,一般KV值都不是很大,因为要保证相同功率下扭矩的输出,一般市面上用的N5065无刷电机,功率绝对够用,很有加速推背感。3、电调:用无刷电机就肯定用到电调,就不像是自己用mos管搭直流电机驱动了,这里的电调一定要大,玩过四轴飞行器的朋友肯定知道,30A的电调肯定够用,但是在这里120A左右的电调才可以,因为你要知道,它载的是100多斤的人。4、电池:100A的电流,常见并且常用的只有锂电池可以做到,分享一下选型标准,注意电池的放点倍率C,最大放电电流等于容量乘以倍率,通过计算就可以知道可不可以达到电机工作电流,然后最好是6节锂电池串联的简称6S电池。 
       第二部分 控制系统的设计与制作         有了滑板和动力设备,那么就该控制出场了,首先 1、主控芯片:我选用的是ARM cotex-M0系列的KL26,这个芯片比较贵,但是我用顺手了,大家也可以选用STM32,为什么选用配置这么高的芯片呢,原因就是便于以后再次开发,不管是想做成手持式蓝牙、2401或者其他频段遥控,或者做手机端遥控,再者加上CCD摄像头做自适应寻迹等等,都可以做,并且不难,这正是DIY的乐趣。 2、电路板:我用的电路板是万用板自己焊的电路,如果想用手持遥控或者手机遥控的话,万用板电路不是特别复杂,需要的我可以提供电路图,下一步准备自己画印刷电路板,可以搭载更多模块,甚至FPC封装的摄像头,以实现滑板自主巡航。       3、其他模块:主要有蓝牙模块:进行串口通讯,可以和手机端或者手持端通信进而遥控;蜂鸣器模块:加减速以及其他误操作时进行提示;光电对管模块:检测人体是否在滑板上,没有的时候闭锁滑板,防止指令误操作,跳下滑板的时候,滑板自动停止,防止不及时操作造成的隐患。霍尔模块:进行滑板的测速(程序中会有限速处理),可根据自己适应程度放宽,最高可到45公里每小时,大胆尽管来试。其他模块可根据兴趣搭载,与单片机之间的数据采集和通讯会在程序部分讲解。 
       第三部分 后期调试       后期调试主要是手机和滑板之间的调试。1:协议必须一致,使用蓝牙通讯,两方的接受和发送必须提前商量好每个字节所代表的含义。2:在线调试:这一步主要是为了确认协议没有错误,并且每条指令都可以准确无误的执行,这样滑起来才放心嘛,在线调试界面在K60的live watch界面中,可以调出来观看。3:速度调试 ,当写好协议,手机可以正常遥控滑板时,注意启动时的速度设定,太小了滑板会起不来,太大了容易使人由于惯性摔倒,这块为什么会这样和无刷电机的特性有关,后续会更深入的讲解。       目前为止,如果你看完了所有的文章,相信你已经大概懂得了如何制作一个炫酷的电动滑板了,你现在已经比大多数人懂得多了,接下来就是一步步更深入的细节了,接下来会有代码,大量图片,以及专业术语出现,希望你能坚持下去,做出一个属于你自己的代步工具。我爱电动滑板,更爱自己做的。 
   希望可以激发你的灵感,快来创新玩起来吧!!! 
 
 
   
 
 
       这里主要说一些代码的实现,考虑到很多人大家用的单片机不太一样,所以我就没必要把整个工程都贴出来(作者的是KL26),有需要的可以留言发邮箱,所以这里就只贴出来主要部分代码。 
 
   
 
   1、整体结构    主要模块:一路PWM,一个PIT定时器(包括设置定时中断),一个串口(包括串口接受中断),若干GPIO。其对应的初始化为:     DisableInterrupts;     gpio_init (PTE2, GPO,0);     // FENG MING        gpio_init (PTA17, GPI,1);       // HONG WAI      uart_init (UART1, 9600);      // 设置串口,9600波特率      tpm_pwm_init(TPM0, TPM_CH1,200,16);      // 这个电调需要先给大概一毫秒的低电平,完成初始化,大约20%   TPM0_C1V=10000;    // 先给PWM一个低占空比     pit_init_ms(PIT0,8);                          //定时bus时钟中断  set_vector_handler(PIT_VECTORn,pit0_hander);   // 设置PIT中断服务函数到中断向量表里      set_vector_handler(UART1_VECTORn,uart1_test_handler);     EnableInterrupts;       // 使能所有中断     enable_irq(UART1_IRQn); // 使能串口中断   enable_irq(PIT_IRQn);   // 使能PIT中断   uart_rx_irq_en(UART1);  // 使能串口接收中断 
 2、串口模块:主要进行蓝牙串口数据的接受     除了串口初始化,设置接受中断外还需要在中断函数中进行串口数据的接受,以下是部分代码和注释:   voiduart1_test_handler(void) {     UARTn_e uratn = UART1;       if(UART_S1_REG(UARTN[uratn]) &UART_S1_RDRF_MASK)   //接收数据寄存器满     {         uart_getchar(UART1,&Re_buff[counter]);  //Re_buff是自己设置的一个数组,接受串口数据        if(counter==0&&Re_buff[0]!=0xA5) return;  //Re_buff[0]!=0xA5 协议报头为0xA5         counter++;         if(counter==3)   //Re_buff数组只接受三个字节,代表了手机发送的指令         {         counter=0;         sign=1;          }     } 
 3、PIT定时器:主要定时进行串口接收到的数据的解析      启动定时器中断是因为不能一直进行数据解析,因为串口数据需要不断的接受并更新。        Re_buff [ ]有三个字节,其中前两个字节也就是协议的报头为启动信号,0xA5和0x5A,设计这样两个报头的目的是为了防止滑板收到其他的蓝牙数据,导致滑板失控等现象的发生,一般0xA5和0x5A相邻出现的概率很小,如果你想更安全一些,可以多加几个字节作为协议的报头。第三个字节就是滑板的状态字节了,其中0x02 0x03 0x04 0x05 0xAA 0x0FF分别对应着手机上几个按键,eg: 当按下停车按钮时,手机会向滑板发送 0xA50x5A 0x0FF的信息,滑板通过辨别最后一个字节就会知道是停车。       接下来就是一个简单的处理,比如我通过第三个字节检测到要加速,我就可以通过设置A=0,A1=0,A2=0,B=0,C=1,D=0;(这几个变量是半夜三四点迷糊的时候瞎定的,后续也没改)这几个变量的值,也可以说是置标志位来进行接下来的处理,接下来的处理也就是控制PWM的占空比实现调速,代码实现在主函数的while循环中。   voidpit0_hander() {     if(PIT_TFLG(PIT0) == 1 )        //判断是否 PIT0 进入中断     {       if(sign)          {           sign=0;          if(Re_buff[0]==0xA5)          if(Re_buff[1]==0x5A)      // 协议报头判断          {            if(Re_buff[2]==0x02)    // 加速            {              A=0,A1=1,A2=0,B=0,C=0,D=0;              Re_buff[2]=0x00;                          }            if(Re_buff[2]==0x03)            {              A=0,A1=0,A2=1,B=0,C=0,D=0;              Re_buff[2]=0x00;            }                        if(Re_buff[2]==0x04)            {              A=0,A1=0,A2=0,B=1,C=0,D=0;              Re_buff[2]=0x00;                          }                        if(Re_buff[2]==0x05)                          {              A=0,A1=0,A2=0,B=0,C=1,D=0;              Re_buff[2]=0x00;                          }                        if(Re_buff[2]==0xAA)   // 启动            {              A=1,A1=0,A2=0,B=0,C=0,D=0;              Re_buff[2]=0x00;                          }            if(Re_buff[2]==0xFF)   // 停车            {              A=0,A1=0,A2=0,B=0,C=0,D=1;              Re_buff[2]=0x00;            }           }          }             duiguan=gpio_get(PTA17);    // 以下部分如果不加光电对管可以忽略,主要实现自启停                  if(!qidongflag)            if(!duiguan)         {            BmaCnt=25;             // BmaCnt 为蜂鸣器设置,数值大小控制响的时间的长短            qidongflag=1;          }             if(pwm>=jishupwm)          if(qidongflag)     {            if(!duiguan)            {            zhanli++;            if(zhanli>600)            {            zhanli_flag=1;             zhanli=600;            }            }                         if(zhanli_flag)            if(duiguan)            {            zhanli_flag=1;            zhanli--;            if(zhanli<400)            {             pwm=10000;              zhanli_flag=0;            }          }        }                       if(BmaCnt > 0)             {          gpio_set (PTE2, 1);          BmaCnt--;         }       else       {        gpio_set (PTE2, 0);        }            PIT_Flag_Clear(PIT0);       //清中断标志位     }   } 
 
 4、PWM控制:将PIT转换后的信息进行相应的PWM占空比的设置      举个例子就明白了:比如我加速的信号是0X02,这时候我在PIT中断里面判断第三个字节为0X02为预先设计的加速信号,所以设置了使A=0,A1=1,A2=0,B=0,C=0,D=0;(在3部分代码中实现的),这里我要做的就是判断A1是否为1(只有这里置1了,其余的比如说减速停车信号时,该A1变量均为0),判断为1后进行PWM的设置,设置完之后,滑板就会自动进行加减速。部分实现代码如下:     while(1)    {          if(A&&!A1&&!A2&&!B&&!C&&!D)       qidongflag=1;          if(qidongflag)   {         if(!key_flag)        if(!A&&A1&&!A2&&!B&&!C&&!D)     // 判断 只有A1置 1          {           key_flag=1;           A1=0;                // 进来之后立马清除标志位           pwm=pwm+100;         // PWM加100,进行加速           if(pwm>14000)           pwm=14000;          // 控制最大速度,注意滑行安全           if(pwm<jishupwm)           pwm=jishupwm;            BmaCnt=15;        // 每次手机发送指令,这边进行蜂鸣器哔哔提示,说明加速了           key_flag=0;          } 
 
 5、GPIO模块      进行蜂鸣器和光电对管的检测,其实就是一个高低电平的输出及检测判断,实现起来非常简单,这里就不贴代码了。   
 需要完整代码或细节可blog.csdn.net微博里联系其本人。 
 
 |