Как выбрать датчик с использованием чипа 74HC138 на Wemos D1 Mini?

У меня есть проект для дипломной работы.

Речь идет о мониторинге температуры и влажности с использованием телеметрической передачи очереди сообщений на последовательном NodeJS. Чтобы получить данные датчиков для Wemos D1 Mini и NodeJS, я также сделал это для MQTT. Мой преподаватель хочет получить данные с двух датчиков по краям комнаты, он предлагает использовать 74HC138. Я использую эту техническую таблицу 74HC138 и эту Библиотека BME280.

Это моя схема:

Schematic

Это мой код:

#include <BME280.h>

const uint32_t SERIAL_SPEED = 115200;
const uint8_t SCK_PIN = D5;
const uint8_t MISO_PIN = D6;
const uint8_t MOSI_PIN = D7;
const uint8_t SPI_CS1_PIN = 15;
const uint8_t SPI_CS2_PIN = 14;
const uint8_t GPIO[3] = {D1, D2, D3};

static int32_t temperature, humidity, pressure;
int i;

BME280_Class   BME280;

void setup() {
  Serial.begin(SERIAL_SPEED);
  pinMode(SCK_PIN, OUTPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, INPUT);

  SPI.begin();
  SPI.setBitOrder(LSBFIRST);

  Serial.println(F("condition before loop = "));
  //status_pin();
  for (i = 0; i < 3; i++) {
    pinMode(GPIO[i], INPUT);
    digitalWrite(GPIO[i], HIGH);
  }
  pinMode(SPI_CS1_PIN, OUTPUT);
  pinMode(SPI_CS2_PIN, OUTPUT);

  Serial.println(F("Starting Hardware SPIDemo example program for BME280"));
  Serial.print(F("- Initializing BME280 sensor\n"));

  if ( (!BME280.begin(SPI_CS1_PIN) && (!BME280.begin(SPI_CS2_PIN) ) {
    Serial.println(F("-  Unable to find BME280. Waiting 3 seconds."));
    delay(3000);
  }

  BME280.mode(SleepMode);
  Serial.print(F("- Sensor detected in operating mode \""));
  Serial.print(BME280.mode());
  Serial.println(F("\"."));
  if (BME280.mode() == 0) {
    Serial.print(F("- Turning sensor to normal mode, mode is now \""));
    Serial.print(BME280.mode(NormalMode));
    Serial.println("\"");
  }
  Serial.println(F("- Setting 16x oversampling for all sensors"));
  BME280.setOversampling(TemperatureSensor, Oversample16);
  BME280.setOversampling(HumiditySensor,   Oversample16);
  BME280.setOversampling(PressureSensor,   Oversample16);
  Serial.println(F("- Setting IIR filter to maximum value of 16 samples"));
  BME280.iirFilter(IIR16);
  Serial.println(F("- Setting time between measurements to 1 second"));
  BME280.inactiveTime(inactive1000ms);
  Serial.print(F("- Each measurement cycle will take "));
  Serial.print(BME280.measurementTime(MaximumMeasure) / 1000);
  Serial.println(F("ms.\n\n"));
}

void loop() {
  static uint8_t loopCounter = 0;
  byte pin1 = 0x74;
  byte pin2 = 0x71;

  if ( BME280.begin(SPI_CS1_PIN) == 1 ) {
    selpin(pin1);
    Serial.println(F(" Data Bme = "));
  } else if ( BME280.begin(SPI_CS2_PIN) == 1 ) {
    selpin(pin2);
    Serial.println(F(" Data Bme = "));
    printdata();
  }

  if (++loopCounter % 10 == 0) {
    Serial.print(F("\n- Turning "));
    if (BME280.getOversampling(HumiditySensor) == 0) {
      BME280.setOversampling(HumiditySensor, Oversample16);
      Serial.print(F("ON"));
    } else  {
      BME280.setOversampling(HumiditySensor, SensorOff);
      Serial.print(F("OFF"));
    }
    Serial.println(F(" humidity sensing"));
    Serial.print(F("- Each measurement cycle will now take "));
    Serial.print(BME280.measurementTime(MaximumMeasure) / 1000.0);
    Serial.println(F("ms.\n"));
  }

  Serial.println(F("condition after loop = "));
  //status_pin();
  Serial.println();

}

float altitude(const float seaLevel = 1013.25) {
  int32_t temp, hum, press;
  BME280.getSensorData(temp, hum, press);
  float Altitude = 44330.0 * (1.0 - pow(((float)press / 100.0) / seaLevel, 0.1903));
  return (Altitude);
}

void printdata () {
  BME280.getSensorData(temperature, humidity, pressure);
  Serial.print(F("Temperature : "));
  Serial.print(temperature / 100.0);
  Serial.println(F(" *C"));
  if (BME280.getOversampling(HumiditySensor) != 0) {
    Serial.print(F("Humidity : "));
    Serial.print(humidity / 100.0);
    Serial.println(F(" %"));
  }
  Serial.print(F("Pressure : "));
  Serial.print(pressure / 100.0);
  Serial.println(F(" hPa"));
  Serial.print(F("Altitude : "));
  Serial.print(altitude());
  Serial.println(F(" m"));
  Serial.println();
  delay(5000);
}

Последовательный вывод всегда говорит: Невозможно найти BME280. Ожидание 3 секунды. Я знаю, что это потому, что контакт CS не может быть обнаружен. Я думаю, что в моем коде чего-то не хватает.

РЕШЕНО

Спасибо моему приятелю @Majko, у меня нет в наличии 74HC138, но у меня есть 74HC139, думаю, для меня то же самое, я воспользовался советом @Majko рано утром после того, как сделал сборку своей платы самостоятельно, чтобы определить выбор чипа Вернемся к моему контакту включения и вернём мой недостающий код, который меня не понимает.

См. ниже подробный журнал загрузки моего скетча.

См. ниже информацию о последовательном мониторе.

Спасибо.

, 👍1


1 ответ


Лучший ответ:

3

Использовать 74HC138 в этой ситуации бессмысленно и расточительно. Вы используете 3 контакта (или 4 — см. ниже), чтобы управлять чипом и выбирать между двумя контактами. Это приведет к потере на один контакт больше, чем если бы вы напрямую управляли контактами CS.

Это имеет смысл только в том случае, если вы хотите подключить 5 или более устройств. В этом случае вы сэкономите на количестве используемых контактов.

В любом случае, в вашем коде не хватает абсолютно всего, что связано с 74HC138. Во-первых, вы используете библиотеку, которая предполагает, что контакты CS напрямую подключены к MCU. Во-вторых, не существует кода для установки контактов A/B/C в правильное состояние для выбора выхода.

Если вам действительно обязательно использовать 74HC138, я бы посоветовал:

  • Используйте один и тот же вывод CS в своем коде для каждого экземпляра BMS280.
  • Подключите этот контакт CS к G2A на 74HC138.
  • Для доступа к датчику используйте следующую процедуру:
    1. Выберите правильный выход на 74HC138, установив контакты A/B/C в двоичное представление нужного вам выхода.
    2. Выполните необходимые операции BME280 на соответствующем экземпляре

schematic

Вывод CS, который вы передали экземплярам BME280, будет управлять состоянием текущего выбранного выхода на 74HC138, превращая его в демультиплексор, управляемый выводами A/B/C. Использование нескольких экземпляров класса BME280, связанных с каждым выбранным выходом, позволит правильно отслеживать любое внутреннее состояние и данные, связанные с устройством, подключенным к этому выходу.

Или, и это просто выбрасывание идей, не используйте 74HC138 и скажите своему «преподавателю», что это глупая идея использовать 3 контакта (4, включая контакт выбора чипа) для управления парой устройств, которые нужно всего 2 контакта.

,

Я все еще немного запутался, сэр, вы имеете в виду "Подключите этот вывод CS к Q2A на 74HC138"? Я должен подключить CS, чтобы включить входной вывод, и куда я должен подключить выходной вывод Y1-Y2? Где я могу найти пример отправки двоичного представления на чип? Я действительно нуб в затворе чипа, сэр, @abu-ahmed al-khatiri

Извините, на вашей маленькой картинке это G, а не Q. Мне кажется, это то же самое. Вы не «отправляете» двоичное представление на чип. Вы устанавливаете три контакта, подключенных к A/B/C, на это двоичное представление. Выход 0 — НИЗКИЙ/НИЗКИЙ/НИЗКИЙ. Выход 1 — ВЫСОКИЙ/НИЗКИЙ/НИЗКИЙ. Выход 2 — НИЗКИЙ/ВЫСОКИЙ/НИЗКИЙ, выход 3 — ВЫСОКИЙ/ВЫСОКИЙ/НИЗКИЙ и т. д. Выходы идут так, как они есть сейчас., @Majenko

да, это G, все в порядке, хорошо, я понимаю, что вы имеете в виду на своей картинке. Чтобы установить контакты A/B/C, мне нужно использовать pinMode или digitalWrite, сэр?, @abu-ahmed al-khatiri

Оба. pinMode для установки их в качестве выходов и digitalWrite для установки логических уровней., @Majenko

привет еще раз, мой друг, если моя лекция хочет установить вывод включения на низкий уровень, какой из них мне объявить вывод CS для моего 74hc139 сэр? Я не получил никаких опций., @abu-ahmed al-khatiri

Я не понимаю, о чем вы спрашиваете (языковой барьер)., @Majenko

Извините, если я ошибся, если мой преподаватель хочет подключить вывод включения к GND как активный низкий уровень, как мне подключить вывод CS в Wemos к IC 74hc139, сэр?, @abu-ahmed al-khatiri

С проводом? Я все равно не понимаю, чего ты хочешь., @Majenko

да, с помощью провода, если контакт GA на контакте GND имеет активный низкий уровень, как мне инициализировать контакт CS в Wemos для IC?, @abu-ahmed al-khatiri

Библиотека bme280 должна сделать все это за вас., @Majenko

если я определю вывод D8, где я должен подключиться к 74hc138, чтобы получить данные?, @abu-ahmed al-khatiri

G2A, как я показал на своей схеме., @Majenko

если я подключу вывод D8 к выводу G2A, будет ли он активен на низком уровне?, @abu-ahmed al-khatiri

G2A и G2B активны на низком уровне. G1 активен на высоком уровне. Все три должны быть активны для работы чипа., @Majenko

становится ли вывод D8 активным на низком уровне?, @abu-ahmed al-khatiri

Выходы не имеют концепции "активности", только текущий выбранный уровень. Если вы используете D8 в функции begin для объекта BME280, то код BME280 переведет его на низкий уровень, когда это необходимо., @Majenko

если я подключу вывод G2A к выводу GND как активный низкий уровень, как мне использовать вывод D8 для выполнения функции начала?, @abu-ahmed al-khatiri

Wemos подключает его к земле для вас. Вы не подключаете его к земле. D8, когда низкий, подключает штифт к земле., @Majenko

Теперь я вижу, что я за тебя проголосовал!!, @abu-ahmed al-khatiri