Высокопроизводительная версия светофора

Предложена Глебом Пониклеевым. Эта программа самая быстрая из рассмотренных нами. Основная особенность программы в том, что в коде не используются функции digitalWrite и delay. Управление портами контроллера производится передачей управляющих последовательностей непосредственно на выходные регистры контроллера.

Сценарий работы программы не зависит от кода. Для задания нужного алгоритма работы нужно изменить содержимое массива структур scens. Структура содержит три параметра: состояние каналов, длительность состояния, 0 – режим вывода состояния.

Данная программа умеет мигать светодиодами. Для включения мигания в массив scens вписывается строка, в которой в качестве 3-го параметра указывается число миганий. Для этой строки, второй параметр структуры содержит длительность включения/выключения канала. Единицы в первом параметре указывают те каналы, которые будут мигать.

unsigned long timeM = 0;
int n = 0;
int nBlinkF = 0;
struct Scene {
	byte stat;
	unsigned long tT;
	int nBlinks;
};
Scene scens[]{
	  {B11001, 1500, 0},
	  {B00100, 100, 3},
	  {B01110, 1500, 0},
	  {B00001, 100, 3},
	  {B00101, 1000, 0},
};
byte max_scens = 0;
//******************************
void setup() {
	DDRD = B01111100;
	max_scens = sizeof(scens) / sizeof(scens[0]);
	PORTD |= B1111100;
}
//*******************************
void loop() {
	if (millis() - timeM >= scens[n].tT) {
		timeM = millis();
		n += (nBlinkF == 0);
		n *= (n == max_scens ? 0 : 1);
		if (scens[n].nBlinks != 0) {
			if (nBlinkF == 0) {
				nBlinkF = scens[n].nBlinks * 2; //число циклов переключения
			}
			else {
				PORTD = PORTD ^ (scens[n].stat * 4);
				nBlinkF--;
			}
		}
		else {
			PORTD = scens[n].stat * 4;
		}
	}
}