Муфты электромонтажные от производителя Fucon

Бюджетная система автоматизации котельной установки загородного дома. Часть 2

Журнал РАДИОЛОЦМАН, октябрь 2016

Часть 1

Михаил Русских

Приводятся преимущества ОС Android для разработчиков аппаратного обеспечения, рассматриваются библиотеки PhysicaloidLibrary и AndroidPlot, описываются методы приема данных по интерфейсу USB, сохранения принятых данных в файл и считывания их из файла, визуализация этих данных в виде графика.

В первой части статьи была описана подсистема автоматизации жидкотопливной котельной установки, основанная на плате Arduino Uno и отвечающая за регулирование температуры отапливаемого помещения путем своевременного включения и отключения горелки с учетом показаний датчика температуры. В этой части будет рассмотрена подсистема визуализации, основанная на недорогом планшете на базе операционной системы Android.

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

ОС Android имеет ряд преимуществ, полезных для разработчиков программного и аппаратного обеспечения. Эта ОС предоставляет достаточно легкий доступ к аппаратным ресурсам мобильной платформы, на которой она установлена, а благодаря своему широкому распространению и поддержке многочисленными сообществами программистов в бесплатном доступе можно найти большое количество библиотек, значительно облегчающих написание программ для этой ОС. Программа, реализующая подсистему визуализации, была написана в среде разработки Eclipse на языке Java. Исходный код программы можно найти в [1]. Здесь будут рассмотрены основные моменты кода, а также библиотеки, упрощающие обмен данными по интерфейсу USB и создание визуально информативного интерфейса.

Как уже было сказано в предыдущей части, с платы Arduino Uno через интерфейсный модуль с микросхемой FT232RL на вход USB приходят данные, содержащие импульсы, поступившие с расходомера LS-04, и значения температуры, зарегистрированной датчиком LM335. Эти данные должны быть приняты в программе и впоследствии визуализированы. Для организации обмена данными по интерфейсу USB сегодня существует ряд библиотек, написанных на Java. Библиотека Physicaloid Library [2], использованная в данном случае, является одной из самых стабильных и простых в использовании. Эта библиотека изначально была разработана для организации связи Android-устройства с микроконтроллерными платами, подобными Arduino. С помощью нее также можно записывать прошивки в платы Arduino непосредственно из устройства на базе ОС Android.

Чтобы подключить библиотеку Physicaloid к проекту в среде разработки Eclipse, нужно в меню выбрать File → Import. В окне Select следует указать строку Existing Projects Into Workspace, в появившемся окне Import Projects по нажатию на кнопку Browse необходимо выбрать скачанный каталог Physicaloid Library и затем нажать Finish. После этого в окне Package Explorer следует нажать правой кнопкой на текущем проекте и выбрать Properties → Android, далее нажать на кнопку Add и выбрать PhysicaloidLibrary. Подключив таким образом данную библиотеку, можно с помощью несложных функций обмениваться данными с Arduino через адаптер интерфейсов USB-UART.

Библиотека функционирует через класс Physicaloid. Для работы с библиотекой сначала в методе onCreate нужно объявить его следующим образом:

mPhysicaloid = new Physicaloid(this);

После этого нужно открыть порт для приема данных. Это осуществляется с помощью метода open(). Код открытия порта для чтения данных выглядит так:

    if (!mPhysicaloid.isOpened()) {
      if (mPhysicaloid.open()) {

        mPhysicaloid.addReadListener(new ReadLisener() {
          @Override
          public void onRead(int size) {
           byte[] buf = new byte[size];
           mPhysicaloid.read(buf, size);
           readStr = new String(buf);
         }
      });
     }
    }

В этом коде после проверки с использованием условных операторов того, что порт открыт, с помощью метода addReadListener активируется «слушатель» порта, который принимает поступившие байты, формирует из них буферный массив buf, а затем преобразовывает его в строковый тип с последующей записью в переменную readStr.

Дальнейшей задачей приложения является расшифровка записанных в строковую переменную readStr данных. Для этого в классе run() основного потока (Thread) программы в блоке кода, предназначенном для получения истинных значений поступивших данных, с помощью метода length(), определяется длина строки readStr, затем с использованием метода split(””) выполняется расщепление этой строки на массив строк arr_str, состоящих из одного необходимого для нас символа. Далее каждый символ выделяется с помощью метода charAt(0) и преобразуется в целочисленное значение с последующим помещением в массив arr_int. После этого мы можем определить смысл символа, то есть понять, представляет ли он собой зашифрованную величину температуры или импульс.

Если текущий символ равен 1 (49 в представлении кодировки ASCII), то это значит, что через Arduino и адаптер USB-UART поступил импульс, изначально сгенерированный расходомером LS-04. При этом переменная программного счетчика импульсов cnt_ph инкрементируется.

Данные о температуре варьируются в определенном диапазоне. Программно ограничим этот диапазон от –35 °C до +35 °C. Помня, что перед пересылкой из Arduino в планшет температурного значения к нему прибавлялась величина 90, сформируем условие, при котором переменная программного счетчика количества поступивших температурных значений t_cnt будет инкрементироваться, если символ будет в диапазоне от 55 до 125. Получив целый ряд записанных в массив tmp_arr температурных значений, необходимо вычислить среднюю температуру за прошедший час, которая в итоге будет показана пользователю в статистике на экране планшета. С этой целью формируется цикл для расчета суммы всех температурных значений за час tmp_sum, затем эта сумма делится на количество этих температурных значений за час. Выглядит этот фрагмент кода следующим образом:

    for (int t = 1; t <= t_cnt; t++)
    {tmp_sum = tmp_sum + tmp_arr[t];}
    tmp_avr = tmp_sum/t_cnt;

В общем виде алгоритм приема и обработки информации о температуре и импульсах показан в виде блок-схемы на Рисунке 4.

Бюджетная система автоматизации котельной установки загородного дома
Рисунок 4. Блок-схема алгоритма приема и обработки информации о
температуре и импульсах.

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

Здесь year_str, month_str, day_str – год, месяц и день текущей даты, соответственно. Эти строковые переменные сначала были получены как целочисленные переменные с помощью специального класса Calendar, позволяющего получить текущую дату, а затем преобразованы в строковые.

Запись файл осуществляется с помощью следующего фрагмента кода:

    String filename1 = ”m” + year_str + month_str + day_str;
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
      openFileOutput(filename1, MODE_APPEND)));
    bw.write(hr_str + ”/” + get_cnt);
    bw.write(” ”);
    bw.close();

Здесь используется поток BufferedWriter bw для записи в файл. Открытие файла выполняется через метод openFileOutput, первым аргументом которого является имя файла, а второй аргумент указывает на режим записи. В нашем случае MODE_APPEND свидетельствует о том, что новые данные будут добавляться в конец файла, не затрагивая при этом предыдущих. Различные виды данных при записи разделяются символом «/». Так, переменная hr_str представляет час в строковом выражении. Переменная get_cnt сочетает в себе количество импульсов за час и среднюю температуру за час, разделенные также символом «/», поскольку ранее в коде она была определена как cnt_ph_str_fin + ”/” + tmp_str_fin. Каждая порция данных отделяется от других символом пробела. Закрытие потока записи данных в файл осуществляется с помощью команды bw.close().

Теперь полученную и сохраненную в памяти планшета информацию необходимо визуализировать для ее лучшего восприятия пользователем. Чтобы значительно облегчить эту задачу, следует воспользоваться библиотекой для построения графиков. В данном случае была задействована библиотека AndroidPlot [3], являющаяся бесплатной и довольно легкой в освоении и использовании. С помощью нее можно строить линейные графики, круговые диаграммы, точечные диаграммы и другие типы графиков. Она совместима с версиями Android 1.6 и выше.

Библиотека AndroidPlot подключается к проекту в среде Eclipse несколько иначе, чем библиотека PhysicaloidLibrary. Ее можно в виде готового Java-файла androidplot-core-0.6.0.jar (в данном случае использовалась версия 0.6.0) поместить в директорию libs проекта. Далее следует объявить зависимости и дополнить основной XML-файл, как показано в [4], с некоторыми изменениями под свой проект.

Первоочередной задачей данной системы визуализации является отображение в виде столбцовой диаграммы зависимости затраченных литров топлива от времени. Наглядно такую диаграмму, реализованную в приложении с помощью библиотеки AndroidPlot, можно представить на Рисунке 5.

Бюджетная система автоматизации котельной установки загородного дома
Рисунок 5. Диаграмма, показывающая количество сожженных литров топлива в
определенном временном промежутке.

На этом рисунке показаны почасовые затраты топлива за один день, дата которого вводится в три поля в формате дд.мм.гг, расположенные под текстом «Введите дату». После ввода даты и нажатия кнопки «Прочитать данные» формируется диаграмма на основе информации, полученной с платы Arduino. Для удобства просмотра графика за текущий день имеется кнопка «За сегодня», позволяющая сформировать диаграмму без ввода даты. Данный график наглядно демонстрирует расход топлива, что очень удобно для быстрого анализа, но не предоставляет точных цифр, поэтому у пользователя имеется возможность изменить графическое отображение на текстовое. Это осуществляется по нажатию кнопки «График/текст». Экран с текстовым отображением информации показан на Рисунке 6.

Бюджетная система автоматизации котельной установки загородного дома
Рисунок 6. Текстовое представление информации.

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

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

Рассмотрим процесс формирования графика за текущий день. Сначала график необходимо очистить от возможно уже имеющихся точек, нанесенных при предыдущем построении, чтобы данные не накладывались друг на друга. Это можно осуществить с помощью следующего фрагмента кода:

    int rollsize = rollHistorySeries.size();
     for (int i = 0; i < rollsize; i++) {
     rollHistorySeries.removeLast();
     }

Здесь сначала вычисляется размер графика, то есть количество имеющихся на нем точек, а затем в цикле поочередно удаляются все эти точки с помощью процедуры removeLast().

Далее, используя класс Calendar, вычисляется текущая дата с записью года, месяца и дня в строковые переменные year_str, month_str, day_str, соответственно. После этого формируется имя файла, из которого будут браться данные для отображения.

    String filename2 = ”m” + year_str + month_str + day_str;

Так же как и ранее создавался поток для записи информации в файл, так и теперь подобным образом создается поток для чтения из файла.

    BufferedReader br = new BufferedReader(new InputStreamReader(
      openFileInput(filename2)));

Далее формируется цикл с предусловием, который будет работать до тех пор, пока при считывании данных из файла не появится пустая строка, означающая конец файла. В этом цикле сначала разделяются через символ пробела совокупности данных, включающих в себя час и соответствующие ему импульсы и среднюю температуру. Затем уже сами эти элементы отделяются друг от друга символом «/» и записываются в соответствующие переменные hr_now, cnt_now и tmp_now. После этого создается цикл от 0 до 24 (количество часов в сутках), в котором происходит формирование графика и запись информации об импульсах и температуре в массивы для последующего их отображения в текстовом виде. Фрагмент кода с циклом выглядит следующим образом:

    for (int n = 0; n < 24; n++) {
      if (hr_now==n) {
      rollHistorySeries.addLast(hr_now, cnt_now*0.005);
        rollHistorySeries.addLast(hr_now+1, cnt_now*0.005);
        hr_ch[n]=cnt_now*0.005;
        tmp_ch[n]=tmp_now;
     } else {
       rollHistorySeries.addLast(n, 0);
       rollHistorySeries.addLast(n+1, 0);
  }
}

Здесь с помощью rollHistorySeries. addLast на график добавляется точка, у которой координата по оси абсцисс выражает час, а по оси ординат количество литров, являющееся произведением числа импульсов за этот час на коэффициент 0.005 л/имп расходомера LS-04, описанного в предыдущей части. Все точки графика соединяются сплошной линией, и область, оставшаяся под точками и их соединительными линиями, закрашивается цветом. Таким образом, две идущие последовательно команды rollHistorySeries.addLast с одинаковым вторым аргументом и отличающимся на 1 первым аргументом формируют на графике столбец, показывающий количество затраченных литров в течение определенного часа. Для того чтобы все введенные точки и линии отобразились на графике, необходимо перерисовать график. Это осуществляется с помощью одной команды aprHistoryPlot.redraw(). Далее следует вывод данных в текстовом формате, который линеен и достаточно прост, поэтому не нуждается в дополнительном описании. Алгоритм отображения данных в графическом формате можно представить в виде блок-схемы на Рисунке 7.

Бюджетная система автоматизации котельной установки загородного дома
Рисунок 7. Блок-схема алгоритма отображения данных в графическом формате.

При вводе определенной даты принцип обработки данных и их отображения в целом аналогичен, за исключением некоторых моментов. Так, программа сначала определяет, какой временной диапазон был задан пользователем: день, месяц или год. В случае если выбран один конкретный день, срабатывает такой же алгоритм, как и описанный выше, только вместо текущей даты используется дата выбранного дня. Если пользователя интересуют данные за один месяц или за целый год, то программа считывает все файлы за этот период, суммируя импульсы и высчитывая среднюю температуру. При этом на графике формируются не 24 столбца, а 30 (28, 29, 31 в зависимости от месяца) при выводе данных за месяц, либо 12 при выводе данных за год.

Таким образом, создание приложения для визуализации данных системы автоматизации котельной с использованием библиотек PhysicaloidLibrary и AndroidPlot представляет собой довольно простой процесс. Эти библиотеки и описанные в данном материале методы формирования графиков и подключения устройства на базе ОС Android к платам типа Arduino можно использовать в других проектах, где необходима несложная визуализация данных, полученных от внешних устройств.

Ссылки

Электронные компоненты. Бесплатная доставка по России
Для комментирования материалов с сайта и получения полного доступа к нашему форуму Вам необходимо зарегистрироваться.
Имя