电滑板攻略 – 主控板程序

这一部分内容也许会有点儿枯燥,对Arduino了解不多的同学,可能要先去预习一下。如果大家有需要的话,我也可以考虑发一系列Arduino的入门教程 :)

主控板是指的装在滑板上的那一部分电路板,首先贴一下电路原理图:
电动滑板源代码

电动滑板源代码

对着原理图,说说电滑板的几个功能:
1. JP1用来连接电调,这部分电路的供电也是从电调来来。说到这里顺便说一句,很多电调自带BEC功能,可以提供5V或6V的电压给单片机用。
电流可以支持到1A以上,带动各种传感器完全无压力。但是如果要点亮灯带或者响个大喇叭的话,就需要从电池直接引电压。
2. 标记SPK是个无源小喇叭,通过一定频率的方波来发出声音。
3. 中间那个方块就是Arduino pro mini,选用的是5V 16M的版本,它就是整个控制系统的“神经中枢”
4. Bluetooth就是蓝牙的插座,我们选用的蓝牙模块一共有6根针,我们用了最简的四根针方案,如果你需要修改蓝牙设置,得手动用夹子给Key针脚接高电平
5. LDR和4k7,是一个光敏电阻和一个4k7的电阻。一般的光敏电阻,电阻值随着光线的增大而减小,我们通过测量获取的电压,就可以评估当前的环境亮度。这样晚上天黑的时候,滑板的夜行灯就可以自动亮起来了
6. 那4个圆圈,它的目标是当主板需要采电时,把电池的正负极接到这里,然后再引出去。因为电压比较高电流比较大,所以一共4个大圆圈。
7. 圆圈边上的JP3,是用来接灯带的,因为我们用的是6S的电池,电压平时在24V左右,所以可以选用两条12V的灯带串联一下。
灯带边上是场效应管,你可以理解为一个电子开关,通过输入0或者1来关闭或打开灯带。
8. 左下角的JP2 是个独立的东西,它的作用是把原来电调的开关引到这个板子上来,避免甩着一个小尾巴(这个功能不用也可以)
代码如下,有些地方我写了注释,不好理解的地方请大家留言,我在后续的攻略里会继续介绍。
  1. #include <EEPROM.h>
  2. #include <Servo.h>
  3. #include <SoftwareSerial.h>
  4. SoftwareSerial mySerial(11, 5); //Product board
  5. int motorPin = 12;    // The pin output PWM to control motor
  6. int motorPin2 = 0;   // For the new board with 2 motors, if motorPin2 < 0, then ignore it
  7. int hornPin = 10;
  8. int hornOffTime = 1000; // Cannot use horn too long, must less than 1s
  9. int hornStartTime = 0;
  10. int power = 50;       // Control pow value, from 0 to 100;
  11. long lastRecvTime = 0; // If cannot recv control info in 0.2s, stop the moto
  12. int shutDownTimeRange = 200;
  13. int powerScale = 100;  //if set the power scale by mobile
  14. int testingValue = 0;
  15. int lightMode = 2;   // 1: on; 2:off; 3: auto
  16. int lightCtrlPin = 10;
  17. int envLightSensorPin = 1;
  18. boolean lightStatus = false;  // shutdown ligth by default
  19. Servo powerServo;
  20. Servo powerServo2;
  21. // The Led pin for debug
  22. int ledPin = 13;
  23. int light = 1;
  24. int counter = 0;
  25. // Beep pin
  26. int beepPin = 6;
  27. boolean beepStatus = false;
  28. // Connect to speaker
  29. int tonePin = 6;
  30. // battery pin
  31. int batteryPin = 0;
  32. float batteryScale = 11;
  33. float batteryAlert = 3.5;
  34. void setup()
  35. {
  36. pinMode(ledPin,OUTPUT);
  37. pinMode(beepPin,OUTPUT);
  38. pinMode(lightCtrlPin,OUTPUT);
  39. pinMode(hornPin,OUTPUT);
  40. powerScale = EEPROM.read(0);
  41. if (powerScale <= 0 || powerScale > 100) powerScale = 100;
  42. lightMode = EEPROM.read(1);
  43. if (lightMode <= 0 || lightMode > 3) lightMode = 2; // default light off
  44. Serial.begin(9600);
  45. mySerial.begin(9600);
  46. powerServo.attach(motorPin);
  47. if (motorPin2 > 0) powerServo2.attach(motorPin2);
  48. }
  49. void checkBattery()
  50. {
  51. if (counter == 0 || counter == 200) {
  52. int readValue = analogRead(batteryPin);
  53. if (readValue > 5 && batteryScale * readValue / 1024 * 5 < batteryAlert * 6) {
  54. digitalWrite(beepPin, beepStatus);
  55. beepStatus = !beepStatus;
  56. } else {
  57. digitalWrite(beepPin, 0);
  58. }
  59. }
  60. }
  61. void updateCounter() {
  62. counter++;
  63. if (counter >= 400) counter = 0;
  64. }
  65. void switchLight()
  66. {
  67. if (counter == 0) {
  68. digitalWrite(ledPin, light);
  69. light = 1 - light;
  70. //Serial.println(testingValue);
  71. }
  72. }
  73. void sendPowerInfo()
  74. {
  75. if (counter == 0) {
  76. mySerial.write((byte)(analogRead(batteryPin) / 4));
  77. }
  78. }
  79. void loop()
  80. {
  81. long t0 = micros();
  82. int readPower = -1;
  83. while(mySerial.available()) {
  84. readPower = mySerial.read();
  85. lastRecvTime = micros();
  86. digitalWrite(ledPin, light);
  87. light = 1 - light;
  88. //counter = 0;
  89. if (readPower > 100) {
  90. break;
  91. }
  92. }
  93. if (readPower > -1 && readPower <= 100) {
  94. // Normal status
  95. power = readPower;
  96. }
  97. if (readPower == 255 || (lastRecvTime > 0 && (t0-lastRecvTime)/1000 > shutDownTimeRange)) {
  98. power = 50; // 松手默认滑行
  99. }
  100. if (readPower > 100 && readPower <= 200) {
  101. powerScale = readPower - 100;
  102. EEPROM.write(0, (byte) powerScale);
  103. }
  104. if (readPower > 200 && readPower <= 203) {
  105. lightMode = readPower - 200;
  106. EEPROM.write(1, (byte) lightMode);
  107. }
  108. if (readPower == 204) {
  109. digitalWrite(hornPin, 1);  // start horn
  110. hornStartTime = t0;
  111. tone(tonePin, 4000);
  112. }
  113. //if (readPower == 205 || (hornStartTime > 0 && (t0 - hornStartTime) / 1000 > hornOffTime)) {
  114. if (readPower == 205) {
  115. digitalWrite(hornPin, 0);  // stop horn
  116. hornStartTime = 0;
  117. noTone(tonePin);
  118. }
  119. // light control
  120. if (lightMode == 1) {
  121. // light on
  122. digitalWrite(lightCtrlPin, 1);
  123. lightStatus = true;
  124. } else if (lightMode == 2){
  125. // light off
  126. digitalWrite(lightCtrlPin, 0);
  127. lightStatus = false;
  128. } else {
  129. //auto
  130. int envLight = analogRead(envLightSensorPin);
  131. testingValue = envLight;
  132. if (!lightStatus && envLight < 800) {
  133. lightStatus = true;
  134. }
  135. if (lightStatus && envLight > 900) {
  136. lightStatus = false;
  137. }
  138. digitalWrite(lightCtrlPin, lightStatus);
  139. }
  140. updateCounter();
  141. switchLight();
  142. checkBattery();
  143. double T = 2500;
  144. // if has power scale
  145. double scaledPower = power;
  146. if (power > 50) {
  147. scaledPower = 50 + (power - 50) * powerScale / 100;
  148. }
  149. double len = 900 + scaledPower * 12; //(0~100对应总周期0.9ms~2.1ms)
  150. powerServo.writeMicroseconds(len);
  151. if (motorPin2 > 0) powerServo2.writeMicroseconds(len);
  152. int leftMs = (int) (t0 + T - micros());
  153. if (leftMs > 1500 && (t0-lastRecvTime)/1000 < shutDownTimeRange) {
  154. sendPowerInfo();
  155. leftMs = (int) (t0 + T - micros());
  156. }
  157. if (leftMs < 1) leftMs = 1;
  158. delayMicroseconds(leftMs);
  159. }
不知道为什么,这里的源代码格式功能不好用了,如果需要做过高亮的代码,请点击这里:


对 “电滑板攻略 – 主控板程序” 的 7 条 评论

  1. 朱冰清 说:

    …………想要入门教程……可以的话可以发一份吗
    谢谢

  2. 朱冰清 说:

    或者有什么书可以推荐下吗 最近在图书馆找了几本书也看了下 不过…………大学学的是机械工程的 没什么太大的基础 很多都看不懂 基本没啥基础T^T 对了 我邮箱是 zyjzbqgz@163.com

    • 有一本特别基础的书,叫”爱上arduino“

      • 朱冰清 说:

        谢谢啦 今天去图书馆找到了这本书 的确很基础呢 还找到一本 Arduino编程从零开始 感觉 也挺好的 教关于编程放面的 然后今天就实验了下 用之前买的arduino入门套装 想做一个那个书上说的 调光按钮 就是 按一下灯亮 按住不放灯会有变化 但失败了………………情况变成 按一下 等亮了 然后灯就开始变化 等再按一下灯就灭了QAQ

        • 是彩色灯吗?那是你的LED选了彩光的,只要通了电就会变色 :)

          • 朱冰清 说:

            嗯 对的 一通电就开始亮了 明明程序上不是这么写的T^T

            const int led = 9;
            const int kaiguan = 7;
            int zhuangtai = 0;
            int val = 0;
            int vval = 0;
            unsigned long st = 0;
            int liangdu = 128;

            void setup()
            {
            pinMode(led,OUTPUT);
            pinMode(kaiguan,INPUT);
            //vval=digitalRead(kaiguan); 不知道为什么这里再加上这 句就可以通电后不亮,不加的话通电就直接亮了//
            }

            void loop()
            {
            val = digitalRead(kaiguan);

            if((val == HIGH)&&(vval == LOW))
            {
            zhuangtai = 1 – zhuangtai;
            st = millis();
            };

            if((val == HIGH)&&(vval == HIGH))
            {
            if( zhuangtai==1 &&(millis() – st )>100)
            {
            liangdu++;
            delay(10);
            };
            };

            vval = val;

            if(zhuangtai==1)
            {
            analogWrite(led,liangdu);
            }
            else
            {
            analogWrite(led,0);
            };
            }

  3. JeffBao 说:

    赞一个~!

发表评论

可以使用下列 XHTML 标签:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>