1-wire. Как происходит индексация

sigma_shig
Offline
Зарегистрирован: 30.12.2016

А как происходит индексация ведомых устройств на шине 1-wire? Суть проблемы: у меня есть шина, на которую нанизана гирлянда 10 термометров. Могу ли я полагаться, что самое первое устройство будет с индексом 0, следующее - индекс 1 и т.д.? Или как иначе определить, какой термометр из этой гирлянды выдал это значение? Да, я могу узнать адрес каждого устройства и прописать его в скетч. Но, как это сделать для серийного производства - не будешь же, для каждого термометра модифицировать скетч. И что делать, если один датчик сгроел и я его заменил другим - надо ли исправлять скетч? Или просто полагаться на индексы?

gena
Offline
Зарегистрирован: 04.11.2012

  Каждый термометр имеет уникальный номер и, думаю, каждый раз придётся при замене термометра править скетч. Или писать светч, который даст возможность вручном режиме присваивать термометрам индексы.

bwn
Offline
Зарегистрирован: 25.08.2014

gena пишет:

  Каждый термометр имеет уникальный номер и, думаю, каждый раз придётся при замене термометра править скетч. Или писать светч, который даст возможность вручном режиме присваивать термометрам индексы.

Воистину так. А для серийного применения и замены пишем функцию определения, на экране - нагрей датчик1, греем, прописывается индекс и так до конца. При следующей загрузке определили, что появился новый номер, все по новой. Ну или каждому свою линию.

В принципе вроде возможен еще вариант, но он не менее гемморойный, определяем адреса всех датчиков и распологаем их в возрастающем порядке, определяются и сортируются они вроде по возрастанию, тогда индекс будет равен порядковому номеру датчика.

sigma_shig
Offline
Зарегистрирован: 30.12.2016

Примерно так я и предполагал :( А кто-то поднимал несколько OneWire на одном контроллере? Это сильно грузит ардуину?

bwn
Offline
Зарегистрирован: 25.08.2014

А чему там грузить особо, команду на конвертацию общую подать нельзя, а все остальное и так выполняется для каждого.

bwn
Offline
Зарегистрирован: 25.08.2014

Проблема, что при десяти датчиках уже и пинов цифровых не остается для 8-328.

sigma_shig
Offline
Зарегистрирован: 30.12.2016

Я не залазил в "потроха" OneWire библиотеки потому и не знаю. Мало ли, вдруг она перехватывает таймер или еще какой-то уникальный ресурс.

bwn
Offline
Зарегистрирован: 25.08.2014

Там в любом случае последовательный опрос каждого датчика. Блокировка есть, у человека вывод на ТВ глючил, пока опрос датчиков не разнесли во времени и чем их больше, тем сильнее усугубляется проблема. Возможно и свою функцию опроса писать придется, без библиотек.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

bwn пишет:

Блокировка есть, 

Если Вы о маленьких (микросекундных) блокировках, то да, а если о той самой - в полторы секунды, то её легко обойти. В библиотеке для "далласа" это и прямо предусмотрено, но там ошибка в методе и из-за этого блокируется в любом случае, но обойти можно даже штатными средствами библиотеки, без правки ошибки и дописывания своих методов.

bwn
Offline
Зарегистрирован: 25.08.2014

ЕвгенийП, именно о микросекундных, ТС не обозначил, что для него "тормозить". DT я принципиально не использую, вообще в ней смысла не вижу. OneWire делает тоже самое, только гибче и дешевле.)))

sigma_shig
Offline
Зарегистрирован: 30.12.2016

Мне нужно опросить 10 датчиков в течении секунды. А можно подробнее про "полуторасекундную блокировку"?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Про полторы секунды я погорячился - 750ms на самом деле.

Даташит на датчик откройте, там подробнее написано сколько времени этому датчику нужно, чтобы подшотовить результат.

Так вот библиотека DallasTemperature (если её использовать в лоб) тупо савит там delay(750)

bwn
Offline
Зарегистрирован: 25.08.2014

sigma_shig пишет:

Мне нужно опросить 10 датчиков в течении секунды. А можно подробнее про "полуторасекундную блокировку"?

Если нет критичных к задержкам (ТВ экран, диммер) устройств, то вы и сотню за секнду опросите. Задержка обусловлена даташитом - в 12битном режиме не менее (более сколько угодно) 750мС. Начнете считывать раньше - температуру он отдаст, но это будет от предыдущего измерения.
В гугле наберите "DS18B20 Чернов" - неплохой русский перевод. Если аглицким владеете, то лучше оригинал.

sigma_shig
Offline
Зарегистрирован: 30.12.2016

Правильно ли я понял с этой задержкой, если использовать DT и опрашивать температуру в цикле раз в секунду: допустим, я установил setWaitForConversion(false), сделал requestTemperature() и сразу же getTempC() без задержки, то, в итоге, я получу температуру с прошлого измерения, но, на следующем проходе цикла, я получу уже обновленную температуру (но опять не "свежайшую"). Таким образом я могу избежать delay, но показания термометра будут отставать на один цикл. Так?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Неправильно. Там ошибка в библиотеке. Так не сработает. Ну, разве что, Вы её поправите.

Да и вообще это идейно неправильно. Преобразование может и раньше закончиться 750 - это максимальное время за которое оно гарантировано закончится.

Правильно:

1. запустить преобразование (и ничего не ждать). Можно запускать хоть у 10-ти датчиков
2. Периодически спрашивать "ну как там, ещё не готово?" (тоже у всех 10)
3. По мере готовности запрашивать температуру у соответсвующего датчика.

sigma_shig
Offline
Зарегистрирован: 30.12.2016

Полез в исходники библиотеки:

bool DallasTemperature::requestTemperaturesByAddress(const uint8_t* deviceAddress){

    uint8_t bitResolution = getResolution(deviceAddress);
    if (bitResolution == 0){
     return false; //Device disconnected
    }

    if (_wire->reset() == 0){
        return false;
    }

    _wire->select(deviceAddress);
    _wire->write(STARTCONVO, parasite);


    // ASYNC mode?
    if (!waitForConversion) return true;

    blockTillConversionComplete(bitResolution, deviceAddress);

    return true;

}

Вижу, что если сделать setWaitForConversion(false), то запрос на конверсию будет запущен и ожидания не будет. А потом? в своем коде  

if (isConversionAvailable(deviceAddress)) { // Ура, есть значение!
...
} else { //ну еще подожди....}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, да, примерно так. Вот, посмотрите работающий код, если интересно.

template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }

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

#define SENSOR_PIN 6

OneWire oneWire(SENSOR_PIN);
DallasTemperature sensors(&oneWire);
DeviceAddress deviceAddress;


void setup(void) {
  Serial.begin(115200);
  Serial << "Non blocking Dallas Temperature Demo\n";
  sensors.begin();
  sensors.getAddress(deviceAddress, 0);
  sensors.setWaitForConversion(false);
}

void loop(void) {
	static bool didNotSendYet = true;
	static unsigned long start;
	if (didNotSendYet) {
		 start = millis();
		sensors.requestTemperaturesByAddress(deviceAddress); 
		didNotSendYet = false;
	} else if (sensors.isConversionAvailable(deviceAddress)) {
		const float temp = sensors.getTempC(deviceAddress);
		const unsigned long duration = millis() - start;
		Serial << "Temperature: " << temp << " (" << duration << " ms)\n"; 
		delay(2000);
		didNotSendYet = true;
	}
}
 
bwn
Offline
Зарегистрирован: 25.08.2014

Ну что вас всех на эту DT прет. Или лишних 2К имеется? Вот на OneWire и сторожевом таймере. Дальше есть и на миллис.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так я для себя и без OneWire делаю - полный самогон, часто нужно делать на тиньках безо всякой ардуно-среды, так что давно как-то сделал этот протокол "совсем вручную" и пользую. Но тем, кто только начинает и всего боится - так проще. Есть тип готовая бибилотека, написанная большими мальчишками. 

bwn
Offline
Зарегистрирован: 25.08.2014

У меня с ней как то сразу не заладилось. OneWire  на порядок проще оказалась. Шли себе команды последовательно и укладывай данные как хочется. ИМХО.

achuser
Offline
Зарегистрирован: 02.03.2013

Может кто в курсе, все таки, как индексация работает?  При каждой инициализации список составляется по принципу кто первый ответил, того и место? Или согласно адресам в алфавитном порядке? 

Например, есть несколько датчиков, чтобы не заморачиваться с их адресами, а просто использовать индекс 0, индекс1 и и тд, при первой сборке определить кто есть кто и пользоваться так постоянно.

Или при следующей загрузке программы тот датчик, что был индекс0 может залезть в адрес индекс1 уже?

 

bwn
Offline
Зарегистрирован: 25.08.2014

В порядке возрастания адресов. Посмотрите в описаниях и даташите, там алгоритм расписан.

Второй вариант, прописать адреса в массиве в нужном порядке.

achuser
Offline
Зарегистрирован: 02.03.2013

ок, спасибо, просто вроде остледил датчик, поставил устройтсво, и по ощущениям теперь все наоборот, второй стал первым :) Буду наблюдать дальше. 

bwn
Offline
Зарегистрирован: 25.08.2014

А чего наблюдать то, зажигалку поднесите и все ясно.