找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16044|回复: 6
打印 上一主题 下一主题
收起左侧

參考网上arduino下推式磁悬浮制作(源码+电路图)

  [复制链接]
跳转到指定楼层
楼主
參考网上arduino下推磁悬浮制作

1.有曾加一些功能LCD显示PID,霍尔輸入及其它輸出,

2.PID叄數可从arduino serial Monitor,更改輸入kp1.4 ENTER,ki0.01ENTER, kd7.8ENTER.

4.SW可微调X-,X+,Y-,Y+位置,

5.L298N輸入用74LS04,

6.霍尔要安裝的高度在線圈高度一半的高度.

7.缐圈头要接在一起,兩个缐圈尾接到L298N OUT位置.

8.線圈及霍尔都是跟网上一样安裝,

安裝完成试机

1.L298N不要接12V.

2.arduino接上电源5V调教OFFSET R5,R6 到約2.15V.

3.把浮子放到霍尔上XY方向左右移动LCD Hx,Hy數字会变化,

4.先把L298N,IN1,IN2不要接,只接X,IN3,IN4,然后接12V电源,X缐圈是否对X霍尔,
  如果接缐正確会有力拉动浮子,可调OFFSET ,R5 调到浮子在兩个缐圈中心位置.
  然后接上IN1,IN2,Y線圏跟X線圈一样方法调,但调OFFSET,R6.

5.如果XY接缐正確浮子会浮动的,然后调教R5,R6使浮子在四个缐圈中心位置.
   如果浮子沒有拉力拉向中心,檢查有无接错缐.

6.调教PID參数会使浮子隐定.

7.PID參数可从arduino serial Monitor,
  更改輸入
kp1.43 ENTER
ki0.018ENTER
kd7.5ENTER

8.4SW可微调浮子位置.

这个程式都是从网上arduino的磁浮程式更攺过來,如有错請自行更正.
大家玩得开心.


制作出来的实物图如下:


电路原理图如下:


下面是arduino程序源码
网上資料
wwwtorresballard.co点uk/levitron/
www点amobbs点com/thread-3752191-2-1.html
  1. #include <Wire.h>
  2. #include <LiquidCrystal_I2C.h>
  3. LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

  4. String mySt = "";
  5. boolean stringComplete = false;  // whether the string is complete

  6. int anaPin_y =   0;     //Arduino Analogic Pin 0
  7. int anaPin_x =   1;     // Arduino Analogic Pin 1
  8. //int pin3_x   =   3;
  9. //int pin4_x   =   4;
  10. int pin_pwm5_x = 5;   // Arduino Digital  Pin 5
  11. int pin_pwm6_y = 6;   // Arduino Digital  Pin 6
  12. //int pin7_y   =   7;
  13. //int pin8_y   =   8;
  14. int subPin_x =   9;     // Arduino Digital  Pin 7
  15. int addPin_x =   10;    // Arduino Digital  Pin 8
  16. int subPin_y =   11;    // Arduino Digital  Pin 11
  17. int addPin_y =   12;    // Arduino Digital  Pin 12

  18. int timer1_counter;   //for timer

  19. //---------------------------------------------------------

  20. int HallX[5], HallY[5];            //Hall effect reading arrays
  21. int MaxX, MaxY, MinX, MinY;        //Error contol variables
  22. int AveHallX=0, AveHallY=0;        //Average hall sensor readings
  23. int setPtX=380;  //430;            // Hall sensor value for equilibrium state
  24. int setPtY=380;  //430;
  25. int errorX;              // midValue - current X hall sensor reading
  26. int prevErrX=0;          // Previous error used to calc derivatve
  27. int dErrorX;             // Derivative of error in X
  28. int errorY;              // midValue - current Y hall sensor reading
  29. int prevErrY=0;          // previous error for calculating dirivative
  30. int dErrorY;             // derivative of error in Y
  31. int powerX;              //PWM value driving X coil
  32. int powerY;              //PWM value driving Y coil
  33. float Kp=1.43;//1.58;    // Proportional weighting
  34. float Ki=0.18;           // Derivative weighting
  35. float Kd=7.5;   //9.79;  // Integral weighting
  36. float varKp = 0;         // Tuning variables (external)
  37. float varKi = 0;
  38. float varKd = 0;
  39. float SumX = 0;          // Sum of XY readings
  40. float SumY = 0;
  41. float integralX = 0;     // Set intial integrals to be zero
  42. float integralY = 0;
  43. //---------------------------------------------------------
  44. void setup()
  45. {
  46.   lcd.begin(20, 4);
  47.   // Levitator initialization Begin;
  48.   Serial.begin(9600);
  49.   Serial.println("Starting...");
  50.   // Digital Pins Work Mode Setup;
  51.   pinMode(pin3_x,OUTPUT);
  52.   pinMode(pin4_x,OUTPUT);
  53.   pinMode(pin_pwm5_x, OUTPUT);
  54.   pinMode(pin_pwm6_y, OUTPUT);
  55.   pinMode(pin7_y,OUTPUT);
  56.   pinMode(pin8_y,OUTPUT);
  57.   pinMode(addPin_x, INPUT_PULLUP);
  58.   pinMode(subPin_x, INPUT_PULLUP);
  59.   pinMode(addPin_y, INPUT_PULLUP);
  60.   pinMode(subPin_y, INPUT_PULLUP);

  61.   //--------------------------timer setup
  62.   noInterrupts();           // disable all interrupts
  63.   TCCR1A = 0;
  64.   TCCR1B = 0;
  65.   timer1_counter = 34286;   // preload timer 65536-16MHz/256/2Hz (34286 for 2ms)
  66.   TCNT1 = timer1_counter;   // preload timer
  67.   TCCR1B |= (1 << CS10);    // no prescaler
  68.   TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  69.   interrupts();             // enable all interrupts
  70.   //------------------------------------------------------------------------

  71.   lcd.backlight();
  72.   lcd.setCursor(0, 0);
  73.   lcd.print("Kp:");
  74.   
  75.   lcd.setCursor(0, 1);
  76.   lcd.print("Ki:");
  77.   
  78.   lcd.setCursor(0, 2);
  79.   lcd.print("Kd:");
  80.   
  81.   lcd.setCursor(14, 0);
  82.   lcd.print("Hx:");

  83.    lcd.setCursor(14, 1);
  84.   lcd.print("Hy:");

  85.   lcd.setCursor(14, 2);
  86.   lcd.print("Px:");

  87.   lcd.setCursor(14, 3);
  88.   lcd.print("Py:");

  89.   lcd.setCursor(8, 0);
  90.   lcd.print("X:");

  91.   lcd.setCursor(8, 1);
  92.   lcd.print("Y:");
  93.   
  94. }
  95. //-----------------------------------------------------------------------
  96. void loop()
  97. {
  98.    if (stringComplete)
  99.       {
  100.   // clear the string when COM receiving is completed   
  101.        stringComplete = false;
  102.        }
  103.   //receive command from serial Monitor
  104.   if (mySt.substring(0, 2) == "kp")
  105.        {
  106.         Kp = mySt.substring(2, mySt.length()).toFloat(); //get string after kp
  107.        }
  108.   if (mySt.substring(0, 2) == "ki")
  109.         {
  110.         Ki = mySt.substring(2, mySt.length()).toFloat(); //get string after ki
  111.         }
  112.   if (mySt.substring(0, 2) == "kd")
  113.         {
  114.          Kd = mySt.substring(2, mySt.length()).toFloat(); //get string after kd   
  115.          }
  116.     mySt = "";
  117. //----------------------------------------------------------------------------------   
  118. Serial.println(powerX);
  119. // delay(1);
  120. //------------------------------------------------------------------------------------
  121.   lcd.setCursor(3, 0);
  122.   lcd.print("    ");
  123.   lcd.setCursor(3, 0);
  124.   lcd.print(Kp);
  125.   
  126.   lcd.setCursor(3, 1);
  127.   lcd.print("    ");
  128.   lcd.setCursor(3, 1);
  129.   lcd.print(Ki);
  130.   
  131.   lcd.setCursor(3, 2);
  132.   lcd.print("    ");
  133.   lcd.setCursor(3, 2);
  134.   lcd.print(Kd);
  135.   
  136.   lcd.setCursor(17, 0);
  137.   lcd.print("   ");
  138.   lcd.setCursor(17, 0);
  139.   lcd.print(AveHallX);

  140.   lcd.setCursor(17, 1);
  141.   lcd.print("   ");
  142.   lcd.setCursor(17, 1);
  143.   lcd.print(AveHallY);

  144.   lcd.setCursor(17, 2);
  145.   lcd.print("   ");
  146.   lcd.setCursor(17, 2);
  147.   lcd.print(powerX);

  148.   lcd.setCursor(17, 3);
  149.   lcd.print("   ");
  150.   lcd.setCursor(17, 3);
  151.   lcd.print(powerY);

  152.   lcd.setCursor(10,0);
  153.   lcd.print("   ");
  154.   lcd.setCursor(10,0);
  155.   lcd.print(setPtX);
  156.   
  157.   lcd.setCursor(10,1);
  158.   lcd.print("   ");
  159.   lcd.setCursor(10,1);
  160.   lcd.print(setPtY);
  161.      
  162. //----------------------------------------------------------------------
  163. // Increase The Value Of Levitation Point;
  164.   if (digitalRead(addPin_x) == LOW)
  165.     {
  166.     setPtX++;
  167.     delay(1);
  168.     }
  169.   if (digitalRead(subPin_x) == LOW)
  170.     {
  171.     setPtX--;
  172.     delay(1);
  173.     }
  174.   if (digitalRead(addPin_y) == LOW)
  175.     {
  176.     setPtY++;  
  177.     delay(1);
  178.     }
  179.   if (digitalRead(subPin_y) == LOW)
  180.    {
  181.     setPtY--;
  182.     delay(1);
  183.     }

  184. }

  185. //--------------------------------------------------------------
  186. ISR(TIMER1_OVF_vect)                      // interrupt service routine - tick every 0.1sec
  187. {
  188.   // PORTB ^= _BV(5);                     //test Toggle LED, PB5 = Arduino pin 13
  189.    digitalWrite(13,HIGH);
  190.    TCNT1 = timer1_counter;                // set timer
  191. //--------------------------------------------------------------------------
  192.     HallX[0] = analogRead(anaPin_x);
  193.     MaxX=HallX[0];
  194.     MinX=MaxX;

  195.     HallY[0] = analogRead(anaPin_y);
  196.     MaxY=HallY[0];
  197.     MinY=MaxY;
  198.   
  199.     HallX[1] = analogRead(anaPin_x);
  200.     if (HallX[1]>MaxX){MaxX=HallX[1];}
  201.     else if (HallX[1]<MinX){MinX=HallX[1];}  
  202.      
  203.     HallY[1] = analogRead(anaPin_y);
  204.     if (HallY[1]>MaxY){MaxY=HallY[1];}
  205.     else if (HallY[1]<MinY){MinY=HallY[1];}
  206.    
  207.     HallX[2]=analogRead(anaPin_x);
  208.     if (HallX[2]>MaxX){MaxX=HallX[2];}
  209.     else if (HallX[2]<MinX){MinX=HallX[2];}   
  210.      
  211.     HallY[2] = analogRead(anaPin_y);
  212.     if (HallY[2]>MaxY){MaxY=HallY[2];}
  213.     else if (HallY[2]<MinY){MinY=HallY[2];}
  214.    
  215.     HallX[3] = analogRead(anaPin_x);
  216.     if (HallX[3]>MaxX){MaxX=HallX[3];}
  217.     else if (HallX[3]<MinX){MinX=HallX[3];}  
  218.       
  219.     HallY[3] = analogRead(anaPin_y);
  220.     if (HallY[3]>MaxY){MaxY=HallY[3];}
  221.     else if (HallY[3]<MinY){MinY=HallY[3];}
  222.    
  223.     HallX[4] = analogRead(anaPin_x);
  224.     if (HallX[4]>MaxX){MaxX=HallX[4];}
  225.     else if (HallX[4]<MinX){MinX=HallX[4];}   
  226.    
  227.     HallY[4] = analogRead(anaPin_y);
  228.     if (HallY[4]>MaxY){MaxY=HallY[4];}
  229.     else if (HallY[4]<MinY){MinY=HallY[4];}
  230.       
  231. SumX=HallX[0]+HallX[1]+HallX[2]+HallX[3]+HallX[4];
  232. SumY=HallY[0]+HallY[1]+HallY[2]+HallY[3]+HallY[4];

  233. AveHallX = (SumX-MinX-MaxX)/3;                               // Average x reading
  234. AveHallY = (SumY-MinY-MaxY)/3;                               // Average y reading

  235. errorX = setPtX - AveHallX;                                  // X position error
  236. errorY = setPtY - AveHallY;                                  // Y position error

  237. dErrorX = errorX - prevErrX;                                 // X position differential error
  238. dErrorY = errorY - prevErrY;                                 // Y position differential error

  239. integralX = integralX + errorX*0.015;                       // X integral
  240. integralY = integralY + errorY*0.015;                       // Y integral

  241.      if (integralX > 500) integralX = 500;
  242.      if (integralX < -500) integralX = -500;
  243.    
  244.      if (integralY > 500) integralY = 500;
  245.      if (integralY < -500) integralY = -500;

  246. powerX = errorX*Kp + integralX*Ki + dErrorX*Kd;             // X power
  247. powerY = errorY*Kp + integralY*Ki + dErrorY*Kd;             // Y power

  248. prevErrX=errorX; // Assign new previous x error value
  249. prevErrY=errorY; // Assign new previous y error value
  250. //----------------------------------------------------------------------------

  251.   // Check the value for levitation point;
  252.    // if (powerX < 0)   powerX = 0;
  253.     if (powerX < 0) powerX= 0;
  254.     if (powerX > 255) powerX = 255;
  255.   
  256.     if (powerY < 0) powerY = 0;
  257.     if (powerY > 255) powerY = 255;

  258. //----------------------------------------------------------------------------
  259.    analogWrite(pin_pwm5_x, powerX);
  260.    analogWrite(pin_pwm6_y, powerY);
  261.    
  262.     prevErrX=errorX;                  
  263.     prevErrY=errorY;                   // Assign new previous y error                                    
  264. //--------------------------------------------------------------------------------
  265. // PORTB ^= _BV(5);                          //測試LED,PB5 = Arduino腳13
  266.   digitalWrite(13,LOW);   
  267. }
  268. void serialEvent() {
  269.   while (Serial.available()) {
  270.                                              // get the new byte:得到新的字節:
  271.     char inChar = (char)Serial.read();
  272.                                              // 將它添加到inputString:
  273.     if (inChar != '\n') {
  274.       mySt += inChar;
  275.     }
  276.                                              // 如果傳入的字符是換行符,請設置標誌
  277.                                              
  278.     if (inChar == '\n') {
  279.       stringComplete = true;
  280.     }
  281.   }
  282. }
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏10 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:316613 发表于 2019-11-28 14:40 | 只看该作者
这帖子为啥没人顶?
回复

使用道具 举报

板凳
ID:25481 发表于 2019-11-29 07:51 | 只看该作者
很好的实际教程
回复

使用道具 举报

地板
ID:651779 发表于 2019-12-1 00:16 来自手机 | 只看该作者
这个好厉害
回复

使用道具 举报

5#
ID:85726 发表于 2020-3-3 16:34 | 只看该作者
不错,可以学习一下
回复

使用道具 举报

6#
ID:84702 发表于 2024-1-2 23:34 | 只看该作者
不错不错,好像不能复制
回复

使用道具 举报

7#
ID:330820 发表于 2024-1-14 10:04 | 只看该作者
yuandm8888 发表于 2024-1-2 23:34
不错不错,好像不能复制

已更改了可以复制了,但设时间发出來
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表