Для изучения способов работы с серийным портом на платформе Arduino поставил себе задачу - получить данные с цифрового мультиметра MAS-344* фирмы Mastech. Данный прибор имеет RS-232C интерфейс для вывода значений измеряемых параметров. Но проблема в том, что его интерфейс имеет нестандартные для библиотеки Serial настройки.
* Статья актуальна для приборов серий: MAS-343 / MAS-344 / MAS-345 / M9803R.
Как выйти из создавшегося положения?
После установки программы "DMM View" с диска, входящего в комплектацию прибора, обнаружил в каталоге файл с описанием программы и описанием интерфейсов приборов:
После установки программы "DMM View" с диска, входящего в комплектацию прибора, обнаружил в каталоге файл с описанием программы и описанием интерфейсов приборов:
3. RS232C Interface protocol
3-1. MAS34X series
Mode : 600,n,7,2
Format : Ascii Code
Total : 14 bytes
Whenever any one byte received from P/C, output 14 bytes.
BYTE 1-2 : MEASURING MODE (ex;DC,AC,OH,CA,TE...)
BYTE 4 : SIGN(-)
BYTE 5-9 : Decimal point and value
Current measurement value(ex;10.00, OL.,3.999)
BYTE 10-13 : Unit (ex; mV,A,KOHM,nF...)
BYTE 14 : Carriage Return
Note : Interval time over 1 second is required for stable
measuring data from the meter.
3-2. M9803R
Mode : 9600,n,7,2
Format : Ascii code and Hex Code
Total : 11 bytes
The serial data output twice on each A/D conversion cycle.
BYTE 1 : - - - +/- Batt - OL
+/- : 0 for positive, 1 for negative
Batt : 0 for normal, 1 for low battery
OL : 0 for normal, 1 for Over Range
BYTE 2 ~ 5 : Ascii code of measurement value (MSD ~ LSD)
BYTE 6 : Unit
0000000 DC V
0000001 AC V
0000010 DC mA
0000011 AC mA
0000100 Ohm
0000101 Buzzer
0000110 Diode
0000111 ADP
0001000 DC A
0001001 AC A
0001010 Hz
0001011
0001100 CAP
BYTE 7 : Range
0000000 400mV,4mA,400ohm,10kHz,4nF
0000001 4V,40mA,4kohm,100kHz,40nF
0000010 40V,400mA,40kohm,1000kHz,400nF
0000011 400V,4000mA,400kohm,4uF
0000100 4000V,4Mohm,40uF
0000101 40Mohm,100Hz
0000110 1000Hz
Diode : 4V range
Buzzer : 400ohm range
DC A and AC A : 40A range
BYTE 8 : Special Function I
- - - max min rel hold
0 for normal, 1 for the function
BYTE 9 : Special Function II
- - - mem auto manl apof
0 for normal, 1 for the function
BYTE 10 : CR (Carrage Return)
BYTE 11 : LF (Line Feed)
Как видно из описания, мы имеем дело с нестандартными для библиотеки Serial настройками интерфейса, т.к. библиотека Serial позволяет изменять только скорость передачи данных, а остальные параметры жестко установлены в значения: n, 8, 1 , где n - нет контроля четности, 8 - бит данных, 1 - стоп бит. Нам же следует установить: 7 - бит данных и 2 - стоп бита!
Для настройки параметров UART нам следует обратиться за помощью к документации по AVR ATmega (в своем примере я использую МК блок на ATmega2560-16AU, Datasheet PDF 7,32 MB).
Глава 22 документации посвящена USART, в разделе 22.9.4 "UCSRnC – USART Control and Status Register n C" описан регистр UCSRnC, который позволяет задать нам требуемые параметры интерфейса. Символ n в названии регистра и в названиях его бит - номер USART МК, для ATmega2560 n может принимать значения от 0 до 3.
Глава 22 документации посвящена USART, в разделе 22.9.4 "UCSRnC – USART Control and Status Register n C" описан регистр UCSRnC, который позволяет задать нам требуемые параметры интерфейса. Символ n в названии регистра и в названиях его бит - номер USART МК, для ATmega2560 n может принимать значения от 0 до 3.
- Bits 5:4 – UPMn1:0: Parity Mode: 2 бита для установки контроля четности:
- UPMn1 UPMn0 Parity Mode
- 0 0 Disabled
- 0 1 Reserved
- 1 0 Enabled, Even Parity
- 1 1 Enabled, Odd Parity
- Bit 3 – USBSn: Stop Bit Select: 1 бит для установки количества стоповых бит:
- USBSn Stop Bit(s)
- 0 1-bit
- 1 2-bit
- Bit 2:1 – UCSZn1:0: Character Size: 2 бита для установки количества бит данных*
- UCSZn1 UCSZn0 Character Size
- 0 0 5-bit
- 0 1 6-bit
- 1 0 7-bit
- 1 1 8-bit
Теперь настройка USART сводится к инициализации его стандартным способом, после чего можно установить требуемые биты в регистре UCSRnC.
Код инициализации для USART2 выглядит так:
void setup() {
...
// инициализируем USART2
Serial2.begin(600);
// сейчас настройки такие: 8-bit, no parity, 1 stop bit
// очищаем изменяемые биты
UCSR2C = UCSR2C & B11000001;
// установка: parity == n
UCSR2C = UCSR2C | B00000000; // | (0 << UPM20);
// установка: stop == 2
UCSR2C = UCSR2C | B00001000; // | (1 << USBS2);
UCSR2C = UCSR2C | B00001000; // | (1 << USBS2);
// установка: size == 7
UCSR2C = UCSR2C | B00000100; // | (2 << UCSZ20);
...
}
Полный код скетча:
/*
!!! Чтение данных с мультиметра MAS-344 !!!
!!! FOR MEGA/2560/ADK !!!
UCSR2C = UCSR2C | B00000100; // | (2 << UCSZ20);
...
}
Прибор следует подключать к USART через RS232-TTL конвертер. Управляющий сигнал DTR должен быть выставлен. Периодически отправляем на прибор байт данных, в ответ получаем 14 байт данных.
Полный код скетча:
/*
!!! Чтение данных с мультиметра MAS-344 !!!
!!! FOR MEGA/2560/ADK !!!
27.04.2012
Используется Serial2.
Для активации передачи данных с прибора следует выставить сигнал DTR.
Для соединения с МК использовался дата-кабель от Siemens ME45 (DCA-500),
его вывод DB9(6)-DSR подключен к выводу DB9(4)-DTR прибора,
т.к. по схеме DCA-500 DB9(6)-DSR выставлен.
RX/TX обмениваем местами, GND.
Питание на дата-кабель 5V с платы МК.
Настройку порта на 600,7,n,2 делаем через регистр AVR UCSR2C (2 - номер USART).
Для соединения с МК использовался дата-кабель от Siemens ME45 (DCA-500),
его вывод DB9(6)-DSR подключен к выводу DB9(4)-DTR прибора,
т.к. по схеме DCA-500 DB9(6)-DSR выставлен.
RX/TX обмениваем местами, GND.
Питание на дата-кабель 5V с платы МК.
Настройку порта на 600,7,n,2 делаем через регистр AVR UCSR2C (2 - номер USART).
Bit 7 6 5 4 3 2 1 0
UMSELn1 UMSELn0 UPMn1 UPMn0 USBSn UCSZn1 UCSZn0 UCPOLn
R/W R/W R/W R/W R/W R/W R/W R/W R/W
IniVal 0 0 0 0 0 1 1 0
где n - номер USART
UMSELn1 UMSELn0 UPMn1 UPMn0 USBSn UCSZn1 UCSZn0 UCPOLn
R/W R/W R/W R/W R/W R/W R/W R/W R/W
IniVal 0 0 0 0 0 1 1 0
где n - номер USART
Автор: Сафронов Юрий (Garry)
e-mail: garry1301@gmail.com
*/
*/
String inputString = ""; // строка для накопления данных
boolean stringComplete = false; // данные приняты полностью
unsigned long Millis;
void setup() {
// резервируем место под принимаемые данные
inputString.reserve(20);void setup() {
// резервируем место под принимаемые данные
Serial.begin(9600);
// инициализируем USART2
Serial2.begin(600);
// сейчас настройки такие: 8-bit, no parity, 1 stop bit
// сейчас настройки такие: 8-bit, no parity, 1 stop bit
// очищаем изменяемые биты
UCSR2C = UCSR2C & B11000001;
// установка: parity == n
UCSR2C = UCSR2C | B00000000; // | (0 << UPM20);
// установка: stop == 2
UCSR2C = UCSR2C | B00001000; // | (1 << USBS2);
// установка: size == 7
UCSR2C = UCSR2C | B00000100; // | (2 << UCSZ20);
Millis = millis();
}
void loop() {
// установка: stop == 2
UCSR2C = UCSR2C | B00001000; // | (1 << USBS2);
// установка: size == 7
UCSR2C = UCSR2C | B00000100; // | (2 << UCSZ20);
Millis = millis();
}
void loop() {
// периодически отправляем байт на прибор,
// он должен вернуть строку из 14 символов
if (millis() - Millis > 2000) {
Serial2.write('0');
Millis = millis();
}
// выводим принятую строку
if (stringComplete) {
Serial.print(inputString);
// готовимся к приему новой строки
inputString = "";
stringComplete = false;
}
}
void serialEvent2() {
// принимаем данные
while (Serial2.available()) {
char inChar = (char)Serial2.read();
inputString += inChar;
// прибор завершает передачу данных символом <CR>
if (inChar == '\r') {
// мы тоже завершаем
inputString += '\n';
stringComplete = true;
return;
}
}
}
(продолжение следует...)
Комментариев нет:
Отправить комментарий