IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 上拉式磁悬浮制作经历与踩坑~(基于stm32f103 Arduino 和51没试过,不过应该类似) -> 正文阅读

[嵌入式]上拉式磁悬浮制作经历与踩坑~(基于stm32f103 Arduino 和51没试过,不过应该类似)

最近在做上拉式磁悬浮,但是在csdn还有arduino中文社区上搜了一圈,好像没什么类似的,索性做完后就来记录一下我的经历吧,说不定可以给大家避避雷。

首先放一张常见不常见的几种方案,图片来自阿莫论坛,图中第三种不科学(电磁铁产生的磁场会干扰霍尔,而第二种上下两个霍尔可以抵消这种影响,我刚开始就是踩得这个坑),第四种太过少见也不是很了解。最经常见到的就是第一种和第二种。还用一种是在2的上面放一个磁铁去“拉”下方磁铁以抵消重力(参考下推式的原理)
在这里插入图片描述我自己采用的是第二种,因为这种可以实现一体化(第一种需要上下两个部分。

踩坑:

先说说踩得坑;首先,做上拉式磁悬浮需要一个架子,重点来了,这个架子一定要结实可靠,不然极度搞心态(别问我怎么知道的555)
给大家看一下我的架子,淘宝六块钱买的5跟木头,然后用热熔胶拼的:
在这里插入图片描述
2、一定要共地!
3、板子上有AD的一般可以不用买信号放大器了,我买的是LM358模块,买回来发现没有用处。(32自带的好像是12位ADC,8位ADC的转换精度不确定需不需要,建议看看硬件手册)
4、杜邦线,洞洞板,热熔胶什么的多买点,反正也便宜,以后也能用。省的等快递时间
5、线圈会发热,如果是用热熔胶固定的霍尔元件得注意隔热(我是垫了层木板)

过程:
然后开始加工过程,我朴素的(简陋的)实践经验告诉我,一个这样的系统需要五部分,

  1. 控制部分(MCU,我用的正点原子的32Mini开发板);
  2. 传感部分(我用的线形霍尔503,直接接到板子上的ADC,通过软件滤波,注意32的adc接入电压最好不要超过3.3v);
  3. 驱动部分(我用的L298N成品模块);
  4. 电源部分(我用的一个12v转3.3v,5v的电源模块,外部12v电源是一个3-24v可调电源)
  5. 运动部分(这里是电磁铁,我用的是之前买好的成品线圈 ,有铁芯)

然后将硬件固定到洞洞板上,两个霍尔元件用线引出来(线最好长点)先不要固定。之后将洞洞板固定到架子上,然后先通电调试,之后写代码读取传感器示数 :

我基本上都是用的正点原子的官方代码库,如果有看不懂的可以留言,看见就回。

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "adc.h"
#include "pwm.h"
#include "key.h"

u16 PID_Cal(PID *pp,u16 adc_2,u16 adc_1);
u16 pwm_next_val=0;
   	
 int main(void)
 { 
	u8 t=0;
	u16 adcx,adcx2;
	u32 ERR;
	pp.SetPoint=500; pp.P=12.2;	pp.I=0;	pp.D=29;	 	//这个参数不是很好	
	pp.LastError=0; 
	//float temp;
	delay_init();	    	 //延时函数初始化	  
	uart_init(9600);	 	//串口初始化为9600
	LED_Init();		  		//初始化与LED连接的硬件接口
 	Adc_Init();		  		//ADC初始化	  
  KEY_Init(); 	 
	//TIM1_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz 
	LED0=0;
	while(1)
	{
		adcx=Get_Adc_Average(ADC_Channel_1,3);
		adcx2=Get_Adc_Average(ADC_Channel_2,3);
		printf("显示ADC的值%d\n",adcx);
		printf(" \r\n");
		printf("显示ADC22的值%d\n",adcx2);
		printf(" \r\n");
		ERR = adcx2-adcx;
		printf("差值--上减下%d\n",ERR);
		printf(" \r\n\r\n\r\n\r\n");
		
		delay_ms(200);
		ERR += 1;
		
	}											    
}	

之后连接好两个霍尔,把他们紧挨着放到一块,正常情况下两个应该非常接近(最多相差一二),我之前的霍尔可能是因为焊接的问题,两个的示数相差了几十。
然后把线圈通电,在通电(有磁力)的情况下安装两个霍尔。要求安装固定后两者的差值也要尽可能地小(最多不超过十),然后断电,看看断电后两者的差值如何,如果还是十以内的话就没问题。

之后就是写控制代码了,常见的是PID控制里面的PD控制,不要积分项。关于PID控制算法可以百度下其他文章,我已经枉为自动化学生了55.

比如:
https://www.arduino.cn/forum.php?mod=viewthread&tid=12813&highlight=PID
https://blog.csdn.net/qq_39200996/article/details/81477223
http://openedv.com/forum.php?mod=viewthread&tid=309084&highlight=pid

给大家看一个网上淘来的代码(上拉式真的好少呀):

#include<iom16v.h>
#include<macros.h>
#include"12864.h"
#include"INIT.h"
#include"ADC.h"
#define uint unsigned int
#define uchar unsigned char
int ads,m;
int kp=139;ki=0,kd=260;
int temp=0;
int pid(int input)
{
 	  //输入范围:
	  //输出范围:
 	  static int n1,n2,n3,res;  
	  n1=176-input;
	  res=22+kp*n1/64+kd*(n1-n2);
	  n3=n2;
	  n2=n1;
	  return res;
}

void main(void)
{	
static int shur,diandwn,dianup;
  ADC_init();
  IO_init();
  LCD_init();
  PORTB&=~0x01;
  PORTB|=0x02;
  Delay_ms(200);
  //display_map(QQ);
//  Delay_ms(20000);
  LCD_Clr_All();
  
  while(1)
  {
   		  getdata();
  		 DDRD|=0X30;
		 TCCR1A=0X63;
		 TCCR1B=0X1B;
		 OCR1A=99;
		 shur=AD[1]+AD[2]-129;
		 temp=pid(shur);
		 if(shur<=131)temp=0;
		if(temp>99)temp=99;
		 if(temp<0)temp=0;
		 OCR1B=temp;
	//QF;
  }
}

再给大家看下我的代码,参数没调好,不算很稳定:

typedef struct PID {
	float SetPoint;
	float P;        //
	float I;        // 
	float D;        // 
	int LastError;
	int sumERROR;
} PID;

PID pp;

u16 PID_Cal(PID *pp,u16 adc_2,u16 adc_1);
u16 pwm_next_val=0;
   	
 int main(void)
 { 
	u8 t=0;
	u16 adcx,adcx2;
	u32 ERR;
	pp.SetPoint=500; pp.P=12.2;	pp.I=0;	pp.D=29;	 pp.LastError=0; //2.7,70.1.1,10 pp.SetPoint=500; pp.P=3.1;	pp.I=0;	pp.D=126;
	 //SetPoint=500; pp.P=12.3;	pp.I=0;	pp.D=27
	//float temp;
	delay_init();	    	 //延时函数初始化	  
	uart_init(9600);	 	//串口初始化为9600
	LED_Init();		  		//初始化与LED连接的硬件接口
 	Adc_Init();		  		//ADC初始化	  
  KEY_Init(); 	 
	TIM1_PWM_Init(899,0);//不分频。PWM频率=72000/(899+1)=80Khz 

	while(1)
	{
		adcx=Get_Adc_Average(ADC_Channel_1,3);
		adcx2=Get_Adc_Average(ADC_Channel_2,3);

		if(adcx<1900){
			pwm_next_val=PID_Cal(&pp,adcx2,adcx);
			TIM_SetCompare1(TIM1,pwm_next_val);
		}
		else{
			pwm_next_val = 899;
			TIM_SetCompare1(TIM1,pwm_next_val);
		}
		delay_us(200);
		ERR += 1;
		
		t=KEY_Scan(0);		//得到键值
		switch(t)
		{				 
			case KEY0_PRES:
				LED1 = !LED1;
				printf("显示yixiliePWM的值%d\n",pwm_next_val);
			  printf(" \r\n");
				break;
			case KEY1_PRES:
				break;
			case WKUP_PRES:				
				
				break;
			default:
				break;
		}
	}											    
}	
 
u16 PID_Cal(PID *pp, u16 adc_2, u16 adc_1)
 {
	 
	 int dERROR=0, ERROR=0,mid_pid_val=0;
	 ERROR=pp->SetPoint-(adc_2-adc_1);//当前误差,用于比例计算
	 //pp->sumERROR+=ERROR;            //误差和,用于积分计算
	 dERROR=ERROR-pp->LastError;     //误差偏差,用于微分运算
	 pp->LastError=ERROR;

	 mid_pid_val=300+pp->P*ERROR+pp->D*dERROR;//计算PID的值
	 
	 if(mid_pid_val>0){
		 //GP7 = 0;
		 if(mid_pid_val>899)
		 {
			 mid_pid_val=899;
		 }
	 }
	 
	 else if(mid_pid_val<0){
		 //GP7 = 1;
		 mid_pid_val = 0;
	 }
	 mid_pid_val = 899-mid_pid_val;  //其实是阈值,阈值之前不输出
	 return mid_pid_val;
 }
 

之后就是调pid参数了,每个人的硬件都不同,所以参数也不尽相同,而且我的也一言难尽,不足为训,唯一的一点经验是先调到抖动(类似自控的等幅振荡),之后再慢慢的增大Kd,减小Kp。如有不对还请大佬指出来,感谢。

想到什么其他的了会随后补充~

另外附上图片几张以供参考,还有其他人的我感觉值得参考的我也会贴上链接:

在这里插入图片描述在这里插入图片描述请添加图片描述另外两个链接,感觉他们做的都挺好的:
https://www.amobbs.com/thread-4552606-1-1.html
https://arduino.ncnynl.com/archives/201603/374.html

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-30 12:12:35  更:2021-08-30 12:13:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:57:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码