sub unsigned short tarirovka_01(short input)
//input - АЦП на входе (измеряемый ток)
unsigned short input_base = 0
unsigned short index = 0 // Индекс вводимой ячейки
// Переменные для математического преобразования
unsigned short selection0 = 0, adc0 = 0, real0 = 0
unsigned short selection1 = 1, adc1 = 0, real1 = 0
float output = 0.0, base_adc = 0.0, delta_adc = 0.0, delta_real = 0.0
unsigned short outputd = 0
GetData(selection0, "Local HMI", RECIPE, "Tank1.Selection")
input_base = input / 1000 // input - измеряемый ток, в мА*1000
if input_base >= 4 and input_base <= 19 then
selection0 = input_base - 4 // input = 4000 => selection = 0 (adc=4000, real=...)
// Запрашиваем две тарировочных точки
SetData(selection0, "Local HMI", RECIPE, "Tank1.Selection")
GetData(adc0, "Local HMI", RECIPE, "Tank1.ADCunit")
GetData(real0, "Local HMI", RECIPE, "Tank1.real")
selection1 = selection0 + 1
SetData(selection1, "Local HMI", RECIPE, "Tank1.Selection")
GetData(adc1, "Local HMI", RECIPE, "Tank1.ADCunit")
GetData(real1, "Local HMI", RECIPE, "Tank1.real")
// вычисление координат точки на отрезке
base_adc = input - adc0
delta_adc = adc1 - adc0
delta_real = real1 - real0
// Итоговое тарированное значение в float
output = ((delta_real * base_adc) / delta_adc) + real0
// округляем до десятичного
outputd = ROUND(output)
else if input_base == 20 then // Если достигли верхней точки измерений, 20 mA
selection0 = 16
SetData(selection0, "Local HMI", RECIPE, "Tank1.Selection")
GetData(outputd, "Local HMI", RECIPE, "Tank1.real")
else // Если уровень измерений ниже нижнего порога, т.е. мой ICPCON сигнализирует об обрыве датчика, посылая "-32768"
outputd = 0
end if
return outputd
end sub
i.miroshnichenko писал(а):Разобрался, как это делать.
Принцип тарировки/градуирования: есть таблица соответствия точек, на две колонки - исходный параметр (например, АЦП датчика, или уровень по мерному щупу, и т.д.), и результирующий (например, соответствующий объем).
Количество строк - произвольное.
Между двумя точками преобразование линейное, т.е. необходимо найти ординату точки, лежащей на отрезке между известными двумя точками, и абсцисса искомой точки также известна.
Упрощенно мат.модель получается такая: y=((y1-y0)*(x-x0)/(x1-x0))+y0, где (x,y) - искомая точка, (x0,y0) и (x1, y1) - координаты концов отрезка.
Я решил делать сквозную трансляцию "на лету", и поэтому написал библиотечную функцию, которую использую в адресной метке. Для упрощения, у меня используется 17 тарировочных точек (т.к. контроллер ICPCON M-7017Z, которым я собираю данные, умеет замерять ток от 4 до 20 мА, и каждая точка у меня в тарировочной таблице соответствует целому миллиамперу). И в этом случае я могу без использования циклов чисто математически определить строку из таблицы, с помощью округления.
selection0 и 1 - номера точек (строк рецепта), между которыми находится тарируемая (градуируемая) точка.
adc0 и 1 - исходные значения АЦП, из таблицы.
real0 и 1 - итоговые значения из таблицы.
Для упрощения математического кода, ввел доп.переменные:
base_adc = input - adc0, это (x-x0) в мат.модели
delta_adc = adc1 - adc0, это (x1-x0) в мат.модели
delta_real = real1 - real0, это (y1-y0) в мат.модели
8bit писал(а):а ICPCON M-7017Z не мог сам это всё посчитать и выдать в панель готовый результат ?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7