盗梦陀螺攻略5- PID平衡算法

刚过完长假,继续发攻略来克服长假综合症。看到galiu同学带着女儿玩乐高,我突然非常高兴,哈哈,也许这就是若干年后的我啊! :)

进入正题,介绍提了多次的PID平衡算法。先从网上摘抄一段:

当今的自动控制技术都是基于反馈的概念。反馈理论的要素包括三个部分:测量、比较和执行。测量关心的变量,与期望值相比较,用这个误差纠正调节控制系统的响应。

这个理论和应用自动控制的关键是,做出正确的测量和比较后,如何才能更好地纠正系统。

在工程实际中,应用最为广泛的调节器控制规律为比例、积分、微分控制,简称PID控制,又称PID调节。它以其结构简单、稳定性好、工作可靠、调整方便而成为工业控制的主要技术之一。当被控对象的结构和参数不能完全掌握,或得不到精确的数学模型时,控制理论的其它技术难以采用时,系统控制器的结构和参数必须依靠经验和现场调试来确定,这时应用PID控制技术最为方便。即当我们不完全了解一个系统和被控对象,或不能通过有效的测量手段来获得系统参数时,最适合用PID控制技术。PID控制,实际中也有PI和PD控制。PID控制器就是根据系统的误差,利用比例、积分、微分计算出控制量进行控制的。

比例(P)控制
比例控制是一种最简单的控制方式。其控制器的输出与输入误差信号成比例关系。当仅有比例控制时系统输出存在稳态误差(Steady-state error)。

积分(I)控制
在积分控制中,控制器的输出与输入误差信号的积分成正比关系。对一个自动控制系统,如果在进入稳态后存在稳态误差,则称这个控制系统是有稳态误差的或简称有差系统(System with Steady-state Error)。为了消除稳态误差,在控制器中必须引入“积分项”。积分项对误差取决于时间的积分,随着时间的增加,积分项会增大。这样,即便误差很小,积分项也会随着时间的增加而加大,它推动控制器的输出增大使稳态误差进一步减小,直到等于零。因此,比例+积分(PI)控制器,可以使系统在进入稳态后无稳态误差。

微分(D)控制
在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系。自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳。其原因是由于存在有较大惯性组件(环节)或有滞后(delay)组件,具有抑制误差的作用,其变化总是落后于误差的变化。解决的办法是使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零。这就是说,在控制器中仅引入 “比例”项往往是不够的,比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势,这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调。所以对有较大惯性或滞后的被控对象,比例+微分(PD)控制器能改善系统在调节过程中的动态特性。

看概念可能有点晕,举个小小的例子也许能帮助理解。看下面的图:

假设我们想把一个小球稳定在一个光滑的坡顶,这显然是一个不平衡的系统,稍有扰动小球就会滚下来。假设恰好平衡的位置坐标是L,我们可以测量到小球的位置是x,那么怎么给小球施加f(x)的力反馈,让它能够平衡呢?

最直观的想法就是f(x) = Kp*(L-x),简单的说就是你在左边我就向右推,你在右边我就向左推,这就是比例因子P;

现在考虑两种情况,同样是在x位置,小球静止和小球具有速度V这两种情况。很明显,如果V>0,我们只需要施加更小的力,因为小球自身的惯性会让它运动向平衡位置。所以可以修正f(x) = Kp*(L-x) – Kd*V。因为速度一般不容易测量,我们常常用位置的变化Δx除以测量的时间差Δt来计算速度,所以这就是微分因子D;

情况继续发生变化,上面考虑的是斜坡静止的情况,如果这个变态的斜坡是移动的怎么办呢?(例如两轮平衡机器人实际上是可以运动的,对于静止的磁悬浮来说,不需要考虑这个参数)这时候我们需要不断的累加并平均x值,来计算平衡位置的L,这个就是积分因子I;

以上就是PID的简要介绍。说起来容易,真正调试的时候,最恼火的就是这几个参数到底是多少,办法只有一个:试,不断的试!

当然,试验也不要当老黄牛,累死都没人知道。我曾经试其中某个参数,从0.1开始,每次加0.01,差点试到崩溃。后来想了个办法,用串口把Arduino的读数发送到电脑,然后用软件分析结果,看到数据明显发现这个值偏小,发狠改到20,就这样成功了…..

当时的数据找不到了,发一段成功悬浮时的log吧,其中两种颜色分别代表两个方向的传感器读数(相当于x):

PID的测量值

从图上可以看出,平衡的位置具体在哪里,我们可能不一定能精确知道,但是通过合适的反馈系统,陀螺能够自动稳定到相应的位置上。参数不正确的情况下,这些点会越振越远,直到失控。

最后附上源代码,没有时间整理,可能有不少问题,有兴趣的同学凑合看吧 :)

//PINs setting
int adjust1Pin = 1;    //用来调节A的电位器
int adjust2Pin = 2;    //用来调节B的电位器
int read1Pin = 4;      //用来连接输入A传感器
int read2Pin = 3;      //用来连接输入B传感器
int i1Pin = 36;        //连接电机驱动板的I1接口
int i2Pin = 37;        //连接电机驱动板的I2接口
int i3Pin = 39;        //连接电机驱动板的I3接口
int i4Pin = 38;        //连接电机驱动板的I4接口
int power1Pin = 5;     //连接电机驱动板的EA接口
int power2Pin = 6;     //连接电机驱动板的EB接口
int rotatePin = 3;     //用来控制磁场旋转的PMW接口

boolean debug = false;
boolean writeLog = false;
double setKd1 = 0.55;
double setKd2 = 0.55;
double setKp = 22;
int offset = 70;
int delayMs = 1;
int tick = 0;
int myLog[3500];

//PID structure
typedef struct {
  double target;
  double aver;
  double Kp;
  double Kd;
  int preError;
  int power;
  boolean flag;
  double v;
} PID;

PID Pid1, Pid2;

void setup()
{
  pinMode(i1Pin, OUTPUT);     //I1和I2都是数字信号
  pinMode(i2Pin, OUTPUT);     //通过设置I1和I2来控制电流方向
  pinMode(i3Pin, OUTPUT);     //I1和I2都是数字信号
  pinMode(i4Pin, OUTPUT);     //通过设置I1和I2来控制电流方向
  pinMode(power1Pin, OUTPUT);  //按占空比方式输出的模拟信号
  pinMode(power2Pin, OUTPUT);  //按占空比方式输出的模拟信号
  pinMode(rotatePin, OUTPUT);  //按占空比方式输出的模拟信号

  //analogWrite(rotatePin, 128);

  Serial.begin(9600);          //设置波特率
  TCCR0B = 0x01;   // Timer 0: PWM 5 &  6 @ 16 kHz
  TCCR1B = 0x01;   // Timer 1: PWM 9 & 10 @ 32 kHz
  TCCR2B = 0x01;   // Timer 2: PWM 3 & 11 @ 32 kHz
  Pid1.Kp = setKp;
  Pid1.preError = 0;
  Pid1.Kd = setKd1;
  Pid1.power = 0;
  Pid1.flag = true;
  Pid1.target = 300;
  Pid1.aver = 0;
  Pid1.v = 0;
  Pid2.Kp = setKp;
  Pid2.preError = 0;
  Pid2.Kd = setKd2;
  Pid2.power = 0;
  Pid2.flag = true;
  Pid2.target = 300;
  Pid2.aver = 0;
  Pid2.v = 0;
  tick = 0;
}

int tick2 = 0;
//boolean rotateFlag = true;
void loop()
{
  //digitalWrite(rotatePin, rotateFlag);
  //rotateFlag = ! rotateFlag;
  //delay(16000);
  //return;

  if(debug) tick = 0;
  tick++;
  if(tick==500)
  {
    tick2++;
    if(tick2<50) {tick = 0;return;}
    tick2 = 0;
    if(writeLog)
    {
      for(int i=0;i<500;i++)
      {
        Serial.print(myLog[i*7 + 0]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 1]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 2]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 3]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 4]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 5]);
        Serial.print("  ");
        Serial.print(myLog[i*7 + 6]);
        Serial.println("  ");
      }
      Serial.println(Pid1.target);
      Serial.println(Pid1.preError);
      Serial.println(Pid2.target);
      Serial.println(Pid2.preError);
    }
    return;
  }
  else if(tick>500)
  {
    tick = 0;
    //delay(990000);
    return;
  };

  //=======第一组电位器和传感器========
  int readValue1 = 0;
  for(int i = 0; i < 4; i++) readValue1 += analogRead(read1Pin);
  readValue1 >>= 2;
  //readValue1 += (Pid1.flag ? 1 : -1) * Pid1.power / 17;
  int adjustValue1 = analogRead(adjust1Pin); //410 analogRead(adjust1Pin);
  Pid1.aver = Pid1.aver * 0.9995 + readValue1 * 0.0005;
  Pid1.target = Pid1.target + (Pid1.target - Pid1.aver) / 100.0;
  Pid1.target = max(0, max(adjustValue1 - offset, Pid1.target));
  Pid1.target = min(755, min(adjustValue1 + offset, Pid1.target));

  //=======第二组电位器和传感器=======
  int readValue2 = 0;
  for(int i = 0; i < 4; i++) readValue2 += analogRead(read2Pin);
  readValue2 >>= 2;
  //readValue2 += (Pid2.flag ? 1 : -1) * Pid2.power / 6;
  int adjustValue2 = analogRead(adjust2Pin); //240 analogRead(adjust2Pin);
  Pid2.aver = Pid2.aver * 0.9995 + readValue2 * 0.0005;
  Pid2.target = Pid2.target + (Pid2.target - Pid2.aver) / 1000.0;
  Pid2.target = max(0, max(adjustValue2 - offset, Pid2.target));
  Pid2.target = min(755, min(adjustValue2 + offset, Pid2.target));

  if(debug)
  {
    Serial.println(adjustValue1);
    Serial.println(adjustValue2);
    Serial.println(readValue1);
    Serial.println(readValue2);
    Pid1.flag = adjustValue1 > 512;
    Pid1.power = abs(adjustValue1 - 512) / 2;
    if(Pid1.power > 255) Pid1.power = 255;
    digitalWrite(i1Pin, Pid1.flag);
    digitalWrite(i2Pin, !Pid1.flag);
    analogWrite(power1Pin, Pid1.power);
    Pid2.flag = adjustValue2 > 512;
    Pid2.power = abs(adjustValue2 - 512) / 2;
    if(Pid2.power > 255) Pid2.power = 255;
    digitalWrite(i3Pin, Pid2.flag);
    digitalWrite(i4Pin, !Pid2.flag);
    analogWrite(power2Pin, Pid2.power);
    delay(32000);
    return;
  }

  //Calculate power values
  double v, error;
  error = readValue1 - Pid1.target;
  v = error - Pid1.preError;
  Pid1.v = (Pid1.v * 6 + v) / 7;
  Pid1.power = (int)error * Pid1.Kd + Pid1.v * Pid1.Kp;
  Pid1.flag = Pid1.power > 0;
  Pid1.power = abs(Pid1.power);
  if(Pid1.power>255) Pid1.power = 255;
  Pid1.preError = error;

  error = readValue2 - Pid2.target;
  v = error - Pid2.preError;
  Pid2.v = (Pid2.v * 6 + v) / 7;
  Pid2.power = (int)error * Pid2.Kd + Pid2.v * Pid2.Kp;
  Pid2.flag = Pid2.power < 0;
  Pid2.power = abs(Pid2.power);
  if(Pid2.power>255) Pid2.power = 255;
  Pid2.preError = error;

  //Write PMW to control the floa
  digitalWrite(i1Pin, Pid1.flag);
  digitalWrite(i2Pin, !Pid1.flag);
  analogWrite(power1Pin, Pid1.power);

  digitalWrite(i3Pin, Pid2.flag);
  digitalWrite(i4Pin, !Pid2.flag);
  analogWrite(power2Pin, Pid2.power);

  myLog[tick * 7 + 0] = tick;
  myLog[tick * 7 + 1] = (int)Pid1.target;
  myLog[tick * 7 + 2] = readValue1;
  myLog[tick * 7 + 3] = Pid1.power;
  myLog[tick * 7 + 4] = (int)Pid2.target;
  myLog[tick * 7 + 5] = readValue2;
  myLog[tick * 7 + 6] = Pid2.power;

  /*
  for(int i=0;i<8;i++)
  {
    digitalWrite(rotatePins[i] , 0);
    digitalWrite(rotatePins[(i + 1) % 8] ,1);
    delay(1);
  }
  digitalWrite(rotatePins[0] , 0);
  */

  delay(delayMs);
}


对 “盗梦陀螺攻略5- PID平衡算法” 的 155 条 评论

  1. John 说:

    哇哈~这个赞~都用到PID控制了!学习学习!

  2. 玩平衡用PID,价格便宜量又足 :)

  3. 胡雪岩 说:

    是个好东东,我还不太会啊

  4. 魔王 说:

    那个 segway 小车的PID 曾经测试了N^N遍..还是没有成功

  5. z 说:


    用什么软件、分析接收串口发来的数据?

  6. propolis 说:

    虽然不太懂,学习一下。呵呵

  7. 老白兔 说:

    大哥!!!佩服的五体投地啊!!!
    我是学计算机的,我们那个单片机啊什么的都没学,稍微会点编程,
    好后悔以前电子电路打酱油了啊……
    对你的这些东西都感到震撼!!!
    头一回有这么强烈的想好好学点东西的冲动……
    能不能跟我说下,要学习些哪些方面的知识啊……
    谢谢,膜拜啊……

    • 哈哈,爱好跟专业是两回事,我的专业是航空发动机
      有了想法,在google上查查资料,动起来就没那么难了
      需要涉及到的知识点主要包括:电子电路,嵌入式,C或者Java编程
      电子电路我也不熟,所以用的是Arduino的开发板,不用做板子了

  8. galiu 说:

    被点名了哇?呵呵。
    带着女儿玩乐高的好处之一是,申请经费非常便利啊…
    最近刚借着要遥控乐高为名,把手机换成了G7,努力搞Android中…
    :D :D

    • cool!我最近也刚入手了G7,嘿嘿,也是准备用来遥控用
      blog如果你自己有空间的话,就用wordpress
      没有空间的话,用新浪微薄

  9. galiu 说:

    请教下楼主,blog有哪个比较推荐啊?

  10. 海云飞 说:

    老大研究下‘四轴’飞行器吧,那个更爽!看看ar.drone

  11. itiancai 说:

    不是吧,我说自控的都没你用的熟。悲剧,自己已经被无情的就业大军推倒自动控制行业了。电子和机器人竟成业余爱好了。我可怜的IFAN还躺在工具箱里。

  12. jjhigh24 说:

    好强啊,第一次进入到这个网站,我琢磨到半夜才恋恋不舍的关电脑,太佩服了,作为电子专业的我,深感羞愧,C语言我们才刚刚起步学习,不想您老人家都已经出神入化了。我的好几个同学对你的网站都爱疯了,最近我们几个人组织三人的小队伍,打算将您的陀螺战役再做一遍,以表敬意!中途遇到什问题还望您多多指点,顺便问一下,这样的制作,成本会很高吗?

    • 欢迎欢迎!
      这个制作成本不高,少吃几顿饭就出来了 :)
      如果用老顽童的电路方案,会更便宜
      我的方案用了单片机,那个arduino的板子可能会贵一点,一百多吧
      另外,磁铁和线圈也得各几十元

      • jjhigh24 说:

        好嘞,说干就干,下周末我们就去上海买材料去~~~

        • 哇,还得去上海买?路费就不便宜了吧?
          我那个有个清单,先看看
          到时候一次全搞定,省的老跑
          实在不够的可以淘宝 :)

          • jjhigh24 说:

            没有啊,我学校离那儿近,半个小时的路就OK了,不过说的对,有些东西却是要去淘宝的,但更想去真正的电子市场看看,体验一下…感觉会不错~哈哈

  13. 李宙恒 说:

    代码好难看懂 能否多加一点注释啊

  14. 李宙恒 说:

    或者有一个流程图也行 这样看起来会比较方便吧。。。不然那么多 符号数字。。头都大了。。。

  15. 李宙恒 说:

    动力哥!!!!有米有比较完整的原理图啊 就是你做的这个。。有的话麻烦一下~~~~~发到我邮箱吧 453569822@qq.com 感谢了 !!!!!!!!最近一直在弄这个。。。很悲催啊啊啊

  16. 李宙恒 说:

    还有 霍尔元件放在那个地方 是用来监测谁的磁通的变化?想来想去 4个螺线管的磁场方向应该是平行霍尔元件的表面的吧。那霍尔器件就不能监测到了。。
    说白了 我还是对这个系统如何反馈。如何控制有点迷惑。。。
    好了 虽然这个问题有点白痴。。请表拍我~~~~~~

    • 你说对了,4个线圈的磁场方向是平行霍尔表面的,目的就是线圈电流对霍尔没有影响
      注意注意,霍尔元件是用来判断陀螺位置的,跟线圈没有关系
      哈哈,你都知道自己问的问题不合适了,自己拍几下吧 :D

      • 李宙恒 说:

        哦 soga!那程序呢???有没有详细的注释哈。。不然太难看了。。

        • 我帖程序的时候,显然不会故意把注释删了再贴
          你看上面那几行英文就是我的注释了
          其实就是PID算法
          我建议你也先做一个上拉式的,只有一个线圈
          以此了解PID,然后就能看懂代码了

          这段代码,你把debug,tick相关的都删掉,然后把所有的Pid1,Pid2这样的删掉一半,就会发现其实没几行了

          • 李宙恒 说:

            嗯 好的 上拉式的貌似简单的。。还有一个问题。debug和 tick是做啥的啊???

  17. 李宙恒 说:

    终于快要看懂了 。这个是用的位置式PID算法吧?(别又错了) 。
    关于PID的计算过程那里已经懂了
    但还是有几个地方不太明白
    1.target = 300 ;为什么是300 300对应的电压应该是300/1024*5 吧
    而霍尔传感器的输出(无磁通时)为2.5V啊 这之间应该有运放的作用吧?
    2.//=======第一组电位器和传感器======== 这个过程不是太明白在做些什么。。能稍微讲一下么。大概意思就行。。

  18. lslsls 说:

    这个采样用到了什么滤波算法?

    • 这里采用了最先进,快速,高效的算术平均滤波算法…..
      好吧,专家们一般都这样用术语吓唬人
      其实就是取几个值平均一下嘛,代码看这里:
      int readValue1 = 0;
      for(int i = 0; i < 4; i++) readValue1 += analogRead(read1Pin);
      readValue1 >>= 2;

      • DaisyHUnter 说:

        内个 readValue1 >>=2 这里是什么意思?查了资料说指2进制位移运算,但是,高中狗对介个并不太懂,可以说下它在这里用处么?

        • Prince z 说:

          >>2表示位向右移两位,二进制所以相当于得到的值除以4(比如十进制1000右移一位表示0100,变成10分之1),即取平均,相当于滤波。

  19. 没错,就是PID,呵呵
    target你没看懂太正常了,因为我刚才看了半天,想了半天才想起来这是干啥用的 :D
    大概说说当初加这个参数的原因
    我们调节一个平衡位置的时候,需要有个目标值,它表示陀螺正好处于平衡位置时传感器的读数。这个目标值是多少我们其实并不知道,而且它会随着温度,环境磁场而变化,这就是我外接ajustPin的原因,既然你不知道目标值是多少,那么调一调试试,拧电位器让它能平衡为止

    所以我最初的程序是这么写的:
    Pid1.target = adjustValue1;

    请注意,这样写就已经可以实现平衡了!所以你看代码的时候,可以先把Pid1.aver,offset这些东西都删掉,代码就容易看懂了

    后来发现一个小问题,比如物理上真正的平衡点位置是300,而我拧到的位置是adjustValue1=350,虽然有点误差,但是依然可以平衡。只是线圈强行把陀螺稳定在一个不平衡的位置,它肯定是要多用电的。所以我想做点优化,让程序自己找到这个300值。上面那个aver就是平均的意思,当我发现施加的电流多次平均以后总是偏向某一边,我就把adjustValue做一点修正,让它反过去接近真正的值。

    结果问题又来了,当我刚把陀螺放上去的时候,这个aver是从0突然变大的,最初的一秒钟很不准确,这个算法会误认为陀螺现在位置偏移非常大,就猛加电流,结果真的就不平衡了。所以我又加了一个offset参数,表示修正的范围,超过这个范围,我就不在修正了。

    这段代码的结果是,陀螺刚放上去的时候,会稍微抖动一下,然后会慢慢的越来越平稳。

    总结:这上面都是浮云,其实我监测的电流值只下降了一点点,至于平稳,你慢慢的调电位器,一样可以调到一个非常平稳的位置。不过我也懒得把程序改回去了,这就是你看到的结果。建议你只留这么一句即可:
    Pid1.target = adjustValue1;

    这样顺便把第一个问题也回答了,那个target最后是会被adjustValue覆盖的,所以写成多少都可以,写成300完全是个人爱好 :D

    • 比利丸 说:

      请教一下第128行 Pid1.aver = Pid1.aver * 0.9995 + readValue1 * 0.0005;在setup()就已定义Pi1.aver=0,那么*0.9995有什么意义呢?

  20. 李宙恒 说:

    昨天终于把电路搭好了 看着一堆一堆杂乱的线 放上小磁铁试了试。
    当用手托着小磁铁靠近线圈上方时,感觉到有点震动,感觉也快要平衡了(自我安慰一下),但一松开手 小磁铁就被吸到大磁铁上去了。。

    有一个问题 这个adjust1Pin 这个电位器的解法是这样的吗??电位器两端分别接地 和 VCC ,中间的接arduino 的1管脚 ???()
    然后调平衡用这个来调??
    始终感觉不大对劲啊。可以调节与LM358相连的电位器,使得输出运放输出电压在2.5V 那么可以设置target=511啊 。这样不是更方便吗?

    • 你理解的很正确
      但是与LM358相连的电位器是被放大几十倍的,太灵敏了,稍微一动就变几十,想把它调到准确的2.5V有点困难(还会温漂,每次读数都变)
      而且那个电位器比较小,是焊在板子上的,你做好以后封到盒子里,怎么调节它呢?
      所以我再引出来一个大电位器,这个是不放大的,调起来方便,而且可以把它安装在盒子的面板上,看上去比较酷

      具体操作的时候,先调板子上的电位器,让它差不多是2.5V,这个以后就不动了。将来再调就调adjustPin1,如果传感器温漂到2.0V,你调节target到400左右也是一样平衡的 :)

  21. 李宙恒 说:

    与LM358项链的电位器这个调节会改变运放同相端的电压。这个电压是直流的 不会被放大。运放放大的交流信号吧,也是就传感器测得的电压的波动(传感器的输出电压是2.5V基准电压+波动),运放会放大这个由磁场变化所导致的传感器的输出信号的波动吧 。。

    昨天我就调节的这两个电位器(全是裸露在外边的。。。。),电压变化连续,也不太灵敏,貌似转了10几圈才从0.8V转到2.5v 。。

    还有一个地方不太明白,就是如何根据error来判断通电的顺序,Pid1.flag = Pid1.power > 0; 就是这里了,由于昨天弄得很仓促,线接的一团糟。。。这个地方要考虑线圈的接法 和 线圈与 L298N的接法 吧??如果发现磁铁往左偏,经过程序运算后,我还把磁铁往左推。。。。。。。

    没时间了 上课去了。。
    感谢动力哥早上的指导!!!

  22. 李宙恒 说:

    老顽童,,请教一个问题哈
    我把LM358 的正相电压调到了2.5V 发现这个芯片的2个输出 1和7脚 电压始终在3.8V。而且调节正相的电位器 几乎是没有变化。。是不是就可以确定这个芯片坏掉了。。

    • 老顽童 说:

      两个正相都在2.5V.

      两个负相也要上2.5V.

      输出才会是2.5V.

      • 李宙恒 说:

        用的负反馈接法 闭环增益50。
        但是无论如何电阻 为啥运放的值就不变呢?

        • 老顽童 说:

          正相在2.5V.

          负相也要在2.5V. 输入才为零.

          输出才不会被50倍把小误差放大到饱和区. 才可能也在2.5V附近.

        • 老顽童 说:

          没见到图,就不具体.
          口述的会各说各的,想不到一起去.

          变动电阻时,要看电阻处在什么地方.
          如能大幅变动电压的. 输出就应该有反应.

          如果仅仅只是变动阻值,也许回路阻抗很大. 这点变动没反应也正常.

    • 老顽童 说:

      还有就是要控制好闭环增益.(多级时,尽量小环,不要大环).
      在够用的条件下,放大量尽量取低点.比如100倍以下.

      要不然,开环增益太高,容易自激,
      量到的就是一乱七八糟,和莫明奇妙的信息,会把分析引入岐途.

      • 李宙恒 说:

        额 换了一个LM358 莫名奇妙的好了。。
        老顽童,问一下哈 ,有没有这样的器件啊。。有两个输出口,当输入电压高于某个值时2个输出均为高,当输入电压低于某个值时输出电压均为低,当输入电压在这两者之间时一个输出高 一个输出低。。。

        • 这种器件组合一下就可以吧,把输入分成两股,然后用两个比较器,一个high,一个low
          各自输出各自的不就好了嘛 :D

        • 老顽童 说:

          还不知道有没有现成的三电平器件, 有市场需求的话,应该也不难生产.

          只知道近些年在DC变换中,开始流行三电平变换器,很巧妙的,适用于高电压,大功率场合.
          把一个方波分割成2个,分2次切换,减轻了对开关管的应力. 除了赞叹外,本人还没有实践过. 人类,真的是创意无穷.

          • 李宙恒 说:

            嗯 创意无穷,我还在一个网上看到别人用电子元器件做的各种动物造型。。真的很有趣。
            运放是放大交流信号啊。?怎么成直流放大器了?

          • 老顽童 说:

            就是特意来纠正你的.

            运放是正宗的,专门的直流放大器.

        • 老顽童 说:

          运放是直流放大器.

  23. 李宙恒 说:

    好像找到一点原因了 我一旦打开实验室的直流稳压电源 霍尔的输出变化很大。难道实验室的直流稳压源对霍尔有影响?

    • 如果是这样的话,可能是你的直流稳压电源容量不够,初始电流太大的时候撑不住
      对霍尔的影响可能是“副产品”

      • 李宙恒 说:

        进一步实验排查发现 没那么简单。。应该不是直流稳压源的影响 而是线圈们的影响。。因为用一个9V电池接在线圈两端 发现霍尔输出变化了。。。
        应该和霍尔的位置有关。
        但是洞洞板这个东西,霍尔器件不太好调整位置啊。。要调整就只能调整线圈的位置了。。

        • 对,安装霍尔有注意事项的,平面一定要竖直,另外高度上尽量接近线圈高度的中心
          即使这样,也只是尽量减少线圈对霍尔的影响而已,肯定多少有一点磁通量的

          • 李宙恒 说:

            嗯 是的啊 最近一直在调试 发现霍尔的安装要很精确。。。
            就算感觉调的很竖直了,给线圈通上9V电压,再测一下readvalue 发现还是变话了40多。。。

          • 40多可以接受了,反正可以用adjust调节的
            两个电位器当然不是同时调,readValue调到500左右,以后就再也不动了
            adjust连到外面,以后用这个调

  24. 李宙恒 说:

    现在真的发现和每次做实验 就算与运放相连的电位器不变 但是arduino读出来的readvalue变化 每次实验都不一样 而且变化比较大。。有时候是300多 有时候500多。。
    另外问一下 调整adjustvalue 怎么调???
    您说的是调整到浮子平衡为止,但是调到哪能平衡呢 总不能一个一个值去试吧。。

    • adjustValue就是一个大电位器,一共就一圈,拧一下就知道了
      一般来说,我的那个磁悬浮隔一段时间以后,放上去就不能平衡了
      这时候用手大概扶一下,电位器拧一圈,你能明显感觉到手上不吃劲,那就是到平衡位置了

  25. 李宙恒 说:

    还有就是 与线圈相连的L298的接线方向要不要特别注意的??万一通电时候产生一个 通电的方向反了 也完蛋了 。。。

  26. 李宙恒 说:

    还有。。。
    参数应该怎么调 ,,,我现在把浮子放上去能感到很快的抖动了。。是程序的参数出问题了,还是其他的????崩溃了。

    • 小盆友,以我的经验看,浮子抖动就是快成功了!
      先恭喜一下,基本上应该就是参数的问题了。
      咱们的磁铁,线圈,浮子,霍尔位置都不一样,参数可能会差比较多,多试试吧

      • 李宙恒 说:

        浮子还是往下面的那个大磁铁那里飞!!!!
        就是我把浮子往旁边推一点,试一试线圈的斥力,看能不能把它推回来。。结果线圈好像对浮子只有抖动似的。。浮子一下就飞到大磁铁上去了。。
        我把PWM输出上限调到1023了 才有感觉 。。线圈不给力啊。。

  27. 李宙恒 说:

    震动感很强 但是老震飞 把浮子放到中间地方也给震到旁边去了。。。是不是PID设置参数的问题 。。那这个参数应该咋样设置啊。。
    还有,您那个坐标图里边的红点是啥?黑点是target吧?

    • 参数….慢慢试吧,没啥好办法
      红点和黑点分别是readValue1和readValue2,它们震荡的中心位置分别是各自的target

      • 李宙恒 说:

        当把浮子放上去的时候 你的readvalue好像变化不大啊 我的是直接快要变到两个极限值了。。

        • 你的电源电压是多少?
          线圈铜丝直径?线圈电阻多少?
          感觉真的是线圈不给力

          • 李宙恒 说:

            今天弄好了 电流变大了 3A多。。。线圈的磁力还是蛮大的。。再就是控制上的问题了 。。。

  28. 李宙恒 说:

    我可不是“业内”,只是看见厕所上有很多XXXX

  29. 老顽童 说:

    有一个概念必须明确,运放就是专门的直流放大器.
    这一点,可以去找书本核实.也可以剖析内部电原理.
    ········
    整个磁悬浮电路中,就没有交流, 只有被换向的直流. 顶多是被PWM的直流.

    如何分辨出是交流,还是被换向的直流呢?
    交流总是会表现出有周期的特征.那怕是变周期的.

    直流的按需换向就难有周期特征. 那怕是出现了机械振动的表象.

    关键是看频率当家,还是位移作主.

    • 李宙恒 说:

      哦 是的。。我隐隐约约记起来了老师说的话。。。。看来我得好好补习基础知识了。。

      • 看来确实是专业科班出身 :)
        不过我觉得PWM可以认为是一个稳定的直流叠加一个交流分量
        老顽童说的周期特征来区分交流直流,我感觉不太合理
        PWM的周期性就非常明显

        • 李宙恒 说:

          怎么就是不稳定呢不稳定呢。。。调啊调啊 调得我心都碎了。。。。
          怎么这磁悬浮就不能给个面子呢。。??

        • 老顽童 说:

          PWM是直流脉动,只变占空比不变方向,顶多算脉动周期,
          还是直流性质 ,何来交流呢?

          霍尔指导换向,不是周期指导换向,
          所以,换向了,也不是交流.

          比如,交流感应电机是频率主宰旋转.属交流电机.

          永磁无刷电机由霍尔指导换向,尽管流向都变了,
          却不是交流电机.因为这换向只和位移有关,与频率无关.

          • 我明白你的意思,呵呵,必须是周期性+电流换向才是交流
            我以前学力学的时候,做过波的叠加和分解
            所以习惯性的把PWM这种直流脉冲分解为一个平均的直流分量,叠加一个交流分量
            当然我这种观点在电学专业上看可能太不专业了,主要是术语用的不精确
            受教了,多谢:)

          • 老顽童 说:

            不是啊. 咱现在真正计较的是,在黄二的那类电路上,就是无法捉到稳定的波形. 就是因为它根本就没有周期.

            不似你那个5V的PWM,尽管只是脉动,总还能见到,对吧.

            那么老头他们那时在讨论的频率,应该就只是自激了.

  30. vvisper 说:

    digitalWrite(i1Pin, Pid1.flag);
    digitalWrite(i2Pin, !Pid1.flag);
    analogWrite(power1Pin, Pid1.power);
    这几行是控制线圈电流方向的吗? 我怎么看不没明白呢 就像之前小电机实验里的这几行
    boolean buttonPressed = digitalRead(buttonPin);
    //设置转动方向,I1和I2值相反时,分别对应两种不同的转向;I1和 I2值相同时停止转动
    digitalWrite(i1Pin, buttonPressed);
    digitalWrite(i2Pin, !buttonPressed);
    我的意思是 比如一组水平放置的线圈 陀螺在旋转过程中水平向左偏移了 那么就应该控制左边的线圈产生斥力 此时右边的是吸引力 把它牵引像平衡位置 这是如何通过这几行代码实现的呢 我弄不明白了 。
    另外 是不是说 陀螺偏移的越大 传感器感应电压就越大 放大后传入单片机的电压就大 就应该控制输出pwm增大线圈中的电流? 也就是说除了给线圈供电的20v及其相应的电流外 EA端口收到的pwm信号会增大线圈中的电流?
    我有点乱啊。。。

    • 哈,你一点都没乱,最后一段说的全部正确 :)
      L298N你可以理解为一个放大器,EA=0的时候,线圈两端电压也是0,可以用万用表量一下检验。
      输出PWM的时候,线圈两端的电压是方波,算平均电压的话就是在变化了

  31. vvisper 说:

    拜托你给我讲一下 控制线圈电流方向的那几个代码 我不明白他们是怎么控制的 就像我上面问到的问题 难道线圈中的电流是不断交替变化的吗 这样岂不是很不稳定。。

  32. wlreg 说:

    这个算法没有看懂啊,囧。没有学过PID算法,不知道有没有参考书籍推荐呢,老男孩大神 T T,先谢谢。

    • 这个好像没有参考书,都是网上的文章一篇一篇的,拿出骗mm的决心,死缠烂打,其实很快就看明白了

      • wlreg 说:

        诶,我想的MM都不理我了,现在专心搞专业的说
        话说
        —————————————————————
        TCCR0B = 0×01; // Timer 0: PWM 5 & 6 @ 16 kHz
        TCCR1B = 0×01; // Timer 1: PWM 9 & 10 @ 32 kHz
        TCCR2B = 0×01; // Timer 2: PWM 3 & 11 @ 32 kHz
        —————————————————————
        这段设置的是什么呢,看不懂……原本板子今天可以拿到的,但是因为某些原因和快递错失了,失望ing

        • 这位同学,mm比专业重要,赶紧回去泡妞!
          btw:这段的作用是加快PWM的频率,看这里:http://www.diy-robots.com/?p=852

          • wlreg 说:

            如果生命中出现过那个人,那别人就只能是将就。一直都是不将就自己走过来的,其他mm什么的一点兴趣都没有啊,和专业比起来她们都弱爆了。还真是很羡慕老男孩和圈圈妈啊。
            原来老男孩筒子还有其他关于这个开发板的博文的呀,我还以为都在小爱的那个项目里哩。虽然还是看不懂,但是会努力看懂的。话说在成功弄出来之前我想都会打搅到老男孩筒子诶,由于是菜鸟希望老男孩筒子可以体谅一下哈!

          • DaisyHUnte 说:

            跨越时空的陈年狗粮

          • 在路上 说:

            跨越时空。现在看来十年前房价还是相对友好啊,大家业余时间还都有心思鼓捣这些娱乐。现在也就在校生还能有闲情逸致搞这些玩,大批人都忙着赚钱养家去了。

        • wlreg 说:

          那个“Arduino系列教程之 – PWM的秘密(下)”,我猜我大概是看懂了大部分吧,但是还是没有看懂
          —————————————————————
          TCCR0B = 0×01; // Timer 0: PWM 5 & 6 @ 16 kHz
          TCCR1B = 0×01; // Timer 1: PWM 9 & 10 @ 32 kHz
          TCCR2B = 0×01; // Timer 2: PWM 3 & 11 @ 32 kHz
          —————————————————————
          这个诶。教程上说TCCRnB是用来设置时钟的计数位数的,上面的程序上看,难道它们都是8位的吗。
          不过貌似加快PWM频率的设置就只有这一段吧?这段设置完后下面的程序都不是关于PWM频率设置的是吧,吧?

  33. wlreg 说:

    今天特意把程序打印了出来一条条研究了,程序方面还是有那么一些多地方不太懂诶,或许要先从整个磁悬浮的是怎么运行入手开始理解吧。
    1、看了攻略和上面的评论,整个装置通上电后通过电位器先将接运放的传感器的输出调节为2.5V,然后再放浮子上去。霍尔传感器感应的气势是浮子的磁通吗?然后通过传感器的输出变化反应浮子的倾斜程度?(错了请指正呀,感谢的说。)
    今天在图书馆居然被我找到一本关于PID控制器的书,对照了一下上面的符号和程序上的符号,大概理解了一些之前不懂的变量的意义,但是程序上还是有地方不懂,希望老男孩筒子指导一下吧。
    2、一开始的端口设置里,int rotatePin=3,rotatePin这个变量貌似一直都没有用过吧(只在上面程序注释里看见出现过)……
    3、Kp是比例系数,Kd是微分系数,这个程序采用的是增进式PID?那么setKd,和setKp这些系数都是实验慢慢调试出来的吗?如果我做的有些部件(磁铁的大小之类的)的和老男孩筒子列表里的有出入,那么这些值都要自己找了?
    4、程序第82行,if(debug) tick=0;
    这里debug不是设定为false吗?后面也貌似没有看见有更改过这个值,那么这一句实质上是永远不会运行的吧?
    5、程序第87行,if(tick2>=2;
    这个是右移两位的意思吗?就是相当于除以4了,这个的意义何在呢?
    7、程序144行,if(debug)下面的括起来的真的会运行吗?
    8、程序第162行,delay(32000)
    32000这个其实不用纠结的吧?但是总觉得很特殊的样子,为什么是这个设置……
    9、程序第131行,Pid1.target = min(755, min(adjustValue1 + offset, Pid1.target));
    755这个值是什么样来的呢?不是很明白的样子……
    我知道老男孩筒子有工作平时也比较忙的,可能问题有些繁琐,会让人觉得烦,希望老男孩筒子有心情的时候指导一下吧。这里万分感谢了。

    • wlreg 说:

      又看了遍程序,发现第6个问题的原因是因为上面有一个for语句连续读了4次电位器的值,然后这里右移两位是为了取平均值的原因吧?

    • wlreg 说:

      又看了遍程序,发现第6个问题的原因是因为上面有一个for语句连续读了4次传感器的值,然后这里右移两位是为了取平均值的原因吧?

      • wlreg 说:

        额,之前那个问题也问错了,程序的PID应该是位置型的……
        不过按照那个位置型PID的公式,貌似下面的这段就有点不解了
        ——————————————————
        error = readValue1 – Pid1.target;
        v = error – Pid1.preError;
        Pid1.v = (Pid1.v * 6 + v) / 7;
        Pid1.power = (int)error * Pid1.Kd + Pid1.v * Pid1.Kp;
        ——————————————————
        按照公式,这里应该是
        Pid1.power =Pid1.Kd*v+Pid1.Kp*(int)error
        不是吗?

        • wlreg 说:

          那个,又有了一个新问题。仔细看了一下程序
          第87行
          ———————————————–
          if(tick2<50) {tick = 0;return;}
          ————————————————
          按照我学的C语言的理解(只是入门级别,可能有错),这里有一个return语句,就是执行到这个return的话就会跳出函数体了,而这里正在执行的函数式loop函数,也就是说执行到这里,就跳出loop函数不往下执行了,按照开发板的运作,loop这个函数又会被从头开始执行。而程序的113行和119行也有一个return语句……
          其实我想问的是,按我的理解这段if(tick==500)这段程序是用来检测端口的值用的……其实特意弄tick和tick2这两个变量以及return语句这样来检测端口的用途是什么呢……这段有些弄不懂意图……

          • vvisper 说:

            wlreg 我这几天也在做这个陀螺 我的qq是397133023 如果你在北京就太好了 咱们当面谈谈 动力哥经常不在 我电路搭好了 最严重的是 我怎么测的不带陀螺的时候 传感器输出是2.57v啊 这么大 而通过放大器后的电压竟然不随磁场变化而变化 而且保持3.8v左右。。。。
            晕死

          • 传感器输出2.57V很正常,你需要把电位器的输出也调节到2.57V附近,就可以发现放大器后的电压有变化了。不然的话,这东西放大很多倍,稍微差一点就到最大电压了。

          • vvisper 说:

            我调了一下电位器 现在上电后在不放转子的情况下 从358出来的电压大小是0.05左右,两个都是 我是直接用万用表测的 放上浮子后变化范围是从0.xx到3.xx 总之没超过过4v 然后转子放上面总是飞出去 也有震动 但是线圈没多久就变得很烫 我就得断电 如果再继续 恐怕就着火了 。。。。 各种无语中 我的转子就是四个小钕铁硼 两小块加上两个大一点的薄片形的 上面还粘着个一元硬币。。

          • 这个页面帖子太长了,我早上发了一个集中回答的页面,你们可以在那里讨论,然后我把讨论结果统一添到页面里。

          • 你量过线圈的电阻吗?感觉特别烫的话,可能是铜丝比较粗吧?

          • wlreg 说:

            我的电路还在搭呢,主要是有些材料还没有到……导线、电位器和电阻什么的本来想在实验室拿的,但是还没有拿到手…………

          • vvisper 说:

            我是非常新手的新手 主要就是这段代码的有些地方看不懂 还说问问你呢 你赶紧加我qq吧 十万火急啊 呵呵

          • wlreg 说:

            QQ等我回宿舍才行。
            问一下,你20V电源方面是怎样解决的呀?我发现L298N的接20V电源的接口是那个标注VCC的吧。那种接口的20V电源可以买到么

          • 我是塞了一根电线在电源中心的孔里,然后缠了一段在外面的插头上,最后用黑胶布捆好,土法挺管用。

      • vvisper 说:

        呵呵 我是买的20v 3.25A的电源 本来说把那个接头剪掉劈成两半的 后来看到卖电源的地方都有那样的接头的(就跟arduino开发板那个9v电源一样的接头) 用线接上就可以了 正极vcc 负极接GND 咱们去新开的帖子讨论吧 这个太长。。。

  34. vvisper 说:

    ok 悬浮成功

  35. weihan 说:

    請問這PID的原理可應用在四軸飛行器上嗎??

  36. pizzabad 说:

    origin串口分析具体使用谁会,各位推荐个靠谱的教程也行。
    做磁悬浮分析分析,东西都买齐了,连板子选的都是和oldboy一样的,做电机实验L208一不小心烧坏了,现在在路上,你要为我负责啊!!我可被你骗上道了。。

  37. nicekwell 说:

    关于积分调节,我的理解是这样的:
    还拿小球在光滑坡面上为例,你认为积分项修正在坡面运动时才需要用到,而我觉得是这样的:
    物理平衡位置是x=L,如果我现在就像让小球平衡在x=L处。首先,微分调节我们是没有争议的;比例调节这里也没有争议,如果x>L则施加向左的力,如果x<L则施加向右的力,x=L则仅仅根据当前速度进行调节(微分调节);积分调节貌似确实没用。
    但如果我想要的平衡位置不是x=L处,那么在静止平衡时显然也是有一个恒力作用在小球上的,这个力不是比例调节带来的(Δx=0),也不是微分调节带来的(v=0),这是一个恒定的偏移量,如果平衡位置是x=L则这个偏移量恰好是0。我感觉这个偏移量是由积分调节积累出来的。
    我看你在程序代码中也没有用到积分调节,那么当你想让悬浮物悬浮在非物理平衡位置时,实际平衡位置应该更远离物理平衡位置。因为当物体恰好处于设定的平衡位置时,比例调节为0,如果速度也为0的话线圈就不工作,而此时又不是在物理平衡位置,所以物体要在更远离物理平衡位置处达到平衡。
    这是我对积分调节的理解,所谓消除静差(稳态误差)应该指的就是控制量的恒定的偏差吧?
    在大神面前说话要小心啊,要是不小心错了也不要笑我啊~嘻嘻

  38. homeboy 说:

    你好,我想问问代码中:
    int power1Pin = 5; //连接电机驱动板的EA接口
    int power2Pin = 6; //连接电机驱动板的EB接口
    int rotatePin = 3; //用来控制磁场旋转的PMW接口
    在原理图当中EA和EB不是接了+5V了吗?另外PWM口又是哪个呢?

  39. rotate是本来设想的一种方案,让磁场旋转来诱导浮子旋转,后来发现没有效果,这段代码是无效的

  40. 可乐 说:

    你好,我的硬件都做好了,开始调试PID参数。打算从Kp开始调起,Kd为0。我用手放松地拿着磁浮放在正中间感受,请问当Kp接近合适的范围是磁浮应该是什么样地表现?
    我从0.1开始试,刚开始的时候磁浮要很靠近电磁铁才会感受到斥力。我就把Kp直接增加到8,磁浮在平衡位置就能感受到两边一定的拉扯力,并且手拿着磁浮开始被吸引的摇晃。然后我以0.1为增量一路加到20,磁铁在平衡位置能感受到比较强的力,但是随之Kp增大,我手拿着磁浮开始越来越大幅度地摇晃,并不像我想象中那样,当Kp接近合适值时磁铁会被控制在平衡位置并比较高频地震动。到目前为止,我的磁浮一放上去立马就飞。

    • 所以你现在只调节了 Kp 对吧?只有Kp的话,就会像你说的那样,左右的抖动,而且幅度会越来越大。这个是对的,你可以开始加上一些Kd,Kd偏小的时候表现就是震荡,Kd偏大的时候表现是无法稳定,从侧面滑走。
      震荡的时候就是接近成功了,加油!

      • 可乐 说:

        那请问调Kp的时候调到什么程度可以着手开始调Kd呢?目前为止我说的抖动都是在我轻轻拿着磁浮的时候才会发生,如果我只是把磁浮往平衡位置一放,磁浮只会一下就飞到边上去了,没有看到有任何先震动然后幅度增大失去平衡的过程。我比较困惑的是不知道现在Kp是太大了还是太小了。有可能是太小了控制不住磁浮一下飞出去,也有可能是太大了一下过激了飞出去了。请问动力哥当时在调试的时候是怎么确定Kp是过大了还是过小了?非常感谢

      • 可乐 说:

        成功了!原来是我为了调试写的几行serial.print严重拖慢了arduino的频率,删了以后直接就好了!不过感谢动力哥的文章和解答

        • 恭喜恭喜!
          9600波特率下,发一个字节好像正好是1ms,果然很慢啊
          以后就有经验了 :)

          另外,我有个请求,能否把你做的磁悬浮整理一下照片,发到创酷网上? http://www.chuangkoo.com
          这是我和几个朋友一起做的创客平台,希望许许多多和咱们一样的爱动手的人,有个交流分享的地方。
          我希望做成中国的instructables,同时也是硬科技范儿的果壳 :)

          • 流云 说:

            动力老男孩,您好!我最近也在尝试做磁悬浮,遇到了两个问题想跟大师您请教一下,谢谢了!
            1)两个方向的hall元件平衡的target值是不是一样的?设置为多少合适呢?
            2)要间隔多少时间进行一次PID调整呢?目前我设置的时间是大概5ms读取一次hall元件的值,然后根据当前的偏移方向进行PID调整,这个时间是否合适呢?您当时是多长时间调整一次呢?

          • 如果安装的垂直的话,target应该一样,但是一般手动装不了那么准,会有一点儿误差。至于霍尔值是多少,跟你的磁铁有关,每个人都不一样
            5ms测量一次够用的,每秒钟调节200次呢

          • 流云 说:

            老男孩,谢谢您及时回复,我目前将两个方向的hall元件输入到mcu的值通过电位器调整到2v左右,然后将target值就设置为2v,这样可以吗?接着去调Kp和Kd的参数。当kd为零时,调整kp,发现当值差不多是4的时候,刚放上浮子就会剧烈摆动,然后为了解决剧烈摆动的问题,我开始从0.1调整Kd,每次步进0.1,发现浮子会慢慢由剧烈摆动变为剧烈抖动,当调整到1.2时,基本上不会抖动了,但是浮子仍然会飞出去。我再加大kd的值,如果直接将其设置为30就会感觉到浮子在剧烈的抖动,然后就会飞出去。我想要知道kd设置到1.2时和30两种情况时,哪一种才是接近悬浮的感觉?再次表示感谢,谢谢!

          • 你试试kd用1.2,把Kp降一点儿,到3左右

          • 流云 说:

            老男孩,您好!现在已经可以悬浮2s左右,但是2s后,浮子就会抖动然后被拉飞到环形磁铁上,这种情况下,需要调整Kp还是Kd?另外我发现虽然能悬浮但是电流很大,如何降低电流呢?谢谢了!

          • 这种情况下,两个参数都需要微调。PID是个头疼的事情,最后还是需要费点儿劲尝试。
            听说有自动匹配PID的办法,但是我还不会。
            电流大的话,把上方的磁铁换大一点儿,也就是说浮子的重力主要由磁铁来承担,就可以减少耗电。
            最完美的状态应该是线圈可以支持双向电流(可以吸也可以排斥),浮子的平衡位置基本在磁铁和重力的平衡点,那样的话基本不费电

          • 流云 说:

            谢谢动力老男孩的指点,可不可以这样理解,电流比较大主要还是找的平衡点并不是最优的平衡点,如果保持浮子不变,我可以尝试去重新调整平衡目标值,尽量让电磁铁只是去平衡水平位置,而不承担在垂直方向对浮子产生的力,即在垂直方向只让永磁铁产生的力等于浮子的重力。

  41. 小生 说:

    用串口我可以把数据传到电脑,但是你那个分析的图片是怎么做的呢

  42. 东东东 说:

    图里面由黑色的点线和红色的点线得出什么结论?需要定的目标值?不太明白啊~
    还有串口输出的数据,你是自己一个一个写进去制图的吗,Origin软件已经下了~

  43. 默然 说:

    老男孩还在么,我有问题要请教你

发表评论

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