Измерение веса руды по току статора. Практика. Часть 2. Программная реализация на МК.

Последняя часть из цикла «Измерение веса полезных ископаемых». В данной статье будет показана программная реализация на МК.

Вспомним основы данного метода измерение веса полезных ископаемых по току статора шахтной подъемной установки (ШПУ), оборудованной высоковольтным асинхронным двигателем с фазным ротором.



Вместо предисловия.

Так как реальное устройство не проектировалось и не изготавливалось, то для симулирования данного процесса использовался программный комплекс Proteus. Данный симулятор поддерживает множество различных МК и из списка им поддерживаемых выбиралась аппаратная платформа для реализации алгоритма и проверки всего метода.

Предисловие.

Для удобства проведения испытаний при симулировании, исходная схема в протеусе, показанная в первой части, претерпела изменения. Рассмотрим изменения.


Первый лист схемы.

Изменения коснулись в размножение сигнала напряжения, разрыва токовой цепи, введения индуктивной составляющей в цепь нагрузки.


Второй лист схемы.

Используется компонент ComPim, для связи с ком портом системы. МК фирмы Microchip. Входные сигналы с первого листа. Приборы (вольтметр, амперметр) для визуального контроля параметров напряжения и тока. Переключатели, используются для проведения автоматического вычисления средней точки каналов тока и напряжения.

Введение.

При написании программы для МК PIC18F2580 использовалась бесплатная IDE MpLab X v 2.26, компилятор XC8 v1.20.

Во время разработки программы, пришлось написать собственные математические функции:

  • извлечение квадратного корня из целого 32-х битного числа,
  • извлечение квадратного корня из числа с плавающей точкой одинарной точности,
  • умножение целых беззнаковых чисел 16 бит,
  • умножение целых знаковых чисел 16 бит.


Стандартные функции, которые компилятор использует, не подходили в плане быстродействия, это касается умножения 16х16. А библиотечной функции извлечения квадратного корня из целого 32-х битного числа вообще не нашлось.

Также в проекте использовались пользовательские типы переменных. Они введены для удобства использования.

Пользовательские типы переменных описаны в хидере user_type.h

Инициализация МК.

Инициализация МК вынесена в отдельный модуль в проекте. Производится согласно даташиту на МК. В хидере модуля инициализации включены конфигурационные биты (фьюзы). Для данных МК эти фьюзы можно зашить в прошивку, в .hex файл.

Вот хидер.

#include <xc.h>

/*
 Установка конфигурационных битов МК
*/
#pragma config IESO = OFF
#pragma config OSC = HSPLL      //HS oscillator, PLL enabled (Clock Frequency = 4 x FOSC1)
#pragma config MCLRE = ON       //MCLR pin enabled; RE3 input pin disabled
#pragma config XINST = OFF      //Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
#pragma config PBADEN = OFF     //PORTB<4:0> pins are configured as digital I/O on Reset

/*
 Прототипы функций инициализация периферии МК
 */
void INT_init(void);
void T0_init(void);
void ADC_init(void);
void USART_init(int BAUD);
void T2_init(void);
void PIC_init(void);


Инициализируем необходимую периферию собственной функцией.

Прерывания в данном МК имеют приоритет. Уровней всего два: высокий и низкий. Прерывание от таймера 0, по которому отсчитываем временные интервалы (семплы) для измерений сигналов напряжения и тока, имеет высокий приоритет, так как он критичный ко времени, остальные низкий.

Обработка сигналов с АЦП.

По прерыванию от детектора, который заведен на внешнее прерывание INT1, запускаем таймер с отсчетом 200 мкс интервала. По прерыванию таймера, загружаем в него предустановленное значения, для точного отсчета, и производим считывание значений АЦП с обоих каналов и выполняем предварительные вычисления.

if (Count_sample<SAMPLE){       //Если не достигли нужного количества измерений
        ADCON0bits.GO_DONE=1;       //Запускаем преобразование АЦП
        while(ADCON0bits.GO_DONE);  //Ждем окончание
        ADCON0bits.CHS0=0;          //Подключаем первый канал
        I_adc.byte.HB=ADRESH;
        I_adc.byte.LB=ADRESL;       //Считываем код АЦП
        I_int=(INT)I_adc.Val-I_0.Val;
        /*
         * Так как программные реализации умножения используют алгоритм без
         * использования аппаратного умножителя, пользуемся пользовательской
         * функцией для умножения с привлечением аппаратного умножителя 8х8
         * При симулировании программы встроенным симулятором, скорость
         * выполнения операции умножения 16х16=32 бита возросла почти в четыре раза,
         * количество инструкций уменьшилось
         * с 854 до 288 для беззнакового и до 302 для знакового произведения,
         * при чем пользовательская функция выполняется
         * практически в одном и том же диапазоне инструкций, независимо от значения
         * переменных входящих в произведение
         */
        I_sum+=(SLONG)mul_int(I_int,I_int);
        ADCON0bits.GO_DONE=1;       //Запускаем преобразование АЦП
        while(ADCON0bits.GO_DONE);  //Ждем окончание
        ADCON0bits.CHS0=1;          //Подключаем второй канал к модулю АЦП
        U_adc.byte.HB=ADRESH;
        U_adc.byte.LB=ADRESL;       //Считываем код АЦП
        U_int=(INT)U_adc.Val-U_0.Val;
        U_sum+=(SLONG)mul_int(U_int,U_int);
        P_act+=(SLONG)mul_sint(U_int,I_int);
        Count_sample++;
    }   
    if (Count_sample>=SAMPLE){      //Завершаем измерения, останавливаем таймер
        Count_sample=0;
        Flag_izm=1;
        T0CONbits.TMR0ON=0;
    }


В основном цикле, по флагу Flag_izm производим дополнительные промежуточные вычисления.

if (Flag_izm){                              //Производим расчеты
            Flag_izm=0;
            if (Count_main_sample<MAIN_SAMPLE){
                U_d+=(SLONG)U_sum;
                U_sum=0;
                I_d+=(SLONG)I_sum;
                I_sum=0;
                P_m+=(SLONG)P_act;
                P_act=0;
Count_main_sample++;
            }
}


Протокол ModBus RTU.

В данной реализации связь с «внешним» миром осуществляется с использованием USART МК, поверх данного интерфейса применен промышленный протокол ModBus RTU. Реализация данного протокола довольна проста и не ресурсоемка. Прием сообщений производится в прерывании от приемника USART.

/*обработчик прерывания от приемника уарт*/
    if (PIR1bits.RCIF){
        if (RCSTAbits.FERR || RCSTAbits.OERR) {         /*В случае ошибки приемника*/
            RCSTAbits.CREN=0;                           /*Отключаем приемник для сброса ошибки*/
            RCSTAbits.CREN=1;                           /*Включаем приемник для продолжения работы УАРТ*/
        }
        MODBUS.rxtimer=0;                               /*Сбрасываем таймер конца фрейма по приему очереднего байта*/
        if(MODBUS.rxcnt>(BUF_SZ-2)) MODBUS.rxcnt=0;
            MODBUS.buffer[MODBUS.rxcnt++]=RCREG1;        /*Записываем очередной байт в массив данных ModBus*/
        PIR1bits.RCIF=0;                                /*Сбрасываем флаг прерывания от приемника УАРТ*/
    }


Обработка сообщений от мастера происходит в основном цикле, когда критичные ко времени измерения закончены.

if (Flag_izm){                              //Производим расчеты
…
if (MODBUS.rxgap){                  //Если пришло сообщение
                    MODBUS_SLAVE(&MODBUS);          //обрабатываем его
                    MODBUS.rxgap=0;
                } 
}


Передача по USART организована не совсем оптимальным, блокирующим способом.

/*
 * Функция отправки сообщения мастеру
 */
void TX_FRAME(UART_DATA *MODBUS)
{
      RCSTAbits.CREN=0;
      TXSTAbits.TXEN=1;
      INTCONbits.GIEH=0;                                             /* во время передачи отключим прерывания*/
      INTCONbits.GIEL=0;
      while(MODBUS->txcnt<MODBUS->txlen){
         TXREG=MODBUS->buffer[MODBUS->txcnt++];
         while(!PIR1bits.TXIF) NOP();
      }
      INTCONbits.GIEH=1;
      INTCONbits.GIEL=1;
      MODBUS->txlen=0;
      RCSTAbits.CREN=1;
}


Заполнение таблицы регистров ModBus.

Протокол ModBus позволяет разработчику оборудования самому определять, какие регистры в карте за какой параметр будут отвечать. Нет каких то жестких правил в этом деле. Так что мы не будем придумывать что-то сложное и не разумное.

Начнем с первого регистра (нулевого). В него положим значение действующего напряжения в формате Real, то есть значение будет занимать два 16-ти битных регистра Modbus. Далее значение тока, активной мощности, полной мощности, косинуса.

                res_table[0].Val=U_real.word.LW;    //Заполняем таблицу регистров
                res_table[1].Val=U_real.word.HW;    //Модбас, для ответа мастеру
                res_table[2].Val=I_real.word.LW;
                res_table[3].Val=I_real.word.HW;
                res_table[4].Val=P_real.word.LW;
                res_table[5].Val=P_real.word.HW;
                res_table[6].Val=P_pol.word.LW;
                res_table[7].Val=P_pol.word.HW;
                res_table[8].Val=Cos_p.word.LW;
                res_table[9].Val=Cos_p.word.HW;


Теперь при запросе мастера значений данных регистров, устройство ответить вполне адекватными данными.

Для отображения данных от устройства, на данном этапе, воспользуемся OPC сервером. Его внутренних инструментов достаточно для отображения данных, записи значений в регистры и т.д.

Автоматическое определение средней точки каналов и расчет коэффициентов.

Для проведения измерений, нам необходимо вычислять среднюю точку синусоиды сигналов напряжения и тока. В данном случае, мы будем использовать алгоритм, расписанный в прошлой статье.
Для автоматического вычисления АЦП0 каналов, необходимо снять с них полезный сигнал, т.е. разорвать токовую петлю, в которую включен датчик тока ACS712 и подключить на вход напряжения среднюю точку с ОУ. Далее алгоритм, произведет вычисление среднеквадратичного значение сигнала, и по команде от мастера, мы вычисленные значения занесем в АЦП0 для каждого канала и запишем эти значения в EEPROM. После этого, подключим исследуемые сигналы напряжения и тока.

if (MODBUS.write){
            if (res_table[10].Val==1){          //Команда на автоматическое
                U_0.Val=(WORD)U_real.Val;       //вычисление АЦП0
                I_0.Val=(WORD)I_real.Val;
                eeprom_write(0,U_0.byte.HB);    //Записываем в еепром значения
                eeprom_write(1,U_0.byte.LB);    //АЦП0  по каналам
                eeprom_write(2,I_0.byte.HB);
                eeprom_write(3,I_0.byte.LB);
            }
}


Для вычисления коэффициентов воспользуемся следующим порядком действий. После вычисления средней точки каналов, подключения реальных сигналов на аналоговые входы, алгоритм вычисляет среднеквадратичное значение напряжения и тока в единицах АЦП. Для перевода их в физические величины необходимо измерить данные сигналы приборами, вольтметром и амперметром. Измеренные приборами значения записываем в нужные регистры Модбас, и по команде от мастера производим вычисление коэффициентов. Для уменьшения длины посылки по Модбас, в данной реализации, значение с приборов переводится к целочисленному значению путем умножения значения напряжения на 10, а значение тока на 100. Полученные данные записываются в регистры, и по команде от мастера производится расчет коэффициентов. Рассчитанные коэффициенты записываются в EEPROM.

if (MODBUS.write){
            if (res_table[10].Val==2){          //Команда на вычисление коэффициентов
                K_u.Val=U_real.Val/res_table[11].Val;   //тока и напряжения
                K_u.Val*=10.0;
                K_i.Val=I_real.Val/res_table[12].Val;
                K_i.Val*=100.0;
                eeprom_write(4,K_u.byte.MB);    //Записываем коэффициенты
                eeprom_write(5,K_u.byte.UB);
                eeprom_write(6,K_u.byte.HB);
                eeprom_write(7,K_u.byte.LB);
                eeprom_write(8,K_i.byte.MB);
                eeprom_write(9,K_i.byte.UB);
                eeprom_write(10,K_i.byte.HB);
                eeprom_write(11,K_i.byte.LB);
            }
            res_table[10].Val=0;
            MODBUS.write=0;
        }


Расчет веса.

Вес руды можно высчитывать непосредственно из формулы, приведенной в первой части повествования.



Где:

  • F0 – сила развиваемая двигателем при подъеме пустого сосуда,
  • F – сила, измеренная при подъеме груженного сосуда,
  • g – ускорение свободного падения в точки взвешивания.


В данной реализации измерение массы не производится, так как симулирование в Протеусе не предусматривает такую возможность.

Симуляция в протеусе позволяет понять жизнеспособность основной идеи: «Измерение веса руды во время транспортировки в подъемном сосуде по току статора».

Архив с проектом в MpLab X и файлом проекта протеуса находится здесь.

Видео, наглядно показывающее обработку сигналов напряжения и тока, вычисление активной мощности, косинуса фи и полной мощности показано ниже.



Заключение.

Измерение веса добытых полезных ископаемых в промышленности имеет большое значение в технологическом учете, оценки эффективности производимых работ и т.д.

Для измерения массы руды используется много различных видов и типов весовых устройств.

В данном цикле статей была рассмотрена возможность измерения веса руды, по измерению развиваемого момента приводного двигателя ШПУ во время транспортировки груза в подъемном сосуде. Данный способ используется в ШПУ снабженными двигателями постоянного тока, где вычисление массы производится по току якоря при постоянном возбуждении.

P.S.

Так как добыча полезных ископаемых в мире производится в больших объемах, и предпосылок на снижение нет, то этот способ измерения весы руды для технологического учета имеет право на жизнь. И может в недалеком будущем мы увидим промышленные устройства для измерения массы груза в подъемном сосуде, основанные на данном принципе.
  • -1
  • 28 января 2016, 11:12
  • Helix

Комментарии (25)

RSS свернуть / развернуть
Вес руды можно высчитывать непосредственно из формулы...
То есть предполагается, что средний ток при подъёме не меняется во времени?
И зависит только от массы груза?
0
Измерение производится на прямолинейном участке, при постоянной скорости вращения двигателя. В это время усилие F на окружности радиуса R, равно сумме усилий, необходимых для транспортировки груза массой Мгр, а также на преодоление сил шахтного сопротивления Fш и сил статической неуравновешенности Fст поднимаемой и опускаемой ветвей подъемной установки:
Так что в точке взвешивания ток прямо пропорционален массе поднимаемого груза.
В теоретической части расписано.
0
Но тогда где схема, определяющая «прямолинейность участка», контролирующая радиус?
Короче, где схема синхронизации? :)
0
Данный цикл расписывает метод взвешивание массы поднимаемого груза ШПУ. В теории расписано в какой точке производятся замеры, а как синхронизировать начало измерений в этой точке, разработчик устройства решит сам, исходя из конкретного подъема и т.д. Эти статьи не описывают создание ВУ (взвешивающего) на МК с «нуля».
0
Как ответил автор на подобный вопрос в предыдущем топике:
— Все будет калиброваться!
0
А не проще взять 3-фазный счётчик электроэнергии с шиной ModBus и разницу энергии считать на спуске и на подъёме? Появится некая дифференциальность, которая благотворно скажется на точности измерения веса :)
+2
Не вопрос. От этого сам метод останется неизменным. А считывание и обработку данных с счетчика кому то делать необходимо, хоть МК, хоть PLC — так что разработка устройства так и так.
0
Хотя измерять энергию потраченную за весь путь подъема и спуска смысла нет, так как она будет сильно варьироваться от манеры «езды» конкретной машинистки при неизменных величинах. «Взвешивать» все равно придется на прямолинейном участке.
0
Симуляция в протеусе позволяет понять жизнеспособность основной идеи: «Измерение веса руды во время транспортировки в подъемном сосуде по току статора».
Извините, но не соглашусь. То, что таким образом удастся что-то намерять, было понятно и без симуляции. А вот как полученные цифры будут коррелировать с весом руды в реальных условиях – вопрос открытый.
+2
Вот тут показано, как перевести замеры тока и напряжения в тонны груза. Из силы измеренной при подъеме вычесть силу при подъеме пустого сосуда и разделить на g, получим килограммы груза.
0
Да как перевести в тонны понятно, но это все теоретически.

Приведу другой пример: чтобы сделать БИНС можно взять трехосевой акселерометр и через двойное интегрирование перейти от ускорений к координатам. В теории это звучит красиво а вот на практике получится полная фигня, т. к. будет адски копится ошибка при интегрировании.

Вот и у Вас получается, что в теории все красиво, а вот какая получится практическая погрешность – это вопрос.
0
На счет погрешности, то да, пока не будут проведены полноценные испытания. Но оценить порядок погрешности можно теоретически. Для метрологии эта погрешность будет великовата, но для технологического учета вполне сносна. Тут измерения происходят в динамике, так что о «ювелирности» говорить не приходится.
0
Вообще-то это делается несколько по другому. Весоизмерительный пост в виде отрезка рельсошпальной решетки, опирающейся на 4-8 тензодатчиков. На них вагон заезжает с рудой. За счет того, что сцепка в вертикальном направлении не жесткая, погрешность измерений вполне достаточна даже для коммерческого учета (меньше 1%). Есть метод, который допускает динамическое взвешивание, на ходу.
0
тупо магнитное поле у двигателя не равномерное, правда циклическое. Потом с увеличением нагрузки увеличиваются и другие потери. Какие-то пропорционально, какие-то по кривой.
0
от увеличения температуры изменяется сопротивление обмоток, потокосцепление…
ну и в таком духе можно продолжать=))
0
Некоторые величины можно измерят и ввести в уравнение (температуры обмоток например).
0
Так и никто не мешает построить график силы/момента от массы поднимаемого груза по 5,6,10 точкам, аппроксимировать, и снизить погрешность. Для увеличения точности, снижения погрешности, необходимо провести целый комплекс мер. Все это в руках разработчиков.
0
У Вас будет n-е количество переменных (не все из них линейные) в данном уравнении. И чем больше n, тем выше точность.
З.Ы. Пора мне идти вспоминать матрицы… и операции с ними=))
0
У Вас будет n-е количество переменных

У нас было 2 нелинейных коэффициентов для компенсации влияния температуры, 3 матрицы для внесения уточняющих коэффициентов механических потерь, 5 нелинейных функций для электрических потерь и целое множество более мелких и линейных коэффициентов, а также дифуры высшего порядка описания процессов преобразования энергии в асинхронных машинах. Единственное, что вызывало у меня опасение — это дифуры. Но я знал, что рано или поздно мы перейдем и на эту дрянь.

:)
+1
+2
«Взвешивать» все равно придется на прямолинейном участке.
И это будет основным источником ошибки.
Я бы даже 2 счётчика поставил — на спуск и на подъём. И не проблема хоть за месяц план по подъёму определяй :) Тем более руководство интересуют «интегральные» характеристики. (Причём, чем выше «ранг», тем выше степень «интеграции» — мастера интересуют данные за смену, начальника участка — за сутки, директора — за месяц:)
0
И это будет основным источником ошибки.
Поясните почему?
Если одноконцевой подъем, то на спуске делать нечего и мерить нечего. Если с противовесом, то обязательно взвешиваем опускаемую ветвь, и отнимаем её при подъеме. На двуконцевых подъемах, измерение производится в обе стороны.
0
Всё прочитать не осилил, но смысл понятел по мощности потребления судить о массе переносимого груза, с учётом некоторых коэфициентов подбираемых опытным путём.
Так вот на этот счёт:
В нашем ведении есть почти весь конвеер(скоро весь) протяжённостью около 14км и состоит из 5-ти участков разной длины, который доставляет уголь от места добычи до электростанции. Так вот по мощности приводов конечно можно определить больше<->меньше угля туда сыпиться с погрешностью процентов 10%, но не лучше, а учёт угля комерческий, т.е. подобный метод измерения до одного места и не более чем игрушка в руках обслуживающего персонала и оператора, для нас как организации которая устанавливала привода на конвеер и делала АСУ ТП, конечно бывает полезным посмотреть в SCADA поведение конвеера с привязкой по мощностям, но как уже где-то здесь писали это больше не учёт массы груза, а отслеживание по этим показателям неисправностей.
Вообщее для учёта установлены весы, в нашем случае радиационые, которые имеют сертификат, проходят поверку периодически. А подобные системы без сертификата (на предложенную систему измерения вообще это будет проблематично, потому как привязка мощности к массе не постоянна в длительные промежутки времени) не нужны заказчикам.
+1
  • avatar
  • CHIP
  • 28 января 2016, 20:48
Кстати, стало интересно, решил глянуть на чем делают цифровые электросчетчики и какие там параметры АЦП. Первое, что нагуглилось — AD7755. У данной чипы АЦП 16 бит, частота 900 кГц. Поэтому мне кажется, что выбранные Вами параметры (10 бит 5120  Гц) дадут очень существенную погрешность при измерении мощности.
0
Только сейчас подумал, это же была моя идея :) косвенно измерять массу прицепленную к rc-серво. Но я даже ток не измерял.
+1
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.