arduino 磁悬浮

本文介绍了使用arduino uno和相关组件实现磁悬浮的步骤,重点在于线性霍尔元件的调整和PID控制算法的应用。通过调整霍尔元件位置确保力的平衡,采用中断方式获取数据以提高速度。文章详细讨论了PID参数的调试,包括比例、积分和微分参数的影响,强调了参数设置对系统稳定性的重要性。同时,提供了完整的代码实现,包括位置和速度闭环PID控制。
摘要由CSDN通过智能技术生成

用4个电磁铁,一个永久磁铁圈,一个arduino uno单片机,一个tb6612,线性霍尔ah3503

使用的东西不要那么死板

1、线性霍尔元件两个,必须成垂直交叉,但是在实际做的过程中,完全垂直交叉可能性不大,就需要手动调整
   这是非常重要的,而且会影响后面的调试,特别是初期,你根本感觉不到问题,什么是正确的,什么是错误的
   只能凭借经验.
   到最后,实际上当你感受到力,使得浮子被夹在中间,但是位置不正确,就可以手动去调整霍尔元件。
   如果是加5v电,就没必要加放大器,直接接到主板里就好。
   获取霍尔数据最好用中断的方式,这样速度快。
2、当你上电后,如果能感觉浮子在x轴、y轴都有力量控制在中间,那么距离成功就不远了。如果没感觉到这个力
   多半是线路颠倒。
3、在上电施加的力,必须反应足够快,如果你听到有很大的电流声,就要提高频率,直到听不到电流声音。
   发现抖动太大,可以减小力量
4、pid算法很简单,不需要太复杂,但调试参数就有点花费时间,
   但我们通常把注意力集中在具体代码上,这是错误的方向
   kp是主要的力参数,这个只要你感受到能承受浮子被夹在中间,并且软绵绵的就可以了
   ki似乎没太大作用,设置大了,浮子摆动太大。
   kd控制浮子摆动,调合适为止
    pid->Kp=0.8500;       //K比例
    pid->Ki=0.01;     //K积分,注意,和上几次相比,这里加大了积分环节的值
    pid->Kd=1.6000;       //K微分
5、对于pwm的设置,实际上没有特别的,根据芯片的说明书来做就好,还可以问一问GPT大仙。
6、整体的反应用时钟中断来做,这样速度才能跟上。

这是获得的数据,大家可以分析

x0 y0 pidx pidy
21.1 -45.8 19.3 -39.56
31.1 -45.8 32.23 48.89
31.1 -45.8 -1.45 -9.86
51.1 -45.8 -54.12 -36.4
91.1 -45.8 -57.7 -85.57
-58.9 -35.8 -65.46 147.87
-38.9 -35.8 57.12 83.73
-38.9 -35.8 27.01 63.51
-28.9 -35.8 -22.42 32.96
-18.9 -35.8 21.54 43.87
-8.9 -35.8 39.08 -38.11
-8.9 -35.8 36.05 72.83
1.1 -35.8 76.28 -1.43
1.1 -35.8 -12.02 -14.98
1.1 -35.8 -10.37 16.5
1.1 -35.8 -11.71 57.34
11.1 -35.8 -42.37 40.45
11.1 -35.8 9.08 -64.33
11.1 -35.8 6.93 18.81
11.1 -35.8 -13.6 -7.18
11.1 -35.8 -7.26 34.57
11.1 -35.8 -14.27 44.8
21.1 -35.8 -14.75 35.43
21.1 -35.8 -33.01 -24.24
31.1 -35.8 18.18 -8.75
51.1 -35.8 42.85 91.34
51.1 -35.8 -8.43 12.73
-38.9 -25.8 -57.49 41.12
-18.9 -25.8 -1.04 23.13
-8.9 -25.8 44.41 57.94
-8.9 -25.8 43.26 105.96
-8.9 -25.8 -33.78 34.68
-8.9 -25.8 -6.25 73.72
-8.9 -25.8 13.28 50.95
-8.9 -25.8 31.58 26.07
-8.9 -25.8 0.01 86.18
-8.9 -25.8 -0.76 43.64
-8.9 -25.8 13.1 27.06
1.1 -25.8 103.7 70.14
1.1 -25.8 29.29 41.91
1.1 -25.8 8.52 12.27

下面是代码,包含了注释和制作过程,所以非常值


#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_VL53L0X.h>

float geta00,geta01;     //原点
float geta0,geta1,geta2; //获取的数据
float getas0,getas1;     //getas0=geta0-geta00;
float geta10s0,geta10s1; //geta00=(float)geta10s0/(float)read10;
int   geta10i=0;         //读书数据次数
float getapid0,getapid1; //获取pid值
int geti=0;
int chei,ultrasonic_x_i;
float ultrasonic_x_old;
int pinultrasonic=12;
uint16_t Infrared_ranging=0;
int Infraredranging_ultrasonic=0;
int timer2_maglev_i=0;


// 定义霍尔传感器输入引脚
int Pina0 = A1; 
int Pina1 = A2; 
int Pina2 = A4; 
int Pina2i = 0; 

int encoderPin1A = 2;
int encoderPin1B = 8;
int encoderPin2A = 3;
int encoderPin2B = 11;
long encoderCount1 = 0;
long encoderCount2 = 0;
float encoderspeed1 = 0;
float encoderspeed2 = 0;
float millisold=0;
// 定义pwm电磁铁输出引脚 
int pwm0 = 9;
int pwm1 = 10; 

volatile uint16_t adcValue0; // 定义一个全局变量来存储ADC通道0的读数
volatile uint16_t adcValue1; // 定义一个全局变量来存储ADC通道1的读数
volatile uint16_t adcValue2; // 定义一个全局变量来存储ADC通道2的读数
bool getadbValues100=false;//是否读最初值,开始算pid
bool geta2Values=false;//是否有磁铁来


struct _pid{
    float SetSpeed;            //定义设定期望值,目标值
    float ActualSpeed;         //定义实际值
    float Proportion_err;      //定义比例误差
    float err;                 //定义偏差值
    float err_last;            //定义上一个偏差值
    float err_lastlast;        //定义上上一个偏差值
    float Kp,Ki,Kd;            //定义比例、积分、微分系数
    float voltage;             //定义电压值(控制执行器的变量)
    float integral;            //定义积分值
    float isintegral;          //是否积分
    float derivative;          //计算微分项
    float u;                   //本次输出
    float umax;
    float umin;
    float elapsedTime;        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值