杨枝小甘露
杨枝小甘露
发布于 2020-10-02 / 13 阅读
0
0

毕业设计记录

1、选题

《基于无线传感网的智能灌溉系统的研究与设计》

两个关键词:

1)无线传感网:具有感知、处理和无线通信能力的微型节点构成的网络

2)智能灌溉系统:其智能体现在,这个系统可以通过一定的编程,处理环境信息和人工指令,并基于信息处理结果,来控制是否灌溉、何时灌溉、灌溉水量等。

1)什么是智能灌溉系统?简单介绍

智能灌溉系统是一种基于物联网和传感器的自动化灌溉解决方案,通过传感器实时采集环境参数,结合数据与远程控制技术,监控灌溉

智能灌溉系统,其智能体现在,这个系统可以通过一定的编程,处理环境信息和人工指令,并基于信息处理结果,来控制是否灌溉、何时灌溉、灌溉水量等。

2)为什么要选这个题目?

1、具有现实意义,农业灌溉效率低、水资源浪费严重

2、符合专业毕业设计要求



2、简单介绍项目

以MSP430F149 芯片为核心,集成风速、风向及土壤 PH 值传感器,通过内置/外置 A/D 转换模块处理信号,结合 ESP8266 WiFi 模块实现环境数据远程传输至手机端,并利用 OLED 屏实时显示监测信息。

3、项目流程

1)分析项目

分析项目:要完成这个毕业设计,其核心就是一个可以集成多种传感器、并处理传感器信号的芯片。同时芯片还要具有控制电信号的能力,以达到“智能灌溉”的控制灌溉的目的,即输出一个水阀控制信号。

2)确定系统大致流程需要主芯片,几个传感器,液晶P显示OLED

芯片工作电压是3.3V,设计时用电脑USB接口供电。不同的模块需要接的电源也不一样。风速风向传感器接15V的电源适配器,Wifi模块和液晶显示模块接3.3V电源,PH值传感器模块接5V电源,A/D模块接入5V电源。

a.主芯片

主芯片选择:

本科生完成这个项目,只是一种实验研究,不需要拿出具体的可商用成品,因此技术选型上:

  1. 芯片应当具有较成熟的生态,要能兼容通用传感器
  2. 采购物料时,要能购买到该芯片的开发板,以有助于完成毕业设计
  3. 芯片应当避开STM32这种大众化的芯片,以避开查重

为什么没有用stm32芯片?

芯片选用MSP430,这是德州仪器的一款16位单片机芯片。相比于STM32,这个芯片的优势在于,16位芯片的功耗要更低。并且16位芯片的性能实现选题中所需要的功能已经足够了。

MSP430F149劣势?

当然劣势就是这个芯片在国内的资料较少,如果需要学习,最好的途径是直接打开德州仪器的官网,搜索MSP430F149,下载用户指南。

打开:https://www.ti.com.cn/zh-cn/microcontrollers-mcus-processors/msp430-microcontrollers/products.html

然后在这里筛选型号

MSP430F149常识

省去了我们引出IO口和AD电源的工作,可以通过USB下载程序。并且有一个标准 JTAG 接口(14 针), 支持硬件仿真。

tips-01-USB串口用途

USB可以下载程序是因为开发板的厂家在板子上集成了一块BSL。这样连接到电脑就可以被识别为一个CH340的COM串口。

但如果我们要通过串口通信,此时USB默认被BSL占用,无法将其他设备通过USB与芯片进行串口通信,我们就需要跳线来使用串口功能:


(一)ADC12 - AD转换模块(模数转换)

ADC12是MSP430芯片自带的模数转换模块,有8个引脚,芯片内部编号为A0-A7,可以读取8个电压信号。

外部端口为P6,引脚为P60-P67。

代码操作P6SEL寄存器。寄存器8位二进制,每一位操作对应的引脚开关。0/低位为关,1/高位为引脚使能。

代码实现:

定义:

定义缓冲区数组,AdBuff[4]

AdBuff 是一个 long 类型(4 个元素) 的数组,在 ADC 采样代码中,它用于存储 ADC 采样值(即电压值)控制采样等待逻辑

long AdBuff[4];  // 用于存储 ADC 采样数据

其中AdBuff[3]用来存放当前读取的电压值,每次读取都会被更新。

AdBuff[0] ~ AdBuff[2]用来存放对应的引脚的电压结果。


定义函数:

定义unsigned long SysAdDetect(uchar ch)

用来读取ADC12模块对应通道的数字信号,即电压值,避免重复代码

把电压值存入AdBuff数组对应的位置,如P60引脚电压值存入AdBuff[0],单位是mV毫伏,long整型。

P6SEL寄存器操作代码解析:

P6SEL |= (0x01<<ch);

P6SEL的值的变化控制了引脚启用,当P6SEL的第x位为高电平时,表示P6.x引脚生效,此时ADC12模块的存储寄存器中读取的就是该引脚(P6.x)的电压。

存储寄存器名称:ADC12MEM0

unsigned long SysAdDetect(uchar ch)
{
    P6SEL = 0;
    AdBuff[3] = 0;
    AdBuff[ch] = 0;
    P6SEL |= (0x01<<ch);                            // 使能ADC通道
    ADC12CTL0 = ADC12ON + SHT0_8 + MSC;           // 打开ADC,设置采样时间
    ADC12CTL1 = SHP+CONSEQ_2;                 // 使用采样定时器
    ADC12IE = 0x01;                           // 使能ADC中断
    ADC12CTL0 |= ENC;                         // 使能转换
    ADC12CTL0 |= ADC12SC;                     // 开始转换
    _EINT();
    while((AdBuff[3]==0)&&(AdBuff[ch]<=10000))
    {
         AdBuff[ch]++;
    }
    if(AdBuff[ch]>=10000)
    {
        AdBuff[ch]=0xFFFFFFFF;
    }
    else
    {
        AdBuff[ch]=AdBuff[3];
    }
    P6SEL  =0;
    ADC12CTL0 &=~(ADC12ON+SHT0_8+MSC);           // 打开ADC,设置采样时间
    ADC12CTL1 &=~(SHP+CONSEQ_2);                 // 使用采样定时器
    ADC12IE   &=~0x01;                           // 使能ADC中断
    ADC12CTL0 &=~ ENC;                         // 使能转换
    ADC12CTL0 &=~ADC12SC;                     // 开始转换 
    _DINT();
}

b.模块与传感器选型

ESP8266

ESP8266是一种集成了 Wi-Fi 功能的低成本无线通信模块,主要用于实现设备的网络连接和数据传输。其核心功能是通过 Wi-Fi 协议与互联网或局域网通信,支持 TCP/IP 协议栈,能够将传感器数据上传至云端或手机端,或接收远程指令,从而实现物联网(IoT)应用的无线控制与监控。

为什么不能直接在 MSP430 开发板上使用 Wi-Fi 模块?

  1. 硬件资源限制
    MSP430 是超低功耗微控制器,设计重点在于低能耗而非复杂通信。其外设接口(如 UART、SPI)和内存资源有限,可能无法直接驱动高带宽或协议复杂的 Wi-Fi 模块。ESP8266 需要稳定的串口通信(UART)和协议解析能力,而 MSP430 的实时处理能力可能不足。
  2. 协议栈与软件支持
    Wi-Fi 模块需运行完整的网络协议栈(如 TCP/IP、HTTP),而 MSP430 的存储空间(Flash/RAM)较小,难以承载复杂的网络协议和数据处理代码。ESP8266 内置协议栈,可通过 AT 指令简化控制,但仍需主控芯片具备较强的指令解析能力。
  3. 电源与功耗
    ESP8266 在通信时功耗较高(峰值电流可达 200mA+),而 MSP430 通常用于低功耗场景(如电池供电)。直接连接可能导致电源不稳定或超出开发板的供电能力。
  4. 接口兼容性
    ESP8266 默认通过 UART 通信,需占用 MSP430 的串口资源。若开发板未预留足够接口,或未配置电平转换电路(如 3.3V-5V),可能导致通信失败。

解决方案
若需在 MSP430 上使用 Wi-Fi 功能,可通过以下方式实现:

  • 模块化设计:将 ESP8266 作为独立通信单元,通过 UART 与 MSP430 交互,仅传输关键数据。
  • 简化协议:使用 AT 指令控制 ESP8266,减少 MSP430 的协议处理负担。
  • 电源管理:为 ESP8266 提供独立电源或优化供电电路,避免影响主控稳定性。
  • 软硬件优化:选择低功耗模式(如 ESP8266 的 Deep Sleep)并优化代码,平衡功能与能耗。

通过合理设计,MSP430 与 ESP8266 可以协同工作,但需在资源分配、功耗控制和通信协议上进行针对性优化。

原理

ESP8266的三种工作方式

AP模式(热点模式)- ESP8266 模块作为热点,手机wifi设置里可以搜到

STA模式(基站模式)- ESP8266 模块作为客户端,通过串口控制指令连接手机热点/其他wifi

AP和STA共存模式(不考虑)

AT指令设置ESP8266模式

前期工作:将ESP8266-01模块与“串口转USB工具”连接好,连接电路图下图所示,多检查几次注意线是否接好。

我们用了5条线进行连接,要注意,ESP8266的CH_PD引脚一定要接3.3V高电平,否则模块不能工作!

例1-模块在AP模式下做TCP Server,也就是ESP8266当做热点,并成为一个TCP Server让别人来加入。

在串口调试助手上依次输入以下AT指令,要注意选择发送新行(否则有可能发什么在串口工具上返回什么),串口波特率默认为115200, 当模块在AP模块下做TCP Server时,默认的IP 为 192.168.4.1, 端口可自己设定为 8899(默认为 333),通过手机网络调试助手设置ip地址和端口号,分别进行接收和发送数据,如下面几幅图所示。

通过控制字(即通过两根串口引脚发送特定的数据),来配置ESP8266。

配置好后,模块和手机通过TCP协议通信,发送文本。

AT                         //测试模块正常工作                  

AT+CWMODE=2                //设置AP模式

AT+CWSAP="ESP8266Test","13141516",11,0   //设置AP名称和密码,设置后在手机端可以搜到

AT+CIPMUX=1                //设置多连接

AT+CIPSERVER=1,8899        //设置端口号,这个端口号在手机网络调试助手上要用到。
AT+CIPSTART="TCP","192.168.1.115",8899 // 设置IP地址和端口

AT+CIPSEND=0,10            //发送10个字节数据

手机操作:

首先连刚才在ESP8266上配置的热点:

连上以后打开TCP客户端软件,应用商店下的,一般叫网络助手之类的名字。

手机启动TCP客户端,连接刚才在ESP8266里配置的TCP服务端。填写IP地址和端口,连接后就可以发送和接收数据。

此处遇到的困难

初始化串口、设置波特率

解决方案:找厂商要资料,要样例,和特定的波特率,然后根据样例不断调整

PCF8591

为什么要使用PCF8591芯片连PH值传感器

PCF8591是外置A/D转换模块

1、资源优化:解决MSP430F149内置ADC(模数转换)通道或资源不足的问题

2、简化系统减少自定义电路设计复杂度,有可扩展性,为未来升级提供硬件冗余。

3、高精度要求:PH值的微小变化(如±0.1)可能对作物生长产生显著影响,其他传感器(如风速传感器)可能对精度要求较低或直接输出数字信号。且成本低

风速传感器

电流型输出信号转换计算

量程030m/s,420mA输出,当输出信号12mA时,计算当前风速。风速量程的跨度为30m/s,用16mA电流信号来表达,30m/s/16mA=1.875m/s/mA,即电流变化1mA风速变化1.875m/s.那么可以计算测量值测量值12mA-4mA=8mA.8mA*1.875m/s/mA=15m/s,则当前的风速=15m/s.

电压型输出信号转换计算

量程0~30m/s,以0-10V输出为例,当输出信号为5V时,计算当前风速。风速量程的跨度为30m/s,用10V电压信号来表达,30m/s/10V=3m/s/V,即电压每变化1V对应风速变化3m/s.测量值5V-0V=5V。5V*3/m/s/V=15m/s。则当前风速为15m/s。

风向传感器

量程0~360,以0-10V输出为例,当输出信号为5V时,计算当前风向。风向量程的跨度为360,用10V电压信号来表达,360/10V=36/V,即电压每变化1V对应风向变化36度.测量值5V-0V=5V。5V*36/V=180度。则当前风向为180度。

3)确定硬件电路设计,设计引脚,接线

先确定引脚,一次接几个引脚,然后写部分代码

一共有:风速传感器模块、风向传感器模块、PH值传感器模块、外置独立A/D模块、wifi模块、液晶显示模块

4)用IAR编写芯片代码

开发框架

该单片机使用较多的编程环境有IAR和CCS。

CCS是TI自己推出的开发编译环境,然而大学中IAR用的比较多,所以选择IAR。

IAR和C的区别:IAR很多写法和C语言不一样,有些输入输出引脚需要查表,学习新api,在while循环里通过iar提供的api,编写引脚判断条件


如何编写程序的

定义常量,定义管脚(SCL和SDA)高低电平——SCL(时钟信号)和SDA(数据信号)在 I2C 总线上,主设备通过控制这两个信号线来实现对从设备的控制和通信。

I2C 通信:设置I2C(串行总线,半双工通信方式)相关函数(起始、终止、有无应答,发送数据,读写数据)

****串口通信:初始化串口、发送串口数据(UART串口用于数据传输)

ADC采集:包含读取ADC转换值、读取PCF8591传感器数值

OLED****:在 OLED 屏幕 指定位置显示字符串信息。

wifi:

通过 ESP8266 WiFi 模块,将 风速、风向、PH 值 发送到 手机端 或 服务器

  • 通过 UART0 向 PC 或 ESP8266 发送字符串数据
  • 通过 UART1 向 WiFi 模块 发送数据。

主函数:

初始化 系统时钟、串口、OLED

循环定期读取传感器的传来的数字信号的值,调用ADC函数处理数字信号的值,读取值映射,调用oled和ESP8266函数,将结果展示在OLED 显示屏 ,并通过wifi模块实现无线传输

进入 <font style="color:#000000;">while</font> 循环,定期采集风速、风向、PH 值,并通过 OLED 显示 + 串口发送。

5)仿真与调试

4、难点:

1)对于OLED屏幕显示的问题

当时厂家给的OLED屏幕教程只涉及数字和英文字母,有一个困难点就是如何显示中文

通过自己上网搜索,问厂家,然后他们推荐了一个PCTOLCD2002,可以取字模,那我需要的就是把我所要涉及到的所有的汉字取字模,把中文字模放到oled的头文件里面

主函数调用oled显示屏幕的时候,又遇到问题,就是字有重影,还是中间有条线切割,倒着的。然后又是各种找资料发现本质上oled的显示字符的原理是用点亮点阵的来实现的,那么字符重影的问题就是相邻字的间距太小了,于是去主函数调整字符间距,并且在取字模的时候,需要设置取模走向和取模方式,比如我每个字的空间是8*16,那我第一个字符位置0~8,第二个字符位置就从10~18,然后解决了这个问题

收获就是,学习的过程就是边实践,在实践中遇到问题再去解决问题,才能真学会,学了一些嵌入式开发的知识

2)对于PCF8591的读取字节过程。 如何设置外置的A/D转换模块

/********************************************************************
函数名称:read1byte
功    能:从I2C总线读取一个字节
参    数:无
返回值  :读取的数据
********************************************************************/
uchar read1byte(void)
{
	uchar ReadData = 0x00,i;
        uchar flag;    
	for(i = 0;i < 8;i++)
	{
            SDA_H;
            delay_us(5);
            SCL_H;
            SDA_IN;
            delay_us(5);
            flag = SDA_VAL;//菜端起来
            ReadData <<= 1;//转桌子
            if(flag)	ReadData |= 0x01;//放菜
            SDA_OUT;
            SCL_L;
            delay_us(5);
	}

	return ReadData;
}

读取一个字节时

PCF8591按位发送,MSP430按位接收

画板

3)OLED如何平衡传感器读取和屏幕刷新的问题

**一开始,为了在OLED上显示传感器值变化的内容****,**设置一个buton值(0表示有信号输入,1表示没信号输入 ),初始置1(西风),后面判断,如果有信号输入,button置0(东风),刷新屏幕,此时出现问题,只有在第一次有信号变化时,屏幕会刷新。后面每次信号变化都不再刷新,值不再变化;

**分析原因****:**虽然外层while(1)一直在循环,一直在读取信号,但是由于上述程序是覆盖信号,覆盖只有第一次有效

设想情况:1、读一次传感器刷新一次(问题:不管输入信号变没变,都一直刷新,刷新次数太多,屏幕不停地闪)

2、设置delay,读一次等一秒再刷(不能根本解决问题,屏幕还会闪,显示屏幕delay会影响输入信号,程序在执行耗时动作在等,不会响应其他信号)

**最后尝试取非做法****:**在while(1)函数最外层定义previousbutton这个前次状态变量,默认置1(西风),在循环函数内部,判断传感器信号是否发生改变的条件为,本次接收的变量button是是否和前次状态previousbutton相同,若不同,说明输入信号发生改变,再去刷新屏幕,这样减少了屏幕刷新次数

5、总结项目成败,如何优化

成功点:1、OLED和手机上确实显示了数据,达到目标

2、自己代码能力有所提升,了解了这些芯片和器件

3、学习的过程

优化点:1、把灌溉系统做成可自主配置的,可以多接入一些传感器,检测哪些参数由管理者自主调节控制

2、可以接水泵,通过算法检测控制浇水

3、可以通过软件结合Ai给一些浇灌合理建议


评论