【DIY电动滑板车】

本文详述了一个使用Arduino UNO和蓝牙模块控制的电动滑板车设计,包括机械结构、电机选择与控制、主控板遥控模块的搭建。设计亮点在于自动紧急刹车系统和无线遥控功能,采用N5065无刷电机和HC-05蓝牙模块,实现了安全高效的个人代步工具。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Arduino教程传送门🧭🏔🌋🛤🏞🏜

1. 前言

  • 国有共享自行车,国外有共享滑板车。近年来,电动滑板车受到越来越多人的关注,在一些欧美城市甚至成为了个人代步的主力军。电动滑板是以传统滑板为基础,加上手扶杆和电力套件的两/三/四轮交通工具。
  • 相比起电动摩托车、电动自行车,电动滑板车出现的时间相对较晚,并且是随着前两者的发展而逐步完善的。在学校上课有时候比较远,想自己动手做一下代步工具。于是我想起了博人传的电动滑板,打算做一个来玩玩,与此同时拉动大众创新,万众创业。
    在这里插入图片描述

2. 设计方案

本设计采用长板滑板版面,选用直流无刷电机,使用计算机辅助设计(CAD)绘制特殊规格长板滑板的皮带轮及电机架,以航模电池11.1V4500MAH电池供电。配以专用直流无刷电机电调。主控电路与遥控电路均以Arduino UNO为核心,采用PWM脉冲宽度调制方式,使用蓝牙数据通讯协议进行无线数据透传。以下为个模块设计简介。

2.1 机械结构模块

机械模块主要解决传动系统搭建及电机的安装。车架架设计为高64MM,长248MM7.25英寸的支架。传动系统采用同步轮传动,使用皮带连接。齿轮比是大轮36齿,小轮12齿,用5M*270,11带宽齿的齿轮带连接,传动比为3:1,如图电机支架同步轮及配件。
图电机支架同步轮及配件

2.2 电机模块

电机的KV值,决定着电机的转速增加量,KV值越大转速越快。电动滑板在启动时,由于静摩擦的原因,启动的阶段阻力非常大,之后阻力会突然变小。所以,电动滑板在启动之后常常有顿挫感。电机的选择对滑板的安全性的提升显得尤为重要。根据滑板的启动的特性,应选用KV值越小的电机。

2.2.1 电机选择

本设计电机选用N5065外转子无刷电机270KV,其各项参数指标如图左边为无刷电机N5065,右边为C5065
如图左边为无刷电机N5065,右边为C5065

首先从电机型号上来说n5065表示电机尺寸为:直径50mm,长度65mm。前面的n和c表示系列号,其中n系列做工和工作效率高于c系,N电机比C电机功率大,发热小,扭力大。N电机比C电机的磁铁长度和定子长度稍微长一些,n系尾部为平面,c系尾部为锥形。详细参数如下:
在这里插入图片描述可以看到,n5065的功率要比c5065大,一个是1820W,一个是1665W。电压比c5065高,重量也比c5065重50g。(注:这里只说了KV值400得,你也可以选择270的)
根据公式:转速=KV值X电压;
n5065电机转速=KV (400)x22(v)=8800rpm ;
c5065电机转速=KV (400) x20(v)=8000rpm ;

2.2.2 电机控制

单片机的控制信号,可以轻松输出0或1,假设速度峰值的时候控制电压是1,停止时为0,那么中等速度可以用输出0.5来表示。单片机不能直接输出0.5。但可使单片机输出快速的在0和1之间切换,输出结果与0.5相似。输出如图,具体控制采用analogWrite,也可参考舵机控制
在这里插入图片描述

在本设计中使用KV值为270KV的N5065无刷电机,无刷电机和有刷电机有相似之处,也有转子和定子,只不过和有刷电机的结构相反;有刷电机的转子是线圈绕组,和动力输出轴相连,定子是永磁磁钢;无刷电机的转子是永磁磁钢,连同外壳一起和输出轴相连,定子是绕组线圈,去掉了有刷电机用来交替变换电磁场的换向电刷,故称之为无刷电机。依靠改变输入到无刷电机定子线圈上的电流波交变频率和波形,在绕组线圈周围形成一个绕电机几何轴心旋转的磁场,这个磁场驱动转子上的永磁磁钢转动,电机就转起来了,电机的性能和磁钢数量、磁钢磁通强度、电机输入电压大小等因素有关,更与无刷电机的控制性能有很大关系,因为输入的是直流电,电流需要电子调速器将其变成3相交流电,还需要从遥控器接收机那里接收控制信号,控制电机的转速,以满足模型使用需要。相比于传统直流有刷电机相比,无刷电机能量密度高,力矩大,重量轻,性能好等优点。增强了电机的可靠性,但是无刷电机的驱动比有刷电机要复杂得多,需要通过专门的电子驱动器才能正常工作,为降低开发难度的目的,该部分采用了车模用的无刷电机调速器,该调速器可根据输入的PWM信号占空比的大小来控制无刷电机的转速。

2.3 主控板及其遥控模块

本设计选用Arduino UNO作为控制芯片,手机app收发作为上位机遥控。app使用参考

2.3.1 主控芯片选择

Arduino UNO是基于ATmega328P的Arduino开发板。它有14个数字输入/输出引脚(其中6个可用于PWM输出)、6个模拟输入引脚,一个16MHz的晶体振荡器,一个USB接口,一个DC接口,一个ICSP接口,一个复位按钮。它包含了微控制器所需的一切,你只用简单地把它连接到计算机的USB接口,或者使用AC-DC适配器,再或者用电池,就可以驱动它。可参考什么是Arduino?
在这里插入图片描述

2.3.2 无线通信模块的选取

  • 本设计的无线通信模块选择HC-05主从机一体蓝牙模块,该模块能耗低,稳定性强,具有很好的抗干扰能力。选用蓝牙模块以后,可以实现双向通讯,加入显示模块及其他传感器模块后,遥控器可显示电池电量,行驶速度,行驶里程和载重等。为之后功能的增加和改进,提供了便利,同时大量搭载蓝牙的设备可以用于控制滑板,例如开发手机APP控制端,将手机作为遥控端使用。
  • 本设计的遥控器和主控板上,分别有一块Arduino UNO和一个HC-05蓝牙模块。蓝牙模块设置了自动配对之后,上电之后它们就进入“传输”状态,这时,使用函数mySerial.available()及mySerial.read()编写程序,便可实现遥控器与主控板之间的数据传输。我们了解了在Arduino中使用HC05蓝牙模块的两个主要步骤,首先是进入AT模式对蓝牙模块进行设置,这里要注意接线的正确性,设置完成后,就可以将蓝牙模块的TX与Arduino RX连接,RX与Arduino TX连接,再通过Arduino程序中的Serial来实现数据的传输与读取。最后,在通过Android上的蓝牙串口调试APP,来测试我们的试验是否成功。
    在这里插入图片描述
    可参考以下代码,这个可以将自己的蓝牙重命名,快点起个好听的名字吧!😀😀😀
#include <SoftwareSerial.h> 

// Pin10为RX,接HC05的TXD
// Pin11为TX,接HC05的RXD
SoftwareSerial BT(10, 11); 
char val;

void setup() {
  Serial.begin(38400); 
  Serial.println("BT is ready!");
  // HC-05默认,38400
  BT.begin(38400);
}

void loop() {
  if (Serial.available()) {
    val = Serial.read();
    BT.print(val);
  }

  if (BT.available()) {
    val = BT.read();
    Serial.print(val);
  }
}

2.3.3 自动紧急刹车控制

防追尾系统对于驾驶员来说是一大必要辅助驾驶利器。此次设计的防追尾系统主要利用超声波在空气中的传播速度和关系进行测量。超声波具有指向性强、能量消耗慢且在介质中传播距离较远特点。其实说到超声波,我们就会想到蝙蝠,是的,它的工作原理就是模仿蝙蝠的。先发出一个声音,然后在接收返回的声音,通过发出和返回的时间差来可以计算出距离,就这么简单。所以我们就要有一个机制,发出多长的声波信号(和发电报一样),回收采集的理论上应该是发出的同时就要采样收集了。
自动紧急刹车控制

我们的单片机或者这里说的Arduino采用的是单线程的程序运行机制,故而发送的同时肯定不能收集,一般是等发送完毕后开始收集,所以这个模块中则有一个缓冲机制,将收到的信号暂时存储等待设备来读取。编写代码我们一如既往的要使用串口,这里不再赘述。使用超声波模块,我们要特别注意pluseIn函数的使用,它用于检测引脚输出的高低电平的脉冲宽度。pulseIn(pin,value)//value为LOW或者HIGH,pulseIn(pin,value,timeout)可以看出,这和我们之前使用到的digitalWrite基本相同,一般都是两个参数,一个参数是管脚一个是高低电平的设定。实现可参考Arduino 与HC-SRO4超声波传感器的OLED握手

3. 实验步骤

3.1 实验材料

  • 主控板:Arduino Uno R3开发板,sensor shield拓展板,USB数据线

  • 传感器:HC-SRO4超声波传感器,光照传感器

  • 执行器:N5056无刷电机,LED灯,一路高电平触发继电器,有源蜂鸣器

  • 通讯:蓝牙HC05

  • 辅助硬件:滑板,同步带结构,盒子,泡沫,热熔胶,公母线若干

  • 软件:一台安装Arduino开发环境的电脑

3.2 根据原理图搭建电路

  • 蓝牙RX接Arduino的TX,蓝牙TX接Arduino的RX
    有源蜂鸣器引脚2
  • 继电器引脚4,然后单独接led灯与外接电源串联
  • ESC定义无刷电机引脚9,电调提供电源
  • 超声波Trig接6,Echo接5
  • 光照检测接A0

实验原理图:
在这里插入图片描述

3.3 新建sketch

拷贝如下代码并进行保存编译上传
代码:
MIxly模块

在这里插入图片描述

Arduino IDE完整代码

String throttle;
volatile unsigned int speed_min;
volatile unsigned int speed_level;
volatile unsigned int speed_one;
volatile unsigned int speed_two;
volatile unsigned int speed_three;
volatile unsigned int speed_max;
volatile unsigned int speed_add;
volatile long mTime;
volatile long test;
volatile int item;
volatile int length;
volatile int buzzer;
volatile int ledPin;
volatile int ESC;
volatile int light;
volatile boolean heart;

void Action(String throttle) {
  Serial.print(item);
  Serial.print("--");
  if (throttle == "stop") {
    analogWrite(ESC,speed_level);
    pinMode(buzzer, OUTPUT);
    digitalWrite(buzzer,LOW);
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin,LOW);
    throttle = "";
    item = speed_level;
    buzzer2(1, 500);
    Serial.print("stop");

  } else if (throttle == "decrease") {
    if (item > speed_level) {
      for (int i = (item); i >= (item - speed_add); i = i + (-1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    }
    item = item - speed_add;
    buzzer2(1, 100);
    Serial.print("decrease");
  } else if (throttle == "increase") {
    if (item < speed_max) {
      for (int i = (item); i <= (item + speed_add); i = i + (1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    }
    item = item + speed_add;
    buzzer2(1, 200);
    Serial.print("increase");
  } else if (throttle == "one") {
    if (item <= speed_one) {
      for (int i = (item); i <= (speed_one); i = i + (1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    } else {
      for (int i = (item); i >= (speed_one); i = i + (-1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    }
    item = speed_one;
    buzzer2(1, 150);
    Serial.print("speed1");
  } else if (throttle == "two") {
    if (item <= speed_two) {
      for (int i = (item); i <= (speed_two); i = i + (1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    } else {
      for (int i = (item); i >= (speed_one); i = i + (-1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    }
    item = speed_two;
    buzzer2(2, 150);
    Serial.print("speed2");
  } else if (throttle == "three") {
    if (item <= speed_three) {
      for (int i = (item); i <= (speed_three); i = i + (1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    } else {
      for (int i = (item); i >= (speed_three); i = i + (-1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    }
    item = speed_three;
    buzzer2(3, 150);
    Serial.print("speed3");
  } else if (throttle == "four") {
    if (item <= speed_max) {
      for (int i = (item); i <= (speed_max); i = i + (1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    } else {
      for (int i = (item); i >= (speed_max); i = i + (-1)) {
        analogWrite(ESC,i);
        delay(50);
      }

    }
    item = speed_max;
    buzzer2(4, 150);
    Serial.print("speed4");
  } else if (throttle == "turn on") {
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin,HIGH);
    buzzer2(1, 200);
    Serial.print("turn on");
  } else if (throttle == "turn off") {
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin,LOW);
    buzzer2(1, 200);
    Serial.print("turn off");
  } else if (throttle == "buzzer on") {
    buzzer2(2, 300);
    Serial.print("buzzer on");
  } else if (throttle == "buzzer off") {
    buzzer2(2, 100);
    Serial.print("buzzer off");
  }
  Serial.print("--");
  Serial.println(item);
  throttle = "";
}

void lanya() {
  if (Serial.available() > 0) {
    throttle = Serial.readString();
    if (throttle == "start") {
      Serial.println("手机蓝牙模式");
      Serial.println("Start,read go!");
      buzzer2(3, 200);
      do{
        throttle = "";
        throttle = Serial.readString();
        if (throttle == "reset") {
          analogWrite(ESC,speed_min);
          pinMode(buzzer, OUTPUT);
          digitalWrite(buzzer,LOW);
          pinMode(ledPin, OUTPUT);
          digitalWrite(ledPin,LOW);
          heart = 0;
          Serial.println("reset");
          buzzer2(1, 500);
          break;

        }
        if (throttle == "") {
          heart = 1;
          mTime = millis();

        }
        distance();
        if (heart == 1) {
          test = millis();
          if (test - mTime > 10000) {
            throttle = "stop";

          }

        }
        if (throttle != "") {
          Action(throttle);

        }
      }while(true);

    }

  }
}

void buzzer2(int x, int y) {
  for (int i = (1); i <= (x); i = i + (1)) {
    pinMode(buzzer, OUTPUT);
    digitalWrite(buzzer,HIGH);
    delay(y);
    pinMode(buzzer, OUTPUT);
    digitalWrite(buzzer,LOW);
    delay(y);
  }
}

float checkdistance_6_5() {
  digitalWrite(6, LOW);
  delayMicroseconds(2);
  digitalWrite(6, HIGH);
  delayMicroseconds(10);
  digitalWrite(6, LOW);
  float distance = pulseIn(5, HIGH) / 58.00;
  delay(10);
  return distance;
}

void distance() {
  length = checkdistance_6_5();
  if (length < 100) {
    length = checkdistance_6_5();
    if (length < 100) {
      throttle = "stop";
      Serial.print("--");
      Serial.print("distance is:");
      Serial.print(length);
      Serial.print("--");

    }

  }
}

void light_check() {
  light = analogRead(A0);
  if (light < 200) {
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin,HIGH);

  } else {
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin,LOW);

  }
}

void setup(){
  throttle = "";
  speed_min = 80;
  speed_level = 100;
  speed_one = 135;
  speed_two = 150;
  speed_three = 175;
  speed_max = 200;
  speed_add = 10;
  mTime = 0;
  test = 0;
  item = speed_level;
  length = 0;
  buzzer = 2;
  ledPin = 4;
  ESC = 9;
  light = 0;
  heart = 0;
  Serial.begin(9600);
  analogWrite(ESC,speed_level);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin,LOW);
  pinMode(buzzer, OUTPUT);
  digitalWrite(buzzer,LOW);
  // throttle蓝牙接收指令
  // speed_min最小控制速度
  // speed_level启动速度
  // speed_one速度1
  // speed_two速度2
  // speed_three速度3
  // speed_max速度4,也是最大速度
  // speed_add单位速度增加量
  // mTime记录过去的系统时间
  // test记录当前系统时间
  // item速度控制实际值
  // length超声波测的当前距离障碍物距离
  // heart心跳指示
  // buzzer定义有源蜂鸣器引脚2
  // ledPin定义有前灯引脚4
  // ESC定义无刷电机引脚9
  // 超声波Trig接6,Echo接5
  // 光照检测接A0
  pinMode(6, OUTPUT);
  pinMode(5, INPUT);
}

void loop(){
  do{
    lanya();
    delay(10);
    light_check();
  }while(true);

}

3.4 操作:

  • a.首先进行光照检测,如光线较弱则自动打开前灯;
  • b.连接好蓝牙,发送“start”字符串开始遥控,发送“one”,“two”,“three”,“four”即可实现稳步增速,发送“increase”、“dicrease”即可实现精准调速,发送“turn on”、“turn off”即可打开前灯led继电器,发送“buzeer on”、“buzeer off”即可触发有源蜂鸣器声响;
  • c.发送stop即可实现关闭所有增益,发送“reset”即可实现复位跳出循环,再次发送发送“start”字符串又开始遥控。

超声波测距检测前方物体距离小于100cm及时关闭所有增益,起到自动紧急刹车保护,程序中执行动作时有蜂鸣器响应反馈;还有心跳包程序,可判断是否蓝牙断开(若断开及时关闭所有增益,起到失控保护)。
在这里插入图片描述

4. 设计创新点

  • 本次设计开发了基于Arduino 微控制器的电动滑板设计, 加入无线通信 HC-05 蓝牙。
  • 设计并开发了机械零部件,编写主控板及遥控器程序,完成了滑板的设计。
  • 通过测试,本设 计功耗低,续航能力强,能轻松爬陡坡;速度容易调节,可 通过遥控器调节,也可以通过后续开发蓝牙设备上位端调节;
  • 对电机控制有失控保护程序,当电机在运转的时,如果与上 位机断开连接时,Arduino 微控器会将油门值降为零,大大的避免了安全事故;
  • 本设计还留有其他接口,方便产品的后 续研发与升级,并预留了一定的扩展空间。

5. 项目小结

  • 其实小组成员觉得有些无从下手。在经过老师在课下的讲解之后,发现需要分阶段来完成相关功能,并且提供相关技术支持,也就是有很多需要同学之间合作的内容,还找过车工电焊老师帮忙,经过一个星期合理解决动力传动系统。最终在我们组员几个人的合作下终于完成了这次的课程设计,看到滑板动起来我们也觉得很有成就感。
  • 历时半年的设计结束了,虽然有时开会不方便,我们采取灵活的线上线下会议,老师实时测评,高效平稳推动项目良性发展这一设计过程不仅是对我们知识应用能力的考验,更是对我们的细致,认真,耐心和与人合作的团队精神的考验,而这些品质,无疑是我们未来作为一个机械工程师必须和应有的职业品质,也为明年的毕业设计打下了一个很好的基础。这次的科研立项磨练了我们的细心和耐心,同时团队合作也培养了我们与人合作的能力,加深了我们同学之间的感情。
  • 但我们这次的设计也还是有很多不足之处,仍需要进一步改进。在以后的此类设计中我们应吸取这次的经验教训,更加完善设计。根据项目的进展适时调整下一步的规划,脚踏实地,慢慢达到设计要求和老师的标准。这个滑板虽然电池出现供电故障,但更换电池后来回上课打卡累计安全行驶100公里以上最后尝试发表一篇关于电动滑板车学术性论文;并且完成对电动滑板车结构的优化设计;努力完成科研项目的基本任务。

6. 专家鉴定意见

  • 该课题组同学通过市场调研并结合自己所学专业背景,提出了开发电动滑板车的研究课题,该课题将机械与电子有机结合,形成完整的开发方案,经过课题组同学们的辛苦工作,将设计图纸变成实物样品,是一件非常难得的作品,作品实现了当初设计时的各项功能,满足了预先构想,特别是将目前机电产品开发过程中经常需要运用的软件和硬件知识完美掌握,并能结合实际做出样品,非常可贵。
  • 课题的开展锻炼同学们各方面的能力,到达了预期效果,完成各项任务,建议同意结题。
    相关说明书及代码
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2345VOR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值