пятница, 27 апреля 2012 г.

Чтение данных с мультиметра MAS-344 на Arduino

Для изучения способов работы с серийным портом на платформе Arduino поставил себе задачу - получить данные с цифрового мультиметра MAS-344* фирмы Mastech. Данный прибор имеет RS-232C интерфейс для вывода значений измеряемых параметров. Но проблема в том, что его интерфейс имеет нестандартные для библиотеки Serial настройки.

* Статья актуальна для приборов серий: MAS-343 / MAS-344 / MAS-345 / M9803R.

Как выйти из создавшегося положения?

После установки программы "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.


Давайте посмотрим, какие биты регистра нам потребуются для установки параметров, которые невозможно установить при помощи библиотеки Serial.
  • 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
* Есть возможность установить 9 бит данных, но для этого потребуется еще регистр UCSRnB.


Теперь настройка 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);
  // установка: size == 7
  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).


  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


  Автор: Сафронов Юрий (Garry)
  e-mail: garry1301@gmail.com
*/


String inputString = ""; // строка для накопления данных
boolean stringComplete = false; // данные приняты полностью
unsigned long Millis;


void setup() {
  
  // резервируем место под принимаемые данные
  inputString.reserve(20);
  
  Serial.begin(9600);
  
  // инициализируем 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);
  // установка: 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;
      
    }
    

  }
  

}



(продолжение следует...)


Комментариев нет:

Отправить комментарий