单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:16361|回复:6
打印上一主题下一主题

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

 [复制链接]
跳转到指定楼层
楼主
ID:330820发表于 2018-12-17 11:22|只看该作者|只看大图回帖奖励
參考网上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. }
复制代码


评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

沙发
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 单片机教程网