基于BBB的4轮移动轮式机器人系统设计与实现(四)--BeagleBone Black PWM 应用程序开发
2015-04-24 23:10
555 查看
在BBB开发板中,PWM的应用程序一共有三个类:PWM基类、PWM舵机类、PWM电机控制类
PWM基类表示PWM引脚的通用功能,如加载PWM引脚所对应的设备树、加载PWM定时器等
PWM基类定义
PWM基类实现
PWM舵机控制类定义
PWM舵机控制类实现
PWM电机控制类定义
PWM电机控制类实现
应用方法:
PWM基类表示PWM引脚的通用功能,如加载PWM引脚所对应的设备树、加载PWM定时器等
PWM基类定义
/* * BeagleBonePWM.h * * Created on: 2014-6-9 * Author: sfe1012 */ #ifndef BEAGLEBONEPWM_H_ #define BEAGLEBONEPWM_H_ #include <string> #include <dirent.h> #include <fstream> #include <sstream> #include <iostream> #include <unistd.h> const std::string PIN_MOTOR_FORWARD("P8_13"); const std::string PIN_MOTOR_BACK("P8_19"); const std::string PIN_SERVO_DERECTION("P9_14"); const std::string PIN_SERVO_SHOOK_HEAD("P9_16"); const std::string PIN_SERVO_NOD_HEAD("P9_21"); const int MICRSECONDS_TO_NANOSECONDS = 1000;//微秒 转换 纳秒 const int MILLISECONDS_TO_MICROSECONDS = 1000;//毫秒 转换 微妙 const int MILLISECONDS_TO_NANOSECONDS = MILLISECONDS_TO_MICROSECONDS * MICRSECONDS_TO_NANOSECONDS; //毫秒 转 纳秒 const long MODULE_DELAY_TIME_US = 100 * MILLISECONDS_TO_MICROSECONDS; // Time to wait for module to be loaded and the sysfs interface setup //#define DEBUG_VERBOSE_OUTPUT 1 namespace PWM { template<class T> inline std::string ToString(const T & value) //模板函数 数据类型转换 { std::stringstream ss; ss << value; return ss.str(); } inline void WriteToFile(const std::string & filePath, const std::string & value)//命令字写入相应的 管脚 对应的 属性文件 { #if DEBUG_VERBOSE_OUTPUT std::cout << "Writing: " << value << " to: " << filePath << std::endl; #endif std::ofstream out; out.open(filePath.c_str()); out.exceptions(std::ios::badbit); out << value << std::endl; out.close(); } // A bunch of helper functions to get us locations in the file system. // They are used so that we can manipulate the pwm driver through the /sys interface //这个函数将会返回在 dirname目录下 文件名称为filenameTofind 文件名 std::string GetFullNameOfFileInDirectory(const std::string & dirName, const std::string & fileNameToFind); std::string GetCapeManagerSlotsPath();//获得slots 目标名称 std::string GetOCPPath();//获得ocp的文件目录 int GetCapeManagerSlot(const std::string & moduleName);//获取设备模块 当得到的时候 就返回 设备号 void LoadDeviceTreeModule(const std::string & name);//加载设备模块 到 设备树 void UnloadDeviceTreeModule(const std::string name);//卸载设备模块 设备树 class Pin //管脚类 { public: enum RunStatus { Free = -2, WaitingForSetp, Disabled, Enabled,//-1、0、1 }; enum Polarity { PolaritryHigh = 0, PolarityLow, // 1 }; private: std::string m_dutyFilePath;//管脚 占空比设置 文件位置 std::string m_periodFilePath;//管脚 周期设置 文件位置 std::string m_polarityFilePath;//管脚 输出占空比 极性 (BBB默认情况下,1表示占空比的输出为负,0表示为正) std::string m_runFilePath;//管脚 运行 控制位 std::string m_pinName;//管脚 命名 long m_periodNS; // 周期 纳秒单位 long m_dutyNS; //占空比 纳秒单位 Polarity m_polarity; //极性 RunStatus m_runStatus; //运行状态 public: /*********SFE ADD*****************/ void LoadDeviceTreeModuleForEspecial(const std::string &strName)const { LoadDeviceTreeModule(strName);//加载设备模块 到 设备树 } /************************************/ const std::string &GetDutyFilePath() const//获取占空比设置文件的位置 { return m_dutyFilePath; } const std::string &GetPeriodFilePath() const//获取周期设置文件的位置 { return m_periodFilePath; } const std::string &GetPolarityFilePath() const//获取极性设置文件的位置 { return m_polarityFilePath; } const std::string &GetPinName() const//获取管脚的名字 { return m_pinName; } const std::string &GetRunFilePath() const //获取管脚 运行管理的文件位置 { return m_runFilePath; } const RunStatus &GetRunStatus() const //获取管脚 运行状态 { return m_runStatus; } const long &GetPeriodNS() const //获取周期 纳秒为单位 { return m_periodNS; } const Polarity &GetPolarity() const //获取 管脚的极性 { return m_polarity; } const long &GetDutyNS() const // 获取 管脚的占空比 纳秒为单位 { return m_dutyNS; } private: void WriteDutyNSToFile() //向占空比 设置文件 写入命令 { WriteToFile(GetDutyFilePath(), ToString(GetDutyNS())); } void WritePeriodNSToFile() // 向周期 设置文件 写入命令 { WriteToFile(GetPeriodFilePath(), ToString(GetPeriodNS())); } void WritePolarityToFile() //向 极性控制 文件 写入命令 { WriteToFile(GetPolarityFilePath(), GetPolarity() == PolaritryHigh ? std::string("0") : std::string("1")); } public: //占空比设置 void SetDutyNS(const long & dutyNS)//纳秒 { m_dutyNS = std::min(dutyNS, GetPeriodNS()); if (GetRunStatus() == Enabled) WriteDutyNSToFile(); } void SetDutyUS(const int &dutyUS)//微妙 { SetDutyNS((long) dutyUS * MICRSECONDS_TO_NANOSECONDS); } void SetDutyMS(const int &dutyMS)//毫秒 { SetDutyNS((long) dutyMS * MILLISECONDS_TO_NANOSECONDS); } void SetDutyPercent(const float &percent) { SetDutyNS(long(GetPeriodNS() * percent)); } //周期设置 void SetPeriodNS(const long & periodNS)//纳秒 { if (GetRunStatus() == Enabled || GetRunStatus() == Disabled) { std::cout << "Trying to set the period but we need to release the PWM module first!" << std::endl; throw std::bad_exception(); return; } m_periodNS = periodNS; if (GetRunStatus() == Enabled) WritePeriodNSToFile(); } void SetPeriodUS(const int &periodUS) //微妙 { SetPeriodNS((long) periodUS * MICRSECONDS_TO_NANOSECONDS); } void SetPeriodMS(const int &periodMS) //毫秒 { SetPeriodNS((long) periodMS * MILLISECONDS_TO_NANOSECONDS); } void SetPolarity(const Polarity & polarity)//设置极性 { m_polarity = polarity; if (GetRunStatus() == Enabled) WritePolarityToFile(); } private: void SetRunStatus(const RunStatus & newRunStatus) // 运行状态设置 { if (newRunStatus != GetRunStatus()) { if (newRunStatus == Disabled) { WriteToFile(GetRunFilePath(), std::string("0")); } else if (newRunStatus == Enabled) { if (GetRunStatus() == Free) { InitPinFS(); } // Force write the file values out WritePeriodNSToFile(); WriteDutyNSToFile(); WritePolarityToFile(); WriteToFile(GetRunFilePath(), std::string("1")); } else if (newRunStatus == Free) { if (GetRunStatus() != Disabled) { SetRunStatus(Disabled); } UnloadDeviceTreeModule(GetPinName()); } } m_runStatus = newRunStatus; } public: void Enable() //运行状态 设置为 开始运行 { SetRunStatus(Enabled); } void Disable() { SetRunStatus(Disabled); } void Release() { SetRunStatus(Free); } public: ~Pin() { Release(); } Pin() {} //默认构造函数中的 周期为20毫秒 占空比为 0 毫秒 Pin(const std::string & pinName, const long & periodNS = 20 * MILLISECONDS_TO_NANOSECONDS, const long & dutyNS = 0* MILLISECONDS_TO_NANOSECONDS) : m_pinName(pinName) { // If the pin is already in use then we need to free it! if (GetCapeManagerSlot(GetPinName()) != -1) //查找当强的管脚是否已经被应用 ,yes:释放它 UnloadDeviceTreeModule(GetPinName()); m_runStatus = WaitingForSetp; InitPinFS(); SetPeriodNS(periodNS);//周期 SetDutyNS(dutyNS);//占空比 SetPolarity(PolaritryHigh);//极性 //InitPinFS(); } void InitPinFS() //设置BBB定时器 管脚命名 获取相应文件的位置 信息 { //LoadDeviceTreeModule(std::string("am33xx_pwm"));//加入pwm定时器 std::string pinModule = std::string("sc_pwm_") + GetPinName();// LoadDeviceTreeModule(pinModule);//加入pin std::string pinInterfacePath = GetOCPPath() + GetFullNameOfFileInDirectory(GetOCPPath(), GetPinName()) + "/"; m_dutyFilePath = pinInterfacePath + "duty"; m_periodFilePath = pinInterfacePath + "period"; m_polarityFilePath = pinInterfacePath + "polarity"; m_runFilePath = pinInterfacePath + "run"; #if DEBUG_VERBOSE_OUTPUT std::cout << GetDutyFilePath() << std::endl; std::cout << GetPeriodFilePath() << std::endl; std::cout << GetPolarityFilePath() << std::endl; std::cout << GetRunFilePath() << std::endl; #endif } }; } #endif /* BEAGLEBONEPWM_H_ */
PWM基类实现
/* * BeagleBonePWM.cpp * * Created on: 2014-6-9 * Author: sfe1012 */ #include "BeagleBonePWM.h" namespace PWM { // A bunch of helper functions to get us locations in the file system. // They are used so that we can manipulate the pwm driver through the /sys interface //这个函数将会返回在 dirname目录下 文件名称为filenameTofind 文件名 std::string GetFullNameOfFileInDirectory(const std::string & dirName, const std::string & fileNameToFind) { DIR *pDir; dirent *pFile; if ((pDir = opendir(dirName.c_str())) == NULL) { std::cout << "Directory name: " << dirName << " doesnt exist!" << std::endl; throw std::bad_exception(); } while ((pFile = readdir(pDir)) != NULL) { std::string currentFileName = (pFile->d_name); if (currentFileName.find(fileNameToFind) != std::string::npos)//string 查找函数 { return currentFileName; } } return std::string(""); } std::string GetCapeManagerSlotsPath()//获得slots 目标名称 { static std::string g_capeManagerSlotsPath; if (g_capeManagerSlotsPath.length() <= 0) { #if DEBUG_VERBOSE_OUTPUT std::cout << "Setting up cape manager path" << std::endl; #endif std::string capeBasePath("/sys/devices/"); std::string fileName = GetFullNameOfFileInDirectory(capeBasePath, std::string("bone_capemgr.")); g_capeManagerSlotsPath = capeBasePath + fileName + "/slots"; } return g_capeManagerSlotsPath; } std::string GetOCPPath() //获得ocp的文件目录 { static std::string g_ocpPath; if (g_ocpPath.length() == 0) { std::string ocpBasePath("/sys/devices/"); std::string ocpName = GetFullNameOfFileInDirectory(ocpBasePath, std::string("ocp.")); g_ocpPath = ocpBasePath + ocpName + '/'; } return g_ocpPath; } int GetCapeManagerSlot(const std::string & moduleName) { #if DEBUG_VERBOSE_OUTPUT std::cout << "Trying to find slot for module: " << moduleName << std::endl; #endif std::ifstream in(GetCapeManagerSlotsPath().c_str());//找到 /sys/devices/bone_capemgr.9/slots in.exceptions(std::ios::badbit);//读取slots 文件 int slot = -1; while (in >> slot) { std::string restOfLine; std::getline(in, restOfLine); //获取slots 中的一行 if (restOfLine.find(moduleName) != std::string::npos)//在这一行中查找是否有这个管脚 { #if DEBUG_VERBOSE_OUTPUT std::cout << "Found Module: " << moduleName << " at slot: " << slot << std::endl; #endif return slot; } } #if DEBUG_VERBOSE_OUTPUT std::cout << "Module: " << moduleName << " not found in cape manager!" << std::endl; #endif return -1; } void LoadDeviceTreeModule(const std::string & name) { int slot = GetCapeManagerSlot(name);//查找是否存在 不存在返回 -1 if (slot == -1) { #if DEBUG_VERBOSE_OUTPUT std::cout << "Adding Module: " << name << std::endl; std::cout << "Its going in: " << GetCapeManagerSlotsPath() << std::endl; #endif WriteToFile(GetCapeManagerSlotsPath(), name);//命令写入其中 usleep(MODULE_DELAY_TIME_US); } else { #if DEBUG_VERBOSE_OUTPUT std::cout << "Module " << name << " is already in here!" << std::endl; #endif } } void UnloadDeviceTreeModule(const std::string name) { int currentSlot = GetCapeManagerSlot(name); if (currentSlot == -1) { std::cout << "Why is the module " << name << " being unloaded when its not in use?" << std::endl; throw std::bad_exception(); } #if DEBUG_VERBOSE_OUTPUT std::cout << "Unloading module: " << name << std::endl; #endif WriteToFile(GetCapeManagerSlotsPath(), std::string("-") + ToString(currentSlot)); usleep(MODULE_DELAY_TIME_US); } }
PWM舵机控制类定义
/* * BeagleBonePwmServo.h * * Created on: 2014-6-10 * Author: sfe1012 */ #ifndef BEAGLEBONEPWMSERVE_H_ #define BEAGLEBONEPWMSERVE_H_ #include "BeagleBonePWM.h" #include "BeagleBonePwmMotor.h" class BeagleBonePwmServo:public BeagleBonePwmMotor { public: BeagleBonePwmServo(const std::string &strPinName, const long &lPeriodTimeNs, const long &lDutyTimeNs, const long &lDrive, const long &lServoRightLimitUs, const long &lServoLeftLimitUs, const long &lServoCenterUs); ~BeagleBonePwmServo(); public: const long &GetCenterValue()const; void SetCenterValue(const long &lCenterValueUs); public: void EnableMotorPwm(); //void UpdateCurrentPwm(); void UpdateMotorPwmSignalByStep(const long &lTargetDrive); void UpdateMotorPwmSignalBySetCurrentDriveNs(const long &lCurrentDrive); private: long m_lServoRightLimitUs; long m_lServoLeftLimitUs; long m_lServoCenterUS; long m_lServoCurrentUS; long m_lServoStep; }; #endif /* BEAGLEBONEPWMSERVE_H_ */
PWM舵机控制类实现
/* * BeagleBonePwmServo.cpp * * Created on: 2014-6-13 * Author: sfe1012 */ #include"BeagleBonePwmServo.h" BeagleBonePwmServo::BeagleBonePwmServo(const std::string &strPinName, const long &lPeriodTimeNs, const long &lDutyTimeNs, const long &lDrive, const long &lServoRightLimitUs, const long &lServoLeftLimitUs, const long &lServoCenterUs): BeagleBonePwmMotor(strPinName,lPeriodTimeNs,lDutyTimeNs,lDrive){ m_lServoRightLimitUs = lServoRightLimitUs;//1000 m_lServoLeftLimitUs = lServoLeftLimitUs;//2000 m_lServoCenterUS = lServoCenterUs;//1500 m_lServoCurrentUS = 0; m_lServoStep = (lServoLeftLimitUs - lServoRightLimitUs)/lDrive; } BeagleBonePwmServo::~BeagleBonePwmServo(){ } const long &BeagleBonePwmServo::GetCenterValue()const{ return m_lServoCenterUS; } void BeagleBonePwmServo::SetCenterValue(const long &lCenterValueUs){ m_lServoCenterUS = lCenterValueUs; } void BeagleBonePwmServo::EnableMotorPwm(){ GetPwmPinClass().SetDutyUS(m_lServoCenterUS); GetPwmPinClass().Enable(); m_lServoCurrentUS = m_lServoCenterUS; } void BeagleBonePwmServo::UpdateMotorPwmSignalByStep(const long &lTargetDrive){ m_lServoCurrentUS += lTargetDrive; if(m_lServoCurrentUS > m_lServoLeftLimitUs){ m_lServoCurrentUS = m_lServoLeftLimitUs; } else if(m_lServoCurrentUS < m_lServoRightLimitUs){ m_lServoCurrentUS = m_lServoRightLimitUs; } GetPwmPinClass().SetDutyUS(m_lServoCurrentUS*m_lServoStep);// Write out to PWM GetCurrentDrive() } void BeagleBonePwmServo::UpdateMotorPwmSignalBySetCurrentDriveNs(const long &lCurrentDrive){ long lCurrentDriveTemp = 0 ; if(lCurrentDrive > m_lServoLeftLimitUs*1000){ lCurrentDriveTemp = m_lServoLeftLimitUs*1000; } else if(lCurrentDrive < m_lServoRightLimitUs*1000){ lCurrentDriveTemp = m_lServoRightLimitUs*1000; } else lCurrentDriveTemp = lCurrentDrive; std::cout<<"lCurrentDriveTemp:"<<lCurrentDriveTemp<<std::endl; GetPwmPinClass().SetDutyNS(lCurrentDriveTemp);// Write out to PWM GetCurrentDrive() }
PWM电机控制类定义
/* * BeagleBonePwmMotor.h * * Created on: 2014-6-13 * Author: sfe1012 */ #ifndef BEAGLEBONEPWMMOTOR_H_ #define BEAGLEBONEPWMMOTOR_H_ #include "BeagleBonePWM.h" class BeagleBonePwmMotor { public: BeagleBonePwmMotor(); BeagleBonePwmMotor(const std::string &strPinName, const long &lPeriodTimeNs, const long &lDutyTimeNs, const long &lDrive); virtual ~BeagleBonePwmMotor(); public: PWM::Pin &GetPwmPinClass(); const long &GetTargetDriveStep()const; void SetTargetDriveStep(const long & lTargetDriveStep); const long &GetCurrentDrive()const; void SetCurrentDrive(const long & lCurrentPWM); void LoadDeviceTreeModule(const std::string &strName)const; public: virtual void EnableMotorPwm(); virtual void UpdateCurrentPwm(); virtual void UpdateMotorPwmSignalByStep(const long &lTargetDrive); virtual void UpdateMotorPwmSignalBySetCurrentDriveUs(const long &lCurrentDrive); virtual void UpdateMotorPwmSignalBySetCurrentDriveNs(const long &lCurrentDrive); private: PWM::Pin m_Pin; long m_lCurrentDrive; long m_lTargetDriveStep;//在当前的档位上 加多少 还是 减掉 多少 long m_lDrive; //一共有多少个前进档位 long m_lStep; //每个档位代表多少个 微妙的占空比 }; #endif /* BEAGLEBONEPWMMOTOR_H_ */
PWM电机控制类实现
/* * BeagleBonePwmMotor.cpp * * Created on: 2014-6-13 * Author: sfe1012 */ #include"BeagleBonePwmMotor.h" BeagleBonePwmMotor::BeagleBonePwmMotor(const std::string &strPinName, const long &lPeriodTimeNs, const long &lDutyTimeNs, const long &lDrive): m_Pin(strPinName, lPeriodTimeNs,lDutyTimeNs){ m_lCurrentDrive = 0; m_lTargetDriveStep = 0; m_lDrive = lDrive; m_lStep = lPeriodTimeNs / (m_lDrive*1000); } BeagleBonePwmMotor::BeagleBonePwmMotor() { } BeagleBonePwmMotor::~BeagleBonePwmMotor(){ } PWM::Pin &BeagleBonePwmMotor::GetPwmPinClass(){ return m_Pin; } const long &BeagleBonePwmMotor::GetTargetDriveStep()const{ return m_lTargetDriveStep; } void BeagleBonePwmMotor::SetTargetDriveStep(const long & lTargetDriveStep){ m_lTargetDriveStep = lTargetDriveStep; } const long &BeagleBonePwmMotor::GetCurrentDrive()const{ return m_lCurrentDrive; } void BeagleBonePwmMotor::SetCurrentDrive(const long & lCurrentDrive){ m_lCurrentDrive = lCurrentDrive; } void BeagleBonePwmMotor::EnableMotorPwm(){ GetPwmPinClass().Enable(); } void BeagleBonePwmMotor::UpdateCurrentPwm(){ if(m_lTargetDriveStep > 0 || m_lTargetDriveStep == 0){ m_lCurrentDrive += m_lTargetDriveStep; } else if(m_lTargetDriveStep < 0){ m_lCurrentDrive += m_lTargetDriveStep; } if(m_lCurrentDrive > m_lDrive){ m_lCurrentDrive = m_lDrive; } else if(m_lCurrentDrive < 0){ m_lCurrentDrive = 0; } #ifdef DEBUG_VERBOSE_OUTPUT std::cout<<"m_lCurrentDrive :"<<m_lCurrentDrive<<std::endl; #endif } void BeagleBonePwmMotor::UpdateMotorPwmSignalByStep(const long &lTargetDriveStep){ SetTargetDriveStep(lTargetDriveStep); UpdateCurrentPwm(); #ifdef DEBUG_VERBOSE_OUTPUT std::cout<<"UpdateMotorPwmSignalByStep : GetCurrentDrive()*m_lStep::"<<GetCurrentDrive()*m_lStep<<std::endl; #endif GetPwmPinClass().SetDutyUS(GetCurrentDrive()*m_lStep);// Write out to PWM GetCurrentDrive() } void BeagleBonePwmMotor::UpdateMotorPwmSignalBySetCurrentDriveUs(const long &lCurrentDrive) { // long lCurrentDriveTemp = 0; // if(lCurrentDrive > m_lDrive || lCurrentDrive == 0) // { // lCurrentDriveTemp = m_lDrive; // } // if(lCurrentDrive < 0) // { // lCurrentDriveTemp = 0; // } #ifdef DEBUG_VERBOSE_OUTPUT std::cout<<"UpdateMotorPwmSignalBySetCurrentDrive : GetCurrentDrive()*m_lStep::"<<lCurrentDrive*m_lStep<<std::endl; #endif GetPwmPinClass().SetDutyUS(lCurrentDrive*m_lStep);// Write out to PWM GetCurrentDrive() } void BeagleBonePwmMotor::UpdateMotorPwmSignalBySetCurrentDriveNs(const long &lCurrentDrive) { #ifdef DEBUG_VERBOSE_OUTPUT std::cout<<"UpdateMotorPwmSignalBySetCurrentDrive :"<<lCurrentDrive<<std::endl; #endif GetPwmPinClass().SetDutyNS(lCurrentDrive);// Write out to PWM GetCurrentDrive() } void BeagleBonePwmMotor::LoadDeviceTreeModule(const std::string &strName)const { m_Pin.LoadDeviceTreeModuleForEspecial(strName); }
应用方法:
#include <stdlib.h> #include"GraduationHead.h" #include"BeagleBonePwmMotor.h" #include"BeagleBonePwmServo.h" using namespace std; int main(){ cout << "!!! Hello BeagleBone Black !!!" << endl; // prints !!!Hello World!!! /***PIN_MOTOR_BACK***********PWM Init**********PIN_MOTOR_FORWARD*********/ BeagleBonePwmMotor PWMTimeLoad; PWMTimeLoad.LoadDeviceTreeModule("am33xx_pwm"); BeagleBonePwmMotor MotorForward(PIN_MOTOR_FORWARD,20 * MILLISECONDS_TO_NANOSECONDS,0,100);// BeagleBonePwmMotor MotorBack(PIN_MOTOR_BACK,20 * MILLISECONDS_TO_NANOSECONDS,0,100); BeagleBonePwmServo ServoShookHead(PIN_SERVO_SHOOK_HEAD,20 * MILLISECONDS_TO_NANOSECONDS,0,100,1000,2000,1500); BeagleBonePwmServo ServoNodHead(PIN_SERVO_NOD_HEAD,20 * MILLISECONDS_TO_NANOSECONDS,0,100,1000,2000,1500); BeagleBonePwmServo ServoDerection(PIN_SERVO_DERECTION,20 * MILLISECONDS_TO_NANOSECONDS,0,100,1370,1650,1500); MotorForward.EnableMotorPwm(); MotorBack.EnableMotorPwm(); ServoShookHead.EnableMotorPwm(); ServoNodHead.EnableMotorPwm(); ServoDerection.EnableMotorPwm(); usleep(MODULE_DELAY_TIME_US);;//等待PWM定时器设置成功 /****************Data Analaze*******************/ SerialDataAnalaze oSerialDataAnalaze; /**********************PWM Data*****************/ long olMotorForward = 500; //ns long olMotorBack = 0;//500; //ns long olServoShookHead = 1500000; //ns long olServoNodHead = 1500000; //ns long olServoDerection = 1500000; //ns long lButtonNum = 0; while(1) { MotorForward.UpdateMotorPwmSignalBySetCurrentDriveNs(olMotorForward); //usleep(MODULE_DELAY_TIME_US);;//等待设置成功 MotorBack.UpdateMotorPwmSignalBySetCurrentDriveNs(olMotorBack); //usleep(MODULE_DELAY_TIME_US);;//等待设置成功 ServoShookHead.UpdateMotorPwmSignalBySetCurrentDriveNs(olServoShookHead); //usleep(MODULE_DELAY_TIME_US);;//等待设置成功 ServoNodHead.UpdateMotorPwmSignalBySetCurrentDriveNs(olServoNodHead); //usleep(MODULE_DELAY_TIME_US);;//等待设置成功 ServoDerection.UpdateMotorPwmSignalBySetCurrentDriveNs(olServoDerection); //usleep(MODULE_DELAY_TIME_US);;//等待设置成功 } return 0; }
相关文章推荐
- 基于BBB的4轮移动轮式机器人系统设计与实现(五)--BeagleBone Black编码器开发应用
- 基于BBB的4轮移动轮式机器人系统设计与实现(三)--BeagleBone Black PWM 驱动
- 基于BBB的4轮移动轮式机器人系统设计与实现(六)--网络通信类的开发
- 基于BBB的4轮移动轮式机器人系统设计与实现(一)-----开篇引言
- 基于BBB的4轮移动轮式机器人系统设计与实现(二)-----硬件搭建
- 基于BBB的4轮移动轮式机器人系统设计与实现(八)-- SIM908 GPS 数据获取
- 基于BBB的4轮移动轮式机器人系统设计与实现(七)-- 遥控手柄 控制 类
- 基于J2ME-J2EE的移动工资查询系统 的设计与实现
- Beaglebone black(BBB)使用spi接口oled:基于python
- Beaglebone Black——系统启动后BBB板子的盘符没有出来、系统启动自动挂载分区
- 基于数据挖掘技术的客户关系管理系统设计与实现
- 嵌入式实战项目:基于嵌入式linux花卉大棚温湿度监测与调节系统的设计与实现
- 移动操作系统"元心"可能基于MeeGo系统开发
- 【加密解密】基于CryptoAPI的文件加解密系统设计与实现
- 游戏任务成就体系的实现(附三):成就系统基于Mysql+Cache的数据库访问设计实现
- 游戏任务成就体系的实现(附七):成就系统基于Redis的数据库访问设计实现
- 模块管理常规功能自定义系统的设计与实现(56--开源开发测试版发布 )
- Hadoop应用开发--基于MapReduce推荐系统的实现
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 基于数据库资源的多语言实现
- 【转】谈基于SOA的应用系统设计和开发