查看“BOXZ mini/zh”的源代码
←
BOXZ mini/zh
跳转至:
导航
、
搜索
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
{| style="width: 800px;" |- | ==概述== *项目名称:Microduino机器人小车 *目的:通过Microduino Joypad来控制BOXZ mini机器人小车 *难度:高级 *耗时:3小时 *制作者:Microduino Studio-YLB ==材料清单== *Microduino设备 {|class="wikitable" |- |模块||数量||功能 |- |[[Microduino-Core/zh]]||1||核心板(Joypad) |- |[[Microduino-Core+/zh]]||1||核心板(Robot) |- |[[Microduino-USBTTL/zh]]||1||下载程序 |- |[[Microduino-nRF24/zh]]||2||无线通讯 |- |[[Microduino-Joypad/zh]]||1||遥控 |- |[[Microduino-TFT/zh]]||1||显示 |- |[[Microduino-Motor/zh]]||1||四轴电机驱动 |- |[[Microduino-Robot/zh]]||1||驱动连接底板 |} *其他设备 {|class="wikitable" |- |模块||数量||功能 |- |机器小车机架||1||车体 |- |螺丝||18||固定 |- |螺母||8||固定 |- |Micro-USB数据线||1||下载程序 |- |车轮||1||车体 |- |电机||1||驱动车轮 |- |电池||1||供电 |} [[File:Boxz物料.jpg||600px|center|thumb]] ==实验原理== 机器人小车种类比较多,如循迹,壁障,蓝牙遥控小车,电脑鼠等。但是其行走控制方式基本是一样的,无非就是前后左右四个方向运动。当然结构上会有一定区别,不同功能需要采用不同传感器,本次我们主要使用两轮驱动,通过控制两个轮子的旋转方向,实现前进后退,旋转等功能,当然还要加上万向轮,这样才能保持平衡。 该小车结构简单,主要包括三个方面:车轮、车身、控制系统。 1)车轮采用两个减速电机,扭力大,可PWN调速,控制简单。 2)车身采用亚克力板,大小:8cm*8cm*8cm。 3)整个控制系统包括四个部分: *供电系统 因为BOXZ体积比较小,所以采用锂电池。 *中央处理器 中央处理器是整个小车的核心,就像电脑的CPU,人的大脑,有一定思维能力,能够处理复杂事件。采用Microduino-Core作为核心。 *无线通讯 小车采用Microduino-nRF24无线通讯方案,通讯速度响应快,控制范围:空阔地域大约100米。 *电机控制 采用Microduino-Motor直流电机驱动模块,一个模块能够驱动两个电机。同时结合Microduino-Robot底板,将中央处理器和直流电机模块连接起来。 ==文档== ==调试过程== 将Microduino Core、Microduino USBTTL堆叠在一起.用数据线将写好的程序通过Microduino USBTTL上传到Microduino Core上。 注意:最好不要将所有模块堆叠在一起之后再上传程序 [[File:download1.jpg||500px|center|thumb]] 打开Aroduino IDE,若电脑中没有安装,则参照附录中的安装方法,先安装Aicroduino IDE。点击左上【文件】选项→点击【打开】。 [[File:Bleopen.jpg||500px|center|thumb]] 浏览到项目程序地址,点击“Robot_v0.2.ino”程序打开 [[File:Boxzopen1.jpg||500px|center|thumb]] [[File:Boxzopen2.jpg||500px|center|thumb]] 之后点击左上角的"√"进行编译,点击上边栏的工具,确认板卡(Microduino-Core)处理器(Atmega328P@16M,5V)和端口号(COMX)。三项都如图确认无误之后点击"→"按钮下载程序到开发板上 [[File:Boxz步骤.jpg||500px|center|thumb]] Joypad操作说明 [[File:Joypadtest.jpg||300px|center|thumb]] [[File:Joypad物料.jpg||300px|center|thumb]] *左上边是油门控制开关,打开(拨到上面),才能进行控制,你可以摇动摇杆,观察屏幕的变化。 *右边开关是精度调整开关,开关拨到上面可以最大幅度控制,否则只能小幅度控制了,小幅度有助于稳定控制。 *左边摇杆本次未使用。 *右边摇杆在垂直方向上控制前后方向移动,往上向前,往下向后,在水平方向上控制左右方向移动。 Joypad开机设置 [[File:Joypadtest1.jpg||300px|center|thumb]] 打开遥控器电源开关,按下复位按键(左边USB接口右边那个)进入系统,请在4S内按下【key1】按键,进入遥控器校准和控制选择模式。 360度最大幅度旋转两个摇杆,遥控板会读入摇杆的位置数据,摇动至示数不再变化即可 [[File:Joypadtest2.jpg||300px|center|thumb]] 选择控制模式,可以通过【key3】按键来选择是控制四轴飞行器(Quad.)还是机器人(Robot),Robot模式可控制自平衡车和BOXZ mini,黑色表示选中。因此我们需要选择Robot模式。还可以通过【key4】按键来选择是否是体感控制模式,如果选择体感模式,你必须叠加Microduino-10DOF模块,选择“MPU ON”。如果是摇杆控制模式,选择“MPU OFF”。 这次搭建没有使用10DOF模块,因此选择MPU OFF模式; [[File:Joypadtest3.jpg||300px|center|thumb]] 选择完成后,通过【key2】按键退出配置,进入操作 [[File:Joypadtest4.jpg||300px|center|thumb]] 将左上边控制开关打开(拨到上面),才能进行控制,你可以摇动摇杆,观察屏幕的变化 [[File:Joypadtest5.jpg||300px|center|thumb]] 右边开关是幅度调节模式,开关拨到上面可以最大幅度控制Robot,否则只能小幅度控制。如果使用小幅度控制小车,右边摇杆拨到最大位置,小车速度也只能小范围变化,这样有助于稳定控制 [[File:Joypadtest6.jpg||300px|center|thumb]] 当启动小车时,只需要用到右边的摇杆,摇杆的方向和平衡车的方向一致,你可以尝试摇杆控制是否正确。如果发现方向有问题,可以在Robot_v0.2前4行代码更改引脚定义 如果原来的引脚定义如下: [[File:Boxzpin1.jpg||300px|center|thumb]] 而此时左右旋转反了,可以更改为 [[File:Boxzpin2.jpg||300px|center|thumb]] 如果最开始的引脚是情况2,那么方向错了就改成情况1就可以了。 打开BOXZ_mini小车上Microduino-Robot底板上的电源开关,拨到ON(左边),如果可以看到核心板上的红色led亮,说明供电正常。你可以愉快的玩耍了。 ==注意问题== *下载程序时候最好只叠加core(core+)和USBTTL,虽然本次搭建涉及的nRF24不会引起冲突,但是别的通信模块有时会造成串口冲突,养成好习惯。 *锂电池正负极别接错了,否则会烧坏电路。 *调试好后,实际运行时不要使用USB供电,电压不足,请使用电池。 ==小车程序说明== <source lang="cpp"> #define motor_pin0A 7 //PWM #define motor_pin0B 5 #define motor_pin1A 8 //PWM #define motor_pin1B 6 #define FIX_THROTTLE_A 1 //-1 or 1 #define FIX_THROTTLE_B -1 //-1 or 1 #define REVERSE_THROTTLE 1 //-1 or 1 #define REVERSE_STEERING 1 //-1 or 1 #define MAX_THROTTLE 255 //最大油门 100~255 #define MAX_STEERING 200 //最大转向 100~512 //rf======================================= #include <RF24Network.h> #include <RF24.h> #include <SPI.h> // nRF24L01(+) radio attached using Getting Started board RF24 radio(9, 10); RF24Network network(radio); const uint16_t this_node = 1; //设置本机ID const uint16_t other_node = 0; //-------------------------------- struct send_a //发送 { uint32_t node_ms; //节点运行时间 }; unsigned long last_sent = 0; //定时器 //-------------------------------- struct receive_a //接收 { uint32_t ms; uint16_t rf_CH0; uint16_t rf_CH1; uint16_t rf_CH2; uint16_t rf_CH3; uint16_t rf_CH4; uint16_t rf_CH5; uint16_t rf_CH6; uint16_t rf_CH7; }; unsigned long clock; //主机运行时间 int tem_xuan = 0; //主机请求时序 //---------------------------- boolean node_STA = false; float throttle; float steering; unsigned long safe_ms = millis(); void setup() { Serial.begin(115200); pinMode(motor_pin0A, OUTPUT); pinMode(motor_pin0B, OUTPUT); pinMode(motor_pin1A, OUTPUT); pinMode(motor_pin1B, OUTPUT); //nRF============================== SPI.begin(); //初始化SPI总线 radio.begin(); network.begin(/*channel*/ 70 , /*node address*/ this_node); Serial.println("===========start==========="); } int motor_vol[2]; // 主循环////////////////////////////////////////////////////////////////////////// void loop() { //=============================================================== if (nRF(&throttle, &steering)) { vorobot(); Serial.print(throttle); Serial.print(","); Serial.println(steering); } //=============================================================== if (safe_ms > millis()) safe_ms = millis(); if (millis() - safe_ms > 2000) { steering = 0; throttle = 0; digitalWrite(motor_pin0A, LOW); digitalWrite(motor_pin0B, LOW); digitalWrite(motor_pin1A, LOW); digitalWrite(motor_pin1B, LOW); } } void vorobot() { /* if(node_STA) { } */ //=============================================================== int motor_speed = 0; motor_speed = REVERSE_THROTTLE * throttle; motor_vol[0] = motor_speed; motor_vol[1] = motor_speed; //---------------------------------- int motor_steer = 0; motor_steer = REVERSE_STEERING * steering; motor_vol[0] -= motor_steer / 2; motor_vol[1] += motor_steer / 2; for (int a = 0; a < 2; a++) { if (motor_vol[a] > MAX_THROTTLE) { motor_vol[0] -= (motor_vol[a] - MAX_THROTTLE); motor_vol[1] -= (motor_vol[a] - MAX_THROTTLE); } else if (motor_vol[a] < -MAX_THROTTLE) { motor_vol[0] -= (MAX_THROTTLE + motor_vol[a]); motor_vol[1] -= (MAX_THROTTLE + motor_vol[a]); } } Serial.print(motor_vol[0]); Serial.print(","); Serial.print(motor_vol[1]); Serial.println(""); motor_vol[0] *= FIX_THROTTLE_A; motor_vol[1] *= FIX_THROTTLE_B; motor_driver(0, -motor_vol[0]); motor_driver(1, motor_vol[1]); } boolean motor_driver(int _motor_driver_num, int _motor_driver_vol) { switch (_motor_driver_num) { case 0: if (_motor_driver_vol == 0) { //Serial.println("0 OFF"); digitalWrite(motor_pin0A, LOW); digitalWrite(motor_pin0B, LOW); } else if (_motor_driver_vol > 0) { //Serial.println("0 Z"); analogWrite(motor_pin0A, _motor_driver_vol); digitalWrite(motor_pin0B, LOW); } else { //Serial.println("0 F"); analogWrite(motor_pin0A, 255 + _motor_driver_vol); digitalWrite(motor_pin0B, HIGH); } break; case 1: if (_motor_driver_vol == 0) { //Serial.println("1 OFF"); digitalWrite(motor_pin1A, LOW); digitalWrite(motor_pin1B, LOW); } else if (_motor_driver_vol > 0) { //Serial.println("1 Z"); analogWrite(motor_pin1A, _motor_driver_vol); digitalWrite(motor_pin1B, LOW); } else { //Serial.println("1 F"); analogWrite(motor_pin1A, 255 + _motor_driver_vol); digitalWrite(motor_pin1B, HIGH); } break; default : return false; } return true; } boolean nRF(float * _speed, float * _turn) { network.update(); // Is there anything ready for us? while ( network.available() ) { // If so, grab it and print it out RF24NetworkHeader header; receive_a rec; network.read(header, &rec, sizeof(rec)); clock = rec.ms; //接收主机运行时间赋值 float * _i = _speed; _i[0] = map(rec.rf_CH1, 1000, 2000, -MAX_THROTTLE, MAX_THROTTLE); _i = _turn; _i[0] = map(rec.rf_CH0, 1000, 2000, -MAX_STEERING, MAX_STEERING); node_STA = (rec.rf_CH7 > 1500 ? true : false); //接收请求时序赋值 { //Serial.print("Sending..."); send_a sen = { millis() }; //把这些数据发送出去,对应前面的发送数组 RF24NetworkHeader header(0); boolean ok = network.write(header, &sen, sizeof(sen)); safe_ms = millis(); if (ok) { return true; //Serial.println("ok."); } else { return false; //Serial.println("failed."); } } safe_ms = millis(); } } </source> ==Joypad程序说明== <source lang="cpp"> #include "Arduino.h" #include "def.h" #include "time.h" #include "bat.h" #if defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega128RFA1__) #include "mpu.h" #endif #include "joy.h" #include "key.h" #include "data.h" #include "nrf.h" #include "mwc.h" #include "tft.h" #include "eep.h" #if defined(__AVR_ATmega128RFA1__) #include <ZigduinoRadio.h> #endif //joypad================================ #include <Joypad.h> //eeprom================================ #include <EEPROM.h> //TFT=================================== #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific #include <SPI.h> //rf==================================== #include <RF24Network.h> #include <RF24.h> #if defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega128RFA1__) //MPU=================================== #include "Wire.h" #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #endif //spi=================================== #include <SPI.h> void setup() { // initialize serial communication at 115200 bits per second: #ifdef Serial_DEBUG Serial.begin(115200); delay(100); Serial.println("========hello========"); #endif //--------------- key_init(); //--------------- #ifdef Serial_DEBUG Serial.println("\n\r EEPROM READ..."); #endif eeprom_read(); //--------------- #ifdef Serial_DEBUG Serial.println("\n\r TFT INIT..."); #endif TFT_init(true, tft_rotation); //--------------- #ifdef Serial_DEBUG Serial.println("\n\r TFT BEGIN..."); #endif TIME1 = millis(); while (millis() - TIME1 < interval_TIME1) { TFT_begin(); if (!Joypad.readButton(CH_SWITCH_1)) { #ifdef Serial_DEBUG Serial.println("\n\rCorrect IN..."); #endif //--------------- #ifdef Serial_DEBUG Serial.println("\n\r TFT INIT..."); #endif TFT_init(false, tft_rotation); while (1) { if (!TFT_config()) break; } #ifdef Serial_DEBUG Serial.println("\n\rCorrect OUT..."); #endif //--------------- #ifdef Serial_DEBUG Serial.println("\n\r EEPROM WRITE..."); #endif eeprom_write(); } } //--------------- #ifdef Serial_DEBUG Serial.println("\n\r TFT CLEAR..."); #endif TFT_clear(); //--------------- #ifdef Serial_DEBUG Serial.println("\n\r TFT READY..."); #endif TFT_ready(); //---------------.l if (mode_protocol) //Robot { SPI.begin(); //初始化SPI总线 radio.begin(); network.begin(/*channel*/ nrf_channal, /*node address*/ this_node); } else //QuadCopter { unsigned long _channel; #if !defined(__AVR_ATmega128RFA1__) switch (mwc_channal) { case 0: _channel = 9600; break; case 1: _channel = 19200; break; case 2: _channel = 38400; break; case 3: _channel = 57600; break; case 4: _channel = 115200; break; } #else if _channel = mwc_channal; #endif mwc_port.begin(_channel); } //--------------- #ifdef Serial_DEBUG Serial.println("===========start==========="); #endif #if defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega128RFA1__) if (mode_mpu) initMPU(); //initialize device #endif } void loop() { // unsigned long time = millis(); #if defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega128RFA1__) //MPU-------------------------------- if (mode_mpu) getMPU(); #endif //DATA_begin------------------------------ data_begin(); //DATA_send------------------------------- if (millis() < time2) time2 = millis(); if (millis() - time2 > interval_time2) { if (mode_protocol) nrf_send(); //Robot else data_send(); //QuadCopter time2 = millis(); } //节点查错------------------------------- vodebug(); //BAT-------------------------------- if (time3 > millis()) time3 = millis(); if (millis() - time3 > interval_time3) { vobat(); time3 = millis(); } //TFT------------------------------------ TFT_run(); //=================================== // time = millis() - time; // Serial.println(time, DEC); //loop time } </source> ==视频==
返回至
BOXZ mini/zh
。
导航菜单
个人工具
创建账户
登录
名字空间
页面
讨论
变种
视图
阅读
查看源代码
查看历史
更多
搜索
Welcome
首页
创客大赛
大赛详情
3D打印
安装月球车
图形化编程
操控月球车
升级月球车
编程工具下载
软件下载
Arduino
Processing
Mixly
Scratch
模块套件
Microduino 102
mCookie 102
mCookie 202
mCookie 302
IBC
其他
应用套件
四轴飞行器
平衡车
小车CUBE
音乐播放器
刷卡音乐播放器
wifi气象站
彩虹音乐触摸灯
分贝检测仪
迎门汇报
LED点阵时钟
LED点阵屏幕
硬件
mCookie
Sensor
Microduino
MicroWrt
MicroNux
MicroRobot-Core
MicroRobot-CoreESP
ideaBoard
ideaBox
MicroMV
MicroAI
帮助
常见问题
帮助
工具
链入页面
相关更改
特殊页面
页面信息