Когда-то давно я написал статью про реакционные ароматизаторы. Прошло много времени, я вернулся к этому вопросу.
В этой статье я не буду вдаваться в подробности технологии разработки реакционных ароматизаторов, а расскажу о моем опыте автоматизировать свое рабочее время и поделюсь кодом, который может кому пригодится. В руки мне попался лабораторный химический реактор китайского производства и к большому сожалению в нем отсутствовали инструменты по автоматизации охлаждения, считывания и записи данных, программирования режимов, что было очень важно. Сам реактор представлял из себя обычную металлическую болванку на штативе, с ТЭНом до 350 градусов. За контроль температуры отвечает контроллер Yudian AI518.
Хорошей новостью для меня было наличие в нем порта RS-485.
Да, в Yudian AI518 есть таймеры и какие-то самые простые программы, но во-первых, очень было интересно сделать свой «блэк-джек» с окнами и кнопочками, а во вторых не очень удобно тыкать на штатный контроллер, хотелось бы это все делать на компьютере.
Так как у меня был опыт работы с контроллерами Arduino, изначально решил сделать общение и управление через него, потом уже появилась идея написать программку на Qt которая будет отвечать за управление и автоматизацию, а Arduino Mega за формирование и расшифровку пакетов с AI518.
Так как клапан включения холодной воды может находится на расстоянии от компьютера и самой установки, было принято решение соорудить еще дополнительный контроллер, который будет по команде включать/выключать клапан холодной воды и считывать-отправлять температуру охлаждения. Да, под конец проекта, я понял, что очень конструкция нагромождена, можно было бы свистком RS485 на компе и одной программой отделаться, но амбиции сделать собственный девайс подогревали интерес.
Итого в нашей связке:
- Штатный контроллер Yudian AI518.
- Arduino Mega + 2 конвертера RS485 (MAX485)
- Arduino nano + 1 конвертер RS485 (MAX485) + термопара + транзистор на 12V.
- Клапан холодной воды на 12V.
Первым делом, был написана структура общения между мегой и нано.
struct packet_arduino_pomp //пакет Arduino nano
{
byte start_byte_one;//в коротком пакете равен 212
byte start_byte_two;//в коротком пакете равен 211
byte temp_pomp;//температура охлаждения
byte on_of_pomp;//on-off насоса (1 или 0)
byte CRC8;//контрольная сумма
/*упаковать*/
void pask()
{
CRC8 = (start_byte_one + start_byte_two + temp_pomp + on_of_pomp + tmp) / 10;
}
/*проверка упаковки*/
bool test_pask()
{
if (CRC8 == (start_byte_one + start_byte_two + temp_pomp + on_of_pomp + tmp) / 10) return 0; //ОК
return 1; // ошибка
}
};
Когда все стабильно работало, я начал много читать про разные протоколы передачи данных, но не мог найти тот что мне нужен. Дело в том, что штатный контроллер Yudian AI518 общается с внешним миром по протоколу AIBUS, как я понял это китайский аналог MODBUS. (документация ) Делал я это первый раз и ориентируясь на документацию и помощь всех возможных форумов.
Структура исходящего пакета для Yudian AI518:
struct tagREQ_FRM_T
{
uint8_t u8DevAddr1;
uint8_t u8DevAddr2;
uint8_t u8ReqType;
uint8_t u8DevPara;
uint8_t u8LoParam;
uint8_t u8HiParam;
uint8_t u8LoSumCheck;
uint8_t u8HiSumCheck;
} ;
Структура входящего пакета для Yudian AI518:
struct tagANS_FRM_T
{
uint8_t u8LoPV;
uint8_t u8HiPV;
uint8_t u8LoSV;
uint8_t u8HiSV;
uint8_t u8MV;
uint8_t u8ALm;
uint8_t u8LoParam;
uint8_t u8HiParam;
uint8_t u8LoSumCheck;
uint8_t u8HiSumCheck;
};
По сути получилось, что на Mega приходят пакеты от всех устройств (от nano со значениями температуры охлаждения, от AI518 с обновленной температурой реактора и прочими значениями и команды от компьютера). Потом Мега все объединяла в один пакет и отправляла на компьютер, где его читала программа на QT.
Структура пакета мега-компьютер:
struct packet_big //пакет PC
{
byte start_byte_one;//в длинном пакете равен 254
byte start_byte_two;//в длинном пакете равен 232
byte temp_pomp;//температура охлаждения
byte on_of_pomp;//on-off насоса (1 или 0)
byte ex_temp_reactor_one;//текущая температура в реакторе 1
byte ex_temp_reactor_two;//текущая температура в реакторе 2
byte current_temp_reactor;//выставленная температура в реакторе
byte timer_ex;//таймер
byte tmp;//пока не трогаем
byte CRC8;//пока не трогаем
void pask()
{
CRC8 = (start_byte_one + start_byte_two + temp_pomp + on_of_pomp + ex_temp_reactor_one + ex_temp_reactor_two + current_temp_reactor + timer_ex + tmp) / 10;
}
/*проверка упаковки*/
bool test_pask()
{
if (CRC8 == ((start_byte_one + start_byte_two + temp_pomp + on_of_pomp + ex_temp_reactor_one + ex_temp_reactor_two + current_temp_reactor + timer_ex + tmp)) / 10) return 0; //ОК
return 1; // ошибка
}
};
Так как китайский протокол молчит, если отправленный пакет не подходит под описание, подбирая структуру, я вообще начал думать, что он сломан, но в итоге все получилось. Когда я увидел в логе первый корректные цифры, было счастье…
Для того чтобы обезопасить контроллер на Ардуино nano от влаги, решил вытравить свою собственную плату и поместить ее в корпус. Дело не хитрое, есть множество описаний как это делать, но выбрал я технологию ЛУТа. (ЛУТ). Самое сложное было подобрать подходящую глянцевую бумагу для струйника, на котором нормально печатает лазерный принтер. Но после всех проб и ошибок получилась вот такое устройство.
А как же программа на компьютере, с кнопочками и окнами. Благо на Qt такие вещи очень несложно делать. Формировать запросы и читать их с «басурманского» устройства мы умеем, теперь необходимо чтобы мы могли задавать режимы, строить график время-температура, выдавать в конце реакции отчет о скорости нагрева до выставленной температуры, собственно само время реакции, скорость охлаждения до определенной температурs и т.д. Объединив все это в отдельную структуру, по QSerialPort, через COM порт к которому подключается сама Ардуинка, передаем и принимаем значения.
Самое сложное, было скомпилировать готовый проект под Windows XP. К сожалению, на работе стоят именно эти системы и пришлось пару дней потанцевать с бубном, чтобы все заработало. Так как я это делал уже второй день, не осознанно и перебирая все предлагаемые варианты с форумов, точной инструкции не выложу.
В итоге получилась программа, которая работает и помогает мне на моем рабочем месте и экономит кучу времени (Проект QT выкладывать не буду, так как там ничего интересного. Передача данных через QSerialPort, а дальше, что душа пожелает).
Ссылки на прошивки для Ардуинок:
Автор: Ostapich