Designing a Smart Agriculture Control System Based on CC2530

1. Project Background

Smart agriculture is a rapidly developing field in recent years, aiming to utilize advanced sensing technology, Internet of Things (IoT) technology, and cloud computing technology to achieve automated and intelligent agricultural production management, thus improving agricultural production efficiency and quality. This article designs a smart agriculture control system based on CC2530, using sensors such as DHT11 module, BH1750 module, and soil moisture sensor to upload collected data to the host computer for display via serial protocol.

2. System Framework

This system mainly consists of the following components:

[1] Collection End: Composed of CC2530 microcontroller and various sensors, responsible for measuring environmental temperature and humidity, light intensity, and soil moisture, and uploading the collected data to the host computer for display via serial protocol.

[2] Host Computer: Developed using Qt, responsible for receiving and displaying the data uploaded via serial.

[3] Transmission Medium: Uses serial protocol for data transmission, supports asynchronous communication, and has a data frame structure.

[4] Sensor Module: Includes DHT11 module, BH1750 module, and soil moisture sensor, monitoring and controlling the agricultural production environment by collecting information such as environmental temperature and humidity, light intensity, and soil moisture.

Designing a Smart Agriculture Control System Based on CC2530

Designing a Smart Agriculture Control System Based on CC2530

CC2530 is a low-power wireless system-on-chip (SoC) launched by Texas Instruments, based on the ZigBee protocol, integrated with an ARM Cortex-M3 processor and IEEE 802.15.4 standard wireless communication module, enabling low-rate wireless data transmission and network interconnection. The main features of the CC2530 chip are low power consumption, high reliability, strong flexibility, and ease of integration and development, widely used in wireless data transmission and control systems in fields such as IoT, smart homes, smart meters, and smart lighting.

Designing a Smart Agriculture Control System Based on CC2530

BH1750 is a digital ambient light sensor that can be used to measure light intensity. It has high resolution and sensitivity, and compared to ordinary photoresistors, it has a wider dynamic range and linearity. BH1750 can be connected to microcontrollers or other electronic devices via I2C interface, such as Arduino and Raspberry Pi. It is widely used in night lighting systems, automatic control systems, and security monitoring.

Designing a Smart Agriculture Control System Based on CC2530

DHT11 is a digital temperature and humidity sensor that can measure the ambient temperature and relative humidity. It is commonly used in home and industrial automation, capable of monitoring environmental conditions in various applications.

DHT11 has four pins: VCC (positive power), GND (ground), DATA (data signal), and NC (not used). It can connect to a microcontroller via a single bus interface and outputs temperature and humidity values in digital form. Its temperature measurement range is from 0℃ to 50℃, and humidity measurement range is from 20%RH to 90%RH.

When using the DHT11 sensor, some issues need to be noted. For example, before reading data, the sensor should be powered on and wait for 1 to 2 seconds to stabilize. Additionally, after reading the data, data verification is required to ensure data accuracy.

Designing a Smart Agriculture Control System Based on CC2530

3. System Design

[1] Collection End Design

The collection end consists mainly of the CC2530 microcontroller and various sensors. The temperature and humidity are measured using the DHT11 module, light intensity is measured using the BH1750 module, and soil moisture is measured using a soil moisture sensor. By collecting this information, the environmental state of the farmland can be understood, and adjustments and controls can be made as needed to ensure normal crop growth.

[2] Host Computer Design

The host computer is developed using QT, supporting serial communication and data display. In the configuration of the data transmission port, serial communication adopts asynchronous communication mode, supporting data frame structure, meaning each data packet consists of start bit, data bits, checksum, stop bit, etc., to ensure stability and reliability of data transmission. Meanwhile, the host computer also implements dynamic display of data and historical data query and export functions, facilitating users to analyze and process farmland environmental data.

4. Host Computer Source Code Implementation

Below is the implementation code for reading data from the serial port using Qt:


#include <QCoreApplication>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QSerialPort serial;
    serial.setPortName("COM1");  // Set port number based on actual situation
    if (!serial.open(QIODevice::ReadWrite)) {  // Open serial port
        qDebug() << "Failed to open serial port!";
        return 1;
    }

    // Set serial port parameters
    serial.setBaudRate(QSerialPort::Baud115200);
    serial.setDataBits(QSerialPort::Data8);
    serial.setParity(QSerialPort::NoParity);
    serial.setStopBits(QSerialPort::OneStop);
    serial.setFlowControl(QSerialPort::NoFlowControl);

    while (true) {
        if (serial.waitForReadyRead(1000)) {  // Wait for data
            QByteArray data = serial.readAll();  // Read all data
            qDebug() << "Received data:" << data;  // Print all data

            // Parse data
            QStringList dataList = QString(data).split(",");
            if (dataList.size() == 4) {
                float temperature = dataList[0].toFloat();
                float humidity = dataList[1].toFloat();
                float illumination = dataList[2].toFloat();
                float soilMoisture = dataList[3].toFloat();

                // Print parsed data
                qDebug() << "Temperature:" << temperature << "°C";
                qDebug() << "Humidity:" << humidity << "%";
                qDebug() << "Illumination:" << illumination << "lux";
                qDebug() << "Soil Moisture:" << soilMoisture << "%";
            }
        }
    }

    return a.exec();
}

When reading data, the waitForReadyRead function is used to wait for serial data to arrive, with the parameter indicating the maximum wait time in milliseconds. When parsing data, the QString’s split function is used to separate the data into multiple strings based on commas, and then each string is converted into the corresponding floating-point number.

5. CC2530 Device Side Source Code

[1] BH1750 Data Reading

Below is the code for the CC2530 microcontroller to read the values from the BH1750 light sensor and print them to the serial port:


#include "hal_board_cfg.h"
#include "hal_types.h"
#include "hal_defs.h"
#include "hal_uart.h"
#include "onboard.h"
#include "hal_i2c.h"

#define BH1750_ADDR 0x23  // BH1750 default address

void initUART();
void sendStr(char *str);
void BH1750_init();
uint16 BH1750_read();

void main()
{
    // Initialize
    halBoardInit();
    initUART();
    BH1750_init();

    while (TRUE)
    {
        // Read sensor data
        uint16 illumination = BH1750_read();
        char str[16];
        sprintf(str, "%d", illumination);

        // Print data to serial port
        sendStr(str);

        // Delay for 1 second
        halMcuWaitMs(1000);
    }
}

void initUART()
{
    HAL_UART_CFG_T uartCfg;

    uartCfg.baudRate = HAL_UART_BR_115200;
    uartCfg.flowControl = FALSE;
    uartCfg.parity = HAL_UART_PARITY_NONE;
    uartCfg.stopBits = HAL_UART_STOP_BITS_1;
    uartCfg.startGuardTime = 0;

    HalUARTInit();
    HalUARTOpen(HAL_UART_PORT_0, &amp;uartCfg);
}

void sendStr(char *str)
{
    while (*str != '\0')
    {
        HalUARTWrite(HAL_UART_PORT_0, (uint8*)str, 1);
        str++;
    }

    HalUARTWrite(HAL_UART_PORT_0, (uint8*)"\r\n", 2);
}

void BH1750_init()
{
    uint8 pBuf[2];

    pBuf[0] = 0x01;  // Start measurement command
    halI2CWrite(BH1750_ADDR, pBuf, 1);

    pBuf[0] = 0x10;  // Set resolution to 1lx
    halI2CWrite(BH1750_ADDR, pBuf, 1);
}

uint16 BH1750_read()
{
    uint8 pBuf[2];

    halI2CRead(BH1750_ADDR, pBuf, 2);

    uint16 illumination = (pBuf[0] <&lt; 8) | pBuf[1];

    return illumination;
}

In the above code, the initUART function initializes the serial port, the sendStr function prints a string to the serial port. The BH1750_init function initializes the BH1750 sensor, including sending the start measurement command and setting the resolution to 1lx. The BH1750_read function reads the sensor data and calculates the light intensity value. In the main function, a while loop continuously reads data from the sensor and prints it via the serial port. The delay function halMcuWaitMs is a delay function provided by CC2530, and other methods can be used to implement the delay waiting function.

[2] DHT11 Temperature and Humidity Data Reading

Below is the code for the CC2530 microcontroller to read temperature and humidity from the DHT11 sensor and print them to the serial port:


#include "hal_types.h"
#include "hal_board.h"
#include "hal_uart.h"

#define DHT11_PORT 1   // DHT11 connected to P1 port

// Send a DHT11 start signal
void DHT11_Start(void) {
  // Set pin to output mode
  P1SEL &amp;= ~(1 <&lt; DHT11_PORT);
  P1DIR |= (1 <&lt; DHT11_PORT);

  // Pull down the pin
  P1_1 = 0;

  // Wait for at least 18ms
  HalDelayMs(18);

  // Pull up the pin
  P1_1 = 1;

  // Wait 20~40us and switch to input mode
  HalDelayUs(30);
  P1DIR &amp;= ~(1 <&lt; DHT11_PORT);
}

// Wait for DHT11 response signal
uint8 DHT11_WaitResponse(void) {
  uint8 timeOut = 0;
  while(P1_1 &amp;&amp; timeOut < 200) {  // Wait for low level to appear, return 1 on timeout
    HalDelayUs(1);
    timeOut++;
  }
  if(timeOut >= 200) return 1;

  timeOut = 0;
  while(!P1_1 &amp;&amp; timeOut < 200) {  // Wait for high level to appear, return 1 on timeout
    HalDelayUs(1);
    timeOut++;
  }
  if(timeOut >= 200) return 1;

  return 0;
}

// Read a bit
uint8 DHT11_ReadBit(void) {
  uint8 timeOut = 0;
  while(P1_1 &amp;&amp; timeOut < 200) {  // Wait for low level to appear, return 1 on timeout
    HalDelayUs(1);
    timeOut++;
  }

  timeOut = 0;
  while(!P1_1 &amp;&amp; timeOut < 200) {  // Wait for high level to appear, return 1 on timeout
    HalDelayUs(1);
    timeOut++;
  }

  HalDelayUs(40);  // Wait for 40us

  if(P1_1) return 1;  // If no low level appears within 40us, return 1, indicating data error

  return 0;
}

// Read a byte
uint8 DHT11_ReadByte(void) {
  uint8 byte = 0;
  uint8 i;
  for(i=0;i<8;i++) {
    byte <&lt;= 1;
    byte |= DHT11_ReadBit();
  }
  return byte;
}

// Read temperature and humidity data from DHT11
void DHT11_ReadData(uint8* temperature, uint8* humidity) {
  uint8 data[5];

  // Send start signal
  DHT11_Start();

  // Wait for response signal
  if(DHT11_WaitResponse()) {
    *temperature = 0;
    *humidity = 0;
    return;
  }

  // Read data
  data[0] = DHT11_ReadByte();  // Humidity integer part
  data[1] = DHT11_ReadByte();  // Humidity decimal part
  data[2] = DHT11_ReadByte();  // Temperature integer part
  data[3] = DHT11_ReadByte();  // Temperature decimal part
  data[4] = DHT11_ReadByte();  // Checksum

  // Calculate checksum
  uint8 sum = data[0] + data[1] + data[2] + data[3];
  if(sum != data[4]) {
    *temperature = 0;
    *humidity = 0;
    return;
  }

  // Calculate temperature and humidity
  *humidity = data[0];
  *temperature = data[2];
}

// Initialize serial port
void UART_Init(void) {
  HalUARTInit();
  HalUARTCfg_t uartConfig;
  uartConfig.configured = TRUE;
  uartConfig.baudRate = HAL_UART_BR_115200;
  uartConfig.flowControl = FALSE;
  uartConfig.flowControlThreshold = 64;
  // Set serial port transmission format
  uartConfig.rx.maxBufSize = 128;
  uartConfig.tx.maxBufSize = 128;
  uartConfig.idleTimeout = 6;
  uartConfig.intEnable = TRUE;
  uartConfig.callBackFunc = NULL;
  HalUARTOpen(HAL_UART_PORT_0, &amp;uartConfig);
}

// Print temperature and humidity to serial port
void PrintData(uint8 temperature, uint8 humidity) {
 char buf[32];
 sprintf(buf, "Temperature: %dC, Humidity: %d%%\r\n", temperature, humidity);
 HalUARTWrite(HAL_UART_PORT_0, (uint8*)buf, strlen(buf));
}

void main(void) {
 uint8 temperature, humidity;

 // Initialize serial port
 UART_Init();

 while(1) {
 // Read data from DHT11
 DHT11_ReadData(&amp;temperature, &amp;humidity);

 // Print data to serial port
 PrintData(temperature, humidity);

 // Wait for 1 second
 HalDelayMs(1000);
 }
}

This code uses the CC2530 microcontroller to read the ambient temperature and humidity through the DHT11 sensor and prints them to the serial port. The implementation process involves sending a start signal, waiting for the DHT11 response signal, then reading the humidity integer, humidity decimal, temperature integer, temperature decimal, and checksum sequentially. After verifying the checksum, the temperature and humidity are calculated and output via the serial port. To ensure data accuracy, it is necessary to wait one second before each data reading.

Leave a Comment