Всем доброго времени суток! Написал вот такой код, выводящий на 4-разрядный семисегментный индикатор время и температуру. Спойлер: Код Код (C++): #include <Wire.h> #include <BMP085.h> #include <DS3231.h> #define latchPin 3 // 12 защёлка #define clockPin 2 // 11 тактование #define dataPin 4 // 14 данные DS3231 clock; RTCDateTime DateTime; BMP085 dps = BMP085(); unsigned long gen1P = 0UL; unsigned long gen2P = 0UL; bool dot=0; // включение/отключение двоеточия bool switching=0; // переключение между температурой и временем long Temperature = 0; // хранение температуры byte Numbers_array[12] = { 0x3F, 0x6, 0x5B, // 0, 1, 2 0x4F, 0x66, 0x6D,// 3, 4, 5 0x7D, 0x7, 0x7F, // 6, 7, 8 0x6F, 0x39,0x63, // 9,C,* }; byte clipboard[2][4]; // буфер обмена void setup() { //Serial.begin(9600); DDRD = B11111100; // 2, 3, 4, 5, 6, 7 - выход DDRB = B00001111; // 8,9,10,11 - выход PORTB |= B00001111; // выключаем все разряды clock.begin(); Wire.begin(); delay(1000); dps.init(); gen1P, gen2P = millis(); } void loop() { DateTime = clock.getDateTime(); uint8_t hour = uint8_t(DateTime.hour); uint8_t minute = uint8_t(DateTime.minute); uint8_t second = uint8_t(DateTime.second); blinkDot(); getTime(hour, minute); getTemp(second); display_Of_data(); if((second>=0 && second<=1) || (second>=6 && second<=7)) PORTB |= B00001111; if (second>=1 && second<=6 ) switching = 1; // с 1 по 6 секунду отображаем температуру else switching = 0; // отображаем время } bool isTimer(unsigned long startTime, unsigned long period ) { unsigned long currentTime; currentTime = millis(); if (currentTime >= startTime) return (currentTime >= (startTime + period)); else return (currentTime >= (4294967295 - startTime + period)); } void display_Of_data() { static byte n = 0; if (isTimer (gen1P, 1)) { gen1P = millis(); n++; if (n >= 4)n = 0; PORTD &= ~(1<<PD3); // защёлка LOW shiftOut(dataPin, clockPin, MSBFIRST, clipboard[switching][n]); // передаём последовательность в регистр PORTD |= (1<<PD3); // защёлкиваем регистр PORTB |= B00001111; // выключаем все разряды PORTB &= ~(1<<n); // последовательно включаем каждый разряд } } void getTime(uint8_t hr, uint8_t mn) { clipboard[0][0] = Numbers_array[hr/10]; clipboard[0][1] = Numbers_array[hr%10]; clipboard[0][2] = Numbers_array[mn/10]; clipboard[0][3] = Numbers_array[mn%10]; } void getTemp(uint8_t sec) { if(sec==1) dps.getTemperature(&Temperature); // каждую минуту считываем показания с датчика uint8_t i = Temperature/10; clipboard[1][0] = Numbers_array[i/10]; clipboard[1][1] = Numbers_array[i%10]; clipboard[1][2] = Numbers_array[11]; clipboard[1][3] = Numbers_array[10]; } void blinkDot() { if(!switching) { if (isTimer (gen2P, 1000)) { gen2P = millis(); dot=!dot; } if (dot) PORTD |= (1<<PD5); else PORTD &= ~(1<<PD5); } else PORTD &= ~(1<<PD5); } Код работает без нареканий)) Этого мне показалось мало и решил я добавить «плюшек» в виде возможности регулирования яркости разрядов и плавного включения/выключения двоеточия. Начал с двоеточия, и тут же начались проблемы. Дополнил существующую функцию управления двоеточием циклом for(пока только одним, в момент включения) Спойлер: Код Код (C++): void blinkDot() { if(!switching) { if (isTimer (gen2P, 1000)) { gen2P = millis(); dot=!dot; } if (dot) //PORTD |= (1<<PD5); { for (byte i=0; i<=255; i++) { analogWrite(5,i); delay(10); } } else PORTD &= ~(1<<PD5); } else PORTD &= ~(1<<PD5); } Но после такого индикатор начал вести себя как одержимый дьяволом! То включится один сегмент, то второй… один горит ярче другой тускнее. Короче полная вакханалия)) Ради интереса попробовал сделать вот так Спойлер: Код Код (C++): void blinkDot() { if(!switching) { if (isTimer (gen2P, 1000)) { gen2P = millis(); dot=!dot; } if (dot) //PORTD |= (1<<PD5); { analogWrite(5,50); } else PORTD &= ~(1<<PD5); } else PORTD &= ~(1<<PD5); } Теперь двоеточие горит постоянно (не отключается) с заданной яркостью. Подскажите пожалуйста, как можно добиться требуемого результата, сам я в ступоре ((
Как уже писал выше, код работает отлично и в таком виде. Отказаться полностью от ардуиновских функций не могу, тупо из-за отсутствия достаточного количества знаний по данной теме.Вопрос в другом, почему когда я пытаюсь сделать ШИМ на одном 5 пине перестает работать вся конструкция...?
Ответ прост. Неправильно спроектирована программа. Но требовать от ардуинщика этого, когда он худо бедно освоил Си ардуиновского минимума не реально. Вы просто пожинаете плоды куцевого знания основ программирования. Помочь вам не смогу. Для этого надо переписывать все и в результате вы перестанете понимать скетч.