NooLite MT1132 — структура команд.

После общего знакомства с nooLite, начнем изучение вопросов неглупого освещения жилища от nooLite с модуля МТ1132. Этот модуль подключается к управляющему устройству через UART и принимает от него 12 байт. Если команда составлена правильно, на модуле загорается красный диод и команда транслируется на силовой блок, иначе ничего не происходит. (Производитель мог бы добавить мааааленький диодик на канал RX модуля, дабы неопытный пользователь понимал, что электрическая часть соединения исправно работает, а вот программистские навыки еще требуют совершенствования. Без диодика не всегда ясно, доходит ли сигнал до модуля в принципе, или нет. Хорошо, если под рукой есть осциллограф etc., а если — нет?)
Что же должен принять от управляющего устройства модуль? Ниже — картинка, где показана структура команды. Эта картинка несколько упрощена, но достаточна для работы с модулем, исключая случаи, когда он будет управлять трехцветной светодиодной лентой.

noolite

Сразу ухватить картинку удается не всегда, поэтому несколько пояснений.

Перечислим команды для ячейки 6:

0 — выключить нагрузку
1 — запустить плавное понижение яркости
2 — включить нагрузку
3 — запустить плавное повышение яркости
4 — включить или выключить нагрузку
5 — запустить плавное изменение яркости в обратном направлении
6 — установить заданную в «Байт данных 0» яркость
7 — вызвать записанный сценарий
8 — записать сценарий
9 — отвязка
10 — остановить регулировку
15 — привязка

Поскольку модуль может отправлять команды на 32 силовых блока,  он обязательно должен получить номер канала (0-31). Это элемент [5].

На силовой блок в элементе [2] будет отправлена одна из возможных команд.

Если это команда 6 (установить яркость), то в элемент [3] нужно записать  единицу, а в элемент [6] — значение яркости. Значение это ни в процентах, ни в привычных байтах, а просто, значение из ряда 35 — 155. Казалось бы, что мешало производителю привести эти значения к привычной амплитуде: 0 — 100, или 0 -255… Да, странно.

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

Поясню. Если команды в диапазоне 0 — 15, то значение ячеек [3] и [6] — ноль. А если мы отправим команду, например, 75, то автоматически ячейку [3] можно установить в единицу, а [2] — в 6. Позже мы напишем функцию, которая все это будет делать.

Элемент [10] представляет собой контрольную сумму. Все предыдущие элементы необходимо сложить, а потом взять лишь младший байт от сложения. В примере на сайте Ноотехники это делается так:

int checkSum = 0;
for(byte i = 0; i < 10; i++) {
    checkSum+= buf[i];
}
buf[10] = lowByte(checkSum);

Но следует заметить, что в обычном С нет функции lowByte(); поэтому правильно будет использовать следующую конструкцию:

buf[10] = checkSum & 0xFF;

Теперь разберемся с командами, то есть содержанием элемента [2].

0 — выключить нагрузку.
1 — запустить плавное понижение яркости, от текущего до выключения.
2 — включить нагрузку полностью.
3 — запустить плавное повышение яркости до максимума.
4 — включить или выключить нагрузку. Посылая одну единственную эту команду мы то включаем то выключаем силовой блок, в зависимости от предыдущего состояния.
5 — запустить плавное изменение яркости в обратном направлении. Эта команда плавно включает или выключает силовой блок, меняет его текущее состояние.
6 — установить заданную яркость.
9 — запустить процедуру стирания адреса (отвязать модуль от силового блока).
15 — привязка к силовому блоку.

Теперь напишем функцию, которая принимала бы два аргумента, и посылала на силовой блок правильную команду. За основу был взят пример с сайта Ноотехники.

void sendCommand(uint8_t channel, uint8_t command) {
	/*
	Мы не будем проверять command на допустимость.
	В данном случае command должно принимать значение 
	от 0 до 10, 15, 32 - 155. 
	
	Значение channel должно быть от 0 до 31.  
	
	Если по каким-то причинам Вы не уверены в том, что 
	эти аргументы могут не соответствовать требованиям,
	следует проверить их и осуществить возврат из функции
	до передачи команды MT1132.
	*/
	
	// Создаем массив из 12 элементов
	uint8_t buf[12];
	// Сначала заполняем массив понятными значениями 
	buf[0] = 85;
	buf[1] = 80;
	buf[4] = 0;
	buf[5] = channel;
	buf[7] = 0;
	buf[8] = 0;
	buf[9] = 0;
	buf[11] = 170; 
	// Если команда от 15 и меньше - это любая команда кроме управления яркостью
        // 6, отправлять не рекомендуется, но и в этом случае ничего страшного не произойдет  
	if (command < 16) {
		buf[2] = command;
	// В этом случае требуется обнуление элементов [3] и [6]
		buf[3] = 0;
		buf[6] = 0;
	}
	// Если команда от 32 до 155 - это управление яркостью
	else {
	// Значит настоящая команда - 6
		buf[2] = 6; 
	// Элемент [3] требует установки в 1
		buf[3] = 1;
	// А в элемент [6] передаем значение яркости.
		buf[6] = command;
	}
	// Вычисляем контрольную сумму
	int checkSum = 0;
	// Складываем первые 10 элементов
	for(uint8_t i = 0; i < 10; i++) {
		checkSum+= buf[i];
	}
	// Оставляем от сложения младший байт 
	buf[10] = checkSum & 0xFF;
	// Отправляем команду в UART
	for(uint8_t i=0;i<(12);i++) 
	{
		mySerial.write(buf[i]);
	} 
}

Таким образом, вызывая из программы эту функцию с аргументами 3,15 — мы можем привязать силовой блок к модулю, а каждая посылка аргументов 3,3 будет плавно включать или выключать его. Если же мы вызовем функцию с аргументами 3, 45 — мы лишь слегка включим нагрузку.

О практической реализации — в следующей заметке. А пока — как это работает:

Устраивает? Читаем дальше.

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

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s