newlandmark

ART-Pi 4G communication expansion board

 
Overview
1. Schematic diagram and PCB
 
1. Power supply: Since the CAT.1 module consumes a lot of power instantly when sending data, the power module must consider the output power. Since my input voltage is 5V and the module power supply is 4V, I chose MIC29302 LDO.
image.png
2. Serial communication: The serial communication level of the Air724 module is 1.8V, while the GPIO level of the H750 is 3.3V. The two cannot be directly connected and need to use a level conversion circuit. There are many level conversion ICs on the market. Since I designed The circuit only has one set of serial port connections, and the finished level conversion ICs all have 8 channels. To avoid waste, I used the three-stage tube clamp and the two-stage tube one-way conduction principle to do the level conversion.
image.png
 
3. Air724 firmware download: Air724 officially provides a variety of firmware (AT, DTU, secondary development). Users can download the corresponding firmware according to their needs. The officially recommended method is USB download. The UBOOT pin needs to be pulled down during USB download. You can enter the download mode only after restarting. When designing the circuit, be sure to reserve the UBOOT button and USB communication circuit. Of course, you can also download it through a flying cable. I use this mainly for learning, and everything that needs to be extracted is extracted.
image.pngimage.png
 
4. Power-on button: After the factory firmware of the module is powered off or shut down, you need to pull down the POWER_KEY for more than 3S before it can be powered on (the power-on method varies depending on the firmware version. The DTU firmware used this time is powered on)
image.png
 
5. SHT30 temperature and humidity module: To facilitate the debugging of network communications, the SHT30 temperature and humidity module is equipped with an STH30 temperature and humidity probe onboard, which can be used to provide reported dynamic data.
image.png
 6. ART-PI GIPIO allocation
     Air724 module serial communication 4G_UART_RX_PIN-------------PA9" 4G_UART_TX_PIN----------------PA10
     SHT30 I2C communication SHT30_SDA -------------------- PH9 SHT30_SCL-------------------------------- --PH10
 
7. Regarding the PCB: Because the heating of the 4G module was not taken into account during the layout, the SHT30 was placed too close to the module, causing the SHT30 to collect a high temperature after being powered on for a period of time. In the future, other partners will make temperature detection circuits, which must be considered. The heating of surrounding devices.
    image.png
 
2. Development of ART_Pi program
        1. Create a project
                Please refer to this linked document for project creation, and I won’t go into details here:
        2. Peripheral configuration
                The 4G module uses serial port 1 communication
image.png
        The SHT30 module uses I2C communication
image.png
3. Obtain the driver package
        This case will use JSON data format to send data, and the cJSON parser needs to be enabled.
image.png
        Using SHT30 driver package
image.png
 
4. Main program code
 

/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date Author Notes
 * 2021-03-28 ZYH the first version
 */

/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date Author Notes
 * 2021-01-24 ZYH the first version
 */

 

#include <rtthread.h>
#include <rtdevice.h>
#include "cJSON.h"
#include "string.h"
#include "stdio.h"
#include "swap.h"
#include "drv_common.h"


ALIGN(RT_ALIGN_SIZE)
static char dtu_stack[1024];
static struct rt_thread dtu_thread;

/* mailbox control block */
struct rt_mailbox dtu_mb;

#define LED_PIN GET_PIN(H, 8)

/* memory pool for mails storage */
static char mb_pool[128];


#define DTU_UART_NAME "uart1" /* cat.1 dtu serial */

static struct rt_semaphore rx_sem;
static rt_device_t serial;

uint8_t LED_STA = 0;
uint8_t rx[100];

static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&rx_sem);

    return RT_EOK;
}

static rt_err_t uart_putchar(char *ch, uint16_t length)
{
    rt_device_write(serial, 0, ch, length);

    return RT_EOK;
}


int dtu_init(void)
{
    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;

    config.baud_rate = 115200;

    serial = rt_device_find(DTU_UART_NAME);
    if (!serial)
    {
        rt_kprintf("find %s failed! ", DTU_UART_NAME);
        return RT_ERROR;
    }

    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);

    rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);

    rt_device_control(serial,RT_DEVICE_CTRL_CONFIG,&config);

    rt_device_set_rx_indicate(serial, uart_input);

    return RT_EOK;
}


uint8_t get_uart_ch(uint8_t* ch)
{
    if(rt_sem_take(&rx_sem, RT_WAITING_NO) != RT_EOK)
        return 0;

    /* 读取 1 字节数据 */
    if(rt_device_read(serial, 0, ch, 1) == 1)
    {
        /* 读取到数据 */
        return 1;
    }
    return 0;
}


void PacketParser(char* json_string)
{
    cJSON* cjson=cJSON_Parse(json_string);
    cJSON* cjson_value=NULL;
    char* value = NULL;


    if(cjson != NULL)
    {
        value = cJSON_GetObjectItem(cjson,"value")->valuestring;
        cjson_value = cJSON_Parse(value);
        if(cjson_value != NULL)
        {
            LED_STA = cJSON_GetObjectItem(cjson,"value")->valueint;
        }
    }
    rt_pin_write(LED_PIN, LED_STA);
    cJSON_Delete(cjson);
    cJSON_Delete(cjson_value);
}


void create_rt_json(float temperature, float humidity)
{
    cJSON *root;
    char* str=NULL;

    root =cJSON_CreateObject();

    cJSON_AddStringToObject(root,"request","ReportTH");

    sprintf(str,"%.1f",temperature);
    cJSON_AddStringToObject(root,"temperature",str);

    sprintf(str,"%.1f",humidity);
    cJSON_AddStringToObject(root,"humidity", str);

    char *s=cJSON_Print(root);
    rt_kprintf("%s   length: %d ",s,strlen(s));
    uart_putchar(s,strlen(s));

    cJSON_Delete(root);

}

uint8_t dtu_ExtractPacket(void)
{
    uint8_t     ch;
    static      uint16_t timeout = 0, len = 0;


    while(1)
    {
        if(get_uart_ch(&ch))
        {
            timeout = 0;
           if(len<sizeof(rx))
           {
               rx[len++] = ch;
           }
           continue;
        }

        else if(++timeout>5)
        {
            if(len!=0)
            {
                rx[len+1] = '';
                PacketParser((char*)rx);
            }
            memset(rx,0,sizeof(rx));
            len = 0;
            timeout = 0;
        }
        return 0;
    }
    return 0;
}


/* timer handle */
static rt_timer_t report_timer;

/* timer #1 timeout callback function */
static void report_timeout(void *parameter)
{
    cJSON *root;

    root =cJSON_CreateObject();

    cJSON_AddStringToObject(root,"request","ReportLed");

    cJSON_AddStringToObject(root,"led",LED_STA?"ON":"OFF");

    char *s=cJSON_Print(root);
    uart_putchar(s,strlen(s));
}

/* thread #2 entry function */
static void dtu_entry(void *param)
{
    dtu_init();
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
    struct dtu_mbt_data *mbt_data;
    while(1)
    {
        /* pend and receive mail(s) from mailbox */
        if (rt_mb_recv(&dtu_mb, (rt_ubase_t *)&mbt_data, RT_WAITING_NO) == RT_EOK)
        {
           switch(mbt_data->type)
           {
               case 0x01:
                   create_rt_json(mbt_data->data[0]/10.0, mbt_data->data[1]/10.0);
                   break;

               default:
                   break;

           }
           /* delay for 100ms */
        }
        rt_thread_mdelay(5);
        dtu_ExtractPacket();
    }
}

 

int dtu_thread_init(void)
{
    rt_err_t result;

    /* initiate a mailbox */
    result = rt_mb_init(&dtu_mb,
                        "dtu_mbt",
                        &mb_pool[0],
                        sizeof(mb_pool) / sizeof(rt_ubase_t), /* size of mails */
                        RT_IPC_FLAG_FIFO);
    if (result != RT_EOK)
    {
        rt_kprintf("init mailbox failed. ");
        return -1;
    }

    /* create timer #1, periodic mode */
    report_timer = rt_timer_create("timer1", report_timeout,
                             RT_NULL, 1000,
                             RT_TIMER_FLAG_PERIODIC);

    /* start timer #1 */
    if (report_timer != RT_NULL)
        rt_timer_start(report_timer);

    /* create thread #2 statically */
    rt_thread_init(&dtu_thread,
                    "dtu",
                    dtu_entry,
                    RT_NULL,
                    &dtu_stack[0],
                    sizeof(dtu_stack),
                    5, 10);

    rt_thread_startup(&dtu_thread);

    return RT_EOK;
}


INIT_APP_EXPORT(dtu_thread_init);

 

Please download the attachment to view the complete code! ! !

 
 
3. CAT.1 module DTU firmware download
        Please see the attachment for firmware and download methods.
 
4. Air724 parameter configuration: There are many ways to configure DTU parameters. There are serial port configuration tools, cloud configuration, and configuration can also be sent through the MCU serial port. I chose cloud configuration (after purchasing the AIR724 module, the official will give you a user name and Default passwordhttp://dtu.openluat.com/login/   
        1. Configure the data transparent transmission serial port (the baud rate, data bits, and check bits are consistent with the ART-Pi parameters)
image.png
 
2. Configure network parameters: I use the SOCKET connection method. Of course, the module supports multiple connections and can be configured as needed.
        Note: The 4G module can only be used as a Client, and it is accessed in traffic mode. The IP is a public network dynamic IP. The connection object must have a public network IP or a public network domain name (if there is no public network IP, it is recommended to use peanut shells for internal content). Network mapping, 1G free traffic per month, enough for testing)
 
image.png
 
5. Demonstration effect (please see the attachment for detailed demonstration effect)
 
S033h5oakqWLmHtTHH8jhKxxOdkug9QTg816pgZU.png
 
参考设计图片
×
 
 
Search Datasheet?

Supported by EEWorld Datasheet

Forum More
Update:2025-06-23 02:40:53

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
community

Robot
development
community

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号