欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
電賽 簡易智能液體容器制作 附TDS傳感器STM32單片機程序
[打印本頁]
作者:
一只靈
時間:
2023-7-15 22:07
標題:
電賽 簡易智能液體容器制作 附TDS傳感器STM32單片機程序
本設計以STM32F1單片機為控制核心,設計并制作了簡易多功能液體容器.設計主要包括單片機控制模塊、電源模塊、超聲波測距模塊、TDS傳感器模塊、壓力傳感器模塊、顯示模塊。該設計利用超聲波測量液體液位,壓力傳感器測量液體重量;TDS傳感器可檢測水中含有的溶解物,利用TDS值,可以區分不同濃度的鹽水、不同的液體種類。再由兩個OLED屏幕顯示液體液位、重量、濃度、種類等參數。經測試,系統基本完成了要求。
一、系統方案
本系統主要由單片機控制模塊、電源模塊、超聲波測距模塊、TDS傳感器模塊、壓力傳感器模塊、顯示模塊組成。
1.1單片機控制模塊的論證與選擇
方案一:采用STC89C51單片機為主控芯片,單片機只有32個IO口、2個定時器和2個外部中斷,內部RAM為128字節,速度和性能比較低,功能較少,所需外圍電路較多,不考慮此方案。
方案二:采用STM32F103C8T6單片機作為控制芯片。由 ST 廠商推出的 STM32 系列單片機,功能強大,性價比高。STM32F103C8T6最小系統板集成了工作頻率為72 MHz的高性能ARM Cortex -M3 32位RISC內核、高速嵌入式存儲器(最高128字節的閃存和最高20k字節的SRAM),以及連接到兩條APB總線的各種增強型I/o和外設。所有器件都提供兩個12位ADC、三個通用16位定時器和一個PWM定時器,以及標準和高級通信接口:最多兩個I2C和SPI、三個USARTs、一個USB和一個CAN。在可行性與精確度指標上比較過后,決定采用方案二。
1.2顯示模塊的論證與選擇
方案一:采用LCD1602顯示。LCD1602是字符型液晶,顯示字母和數字比較方便,控制簡單,成本較低。內部含有日文平假名、英文字母、數字和一些常用符號字庫,沒有中文字庫。但可以自定義的顯示字符,只有兩行顯示。
方案二:采用OLED顯示。OLED即有機發光二極管,具有自發光,不需背光源、對比度高、厚度薄、視角廣、反應速度快等優點,與LCD1602相比,OLED引腳較少,只有4個引腳,使用簡單,方便。
在可行性上比較過后,決定采用方案二。
1.3測距模塊的論證與選擇
方案一:超聲波測距。本系統采用超聲波傳感器進行液位測距,超聲波具有易于定向發射、方向性好、強度易控制、與被測量物體不需要直接接觸的特點。超聲波對液體、固體的穿透本領很大,尤其是在不透明的固體中,超聲波碰到雜質或分界面會產生顯著反射,形成反射回波使得超聲波測距有較高的準確性。
方案二:光電液位傳感器測距。光電傳感器內部包含一個近紅外發光二極管和一個光敏接收器。發光二極管所發出的光被導入傳感器頂部的透鏡。當液體浸沒光電液位開關的透鏡時,則光折射到液體中,從而使接收器收不到或只能接收到少量光線。光電液位開關通過感應這一變化,接收器可以驅動內部的電氣開關,從而啟動外部報警或控制電路。但光電液位傳感器需要接觸液體,容易受到環境損壞。
在可行性上比較過后,決定采用方案一。
1.4液體濃度和種類檢測的論證與選擇
方案一:TDS傳感器。TDS傳感器可準確測量水中含有的溶解物,水中含有的溶解物越多,TDS值越高。可利用TDS值區分鹽水濃度、不同液體的種類。TDS傳感器配合8 位高性價比單片機,內部已做 AD采集,并通過算法計算出對應的TDS值。
方案二::PH傳感器。PH傳感器可檢測溶液中的PH值,不同的PH值對應不同的輸出信號。PH傳感器配合8位單片機處理器,通過此單片機的10位ADC對放大后的傳感器信號采樣,板載電位器調節輸出信號的量程,并通過最小二乘法軟件算法計算出信號與PH值得線性函數關系式,進而采用線性函數關系式求出信號對應的PH值。但不同濃度的鹽水溶液中PH值差別不大,不能滿足要求。在可行性上比較過后,決定采用方案一。
制作出來的實物圖如下:
new ducument.jpg
(2.62 MB, 下載次數: 46)
下載附件
電賽
2023-7-15 22:01 上傳
單片機源程序如下:
#include "stm32f10x.h"
#include <string.h>
#include "delay.h"
#include "stdio.h"
#include "bsp_SysTick.h"
#include "math.h"
#include "Key.h"
#include "OLED.h"
#include "bsp_adc.h"
#include "ds18b20.h"
#include "timer.h"
#include "bsp_usart1.h"
#include "bsp_usart2.h"
volatile uint32_t time = 0; // ms 計時變量
uint32_t a = 0;
uint32_t b = 0;
uint32_t sta= 0;
////定義變量
GPIO_InitTypeDef GPIO_InitStructure;
unsigned char AD_CHANNEL=0;
float TDS=0.0,TDS_voltage;
float TDS_value=0.0,voltage_value;
float compensationCoefficient=1.0;//溫度校準系數
float compensationVolatge;
float kValue=1.67;
float TEMP_Value=0.0;
float averageVoltage=0;
//char TEMP_Buff[5]; //溫度存放數組
char TDS_Buff[6];
extern u8 SET_Flag,SET_Count; //設置標志位
extern u8 CLC_Flag; //清屏標志位
extern u8 Warning_flag;
u8 Warning_count=0;
// ADC1轉換的電壓值通過MDA方式傳到SRAM
extern __IO uint8_t ADC_ConvertedValue[4];
// 用于保存轉換計算后的電壓值
float ADC_ConvertedValueLocal[4];
void GPIO_Configuration(void)
{
// GPIO_InitTypeDef GPIO_InitStructure;
/* Enable the GPIO Clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);
//GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE); //屏蔽所有作為JTAG口的GPIO口
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //屏蔽PB口上IO口JTAG功能
}
///**************溫度采集函數***************/
//void TEMP_Value_Conversion()
//{
//
// TEMP_Value=DS18B20_Get_Temp();
//
// TEMP_Buff[0]=(int)(TEMP_Value)%1000/100+'0';
// TEMP_Buff[1]=(int)(TEMP_Value)%100/10+'0';
// TEMP_Buff[2]='.';
// TEMP_Buff[3]=(int)(TEMP_Value)%10+'0';
//}
/**************TDS值采集函數***************/
float TDS_Value_Conversion()
{
u32 ad=0;
u8 i;
float compensationCoefficient;
float compensationVolatge;
float temperature=25.0;//假設溫度是25度,進行溫度補償,如果有18B20,則采集溫度后,更新這個溫度值
ad=0;
for(i=0;i<50;i++)//讀取50次的AD數值取其平均數較為準確
{
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));//轉換結束標志位
ad=ad+ADC_GetConversionValue(ADC1);//返回最近一次ADCx規則組的轉換結果
}
ad=ad/50;
//ADC_ConvertedValueLocal[0]=(float)ad/4096*3.3; //AD轉換
averageVoltage =(float)ad/4096*3.3; //AD轉換
// averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 1024.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value
compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation
TDS_value = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value
/*顯示EC*/
TDS_Buff[0]=(int)(TDS_value)/1000+'0';
TDS_Buff[1]=(int)(TDS_value)%1000/100+'0';
TDS_Buff[2]=(int)(TDS_value*100)%100/10+'0';
TDS_Buff[3]=(int)(TDS_value*100)%10+'0';
return TDS_value ;
}
///*************數據顯示函數***************/
//void Display_Data()
//{
// //OLED_ShowStr(24,2,TEMP_Buff,2);//測試6*8字符
// //OLED_ShowStr(36,4,TDS_Buff,2);//測試6*8字符
//}
float TDS_Bugg1[2];
uint8_t Num = 0;
uint32_t Num1=0;
void text1()
{
a=0;
delay_ms(100);
TDS_Value_Conversion();//TDS
delay_ms(100);
TDS_Bugg1[0]=TDS_Value_Conversion();
delay_ms(10);
OLED_ShowNum(2,1,TDS_Bugg1[0],3);
}
void text2()
{
a=1;
delay_ms(100);
TDS_Value_Conversion();//TDS
delay_ms(100);
TDS_Bugg1[1]=TDS_Value_Conversion();
delay_ms(10);
OLED_ShowNum(3,1,TDS_Bugg1[1],3);
if( TDS_Bugg1[0] < TDS_Bugg1[1])
{
OLED_ShowString(1,5,"thick water");
}
else
{
OLED_ShowString(2,5,"light water");
}
}
void text3()
{
a=2;
delay_ms(10);
TDS_Value_Conversion();//TDS
delay_ms(10);
OLED_ShowNum(4,1,TDS_Value_Conversion(),3);
if(TDS_Value_Conversion()>=686||TDS_Value_Conversion()<700)
{
OLED_ShowString(3,5,"water");
}
}
/**
* @brief 主函數
* @param 無
* @retval 無
*/
int main(void)
{
GPIO_Configuration(); //IO口配置
/* 配置USART1 */
USART1_Config();
/* 配置USART2 */
USART2_Config();
/* 初始化系統定時器 */
SysTick_Init();
Key_Init();
TIM3_Init(); //初始化配置TIM
//I2C_Configuration(); //I2C初始化
OLED_Init(); //OLED初始化
ADCx_Init(); // ADC 初始化
adc_init();
OLED_Clear();//清屏
OLED_ShowString(1,1,"TDS:");
//TDS 接A1
//接上串口模塊 A9-RX A10-TX
//波特率115200
//接好后,直接打開串口軟件看輸出TDS值。
//注意,如果啟用溫度補償,需要解開”溫度數據轉換“調用,然后把讀到的值更新到TDS溫度補償值中即可。
//其他OLED顯示是屏蔽了,要是OLED顯示,解開初始和調用函數屏蔽即可。
while(1)
{
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0 && a==0 && sta ==0)
{
text1();
sta = 1;
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0 && a==0 && sta ==1)
{
text2();
sta = 2;
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0 && a==1 && sta ==2)
{
text3();
sta = 3;
}
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0 && sta==3 )
{
text3();
sta = 3;
}
}
}
/*********************************************END OF FILE**********************/
復制代碼
Keil代碼下載:
TDS使用版 源程序.7z
(253.46 KB, 下載次數: 28)
2023-7-16 04:20 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
HZ711+hcsor04源程序.7z
(198.11 KB, 下載次數: 20)
2023-7-16 04:20 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1