Author Sun Dongmei: Ph.D. and Associate Professor, School of Automation and Electrical Engineering, Nanjing University of Technology

A data collector based on STM32F107 was designed to collect and process various types of data (such as serial port and CAN port) and upload it wirelessly via a GPRS module. The project involved writing a detailed CAN device driver, implementing serial port data upload and download through the GPRS module, and addressing some issues encountered while using threads during the development process.

First, functional analysis

The system's functionality is illustrated in Figure 1, which is not overly complex. However, due to the large volume of data reported by the lower-level sensor modules, the processing program became quite extensive.

Second, the CAN driver is written

To modularly handle the active reporting data from the sensors, the CAN device no longer used interrupt-based processing but instead utilized the RTT framework to rewrite the device driver. Studying the CAN bus transceiver equipment within the RTT framework:

Only the framework was found, with no actual content. It was similar to writing a 'candevice' like a serial port. Studying the serial port driver in use of the component:

This involved reading code and then writing a driver similar to Linux after understanding the framework.

After completing all the above programs, the device could be operated using general device functions. In the main program, the device was initialized first, followed by registration.

Third, the device mode to achieve serial data processing

The GPRS module is primarily used for receiving serial data. First, a gprswatch process was created to monitor the serial port for incoming data.

Void gprswatch ( void ) { rt_thread_t thread ; thread = rt_thread_find ( "gprswatch" ); if ( thread != RT_NULL ) rt_thread_delete ( thread ); /* Create gprswatch thread */ thread = rt_thread_create ( "gprswatch" , gprswatch_entry , RT_NULL , 0x1000 , 0x12 , 200 ); /* Start the thread if created successfully */ if ( thread != RT_NULL ) { rt_thread_startup ( thread ); //rt_thread_delay(RT_TICK_PER_SECOND/2); } }

In the monitoring GPRS serial port thread, after receiving the serial port data, it analyzes and updates the network status.

/ * Monitoring GPRS serial thread inlet * / void gprswatch_entry (void * parameter ) {rt_err_t result = RT_EOK; rt_uint32_t event; unsigned char gprs_rx_buffer [GPRS_RX_LEN] = {0x00}; while (1) {result = rt_event_recv (& rev_event, REV_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, & event ); if (result == RT_EOK) {if (event & REV_DATA) {rt_memset (gprs_rx_buffer, 0x00, sizeof (gprs_rx_buffer)); rt_thread_delay (RT_TICK_PER_SECOND / 10); rt_device_read (gprs_device, 0, Gprs_rx_buffer , GPRS_RX_LEN ); rt_kprintf ( gprs_rx_buffer ); /* Monitor GPRS module to receive data */ if ( rt_strstr (( char const * ) gprs_rx_buffer , "MYURCCLOSE: 0" )) //network break { net_status = CONNECT_ERROR ; rt_kprintf ( " The network is broken. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . " ); } else if ( rt_strstr (( char const * ) gprs_rx_buffer , "Call Ready" )) // Module restart { net_status = CONNECT_NULL ; rt_kprintf ( " The module is restarted. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ");} Else if (rt_strstr ((char const *) gprs_rx_buffer," + CPIN: NOT READY ")) // card is removed {net_status = CONNECT_ERROR; rt_kprintf (" The card was pulled out. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ");} Else if (rt_strstr ((char const *) gprs_rx_buffer," $ MYURCACT: 0,0 ")) // network disconnection {net_status = CONNECT_DISCONNECT; rt_kprintf (" Disconnected from the network. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ");} Else if (rt_strstr ((char const *) gprs_rx_buffer," MYURCREAD: 0 ")) // there is a network data {net_status = CONNECT_GPRSDATAIN;} else if (rt_strstr ((char const *) gprs_rx_buffer," + CMTI: " )) //There is a text message { net_status = CONNECT_MSGDATAIN ; } else { } } if ( event & REV_STOPWATCH ) { return ; } } } }

The monitoring and operation of the corresponding GPRS module is completed elsewhere in the program. A device operation function is also written for the GPRS module read and write operations, mainly using the gprswatch thread previously written:

/ * GPRS module to send and receive * / rt_bool_t gprs_send_data_package (unsigned char * cmd, char * ack, rt_uint32_t waittime, rt_uint8_t retrytime, rt_uint32_t len) {rt_bool_t res = RT_FALSE; rt_err_t result = RT_EOK; rt_uint32_t event; unsigned char gprs_rx_buffer [GPRS_RX_LEN] = {0x00}; rt_thread_t thread; thread = rt_thread_find ( "gprswatch"); if (thread = RT_NULL!) {rt_thread_delete (thread);} do {rt_device_write (gprs_device, 0, cmd, len); result = rt_event_recv (& rev_event , REV_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, waittime * RT_TICK_PER_SECOND, & event); if (result == RT_EOK) {if (event & REV_DATA) {rt_memset (gprs_rx_buffer, 0x00, sizeof (gprs_rx_buffer)); rt_thread_delay (RT_TICK_PER_SECOND / 2); rt_device_read ( gprs_device , 0 , gprs_rx_buffer , GPRS_RX_LEN ); rt_kprintf ( gprs_rx_buffer ); if ( rt_strstr ( cmd , MSG_IMSI )) // If the IMSI is parsed out of the IMSI data { unsigned char * addr ; addr = rt_strstr (( char const * ) gprs _rx_buffer , "AT+CIMI" ) + 10 ; if ( addr != NULL ) { strncpy ( & imsi [ 0 ], addr , 15 ); rt_kprintf ( " IMSI = :%s " , imsi ); } } if ( rt_strstr ( cmd , MSG_IMEI )) // If the IMEI is parsed out IMEI data { unsigned char * addr ; addr = rt_strstr (( char const * ) gprs_rx_buffer , " \" " ) + 1 ; if ( addr != NULL ) { strncpy ( & imei [ 0 ], addr , 15 ); rt_kprintf ( " IMEI = :%s " , imei ); } } if ( rt_strstr ( cmd , CSQ_CMD )) // If the read CSQ parses out the dbm data { unsigned char csq [ 5 ] = { 0x00 }; unsigned char * addr ; rt_int16_t dbm ; addr = rt_strstr ( (char const *) gprs_rx_buffer, " ,") - 3; rt_strncpy (csq, addr, 3); if (addr = NULL) {dbm = 2 * atoi (csq) - 109;! dbm_data [0] = dbm; dbm_data [ 1 ] = dbm >> 8 ; rt_kprintf ( " DBM = %d " , dbm ); rt_kprintf ( " RSSI = %02x%02x " , dbm_data [ 0 ], dbm_data [ 1 ]); } } if (( rt_strstr ( gprs_rx_buffer , ack )) || ( rt_strstr ( gprs_rx_buffer , "OK" ))) { res = RT_TRUE ; if ( rt_strstr ( cmd , MG323_READ_CMD )) / / If the data command is read, copy the data out { rt_memcpy ( gprs_rx_data , gprs_rx_buffer , GPRS_RX_LEN ); } } else res = RT_FALSE ; } if ( rt_strstr (( char const * ) gprs_rx_buffer , "MYURCREAD: 0" )) //There is network data { net_status = CONNECT_GPRSDATAIN ; rt_kprintf ( " Received network data! " ); } } retrytime -- ; } while (( ! res ) && ( retrytime >= 1 )); g

Transmission Line Steel Tubular Pole

We have got 220kV Transmission Line poles Quality Certificate from Power Industry Steel Tower Qualified Inspection & Test Center from 2001 year. Our steel poles are made from quality sheet through bending, forming, automatic welding and hot galvanization. We can reach one-run machining length of 14m and can bend sheet of thickness up to 45mm. We adopt advanced welding procedures, automatically weld main joints and reach rank-II welding quality.

We have supplied 2400ton 132kV and 220kV transmission line steel pole to WAPDA. Pakistan on 2008 and have supplied 1200ton 138kV transmission line steel pole to Davao light, Philippines on 2009.

Transmission Line Steel Tubular Pole, Tubular Steel Pole, Steel Tubular Pole, Utility Pole

JIANGSU XINJINLEI STEEL INDUSTRY CO.,LTD , https://www.steel-pole.com