集中回复关于下推式磁悬浮的一些问题

wlreg 等同学在PID平衡算法问了好多问题,那个页面的评论太长,已经找不到组织了,所以重开一个页面回答一些问题。

Q1、看了攻略和上面的评论,整个装置通上电后通过电位器先将接运放的传感器的输出调节为2.5V,然后再放浮子上去。霍尔传感器感应的气势是浮子的磁通吗?然后通过传感器的输出变化反应浮子的倾斜程度?(错了请指正呀,感谢的说。)
今天在图书馆居然被我找到一本关于PID控制器的书,对照了一下上面的符号和程序上的符号,大概理解了一些之前不懂的变量的意义,但是程序上还是有地方不懂,希望老男孩筒子指导一下吧。

A:气势这个词用的相当诡异,可能是因为wlreg同学刚喝了藿香正气水吧 :)
首先,电位器把输出调节到2V附近而不是2.5V附近,印象中那个东东输出的电压上限是3.7V,从读数上看最大值到750左右,我大概取了个中间值,对应的读数是400左右。
传感器感应的是浮子的磁通量的“变化量”,因为传感器垂直安装在线圈的中心高度,所以线圈中通电时对传感器基本没影响。而底座大磁环是不动的,所以传感器的读数变化基本都是由于浮子引起的。请注意这里浮子不会倾斜,只会水平移动!通过读数变化就可以知道浮子移动的方向。

—————————————————————

Q2:一开始的端口设置里,int rotatePin=3,rotatePin这个变量貌似一直都没有用过吧(只在上面程序注释里看见出现过)……

A:介位童鞋,你算是说对了,这个变量没有用。那它为啥会出现在代码里呢?其实在我的博客的某个角落里,写过企图给线圈加上旋转磁场,最后没有成功。所以这是一段没有删除干净的代码……嘿嘿,这个角落实在太角落了,以至于我也没有找到,汗

—————————————————————

Q3:Kp是比例系数,Kd是微分系数,这个程序采用的是增进式PID?那么setKd,和setKp这些系数都是实验慢慢调试出来的吗?如果我做的有些部件(磁铁的大小之类的)的和老男孩筒子列表里的有出入,那么这些值都要自己找了?

A: 没错,这些值都要自己找,但是也并非没有经验可循,建议先记录一段log到电脑上,然后把power值和传感器读数列出来对比,就可以估算出这些值了。推荐一个叫Origin的画图软件,可以画出图表对比。据说用excel也可以 :)

—————————————————————

Q4: 程序第82行,if(debug) tick=0;
这里debug不是设定为false吗?后面也貌似没有看见有更改过这个值,那么这一句实质上是永远不会运行的吧?

A: 当你需要调试的时候,把它改为true然后重新烧入板子。debug模式下不是为了悬浮的,而是为了拧那个电位器。
这个说来话长了:那两个电位器的螺丝孔很小,我需要两只手配合才能拧它。这样就不方便用万用表读数,我那个乱七八糟的洞洞板已经焊不下新的线头用来测量。所以你看到下面的几句:
    Serial.println(adjustValue1);   
    Serial.println(adjustValue2);   
    Serial.println(readValue1);   
    Serial.println(readValue2);  

这几行代码把读数打印到屏幕上,这样我就可以两只手调电阻,抬头看读数鸟。
另外顺便加了几行代码,用来判断线圈通电的方向是不是正确。

—————————————————————

Q5:程序第87行,if(tick2>=2;
这个是右移两位的意思吗?就是相当于除以4了,这个的意义何在呢?

A:读4次然后求平均嘛

—————————————————————

Q7、程序144行,if(debug)下面的括起来的真的会运行吗?

A:这个问题其实在Q4解释过了

—————————————————————

Q8: 程序第162行,delay(32000)
32000这个其实不用纠结的吧?但是总觉得很特殊的样子,为什么是这个设置……

A: 在PWM的秘密的两篇文章里,提到了改变PWM频率后,delay(n)的周期会产生变化,这里32000大约是0.5秒左右。对于我们这种老眼昏花的同志,再快就看不清了。

—————————————————————

Q9:程序第131行,Pid1.target = min(755, min(adjustValue1 + offset, Pid1.target));
755这个值是什么样来的呢?不是很明白的样子……

A:参见Q1,这个755应该是我调节时曾经见过的最大值。

————————————————————–

Q10: 额,之前那个问题也问错了,程序的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
不是吗?

A: 这次真的满头大汗了,仔细看了一下,我好像确实是把kd和kp两个参数的含义搞错了。今天忙了一天,现在大脑还是一团浆糊,明天早上再看一眼确认。不过参数虽然含义弄错了,那些参数值是可用的,你把代码里所有的kd和kp互换一下吧 :)
另外,(int) 要放在最前面,是把结果取整用的。

——————————————————————————

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

A:你看这一段中间有一句:if(writeLog)。所以总体来说,tick1和tick2都是用来记录log用的,所以你不用太纠结于这段代码是什么意思。说实话我刚才看了一会儿也有点头昏眼花,恨不得把作者揪出来打一顿。仔细回想了一下,最早只有tick1,当循环500次以后,集中发送一次log(因为串口发数据很慢,会影响采样频率)。后来发现500次还不到1秒钟,这时候可能刚刚放上去还没平稳呢。所以加上了一个tick2,这个500次的循环执行50次以后,大概是30秒,这时候再发送最后的500个数据。
然后再看一下真正运行时的情况,这时候writeLog=false,这些代码基本都属于没有用的了,另外还有一些莫名其妙的tick2 = 0;  tick>500之类的,应该都是进化过程中的垃圾产物。

—————————————————————–

第一回遇到这么认真的读者。其实看代码重在领会精神,没必要理解每一行代码的作用。但是认真的同学也有认真的好处,钻研精神值得赞赏!尤其是那个kp和kd的参数,

其他页面的问题就回答到相应的留言下面了,那里评论没有那么长 :)



对 “集中回复关于下推式磁悬浮的一些问题” 的 123 条 评论

  1. wlreg 说:

    额,受宠若惊,谢谢老男孩筒子啊,谢谢,十分感谢啊

  2. wlreg 说:

    电路逐渐搭起来了,然后我这个天然呆突然发现一个重要的问题没有弄明白。就是程序上power值得确定和realValue和adjustValue的关系式的推倒。
    接下电位器1和电位器2的时候,我发现,这连个电位器实质上是并联的(好吧,这么久才发现我是在很惭愧)。电位器2是一端接5V,一端接地,抽头接开发板,抽头读出来的电压值在板内自动转化就是adjustValue了。所以电位器2是对L358N的输出是没有影响的,对L358N有影响的只有电位器1。
    另外,我发现程序的第144行到164行实质上是作废的吧,因为这段程序就算执行了,对flag,power等值做了输出,但是程序的第166行到第193行,对flag和power的值又重新写了一次,就是说,144行到164行的程序是没有作用的(额,但是检测adjustValue1,readValue1和adjustValue2,readValue2的值还是有用的)。
    然后我的问题来了哦,基于以上两点,adjustValue的影响仅仅是在程序的第123行到第142行的一下几句:
    ——————————————————-
    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));

    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));
    ———————————————————-
    (上面Pid1.target和Pid2.target的公式,第一个除以100和第二个除以1000实质不用在意吧,影响应该不大吧?)
    也就是说adjustValue只是对陀螺刚开始得平衡有帮助吧,而且它的值调节不对的话,可以说反而影响平衡了。

    • 天然呆同学你好 :)

      第144行到164行实质上是作废的吧?
      ———
      这里不是赫然写了if(debug)吗?这段不是用来调节平衡的

      除以100和除以1000应该是我写错了,本意是都除以1000。不过无所谓啦,它的作用是多次采样取近似平均值。设想一种情况,target最初是200,但是运转一段时间后,由于温度升高,它变成了110,这种情况就需要多次平均。

      但是对于陀螺刚放上去的情况,这个target值短期内跳动非常大,所以需要把它强行设置在adjustValue的附近,因为我们认为这个范围内的target才是合理的。

      最后补充一下这个电路的逻辑原理:
      —————————
      1,假设我们已经实现了目标,陀螺被控制在了平衡点,这时候传感器输出到单片机的电压是readValue;
      2,假如我们已经知道这个平衡位置的输入电压是2.5V,对应读数为512,那么我们的程序目标就是把readValue控制到512;(计算power的部分)
      3,问题来了,事实上我们并不知道平衡位置时是512,也许是400,也许是600,总不能每次都改程序实验吧。所以这时候需要adjustValue。把这个电位器拧一圈,你会发现陀螺的受力明显发生变化,在某个位置时会悬浮的很好,这时候我们就找到了想要的那个平衡点。
      4,现在平衡点找到了,比如我们拧到adjustValue=345的时候平衡的很好,可是运行一段时间后,由于受热之类的原因,平衡点移动到360了,这时候会发现readValue的平均值明显偏向一边,振动越来越大,所以这时候需要给他加上一个offset用作调整用
      5,一般来说,温度对平衡点的影响不会很大,所以offset的范围比较小,如果在程序执行时发现target的值和adjustValue差别非常大,那么可能是由于其他原因,例如陀螺刚放上去的时候,值跳动的非常大,这种情况下应该用一个offset的范围把它消除掉。

      • wlreg 说:

        第144到164行是检测端口用的我懂,只是里面还有写i1Pin,i2Pin,power1Pin,i3Pin,i4Pin和power2Pin我就不懂了,因为这段不属于PID算法呀,而且166行开始的PID算法会把上面写的值都覆盖掉的。所以觉得144到164行只有前面四句Serial.println语句有用咯。

        • wlreg 说:

          啊咧,不对。看到下面那句return我突然又想到了。
          144行到164行的if(debug)是为了找到那个平衡点的adjustValue用的,所以这段只是在实验开头用到是吧。找到了这个合适的adjuestValue,这段就可以作废了,是这样吧。所以程序82行才会有
          ————————
          if(debug)tick=0;
          ————————
          这段我一直觉得很奇怪得东西,原来是这样对吧,我们一开始就应该找到这个合适的adjustValue,所以一开始程序是什么也不做的,就是专门在调adjustValue的。找到之后,debug应该设为零,程序才会执行其他的段。一定是这样吧。

        • 你理解了PID算法以后,就可以自己写代码了,我的代码因为在制作过程中走了弯路,或者想了一些其他问题,所以可能有些多余的部分,不用太纠结于细节上 :)

          • wlreg 说:

            嘿嘿,是想改成增量式的PID算法。不过这样参数方面就麻烦了,一个个试的话要试到牛年马月呀。借回来那本PID控制器的书上虽然有参数的一些计算方法,不过发现完全超出了我现在的能力,完全不知道怎样用得上。

          • 没那么麻烦,呵呵,先大步试,差不多了小步走 :)

  3. vvisper 说:

    那个20v 3.25A电源我往298上一接 线圈就会开始发热 不一会就会变得很烫 这个 让我感觉很诡异啊 不应该是这样的啊

  4. vvisper 说:

    我刚才量了一下 在给298接20v外接电源后 我的线圈上就一直有20v左右的电压 。。拧变阻器 电压会变化 但是浮子对电压变化的影像却很小 我外接电源的正极是接vcc 负极就直接跟其他原件共地了 难道不应该这样接吗

  5. wlreg 说:

    悲摧了呀。连续两天晚上都在测试陀螺,但是一开始还没有成功呀,电路重复整了两遍,累死了。
    800匝0.27的线圈,一个电阻都应该有70欧了吧。可是我把对着的两个线圈接起来,一头一尾测它们的电阻,才30欧左右…这样电流应该会很大才对吧,磁场应该会很大才对吧?但是用强磁靠在上面发现四个线圈的磁场都很弱的样子呀,不能保持悬浮呀。
    一开始通过debug调节电位器的时候就已经可以调到将陀螺悬浮起来了吗?还是要调节到什么程度才对呢?

    • 差不多,我的两个线圈是40欧,想起一个问题,你安装了下面的环形大磁铁了吗?
      线圈产生的磁场确实不大,不是靠它来浮起陀螺,而是靠它来平衡。

      debug调节电位器的时候,只是为了调解inputValue到合适的范围,不能调到悬浮。至于调到什么程序,这个需要看你现在的情况,你目前是剧烈振动呢,还是根本就跟没线圈一样?

      一个明显的征兆是,你左右晃动陀螺的时候,会感受到两个方向都有很大的阻力。

      另外,你最好检查一下线圈的情况:
      1,通电时线圈内是否有电流?
      2,每一对线圈是否磁场方向相反?也就是说一个吸的时候另一个必须是拉,电流旋向必须相反。
      3,线圈接线方向是否正确,正确的接线,当陀螺偏向一边的时候,磁力是把它推回去的;如果接反了,反而越推越远。

  6. wlreg 说:

    今天发现,将那个L298N上那个叫做逻辑部分供电模式选择端得按钮按下去(详细位置参考淘宝上L298N电机驱动板,店在江苏镇江那个,应该一搜就在首位的,为了避免发广告的嫌疑,我就不贴网址了),就会输出很大的电压,可以上到接近20V呀,于是线圈产生了十分明显的磁场,于是,于是和下面的环形磁铁发生反应了,线圈会移位呀,移位,之前都没有想到这个问题呀(我的线圈的位置是没有固定下来的,想着会不会要调节一下位置……)
    但是如果不把那个叫逻辑部分供电模式选择端按下去的话,输出电压很微弱呀,基本上感觉不到线圈产生了磁场。但是按那个下去以后,L298N的芯片会很快变烫,十分让人担心的感觉,想知道老男孩筒子在用的时候有没有把那个按钮按下去呢。貌似按了那个按钮下去后,L298N上的几个灯就会着了,会提示电压的方向的。

  7. wlreg 说:

    而且感觉353输出的值没有多大的变化呀,虽然霍尔传感器的灵敏度大吗?记得接5V进去没有磁场的时候测出来的确是2.5V的,但是强磁靠近的时候反而变成2.3V左右了,不知道我的霍尔传感器是不是有问题呀,呀

  8. wlreg 说:

    想确认一下,电位器2只是纯粹地一端接5V,一端接地,抽头接到开发板上的吧。在debug里调节两个电位器2是不会对353的输出有影响的吧?感觉电路图没有接错,但是353输出的霍尔传感器的放大值基本没有变化

    • vvisper 说:

      动力哥用的是2k 和100k的两个电阻 我也是 也就是说理论上放大了50倍 你要放大的是哪个微小的波动 所以说电位器的电压要调到高于传感器输出端的 不放浮子的时候358输出 调到2v左右 你在放上浮子 移动 就会有明显变化了

  9. wlreg 说:

    发现调节电位器1的话,353输出不是900多就是10多,实现不了0到900之间的微调呀。
    然后我用我微小的电路和运放知识,看了一下电路图(diagram那个),发现,如果电位器1(是对应图上的VR1或者VR2吧?)这样连接的话,353的输出只能实现输出0或者输出5呀(应该是的吧),电位器1的抽头接到运放的正向端的话,只能实现比较电位的调节吧,这样当负向端的输入电压大于正向端的输入电压的时候就输出5V,负向端的输入电压小于正向输入电压的时候就输出0V。怎么实现353输出的微调呀(0——5V之间电压),所以我觉得原电路应该要修改的,将正向端接地,可调电阻跨接到输出和负向端之间才对。
    老男孩筒子做的时候可以实现微调吗?

    • 353是跟LM358N类似的放大芯片吧?
      如果是的话,肯定是可以微调的。它不是比较器,是放大器嘛
      我调节电位器1的时候,可以明显看到输出慢慢的从0变到3.75V左右

      • wlreg 说:

        额,搞错了是358N……。
        用来做浮子的圆形磁铁的磁场是怎样分布的呢。卖传感器给我的老板在演示的时候,只将圆形磁铁的圆形面逐渐靠近传感器的平面的时候传感器的示数是用很大的变化。但是我们的浮子的圆形面是浮在传感器上方的呀,这样的传感器检测的磁场变化貌似很少吧

      • vvisper 说:

        同问 虽然我那个成功了了 但是我也觉得这个传感器工作原理 有点怪 我觉得如果是Levitron的话 陀螺就需要一定的角速度 它的重量每0.3g的变化就会影像悬浮 而咱们现在做的这个 似乎对陀螺重量要求不是很严格 我感觉他倒下去的时候是侧向翻到的所以会产生磁场变化 但是这个磁场和环形磁铁以及电磁铁作用后 肯定变得很复杂呀 传感器感应到的 到底是什么样的磁场呢

  10. wlreg 说:

    电路搭好已经5天了,5天里几乎每天晚上都在弄这个,但是还是没有什么进展,真是囧死了。
    我还在DEBUG那段调试里停滞不前呀。我知道target这个值是平衡位置时候的传感器的读数(经过358),而传感器有这个读数的时候浮子是特定在一个点上才有可能的,那么这个平衡位置其实就是一个点了。
    由于霍尔传感器是靠近一个面是示数增加,靠近另外一个面是示数减少,所以浮子的平衡位置,甚至是活动范围只能在两个霍尔传感器所形成的直角所包围的范围内。(以上分析都没有错吧?)
    那么DEBUG那段,调节adjustValue的值究竟是为了找到这个平衡位置,但是我怎么知道我调到的是平衡位置呢?因为就算我调到了平衡位置的值,但那也只是反应在adjustValue上啊,其实浮子可能并不在这个读数所应该在的那个点上。所以我DEBUG究竟要有一个什么现象才算是完成了呢?

    • debug的目标只是让readValue和adjustValue接近而已,不会有什么现象。用几分钟就可以调完,这时候是不能悬浮的,需要把debug去掉,然后继续调pid参数。

    • 另外,印象中你的霍尔传感器有问题,这个排除了
      吗?至少陀螺移动时,你应该要看到读数连续变化

      • wlreg 说:

        嗯排除了,换了新的霍尔传感器

      • wlreg 说:

        另外平衡位置的位置只能是在霍尔传感器形成的直角所包围的范围内这点没有错吧,因为如果不以一个面为基准的话,对应同一个平衡位置时的读数,平衡位置可能有两个了。

        • 这里你又理解错啦,当陀螺从传感器上方路过的时候,传感器读数是连续变化的。
          例如陀螺在正上方时读数是3,那么在左边可能是4,在右边是2,并不存在你说的两个平衡位置(不是对称的)

  11. wlreg 说:

    调参数要怎样根据数据分析呢?看老男孩筒子PID算法上的那个点图,不知道具体是要分析哪些数据(X上是读数的话,那么Y轴上的是什么),要出现怎样的图才算是接近呢。我打算用MATLAB作图,应该会比较准确

    • 这个只能估算,你先随便设置几个pid的参数,然后把数据打印出来。
      就可以看出你的调节量是大了还是小了,然后继续改。
      其实你需要调节的只有两个参数,其中先调那个线性的参数,调到合适的时候,可以看到的现象是:虽然不能悬浮,但是会剧烈震荡
      然后调那个微分的参数,减小震荡就可以悬浮了。

      • wlreg 说:

        也就是说DEBUG那段可以跳过是吗?其实adjustValue的值可以在实现平衡之后再设定吧?不用DEBUG那段也是可以实现平衡的,DEBUG那段调试只是为了让初期平衡得更好一点?

        • 嗯?我好像已经说过了,debug那段只是为了让你调readValue1和readValue2到一个合适的范围,你看到读数到300~400之间都可以 :)
          除此之外没有别的作用。

  12. wlreg 说:

    突然想起,我有一个线圈由于漆包线不够所以只绕了600多匝,其他都是800匝…这样不对称性也可以悬浮起来的吧?不过可能两组的Kp,Kd参数会不同?

    • 这个不对称有点多,但是应该是可以悬浮的,你说的没错,两组kp,kd会稍有差别。
      但是这不是主要因素,因为kp,kd在一个比较大的范围内都是可行的,有偏差的时候,可能是振动大一点,也可能浮一会儿就失控。你应该至少做到用手抓着陀螺轻微移动的时候,能感觉到四面的阻力

  13. wlreg 说:

    今天发现有一个霍尔传感器又坏了(真是娇气呀),明天再去买一个新的霍尔传感器,于是今天想研究一下数据分析。
    我将debug改成false,然后将回显的7组一共3500个数据用EXCEL画了图出来(在我的围脖上发布了,老男孩筒子可以去看看指导一下吗,点我的名字应该就可以链接到)。最后是要把Pid1.target和Pid2.target的值很成一条直线这样的输出的时候就是成功了吗?还是说其他另外5组数据也要有特征呢?

    • 在微博上给你回复了:)

      • wlreg 说:

        那张图是没有放浮子上去的时候的数据诶。诶,还是做不出来,要崩溃了

        • 那就需要重新分析了。首先没有放陀螺的时候,readValue1和readValue2应该都接近是直线。
          你的readValue1变动很大,应该是安装的位置不好,要么是不垂直,要么就是高度上没居中。
          而readValue2虽然是直线,但是很低,这个应该是没有电位器没有调好,你应该在debug模式下把它调到300左右
          另外我注意到你的p2.target变动很大,这个估计是你的电位器出问题了吧,它应该也是直线的

  14. wlreg 说:

    我想问一下,调试KP和KD的时候浮子是怎么操作啊?是一动不动地拿在传感器上方吗?

  15. wlreg 说:

    还是不行,想放弃了。即使PID的参数不对,也是可以感受到存在平衡位置的吧?但是我除了感觉到环形磁铁吸引它往外跑得里外,基本上没有你们说的那种,存在一个偏离的时候会感觉到有力往回拉的平衡位置的感觉

  16. wlreg 说:

    还是弄不出来…即使不调节PID参数也是应该可以感觉到那个所谓的浮子偏离时会收到往回拉的平衡位置吧?但是我一直没有感受到,只感受到下面大磁铁对浮子向外吸的力。

  17. wlreg 说:

    今天成功悬浮了10秒左右了。然后,老男孩筒子,我想说你的PID公式KP和KD确实是反了。今天按你那条公式,我把KP和KD设置成4和30,是有在震动的,但是不能悬浮。后来我发狠心,把公式里的KP和KD位置换了,然后,就悬浮啦,虽然之后10秒中就跑飞了………………之后就是调节参数的问题了吧?

  18. wlreg 说:

    成功悬浮10秒钟…

  19. wlreg 说:

    成功稳定悬浮

  20. wlreg 说:

    昨天就已经实现稳定磁悬浮了。不知道为什么老男孩筒子的博客最近貌似电脑发表评论的话都发不成功

  21. wlreg 说:

    昨天就成功稳定悬浮了。话说,老男孩筒子的博客现在怎么用电脑评论不能呀?【本人受姬中

  22. wlreg 说:

    这样的呀。这个磁悬浮弄好后我在想,现在能悬浮的平衡位置基本上是一个点,位于两个传感器所成的直角上。如果我改用四个霍尔传感器对应四个线圈,甚至三个霍尔传感器对应控制三个线圈来分别单独控制磁场大小,这样平衡位置会不会扩大呢?老男孩筒子由你对霍尔传感器的了解,觉得这样是否可行?

    • 不可行,这个平衡位置事实上不是由霍尔传感器决定的,而是由磁场状态决定的。
      还记得我解释PID的时候举的例子吗?
      把一个小球放在一个拱形斜坡的顶端,这是一个典型的不平衡的例子,虽然坡顶的合力是0,但是任何微小的扰动,都会使他失去平衡。
      对于陀螺来说,平衡位置就是这个坡顶,我们只是把传感器安装在正下方而已。

      注意在咱们这里例子里,线圈产生的力相对于磁铁的力来说是很小的,也就是说这个坡很陡,一旦偏离太多,线圈就算开足马力也无法保持平衡

  23. wlreg 说:

    难道就不可以将坡顶削成平顶吗?

  24. 不能,这个就是恩绍定理论证的,只能有坡度大小区别,不会有平顶。再说了,不管坡度多少,这个是由磁铁分布决定,跟传感器无关

  25. wlreg 说:

    老男孩筒子我需要整理一下我的经验发表一下,这样以后看到你博客的童鞋也可以做得容易一点,你也不用经常回复这方面的问题了哦

  26. vvisper 说:

    再次请教博主,当时你是怎么确定环形磁铁的大小的,环的外径,内径,以及电磁线圈的外径内径,线圈匝数(匝数当然是越多越好),还有就是浮子的大小和直径的,因为在静磁悬浮中,陀螺质量对悬浮成功有很大影响,不能大也不能小,当时是如何估算这些值的呢。

    • 你说的静磁悬浮,应该是那个不用电的玩具陀螺吧。
      事实上,对于有电动调节的系统来说,对陀螺和磁铁的要求很低,你看很多成功的悬浮,各种大小的环形磁铁都有,也有用一圈小磁铁代替的。
      陀螺也是千奇百怪,无非就是想把高度弄高点,显得好看。
      磁场大了,线圈里的电流也就相应大点,没有那么严格,也不太需要估算 :)

  27. robot360 说:

    嗯,不错,学习了。

  28. 老薛 说:

    动力哥,我的磁悬浮也搞成了(发到了博客上)!
    在此谨向革命先行者致敬!

  29. 老薛 说:

    动力哥,我的光传感乐高segay也搞成了。发在了博客。

  30. 老薛 说:

    动力哥,你知道怎么把Arduino的数据写到一个txt的文件里吗?因为Serial.print这个函数只能把数据显示在屏幕上,还要另外拷贝到一个txt文件里,不太方便。能不能软件直接把这些数据写到一个文件里,存在PC上?好像没有这样的函数?

    我查了一些相关的讨论,好像只有讲怎么把数据存到一个SD卡之类的。

  31. 老薛 说:

    多谢动力哥!

  32. wlreg 说:

    诶,之前说暑假的时候总结一下做这个磁悬浮的一些要点,但是后来回到家没有网就忘记了。。。现在说一下一个要点吧:
    其实我们开始做的时候,理解错了“一推一吸才给力”的意思。当时我们以为是通电的时候强磁放在一边线圈上感觉的是斥力,那么放在另一边的线圈上感觉应该是吸力。。。当时真是脑抽啊,不过也怀疑过线圈的方向问题,所以也摆过通电时,强磁分别放在线圈上方都是斥力的情况,不过当时程序用的是老男孩筒子的参数,可能和我们的实际情况有点出入,当时我们有几个人都将强磁放上去过,但是都感觉不了有要浮起来的感觉。所以弄了好久都没有弄出来,后来多得最后一名成员,靠他灵敏的手感,将强磁放对了一个点,强磁浮了大概3秒,我们才确信我们之前的理解错了。。。。。(真是脑抽啊,简单的逻辑没有弄懂)。
    所以弄这个磁悬浮的要点是,通电时,将浮子分别放在线圈上面的时候都要感觉到时斥力才是正确的。

    • 多谢总结分享 :)

      • wlreg 说:

        在分享一下一些东西。可能有同学会对target值的计算感到困惑,算法里为什么target值可以计算出来呢。
        其实这个target值在某些程度上其实是一个输入值。程序一定能够计算出浮子平衡时的target值吗?我觉得其实不是的。做出来的时候我们就知道,浮子必须放在一个特定的点上才能够稳定地浮起来,如果偏离那个点一点,浮子几乎是不可能悬浮起来的。所以当将浮子刚好放在能使其刚好悬浮起来的位置,这就是我们要的target值,而此时这个值读取了,然后就是对浮子悬浮期间相对于悬浮位置的偏移作出相应的控制使其能够稳定悬浮。所以说并不是多次读传感器的读数然后求个平均值就能够求得悬浮的target值,但target值是客观存在,但target值程序并不能计算出来,而可以认为是人为输入。

  33. 在天愿做747 说:

    您好,我有一个问题。
    3503检测的磁场变化主要是由于浮子位置移动而产生的还是线圈电流变化产生的?
    是不是浮子位置移动了,3503检测到浮子位置移动产生的磁场变化,然后通过算法去控制线圈的电流大小,使得线圈产生的磁场变化从而使浮子回归原位,完成对浮子位置的控制?

  34. djb 说:

    能否将环形永磁铁改成小几号的,然后将四个线圈组成的电磁铁放在外面,而传感器位置不变,这样从理论上好像是可以的,实际上操作可行吗

  35. 刘佳俊 说:

    动力哥,请问霍尔传感器有集成了运放的吗?某宝都没有写,傻傻的分不清楚了~但我看别的论坛有人说有种霍尔是集成运放的,求帮鉴定。
    BTW:求问电源怎么弄,某宝上有现成的不?

    • 我的霍尔没有集成运放,所以需要自己加放大电路。
      电源是用了一个旧笔记本的电源,其实电压20V左右,电流2A左右都可以。
      因为平稳之后电流并不大,要这么大的电流就是放上去的瞬间电流比较大

  36. hl 说:

    非常感谢老男孩的攻略,我也分享一下我自己的心得吧,希望可以帮到更多道友。
    一、硬件方面
    (1)线圈方面。两个线圈的同名端相接,构成一对线圈。另一对也一样。PS:你也可以在安装好了线圈,不加底座磁铁,运行程序,把浮子极端的放在各个线圈上,应该都是感到相同的力,来判断你是否线圈连接正确。
    (2)传感器方面。要线性的霍尔。安放位置在每对线圈的中轴线上(这个比较重要),高度大约在线圈的中间。
    (3)接线方面:一对线圈接L298的OUT1,OUT2,另一对接L298n的OUT3,OUT4。刚开始这个不是很严格,你只要一对线圈接一组输出就可以。但是如果你成功后,你就要记住你哪对线圈接OUT1,2;哪对线圈接OUT3,4;一对线圈中哪根线接了OUT1,哪根线接了OUT2。不然你拆了下来,在接上去和上次的接法不同,那你就悲剧了,要在调了。
    二、程序方面
    主要分为几个模块。
    (1)管脚设置。
    (2)PID构建:24~36行,位置式
    (3)LOG模块:89~112行,用于记录LOG数据分析
    (4)电位器和传感器。
    (5)DEBUG模式:144~164行,用于调节传感器和电位器读数。
    (6)PID和POWER计算:166~193

  37. 王明 说:

    问一下,这个东西的输入电压可不可以是5v的而不是20v的

  38. 康凯 说:

    你好,我想按照你的教程做一个出来,并且想把它做成一个小车,请问你做出来大概规格是多少呀。

    • 个头有点大,磁铁直径20多cm,盒子大概40cm宽

      • 康凯 说:

        哈哈哈哈,动力哥居然还在回复我们 真是感谢
        我现在在整定参数 感觉有些迷茫内
        第一个是 浮子稍微偏一丢丢就会感觉到下面环形磁铁的强大磁力,,线圈根本拉不住,即使是255满输入也还是拉不住 但是我看动力哥的视频 即使你用手移动了浮子 浮子仍然会回归原位 感觉好厉害 是你适当抬高了线圈与大磁铁之间的距离吗
        第二点是,调到某个参数的时候 浮子振荡得比较快 迷之抖动 按照PID参数的口诀就是要调大比例度盘,调小微分时间,也就是说kp kd都要增大是吗

  39. hanhanmumuqq 说:

    动力哥,测试时我发现了一个小问题
    arduino 328p的动态内存只有2048byte,但是你的数组myLog有3500个
    初始化的时候没问题,但是loop中一旦开始填充数据时就会溢出死机
    所以应该改小一点
    另外前面的反正是废数据,也没必要存

  40. hanhanmumuqq 说:

    请问一下磁铁移动时lm358的输出情况是不是应该先变小后变大(或先大后小)?为什么我的只有3.8v和0v?

  41. zero 说:

    请问target 的值 是放上浮子后的值 还是未放上浮子的值….

  42. df 说:

    动力哥,您好,请问为什么我的arduino和l298n共地后为什么out口的电压为0,传感器和电位器变化不大,可以用电位器调节传感器,不共地则有电压,但是传感器和电位器读数无规则变化很大。还有外面那一圈小强磁是靠正对的斥力还是靠大圈中心的斥力浮起浮子的?把传感器的读数调到300到400后怎么调pid?麻烦动力哥指点一下

    • 任何电路只要有对比的都必须共地,输出电压为0是代码的原因,建议先做分解实验,能够用Arduino直接控制输出电压以后再考虑磁悬浮。
      传感器经过放大器以后是很灵敏的,磁铁晃过去之后读数明显有变化,如果没有的话,依然是建议先把读传感器的功能做好。
      斥力是靠大圈中心推的,调PID没有好办法,改大改小多试试

  43. df 说:

    动力哥,我看代码一知半解的,我其他的电机测试代码试有电压输出,而且传感器这些也调到了350左右,用传感器测试控制pwm也没问题。你的代码除了pid和测量传感器和电位器读数时把debug改true外还要改哪里么?

    • 这些代码已经七八年了,我其实也记不太清了 :)
      因为IDE升级,现在直接拷出来也许还会报错。不要太纠结细节,大概看看原理,自己重写一遍会好一点儿

  44. df 说:

    动力哥,我把源代码发到你邮箱里面了,希望动力哥帮我看看。

  45. 康凯 说:

    线圈

  46. push 说:

    动力哥,我做的线圈感觉磁力很小,供电电压调到20V了都,这个怎么调啊?L298的pwm占空比70%周期是10ms感觉手拿着浮子有震动,而且都能听到响声,怎么调啊?动力哥

  47. push 说:

    动力哥,霍尔传感器的值总是有波动,转换完之后大概有5Gs的,这个有影响吗?需要滤波吗?如果需要怎么滤波?谢谢动力哥

  48. 小陀螺 说:

    老男孩,时隔多年后被你的制作吸引,不知还在关注这里不,我也想动手做点有意思的,过程中的问题还请多多指教

发表评论

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