#include "iarduino_I2C_Keyboard.h"																									//
#include "iostream"
																																//
//		Инициализация модуля:																										//	Возвращаемое значение: результат инициализации.
bool	iarduino_I2C_Keyboard::begin			(void){																				//	Параметр: отсутствует
		//	Проверяем корректность введённых значений «valCols» и «valRows»:														//	«valCols» - количество кнопок в линии, «valRows» - количество линий с кнопками.
			if(valRows==0  ||  valCols==0)												{	valAddr=0; return false; }else			//	Количество кнопок не может равняться 0.
			if(valRows==1){ if(valCols>10)												{	valAddr=0; return false;}}else			//	Если у модуля кнопки располагаются в одну линию (valRows==1), то в ней          не может быть более 10 кнопок.
			if(valRows==2){ if(valCols> 5)												{	valAddr=0; return false;}}else			//	Если у модуля кнопки располагаются в две  линии (valRows==2), то в каждой линии не может быть более 5  кнопок.
			if(valRows==3){ if(valCols!=3)												{	valAddr=0; return false;}}else			//	Если у модуля кнопки располагаются в три  линии (valRows==3), то в каждой линии должно   быть по    3  кнопки.
																						{	valAddr=0; return false;}				//	Если у модуля кнопки располагаются иначе, то эта библиотека не для него.
		//	Создаём строку символов присваиваемых клавишам.																			//
			for(int i=0; i<10; i++){																								//	Проходим по всем возможным номерам кнопок.
				if(valRows==3){          arrEncoding[i]=( i   <9      )? (i==9?'0':i+1+'0'          ):' '; }						//	Заполняем строку arrEncoding символами от 1 до 9.
				if(valRows==1){          arrEncoding[i]=( i   <valCols)? (i==9?'0':i+1+'0'          ):' '; }						//	Заполняем строку arrEncoding символами от 1 до valCols.
				if(valRows==2){ if(i<5){ arrEncoding[i]=( i   <valCols)? (i==9?'0':i+1+'0'          ):' '; }						//	Заполняем строку arrEncoding символами от 1 до valCols.
								else   { arrEncoding[i]=((i-5)<valCols)? (i==9?'0':i+1+'0'+valCols-5):' '; }						//	Заполняем строку arrEncoding символами от valCols до valCols*2.
				}																													//
			}																														//
		//	Инициируем работу с шиной I2C:																							//
			objI2C->begin(100);																										//	Инициируем передачу данных по шине I2C на скорости 100 кГц.
		//	Если адрес не указан, то ищим модуль на шине I2C:																		//
			if(valAddrTemp==0){																										//
				for(int i=1; i<127; i++){																							//	Проходим по всем адресам на шине I2C
					if( objI2C->checkAddress(i)											){	valAddr=i; delay(2);					//	Если на шине I2C есть устройство с адресом i, то используем этот адрес для проверки найденного модуля...
					if(_readBytes(REG_MODEL,4)											){											//	Читаем 4 байта начиная с регистра «REG_MODEL» в массив «data».
					if( data[0]     == DEF_MODEL_KBD									){											//	Если у модуля с адресом i в регистре «MODEL»   (data[0]) хранится значение DEF_MODEL_KBD, то ...
					if((data[2]>>1) == i                 || data[2] == 0xFF				){											//	Если у модуля с адресом i в регистре «ADDRESS» (data[2]) хранится значение i (адрес+младший бит) или 0xFF (адрес не задавался), то ...
					if( data[3]     == DEF_CHIP_ID_FLASH || data[3] == DEF_CHIP_ID_METRO){											//	Если у модуля с адресом i в регистре «CHIP_ID» (data[3]) хранится значение DEF_CHIP_ID_FLASH (идентификатор модулей Flash), или DEF_CHIP_ID_METRO (идентификатор модулей Metro), то ...
						valAddrTemp=i; i=128;																						//	Считаем что модуль обнаружен, сохраняем значение i как найденный адрес и выходим из цикла.
					}}}}}																											//
				}																													//
			}																														//
		//	Если модуль не найден, то возвращаем ошибку инициализации:																//
			if( valAddrTemp == 0														){	valAddr=0; return false;}				//
		//	Проверяем наличие модуля на шине I2C:																					//
			if( objI2C->checkAddress(valAddrTemp) == false								){	valAddr=0; return false;}				//	Если на шине I2C нет устройств с адресом valAddrTemp, то возвращаем ошибку инициализации
			valAddr=valAddrTemp;																									//	Сохраняем адрес модуля на шине I2C.
		//	Проверяем значения регистров модуля:																					//
			if(_readBytes(REG_MODEL,4)==false											){	valAddr=0; return false;}				//	Если не удалось прочитать 4 байта в массив «data» из модуля начиная с регистра «REG_MODEL», то возвращаем ошибку инициализации.
			if( data[0]     != DEF_MODEL_KBD											){	valAddr=0; return false;}				//	Если значение  регистра «MODEL»   (data[0]) не совпадает со значением DEF_MODEL_KBD, то возвращаем ошибку инициализации.
			if((data[2]>>1) != valAddrTemp       && data[2] !=0xFF						){	valAddr=0; return false;}				//	Если значение  регистра «ADDRESS» (data[2]) не совпадает с адресом модуля и не совпадает со значением 0xFF, то возвращаем ошибку инициализации.
			if( data[3]     != DEF_CHIP_ID_FLASH && data[3] != DEF_CHIP_ID_METRO		){	valAddr=0; return false;}				//	Если значение  регистра «CHIP_ID» (data[3]) не совпадает со значением DEF_CHIP_ID_FLASH и DEF_CHIP_ID_METRO, то возвращаем ошибку инициализации.
			valVers=data[1];																										//	Сохраняем байт регистра «VERSION» (data[1]) в переменую «valVers».
		//	Перезагружаем модуль устанавливая его регистры в значение по умолчанию:													//
			reset();																												//	Выполняем программную перезагрузку.
			delay(5);																												//
			return true;																											//	Возвращаем флаг успешной инициализаии.
}																																	//
																																	//
//		Перезагрузка модуля:																										//	Возвращаемое значение:	результат перезагрузки.
/*
bool	iarduino_I2C_Keyboard::reset			(void){																				//	Параметр:				отсутствует.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Устанавливаем бит перезагрузки:																						//
				if(_readBytes(REG_BITS_0,1)==false){return false;}																	//	Читаем 1 байт регистра «BITS_0» в массив «data».
				data[0] |= 0b10000000;																								//	Устанавливаем бит «SET_RESET»
				if(_writeBytes(REG_BITS_0,1)==false){return false;}																	//	Записываем 1 байт в регистр «BITS_0» из массива «data».
			//	Ждём установки флага завершения перезагрузки:																		//
				do{ if(_readBytes(REG_FLAGS_0,1)==false){return false;} }															//	Читаем 1 байт регистра «REG_FLAGS_0» в массив «data».
				while( (data[0]&0b10000000) == 0);																					//	Повторяем чтение пока не установится флаг «FLG_RESET».
				return true;																										//
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return false;																										//	Возвращаем ошибку
			}																														//
}																																	//
*/
bool	iarduino_I2C_Keyboard::reset			(void){																				//	Параметр:				отсутствует.
			if(valAddr){																										//	Если модуль был инициализирован, то ...
			//	Устанавливаем бит перезагрузки:																					//
				if(_readBytes(REG_BITS_0,1)==false){return false;}																//	Читаем 1 байт регистра «BITS_0» в массив «data».
				data[0] |= 0b10000000;																							//	Устанавливаем бит «SET_RESET»
				if(_writeBytes(REG_BITS_0,1)==false){return false;}																//	Записываем 1 байт в регистр «BITS_0» из массива «data».
			//	Ждём установки флага завершения перезагрузки:																	//
                delay(500);
                /*
                int counter = 0;
				do {
                    if(_readBytes(REG_FLAGS_0,1)==false) {
                        return false;
                    }
                    delay(1);
                    counter++;
                }														//	Читаем 1 байт регистра «REG_FLAGS_0» в массив «data».
				while(((data[0]&0b10000000) == 0) || (counter < 50));																				//	Повторяем чтение пока не установится флаг «FLG_RESET».
                */
                //std::cout << "i'm here" << '\n';
				return true;																									//
			}else{																												//	Иначе, если модуль не инициализирован, то ...
				return false;																									//	Возвращаем ошибку
			}																													//
}																																//
																																	//
//		Смена адреса модуля:																										//	Возвращаемое значение:	резульат смены адреса.
bool	iarduino_I2C_Keyboard::changeAddress	(uint8_t newAddr){																	//	Параметр:				newAddr - новый адрес модуля (0x07 < адрес < 0x7F).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Проверяем новый адрес:																								//
				if(newAddr>0x7F){newAddr>>=1;}																						//	Корректируем адрес, если он указан с учётом бита RW.
				if(newAddr==0x00 || newAddr==0x7F){return false;}																	//	Запрещаем устанавливать адрес 0x00 и 0x7F.
			//	Записываем новый адрес:																								//
				if(_readBytes(REG_BITS_0,1)==false){return false;}																	//	Читаем 1 байт регистра «BITS_0» в массив «data».
				data[0] |= 0b00000010;																								//	Устанавливаем бит «SAVE_ADR_EN»
				if(_writeBytes(REG_BITS_0,1)==false){return false;}																	//	Записываем 1 байт в регистр «BITS_0» из массива «data».
				data[0] = (newAddr<<1)|0x01;																						//	Готовим новый адрес к записи в модуль, установив бит «SAVE_FLASH».
				if(_writeBytes(REG_ADDRESS,1)==false){return false;}																//	Записываем 1 байт в регистр «ADDRESS» из массива «data».
				delay(200);																											//	Даём более чем достаточное время для применения модулем нового адреса.
			//	Проверяем наличие модуля с новым адресом на шине I2C:																//
				if(objI2C->checkAddress(newAddr)==false){return false;}																//	Если на шине I2C нет модуля с адресом newAddr, то возвращаем ошибку.
				valAddr     = newAddr;																								//	Сохраняем новый адрес как текущий.
				valAddrTemp = newAddr;																								//	Сохраняем новый адрес как указанный.
				return true;																										//	Возвращаем флаг успеха.
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return false;																										//	Возвращаем ошибку
			}																														//
}																																	//
																																	//
//		Получение флага наличия подтяжки линий шины I2C:																			//	Возвращаемое значение:	флаг наличия подтяжки линий шины I2C.
bool	iarduino_I2C_Keyboard::getPullI2C		(void){																				//	Параметр:				отсутствует.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Считываем первые два регистра: регистр флагов и регистр битов:														//
				if(_readBytes(REG_FLAGS_0,2)==false ){ return false; }																//	Читаем 2 байта начиная с регистра «REG_FLAGS_0» в массив «data».
			//	Проверяем поддерживает ли модуль управление подтяжкой линий шины I2C:												//
				if( (data[0] & 0b00000100) == false ){ return false; }																//	Если флаг «FLG_I2C_UP» регистра «REG_FLAGS_0» сброшен, значит модуль не поддерживает управление подтяжкой линий шины I2C.
			//	Проверяем установлена ли подтяжка линий шины I2C:																	//
				if( (data[1] & 0b00000100) == false ){ return false; }																//	Если бит  «SET_I2C_UP» регистра «REG_BITS_0»  сброшен, значит подтяжка линий шины I2C не установлена.
				return true;																										//	Возвращаем флаг успеха.
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return false;																										//	Возвращаем ошибку.
			}																														//
}																																	//
																																	//
//		Установка подтяжки линий шины I2C:																							//	Возвращаемое значение:	результат установки подтяжки линий шины I2C.
bool	iarduino_I2C_Keyboard::setPullI2C		(bool f){																			//	Параметр:				флаг подтяжки линий шины I2C.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Считываем первые два регистра: регистр флагов и регистр битов:														//
				if(_readBytes(REG_FLAGS_0,2)==false ){ return false; }																//	Читаем 2 байта начиная с регистра «REG_FLAGS_0» в массив «data».
			//	Проверяем поддерживает ли модуль управление подтяжкой линий шины I2C:												//
				if( (data[0] & 0b00000100) == false ){ return false; }																//	Если флаг «FLG_I2C_UP» регистра «REG_FLAGS_0» сброшен, значит модуль не поддерживает управление подтяжкой линий шины I2C.
			//	Устанавливаем или сбрасываем бит включения подтяжки линий шины I2C:													//
				if(f){ data[0] = (data[1] |  0b00000100); }																			//	Если флаг «f» установлен, то копируем значение из 1 в 0 элемент массива «data» установив бит «SET_I2C_UP».
				else { data[0] = (data[1] & ~0b00000100); }																			//	Если флаг «f» сброшен   , то копируем значение из 1 в 0 элемент массива «data» сбросив   бит «SET_I2C_UP».
			//	Сохраняем получившееся значение в регистр «REG_BITS_0»:																//
				if(_writeBytes(REG_BITS_0,1)==false ){ return false; }																//	Записываем 1 байт в регистр «REG_BITS_0» из массива «data».
				return true;																										//	Возвращаем флаг успеха.
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return false;																										//	Возвращаем ошибку
			}																														//
}																																	//
																																	//
//		Получение количества байтов доступных для чтения:																			//	Возвращаемое значение:	количество байт (0-255).
uint8_t	iarduino_I2C_Keyboard::available		(void){																				//	Параметр:				отсутствует.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Считываем значение счётчика буфера FIFO:																			//
				if(_readBytes(REG_KBD_FIFO_COUNTER,1)==false ){ return 0; }															//	Читаем 1 байт из регистра «REG_KBD_FIFO_COUNTER» в массив «data».
				return data[0];																										//	Возвращаем 1 байт из массива «data».
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return 0;																											//	Возвращаем 0.
			}																														//
}																																	//
																																	//
//		Чтение одного символа из буфера истории нажатий клавиш:																		//	Возвращаемое значение:	символ присвоенный кнопке в момент её нажатия.
char	iarduino_I2C_Keyboard::readChar			(void){																				//	Параметр:				отсутствует.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Считываем значение первого байта из буфера FIFO:																	//
				if(_readBytes(REG_KBD_FIFO,1)==false ){ return ' '; }																//	Читаем 1 байт (номер кнопки) из регистра «REG_KBD_FIFO» в массив «data».
				if(data[0]>9){return ' ';}																							//	Если значение байта (номера кнопки) превышает количество кнопок, то возвращаем пробел.
				return arrEncoding[data[0]];																						//	Возвращаем символ по номеру кнопки.
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return ' ';																											//	Возвращаем пробел.
			}																														//
}																																	//
																																	//
//		Чтение строки из буфера истории нажатий клавиш:																				//	Возвращаемое значение:	количество прочитанных символов (0-255).
uint8_t	iarduino_I2C_Keyboard::readString		(uint8_t* str, uint8_t len, bool end){													//	Параметры:				str - указатель на строку получатель символов, len - ограничение количества читаемых символов (1-254), end - флаг (true/false) указывает добавить символ конца строки.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Считываем значение счётчика буфера FIFO:																			//
				if(_readBytes(REG_KBD_FIFO_COUNTER,1)==false ){ return 0; }															//	Читаем 1 байт из регистра «REG_KBD_FIFO_COUNTER» в массив «data».
				if( data[0]==0  ){ return 0; }																						//	Если счётчик буфера FIFO обнулён, то возвращаем 0 прочитанных символов.
				if( data[0]>len ){ data[0]=len;  }																					//	Если счётчик буфера FIFO превышает значение «len», то далее будем читать «len» байт.
			//	Читаем номера кнопок из буфера FIFO модуля в строку «str», но не более «len» байт:									//	Выполняем чтение в цикле, т.к. в одном пакете можно прочесть не более 32 байт
				for(uint16_t i=0, f=0, j=10; i<data[0]; i+=32){																		//	Определяем флаг «f» успешного чтения данных и переменную «j» для подсчёта количества оставшихся попыток чтения.
					do{f=objI2C->readBytes(valAddr,REG_KBD_FIFO,&str[i],(data[0]>=(i+32)?32:(data[0]%32)));j--;if(!f){delay(1);}}	//	Считываем из модуля «valAddr», начиная с регистра «REG_KBD_FIFO», в строку «str», «data[0]» байт.
					while(!f && j>0);																								//	При неудаче «!f» повторяем чтение, но не более «j» раз.
					delayMicroseconds(500);																							//	Между пакетами чтения необходимо выдерживать паузу.
					if(!f) { str[0]=0; return 0; }																					//	Если чтение одного из пакетов данных выполнено неудачно, то добавляем символ конца строки в начало строки «str» и возвращаем 0 символов.
				}	if(end){ str[data[0]]=0;}																						//	Добавляем символ конца строки в строку «str».
			//	Преобразуем номера кнопок в символы:																				//
				for(uint16_t i=0; i<data[0]; i++){ if(str[i]>9){str[i]=0; return i;} str[i]=arrEncoding[str[i]]; }					//	Возвращаем количество символов.
				return data[0];																										//	Возвращаем количество символов.
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return 0;																											//	Возвращаем 0 символов.
			}																														//
}																																	//
																																	//
//		Очистка буфера истории нажатий клавиш:																						//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::flush			(void){																				//	Параметр:				отсутствует.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
					// omg..
				_writeBytes(REG_KBD_FIFO_COUNTER,1);
			//	Записываем любое значение в счётчик буфера FIFO:																	//
				//if(_writeBytes(REG_KBD_FIFO_COUNTER,1)==false ){ return false; }													//	Записываем 1 любой байт в регистр «REG_KBD_FIFO_COUNTER» из массива «data».
				//return true;																										//	Возвращаем флаг успеха.
			}
			/*
			else{																													//	Иначе, если модуль не инициализирован, то ...
				return false;																										//	Возвращаем ошибку
			}																														//
			*/
}																																	//
																																	//
//		Присвоение символа кнопке:																									//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::setEncoding		(uint8_t col, uint8_t row, char	sym){												//	Параметры:				col - номер кнопки в ряду (1-5), row - номер ряда кнопки (1-3), символ присваиваемый кнопке (кроме символа с кодом 255).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Проверяем корректность введённых значений «col» и «row»:															//
				if(col==0 || col>valCols){return;}																					//	Номер кнопки в ряду не может быть меньше 1 или больше объявленного количества кнопок в ряду.
				if(row==0 || row>valRows){return;}																					//	Номер ряда кнопки   не может быть меньше 1 или больше объявленного количества рядов.
				if(sym==0               ){return;}																					//	Запрещаем кнопке присваивать символ конца строки.
			//	Сохраняем символ «sym» в рассчитанную позицию строки «arrEncoding»:													//
				arrEncoding[(row-1)*(valRows==2?5:valCols)+col-1]=sym;																//
			}																														//
}																																	//
																																	//
//		Присвоение символов множеству кнопок:																						//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::setEncoding		(const char* str){																	//	Параметр:				строка присваиваемых символов.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				for(uint8_t i=1, k=0; i<=valRows; i++){																				//	Проходим по всем доступным рядам с кнопками.
				for(uint8_t j=1;      j<=valCols; j++){																				//	Проходим по всем доступным кнопкам в ряду.
					if(k<strlen(str)){setEncoding(j,i,str[k]);} k++;																//	Присваиваем очередной символ из строки «str» кнопке (j,i).
				}}																													//
			}																														//
}																																	//
																																	//
//		Получение символа присвоенного кнопке:																						//	Возвращаемое значение:	символ присвоенный кнопке.
char	iarduino_I2C_Keyboard::getEncoding		(uint8_t col, uint8_t row){															//	Параметры:				col - номер кнопки в ряду (1-5), row - номер ряда кнопки (1-3), символ присваиваемый кнопке (кроме символа с кодом 255).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Проверяем корректность введённых значений «col» и «row»:															//
				if(col==0 || col>valCols){return 0;}																				//	Номер кнопки в ряду не может быть меньше 1 или больше объявленного количества кнопок в ряду.
				if(row==0 || row>valRows){return 0;}																				//	Номер ряда кнопки   не может быть меньше 1 или больше объявленного количества рядов.
			//	Возвращаем символ строки «arrEncoding» из рассчитанной позиции:														//
				return arrEncoding[(row-1)*(valRows==2?5:valCols)+col-1];															//
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return 0;																											//	Возвращаем символ конца строки.
			}																														//
}																																	//
																																	//
//		Получение порядкового номера кнопки по символу:																				//	Возвращаемое значение:	порядковый номер кнопки (1-10).
uint8_t	iarduino_I2C_Keyboard::getEncoding		(const char	sym){																	//	Параметр:				sym - символ присвоенный кнопке (кроме символа с кодом 255).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				for(uint8_t i=1, k=1; i<=valRows; i++){																				//	Проходим по всем доступным рядам с кнопками.
				for(uint8_t j=1;      j<=valCols; j++){																				//	Проходим по всем доступным кнопкам в ряду.
					if(sym==getEncoding(j,i)){return k;} k++;																		//	Если символ «sym» совпал с символом присвоенным очередной кнопке, то выводим порядковый номер данной кнопки.
				}}																													//
				return 0;																											//	Возвращаем ошибку.
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return 0;																											//	Возвращаем ошибку.
			}																														//
}																																	//
																																	//
//		Установка времени задержки от нажатия на кнопку до принятия её удерживаемой:												//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::setDelay			(uint16_t tim){																		//	Параметр:				время до 25'500 мс.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Проверяем и преобразуем указанное время задержки из тысячных в десятые доли секунд:									//
				if(tim>25500){tim=25500;} data[0]=tim/100; if(tim%100){data[0]++;}													//	Ограничиваем время значением 25'500 мс, преобразуем значение из тысячных в десятые доли секунд, если в значении «tim» есть единицы или десятки миллисекунд, то увеличиваем время «data[0]» на одну десятую долю секунды.
			//	Сохраняем получившееся значение в регистр «REG_KBD_FIFO_HOLD»:														//
				_writeBytes(REG_KBD_FIFO_HOLD,1);																					//	Записываем 1 байт в регистр «REG_KBD_FIFO_HOLD» из массива «data».
				delay(30);																											//	Ждём 30 мс, так как время задержки сохраняется в EEPROM модуля.
			}																														//
}																																	//
																																	//
//		Получение времни задержки от нажатия на кнопку до принятия её удерживаемой:													//	Возвращаемое значение:	время до 25'500 мс.
uint16_t iarduino_I2C_Keyboard::getDelay		(void){																				//	Параметр:				отсутствует.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Считываем значение регистра «REG_KBD_FIFO_HOLD»:																	//
				if(_readBytes(REG_KBD_FIFO_HOLD,1)==false ){ return 0; }															//	Читаем 1 байт из регистра «REG_KBD_FIFO_HOLD» (время в десятых долях секунд) в массив «data».
				return (uint16_t)data[0]*100;																						//	Возвращаем время в миллисекундах.
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return 0;																											//	Возвращаем ошибку 0 миллисекунд.
			}																														//
}																																	//
																																	//
//		Установка периода повтора записи удерживаемой кнопки в буфер FIFO:															//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::setPeriod		(uint16_t tim){																		//	Параметр:				время до 2'550 мс.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Проверяем и преобразуем указанное время задержки из тысячных в сотые доли секунд:									//
				if(tim>2550){tim=2550;} data[0]=tim/10; if(tim%10){data[0]++;}														//	Ограничиваем время значением 2'550 мс, преобразуем значение из тысячных в сотые доли секунд, если в значении «tim» есть единицы миллисекунд, то увеличиваем время «data[0]» на одну сотую долю секунды.
			//	Сохраняем получившееся значение в регистр «REG_KBD_FIFO_REPLAY»:													//
				_writeBytes(REG_KBD_FIFO_REPLAY,1);																					//	Записываем 1 байт в регистр «REG_KBD_FIFO_REPLAY» из массива «data».
				delay(30);																											//	Ждём 30 мс, так как время задержки сохраняется в EEPROM модуля.
			}																														//
}																																	//
																																	//
//		Получение периода повтора записи удерживаемой кнопки в буфер FIFO:															//	Возвращаемое значение:	время до 2'550 мс.
uint16_t iarduino_I2C_Keyboard::getPeriod		(void){																				//	Параметр:				отсутствует.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Считываем значение регистра «REG_KBD_FIFO_REPLAY»:																	//
				if(_readBytes(REG_KBD_FIFO_REPLAY,1)==false ){ return 0; }															//	Читаем 1 байт из регистра «REG_KBD_FIFO_REPLAY» (время в сотых долях секунд) в массив «data».
				return (uint16_t)data[0]*10;																						//	Возвращаем время в миллисекундах.
			}else{																													//	Иначе, если модуль не инициализирован, то ...
				return 0;																											//	Возвращаем ошибку 0 миллисекунд.
			}																														//
}																																	//
																																	//
//		Получение флага состояния, события или времени удержания кнопки:															//	Возвращаемое значение:	флаг состояния, события или время удержания кнопки.
uint16_t iarduino_I2C_Keyboard::getKey			(uint8_t col, uint8_t row, uint8_t type){											//	Параметр:				col - номер кнопки в ряду (1-5), row - номер ряда кнопки (1-3), type - тип получаемого состояния или собития.
			//std::cout << "entering" << '\n';
			uint16_t f=0;																											//
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Проверяем корректность введённых значений «col» и «row»:															//
				if(col!=KEY_ALL || row!=KEY_ALL){																					//	Если выбраны не все кнопки клавиатуры, то ...
					if(col==0   || col> valCols){return 0;}																			//	Номер кнопки в ряду не может быть меньше 1 или больше объявленного количества кнопок в ряду.
					if(row==0   || row> valRows){return 0;}																			//	Номер ряда кнопки   не может быть меньше 1 или больше объявленного количества рядов.
				}																													//
			//	Читаем состояние одной или всех кнопок клавиатуры:																	//
				uint8_t regFirst = col==KEY_ALL?0:((row-1)*(valRows==2?5:valCols)+col-1);											//	Определяем номер первого регистра «REG_KBD_KEYS».
				uint8_t regSum   = col==KEY_ALL?10:1;																				//	Определяем количество регистров «REG_KBD_KEYS» которые требуется прочитать.

				uint8_t nr = REG_KBD_KEYS + regFirst;
				//std::cout << "pre first read" << '\n';
				//if(!_readBytes(REG_KBD_KEYS+regFirst,regSum)){return 0;}															//	Читаем 1 или 10 регистров «REG_KBD_KEYS» в массив «data».
				if(!_readBytes(nr,regSum)){return 0;}															//	Читаем 1 или 10 регистров «REG_KBD_KEYS» в массив «data».
				//std::cout << "post first read" << '\n';
			//	Проходим по всем прочитанным данным:																				//
				for(uint8_t i=regFirst, j=0, k=0; i<regFirst+regSum; i++, j++){														//	Проходим по 1 или 10 элементам массива «data».
				//	Дублируем состояние битов регистра «REG_KBD_KEYS»+«i» в «i» элемент массива «arrREG_KBD_KEYS»:					//
															arrREG_KBD_KEYS[i] |= ( data[j] & KBD_FLG_PUSHED   );					//	Устанавливаем флаг события   кнопки - «нажимается».				Если бит «KBD_FLG_PUSHED»   в байте «arrREG_KBD_KEYS[i]» был установлен, то он и останется установленным!
															arrREG_KBD_KEYS[i] |= ( data[j] & KBD_FLG_RELEASED );					//	Устанавливаем флаг события   кнопки - «отпускается».			Если бит «KBD_FLG_RELEASED» в байте «arrREG_KBD_KEYS[i]» был установлен, то он и останется установленным!
															arrREG_KBD_KEYS[i] |= ( data[j] & KBD_FLG_CHANGED  );					//	Устанавливаем флаг события   кнопки - «состояние изменилось».	Если бит «KBD_FLG_CHANGED»  в байте «arrREG_KBD_KEYS[i]» был установлен, то он и останется установленным!
					arrREG_KBD_KEYS[i] &= ~KBD_FLG_STATE;	arrREG_KBD_KEYS[i] |= ( data[j] & KBD_FLG_STATE    );					//	Определяем    флаг состояния кнопки - «нажата».					Установлен пока кнопка нажата.
					arrREG_KBD_KEYS[i] &= ~KBD_FLG_TRIGGER;	arrREG_KBD_KEYS[i] |= ( data[j] & KBD_FLG_TRIGGER  );					//	Определяем    флаг состояния кнопки - «переключатель»			Меняет состояние с каждым новым нажатием.
					arrREG_KBD_KEYS[i] &= ~KBD_TIM_HOLD;	arrREG_KBD_KEYS[i] |= ( data[j] & KBD_TIM_HOLD     );					//	Определяем    биты времени удержания кнопки.					Время удержания = 0,5 сек * «KBD_TIM_HOLD».
				//	Определяем возвращаемое значение:																				//
					k=(col!=KEY_ALL)?0:(valRows==2?((j%5)<valCols?(j-(5-valCols)*(j/5)):10):(j<(valCols*valRows)?j:10));			//	Определяем позицию бита в возвращаемом числе при чтении всех кнопок.
					if(k<10){																										//	Если позиция бита не выходит за 10 (максимальное число кнопок).
						switch(type){																								//
							case KEY_PUSHED   : f |= (arrREG_KBD_KEYS[i] & KBD_FLG_PUSHED  )? (1<<k):0; arrREG_KBD_KEYS[i] &= ~KBD_FLG_PUSHED;		break;	//	Возвращаемым значениям является флаг  события   кнопки - «нажимается».
							case KEY_RELEASED : f |= (arrREG_KBD_KEYS[i] & KBD_FLG_RELEASED)? (1<<k):0; arrREG_KBD_KEYS[i] &= ~KBD_FLG_RELEASED;	break;	//	Возвращаемым значениям является флаг  события   кнопки - «отпускается».
							case KEY_CHANGED  : f |= (arrREG_KBD_KEYS[i] & KBD_FLG_CHANGED )? (1<<k):0; arrREG_KBD_KEYS[i] &= ~KBD_FLG_CHANGED;		break;	//	Возвращаемым значениям является флаг  события   кнопки - «состояние изменилось».
							case KEY_STATE    : f |= (arrREG_KBD_KEYS[i] & KBD_FLG_STATE   )? (1<<k):0;												break;	//	Возвращаемым значениям является флаг  состояния кнопки - «нажата».
							case KEY_TRIGGER  : f |= (arrREG_KBD_KEYS[i] & KBD_FLG_TRIGGER )? (1<<k):0;												break;	//	Возвращаемым значениям является флаг  триггера  кнопки - «переключатель».
							case KEY_HOLD_05  : f  = (arrREG_KBD_KEYS[i] & KBD_TIM_HOLD    )          ;												break;	//	Возвращаемым значениям является время удержания кнопки в 1/2 долях секунд.
						}																											//
					}																												//
				//	Устранение повторных срабатываний флагов:																		//
					if( type == KEY_PUSHED || type == KEY_RELEASED || type == KEY_CHANGED ){delay(1);}								//	Флагам KBD_FLG_PUSHED, KBD_FLG_RELEASED и KBD_FLG_CHANGED может потребоваться время для сброса в регистре «REG_KBD_KEYS»+«i».
				}																													//
			}																														//
		//	Возвращаем результат:																									//
			//std::cout << "exiting" << '\n';
			return f;																												//
}																																	//
																																	//
//		Получение флага состояния, события или времени удержания кнопки:															//	Возвращаемое значение:	флаг состояния, события или время удержания кнопки.
uint16_t iarduino_I2C_Keyboard::getKey			(char sym, uint8_t type){															//	Параметры:				sym - символ присвоенный кнопке или значение KEY_ALL, type - тип получаемого состояния или собития.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				if((uint8_t)sym == (uint8_t)KEY_ALL){return getKey(KEY_ALL, KEY_ALL, type);}										//	Если запрошено состояие всех кнопок, то возвращаем его.
				for(uint8_t i=1; i<=valRows; i++){																					//	Проходим по всем доступным рядам с кнопками.
				for(uint8_t j=1; j<=valCols; j++){																					//	Проходим по всем доступным кнопкам в ряду.
					if(sym==getEncoding(j,i)){return getKey(j,i,type);}																//	Если символ «sym» совпал с символом присвоенным очередной кнопке, то возвращаем состояние этой кнопки.
				}}																													//
			}																														//
			return 0;																												//	Если модуль не инициализирован, или символ «sym» не совпал ни с одним из символов присвоенных кнопкам, то возвращаем ошибку.
}																																	//
																																	//
//		Получение времени удержания/простоя кнопки в мс:																			//	Возвращаемое значение:	время удержания или простоя кнопки до 25'500 мс.
uint16_t iarduino_I2C_Keyboard::getTime			(uint8_t col, uint8_t row, uint8_t type){											//	Параметры:				col - номер кнопки в ряду (1-5), row - номер ряда кнопки (1-3), type - тип получаемого времени.
			uint16_t f=0;																											//
			if(valAddr){																											//	Если модуль был инициализирован, то ...
			//	Проверяем корректность введённых значений «col» и «row»:															//
				if(col==0 || col> valCols){return 0;}																				//	Номер кнопки в ряду не может быть меньше 1 или больше объявленного количества кнопок в ряду.
				if(row==0 || row> valRows){return 0;}																				//	Номер ряда кнопки   не может быть меньше 1 или больше объявленного количества рядов.
			//	Читаем состояние указанной кнопки клавиатуры:																		//
				uint8_t num = ((row-1)*(valRows==2?5:valCols)+col-1);																//	Определяем номер первого регистра «REG_KBD_KEYS» от 0 до 9.
				if(!_readBytes(REG_KBD_KEYS+num,1)){return 0;}																		//	Читаем 1 байт регистра «REG_KBD_KEYS»+«reg» в массив «data».
			//	Сохраняем флаги событий кнопки:																						//
				arrREG_KBD_KEYS[num] |= ( data[0] & KBD_FLG_PUSHED   );																//	Устанавливаем флаг события кнопки - «нажимается».			Если бит «KBD_FLG_PUSHED»   в байте «arrREG_KBD_KEYS[num]» был установлен, то он и останется установленным!
				arrREG_KBD_KEYS[num] |= ( data[0] & KBD_FLG_RELEASED );																//	Устанавливаем флаг события кнопки - «отпускается».			Если бит «KBD_FLG_RELEASED» в байте «arrREG_KBD_KEYS[num]» был установлен, то он и останется установленным!
				arrREG_KBD_KEYS[num] |= ( data[0] & KBD_FLG_CHANGED  );																//	Устанавливаем флаг события кнопки - «состояние изменилось».	Если бит «KBD_FLG_CHANGED»  в байте «arrREG_KBD_KEYS[num]» был установлен, то он и останется установленным!
			//	Возвращаем время равное 0:																							//
				if(type==KEY_HOLD){ if(!( data[0] & KBD_FLG_STATE  ) ){return 0;}}else												//	Возвращаем 0мс если запрошено время удержания, а кнопка отпущена.
				if(type==KEY_FREE){ if( ( data[0] & KBD_FLG_STATE  ) ){return 0;}}else{return 0;}									//	Возвращаем 0мс если запрошено время простоя  , а кнопка нажата.
			//	Читаем время удержания/простоя кнопки клавиатуры:																	//
				if(!_readBytes(REG_KBD_TIME_KEYS+num,1)){return 0;}																	//	Читаем 1 байт регистра «REG_KBD_TIME_KEYS»+«reg» в массив «data».
				f=data[0]; f*=100;																									//	Сохраняем полученный байт и преобразуем десятые доли секунд в тысячные.
			}																														//
		//	Возвращаем результат:																									//
			return f;																												//
}																																	//
																																	//
//		Получение времени удержания/простоя кнопки в мс:																			//	Возвращаемое значение:	время удержания или простоя кнопки до 25'500 мс.
uint16_t iarduino_I2C_Keyboard::getTime			(char sym, uint8_t type){															//	Параметры:				sym - символ присвоенный кнопке, type - тип получаемого времени.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				for(uint8_t i=1; i<=valRows; i++){																					//	Проходим по всем доступным рядам с кнопками.
				for(uint8_t j=1; j<=valCols; j++){																					//	Проходим по всем доступным кнопкам в ряду.
					if(sym==getEncoding(j,i)){return getTime(j,i,type);}															//	Если символ «sym» совпал с символом присвоенным очередной кнопке, то возвращаем время удержания или простоя кнопки.
				}}																													//
			}																														//
			return 0;																												//	Если модуль не инициализирован, или символ «sym» не совпал ни с одним из символов присвоенных кнопкам, то возвращаем ошибку.
}																																	//
																																	//
//		Установка состояния светодиода:																								//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::setLed			(uint8_t col, uint8_t row, uint16_t f){												//	Параметры:				col - номер светодиода в ряду (1-5), row - номер ряда светодиода (1-3), f - флаг(и) устанавливаемого состояния светодиода (0/1).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				uint8_t num;																										//	Объявляем переменную для хранения номера светодиода или номера флага.
				uint8_t reg;																										//	Объявляем переменную для хранения номера регистра «REG_KBD_LED_L» или «REG_KBD_LED_H».
			//	Проверяем корректность введённых значений «col» и «row»:															//
				if(col!=KEY_ALL || row!=KEY_ALL){																					//	Если выбраны не все светодиоды, то ...
					if(col==0   || col> valCols){return;}																			//	Номер светодиода в ряду не может быть меньше 1 или больше объявленного количества кнопок в ряду.
					if(row==0   || row> valRows){return;}																			//	Номер ряда светодиодов  не может быть меньше 1 или больше объявленного количества рядов.
				}																													//
			//	Если устанавливается состояние одного светодиода:																	//
				if(col!=KEY_ALL){																									//
				//	Определяем регистр и бит управления светодиодом:																//
					num = (row-1)*(valRows==2?5:valCols)+col-1;																		//	Определяем номер светодиода от 0 до 9.
					reg = num<5?REG_KBD_LED_L:REG_KBD_LED_H;																		//	Определяем регистр в котором находится бит управления светодиодом.
					num = num<5?num:num-5;																							//	Определяем номер бита управления светодиодом в регистре reg.
				//	Читаем состояние светодиода:																					//
					if(!_readBytes(reg,1)){return;}																					//	Читаем 1 байт из регистра «REG_KBD_LED_L» или «REG_KBD_LED_H» в массив «data».
				//	Меняем значение бита управления светодиодом:																	//
					if(f){data[0]|= (1<<num);}																						//
					else {data[0]&=~(1<<num);}																						//
				//	Сохраняем состояние светодиода:																					//
					if(!_writeBytes(reg,1)){return;}																				//	Записываем 1 байт в регистр «REG_KBD_LED_L» или «REG_KBD_LED_H» из массива «data».
			//	Если устанавливаются состояния всех светодиодов:																	//
				}else{																												//
				//	Читаем значение яркости светодиодов:																			//
					if(!_readBytes(REG_KBD_LED_L,2)){return;}																		//	Читаем 2 байта в массив «data» из модуля начиная с регистра «REG_KBD_LED_L».
				//	Обнуляем значения битов управления светодиодами:																//
					data[0]&=0xE0; data[1]&=0xE0;																					//	Сбрасываем 5 младших битов.
				//	Проходим по всем светодиодам:																					//
					for(uint8_t i=1, k=0; i<=valRows; i++){																			//	Проходим по всем доступным рядам со светодиодами.
					for(uint8_t j=1;      j<=valCols; j++, k++){																	//	Проходим по всем доступным светодиодам в ряду.
					//	Устанавливаем значения битов управления светодиодами:														//
						num = (i-1)*(valRows==2?5:valCols)+j-1;																		//	Определяем номер бита управления светодиодом.
						if(num<5){if(f&(1<<k)){data[0]|=(1<< num   );}}																//	Устанавливаем биты для регистра «REG_KBD_LED_L».
						else     {if(f&(1<<k)){data[1]|=(1<<(num-5));}}																//	Устанавливаем биты для регистра «REG_KBD_LED_H».
					}}																												//
				//	Сохраняем состояния светодиодов:																				//
					if(!_writeBytes(REG_KBD_LED_L,2)){return;}																		//	Записываем 2 байта из массива «data» в модуль начиная с регистра «REG_KBD_LED_L».
				}																													//
			}																														//
}																																	//
																																	//
//		Установка состояния светодиода:																								//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::setLed			(char sym, uint16_t f){																//	Параметры:				sym - символ присвоенный кнопке светодиода или значение LED_ALL, f - флаг(и) устанавливаемого состояния светодиода (0/1).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				if((uint8_t)sym == (uint8_t)KEY_ALL){setLed(KEY_ALL, KEY_ALL, f);}													//	Если устанавливаются состояния всех светодиодов, то устанавливаем их.
				for(uint8_t i=1; i<=valRows; i++){																					//	Проходим по всем доступным рядам со светодиодами.
				for(uint8_t j=1; j<=valCols; j++){																					//	Проходим по всем доступным светодиодам в ряду.
					if(sym==getEncoding(j,i)){setLed(j,i,f);}																		//	Если символ «sym» совпал с символом присвоенным очередной кнопке светодиода, то устанавливаем состояние этого светодиода.
				}}																													//
			}																														//
}																																	//
																																	//
//		Получение состояния светодиода:																								//	Возвращаемое значение:	флаг состояния светодиода (0/1).
uint16_t iarduino_I2C_Keyboard::getLed			(uint8_t col, uint8_t row){															//	Параметры:				col - номер светодиода в ряду (1-5), row - номер ряда светодиода (1-3).
			uint16_t f=0;																											//
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				uint8_t num;																										//	Объявляем переменную для хранения номера светодиода или номера флага.
				uint8_t reg;																										//	Объявляем переменную для хранения номера регистра «REG_KBD_LED_L» или «REG_KBD_LED_H».
			//	Проверяем корректность введённых значений «col» и «row»:															//
				if(col!=KEY_ALL || row!=KEY_ALL){																					//	Если выбраны не все светодиоды, то ...
					if(col==0   || col> valCols){return 0;}																			//	Номер светодиода в ряду не может быть меньше 1 или больше объявленного количества кнопок в ряду.
					if(row==0   || row> valRows){return 0;}																			//	Номер ряда светодиодов  не может быть меньше 1 или больше объявленного количества рядов.
				}																													//
			//	Если читается состояние одного светодиода:																			//
				if(col!=KEY_ALL){																									//
				//	Определяем регистр и бит управления светодиодом:																//
					num = (row-1)*(valRows==2?5:valCols)+col-1;																		//	Определяем номер светодиода от 0 до 9.
					reg = num<5?REG_KBD_LED_L:REG_KBD_LED_H;																		//	Определяем регистр в котором находится бит управления светодиодом.
					num = num<5?num:num-5;																							//	Определяем номер бита управления светодиодом в регистре reg.
				//	Читаем состояние светодиода:																					//
					if(!_readBytes(reg,1)){return 0;}																				//	Читаем 1 байт из регистра «REG_KBD_LED_L» или «REG_KBD_LED_H» в массив «data».
				//	Определяем состояние светодиода:																				//
					f = (data[0]&(1<<num))?1:0;																						//
			//	Если устанавливаются состояния всех светодиодов:																	//
				}else{																												//
				//	Читаем состояния светодиодов:																					//
					if(!_readBytes(REG_KBD_LED_L,2)){return 0;}																		//	Читаем 2 байта в массив «data» из модуля начиная с регистра «REG_KBD_LED_L».
				//	Проходим по всем светодиодам:																					//
					for(uint8_t i=0; i<10; i++){																					//	Проходим по 10 флагам.
					//	Определяем возвращаемое значение:																			//
						num = valRows==2?((i%5)<valCols?(i-(5-valCols)*(i/5)):10):(i<(valCols*valRows)?i:10);						//	Определяем позицию бита в возвращаемом числе при чтении всех светодиодов.
						if(num<10){ f |= (((data[i<5?0:1]&(1<<(i<5?i:i-5)))?1:0)<<num); }											//	Добавляем значение бита регистра в бит переменной f если его позиция не выходит за 10 (максимальное число светодиодов).
					}																												//
				}																													//
			}																														//
		//	Возвращаем результат:																									//
			return f;																												//
}																																	//
																																	//
//		Получение состояния светодиода:																								//	Возвращаемое значение:	флаг(и) состояния светодиода(ов) (0/1).
uint16_t iarduino_I2C_Keyboard::getLed			(char sym){																			//	Параметры:				sym - символ присвоенный кнопке светодиода или значение LED_ALL.
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				if((uint8_t)sym == (uint8_t)KEY_ALL){return getLed(KEY_ALL, KEY_ALL);}												//	Если запрашиваются состояния всех светодиодов, то возвращаем их.
				for(uint8_t i=1; i<=valRows; i++){																					//	Проходим по всем доступным рядам со светодиодами.
				for(uint8_t j=1; j<=valCols; j++){																					//	Проходим по всем доступным светодиодам в ряду.
					if(sym==getEncoding(j,i)){return getLed(j,i);}																	//	Если символ «sym» совпал с символом присвоенным очередной кнопке светодиода, то возвращаем состояние этого светодиода.
				}}																													//
			}																														//
			return 0;																												//
}																																	//
																																	//
//		Установка яркости свечения светодиодов:																						//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::setLight			(uint8_t light, uint8_t group){														//	Параметры:				light - яркость (0-7), group - группа светодиодов (LED_ALL/1/2).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				if(light>7       ){light=7;}																								//
				if(group==1      ){if(!_readBytes(REG_KBD_LED_L,1)){return;} data[0]&=0x1F;                data[0]|=(light<<5);                      if(!_writeBytes(REG_KBD_LED_L,1)){return;}}else
				if(group==2      ){if(!_readBytes(REG_KBD_LED_H,1)){return;} data[0]&=0x1F;                data[0]|=(light<<5);                      if(!_writeBytes(REG_KBD_LED_H,1)){return;}}else
				if(group==LED_ALL){if(!_readBytes(REG_KBD_LED_L,2)){return;} data[0]&=0x1F; data[1]&=0x1F; data[0]|=(light<<5); data[1]|=(light<<5); if(!_writeBytes(REG_KBD_LED_L,2)){return;}}
			}																														//
}																																	//
																																	//
//		Получение яркости свечения светодиодов:																						//	Возвращаемое значение:	яркость (0-7).
uint8_t	iarduino_I2C_Keyboard::getLight			(uint8_t group){																	//	Параметры:				group - группа светодиодов (LED_ALL/1/2).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				if(group==LED_ALL){group=1;}																						//	Если запрошена яркость всех светодиодов, то читаем яркость 1 группы светодиодов.
				if(group>2){return 0;}																								//	Если указана неизвестная группа светодиодов, то возвращаем 0.
				if(!_readBytes(group==1?REG_KBD_LED_L:REG_KBD_LED_H,1)){return 0;}													//	Читаем 1 байт из регистра «REG_KBD_LED_L» или «REG_KBD_LED_H» в массив «data».
				return (data[0]>>5);																								//	Возвращаем значение яркости.
			}																														//
			return 0;																												//
}																																	//
																																	//
//		Установка светодиодной анимации:																							//	Возвращаемое значение:	отсутствует.
void	iarduino_I2C_Keyboard::setAnimation		(uint8_t num, uint16_t tim){														//	Параметры:				num - номер светодиодной анимации, tim - время свечения светодиода в мс (значение до 2550 мс)
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				if(tim>2550){tim=2550;}																								//	Время свечения светодиода не может превышать 2550 мс.
				data[0]=num; data[1]=tim/10;																						//	Готовим даные для передачи.
				_writeBytes(REG_KBD_ANIMATION,2);																					//	Записываем 2 байта из массива «data» в модуль, начиная с регистра «REG_KBD_ANIMATION».
			}																														//
}																																	//
																																	//
uint8_t	iarduino_I2C_Keyboard::getAnimation		(void){																				//	Определяем функцию получения номера светодиодной анимации			(Параметр:  отсутствует).
			if(valAddr){																											//	Если модуль был инициализирован, то ...
				if(!_readBytes(REG_KBD_ANIMATION,1)){return 0;} return data[0];														//	Читаем 1 байт из регистра «REG_KBD_ANIMATION» в массив «data».
			}																														//
			return 0;																												//
}																																	//
																																	//
//		Чтение данных из регистров в массив data:																					//	Возвращаемое значение:	результат чтения (true/false).
bool	iarduino_I2C_Keyboard::_readBytes		(uint8_t reg, uint8_t sum){															//	Параметры:				reg - номер первого регистра, sum - количество читаемых байт.
			//std::cout << "entering" << '\n';
			bool	result=false;																									//	Определяем флаг       для хранения результата чтения.
			uint8_t	sumtry=10;																										//	Определяем переменную для подсчёта количества оставшихся попыток чтения.
			do{

					//std::cout << "read# " << ('0' + sumtry) << '\n';
					result = objI2C->readBytes(valAddr, reg, data, sum);																//	Считываем из модуля valAddr, начиная с регистра reg, в массив data, sum байт.
				sumtry--;	if(!result){delay(1);}																					//	Уменьшаем количество попыток чтения и устанавливаем задержку при неудаче.
			}	while		(!result && sumtry>0);																					//	Повторяем чтение если оно завершилось неудачей, но не более sumtry попыток.
			delayMicroseconds(500);																									//	Между пакетами необходимо выдерживать паузу.
			//std::cout << "exiting" << '\n';
			return result;																											//	Возвращаем результат чтения (true/false).
}																																	//
																																	//
//		Запись данных в регистры из массива data:																					//	Возвращаемое значение:	результат записи (true/false).
bool	iarduino_I2C_Keyboard::_writeBytes	(uint8_t reg, uint8_t sum, uint8_t num){												//	Параметры:				reg - номер первого регистра, sum - количество записываемых байт, num - номер первого элемента массива data.
			bool	result=false;																									//	Определяем флаг       для хранения результата записи.
			uint8_t	sumtry=10;																										//	Определяем переменную для подсчёта количества оставшихся попыток записи.
			do{	result = objI2C->writeBytes(valAddr, reg, &data[num], sum);															//	Записываем в модуль valAddr начиная с регистра reg, sum байи из массива data начиная с элемента num.
				sumtry--;	if(!result){delay(1);}																					//	Уменьшаем количество попыток записи и устанавливаем задержку при неудаче.
			}	while		(!result && sumtry>0);																					//	Повторяем запись если она завершилась неудачей, но не более sumtry попыток.
			delay(10);																												//	Ждём применения модулем записанных данных.
			return result;																											//	Возвращаем результат записи (true/false).
}																																	//
																																	//
