Posts Tagged ‘磁悬浮’

石墨静态磁悬浮的探索 – 虽然没成功

之前介绍过有人用钕铁硼+铅笔芯可以实现静态的磁悬浮,因为石墨具有抗磁性。当时简单试了下没有成功,后来就没有再深究了,内心深处对这个实验一直持怀疑态度。直到前几天有一位叫做老薛的小朋友动手实验成功,有兴趣的同学可以去翻翻他的博客

这下老男孩坐不住了,老薛同学说了几点可能的原因:
1,把圆片形状的磁铁换为方块的,没有间隙可能漏磁较少;
2,磁铁不一定要大,小块的磁铁可能梯度更大
3,铅笔芯石墨含量越高越好

于是迅速淘了一小堆正方体小磁铁,兴致勃勃的准备见证奇迹,结果再次被打击了:
没有成功的静态磁悬浮

事实上,那根该死的铅笔芯不但没有浮起来,貌似还吸在了磁铁上。我把磁铁片翻过来,它居然还得意洋洋的挂在下面!

相比之下,老薛同学的实验照片如下:
老薛同学的结果

伤心之余,我查了下资料,在阿莫的论坛上找到了疑似答案。主要是国内的铅笔芯都是采用的石墨+粘土配方,而大部分粘土里都是含铁的。需要说明的是抗磁性一般都比磁性弱很多,所以不但不能悬浮,还会被吸住。
没办法,咱也不能因为这个就投诉国货,毕竟铅笔芯不是设计来玩悬浮的。

为啥老薛同学的笔芯可以呢?哈哈,因为他是在英国啊。说到这里,不得不对他们的实验室表示一下由衷的羡慕妒忌恨。他的导师居然和他一起玩磁悬浮,之前还在实验室里玩遥控飞机。唉,国内的导师们,已经被各种论文和指标压的喘不过气,你要是在实验室玩这个,非得被扔到楼下去不可 :D

下面是网上找来的图,可以看出磁铁大小和形状并不是关键原因,主要还是笔芯的问题:

最后,转一个国外某蛋疼到极致,同样也是敬业到极致的某同学的总结,试验了各个国家不同粗细和标号的铅笔芯的悬浮情况:
第一栏是笔芯粗细,国内一般只有0.5和0.7两种;第二栏是HB标号,B越大的越软,石墨含量越高(这次我还试了6B的铅笔芯,用小刀刮成片状,依然不成功);yes和no不解释;第四栏是产地。

其中来自德国的施德楼(Staedtler)铅笔标记了Very Good,这个牌子我一直很喜欢,可惜家里的都是圆珠笔。

Pentel Super Polymer,
0.35  HB YES Japan
0.35 B&2B YES Japan
0.5 B&2B YES Japan
0.5 HB YES Japan
0.5     F YES Japan
0.7  HB (1 box YES, 3 boxes NO) Japan
0.7 B YES Japan
0.9  2B YES 15/$1 at McGuckin, 2524 Arapahoe Ave., Boulder, CO
0.9 HB NO Japan
0.9 B NO Japan
Faber-Castell (1.4 B labeled Brazil)
http//www.faber-castell.de/
0.35   ? Germany
0.5 Super Polymer ? Germany
0.7  2B YES Germany
0.7   ? Germany
0.9   ? Germany
1.4  B,Super Polymer leads for their “E Motion Pencils” YES (very good) 6/$2.88 at Meninger 499 Broadway, Den, CO
2.0 B & 2B NO Germany
Staedtler (Marsmicro Polycarbon) Germany
http://www.staedtler.com
0.5   ? Germany
0.7   ? Germany
0.9 B & 2B YES (very good) No longer made.
0.9 HB YES (less than 2B & B) No longer made.
2.0 B & 2B NO Germany
Derwent
7.0 8B NO  
Stanford
0.5 HB YES Japan
0.9 HB (Sphere TM) NO Korea
Pilot (NEO-X)
0.7 HB YES Japan
MonAmi
0.7 HB NO Korea
School Time      
0.5 HB NO China
       

 

 

盗梦陀螺攻略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);
}

盗梦陀螺攻略4- 下推式磁悬浮电路

距上一篇攻略已经过了快一个月了。这个月生病一次,加班数次,其中还有带病加班的几天,过年前的日子真难过啊 :) 不过今年春节有10天假,强烈期待中。另外后天公司开年会,希望能抽个大奖,哈哈!

下面继续发磁悬浮的攻略。下推式其实原理和上拉式很相似,区别在于需要两组线圈才能维持浮子的平衡。下面是其中一组线圈的电路示意图:

下推式电路示意图

下推式电路示意图,点击看大图

这个电路和之前上拉式的完全一样,所以这次不需要额外的焊接工作,对比上篇博客的电路图,只是多了一些杜邦头的插针,便于连线:

上推式磁悬浮连线实物图

上推式磁悬浮连线实物图

之前制作小爱的时候,试验过Arduino的模拟输入输出数字输入输出,这里再简单复习下。

Android Mega一共有四种IO接口:模拟输入输出和数字输入输出。其中模拟输入标记为“ANALOG IN”,可以测量0~5V的电压,对应在代码中的读数范围是0~1023,示例代码如下:

int readValue1 = analogRead(read1Pin);

模拟输出实际上输出的是一串方波,通过高低电压的占空比来产生“平均电压”。在板上对应的标记是PWM,输出电压同样是0~5V,但是请注意设置的数值范围却是0~255。示例代码如下:

analogWrite(power1Pin, Pid1.power);

数字输入输出需要先设置管脚的模式,直接看示例代码吧,相信聪明的你肯定明白:

pinMode(Pin1, OUTPUT);     //设置为输出管脚
pinMode(Pin2, INPUT);      //设置为输入管脚
digitalWrite(Pin1, HIGH);  //输出高电压
int v = digitalRead(Pin2); //读取Pin2的电压,返回结果是0或1
anduino控制板

anduino控制板

其中0~53所有的接口都可以作为数字输入输出接口,而其中只有2~13可以用作PWM模拟输出。模拟输入的接口编号是0~15,和刚才的编号是互相独立的,不会冲突。对于盗梦陀螺来说,传感器和电位器的读数显然要用模拟输入,而线圈电流的控制也显然要用模拟输出。强烈建议把接线的编号集中写在程序的最前面,这样可以一目了然的看出是怎么接的线:

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接口

细心的朋友一定看到上面代码中,有I1到I4四个接口,我将会把它们设置成数字输出。这里再顺便介绍下L298N的用法。
L298N直接连接了20V的电源,通过板内取电的方式提供5V电压给电路使用。板上包含了对称的两组电流驱动电路,以I1,I2,EA为例:

I1=0;I2=1;  //输出正电压,EA范围0~255时,输出电压对应为0~+20V
I1=1;I2=0;  //输出负电压,EA范围0~255时,输出电压对应为0~-20V
I1=0;I2=0;  //输出电压均为0
I1=1;I2=1;  //输出电压均为0

我们可以用数字输出I1和I2控制线圈的电压方向,用模拟输出EA控制电压的大小。I3,I4和EB是完全一样的,这里就不多说啦。友情提醒一下,Arduino的地线,L298N的地线,还有焊接电路的地线,这些地线一定要都连在一起。

到这里电路硬件的部分就介绍完了,实际上,按照这个方式做好的版本是非常不稳定的。看下面的视频,就是最初的不稳定版本,可以看出振动的非常厉害:

后面会继续介绍如何让悬浮更稳定,主要是引入PID控制的概念,另外还需要提高Arduino的PWM方波频率。

不要再上当了

昨天又收到一封邮件,声称不用电的磁悬浮是可行的,并给我发了一张照片作为证据,希望我研究研究。没看附件的时候,我还在猜想是不是什么反磁性物质或者超导体,结果是这么一个简单的“设计”:

所谓的静态磁悬浮

我承认其实我也没有研究过恩绍大定理的具体内容,但是我相信数学家。至少我相信一点:如果静态磁悬浮这么好实现,恩绍同学一定早被人从天堂揪回来,并追认为中国专家了。

为什么我要说“又”呢,因为前一段时间一些人给我发邮件,阐述了用磁铁制造永动机的想法,当然他们也有证据,比如youku上的这个视频。这些同学宁可相信一个清晰度不高的视频,也不愿意花五分钟搜索下google。这里我倒是有个窍门,但凡遇到自己不太信的东西,只需要搜索下“关键词+骗子”即可。

比如这个视频里的永动机叫Perendev磁电机,我就在google上搜了下“Perendev 骗子”,结果果然被我搜到一些新闻,大概意思如下:
Perendev motor 发明人 Michael Brady 在今年三月底于瑞士遭到逮捕并引渡德国,现在面临诈欺罪起诉。Perendev motor 号称是可以投入量产的免费能源,前几年在网路上相当热门,也有不少拥护者。
不过 Perendev motor 从来没提供过什么称得上证据的东西,只有网路上几段不到10分钟但解析都还不错的影片。当Michael Brady 在 2006 年宣布接受订单后,光是在德国就至少有 61 位客户兴冲冲的付了订金,总金额粗估为一百万欧元。Perendev motor 在俄国、西班牙、荷兰也设有分公司,目前还不知道有没有他国人士下订单。

我觉得很有意思的是,ourdev论坛上也是这样,本来只是大家玩玩磁铁,结果很快就有人发静态悬浮或者永动机的帖子。根源可能在于他们觉得磁铁的力量是凭空出现的。其实引力是普遍存在的,就像高山上的水流下来可以做功,但没有人会把水运到山上倒下来让它发电。磁铁也是一样,它吸住铁皮的时候可以做一点功,但是拉开它们的时候就轮到外界做功,总归它不能产生额外的能量。

以后类似的邮件请不要再发给我了,也希望不要有人再被骗子忽悠。

最后发一个无聊的“磁铁永动机”漫画,仅供娱乐:

盗梦陀螺攻略3- 上拉式磁悬浮

有了磁悬浮陀螺的念头,我没有直接开始做下推式,而是先做一个上拉式的练练手。这件事的经历说明:对一个新手来说,可以采用由浅入深,先易后难的策略;虽然总时间可能会更长一点,但是对增强信心,掌握经验很有帮助。(好吧,水木的Joker们看到这句话一定会想歪,色情猥琐男们请自觉面壁)

上拉式磁悬浮原理相当简单。先用万能的乐高颗粒搭一个架子,把绕好的线圈固定在上面。然后用钕铁硼强磁做一个浮子。小窍门来了,我们在线圈的上方放置一个大磁铁,一开始浮子会被吸在线圈下方,慢慢的向上抬大磁铁,到一定高度时,浮子吸不住了向下落。记住这个位置,把大磁铁固定在那里。这样的效果是:线圈里只要通一点电流,就可以吸住浮子,电流一断浮子就会下落。

线圈和浮子的安装

线圈和浮子的安装

图中的浮子下面有个白色的东西,其实那不是什么秘诀,只是我用来标示上下的记号。大磁铁下面有好几个乐高齿轮,其实那都是调节高度用的,之所以用齿轮而不是用圆片倒是有原因的,因为我觉得比较酷 :D

电路方面,上拉式磁悬浮只需要一个传感器,但是我还是焊了双路的板子,这样和将来的下推式用同一块就可以。电路图还没时间学习怎么画,先用画笔凑合弄了个原理图,里面省略了一些细节,不过应该能看明白了。

上拉式磁悬浮原理图

上拉式磁悬浮原理图

请注意我的电路中用了两个电位器。其中电位器1是多圈电位器,作用是调节传感器输出范围。3503很灵敏,电流被放大以后,很容易就超出0到5V的测量范围,所以在需要一个精密的电位器,让输出范围尽量在5V以内。电位器2是用来调节浮子位置的,它是我们设置的“目标位置”。Arduino开发板的作用,就是调整线圈电流大小,从而控制浮子上下移动,最终让传感器的读数等于我们设定的目标值。实物的接线图请看:

接线图,貌似不太清楚

接线图,貌似不太清楚

这个可能大点

这个可能大点

代码就非常简单了,所有的代码只有下面这几行:

int readPin = 2;    //用来连接输入
int i1Pin = 36;     //连接电机驱动板的I1接口
int i2Pin = 37;     //连接电机驱动板的I2接口
int powerPin = 8;   //连接电机驱动板的EA接口
int adjustPin = 6;

boolean flag = true;
int power = 0;
int readValue = 0;
int adjustValue = 0;

void GetPowerValue()
{
  power = readValue - adjustValue;
  if(power < 0) power = 0;
  if(power > 50) power = 50;
  power = power * 16 / 10;
}

void setup()
{
  pinMode(i1Pin, OUTPUT);     //I1和I2都是数字信号
  pinMode(i2Pin, OUTPUT);     //通过设置I1和I2来控制电流方向
  pinMode(powerPin, OUTPUT);  //按占空比方式输出的模拟信号
  digitalWrite(i1Pin, !flag);
  digitalWrite(i2Pin, flag);
  //Serial.begin(9600);          //设置波特率
}

void loop()
{
  //读取电位器和传感器的读数
  readValue = analogRead(readPin);
  //传感器的电压范围是220~580,所以调节电位器的范围可以稍作调整
  adjustValue = analogRead(adjustPin) / 3 + 220;
  GetPowerValue();
  //Serial.println(readValue);
  //Serial.println(adjustValue);
  //Serial.println(power);

  analogWrite(powerPin, power);
  //delay(2000);
  //delay(1);
}

代码虽然简单,但是在制作的过程中却走了很多弯路。这段代码的重点在于:
power = power * 16 / 10;

这个相当于是调整线圈电流的放大倍数,参数1.6如果小了则吸不住浮子,大了则无法稳定。程序中的16如果换成15或者17都不行的。因为这么一个小小的问题,我走了一星期的弯路。当时怀疑原理不对,在反复检查无果之后,已经跟圈妈提出放弃这个项目。幸好这时候得到了圈圈妈“严厉”的鼓励:遇到这么点困难就打退堂鼓,以后怎么做大事!从另一个角度说,当你想尽办法几乎绝望的时候,其实已经接近成功了,因为你已经排除了大部分错误。

果然第二天就解决了问题!后来在制作下推式的时候,类似的事情又一次发生,那次主要问题在于线圈绕的不行,而重做线圈是一个非常浩大的工程,同样也是在圈妈的鼓励下,终于下决心重新做一遍。在此向顽强的圈妈表示敬意(圈妈表示鸭梨不大,反正她不出力干活^_^ )

这个实验最终的经验总结如下:
1,参数很重要!如果你的磁悬浮上下跳动的厉害,恭喜你,其实你已经接近成功了。
2,这个试验中的参数有效范围非常窄,跟程序也有关系,后面会介绍一种PID算法,可以扩大范围,更容易调节。
3,坚持,太累的时候放松一下,然后换个思路想想。

视频如下:

盗梦陀螺攻略1- 原理图与器件清单

本来昨天就想发这个帖子,因为想画一个原理图出来,所以这两天试着安装了Protel和PCsELcad。结果整了两天也没把图画好,看来圈圈妈说的对,这一行我确实门还没迈进去。既然这样,我先把网上找到的电路图发出来,其实基本是差不多的。
这次做悬浮陀螺,我从中国电子开发网上找到了很多资料,其中下推式磁悬浮的电路,基本上是参考了网友liguang70217的ATmega8单片机方案,点击这里可以查看原帖。
下推式磁悬浮电路图

下推式磁悬浮电路图

更清晰的pdf版本可以从这里下载。看到这里,有些同学们估计已经坐不住了:嗨,早说有这个网站,我们直接去看就得了,何必在这里等攻略捏?
其实Ourdev的磁悬浮开源活动,从09年4月份就开始了,所以心急的同学们应该反省一下自己的搜索能力。另外,那个论坛基本上是高手出没的地方,我等无门无派的新手,看人家双截棍耍的挺酷,自己一动手往往碰的鼻青脸肿。所以我默认来这里看攻略的,都是跟我一样的新手们,尽量从新手的角度来记录制作过程。
首先简单介绍一下这个电路的原理:
图中右下角的两个3503,就是传说中的线性霍尔传感器,安装在浮子的正下方,分别用来测量横竖两个方向的磁场强度;当磁场变化时,输出电压也会相应变化;因为传感器的变化量一般都比较小,所以需要经过放大,这里用的是LM358数字放大电路;放大后的信号由ATMag8单片机采集,经过一定的算法之后,输出控制信号;因为单片机的控制信号支持的电流都比较小,需要用这个信号驱动一个大电流控制板,让它通过电压的变化来控制线圈磁场,从而实现对悬浮物的控制。
因为小爱计划暂时停止了,我手头有一块富裕的Arduino Mega168控制板和一块L298N直流电路板,所以我正好就以手头的这两块板子为基础做实验。当然,DIY的乐趣在于学习和改造,我的磁悬浮和这个电路有下面这些区别:
1. 因为单片机改成了Arduino开发板,所以图中单片机周边的电容和晶振就不需要了。
2. 因为没有合适的电源,我把那个坏掉的笔记本电源利用上了,额定电压20V,最大电流2A。
3.Arduino的电源是9V,所以加了一块lm7809用来生成9V电压。
4.10k和4.7K的电阻,我换成了100k和2k,好像影响不大。
5.L298N的驱动,图中是每组用两根控制线驱动,我改用三根,编程的时候会方便点(这个后面再介绍)
6.外接了两个旋转电位器,用来调节平衡,这个主要是为了装箱子以后方便,免得总开箱用螺丝刀拧。
7.对应的代码,需要针对Arduino进行修改。
因为电路图不太会画,这里就不贴啦。下面是器件清单和相应的资料pdf,方便大家查询:
器件名称 规格 数量 功能 文档
直流稳压电源 20V,2A 1 电源
UGN3503 2 线性霍尔传感器,
用于测量磁场强度
UGN3503.pdf
LM358N 1 数字电流放大器 LM358N.pdf
LM7809 1 输出9V电压,给Arduino供电 lm7809.pdf
Arduino开发板 Mega 168 1 数据采集,逻辑控制,输出控制 见攻略
L298N控制板 1 大电流输出,用于控制线圈磁场 见攻略
电阻 100K
2K
2
2
用于数据采集电路 这个不需要了吧
多圈电位器 10K 2 用于设置空载时的电压。
需要精确设置
dwq1
调节电位器 10K 2 用于调节位置,
精度要求不高
dwq2
导线 最好是芯硬一点的 若干
杜邦头 若干 线多的时候,用这个接插比较方便 dbt
线圈骨架 D32*D15*H18 4 用来绕线圈 gj
漆包线铜丝 直径0.27mm 1公斤 绕线圈
洞洞板 最好买3连孔的,好焊 2块 用来焊电路 ddb
乐高颗粒 齿轮,连杆等 若干 用来搭一些简单结构
圆环形黑磁铁 145*80*20 1个 产生斥力让浮子悬浮 请咨询幼儿园小朋友
钕铁硼强磁 D15*4mm
D30*2mm
D31.7*19.1*3.2mm
1
1
1
用来组装浮子 请咨询幼儿园小朋友
一元钱硬币 1 浮子配重 请咨询央行行长
牙医专用石膏 1公斤装 1 做陀螺造型用 请咨询牙医或骨科大夫
指甲油 古铜色 1 陀螺上漆 请咨询您的mm
好了,以上就是所有需要的材料,下面插播花絮几则:
1,在电路图里,有两个LM358放大器,于是我一开始蹭蹭的就焊了两块上去,后来才知道,这个LM358有两路放大器的,焊一个就够。据圈妈说,这个是原理图,跟器件的真实形状,管脚顺序都未必一样(那个是PCB图)。好吧,新手就是这样….
2.当时为了绕线圈,我在淘宝试过好多关键词,什么线圈轴,线圈,电磁铁芯等等,都没有搜到,只好用乐高的齿轮+轴绕线圈。因为绕的质量不好,调试时吃尽了苦头(振动非常大)再后来,才知道这东西原来叫线圈骨架,买回来重绕,立竿见影的就成功了!
3,我的板子焊好后,得意洋洋的拿去给圈妈鉴定。圈妈惊呆了,作为一个资深业内人士,这么多年来新手见得多了,但是焊的这么丑的真是第一回见:布局不合理,导线满天飞,而且还有各种虚焊连焊,简直可以当反面教材了。唯一欣慰的是能闻到点烤肉味,让人食欲大开。
唉,为了不影响圈圈,我一直在一个阴暗的跑步机架子上焊东西,这样就算不错了,至少运行还蛮稳定的,请欣赏漫天的飞线:
新手焊的板子

新手焊的板子

这个周末做了三件事情

第一件事是给盗梦陀螺做了一个盒子,这件事得到了圈圈妈的大力支持,在此表示感谢!

现在看上去好看多了 :)

盒装版盗梦陀螺

盒装版盗梦陀螺

再换个角度

正面照

正面照

特写:

特写

特写

第二件事是圈圈妈协助我把制作的过程记录了下来,并重新整理了一个视频。呵呵,我也算时髦了一把,玩了一下视频加工,看看效果如何:

第三件事是给CNBeta又投了个稿,特地截了两张”剧照”配合一下 ^_^

看过”盗梦空间“的童鞋们,一定对那个陀螺印象深刻吧?最近,动力老男孩也赶了趟时髦,充当了一把造梦师。图中的盗梦陀螺是采用潘多拉星球的矿石为原料,纯手工打造而成。配上量身定做的底座以后,这个神奇的陀螺不仅不会倒下,还可以保持悬浮状态。

怎么样,是不是有梦境一样的错觉呢?请参考以下做法:
aa

bb

===================================

另外,应网友建议,我在页面的最上面添加了一个“盗梦陀螺”分类,以后会陆陆续续把攻略添加到这个目录中。

磁悬浮的故事(下) – 动态磁悬浮

今天接着上次的内容,继续分享动态磁悬浮。

话说恩绍大定理问世以后,在很长的一段时间内,如果某个物理学家宣布要制造磁悬浮,一定会受到同行们的羞辱,因为这个跟永动机一样是不可能的。可惜的是,有无数的民间“科学家”不认得恩绍,更不知道什么大定理小定理,他们日复一日的做各种尝试。奇迹往往就这样产生了,1993年美国的一位叫罗来.哈里根(Roy Harrigan)的民间发明家申请了一项磁悬浮的专利。玩过陀螺的人一定都注意到一个现象:静止的陀螺是不可能直立的,但是只要旋转起来,就能保持平衡。哈里根同学的方法就是这样,虽然静止的磁铁不能保持稳定,但是可以做成一个陀螺,让它旋转起来就可以保持悬浮状态。

后来有两位无耻的物理学家(美国拉斯维莫斯国家实验室,所以大家也别相信美国的所谓社会公德),作为学院派的人物,他们抱着找茬的态度联系了发明家。在亲眼目睹了这个神奇的发明之后,他们骗走了一套陀螺回去研究。之后的事情大家应该能猜到了,他们稍作修改,申请了新的专利,并制作了一种叫Levitron的玩具大赚特赚。这次为了研究磁悬浮,我也特地从淘宝买了一套,只需要15元:

不用电的磁悬浮,但是需要很高的技巧

不用电的磁悬浮,但是需要很高的技巧

说到这里必须多提两句。据专家分析,这种陀螺在磁体上几十毫米的空中浮动,但稳定区域只有4毫米左右,陀螺必须呆在这一看不见摸不着的狭小区域中才能稳定。不仅如此,陀螺的重量必须精确到1%左右,轻则飞出,重则落地。加之陀螺的稳定还随环境温度变化,必须随时调整。使用者还要学会在磁体强烈的斥力下把陀螺转到一定的转速,快了慢了都不能稳定。作为一个成熟产品,我大概玩了一个小时才能掌握让它浮起来的技巧,真不知道这些发明家们经历了多少失败才发明出来的!在此向这些伟大的DIY玩家致敬!

这个不用电的陀螺虽然能悬浮,但是只能保持几分钟(空气阻力)。然后21世纪到了!集成电路,霍尔传感器,钕铁硼强磁….科技的进步让我这样的业余玩家也可以在家做磁悬浮,这就是所谓的站在巨人肩膀上。这次我做了两种磁悬浮:上拉式和下推式。其中用到的一个关键器件是线性霍尔传感器,这种传感器简而言之就是能够感知磁场的大小:

线性霍尔传感器

线性霍尔传感器

这种传感器的安装要非常小心,因为它测量的是通过那个小小的平面的磁通量,如果磁场和表面平行,那么再强的磁场也测不出来。另外这里必须用线性霍尔,而不是开关型霍尔,我选用的型号是UGN3503。

有了传感器,其他的事情就好办了。例如上拉式磁悬浮,如果检测到磁铁向下运动,就加大电流把它吸上来;反之如果向上运动,就减小电流让它下落。当然这里面也需要一些编程上的技巧,我后面会介绍PID算法原理。

上拉式磁悬浮原理图

上拉式磁悬浮原理图

下推式悬浮原理很类似(其实两种悬浮我用的是同一块电路板),但是需要横竖两个方向共同合作。以一个方向上的截面为例:

下推式磁悬浮原理图

下推式磁悬浮原理图

它的原理是:霍尔传感器在浮子的正下方,当检测到浮子向左运动时,两边的线圈一个吸一个拉,把它推向右;反之如果浮子想右运动,那么两个线圈的电流都反向,把它推向左。用前后左右共四个线圈,两个霍尔传感器配合,就可以把浮子稳定的悬浮住。

至于让浮子旋转,我参考的是鼠笼式电动机的原理,基本上是依据楞次定律,制造一个旋转磁场,以此让浮子无接触的转动。这个实验没有成功,我觉得主要是因为线圈的电磁场随距离衰减过快,无法驱动陀螺。不过这次实验倒是让我学习了一些数字电路的知识,改天也会总结一下发上来。

鼠笼式电动机原理

鼠笼式电动机原理

有了磁悬浮的基础,可以有一些很酷的应用。你可以想象一个悬浮的无线供电灯泡,或者一个悬浮的广告灯箱。有一家叫Crealev的荷兰公司专门做磁悬浮产品,效果非常酷,看下面的产品图:

悬浮台灯

悬浮台灯

悬浮的儿童不宜

悬浮的儿童不宜

昨天跟一群同事一起去吃烤肉,那些肉特别容易粘在篦子上,贪吃的你一定知道的。同事们开玩笑说,你发明个东西,让肉飘在空中吧,无接触式翻烤。呼呼,这还真是个有意思的创意!

好了,磁悬浮的背景故事说完了。还有几句题外话:
上面说起了永动机,不得不再提一下民间发明家们。即使是现在,依然有很多人在孜孜不倦的发明永动机,大部分人当然是浪费时间,但是依然有一些非常有创意的小发明问世,姑且称之为“准永动机”。比如我们常见的自动手表,就是通过人体运动驱动摆锤自动上发条。还有一种神奇的喝水鸟,只要一天的温差超过几度,它就可以不停的点头喝水,很好玩 :)

靠温差运动的神奇“喝水鸟”

靠温差运动的神奇“喝水鸟”

磁悬浮的故事(上) – 静态磁悬浮

先说说这几天都干了什么吧。总结来说,就是又做了一个不成功的实验。在上次的视频里,被眼尖的童鞋们敏锐的指出,这个陀螺转速是越来越慢的。事实上,这个陀螺慢到一定程度之后,会保持稳定的速度旋转,不会停下来。这周的主要想法就是做一个高频旋转的磁场,试试看能不能带动陀螺高速旋转。

使用的方案是:方波+74LS161计数器+74LS138译码器+L298N直流电路驱动器。电路总算是调通了,但是作用力不足以影响陀螺的转速,实在是太肉了。发个截图留念吧,明天就把它拆了。

旋转磁场的发生装置

旋转磁场的发生装置

下面言归正传,把我之前收集的一些磁悬浮相关的知识分享给大家。

自然界的物质有抗磁性,顺磁性和铁磁性三种特性,来自潘多拉星球的阿凡提同学可能对此存有疑惑,不过在咱们地球目前只有这么三种。其中:
抗磁性】几乎是所有物质都有的,它的来源是楞次定律。这个抗磁性非常微弱,大部分情况下可以忽略不记,常温下抗磁性最强的物质是金属铋;
顺磁性】这种物质的主要特征是,不论外加磁场是否存在,原子内部存在永久磁矩。但在无外加磁场时,由于顺磁物质的原子做无规则的热振动,宏观看来,没有磁性;在外加磁场作用下,每个原子磁矩比较规则地取向,物质显示极弱的磁性,金银铝铂之类的金属貌似都是顺磁性;
铁磁性】这个大家最熟悉,一根铁钉在磁铁上蹭几下,它就变成一个小磁铁。具有铁磁性的元素有五种:铁,钴,镍,钆,镝。这些元素的化合物也可能具有铁磁性,咱们最常见的黑磁铁主要成分就是四氧化三铁,还有巨牛无比的钕铁硼(友情提示,那个字念“女”)

说起磁铁,相信是很多小盆友儿时的宝贝,也许大家也曾想过用巧妙的设计让磁铁悬浮起来。例如我构思过这么一个方案,把很多磁铁N极向上贴在一个碗的内侧,然后把另外一些磁铁N向外贴在一个球的外侧,这样是否能悬浮呢?

儿时幻想的磁悬浮

儿时幻想的磁悬浮

下面就是一个著名的恩绍大定理(Earnshaw’s theorem)

这个可恶的家伙早在1842年就用数学证明了:若单靠宏观的静态古典电磁力,稳定的磁悬浮是不可能实现的。这是因为在物件上所承受的各种合力,包括了引力、静电场及静磁场会使物件变得很不稳定。

你可以想象在光滑的坡顶放一个小球,虽然有某个平衡点存在,但事实上是无法稳定的,任意小的扰动都会让它失去平衡。所以大家不要费劲去设计了,像下面这样的磁悬浮列车设计没有外界能源时是无法平衡的:

无法实现的稳定磁悬浮

无法实现的稳定磁悬浮

但是恩绍大定理有个例外,就是前面提到的抗磁性。超导现象就是抗磁性的一个极端情况,因为超导体内部的感应电流可以非常大。实验也非常简单,弄一个超导体的盘子,直接扔一块磁铁进去,它就能稳定的悬浮着。

超导磁悬浮

超导磁悬浮

事实上如果磁场足够大的话,生物体内水分的抗磁性都足以让它悬浮起来。2000年,科学家安德烈·海姆和迈克尔·贝瑞使用磁性让一只青蛙悬浮在半空中,他们因此获得了当年的搞笑挪被窝儿奖(不过他们今年真的拿奖了,因为石墨烯,不得不赞一个,感觉这两个科学家的研究工作都是在玩啊)

用超导体的强大磁场,可以把青蛙悬浮起来

用超导体的强大磁场,可以把青蛙悬浮起来

 我们在常温下有没有可能实现静态稳定磁悬浮呢?答案是肯定的!以我们刚才说的最强的抗磁性金属铋(这个东西居然淘宝有卖的,而且比奶粉便宜)为例。因为它的抗磁性非常弱,所以有网友设计了一种巧妙的方法,先用一组磁铁让悬浮物处于“基本平衡”的状态,这时候微弱的抗磁力就可以让悬浮物稳定的平衡了。看下面的图:

用铋实现的常温下 稳定磁悬浮

用铋实现的常温下 稳定磁悬浮

另外一个例子是石墨烯,这个东西轻飘飘的,也可以在常温下悬浮。下面这个图里,四块磁铁是N对S这样分别吸住的,据说国外有人用铅笔芯削成薄片也可以实现这样的效果。我试了下貌似不行,于是又有人解释说国内的铅笔芯含粘土,不是纯石墨。。。具体怎么样有兴趣的兄弟自己试试吧:)

常温下悬浮的石墨片

常温下悬浮的石墨片

今天晚了,改天再介绍动态磁悬浮。最后发一个展望未来的图,嘿嘿:

想一想都觉得爽啊

想一想都觉得爽啊

盗梦陀螺来啦!

还记得两个月前热映的电影《盗梦空间》吗?那是有圈圈之后第一次去看电影,电影非常酷,我也非常兴奋。也许有人跟我有过类似的经历:早上从梦中惊醒,迷迷糊糊起床,刷牙洗脸吃早饭,然后去学校考试,没想到平时很熟的题目就是不会做,一着急就穿越了,原来还在床上……汗,梦中好像还上了厕所,赶紧检查一下

中国古代也有类似的故事,例如黄粱一梦(典故向下看)。那个道士应该算是Inception的鼻祖了,而那个书生也因为这个梦看透了荣华富贵。嗯?貌似跟电影还挺相似啊,难倒是抄袭了创意?呵呵,跑题了,总之这是一部让人深思的电影。

电影中最让我印象深刻的就是那个陀螺(因为圈圈妈会审查我的博客,所以不能说印象最深刻的是那个小美女造梦师)。看完电影,圈圈妈说:你也做一个不会倒的陀螺吧。

不会倒的陀螺其实很好做,用几块磁铁就可以让陀螺处于竖直稳定状态:

不会倒的陀螺简易版

不会倒的陀螺简易版

这个陀螺叠加上旋转磁场后,就可以一直旋转下去了。但是我觉得这样不够酷,于是跟圈圈妈夸下海口,要做一个能悬浮的陀螺。事实证明,一个已婚已育的IT加班男,最好不要随便吹牛。电影之后我马不停蹄的查阅资料,购买器件,设计电路,制作陀螺,调试程序,到最近才刚刚做成雏形。回头看了下当时的博客,神啊,两个多月过去了。

秀一下做好的陀螺吧,本来想尽量做成跟电影里一样,不过看来手艺一般。这个外形我用小刀整整抠了一晚上,大家给个面子夸一夸吧:

纯手工打造的盗梦陀螺

纯手工打造的盗梦陀螺

这是悬浮状态时的陀螺截图:

悬浮状态的盗梦陀螺截图

悬浮状态的盗梦陀螺截图

有兴趣的同学可以进一步观看视频:

第一次悬浮成功的时候,还真有一种恍然如梦的感觉。也许人生就是这样,有些梦看似遥不可及,真正动起手来其实就是两个月的业余时间。当然,搞不好这个作品只是在梦中实现的,希望明早醒来的时候,这个玩意儿还在我的桌子上 :)

=============传说中的昏鸽线==================
从百度贴一段典故,供半文盲小白们查阅:

唐朝时期,一个书生姓卢,字萃之,别人称之为卢生。

一年,他上京赶考,途中在邯郸的旅馆里投宿,遇到了一个叫吕翁的道士,并向他感慨人生的穷困潦倒。吕翁听后,从衣囊中取出一个枕头给卢生,说:“你晚上睡觉时就枕着这个枕头,保你做梦称心如意。”

这时已晚,店主人开始煮黄米饭。卢生便按着道士的说法开始睡觉,他很快睡着了。在睡梦中,他回到家中,几个月后,还娶了一个清河的崔氏女子为妻,妻子十分漂亮,钱也多了起来。卢生感到十分喜悦。不久他又中了进士,多次层层提拔,做了节度使,大破戎虏之兵,又提升为宰相做了十余年。他先后生了五个儿子,个个都做了官,取得了功名,后又有了十几个孙子,成为天下一大家族,拥有享不尽的荣华富贵。然而到了八十多岁时,他得了重病,十分痛苦,眼看就要死了,突然惊醒,才知是一场梦。

这时,店主煮的黄米饭还未熟。卢生感到十分奇怪地说:“这难道是场梦?”吕翁听了便说:“人生的归向,不也是这样吗?”

经过这次黄粱一梦,卢生大彻大悟,再不去想进京赶考了,反而进入深山修道去了。