Уменьшение времени считывания для считывания датчиков температуры DS18B20

У меня есть ряд датчиков температуры, подключенных к Arduino - я разделил его на 3 секции, причем каждая секция имела на нем 2-4 датчика (из-за расстояний). Это работает, но код, который я использую, кажется мне очень неэффективным - особенно в отношении того, сколько времени потребуется, чтобы прочитать все датчики.

У меня есть 3 блока кода один за другим (которые модифицированы из некоторого кода в Интернете), которые выглядят как ниже - сохраните, конечно, имя класса 1wire.

// Dallas 1 Wire (Main Area):

 //  ds.reset_search();
 //  delay(250);
  while (ds.search(addr))
  {
    for( i = 0; i < 8; i++) {
      Serial.print(addr[i], HEX);
    }

    if (OneWire::crc8(addr, 7) != addr[7]) {
        Serial.println("CRC is not valid!");
        return;
    }

    ds.reset();
    ds.select(addr);
    ds.write(0x44, 0);        // start conversion, with parasite power on at the end

    delay(1000);     // maybe 750ms is enough, maybe not
    // we might do a ds.depower() here, but the reset will take care of it.

    present = ds.reset();
    ds.select(addr);    
    ds.write(0xBE);         // Read Scratchpad

    for ( i = 0; i < 9; i++) {           // we need 9 bytes
      data[i] = ds.read();
    }
    raw = (data[1] << 8) | data[0];
    if (type_s) {
      raw = raw << 3; // 9 bit resolution default
      if (data[7] == 0x10) {
        // "count remain" gives full 12 bit resolution
        raw = (raw & 0xFFF0) + 12 - data[6];
      }
    } else {
      byte cfg = (data[4] & 0x60);
      // at lower res, the low bits are undefined, so let's zero them
      if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
      else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
      else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
      //// default is 12 bit resolution, 750 ms conversion time
    }
    celsius = (float)raw / 16.0;
    Serial.print(":");
    Serial.print(celsius);
    Serial.print(",");
  }

Я отмечаю, что после каждого датчика считывается 1000 мс задержки, и мне интересно, могу ли я уменьшить это до одной 750 мс задержки для всех датчиков. Мои первоначальные попытки сделать это не увенчались успехом - но я признаюсь, что не могу полностью оторваться от ds.reset, ds.select и т. Д., И мои первоначальные попытки сделать это потерпели неудачу.

Можно ли удалить эту задержку после прочтения каждого датчика?

2 голоса | спросил davidgo 16 PM000000100000003731 2015, 22:41:37

2 ответа


1

Спустя почти год и несколько экспериментов я узнал немного больше об использовании этих устройств:

Выдача датчиков Команда Skip ROM, за которой следует команда Convert T, запускает все устройства, которые сразу преобразуют температуру (pg.11 таблицы данных). Затем вам нужно только подождать один период задержки {750,375,188,94} мс для {12,11,10,9} -битного преобразования, прежде чем вы сможете начать считывать температуры.

Если устройства питаются паразитным образом, шина будет нуждаться в сильном подтягивании во время преобразования; 4.7KOhm pullup недостаточно (pg.5 таблицы).

Ардуиновый штырь может испускать 40 мА, и я обнаружил, что второй штырь, напрямую обходящий 4,7 тыс. pullup без предлагаемого транзистора, будет достаточно для подачи тока по меньшей мере для 3 датчиков (сколько я пытался до сих пор) и Я предполагаю, что техника может быть расширена до большего количества контактов. Сильный pullup должен быть включен в течение 10uSec после команды Convert T и продолжаться в течение всего времени преобразования. Спецификация 10uSec в значительной степени означает, что вы должны сделать это в библиотеке.

Я храню сокращенную библиотеку DS18B20, в которой я предполагаю, что датчики на шине связаны друг с другом, поэтому он устанавливает все свои разрешения сразу и сразу начинает их конверсии и предполагает, что шина снабжена паразитом, так что он переключает указанный контакт в качестве сильного подтягивания. Я отказываюсь от некоторой гибкости, которую допускает библиотека полного DSTemperature, но она удовлетворяет моим требованиям к измерению температуры (пока) и упрощает мой код приложения с помощью black-boxing вышеупомянутых методов.

ответил JRobert 12 J0000006Europe/Moscow 2016, 21:35:19
1

Выполнение поиска каждый раз довольно неэффективно. Функция поиска предназначена, если вы не знаете адрес устройства - и требуется некоторое время. В вашем случае, по-видимому, адреса никогда не изменятся. Найдите адреса и скопируйте их в свой код. Или, если это не практично, сохраните их в EEPROM. И даже если это не практично, найдите адреса один раз в настройке.


Затем вам потребуется задержка, пока вы принимаете показания температуры. Почему бы не параллельно этим? В цикле сообщите всем устройствам о чтении. Затем подождите одну секунду. Затем прочитайте их все (в другом цикле). Таким образом, односекундная задержка распределяется между всеми вашими датчиками.

Однако из страницы, связанной с Gerben :

  

И не возможно запускать датчики DS1820 на простом подтягивающем резисторе. На этапе «Конверсия» ему требуется больше энергии. И есть Замечание по применению, обсуждающее это по длине.

Это говорит о том, что если вы используете паразитную силу, мое предложение не будет работать слишком хорошо (наличие нескольких устройств с чтением сделает хуже).


Я нашел этот код на своем диске пару лет назад. Кажется, что нет никаких задержек между датчиками считывания. Задержка в конце основного цикла происходит, главным образом, для остановки спам-анализа последовательного монитора.

Обратите внимание на комментарий:

  

Вызовите sensor.requestTemperatures (), чтобы выдать глобальный запрос температуры ко всем устройствам на шине

Посмотрите, работает ли это для вас.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Streaming.h>

// Data wire is plugged into port 10 on the Arduino
const byte ONE_WIRE_BUS = 10;
const byte TEMPERATURE_PRECISION = 10;
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
DeviceAddress myThermometer [10];
int deviceCount;

void setup(void)
{

  // start serial port
  Serial.begin (115200);
  Serial << "Dallas Temperature IC Control Library Demo" << endl;

  // Start up the library
  sensors.begin();

  // locate devices on the bus
  Serial << "Locating devices..." << endl;
  deviceCount = sensors.getDeviceCount();

  Serial << "Found " << deviceCount << " devices." << endl;

  // report parasite power requirements
  Serial << "Parasite power is: " << (sensors.isParasitePowerMode() ? "ON" : "OFF") << endl; 

  // method 1: by index

  for (int i = 0; i < deviceCount; i++)
  {
    if (sensors.getAddress(myThermometer [i], i))
    { 
      Serial << "Device " << i << " Address: ";
      printAddress(myThermometer [i]);
      Serial << endl;
      sensors.setResolution(myThermometer [i], TEMPERATURE_PRECISION);
    }
    else
      Serial << "Unable to find address for Device " << i << endl;
  }  // end of for loop

}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}


void loop(void)
{ 

  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  sensors.requestTemperatures();

  // now get all temperatures
  for (int i = 0; i < deviceCount; i++)
  {
    float tempC = sensors.getTempC(myThermometer [i]);
    if (tempC > -80)
    { 
      Serial << "Device " << i << " Temperature: " << tempC << endl;
    }
    else
      Serial << "Unable to find temperature for Device " << i << endl;
  }  // end of for loop

  delay (1000);
}
ответил Nick Gammon 17 AM000000120000004431 2015, 00:08:44

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132