项目需求:
- 通过MSP430的IIC管脚实现NST112温度传感器数据的采集加热电阻的温度
- 通过MSP430控制MOS开断从而控制通过加热电阻的电流
- 通过ADC采集外部电压的大小从而实现按键功能
- 通过PID实现温控功能
项目背景及目标:
之前没有接触到MSP430系列的开发,做过STM32HAL库的一些简单程序的设计开发。
在这次项目中对于PID有了一定的认识。
计划实现尽快达到目标温度并保持温度在目标温度附近。
开发工具选择:
CCS:Code Composer Studio 是 TI 微控制器和处理器的集成开发环境 (IDE)。它包括一套用于开发和调试嵌入式应用程序的工具。Code Composer Studio 可在 Windows®、Linux® 和 macOS® 桌面上下载。
Arduino:利用Platfrom插件在VScode上实现程序编写、编译、下载
项目设计思路:
使用MSP430核心板搭配具有LCD显示、ADC按键、加热电阻、温度采集芯片灯功能的扩展板实现具有恒温控制功能,温度可设置并实时进行数据显示的温控系统。
通过NST112实现加热电阻温度的测量,通过MCU进行数据处理之后控制加热电阻通过电流的大小实现温控的功能。
软件流程图:
硬件平台简介:
支持 USB 2.0 的 MSP430F5529 16 位微控制器
- 高达 25 MHz
- 128KB 闪存和 8KB 内存
- 12 位 SAR 模数转换器
- 提供各种 USB 设备类示例和嵌入式软件库(CDC、HID、MSC)
- eZ-FET lite:带应用程序 UART 的开源板载调试器
- 通过使用板载 USB 集线器,为仿真器和目标提供 USB 连接
- USB 作为电源:5V 和 3.3V 通过高效 DC/DC 转换器
- 40 针 LaunchPad 标准,利用 BoosterPack 生态系统
NST112:SOT563超小封装高精度低功耗I2C接口数字温度传感器
加热电阻:
通过开关MOS管实现加热电阻的电流通断,实现温度的控制。
ADC按键:
通过原理图发现ADC按键已经进行了硬件消抖,方便在软件上的编写。
实现的功能:
1.温度采集及在屏幕显示
代码片段:
//NST112
#define NTC_I2C_ADDR 0x48 //i2c地址
#define REG_ADDR 0x00 //寄存器地址
float get_temp();
void write_reg();
//将数据写入寄存器
void write_reg()
{
Wire.beginTransmission(NTC_I2C_ADDR);
Wire.write(REG_ADDR); //写入寄存器地址
Wire.write(0x20); //发送的数据
Wire.endTransmission();
}
//从NST112传感器读取温度
float get_temp()
{
uint8_t buff[2];
float volt;
float temp;
//从设备读取数据
Wire.requestFrom(NTC_I2C_ADDR,2);
if(Wire.available()){
buff[0] = Wire.read();
buff[1] = Wire.read();
}
return buff[1];
}
2.可设定温度
在屏幕驱动选择上,出现了MSP的gcc编译器不支持的情况,在通过与群友讨论过程中发现Uglib可以正常驱动,并且扩展版屏幕SPI接口与MSP430板卡硬件SPI相接,可以实现较高的刷新速率。
unsigned long keyTick = 0;
int adc_volt = 0;
void ADC_key()
{
if(millis() - lcdTick < 10) return;
lcdTick = millis();
adc_volt = analogRead(P6_0);
if(adc_volt > 1500 && adc_volt < 2100)
{
set_temperature -= 10;
// kp -= 0.1;
}
if(adc_volt > 2300 && adc_volt < 3000)
{
set_temperature += 10;
// kp += 0.1;
}
}
//LCD显示
void LCD_init()
{
ucg.begin(UCG_FONT_MODE_TRANSPARENT);
ucg.clearScreen();
}
uint32_t lcdTick = 0;
void LCD_Process()
{
if(millis() - lcdTick < 10) return;
lcdTick = millis();
ucg.clearScreen();
ucg.setRotate90();
ucg.setFont(ucg_font_7x13_tf);
ucg.setColor(255, 255, 255);
ucg.setColor(1, 255, 0,0);
ucg.setPrintPos(5,10);
ucg.print("automatic control system");
ucg.setFont(ucg_font_9x18_mf);
ucg.setPrintPos(5,40);
ucg.print("actual_temp:");
ucg.setFont(ucg_font_9x18_mf);
ucg.setPrintPos(85,60);
ucg.print(temperature_read);
ucg.setFont(ucg_font_9x18_mf);
ucg.setPrintPos(5,80);
ucg.print("set_temp:");
ucg.setFont(ucg_font_9x18_mf);
ucg.setPrintPos(85,100);
ucg.print(set_temperature);
ucg.setFont(ucg_font_9x18_mf);
ucg.setPrintPos(5,120);
ucg.print(kp);
ucg.setFont(ucg_font_9x18_mf);
ucg.setPrintPos(90,120);
ucg.print(kd);
}
3.PID控制
在PID调节中设定三个参数,比例参数Kp、积分参数ki、微分参数kd
在目标值与实际值偏差的数值超过2.60时进行pi的计算。
PID_value = PID_p + PID_i + PID_d;
最后将数值转化为PWM的脉冲宽度实现温度控制。
uint32_t pidTick = 0;
void PID_Control()
{
temperature_read = get_temp();//读取温度传感器数据
PID_error = set_temperature - temperature_read;//计算偏差
PID_p = kp * PID_error;//kp调节
//Calculate the I value in a range on +-2.6
if(-2.60 < PID_error <2.60)
{
PID_i = PID_i + (ki * PID_error);
}
//For derivative we need real time to calculate speed change rate
timePrev = Time; // the previous time is stored before the actual time read
Time = millis(); // actual time read
elapsedTime = (Time - timePrev) / 1000;
PID_d = kd*((PID_error - previous_error)/elapsedTime);
PID_value = PID_p + PID_i + PID_d;
if(PID_value < 0)
{ PID_value = 0; }
if(PID_value > 255)
{ PID_value = 255; }
analogWrite(V_HEAT,PID_value);
previous_error = PID_error; //Remember to store the previous error for next loop.
}
遇到的问题:
PID控制
pid调节,在网上搜集资料时发现大部分PID系统都是针对于飞行控制、平衡车等项目,后来发现了使用热电偶以及3D打印机喷头构成的温控系统,在调节初期时发现总是无法达到目标数值,后来查资料了解了PID各部分参数的意义,将程序进行了修改,通过arduino的串口绘图仪对数据进行可视化展示及通过串口对PID各部分数值进行调节并在最后实现在较快的时间内达到设定温度并保持温度在设定温度附近。
在进行PID参数的调节过程中,因为没有进行过参数的调节,在调节的过程中,达到目标温度时间过长,或者在目标温度附近发生幅度大于3的震荡,明显不符合要求,后来经过查找,发现PID中比例可以适当调大,到达目标温度后出现幅度小于2的超调,通过微分的调整使程序能够尽可能的接近目标设定值。
开发环境,由于对于CCS开发环境不熟悉,出现了很多问题,时间比较紧张,于是决定使用Platform开发平台来对MSP430进行开发。
未来的计划:
改进温控算法使温控系统能够更快更稳定。
小总结:通过这次对MSP430的学习使我对PID有了初步的认识,能够理解PID各部分的功能。学会使用串口绘图仪对数据进行可视化处理。