Мультиплексор cd74hc4067

Тема в разделе "Arduino & Shields", создана пользователем REm, 28 июн 2024.

  1. REm

    REm Гик

    Вроде бы несложная микросхема, и цикл работы понятен. Только вот, когда понадобилось использовать её, то ряд вопросов возник.
    Не выходит спрятать алгоритм в отдельный цикл без 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;
    }
     
     
  2. a1000

    a1000 Гуру

    А что тут непонятного? В приведенном вами примере есть готовая функция readMux для работы с мультиплексором. Скармливайте ей номер канала, а она вернёт вам значение.
     
  3. ostrov

    ostrov Гуру

    Создавайте функцию с входом по таймеру, а ссылку на нее в луп. Так же можно делать вообще для всего, что должно выполняться в какие-то промежутки времени, при этом не останавливая остальную работу.

    Пример:
    Код (C++):
    void setup() {}

    void loop() {
      timeFoo();
    }

    void timeFoo() {
      static unsigned long timer = 0;
      if (timer + 250 > millis()) return;  // тут время, в примере 250 мс
      // тут сама функция
      timer = millis();
    }
     

    И зачем массив состояний пинов? Адрес это биты в полубайте, в вашем случае перевернутом. Не надо никаких библиотек, которые не пойми как работают. Освойте битовые операции, пригодятся еще миллион раз.
     
  4. ИгорьК

    ИгорьК Гуру

    Код (C++):
    if (timer + 250 > millis()) return;  // тут время, в примере 250 мс
    Кажись время проверять надо не так, или я давно ардуину не включал...
     
  5. ostrov

    ostrov Гуру

    Ну, можно накидать несколько правильных вариантов, и это один из них.
     
  6. ИгорьК

    ИгорьК Гуру

    Помнится, что проверять время лучше "сейчас" - "то что было" > "значение", по причине если счетчик через ноль перевалит, то условие с плюсом не выполнится никогда. У меня с плюсом подсветка периодически зависала, что-то через три месяца. Раньше. Теперь не зависает - электричество чаще отключается.
     
  7. b707

    b707 Гуру

    это один из неправильных
     
    DetSimen нравится это.
  8. b707

    b707 Гуру

    ТС куда-то пропал.... мне было бы интересно узнать, где в этом примере ограничение, которое
    Хотя примерчик, конечно. какой-то двоечник писал. Массив на 64 переменные типа инт (то есть 128 байт), когда хватило бы всего 16 ?
    Да и на самом деле нафига тут массив, если числа не более чем номера каналов в двоичном виде
     
    DetSimen нравится это.
  9. ostrov

    ostrov Гуру

    В моем пример будет пропущена одна итерация раз, примерно, в месяц. В вашем, кстати тоже, когда millis перевалит через предел. И то и другое, скорее всего, останется незамеченным.
     
  10. ИгорьК

    ИгорьК Гуру

    Как сказано в одном писании, "практика - критерий истины". Давно хотел потрогать руками:
    Код (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;
      };
    }
    Итого:

    upload_2024-7-10_9-40-18.png


    Был неправ, пепел на голову :) (Был неправ частично :) )
     
    Последнее редактирование: 10 июл 2024 в 13:22
  11. ИгорьК

    ИгорьК Гуру

    В общем, все не совсем так.
    В вашем случае условие срабатывает раньше времени.
    Проблема вашего варианта еще и в том, что условие перестает быть верным при достижении значения интервала. В некоторых случаях, когда вы не успеете его проверить, устройство может не сработать до следующего перехода через 0:

    upload_2024-7-10_9-16-8.png

    Что касается месяца, то документация ардуино говорит "millis() will wrap around to 0 after about 49 days (micros in about 71 minutes)."
     
    Последнее редактирование: 10 июл 2024 в 10:16
  12. KindMan

    KindMan Гуру

    Евгений Петрович (@Asper Daffy) на соседнем форуме, всё про millis описал давно. Но сектанты "свидетели переполненения millis" не переведутся никогда.
     
    Feofan нравится это.
  13. ИгорьК

    ИгорьК Гуру

    У нас с Евгением Петровичем разные методики объяснения.
    У него - правильная и крутая, у меня - наоборот.

    Меньше бываешь на ардуино.ру - меньше заразы цепляешь.
     
    parovoZZ нравится это.
  14. b707

    b707 Гуру

    если вы не идете на ардуино.ру - оно само идет к вам
     
  15. ИгорьК

    ИгорьК Гуру

    "Не идет, а пишет. ... одной ногой, другой - чертит."
     
  16. KindMan

    KindMan Гуру

    У меня иммунитет уже ко всему. Я отделяю зёрна от плевел.
     
  17. ИгорьК

    ИгорьК Гуру

    Я не заметил. Заметил нотки высокомерия и чванства.

    И знаете в чем проблема? Вы ничего плохого не хотели сказать - просто уже модель поведения въелась и вы не замечаете что получается.
    Прочитайте еще раз:

    То есть мне не надо было разбираться, делать, публиковать, рисовать? Да и вообще - раз сам Евгений Петрович... Но у Евгения Петровича объяснение элементарных вещей нубам средствами им вряд ли понятными. Полагаю, у меня не так.

    Но вопрос не в том как ЕП или я объясняем: каждый дирижер сам набирает свой оркестр. Кто-то берет гармошку и барабан, кто-то струнные и челесту. Это дело того, кто работает.

    Проблема в вашем высокомерном нежелании увидеть нюансы, оценить чужой труд, желание понять и время, затраченное на публикацию.

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

    новобранцы, которым ни в одном учебнике об этом не говорят (и Евгений Петрович, похоже, единственный кто это описал ) и

    любители погонять сферических коней - снобы от "абдурино".

    ==================================

    Эти многобуков только из уважения к вам. Главное - вы ничего плохого не хотели, просто модель поведения привычная... Но куда лучше модель - сделать что-то хорошее и этим поделиться.

    Контекст обсуждения простой - не всем известно как работает переход через ноль. Я тоже из их числа и не спец ни разу. И это все.
     
  18. parovoZZ

    parovoZZ Гуру

    Мне не ясна одна абсолютно понятная всем простая вещь: вам доступно любое прерывание от любого таймера. Для чего вы тогда пользуетесь полумерами?
     
  19. ИгорьК

    ИгорьК Гуру

    Зачем мне прерывание, если надо отправлять сообщение или проверять датчик раз в минуту, раз в пять минут? Конечно - вопрос вкуса.

    Для нубов есть скетч типа "мигаем диодом без delay" - там как раз и проверяется время. А потом привыкаешь.
     
  20. ИгорьК

    ИгорьК Гуру

    Что в данном случае "полумеры". Проверка таймера - типовая вещь.