找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 18158|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

參考網(wǎng)上arduino下推式磁懸浮制作(源碼+電路圖)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:330820 發(fā)表于 2018-12-17 11:22 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
參考網(wǎng)上arduino下推磁懸浮制作

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

2.PID叄數(shù)可從arduino serial Monitor,更改輸入kp1.4 ENTER,ki0.01ENTER, kd7.8ENTER.

4.SW可微調(diào)X-,X+,Y-,Y+位置,

5.L298N輸入用74LS04,

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

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

8.線圈及霍爾都是跟網(wǎng)上一樣安裝,

安裝完成試機

1.L298N不要接12V.

2.arduino接上電源5V調(diào)教OFFSET R5,R6 到約2.15V.

3.把浮子放到霍爾上XY方向左右移動LCD Hx,Hy數(shù)字會變化,

4.先把L298N,IN1,IN2不要接,只接X,IN3,IN4,然后接12V電源,X缐圈是否對X霍爾,
  如果接缐正確會有力拉動浮子,可調(diào)OFFSET ,R5 調(diào)到浮子在兩個缐圈中心位置.
  然后接上IN1,IN2,調(diào)Y線圏跟X線圈一樣方法調(diào),但調(diào)OFFSET,R6.

5.如果XY接缐正確浮子會浮動的,然后調(diào)教R5,R6使浮子在四個缐圈中心位置.
   如果浮子沒有拉力拉向中心,檢查有無接錯缐.

6.調(diào)教PID參數(shù)會使浮子隱定.

7.PID參數(shù)可從arduino serial Monitor,
  更改輸入
kp1.43 ENTER
ki0.018ENTER
kd7.5ENTER

8.4SW可微調(diào)浮子位置.

這個程式都是從網(wǎng)上arduino的磁浮程式更攺過來,如有錯請自行更正.
大家玩得開心.


制作出來的實物圖如下:


電路原理圖如下:


下面是arduino程序源碼
網(wǎng)上資料
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:得到新的字節(jié):
  271.     char inChar = (char)Serial.read();
  272.                                              // 將它添加到inputString:
  273.     if (inChar != '\n') {
  274.       mySt += inChar;
  275.     }
  276.                                              // 如果傳入的字符是換行符,請設(shè)置標誌
  277.                                              
  278.     if (inChar == '\n') {
  279.       stringComplete = true;
  280.     }
  281.   }
  282. }
復(fù)制代碼


評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏10 分享淘帖 頂2 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:316613 發(fā)表于 2019-11-28 14:40 | 只看該作者
這帖子為啥沒人頂?
回復(fù)

使用道具 舉報

板凳
ID:25481 發(fā)表于 2019-11-29 07:51 | 只看該作者
很好的實際教程
回復(fù)

使用道具 舉報

地板
ID:651779 發(fā)表于 2019-12-1 00:16 來自手機 | 只看該作者
這個好厲害
回復(fù)

使用道具 舉報

5#
ID:85726 發(fā)表于 2020-3-3 16:34 | 只看該作者
不錯,可以學(xué)習(xí)一下
回復(fù)

使用道具 舉報

6#
ID:84702 發(fā)表于 2024-1-2 23:34 | 只看該作者
不錯不錯,好像不能復(fù)制
回復(fù)

使用道具 舉報

7#
ID:330820 發(fā)表于 2024-1-14 10:04 | 只看該作者
yuandm8888 發(fā)表于 2024-1-2 23:34
不錯不錯,好像不能復(fù)制

已更改了可以復(fù)制了,但設(shè)時間發(fā)出來
回復(fù)

使用道具 舉報

8#
ID:1129526 發(fā)表于 2024-7-29 22:42 | 只看該作者
lamyauhoi 發(fā)表于 2024-1-14 10:04
已更改了可以復(fù)制了,但設(shè)時間發(fā)出來

現(xiàn)在還找得到嗎可以發(fā)一下嗎
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表