0

我收到了从 OneWire 温度设备 DS18b20 读取的代码。我想在同一个引脚上添加另一个传感器,但不太确定如何最好地做到这一点。这段代码不是我自己写的。我正在使用 NodeMCU devkit v0.9。下面的代码只是完整代码的一部分,并且有单独的脚本/选项卡。让我知道我是否应该添加任何其他内容。任何帮助是极大的赞赏。

#include <Arduino.h> // not automatically included?
#include <OneWire.h> // for temp sensor
#include <Wire.h>    // I2C for ADC & RTC
#include <DHT.h>     // Humidity sensor    
#include "sens.h"

#define TEMP_PIN D2  // Where DS18B20 is connected
#define ADDR_LEN 8   // 1-Wire address length // NOT SURE WHAT THESE DO!!
#define DATA_LEN 9   // 1-Wire data length // NOT SURE WHAT THESE DO!!
#define HUMI_PIN D1  // Where the DHT11 is
#define RTC_ADDR 0x68  // Clock's I2C address
#define ADC_ADDR 0x48  // ADC's I2C address
#define SDA  D3    // I2C pins
#define SCL  D4

OneWire ow(TEMP_PIN); // Setup 1-Wire
byte addr[ADDR_LEN];  // To store 1-Wire address
byte data[DATA_LEN];  // To store 1-Wire data
DHT dht(HUMI_PIN, DHT11);  // Setup DHT

String leading0(const int c) {
  // Add a leading zero when stringifying a byte, used for the date
  return (c < 10) ? ("0" + String(c)) : String(c);
}

byte bin2bcd( const byte bin ) {
  // does as the name suggests, RTC uses BCD
  return (bin / 10 * 16) + (bin % 10);
}

byte bcd2bin( const byte bin ) {
  // does as the name suggests, RTC uses BCD
  return (bin / 16 * 10) + (bin % 16);
}

void senssetup() {
  // Setup sensors, called in setup()
  dht.begin();
  Wire.begin(SDA, SCL);
}

float gettemp() {
  int i = 0;
  ow.reset_search();
  do {} while (!ow.search(addr) && i++ < 0xff);
  // Search for 1-Wire devices
  if (i == 0x100) {
    if (debug) Serial.println("No devices found!");
    // Nothing connected
    return 0;
  }
  if (OneWire::crc8(addr, 7) != addr[7]) {
    if (debug) Serial.println("CRC 1 failed!");
    // Checksum thing when getting device's address
    return -1;
  }
  if (addr[0] != 0x10 && addr[0] != 0x28) {
    if (debug) Serial.println("Not a DS18B20");
    // Wrong 1-Wire device
    return -2;
  }
  ow.reset();
  ow.select(addr);
  ow.write(0x44, 0);
  // HEX 44 tells it to convert temperature to readable binary
  delay(1000);
  // It takes ~750ms to convert data, 1s is used to be safe (1s is used in the default library too)
  if (!ow.reset()) {
    if (debug) Serial.println("Device not present");
    // Device has disconnected or broken during conversion?
    return -3;
  }
  ow.select(addr);
  ow.write(0xbe, 0);
  // Tells it we're reading
  for (i = 0; i < DATA_LEN; i++) {
    data[i] = ow.read(); // Read data
  }
  if (debug && OneWire::crc8(data, 8) != data[8])
    Serial.println( "CRC Check 2 failed" );
  // Checksum on data; this fails sometimes, I don't know why
  // temperature is always at the right value so ignore it
  int dat =  ((data[1] << 8) | data[0]);
  if (dat > 32767)
    dat -= 65536;
    // 16 bit data in 2's complement has a sign
    return dat / 16.0;
    // last 4 binary digits are fractional
}
4

1 回答 1

2

您应该将搜索部分与获取温度部分分开。

注意:我不喜欢 NodeMCU,所以你必须在使用它之前将其调整为该语言。我会用C。

例如,您可以使用函数获取温度传感器的所有地址并将它们放入地址数组中:

#define MAX_DEVICES 5
byte addresses[MAX_DEVICES][ADDR_LEN];
byte numOfAddresses;

void getAllAddresses()
{
    numOfAddresses = 0;
    ow.reset_search();
    byte address[ADDR_LEN];

    while (ow.search(address) && (numOfAddresses < MAX_DEVICES))
    {
        if ( OneWire::crc8( address, 7 ) != address[7] )
            continue; // CRC 1 failed

        if ( address[0] != 0x10 && address[0] != 0x28 )
            continue; // Not a DS18B20

        byte i;
        for (i = 0; i < ADDR_LEN; i++)
            addresses[numOfAddresses][i] = address[i];
        numOfAddresses++;
    }

    if (debug)
    {
        Serial.print("Found ");
        Serial.print(numOfAddresses);
        Serial.println(" temperature sensors");
    }
}

然后你可以修改你的函数来获取第 i 个传感器的温度:

float gettemp(byte index)
{
    if (index >= numOfAddresses)
    {
        if (debug) Serial.println( "Index not valid" );
        return -200; // Don't use 0, -1, ..., since they are valid temperatures
    }

    ow.reset();
    ow.select(addresses[index]);
    ow.write(0x44, 0); // HEX 44 tells it to convert temperature to readable binary

    [...]

(只需将每次调用替换addr为调用addresses[index].

那么,在您的代码中,gettemp您将不得不调用gettemp(0)第一个传感器,而不是调用gettemp(1)第二个传感器,依此类推。

您需要getAllAddresses在第一次调用 gettemp 之前调用,否则它将始终返回 -200。您可以在启动时或每 X 秒或每次测量时调用它,这完全取决于您

于 2016-02-18T16:52:59.673 回答