Вроде бы несложная микросхема, и цикл работы понятен. Только вот, когда понадобилось использовать её, то ряд вопросов возник. Не выходит спрятать алгоритм в отдельный цикл без delay Не выходит считывать каждый адрес и значение для использования в связки с реле. (допустим, 1,2 адрес и их значения) Пример позволяет только в монитор значение закидывать. Кто-то делал нечто похожее? Код (C++): # define EN 3 #define S0 4 #define S1 5 #define S2 6 #define S3 7 #define SIG A0 void setup(){ Serial.begin(9600); pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); digitalWrite(S0, LOW); digitalWrite(S1, LOW); digitalWrite(S2, LOW); digitalWrite(S3, LOW); pinMode(EN, OUTPUT); digitalWrite(EN, LOW); } void loop(){ //Loop through and read all 16 values //Reports back Value at channel 6 is: 346 for(int i = 0; i < 16; i ++){ // Serial.print("Value at channel "); // Serial.print(i); // Serial.print(": "); Serial.print(readMux(i)); Serial.print(". "); } Serial.println(); delay(100); } int readMux(int channel){ int controlPin[] = {S0, S1, S2, S3}; int muxChannel[16][4]={ {0,0,0,0}, //channel 0 {1,0,0,0}, //channel 1 {0,1,0,0}, //channel 2 {1,1,0,0}, //channel 3 {0,0,1,0}, //channel 4 {1,0,1,0}, //channel 5 {0,1,1,0}, //channel 6 {1,1,1,0}, //channel 7 {0,0,0,1}, //channel 8 {1,0,0,1}, //channel 9 {0,1,0,1}, //channel 10 {1,1,0,1}, //channel 11 {0,0,1,1}, //channel 12 {1,0,1,1}, //channel 13 {0,1,1,1}, //channel 14 {1,1,1,1} //channel 15 }; //loop through the 4 sig for(int i = 0; i < 4; i ++){ digitalWrite(controlPin[i], muxChannel[channel][i]); } //read the value at the SIG pin int val = analogRead(SIG); //return the value return val; }
А что тут непонятного? В приведенном вами примере есть готовая функция readMux для работы с мультиплексором. Скармливайте ей номер канала, а она вернёт вам значение.
Создавайте функцию с входом по таймеру, а ссылку на нее в луп. Так же можно делать вообще для всего, что должно выполняться в какие-то промежутки времени, при этом не останавливая остальную работу. Пример: Код (C++): void setup() {} void loop() { timeFoo(); } void timeFoo() { static unsigned long timer = 0; if (timer + 250 > millis()) return; // тут время, в примере 250 мс // тут сама функция timer = millis(); } И зачем массив состояний пинов? Адрес это биты в полубайте, в вашем случае перевернутом. Не надо никаких библиотек, которые не пойми как работают. Освойте битовые операции, пригодятся еще миллион раз.
Код (C++): if (timer + 250 > millis()) return; // тут время, в примере 250 мс Кажись время проверять надо не так, или я давно ардуину не включал...
Помнится, что проверять время лучше "сейчас" - "то что было" > "значение", по причине если счетчик через ноль перевалит, то условие с плюсом не выполнится никогда. У меня с плюсом подсветка периодически зависала, что-то через три месяца. Раньше. Теперь не зависает - электричество чаще отключается.
ТС куда-то пропал.... мне было бы интересно узнать, где в этом примере ограничение, которое Хотя примерчик, конечно. какой-то двоечник писал. Массив на 64 переменные типа инт (то есть 128 байт), когда хватило бы всего 16 ? Да и на самом деле нафига тут массив, если числа не более чем номера каналов в двоичном виде
В моем пример будет пропущена одна итерация раз, примерно, в месяц. В вашем, кстати тоже, когда millis перевалит через предел. И то и другое, скорее всего, останется незамеченным.
Как сказано в одном писании, "практика - критерий истины". Давно хотел потрогать руками: Код (C++): unsigned long milliss = 4294967290; // Почти максимальное значение 4,294,967,295 unsigned long prev = 4294967285; // "Это" случилось здесь unsigned long interval = 15; // Интервал до следующей проверки unsigned long delta = 0; bool flagPlus = false; bool flagMinus = false; void setup() { Serial.begin(9600); } void loop() { ++milliss; flagPlus = (prev + interval) > milliss; // Ваш вариант flagMinus = (milliss - prev) > interval; // Вариант с вычитанием delta = milliss - prev; // Сколько прошло времени Serial.println(); Serial.print("Millis: "); Serial.print(milliss); Serial.print(" flagPlus: "); Serial.print(flagPlus); Serial.print(" flagMinus: "); Serial.print(flagMinus); Serial.print(" Delta: "); Serial.print(delta); delay(3000); if(milliss == 35){ // Два интервала с запасом milliss = 4294967290; }; } Итого: Был неправ, пепел на голову (Был неправ частично )
В общем, все не совсем так. В вашем случае условие срабатывает раньше времени. Проблема вашего варианта еще и в том, что условие перестает быть верным при достижении значения интервала. В некоторых случаях, когда вы не успеете его проверить, устройство может не сработать до следующего перехода через 0: Что касается месяца, то документация ардуино говорит "millis() will wrap around to 0 after about 49 days (micros in about 71 minutes)."
Евгений Петрович (@Asper Daffy) на соседнем форуме, всё про millis описал давно. Но сектанты "свидетели переполненения millis" не переведутся никогда.
У нас с Евгением Петровичем разные методики объяснения. У него - правильная и крутая, у меня - наоборот. Меньше бываешь на ардуино.ру - меньше заразы цепляешь.
Я не заметил. Заметил нотки высокомерия и чванства. И знаете в чем проблема? Вы ничего плохого не хотели сказать - просто уже модель поведения въелась и вы не замечаете что получается. Прочитайте еще раз: То есть мне не надо было разбираться, делать, публиковать, рисовать? Да и вообще - раз сам Евгений Петрович... Но у Евгения Петровича объяснение элементарных вещей нубам средствами им вряд ли понятными. Полагаю, у меня не так. Но вопрос не в том как ЕП или я объясняем: каждый дирижер сам набирает свой оркестр. Кто-то берет гармошку и барабан, кто-то струнные и челесту. Это дело того, кто работает. Проблема в вашем высокомерном нежелании увидеть нюансы, оценить чужой труд, желание понять и время, затраченное на публикацию. Вы и сами знаете, что это чушь и бравада. Не переведутся деятели двух категорий: новобранцы, которым ни в одном учебнике об этом не говорят (и Евгений Петрович, похоже, единственный кто это описал ) и любители погонять сферических коней - снобы от "абдурино". ================================== Эти многобуков только из уважения к вам. Главное - вы ничего плохого не хотели, просто модель поведения привычная... Но куда лучше модель - сделать что-то хорошее и этим поделиться. Контекст обсуждения простой - не всем известно как работает переход через ноль. Я тоже из их числа и не спец ни разу. И это все.
Мне не ясна одна абсолютно понятная всем простая вещь: вам доступно любое прерывание от любого таймера. Для чего вы тогда пользуетесь полумерами?
Зачем мне прерывание, если надо отправлять сообщение или проверять датчик раз в минуту, раз в пять минут? Конечно - вопрос вкуса. Для нубов есть скетч типа "мигаем диодом без delay" - там как раз и проверяется время. А потом привыкаешь.