0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何构建两轮自平衡机器人

454398 来源:wv 2019-10-18 09:41 次阅读

步骤1:

1。框架:我的框架只是将两个铝制伺服支架用螺栓固定到两个垂直的胶合板上,并与伺服支架固定在一起。框架的构成或配置方式实际上并不重要。您可能应该将其调高一点,然后将电池放在顶部-多少钱总是一个问题,太高了,电动机将没有足够的扭矩来使车轮足够快地旋转,过低又可能使电动机太慢而无法转动抓住机器人的倾斜。一块水平的胶合板底部装有Arduino Uno和电机控制器。

2。马达:我使用了两个无处不在的黄色齿轮马达和车轮,每个到处都可以找到,价格分别为几美元。它们的转速约为110 rpm,足以平衡,但如果转速约为200或300 rpm,那就太好了。它们的齿轮倾斜度很小,因此机器人总是会有点摆动。在将它们连接到电机控制器之前,您可能应该将两个电机引线互相缠绕,以防止杂散电磁场干扰Arduino。在电动机引线两端连接几个电容器也是一个好主意。我用几个拉链把电动机固定在车架上,效果很好。

3。马达控制器:我使用了L293D迷你控制器,我非常喜欢它,因为我可以使用一个2s锂电池为控制器供电,该控制器还可以为Arduino Uno供电-无需第二个电池。轻巧的重量减轻器和轻巧的重量,意味着机器人更容易平衡。

4。 MPU6050陀螺仪/加速度计:这是一个不错的小模块,用于测量机器人的倾斜角度。调用函数非常简单。我将我的机器人安装在arduino和机器人的倾斜轴上方。有些人说应该更高些,有些人说应该更低些,但是可以找到它在哪里。

5。 Arduino Uno:神经网络将轻松以2k运行。

6。电源开关:连接电源开关以打开和关闭电池真的很值得。使机器人的使用变得比每次都要插入电池更容易。

7。 LIPO电池:我使用800mah 2s电池为所有电池供电。电池寿命通常约为连续运行20分钟或更长时间。足够用于测试和玩耍。

8。原理图:最后一张照片是我连接所有模块和电机的示意图。

步骤2:加载并运行Arduino草图

1。 MPU6050校准:在实际运行机器人之前,首先需要进行的是陀螺仪/加速度计的校准。下载位于以下位置的校准草图:http://forum.arduino.cc/index.php?action = dlattach; 。..在执行之前,将您的机器人笔直站立,并在校准程序运行时不要移动它。除非您碰巧将MPU6050移动到机器人上的新位置,否则您只需运行一次校准例程。

运行时,它将向Arduino串行监视器输出6个值需要三个才能放入草图。

2。 NeuralNet-SelfBalancingRobot草图:将以下草图加载到Arduino Uno。您需要将GYRO/ACC参数更改为校准运行中的参数。然后运行草图,查看机器人是否平衡。我的机器人会在地毯或床上保持相当不错的平衡,但会四处运行,然后掉落在光滑的地板上。

我为我的机器人设置了PID代码,其平衡与Neuro Net略有不同但是使用NN基本上没有调整,只需加载草图即可平衡。 PID例程需要大量的操作。

我可以将我的PID控制器上传到SB机器人,而无需进行任何修改即可比较PID与NN软件。 NN会在平衡点附近以较小的振荡获胜,但会在受到干扰的情况下输给PID。但是我还没有真正调整NN。

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//神经网络程序,使用S型函数并应用于简单的自平衡机器人

//由商洛大学Jim Demello创建,2018年5月

//改编自Sean Hodgins神经网络代码:https://www.instructables.com/id/Arduino-Neural-Ne。

/修改了midhun_s自平衡机器人代码:https://www.instructables.com/id/Arduino-Self-Bala.。.

/构建了我自己的自平衡机器人

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include“ MPU6050.h”

#包括“ math.h”

/**************************************** **********************************

网络配置-为每个网络自定义

************************************************** ****************/

const int PatternCount = 2;

const int InputNodes = 1;

const int Hidd enNodes = 3;

const int OutputNodes = 1;

const float LearningRate = 0.3;

const float Momentum = 0.9;

const float InitialWeightMax = 0.5;

const float Success = 0.0015;

float Input [PatternCount] [InputNodes] = {

{0},//左倾斜

{1}//倾斜

//{-1}//倾斜

//{0,1,1,0} ,//左右左右发光

//{0,1,0,0},//左右左右发光

//{1,1,1,0} ,//顶部,左侧和右侧的灯光

};

const float Target [PatternCount] [OutputNodes] = {

{0,},////左倾斜

{1,}//右倾斜

//{-1,}//左移动

//{0.65, 0.55},//LEFT MOTOR SLOW

//{0.75,0.5},//LEFT MOTOR FASTER

};

/***** ************************************************** ***********

终端网络配置

********************** ***************/

int i,j,p,q,r;

int ReportEvery1000;

int RandomizedIndex [PatternC ount];

长时间训练周期;

浮动Rando;

浮动误差= 2;

浮动累积;

float Hidden [HiddenNodes];

float Output [OutputNodes];

float HiddenWeights [InputNodes + 1] [HiddenNodes];

float OutputWeights [HiddenNodes + 1] [OutputNodes];

float HiddenDelta [HiddenNodes];

float OutputDelta [OutputNodes];

float ChangeHiddenWeights [InputNodes + 1] [HiddenNodes] ;

float ChangeOutputWeights [HiddenNodes +1] [OutputNodes];

#define leftMotorPWMPin 6

#define leftMotorDirPin 7

#define rightMotorPWMPin 5

#define rightMotorDirPin 4

#define sampleTime 0.005

MPU6050 mpu;

int16_t accY,accZ,gyroX;

int motorPower,gyroRate;

float accAngle,gyroAngle,currentAngle,prevAngle = 0,error,prevError = 0,errorSum = 0;

字节数= 0;

long previousMillis = 0;

unsigned long currentMillis;

long loopTimer = 4;

void setMotors(int leftMotorSpeed,int rightMotorSpeed){

//串行.print(“ leftMotorSpeed =”); Serial.print(leftMotorSpeed); Serial.print(“ rightMotorSpeed =”); Serial.println(rightMotorSpeed);

if(leftMotorSpeed》 = 0){

AnalogWrite(leftMotorPWMPin,leftMotorSpeed);

digitalWrite(leftMotorDirPin,LOW);

}

else {//如果leftMotorSpeed为《0,则将dir设置为反向

AnalogWrite(leftMotorPWMPin, 255 + leftMotorSpeed);

digitalWrite(leftMotorDirPin,HIGH);

}

if(rightMotorSpeed》 = 0){

AnalogWrite (rightMotorPWMPin,rightMotorSpeed);

digitalWrite(rightMotorDirPin,LOW);

}

else {

AnalogWrite(rightMotorPWMPin,255 + rightMotorSpeed);

digitalWrite(rightMotorDirPin,HIGH);

}

}

void setup(){

Serial.begin(115200);

Serial.println(“启动程序”);

randomSeed(analogRead(A1));//收集一个随机ADC样本以进行随机化。

ReportEvery1000 = 1;

for(p = 0; p

RandomizedIndex [ p] = p;

}

Serial.println(“ do train_nn”);

train_nn();

delay( 1000);

//将电动机控制和PWM引脚设置为输出模式

pinMode(leftMotorPWMPin,OUTPUT);

pinMode(leftMotorDirPin,OUTPUT);

pinMode(rightMotorPWMPin,OUTPUT);

pinMode(rightMotorDirPin,OUTPUT);

//初始化MPU6050并设置偏移值

mpu.initialize();

mpu.setYAccelOffset(2113);//通过校准例程

mpu.setZAccelOffset(1122);

mpu.setXGyroOffset(7);

Serial.print(“ End在以下位置初始化MPU: “); Serial.println(米利斯());

}

///////////////

/主循环/

/////////////

void loop(){

drive_nn();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////

/使用了训练有素的神经网络要驱动机器人

void drive_nn()

{

Serial.println(“ Running NN Drive”);

while(Error 《成功){

currentMillis = millis();

float TestInput [] = {0,0};

if(currentMillis-previousMillis》 loopTimer) {//每5毫秒或更长时间进行一次计算

Serial.print(“ currentMillis =”); Serial.println(currentMillis);

/////////////////////////////////////

//计算incli的角度国家//

//////////////////////////////////////////

accY = mpu.getAccelerationY();

accZ = mpu.getAccelerationZ();

gyroX = mpu.getRotationX();

accAngle = atan2(accY,accZ)* RAD_TO_DEG;

gyroRate = map(gyroX,-32768,32767 ,-250,250);

gyroAngle =(float)gyroRate * sampleTime;

///////////////////////////////////////////////////////////////////

//补充过滤器///////////////////////////////////////////

////////////////////////////////////////////////////////////////////

currentAngle = 0.9934 *(prevAngle + gyroAngle)+ 0.0066 *(accAngle);

//Serial.print(“currentAngle=“); Serial.print(currentAngle); Serial.print(“ error =”); Serial.println(error);

//错误= currentAngle-targetAngle;//不使用

float nnInput = currentAngle;

//Serial.print(“ nnInput =”); Serial.println(nnInput);

nnInput = map(nnInput,-30,30,0,100);//将倾斜角度范围映射到0到100

TestInput [0] = float(nnInput)/100;//转换为0到1

//Serial.print(“ testinput =”); Serial.println(TestInput [0]);

InputToOutput(TestInput [0]) ;//输入到ANN以获取输出

//Serial.print(”output =“); Serial.println(Output [0]);

///////////////////////////////////////////

//在之后设置电动机功率约束它//

///////////////////////////////////////////

motorPower =输出[0] * 100;//从0转换为1

//如果(motorPower 《50)motorPower = motorPower * -1;

motorPower = map(motorPower,0,100,-300,300 );

motorPower = motorPower +(motorPower * 6.0);//需要乘数以使车轮在接近平衡点时足够快地旋转

//Serial.print(“motorPower =“); Serial.println(motorPower);

motorPower = constrain(motorPower,-255,255);

prevAngle = currentAngle;

previousMillis = currentMillis;

}//结束毫秒循环

//如果(abs(error)》 30)motorPower = 0;//如果跌落则关闭电动机

//motorPower = motorPower + error;

setMotors(motorPower,motorPower);

}

}//drive_nn()函数的结尾

///在培训时显示信息

无效到Terminal()

{

for(p = 0; p

Serial.println();

Serial.print(“ Training Pattern:”);

Serial.println(p);

Serial.print(“ Input”);

for(i = 0; i

Serial.print(Input [p] [i],DEC);

Serial.print(“”);

}

Serial.print (“ Target”);

for(i = 0; i

Serial.print(Target [p] [i],DEC);

Serial.print(“”);

}

/********************* **************

计算隐藏层激活

***************************************** *********************************/

for(i = 0; i

Accum = HiddenWeights [InputNodes] [i];

for(j = 0; j

累计+ =输入[p] [j] * HiddenWeights [j] [i];

}

隐藏[i] = 1.0/(1.0 + exp(-Accum));//激活功能

}

/****************************** ******************************************

计算输出层激活并计算错误

******************************************* ***************************/

用于(i = 0; i

累计= OutputWeights [HiddenNodes] [i];

for(j = 0; j 《隐藏节点; j ++){

累计+ =隐藏[j] * OutputWeights [j] [i];

}

输出[i] = 1.0/(1.0 + exp(-Accum));

}

Serial.print(“ Output”);

for(i = 0; i

Serial.print(Output [i],5);

Serial.print(“”);

}

}

}

无效InputToOutput(float In1 )

{

float TestInput [] = {0};

TestInput [0] = In1;

//TestInput [ 1] = In2;//未使用

//TestInput [2] = In3;//未使用

//TestInput [3] = In4;//不使用

/****************************************** ****************************

计算隐藏层激活

**** ************************************************** ************/

for(i = 0; i

Accum = HiddenWeights [InputNodes] [i];

for(j = 0; j

累计+ = TestInput [j] * HiddenWeights [j] [i];

}

隐藏[i] = 1.0/(1.0 + exp(-Accum));

}

/********* ************************************************** *******

计算输出层激活并计算错误

********************** ***************/

for(i = 0; i

Accum = OutputWeights [HiddenNodes] [i];

for(j = 0; j

累计+ =隐藏[j] * OutputWeights [j] [i];

}

输出[i] = 1.0/(1.0 + exp(-Accum));

}

//#ifdef调试

Serial.print(“输出”);

对于(i = 0 ;我

Serial.print(Output [i],5);

Serial.print(“”);

}

//#endif

}

//训练神经网络

void train_nn(){

/*** ************************************************** *************

初始化HiddenWeights和ChangeHiddenWeights

******************* ***************/

int prog_start = 0;

Serial.println(“开始培训。..”);

//digitalWrite(LEDYEL,LOW);

for(i = 0; i

for(j = 0; j 《= InputNodes; j ++){

ChangeHiddenWeights [j] [i ] = 0.0;

Rando = float(random(100))/100;

HiddenWeights [j] [i] = 2.0 *(Rando-0.5)* InitialWeightMax;

}

}

//digitalWrite(LEDYEL,HIGH);

/************ ************************************************** ****

初始化OutputWeights和ChangeOutputWeights

**************************** ******************************************/

//digitalW rite(LEDRED,LOW);

for(i = 0;我

for(j = 0; j 《= HiddenNodes; j ++){

ChangeOutputWeights [j] [i] = 0.0;

Rando = float(random(100))/100;

OutputWeights [j] [i] = 2.0 *(Rando-0.5)* InitialWeightMax;

}

}

//digitalWrite(LEDRED,HIGH);

//SerialUSB.println(”Initial/Untrained Outputs:“);

//toTerminal();

/****************************************** ****************************

开始训练

****** ************************************************** **********/

用于(TrainingCycle = 1; TrainingCycle 《2147483647; TrainingCycle ++){

/*********** ************************************************** *****

随机分配训练模式的顺序

************************** ********************************************/

用于( p = 0; p

q = random(PatternCount);

r = RandomizedIndex [p];

RandomizedIndex [p] = RandomizedIndex [q];

RandomizedIndex [q] = r;

}

错误= 0.0;

/*************************************** **************************************

以随机顺序遍历每种训练模式

************************************************** ********************/

为(q = 0; q

p = RandomizedIndex [q];

/************************* **********************************************

隐藏计算层激活

********************************************* *****************************/

//digitalWrite(LEDYEL,LOW);

表示(i = 0; i

累计= HiddenWeights [InputNodes] [i];

for(j = 0; j

累计+ =输入[p] [j] *隐藏重量[j] [i];

}

隐藏[i] = 1.0/(1.0 + exp(-Accum));

}

//digitalWrite(LEDYEL,HIGH);

/*********** ************************************************** *****

计算输出层激活并计算错误

************************ *************/

//digitalWrite(LEDRED,LOW);

for(i = 0; i

Accum = OutputWeights [HiddenNodes] [i];

for(j = 0; j

累计+ =隐藏[j] * OutputWeights [j] [i];

}

Output [i] = 1.0/(1.0 + exp(-Accum));

OutputDelta [i] =(Target [p] [i]-Output [ i])*输出[i] *(1.0-输出[i]);

错误+ = 0.5 *(目标[p] [i]-输出[i])*(目标[p] [i]-Output [i]);

}

//Serial.println(Output [0] * 100);

//digitalWrite( LEDRED,HIGH);

/***************************************** *********************************

向后传播到隐藏层的错误

** ************************************************** **************/

//digitalWrite(LEDYEL,LOW);

for(i = 0;我

累计= 0.0;

对于(j = 0; j

累计+ = OutputWeights [i] [j ] * OutputDelta [j];

}

HiddenDelta [i] =累积*隐藏[i] *(1.0-隐藏[i]);

}

//digitalWrite(LEDYEL,HIGH);

/************************* **********************************************

更新内部-》隐藏重量

****************************************** ********************************/

//digitalWrite(LEDRED,LOW);

for(i = 0; i

ChangeHiddenWeights [InputNodes] [i] = LearningRate * HiddenDelta [i] +动量* ChangeHiddenWeights [InputNodes] [i];

HiddenWeights [InputNodes] [i] + = ChangeHiddenWeights [InputNodes] [i];

for(j = 0; j

ChangeHiddenWeights [ j] [i] =学习率*输入[p] [j] * HiddenDelta [i] +动量* ChangeHiddenWeights [j] [i];

HiddenWeights [j] [i] + = ChangeHiddenWeights [j ] [i];

}

}

//digitalWrite(LEDRED,HIGH);

/************************************************* *********************

隐藏更新-》输出权重

******** ************************************************** ********/

//digitalWrite(LEDYEL,LOW);

for(i = 0;我

ChangeOutputWeights [HiddenNodes] [i] =学习率* OutputDelta [i] +动量* ChangeOutputWeights [HiddenNodes] [i];

OutputWeights [HiddenNodes] [i] ] + = ChangeOutputWeights [HiddenNodes] [i];

for(j = 0; j

ChangeOutputWeights [j] [i] = LearningRate * Hidden [ j] * OutputDelta [i] +动量* ChangeOutputWeights [j] [i];

OutputWeights [j] [i] + = ChangeOutputWeights [j] [i];

}

}

//digitalWrite(LEDYEL,HIGH);

}

/********** ************************************************** ******

每100个周期将数据发送到终端进行显示并在OLED上绘制图形

*************** ************************************************** */

ReportEvery1000 = ReportEvery1000-1;

如果(ReportEvery1000 == 0)

{

int graphNum = TrainingCycle/100 ;

int graphE1 =错误* 1000;

int graphE = map(graphE1,3,80,47,0);

Serial.print(“ TrainingCycle:“);

Se rial.print(TrainingCycle);

Serial.print(“ Error =”);

Serial.println(Error,5);

toTerminal() ;

if(TrainingCycle == 1)

{

ReportEvery1000 = 99;

}

否则

{

ReportEvery1000 = 100;

}

}

/******* ************************************************** *********

如果错误率小于预定阈值,则结束

*************** ************************************************** */

如果(错误《成功)中断;

}

}

步骤3:最终注释

1。这些参数可能只需要一点点就可以播放,尤其是可以增加NN输出值的乘法器。当电动机接近平衡时,必须使用该倍增器来提高电动机的转速。事实证明,这几乎迫使机器人成为爆炸式,平衡式机器人。如果在平衡点附近的电动机的值不够高,则机器人将在电动机具有足够的rpm来捕捉下降之前倒下。

2。也许可以使用比S形函数更好的激活函数。有人说tanf函数更有用。我认为真正需要的只是一个简单的f(x)函数。对这个领域的任何人都会真正感兴趣。

3。这是一个简单的单输入,多个隐藏节点和单个输出神经网络,而且肯定会产生过大的杀伤力,因为PID控制器会更简单,并且您实际上可以使用仅一行代码的简单P控制器来达到平衡。但是,我不必像PID控制器那样对这个NN进行调整,所以这很酷。使用更多的输入将很有趣,您可以简单地将陀螺仪的值设置为两个输入,而将加速度计设置为三个输入神经网络的另一个。然后,您将不需要补充过滤器,因为神经网络将充当过滤器。不确定如何操作,但尝试可能很有趣。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 机器人
    +关注

    关注

    211

    文章

    28745

    浏览量

    208914
  • Arduino
    +关注

    关注

    188

    文章

    6477

    浏览量

    188084
收藏 人收藏

    评论

    相关推荐

    人形机器人“造车”,车企扎堆布局!

    人形机器人率先落地于汽车制造应用已被看好,这将加速人形机器人的商用进程。   图源:广汽集团   广汽 GoMate 多项零部件研   GoMate是一款全尺寸的足人形
    的头像 发表于 12-30 01:31 1909次阅读
    人形<b class='flag-5'>机器人</b>“造车”,车企扎堆布局!

    宁德时代机器人团队成立

    宁德时代在机器人领域的布局正逐步展开。去年底,该公司开始加大对机器人领域的投入,并已在上海组建了一支由数十构成的团队,专注于机器人本体
    的头像 发表于 02-12 09:22 236次阅读

    两轮车智能化研究:主机厂扎堆进入,两轮车智能化持续提升

    佐思汽研发布《 2024-2025年两轮车智能化及产业链研究报告 》。 本报告聚焦两轮车的智能化升级,对电动两轮车、摩托车的市场规模、智能化功能特点、智能件分的产业链、海外市场、竞争格局、厂商智能化
    的头像 发表于 01-21 10:59 346次阅读
    <b class='flag-5'>两轮</b>车智能化研究:主机厂扎堆进入,<b class='flag-5'>两轮</b>车智能化持续提升

    广汽轮足人形机器人,保安外卖家教样样来

    不久前,广汽集团对外发布了自主研发的第三代具身智能人形机器人GoMate。这款全尺寸足人形机器人全身拥有38个自由度,在四足状态下高度约1.4米,
    的头像 发表于 01-16 13:58 381次阅读

    【「具身智能机器人系统」阅读体验】2.具身智能机器人的基础模块

    具身智能机器人的基础模块,这个是本书的第二部分内容,主要分为四个部分:机器人计算系统,自主机器人的感知系统,自主机器人的定位系统,自主机器人
    发表于 01-04 19:22

    【「具身智能机器人系统」阅读体验】1.初步理解具身智能

    现状和前沿研究,详细介绍大模型的构建方法、训练数据、模型架构和优化技术。 第4部分(第10章到第13章)深入探讨提升机器人计算实时性、算法安全性、系统可靠性及具身智能数据挑战的具身智能机器人系统研究
    发表于 12-28 21:12

    Qorvo助力电动两轮车性能提升

    电动两轮车已经成了中国人的出行神器,轻巧便捷,即停即走,接娃买菜轻松拿捏,让高油价和停车难不再是事。截至2023年底,中国电动两轮车市场拥有4.2亿辆的保有量,几乎每四就有一辆,且市场仍未见顶。据预测,随着2023年新国标修订
    的头像 发表于 11-15 15:59 316次阅读

    七腾机器人:防爆轮式机器人-四八驱全新上线

    今日,七腾机器人有限公司(以下简称“七腾机器人”)推出全新产品:防爆轮式机器人-四八驱。该款产品是七腾轮式巡检机器人产品系列的最新成员,防
    的头像 发表于 10-21 16:32 263次阅读
    七腾<b class='flag-5'>机器人</b>:防爆轮式<b class='flag-5'>机器人</b>-四<b class='flag-5'>轮</b>八驱全新上线

    构建语音控制机器人 - 深入研究电路

    一个学期的项目。然而,这个机器人并不是你在初中或高中时建造的标准机器人汽车。我和我的实验室伙伴只获得了基本的两轮机器人组件,包括轮子、电机、底盘、Arduino Leonardo、电池和面包板,我们
    的头像 发表于 10-02 16:40 305次阅读
    <b class='flag-5'>构建</b>语音控制<b class='flag-5'>机器人</b> - 深入研究电路

    两轮电动车系统介绍与THVD8000在两轮电动车上的应用

    电子发烧友网站提供《两轮电动车系统介绍与THVD8000在两轮电动车上的应用.pdf》资料免费下载
    发表于 09-27 11:12 0次下载
    <b class='flag-5'>两轮</b>电动车系统介绍与THVD8000在<b class='flag-5'>两轮</b>电动车上的应用

    常见的电动两轮车BMS架构应用说明

    电子发烧友网站提供《常见的电动两轮车BMS架构应用说明.pdf》资料免费下载
    发表于 09-12 09:28 0次下载
    常见的电动<b class='flag-5'>两轮</b>车BMS架构应用说明

    维顶机器人获得B融资

    维顶机器人,一家深耕智能装备制造领域,以机器人应用为核心,致力于为客户提供全方位自动化解决方案的高新技术企业,近日宣布成功完成B融资。本轮融资的具体金额虽未对外披露,但吸引了包括沈阳科投在内的多家知名投资机构参与,彰显了资本市
    的头像 发表于 08-27 15:45 455次阅读

    鲁大师2023两轮电动车行业调研报告

    2021年3月起,鲁大师已经连续年发布涵盖了电动自行车、轻便电动摩托、中高端电动摩托等品类的《电动两轮车行业报告》。如今,在持续进军两轮电动车评测的基础上,通过线上线下多维度深入调
    的头像 发表于 05-15 10:08 383次阅读
    鲁大师2023<b class='flag-5'>两轮</b>电动车行业调研报告

    两轮电动车遥控解锁方案

    两轮电动车遥控解锁方案
    的头像 发表于 05-09 09:33 1416次阅读
    <b class='flag-5'>两轮</b>电动车遥控解锁方案

    基于ACM32 MCU的两轮车充电桩方案,打造高效安全的电池管理

    随着城市化进程的加快、人们生活水平的提高和节能环保理念的普及,越来越多的人选择了电动车作为代步工具,而两轮电动车的出行半径较短,需要频繁充电,因此在城市中设置两轮车充电桩就非常有必要了。城市中的充电
    发表于 03-06 15:10