文章目录
- 0 前言
- 1 简介
- 2 主要器件
- 3 实现效果
- 4 硬件设计
- LoRa发射器:土壤湿度传感器+AHT10温湿度传感器
- LoRa接收器:Lora Radio (433M/868M/915M)
- 设置Lora土壤湿度发射器
- 设置Loara接收器
- 5 软件说明
- 发射器代码
- 接收器的代码
- 5 最后
0 前言
🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
1 简介
本项目中介绍如何制作基于物联网LoRa的智慧农业和远程监控系统。智慧农业意味着监测影响作物生产的环境条件以及跟踪牲畜健康指标。基于LoRa的农业物联网技术可提高效率,减少对环境的影响,最大限度地提高产量并最大限度地减少开支。基于LoRa设备和LoRaWAN协议的智慧农业用例已经表现出明显的优势,例如商业农场的用水量减少了50%。
该项目使用LoRa土壤湿度传感器电路板模块,该模块基于Atmega328P微控制器、LoRa模块RFM95和AHT10温湿度传感器。AHT10温湿度传感器测量当地空气温度和湿度。电容式土壤湿度传感器测量土壤湿度。所有测量数据都可以无线发送至15公里的距离,并且可以被接收器读取。发射器和接收器都是使用LoRa模块设计。
2 主要器件
- AHT10土壤湿度传感器发射器
- LoRa接收器
- USB转UART模块(FTDI模块)
- AAA电池
- Micro-USB数据线
3 实现效果
打开发送器和接收器的串口监视器。Lora发射器和接收器将启动并相互通信。
发射器将读取土壤湿度数据,该数据可以转换为百分比值。同样,AHT10将收集空气湿度和温度数据,然后传输到Lora网关。
发射器发送数据后进入深度睡眠模式或省电模式。在数据传输模式下,它消耗大约0.2mA的电流。在省电模式下,电流降低至0.75µA。通过增大数据传输的间隔,电池寿命可以增加到几个月。
4 硬件设计
LoRa发射器:土壤湿度传感器+AHT10温湿度传感器
发射器电路板由Lora土壤湿度传感器和AHT10温湿度传感器组成。该电路板使用的微控制器是支持Arduino编程的Atmel的Atmega328P。AHT10传感器收集当地空气温度和湿度。电容式土壤湿度传感器检测土壤湿度。该传感器基于555定时器。Lora无线接收器和发射器必须采用相同的工作频率。否则,它不会从另一个接收任何数据。发射器使用LoRa模块RFM95将本地环境数据传输到网关。
Lora发射器由一对AAA电池供电。设备每隔几分钟定期传输数据,然后进入睡眠模式以节省电池电量。根据代码和硬件设置,这项传感器功能可以关闭,或者只在短时间内开启。因此,由于睡眠模式和低功耗模式,电池寿命可以延长几个月。电容式土壤湿度传感器涂有防水涂料,因此即使传感器长时间浸入土壤中也不会产生任何腐蚀作用。该模块适用于智能农场、灌溉、农业等应用。
ATmega328芯片集成了Arduino引导加载程序,因此可以使用Arduino IDE轻松编程。我们只需要一个USB转TTL转换器模块。
LoRa接收器:Lora Radio (433M/868M/915M)
Lora Radio接收器是基于ATmega328和433MHZ/868MHz/915MHz RFM95 LoRa模块的主板。LoRa Radio接收器允许用户以低数据速率发送数据并达到极远的范围。它提供超长距离扩频通信和高抗干扰性,同时最大限度地减少电流消耗。它在此板上具有Arduino pro mini 3.3V 8MHz引导加载程序,并使用CP2104作为USB转串口使用Arduino IDE上传代码。在这个LoRa智慧农业项目中,我们将使用它作为接收器网关。
设置Lora土壤湿度发射器
为了将代码上传到发射器,需要焊接一个5针的插头。所以首先在这里焊接插头。
现在您需要连接USB转UART模块以使用Arduino IDE上传Atmega328的代码。请注意,USB转UART转换器中的DTR需要连接到复位引脚。如果没有DTR,您可能需要手动按下复位按钮来上传代码。
在模块背面安装AAA电池。
现在为了使用Arduino IDE对Lora传感器电路板进行编程,在Arduino IDE中选择默认的一个电路板。从顶部的Arduino IDE菜单中,选择Tools-> Board-> Arduino Pro 或 Pro Mini。同时选择Tools-> Processor-> Atmega328P(3.3V,8Mhz)。
设置Loara接收器
Lora接收器不需要USB转UART模块,因为它可以使用Micro-USB数据线直接编程。
该板使用相同的电路板型号进行编程。所以在Arduino IDE中选择Arduino Pro 或 Pro mini以及ATmega328P (3.3V,8Mhz) 处理器。
5 软件说明
发射器代码
使用Lora发射传感器数据的代码共分为3个文件:Main.ino、I2C_AHT10.cpp和I2C_AHT10.h文件
在编译代码之前需要将RFM95库添加到Arduino IDE中。因此,从下面的链接下载RFM95库并将其添加到库文件夹中。
根据您使用的电路板修改Lora频率的宏定义是433Mhz还是868Mhz还是915Mhz。
如果你的Lora电路板是433MHz:
#define RF95_FREQ 433.0
Main.ino
#include <SPI.h>
#include "RH_RF95.h"
#include "I2C_AHT10.h"
#include <Wire.h>
AHT10 humiditySensor;
int sensorPin = A2; // select the input pin for the potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor
int sensorPowerCtrlPin = 5;
void sensorPowerOn(void)
{
digitalWrite(sensorPowerCtrlPin, HIGH);//Sensor power on
}
void sensorPowerOff(void)
{
digitalWrite(sensorPowerCtrlPin, LOW);//Sensor power on
}
#define RFM95_CS 10
#define RFM95_RST 4
#define RFM95_INT 2
// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 433.0
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);
void setup()
{
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, LOW);
delay(100);
digitalWrite(RFM95_RST, HIGH);
pinMode(sensorPowerCtrlPin, OUTPUT);
//digitalWrite(sensorPowerCtrlPin, LOW);//Sensor power on
sensorPowerOn();
//pinMode(sensorPin, INPUT);
//while (!Serial);
Serial.begin(115200);
delay(100);
Wire.begin(); //Join I2C bus
//Check if the AHT10 will acknowledge
if (humiditySensor.begin() == false)
{
Serial.println("AHT10 not detected. Please check wiring. Freezing.");
//while (1);
}
else
Serial.println("AHT10 acknowledged.");
Serial.println("Marduino LoRa TX Test!");
// manual reset
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
while(!rf95.init()) {
Serial.println("LoRa radio init failed");
while (1);
}
Serial.println("LoRa radio init OK!");
//rf95.setModemConfig(Bw125Cr48Sf4096);
//Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
if (!rf95.setFrequency(RF95_FREQ)) {
Serial.println("setFrequency failed");
while (1);
}
Serial.print("Set Freq to: ");
Serial.println(RF95_FREQ);
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
// The default transmitter power is 13dBm, using PA_BOOST.
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm:
rf95.setTxPower(23, false);
//dht.begin();
}
int16_t packetnum = 0; // packet counter, we increment per xmission
float temperature=0.0;//
float humidity=0.0;
void loop()
{
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
//float humidity = 6.18;//dht.readHumidity();
// Read temperature as Celsius (the default)
sensorPowerOn();//
delay(100);
sensorValue = analogRead(sensorPin);
delay(200);
if (humiditySensor.available() == true)
{
//Get the new temperature and humidity value
temperature = humiditySensor.getTemperature();
humidity = humiditySensor.getHumidity();
//Print the results
Serial.print("Temperature: ");
Serial.print(temperature, 2);
Serial.print(" C\t");
Serial.print("Humidity: ");
Serial.print(humidity, 2);
Serial.println("% RH");
}
// Check if any reads failed and exit early (to try again).
if (isnan(humidity) || isnan(temperature)) {
Serial.println(F("Failed to read from AHT sensor!"));
//return;
}
delay(100);
//sensorPowerOff();
Serial.print(F("Moisture ADC : "));
Serial.println(sensorValue);
//Serial.print(F("Humidity: "));
//Serial.print(humidity);
//Serial.print(F("% Temperature: "));
//Serial.print(temperature);
//Serial.println("Humidity is " + (String)humidity);
//Serial.println("Temperature is " + (String)temperature);
String message = "#"+(String)packetnum+" Humidity:"+(String)humidity+"% Temperature:"+(String)temperature+"C"+" ADC:"+(String)sensorValue;
Serial.println(message);
packetnum++;
Serial.println("Transmit: Sending to rf95_server");
// Send a message to rf95_server
uint8_t radioPacket[message.length()+1];
message.toCharArray(radioPacket, message.length()+1);
radioPacket[message.length()+1]= '\0';
Serial.println("Sending..."); delay(10);
rf95.send((uint8_t *)radioPacket, message.length()+1);
Serial.println("Waiting for packet to complete..."); delay(10);
rf95.waitPacketSent();
// Now wait for a reply
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
Serial.println("Waiting for reply..."); delay(10);
if(rf95.waitAvailableTimeout(8000))
{
// Should be a reply message for us now
if (rf95.recv(buf, &len))
{
Serial.print("Got reply: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(rf95.lastRssi(), DEC);
}
else
{
Serial.println("Receive failed");
}
}
else
{
Serial.println("No reply, is there a listener around?");
}
delay(1000);
}
接收器的代码
#include <SPI.h>
#include <RH_RF95.h>
#define RFM95_CS 10
#define RFM95_RST 9
#define RFM95_INT 2
// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 433.0
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);
int count=0;
void setup()
{
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
//while (!Serial);
Serial.begin(115200);
delay(100);
Serial.println("Arduino LoRa RX Test!");
// manual reset
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
while (!rf95.init()) {
Serial.println("LoRa radio init failed");
while (1);
}
Serial.println("LoRa radio init OK!");
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
if (!rf95.setFrequency(RF95_FREQ)) {
Serial.println("setFrequency failed");
while (1);
}
Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);
// Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
// The default transmitter power is 13dBm, using PA_BOOST.
// If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then
// you can set transmitter powers from 5 to 23 dBm:
rf95.setTxPower(23, false);
}
void loop()
{
if (rf95.available())
{
// Should be a message for us now
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (rf95.recv(buf, &len))
{
count++;
RH_RF95::printBuffer("Received: ", buf, len);
Serial.print("Got: ");
Serial.println((char*)buf);
Serial.print("RSSI: ");
Serial.println(rf95.lastRssi(), DEC);
// Send a reply
uint8_t data[] = "And hello back to you";
rf95.send(data, sizeof(data));
rf95.waitPacketSent();
Serial.println("Sent a reply");
}
else
{
Serial.println("Receive failed");
}
}
}