Работа с 3мя мультиплексорами

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

//Mux control pins
int s0 = 18;
int s1 = 17;
int s2 = 16;

//Mux in "Z" pin
int Z_pin1 = 36;
int Z_pin2 = 39;
int Z_pin3 = 34;


int C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23, C24; // Сюда необходимо поместить значения с каждого канала, возможно перменные необходимо вынести в цикл.

void setup() {
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);

  Serial.begin(9600);
}


void loop() {

  //Loop through and read all 8 values
  for (int i = 0; i < 8; i ++) {
    Serial.print("Mux-1 = ");
    Serial.print(i);
    Serial.print("is : ");
    Serial.println(readMux(i, Z_pin1));
    delay(100);
  }
  for (int i = 0; i < 8; i ++) {
    Serial.print("Mux-2 = ");
    Serial.print(i);
    Serial.print("is : ");
    Serial.println(readMux(i, Z_pin2));
    delay(100);
  }

  for (int i = 0; i < 8; i ++) {
    Serial.print("Mux-3 = ");
    Serial.print(i);
    Serial.print("is : ");
    Serial.println(readMux(i, Z_pin3));
    delay(100);
  }
}

float readMux(int channel, int Z_pin) {
  int controlPin[] = {s0, s1, s2};

  int muxChannel[8][3] = {
    {0, 0, 0}, //channel 0
    {1, 0, 0}, //channel 1
    {0, 1, 0}, //channel 2
    {1, 1, 0}, //channel 3
    {0, 0, 1}, //channel 4
    {1, 0, 1}, //channel 5
    {0, 1, 1}, //channel 6
    {1, 1, 1}, //channel 7
  };

  //loop through the 3 sig
  for (int i = 0; i < 3; i ++) {
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }

  //read the value at the Z pin
  int val = analogRead(Z_pin);

  //return the value
  float voltage = (val * 5) / 1024.0;
  return voltage;
}

для кода три ``` до и после
создайте функцию выставления mux control pin и передавайте в неё номер канала

1 лайк

Спасибо тебе добрый человек :+1:

непонятно в чем вообще проблема?
Вот у вас есть код “опроса перебором”:

который в цикле пробегает все 8 входов. Не нужен опрос всех входов - так не используйте цикл, просто читайте нужный вход функцией readMux(i, Z_pin1)

Или я неверно понял вопрос?

2 лайка

Не совсем правильно видимо сформулировал
Надо примерно так в цикле

Запросить данные с первого мультиплексора 1 канал и записать его в переменную с1.

Запросить данные с первого мультиплексора 6 канал и записать его в переменную с6.

Запросить данные с третьего мультиплексора 5 канал и записать его в переменную с19.

Запросить данные со второго мультиплексора 4 канал и записать его в переменную с12.

И так далее.
Чтобы я сам по сути прописал жёстко очередность опроса каналов.

Это типа я так код по чайниковски объяснил :man_shrugging:t3:

для мультиплексора 3 канал 5 это будет:

c19 = readMux(5, Z_pin3); 

Принцип поняли? - для остальных сами

1 лайк

Массив структуры:

typedef struct {
  uint8_t  muxId;
  uint8_t  channelId;
  int16_t  value;
} muxData_t;

muxData_t muxData[3] = {
  { 
   .muxId = 3,
   .channelId = 6,
   .value = 0,
  },
...
  { 
   .muxId = 1,
   .channelId = 2,
   .value = 0,
  },
}

for ( i от 0 до размера массива) {
 muxData.value[i] = readMux(muxData[i].muxId, muxData[i].channelId);
}
2 лайка

Дай бог тебе здоровью золотой ты мой человек)))
Это как раз ровно то что я и имел ввиду.

Интересное решение. Обязательно попробую. Спасибо

Всем добра.
Получилось вот так.

void loop () {
  int C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15, C16, C17, C18, C19, C20, C21, C22, C23, C24;

  C1 = readMux(0, Z_pin1);
  C2 = readMux(1, Z_pin1);
  C3 = readMux(2, Z_pin1);
  C4 = readMux(3, Z_pin1);
  C5 = readMux(4, Z_pin1);
  C6 = readMux(5, Z_pin1);
  C7 = readMux(6, Z_pin1);
  C8 = readMux(7, Z_pin1);

  C9  = readMux(0, Z_pin2);
  C10 = readMux(1, Z_pin2);
  C11 = readMux(2, Z_pin2);
  C12 = readMux(3, Z_pin2);
  C13 = readMux(4, Z_pin2);
  C14 = readMux(5, Z_pin2);
  C15 = readMux(6, Z_pin2);
  C16 = readMux(7, Z_pin2);

  C17 = readMux(0, Z_pin3);
  C18 = readMux(1, Z_pin3);
  C19 = readMux(2, Z_pin3);
  C20 = readMux(3, Z_pin3);
  C21 = readMux(4, Z_pin3);
  C22 = readMux(5, Z_pin3);
  C23 = readMux(6, Z_pin3);
  C24 = readMux(7, Z_pin3);

Теперь ломаю голову как избавится вот от этого куска кода

float readMux(int channel, int Z_pin) {
  int controlPin[] = {s0, s1, s2};

  int muxChannel[8][3] = {
    {0, 0, 0}, //channel 0
    {1, 0, 0}, //channel 1
    {0, 1, 0}, //channel 2
    {1, 1, 0}, //channel 3
    {0, 0, 1}, //channel 4
    {1, 0, 1}, //channel 5
    {0, 1, 1}, //channel 6
    {1, 1, 1}, //channel 7
  };

  //loop through the 3 sig
  for (int i = 0; i < 3; i ++) {
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }

  //read the value at the Z pin
  int val = analogRead(Z_pin);

  //return the value
  float voltage = (val * 5) / 1024;
  return voltage;
}

Нужно массив как то прописать в каждую строчку кода в цикле.

ты можешь и результаты и мультиплескоры прецтавить сквозным массивом значений 0…23

uint16_t ResValues[24];

uint16_t ReadValue(const uint8_t APin) {
	uint8_t numPin = APin & 0x07;
	
	if (APin < 8)  return readMux(numPin, Z_pin1);
	if (APin < 16) return readMux(numPin, Z_pin2);
	return readMux(numPin, Z_pin3);
}

void loop(void) {
	for (uint8_t i = 0; i < 24; ++i)
		ResValues[i] = ReadValue(i);
}

Проверки индексов сам рисуй.

Деда, а почему ты аргумент функции объявляешь как const ? На что это влияет?

Просто привычка. Ни на что не влияет, кроме того, что унутре функции нельзя изменить значение её параметра. С указателями это полезно, во избежание побочных эффектов, с простыми типами - полезность примерно как у андона на свечке. Но руки сами пишут… :slight_smile:
Золотое правило: если не собираешься ничего менять, обьяви это “ничево” как const, а дальше пусь канпилятор тебя по пальцам бьёть.

Понял, спасибо!

1 лайк

Дает больше информации компилятору для оптимизации.

1 лайк