Измерение унифицированного токового сигнала 4…20 мА (LGT8F328)

Справка

Токовая петля — способ передачи информации с помощью измеряемых значений силы электрического тока. В настоящее время такой способ более распространён в инженерной практике, чем использование для этой цели напряжения. Для задания измеряемых значений тока используется, как правило, управляемый источник тока. По виду передаваемой информации различаются аналоговая токовая петля и цифровая токовая петля.

Аналоговая токовая петля используется для передачи аналогового сигнала по паре проводов в лабораторном оборудовании, системах управления производством и т. д.

Применяется смещенный диапазон 4—20 мА, то есть наименьшее значение сигнала (например, 0) соответствует току 4 мА, а наибольшее — 20 мА. Таким образом весь диапазон допустимых значений занимает 16 мА. Нулевое значение тока в цепи означает обрыв линии и позволяет легко диагностировать такую ситуацию.

Интерфейс аналоговой токовой петли позволяет использовать разнообразные датчики (давления, потока, кислотности и т. д.) с единым электрическим интерфейсом. Также данный интерфейс может использоваться для управления регистрирующими и исполнительными устройствами: самописцами, заслонками и т. д.

На платформе Arduino можно реализовать измерение унифицированного токового сигнала 4…20 мА, для этого необходимо ток преобразовать в напряжение и подать его на аналоговый вход АЦП микроконтроллера. Сопротивление 50 Ом преобразует ток 20 мА в напряжение 1 В. Чем точнее подобрано сопротивление 50 Ом, тем более точные будут показания прибора. Измеритель унифицированного токового сигнала 4…20 мА позволяет задать произвольные значения для тока 4 мА и 20 мА, этими значениями можно задать наименьшую и наибольшую величину измерения (диапазон измерения). Этими величинами может быть ток, напряжение, давление, температура и т.д. Так же можно задать кол-во знаков после запятой у измеренного значения.

Значения наименьшей и наибольшей величины измерения, а так кол-во знаков после запятой у измеренного значения сохраняются в энергонезависимой памяти.

В качестве микроконтроллера используется плата разработчика LGT8F328P-LQFP32 MiniEVB, которая основана на китайском микроконтроллер LGT8F328p и является клоном популярной AVR ATmega328p (Arduino NANO). Микроконтроллер LGT8F328p практически полностью совместим с микроконтроллером ATmega328p и обладает рядом дополнительных функций и возможностей превышающих ATmega328p.

Как ранее отмечалось для измерения тока используется сопротивление 50,00 Ом, на котором происходит падение напряжения 1 В при токе 20 мА и 0,2 В при токе 4 мА. Для более точного измерения падения напряжения вход АЦП микроконтроллера имеет разрешение 12 бит и настроен на внутреннее опорное напряжение 1,024 В.

Измеритель сигнала 4-20 мА имеет три кнопки управления:

  • SET — переключат меню настроек положения запятой, значение LOW для тока 4 мА и HIGH для тока 20 мА
  • UP — изменение положения запятой и увеличение параметров значений LOW и HIGH
  • DW — изменение положения запятой и уменьшение параметров значений LOW и HIGH

Например если необходимо измерить ток 4-20, то настраиваем меню следующим образом

Положение запятой

Значение LOW

Значение HIGH

Измерение

Теперь для примера возьмем датчик давления с диапазоном -1…6 гс/см², с токовым выходом 4…20 мА

Положение запятой

Значение LOW

Значение HIGH

Измерение

При токе 11,4 мА давление датчика равно 2,24 гс/см².

При выходе тока за пределы диапазона на индикаторе появится предупреждения LLLL для тока меньше 4 мА и HHHH для тока выше 20 мА.

 


В данном проекте использован индикатор CPS05641 0.56′ на базе драйвера MAX7219.

Как использовать плату LGT8F328P-LQFP32 MiniEVB в среде Arduino IDE рассказано в http://rcl-radio.ru/?p=129966.

Скетч:

// MAX7219
#define DIN 10
#define CLK 11
#define CS  12
// BUTTON
#define SET  2
#define UP   3
#define DW   4

#define I_KALL 200.00

#include <EEPROM.h>

int u_dig,ind,dp,set,www,del=1;
long u_sum;
int i4,i20;
float i0_20,i_led;
bool minus,w1;
unsigned long times,times0;

void setup() {
  Serial.begin(9600);
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении  
  pinMode(DIN,OUTPUT);
  pinMode(CLK,OUTPUT);
  pinMode(CS,OUTPUT);
  pinMode(SET,INPUT_PULLUP);
  pinMode(UP,INPUT_PULLUP);
  pinMode(DW,INPUT_PULLUP);
  delay(2);
  digitalWrite(CS,HIGH);
  digitalWrite(CLK,LOW);
  digitalWrite(DIN,LOW);
  WriteBit16(0x0F, 0);// тест выкл.
  WriteBit16(0x0C, 1);// вкл. индик.
  WriteBit16(0x0A, 2);// яркость
  WriteBit16(0x09, 0xFF);// дешифраторы вкл.
  WriteBit16(0x0B, 3);// кол-во разрядов
  Serial.println("LED_OK");
  analogReadResolution(12);// АЦП 12 БИТ
  analogReference(INTERNAL1V024);
  pinMode(A1,INPUT);
  dp = EEPROM.read(0);
  i4 = EEPROM.read(10)*256+EEPROM.read(11);if(EEPROM.read(12)==1){i4=i4-2*i4;}
  i20 = EEPROM.read(20)*256+EEPROM.read(21);if(EEPROM.read(22)==1){i20=i20-2*i20;}
}

void loop() {
   if(digitalRead(SET)==LOW){set++;if(set>3){set=0;}eeprom();delay(200);}
   
   if(set==1 && digitalRead(UP)==LOW){dp++;if(dp>2){dp=0;}eeprom();delay(200);}
   if(set==1 && digitalRead(DW)==LOW){dp--;if(dp<0){dp=2;}eeprom();delay(200);} 

   if(set==2 && digitalRead(UP)==LOW){www++;i4++;if(i4>999){i4=999;};eeprom();delay(200/del);}
   if(set==2 && digitalRead(DW)==LOW){www++;i4--;if(i4<-999){i4=-999;}eeprom();delay(200/del);}

   if(set==3 && digitalRead(UP)==LOW){www++;i20++;if(i20>999){i20=999;};eeprom();delay(200/del);}
   if(set==3 && digitalRead(DW)==LOW){www++;i20--;if(i20<-999){i20=-999;}eeprom();delay(200/del);}

   if(digitalRead(UP)==HIGH&&digitalRead(DW)==HIGH){www=0;del=1;}
   if(www>20){del=10;}
   
  if(set==0){
  for(int i=0;i<10;i++){
   if(digitalRead(SET)==LOW){set++;if(set>3){set=0;}delay(100);}
   u_dig = analogRead(A1);
   u_sum += u_dig;
   delay(100);
   }}
   u_dig = u_sum/10.0;u_sum=0;   
   Serial.println(u_dig);
   i0_20 = float(u_dig)/I_KALL;

   i_led =float(i20-i4)/16.0*i0_20-float(i20-i4)/16.0*4.0+i4;
   if(i_led<0){i_led=abs(i_led);minus=1;}else{minus=0;}
   
  if(set==1){
   WriteBit16(1, 14);
   if(dp==1){WriteBit16(2, 0 + 0xF0);}else{WriteBit16(2, 0);}
   if(dp==2){WriteBit16(3, 0 + 0xF0);}else{WriteBit16(3, 0);}
   WriteBit16(4, 0);
   }

   if(set==2){ 
   if(millis()-times<500){ 
   if(i4<0){WriteBit16(1, 10);}else{WriteBit16(1, 15);}}
   if(millis()-times>=500){WriteBit16(1, 13);}
   if(millis()-times>1000){times=millis();}
   ind=abs(i4);
   if(dp==1){WriteBit16(2, ind/100%10 + 0xF0);}else{WriteBit16(2, ind/100%10);}
   if(dp==2){WriteBit16(3, ind/10%10 + 0xF0);}else{WriteBit16(3, ind/10%10);}
   WriteBit16(4, ind%10);
   }

   if(set==3){ 
   if(millis()-times<500){ 
   if(i20<0){WriteBit16(1, 10);}else{WriteBit16(1, 15);}}
   if(millis()-times>=500){WriteBit16(1, 12);}
   if(millis()-times>1000){times=millis();}
   ind=abs(i20);
   if(dp==1){WriteBit16(2, ind/100%10 + 0xF0);}else{WriteBit16(2, ind/100%10);}
   if(dp==2){WriteBit16(3, ind/10%10 + 0xF0);}else{WriteBit16(3, ind/10%10);}
   WriteBit16(4, ind%10);
   }
   
  if(set==0 && u_dig>=500 && u_dig<=4060){
   if(minus==1){WriteBit16(1, 10);}else{WriteBit16(1, 15);}
   ind=i_led;
   if(dp==1){WriteBit16(2, ind/100%10 + 0xF0);}else{WriteBit16(2, ind/100%10);}
   if(dp==2){WriteBit16(3, ind/10%10 + 0xF0);}else{WriteBit16(3, ind/10%10);}
   WriteBit16(4, ind%10);
   }

  if(set==0 && u_dig<500){WriteBit16(1, 13);WriteBit16(2, 13);WriteBit16(3, 13);WriteBit16(4, 13);}
  if(set==0 && u_dig>4060){WriteBit16(1, 12);WriteBit16(2, 12);WriteBit16(3, 12);WriteBit16(4, 12);}

if(millis()-times0>5000 && w1==1){
     EEPROM.update(0,dp);
     EEPROM.update(10,highByte(abs(i4)));EEPROM.update(11,lowByte(abs(i4)));
     if(i4<0){EEPROM.update(12,1);}else{EEPROM.update(12,0);}
     EEPROM.update(20,highByte(abs(i20)));EEPROM.update(21,lowByte(abs(i20)));
     if(i20<0){EEPROM.update(22,1);}else{EEPROM.update(22,0);}
     w1=0;set=0;}   
}// END LOOP

void eeprom(){times0=millis();w1=1;}

void WriteBit16(byte reg, byte data){  
     digitalWrite(CLK,LOW); digitalWrite(CS,LOW);
     for(int i = 7; i >= 0; i--){
        if(((reg >> i) & 1) == 1){digitalWrite(DIN,HIGH);}else{digitalWrite(DIN,LOW);}
        digitalWrite(CLK,HIGH);digitalWrite(CLK,LOW);
        }
     for(int i = 7; i >= 0; i--){
        if(((data >> i) & 1) == 1){digitalWrite(DIN,HIGH);}else{digitalWrite(DIN,LOW);}
        digitalWrite(CLK,HIGH);digitalWrite(CLK,LOW);
        }
     digitalWrite(CS,HIGH);digitalWrite(CLK,LOW);digitalWrite(DIN,LOW);  
  }  

 

Comments

  1. Привет. Заглянул на сайт и увидел этот проект. Какие нужно внести изменения что бы заработал мой дисплей HW-179 (8-сегментный 8-значный дисплей MAX7219), а то горит 3 цифры.

    И было бы интересно узнать как этим девайсом проверить датчик давления ДМ-100 , методика ?

    1. Работать будут только 4 цифры, один разряд под минус. Проект рассчитан только под 4-х разрядный индикатор.
      ДМ-100??? Я не знаю что это за датчик, информации по нему не нашел.

  2. Привет. Получил дисплей. При компиляции скетча для ардуинки ,ошибка в строке

    analogReadResolution(12);// АЦП 12 БИТ
    analogReference(INTERNAL1V024);

    Для LGT , ошибки нет но у меня нет под рукой ее.

Добавить комментарий

Войти с помощью: