英創公司基于SBC870和SBC880工控應用底板設計了專用于擴展驅動電路模塊的DM5028規范,并基于該規范推出了多種擴展模塊,用來滿足工業現場的應用需求。具體可以參考網站上的資料:SBC880工控底板與整機,SBC870工控底板與整機。
ETA104擴展模塊是一款可用于擴展AD輸入的模塊,它使用了ADS7871模擬信號轉換芯片進行擴展,這款芯片的采樣精度為14bit,最高采樣速率為48KSPS,使用SPI總線來通訊,可以和ESMARC系列的任意核心板搭配使用。英創公司在此基礎上做了進一步升級,使其支持采集四路4-20mA電流(精度為14bit),并增加了兩路RS232,兩路RS485,一路CAN總線,四路帶隔離IO輸入以及一路繼電器輸出,詳細資料可以參考ETA104的手冊。
連接示意圖
同時為了進一步降低成本,當ETA104配合英創公司的低成本核心板ESM6800使用時,可以利用ESM6800核心板CPU上自帶的ADC功能來采集電流值,這樣可以省去ETA104模塊上擴展AD部分的器件。ESM6800核心板自帶的ADC采樣精度為12bit,最高采樣速率為1KSPS,通過這種方式能夠較多的降低成本,ESM6800核心板對應的功能管腳配置如下:
AD通道 | 對應管腳 | 對應設備節點 |
AD輸入通道1 | GPIO0 | /sys/bus/iio/devices/iio:device0/ in_voltage9_raw |
AD輸入通道2 | GPIO1 | /sys/bus/iio/devices/iio:device0/ in_voltage8_raw |
AD輸入通道3 | GPIO27 | /sys/bus/iio/devices/iio:device0/ in_voltage0_raw |
AD輸入通道4 | UART2_RXD | /sys/bus/iio/devices/iio:device0/ in_voltage5_raw |
串口,GPIO和CAN總線均使用系統的標準接口就可以正常工作,可以參考英創公司提供的相關例程,本文主要介紹關于AD部分的使用方法。下面首先來看利用擴展芯片ADS7871是如何讀取數據的,因為ADS7871模擬信號轉換芯片是通過SPI總線進行的通訊,所以利用核心板上的SPI總線就可以設置和讀取數據,讀取數據的部分代碼如下:
txbuf[0] = 0x40; txbuf[1] = 0x00; memset(tr, 0 , sizeof(tr)); tr[0].tx_buf = (unsigned long)txbuf; tr[0].rx_buf = (unsigned long)rx; tr[0].len = 2; tr[0].delay_usecs = 0; tr[0].speed_hz = 2500000; tr[0].bits_per_word = 8; /* 進行SPI數據傳輸 */ ret = ioctl(m_fd, SPI_IOC_MESSAGE(1), tr ); if (ret < 1 ) pabort("can't send spi message"); buffer = rx[1]; txbuf[0] = 0x41; txbuf[1] = 0x00; memset(tr, 0 , sizeof(tr)); tr[0].tx_buf = (unsigned long)txbuf; tr[0].rx_buf = (unsigned long)rx; tr[0].len = 2; tr[0].delay_usecs = 0; tr[0].speed_hz = 2500000; tr[0].bits_per_word = 8; /* 進行SPI數據傳輸 */ ret = ioctl(m_fd, SPI_IOC_MESSAGE(1), tr ); if (ret < 1 ) pabort("can't send spi message"); /* 將數據拼接起來 */ buffer |= rx[1] << 8; buffer = buffer>>2;
因為信號源可能存在抖動,所以在讀取數據后增加了中值濾波算法,代碼如下:
#define N 9 int filter(int ch) { uint16_t value_buf[N]; int temp, count; int i, j; for ( count=0;count<N;count++) { value_buf[count] = ETA104_ReadAD(ch, 1); usleep(5000); } /* 采用冒泡法排序 */ for (j=0;j<N-1;j++) { for (i=0;i<N-j;i++) { if ( value_buf[i] > value_buf[i+1] ) { temp = value_buf[i]; value_buf[i] = value_buf[i+1]; value_buf[i+1] = temp; } } } /* 取排序中間值返回 */ return value_buf[(N-1)/2]; }
可以根據實際的情況選擇取使用多少個值來進行中值濾波,實際的測試結果如下:
電流表讀取值(單位:毫安) | 實際讀取值(單位:毫安) |
4.015 | 4.019 |
10.022 | 10.025 |
19.988 | 19.992 |
通過上面的表格可以看出,使用ETA104模塊擴展芯片ADS7871讀取的數據精度為完全能夠達到1%以內。
下面來看看如何使用ESM6800核心板自帶的ADC功能。在Linux內核中,CPU自帶的ADC功能是通過IIO的驅動來實現的,英創公司已經將所需要的驅動集成在了系統中,并且ESM6800核心板的ADC會自動采樣32個點做平均,客戶可以直接讀取,操作十分簡單,具體代碼如下:
char iiotype[4][100] = { "in_voltage9_raw", "in_voltage8_raw", "in_voltage0_raw", "in_voltage5_raw" }; int get_ad(int i) { int ret = 0, ch; char filename[80]; FILE *fp; char buf[20]; sprintf( filename, "/sys/bus/iio/devices/iio:device0/%s", iiotype[i]); fp = fopen(filename, "rt"); if( fp==NULL ) { printf("open %s fail!\n", filename); ret = -1; return ret; } /* 讀取對應的ADC通道值 */ fread( buf, 1, sizeof(buf), fp ); fclose(fp); sscanf( buf, "%d", &ch ); return ch; }
同樣在讀取數據后可以增加中值濾波算法,實際測試結果如下::
電流表讀取值(單位:毫安) | 實際讀取值(單位:毫安) |
4.014 | 4.018 |
10.021 | 10.027 |
19.992 | 19.996 |
根據上面的表格可以看出,使用ESM6800核心板自帶的ADC讀取的數據精度同樣可以達到1%以內。
如有感興趣的客戶,歡迎和英創工程師聯系,索取相關測試代碼和資料。
成都英創信息技術有限公司 028-8618 0660