2016-02-18 2 views
0

Мне был дан этот код, который читается с устройства температуры OneWire DS18b20. Я хотел бы добавить еще один датчик к тому же выводу, но не совсем уверен, как лучше всего это сделать. Я сам не писал этот код. Я использую NodeMCU devkit v0.9. Код ниже - это всего лишь раздел полного кода, и есть отдельные сценарии/вкладки. Дайте мне знать, если я должен добавить что-нибудь еще. Любая помощь приветствуется.Как изменить текущий код на 2 разных устройства OneWire?

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

ответ

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

Затем вы можете изменить вашу функцию, чтобы получить температура г-го датчика:.

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) для второго и так далее.

Перед первым вызовом gettemp вам нужно будет позвонить getAllAddresses, иначе он всегда будет возвращать -200. Вы можете называть его при запуске или каждые X секунд или при каждом измерении, это полностью зависит от вас

+1

спасибо за помощь, я дам вам попробовать – Shane