1

I have a project for my graduate degree.

It's about Monitoring Temperature and Humidity using Message Queuing Telemetry Transport on Serial NodeJS. To get sensor data to Wemos D1 Mini and NodeJS had done, also on my MQTT had done. My lecturer wants to get data from two sensors at the edges of the room, he suggests using a 74HC138. I'm using this 74HC138 Datasheet and I'm using this BME280 Library.

This is my schematic:

Schematic

This is my code:

#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);
}

Serial output always says Unable to find BME280. Waiting 3 seconds. I know it's because CS pin cannot detect. I think something is missing my code.

SOLVED

Thanks to my pal @Majenko, I'm out of the 74HC138 stock but i have 74HC139, i think that's same to me, i tried advice from @Majenko early morning after i make assembly of my board own for define Chip Select Wemos to my enable pin and get back my missing code whom not understand me.

See below for verbose log of uploading my sketch.

enter image description here

See below for serial monitor.

enter image description here

Thanks.

3

Using a 74HC138 in this situation is both pointless and wasteful. You're using 3 pins (or 4 - see below) to drive a chip to select between 2 pins. That's wasting one more pin than you would by directly driving the CS pins.

The only time it would make sense would be if you were wanting to connect with 5 or more devices, in which case you would get a saving in the number of pins used.

Anyway - what you are missing from your code is absolutely everything to do with the 74HC138. First off, you're using a library which assumes the CS pins are directly connected to the MCU. Second, there is no code to set the A/B/C pins to the right state to select an output.

If you really must use the 74HC138 I would suggest:

  • Use the same CS pin in your code for every BMS280 instance.
  • Connect that CS pin to G2A on the 74HC138
  • Use the following procedure to access a sensor:
    1. Select the correct output on the 74HC138 by setting the A/B/C pins to the binary representation of the output you want
    2. Perform the BME280 operations you want on the relevant instance

schematic

simulate this circuit – Schematic created using CircuitLab

The CS pin you passed to the BME280 instances will control the state of the currently selected output on the 74HC138, turning it into a demultiplexer controlled by the A/B/C pins. Using multiple instances of the BME280 class associated with each selected output will allow proper tracking of any internal state and data associated with the device connected to that output.

Or, and this is just throwing ideas out there, don't use the 74HC138 and tell your "lecturer" that it's a stupid idea to use 3 pins (4 including the chip select pin) to control a pair of devices that need a total of 2 pins.

  • i'm still little confuse sir, your mean "Connect that CS pin to Q2A on the 74HC138" i must connect CS to enable input pin and where i must connect Y1-Y2 output pin? where i can find example of send the binary representation to chip. i really noob about chip gate sir – abu-ahmed al-khatiri Sep 8 '18 at 11:17
  • Sorry, that's a G on your little picture, not a Q. Looks the same to me. You don't "send" the binary representation to the chip. You set your three pins connected to A/B/C to that binary representation. Output 0 is LOW/LOW/LOW. Output 1 is HIGH/LOW/LOW. Output 2 is LOW/HIGH/LOW, Output 3 is HIGH/HIGH/LOW, etc. Outputs go as they are now. – Majenko Sep 8 '18 at 12:07
  • yes that's G, it's fine, ok i can see what do you mean on your picture, to set A/B/C pin what i must using pinMode or digitalWrite sir? – abu-ahmed al-khatiri Sep 8 '18 at 12:20
  • Both. pinMode to set them as outputs, and digitalWrite to set the logic levels. – Majenko Sep 8 '18 at 13:11
  • 1
    The wemos connects it to ground for you. You don't connect it to ground. D8, when low, connects the pin to ground. – Majenko Nov 1 '18 at 16:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.