Простой во время опроса датчиков

rfl
Offline
Зарегистрирован: 21.10.2013

Здравствуйте.

Время опроса 5 датчиков DHT22 (4шт) и DS20B18 (1шт) составляет около 1,8 секунды. На этот период Arduino Mega 2560 как бы зависает и не реагирует ни на какие внешние раздражители (кнопки и т.п.)

Планировал на одну Arduino повестить опрос датчиков температуры, выключатели света и др., но так как если нажать выключатель освещения во времяо проса датчиков - он не сработает, что есть не правильно.

Возможно есть способ обойти эту проблему, т.е. чтобы на время опроса МК не "зависал"? Опрос датчиков не всех за раз, а попеременно решает проблему только частично, так как, например, по DataSheet DS18B20 время получения данных - 750 мс (0,7 сек.)

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Можно взять другие датчики
Датчики совсем не обязательно безпрерывно опрашивать. Или у вас температура каждые 5 секунд меняется?
Можно расковырять библиотеку.

Araris
Offline
Зарегистрирован: 09.11.2012

Датчики, видимо, имеются в виду DS18B20.

Вы можете воспользоваться тем, что время опроса для них весьма зависит от установок точности.

Table 1. DS18B20 Conversion Times and Resolution Settings 

Resolution                   9 bit     10 bit     11 bit     12 bit
Conversion Time (ms) 93.75   187.5      375       750
LSB (°C)                        0.5      0.25      0.125     0.0625

Пруф: http://www.maximintegrated.com/en/app-notes/index.mvp/id/4377

 

MaksMS
Offline
Зарегистрирован: 11.03.2013

Можно паузу в 750 мс убрать - просто читатся будет без её предыдущее значение

Araris
Offline
Зарегистрирован: 09.11.2012

MaksMS пишет:

Можно паузу в 750 мс убрать - просто читатся будет без её предыдущее значение

Либо соорудить подобную конструкцию : (ReadTemperatures() вызывается раз в секунду)

void ReadTemperatures()
{
if (DS18B20mode) { DS18B20sensors1.requestTemperatures(); }
                      else { tempGet = DS18B20sensors1.getTempC(DS18B20_devaddr0); }
DS18B20mode = !DS18B20mode;
}

rfl
Offline
Зарегистрирован: 21.10.2013

Araris, MaksMS спасибо за наводку куда копать - суть понял, в реализации буду разбираться, пока что только начинаю осваивать программирование Arduino.

rfl
Offline
Зарегистрирован: 21.10.2013

Разбираясь с библиотекой DallasTemperature и пытаясь заменить delay() на millis() совершенно неожиданно для меня получилось уменьшить время получения температуры с 750 мс (все датчики) до 45 мс (каждый датчик) вообще ничего не изменяя в библиотеке, просто немного подредактировав пример, идущий в комплекте с ней... Код:

 

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

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS_1 35
#define TEMPERATURE_PRECISION 12

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire_1(ONE_WIRE_BUS_1);

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

// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer;

void setup(void)
{
  // start serial port
  Serial.begin(115200);

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

  // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.print("Found ");
  Serial.print(sensors_1.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: "); 
  if (sensors_1.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  // search for devices on the bus and assign based on an index.  ideally,
  // you would do this to initially discover addresses on the bus and then 
  // use those addresses and manually assign them (see above) once you know 
  // the devices on your bus (and assuming they don't change).
  // 
  // method 1: by index
  if (!sensors_1.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
  if (!sensors_1.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 

  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  Serial.print("Device 1 Address: ");
  printAddress(outsideThermometer);
  Serial.println();

  // set the resolution
  sensors_1.setResolution(insideThermometer, TEMPERATURE_PRECISION);
  sensors_1.setResolution(outsideThermometer, TEMPERATURE_PRECISION);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors_1.getResolution(insideThermometer), DEC); 
  Serial.println();

  Serial.print("Device 1 Resolution: ");
  Serial.print(sensors_1.getResolution(outsideThermometer), DEC); 
  Serial.println();
}

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

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors_1.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print("Resolution: ");
  Serial.print(sensors_1.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}

void loop(void)
{ 

  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  
  unsigned long current_millis = millis();
  //sensors_1.requestTemperatures();
  
  sensors_1.requestTemperaturesByAddress(insideThermometer);
  sensors_1.requestTemperaturesByAddress(outsideThermometer);
  
  Serial.print("DONE");
  unsigned long end_millis = millis();
  unsigned long millis_interval = end_millis - current_millis; 
  Serial.print(" Time interval: ");  
  Serial.println(millis_interval);



  // print the device information
  printData(insideThermometer);
  printData(outsideThermometer);
}

Если раскомментировать 114 строку - sensors_1.requestTemperatures() время получения результата заметно возрастает.

Я совсем ничего не понимаю - согласно описанию DS18B20 при точности 12 бит время от запроса до получения температуры - 750 мс. Каким же тогда таким "чудесным" образом используя requestTemperaturesByAddress() вместо requestTemperatures() получилось так сократить время на получение результата?

Да, и просьба разъяснить: если опрашивать датчики DS18B20 раз в секунду - не сократит ли это существенно время до их выхода из строя? В даташите я не нашел никакой информации по этому поводу.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

MaksMS пишет:

Можно паузу в 750 мс убрать - просто читатся будет без её предыдущее значение

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

rfl пишет:

Да, и просьба разъяснить: если опрашивать датчики DS18B20 раз в секунду - не сократит ли это существенно время до их выхода из строя? В даташите я не нашел никакой информации по этому поводу.


Ой какой правильный вопрос. Конечно же датчики стираются от часто прилетающих электронов с запросом.

Radjah
Offline
Зарегистрирован: 06.08.2014
// ВСЕ БЫСТРА МНЕ ТЕМПЕРАТУРУ!!!11
sensors_1.requestTemperatures();
// МЕРЯЙ ТЕМПЕРАТУРУ!!!!111
sensors_1.requestTemperaturesByAddress(insideThermometer);
// И ТЫ ТОЖЕ МЕРЯЙ ТЕМПЕРАТУРУ!!!111
sensors_1.requestTemperaturesByAddress(outsideThermometer);

Или я чего не понимаю, или одно из двух. Зачем сначала запрашивать по всей шине, а потом персональной у каждого датчика?

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

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Radjah пишет:

Или я чего не понимаю, или одно из двух. Зачем сначала запрашивать по всей шине, а потом персональной у каждого датчика?

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


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

rfl
Offline
Зарегистрирован: 21.10.2013

Radjah пишет:

// ВСЕ БЫСТРА МНЕ ТЕМПЕРАТУРУ!!!11
sensors_1.requestTemperatures();
// МЕРЯЙ ТЕМПЕРАТУРУ!!!!111
sensors_1.requestTemperaturesByAddress(insideThermometer);
// И ТЫ ТОЖЕ МЕРЯЙ ТЕМПЕРАТУРУ!!!111
sensors_1.requestTemperaturesByAddress(outsideThermometer);

Или я чего не понимаю...

Строка с sensors_1.requestTemperatures() оставлена для теста, и она, кстати, еще и закомментирована. Только все сразу - как раз медленнее: 750 мс, а по одному (sensors_1.requestTemperaturesByAddress(insideThermometer) и sensors_1.requestTemperaturesByAddress(insideThermometer)) - намного быстрее: 45 мс на каждый датчик, 90 мс на 2.

Надеюсь, так будет понятнее? :)

Puhlyaviy пишет:
rfl пишет:

Ой какой правильный вопрос. Конечно же датчики стираются от часто прилетающих электронов с запросом.

А Вы, наверное, как родились, так сразу у родителей и потребовали: "Телочку мне!!!", ну вот так, прямо с пеленок? :)))
А по сути - зачем марать мой топик своим сарказмом? Ведь его прочитает не один человек, и вместо полезной информации - Ваши сообщения... Вопросы, которые для гуру могут казаться глупыми и смешными, новичку, иногда, бывает решить очень не просто.

Puhlyaviy пишет:
 А еще температура меняется каждую секунду на улице и очень важно ее мониторить.

Бывает важно получить АКТУАЛЬНЫЕ данные о температуре по запросу, например через W5100, как можно быстрее, а по поводу улицы - это всего лишь Ваше, ни чем не обоснованое предположние. Возможно, мне потребуется измерить её у какого-нибудть сатирика в определенном месте с частотой 1Hz :)

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

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

rfl
Offline
Зарегистрирован: 21.10.2013

Puhlyaviy пишет:
Вы делаете мне смешно ...
- скорее, это Вы заставляете меня улыбаться :))) 

Может быть, вместо того, чтобы пытаться издеваться над другими, Вам стоит решить свои личные проблемы? :) 

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

rfl пишет:

Puhlyaviy пишет:
Вы делаете мне смешно ...
- скорее, это Вы заставляете меня улыбаться :))) 

Может быть, вместо того, чтобы пытаться издеваться над другими, Вам стоит решить свои личные проблемы? :) 

 


Давайте забирайтесь на кушетку и начинайте расказывать про мои проблемы. Весь прям внимание.

Radjah
Offline
Зарегистрирован: 06.08.2014

rfl пишет:

Строка с sensors_1.requestTemperatures() оставлена для теста, и она, кстати, еще и закомментирована. Только все сразу - как раз медленнее: 750 мс, а по одному (sensors_1.requestTemperaturesByAddress(insideThermometer) и sensors_1.requestTemperaturesByAddress(insideThermometer)) - намного быстрее: 45 мс на каждый датчик, 90 мс на 2.

Или ты где-то косячишь, или одно из двух.

Если вычисление температуры с разрадностью 12 занимает 750 мс, судя по таблице выше, то откуда возьмутся 45 мс с такой же точностью?

neospromiy
Offline
Зарегистрирован: 15.07.2013

Блин в топике один флуд, мне точноть до сотых не важна, подскажите пожалуйста всё таки ка можно уменьшить до 45мс. Важнее чтоб кнопочи работали, задержа более 1 секунды очень мешает обработке кнопок(

 

 

SunX
SunX аватар
Offline
Зарегистрирован: 04.10.2014

Я не пользовался специальной библиотекой для DS18B20, я тольк пользовался библиотекой OneWire:
http://playground.arduino.cc/Learning/OneWire

И даташитом к датчикам. По даташиту видно, что получение температуры происходит в 2,5 этапа:

* Послать команду, что нужно померять температуру.
* Подождать сколько надо (время зависит от настроек).
* Прочитать температуру.

И во время "Подождать" можно заниматься чем угодно, не обязательно делать delay(750); У меня, например, реализовано все так:

//1-wire, DS18B20 sensors
#include <OneWire.h>

//////////////////////////////////////////////////////////////////////
// **************** W1 DS18B20 Temperature sensor ***************** \\
//////////////////////////////////////////////////////////////////////
OneWire  ds(4);  // on pin 4 (a 4.7K resistor is necessary)
byte W1_addr[8];
bool W1_hasNext;
const int16_t W1_badTemp = 1360; // 85 C, looks like W1(or DS18B20) show such temperature on error.. so, we will do same

void initDS18B20() {
  //Send command to all 1-wire devices. We will think, that we have only ds18b20 sensors here.
  ds.reset();
  ds.skip();
  //To initiate a temperature measurement and A-to-D conversion, themaster must issue a Convert T [44h] command. 
  ds.write(0x44);

  //  delay(750);     // 750ms should be enought

  // Foreach sensor....
  ds.reset_search();
  W1_hasNext = true;
}

int16_t getNextDS18B20Temp() {
  byte data[9];

  //float celsius;

  if (ds.search(W1_addr)) {

    if (OneWire::crc8(W1_addr, 7) != W1_addr[7]) {
#ifdef DEBUG
      Serial.println("CRC is not valid!");
#endif
      return W1_badTemp;
    }

    //display.print(W1_addr[7], HEX); // Print las byte of sensor ID to display

    ds.reset();
    ds.select(W1_addr);
    ds.write(0xBE); // Read Scratchpad

    for (int i = 0; i < 9; i++) { // we need 9 bytes
      data[i] = ds.read();
    }

    // Convert the data to actual temperature
    // because the result is a 16 bit signed integer, it should
    // be stored to an "int16_t" type, which is always 16 bits
    // even when compiled on a 32 bit processor.
    int16_t raw = (data[1] << 8) | data[0];
    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;
    return raw;

  } 
  else {
    W1_hasNext = false;
  }
  return W1_badTemp;

}

void setup() {}

void loop() {
      // Do DS initialisation first as they need ~750ms to convert temperature
      initDS18B20();
      uint32_t dsInitMS = millis();

// Вся остальная работа

    if ((millis() - dsInitMS) < 750) delay(800 - (millis() - dsInitMS)); // +50 ms =)
      while (W1_hasNext) {
        int16_t temp = getNextDS18B20Temp();
        if (temp == W1_badTemp) continue;

        Serial.print(temp / 16.0,1);
        Serial.println("C");
      }

В итоге во время этих 750 милисекунд можно делать что угодно  + кнопкам, если они на 2 и 3 пинах можно повесить прерывания и тогда они будут обрабатываться мгновенно.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

При частом опросе  DS18xxx происходит разогрев датчиков и как следствие - ощутимое  искажение реальной температуры. Следовательно часто опращивать эти датчики нельзя. 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

rfl пишет:

.....  по DataSheet DS18B20 время получения данных - 750 мс (0,7 сек.).......

Да, но не обязательно это время сидеть в delay.....

 

neospromiy
Offline
Зарегистрирован: 15.07.2013

SunX 

спасибо выручил!

rfl
Offline
Зарегистрирован: 21.10.2013

Radjah пишет:
 Или ты где-то косячишь, или одно из двух. Если вычисление температуры с разрадностью 12 занимает 750 мс, судя по таблице выше, то откуда возьмутся 45 мс с такой же точностью? 

Не понятно только одно - где косяк? Ведь все работает как нужно...

SunX - спасибо за код, но на мой взгляд стоит поставить на функцию initDS18B20() таймер, и не крутить её все время, особенно, если информация от brokly - true:

brokly пишет:

При частом опросе  DS18xxx происходит разогрев датчиков и как следствие - ощутимое  искажение реальной температуры. Следовательно часто опращивать эти датчики нельзя. 

trembo пишет:

Да, но не обязательно это время сидеть в delay.....

Не то что бы не обязательно, а вообще функцию delay() нужно изьять из языка :) Вот при попытке избавиться от этой функции в библиотеке DallasTemperature я и обнаружил, что испольование функции requestTemperaturesByAddress() намного быстрее requestTemperatures()... Хотя в теории так быть не должно... Код в посте №6

SunX
SunX аватар
Offline
Зарегистрирован: 04.10.2014

rfl пишет:

Radjah пишет:
 Или ты где-то косячишь, или одно из двух. Если вычисление температуры с разрадностью 12 занимает 750 мс, судя по таблице выше, то откуда возьмутся 45 мс с такой же точностью? 

Не понятно только одно - где косяк? Ведь все работает как нужно...

Возможно просто температура берется с предыдущего запроса, а не с текущего

rfl пишет:

SunX - спасибо за код, но на мой взгляд стоит поставить на функцию initDS18B20() таймер, и не крутить её все время, особенно, если информация от brokly - true:

В Вашем случае - вполне возможно, просто у меня вообще этот код выполняется раз в минуту, потому проблем с нагревом нет :) Но в таком случае и потом получать с датчиков температуру нет смысла несколько раз, проще запомнить в какой-нибудь буфер. Думаю, кстати, использование таймера вообще может помочь избавиться от всех этих задержек при работе с DS18b20

rfl
Offline
Зарегистрирован: 21.10.2013

SunX пишет:

Возможно просто температура берется с предыдущего запроса, а не с текущего

Возможно... даже скорее всего, так как чудес не бывает :) Проверить пока что нет времени.

SunX пишет:

Думаю, кстати, использование таймера вообще может помочь избавиться от всех этих задержек при работе с DS18b20

К сожалению, от всех задержек при цифровых датчиках избавиться невозможно, так как всеравно требуется веремя для задержек на отправку запроса и получение результата (...0101000010...). Это, конечно, уже не 750 мс, но всеже...

Проблему с задержками для себя решил пока что так: опрашиваю цифровые датчики через интервал времени, т.е. 1-ый дачтик, через 10 сек 2-ой, через 10 сек - 3-ий и т.д. по кругу. Правда все равно, казавшеюся по началу идиличесскую картину оцифровки дома портят все эти задержки: ну ведь будет совсем не хорошо, если в момент связи с датчиком DS18B20 послать сигнал на IR-приемник, находящийся на одном микроконтроллере...

Сейчас смотрю в сторону прерываний, но как я понял при поверхностном изучении этого вопроса, проблему с задержками они не решат на 100%.

SunX
SunX аватар
Offline
Зарегистрирован: 04.10.2014

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

TovBender
Offline
Зарегистрирован: 12.04.2015

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

у меня 4 датчика ds18b20 .  делал скетч по циклу For.  не подходит потому что в это время не возможно послать команды радио розеткам. на вкл выкл.

и без For/ тоже не помогает в Loop как идет цикл опроса датчиков то не работают кнопки.

что мне делать подскажите пож.

Radjah
Offline
Зарегистрирован: 06.08.2014

Кнопки на прерывания, опрос датчиков по таймеру или через delay.

TovBender
Offline
Зарегистрирован: 12.04.2015

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

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

TovBender
Offline
Зарегистрирован: 12.04.2015
while (Serial.available() == 0); //функция Serial.аvailable() проверяет, есть ли в COM порте 

// доступные для чтения данные.

int val = Serial.read() - '0';



if (val == 1) transmit(RF1ON);   //если с COM порта поступил символ (1), начинаем отправлять через пин №11 (там радио передатчик)


if (val == 8){
  
  for (int i = 0; i < 5; i++){ // крутим цикл

ds.requestTemperatures(); // считываем температуру с датчиков


Serial.print("Temper1 ");
    Serial.print(ds.getTempC(sensor1)); // отправляем температуру
    Serial.println(" *C");
 . . .
 . . .
 . . .
}
}

 

Radjah
Offline
Зарегистрирован: 06.08.2014

Зачем 5 раз запрашивать замер?!

Запрос на замер идет на все датчики на шине.

И ты вообще читаешь, что пишу?

Кнопки на ПРЕРЫВАНИЕ!

TovBender
Offline
Зарегистрирован: 12.04.2015

это был пример .  можно и без For/ вопрос был в другом . ели начат цикл. опроса датчиков в loop / то кнопки не работают.

как это обойти ????????????????????????????????

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

и что за кнопки прирывания поподробней ?????????????????????

Radjah
Offline
Зарегистрирован: 06.08.2014

http://playground.arduino.cc/Code/Interrupts

http://robocraft.ru/blog/arduino/45.html

Ты на основы забил и просишь помощи.

TovBender
Offline
Зарегистрирован: 12.04.2015

есть ли скетч короткий будет занимать не 15 сраниц .             короткий код существует ???????

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

но можно сделать код и всего 2 строчки и 14 символов. так пишет другой програмист. кто лучший ??

Radjah
Offline
Зарегистрирован: 06.08.2014

"Ищу исполнителя" в другом разделе находится.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Radjah пишет:

Кнопки на ПРЕРЫВАНИЕ!

Radjah, А вы обратили внимание, что у него не используются кнопки? Собссно проблему мы разобрали в соседней ветке. Далласовская библа содержит в себе delay() и не даёт ничему работать, если опрос датчиков крутится  в Loop. Как решить проблему тоже разобрали.

Radjah
Offline
Зарегистрирован: 06.08.2014

Я всего кода не видел же.

Хотя если разобрали, то пусть идет на йух^W^W читать маны.

 

TovBender
Offline
Зарегистрирован: 12.04.2015

Товарищ Dimax .

1 все кнопки у меня в телефоне. который управляет Ардвиной. через блютуз. вывод данных тоже смотрю на экране телефона.       а не на дисплее приставленном к Ардвине, если успели заметить.

2 я не просил написать за меня весь код. я только начинаю разбираться в сетче. вы не видели #32 или не читали полностью.

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

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

TovBender, вы это всё мне пишите я не пойму?

TovBender
Offline
Зарегистрирован: 12.04.2015

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

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

TovBender, читайте внимательнее кто вам что пишет! И отвечайте тому, кто инициирует разговор. Я вам про кнопки, и прочее  о чём вы изливаетесь в #36 ничего не писал!

TovBender
Offline
Зарегистрирован: 12.04.2015

Radjah  я смотрю вы тут сааамый умный с интеллектом УУ.  не из Тагила ? случайно который рулит. ????

вы не читали #32 .

ссылка из друговго чата -- ( есть такие разрабы считают себя чуть ли не супер пупер разработчиками и их время стоит много денег. На деле же пользуются исходниками других. в простом вопросе не отвечают выдают стандартные КЛИШЕ, читай мат часть, и на деле ни кому помочь не могут, потомучто сами не .... )

Radjah
Offline
Зарегистрирован: 06.08.2014

Чувак, у тебя комплексы? Если да, то это к доктору.

Если хочешь, чтобы указали ошибки в коде и/или реализации, то код в студию.

Если хочешь, чтобы за тебя всё написали и спаяли, то дензнаки складывать вон в ту коробочку.

Умолять бесполезно.

Маны - гугл - форум.

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

TovBender, если бы вы взяли на себя труд сделать хоть что то с примерами и рекомендациями из вашей первой ветки, а не скулили на предмет большого кода и кнопок на любимом андроиде, вам бы помогли. Но вы даже не пытаетесь что то попробовать изменить  и забываете основной принцип - сперва отлаживаем локальные задачи, а потом их объединяем.
С таким подходом, лучше сразу в "Ищу исполнителя", там все сделают не доставляя Вам особого беспокойства.

"Рыбки я тебе не дам, а дам тебе удочку"

TovBender
Offline
Зарегистрирован: 12.04.2015

bwn - Прошу вас внимательно прочитать #32, и #36.

если у вас плохо с внимателностью ваши проблеммы. вы ооочень не внимательны.

я просил не писать за меня программу, а только указать варианты, как отменить цикл, и чтоб код был не 240 строк а поменьше, НЕ от того что писать долго, а память у АРДВИНКИ ограничена, если вы не вкурсе. Вы наверное пишете только чтоб помигать лампочкой и покрутить 1 моторчик, то да код можете писать сколь угодно большим. Если сами не можете подсказать, сами не используйте чужой код чтоб другим показать, типа вы круты.  вы не брат Puhlyaviy ? этот товарищь  всех кругом поливает грязью, и НИКОГДА не подсажет.

у меня не только датчики будут,  делать ей будет поручено много, вот и нужен код как можно меньше,

это и в работе, и на скорость тоже влияет.  Я нашёл правельный алгоритм, люди подсказали, теперь сам перенёс свою программку в этот шаблон, всё работает, о чем я просил ТУТ.

и обработка идет паралельно, с другими функциями программы.

TovBender
Offline
Зарегистрирован: 12.04.2015

Остальным Спасибо за наводки и подсказки, Dimax  и остальным, за сотрудничество. Вы помогли.

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

Прочитал я очень внимательно, сделал вывод - написать три строки состоящих из millis и if, как предложил Dimax, вам в лом.
Насчет чужого кода, то это стандартный пример из OneWire, который посмотреть вам тоже в лом.
Делайте выводы.

Ivanii
Offline
Зарегистрирован: 11.10.2015

sensors.setWaitForConversion(true); отвечает за ожидание конца преобразования в sensors.requestTemperatures();

reactor333
Offline
Зарегистрирован: 02.09.2017

SunX пишет:

И во время "Подождать" можно заниматься чем угодно, не обязательно делать delay(750); У меня, например, реализовано все так:

//1-wire, DS18B20 sensors
#include <OneWire.h>

//////////////////////////////////////////////////////////////////////
// **************** W1 DS18B20 Temperature sensor ***************** \\
//////////////////////////////////////////////////////////////////////
OneWire  ds(4);  // on pin 4 (a 4.7K resistor is necessary)
byte W1_addr[8];
bool W1_hasNext;
const int16_t W1_badTemp = 1360; // 85 C, looks like W1(or DS18B20) show such temperature on error.. so, we will do same

void initDS18B20() {
  //Send command to all 1-wire devices. We will think, that we have only ds18b20 sensors here.
  ds.reset();
  ds.skip();
  //To initiate a temperature measurement and A-to-D conversion, themaster must issue a Convert T [44h] command. 
  ds.write(0x44);

  //  delay(750);     // 750ms should be enought

  // Foreach sensor....
  ds.reset_search();
  W1_hasNext = true;
}

int16_t getNextDS18B20Temp() {
  byte data[9];

  //float celsius;

  if (ds.search(W1_addr)) {

    if (OneWire::crc8(W1_addr, 7) != W1_addr[7]) {
#ifdef DEBUG
      Serial.println("CRC is not valid!");
#endif
      return W1_badTemp;
    }

    //display.print(W1_addr[7], HEX); // Print las byte of sensor ID to display

    ds.reset();
    ds.select(W1_addr);
    ds.write(0xBE); // Read Scratchpad

    for (int i = 0; i < 9; i++) { // we need 9 bytes
      data[i] = ds.read();
    }

    // Convert the data to actual temperature
    // because the result is a 16 bit signed integer, it should
    // be stored to an "int16_t" type, which is always 16 bits
    // even when compiled on a 32 bit processor.
    int16_t raw = (data[1] << 8) | data[0];
    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;
    return raw;

  } 
  else {
    W1_hasNext = false;
  }
  return W1_badTemp;

}

void setup() {}

void loop() {
      // Do DS initialisation first as they need ~750ms to convert temperature
      initDS18B20();
      uint32_t dsInitMS = millis();

// Вся остальная работа

    if ((millis() - dsInitMS) < 750) delay(800 - (millis() - dsInitMS)); // +50 ms =)
      while (W1_hasNext) {
        int16_t temp = getNextDS18B20Temp();
        if (temp == W1_badTemp) continue;

        Serial.print(temp / 16.0,1);
        Serial.println("C");
      }

В итоге во время этих 750 милисекунд можно делать что угодно  + кнопкам, если они на 2 и 3 пинах можно повесить прерывания и тогда они будут обрабатываться мгновенно.

Делаю себе управление вентилятором в зависимости от максимальной температуры с 5 датчиков. Думал вывести показания на семисегментный дисплей на TM74HC595. Но пока выполняется этот код ничего еще не выполняется. Код ниже:

//1-wire, DS18B20 sensors
#include <OneWire.h>
#define NumberOfSensors 5//количество датчиков DS18B20
#define SerialPort 1//1 - включить вывод сообщений в COM порт
#define mosfet_pin 9   // пин мосфета
#define ds18b20_pin 10   // пин датчиков DS18B20
#define maxTemp 100  // ограничение температуры максимум(значения выше этого значения будут считаться этим значением)
#define minTemp 20  // ограничение температуры минимум(значения ниже этого значения будут считаться этим значением)
#define voltagefan 0 // Вентилятор на 12 В. Если 0, то источник питания 12 В. Если 1, то 24 В
#define maxSHMValue12V 255  // ограничение значения SHM максимум при 12 В
#define maxSHMValue24V 127  // ограничение значения SHM максимум при 24 В
#define minSHMValue 0  // ограничение значения SHM минимум
#define startSHMValue12V 95  // экспериментальное значения SHM при котором вентилятор стартует при 12 В(значения ниже этого значения будут считаться этим значением)
#define startSHMValue24V 60  // экспериментальное значения SHM при котором вентилятор стартует при 24 В(значения ниже этого значения будут считаться этим значением)
//////////////////////////////////////////////////////////////////////
// **************** W1 DS18B20 Temperature sensor ***************** \\
//////////////////////////////////////////////////////////////////////
OneWire  ds(ds18b20_pin);  // on pin ds18b20_pin (a 4.7K resistor is necessary)
byte W1_addr[8];
bool W1_hasNext;
int16_t temp[NumberOfSensors];
int16_t MAX = 0;
byte SHM;
const int16_t W1_badTemp = 1360; // 85 C, looks like W1(or DS18B20) show such temperature on error.. so, we will do same

void initDS18B20() {
  //Send command to all 1-wire devices. We will think, that we have only ds18b20 sensors here.
  ds.reset();
  ds.skip();
  //To initiate a temperature measurement and A-to-D conversion, themaster must issue a Convert T [44h] command.
  ds.write(0x44);
 
  // Foreach sensor....
  ds.reset_search();
  W1_hasNext = true;
}
 
int16_t getNextDS18B20Temp() {
  byte data[9];
 
  //float celsius;
 
  if (ds.search(W1_addr)) {
 
    if (OneWire::crc8(W1_addr, 7) != W1_addr[7]) {
      return W1_badTemp;
    }
 
    ds.reset();
    ds.select(W1_addr);
    ds.write(0xBE); // Read Scratchpad
 
    for (int i = 0; i < 9; i++) { // we need 9 bytes
      data[i] = ds.read();
    }
 
    // Convert the data to actual temperature
    // because the result is a 16 bit signed integer, it should
    // be stored to an "int16_t" type, which is always 16 bits
    // even when compiled on a 32 bit processor.
    int16_t raw = (data[1] << 8) | data[0];
    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;
    return raw; 
  }
  
  else {
    W1_hasNext = false;
  }
  return W1_badTemp; 
}

void setup() {
   #if (SerialPort)
   Serial.begin(9600);
   #endif
   TCCR1B = TCCR1B & 0b11111000 | 0x01;//31кГц ШИМ на 9 10 порт ардуино
  }

void loop() {
      // Do DS initialisation first as they need ~750ms to convert temperature
      initDS18B20();
      uint32_t dsInitMS = millis(); 
// Вся остальная работа и поиск максимума
    if ((millis() - dsInitMS) < 750) delay(800 - (millis() - dsInitMS)); // +50 ms =)
       for (int i = 0; i < NumberOfSensors; i++) {
       while (W1_hasNext) {
        temp[i] = getNextDS18B20Temp();
        if (temp[i] == W1_badTemp) continue;
        #if (SerialPort) 
        Serial.print(temp[i] / 16.0,1);
        Serial.println("C");
        #endif
        if (temp[i] > MAX) {
            MAX = temp[i];
          }        
        }      
      } 
        #if (SerialPort)
        Serial.print("MAX: ");
        Serial.print(MAX  / 16.0,1); 
        Serial.println("C");
        #endif
//---------------------------------------------------------------------
        MAX = constrain(MAX, (minTemp * 16.0), (maxTemp * 16.0) );//ограничение температур от minTemp до maxTemp
        #if (voltagefan)
        SHM = map(MAX, (minTemp * 16.0), (maxTemp * 16.0), minSHMValue, maxSHMValue24V);//Функция пропорционального переноса значений
        SHM = constrain(SHM, startSHMValue24V, maxSHMValue24V);//ограничение SHM от startSHMValue до maxSHMValue   
        #else
        SHM = map(MAX, (minTemp * 16.0), (maxTemp * 16.0), minSHMValue, maxSHMValue12V);//Функция пропорционального переноса значений
        SHM = constrain(SHM, startSHMValue12V, maxSHMValue12V);//ограничение SHM от startSHMValue до maxSHMValue    
        #endif
        analogWrite(mosfet_pin, SHM);          // подача ШИМ на пин мосфета
//-----------вывод значения шим для дебага-----------------------------
        #if (SerialPort)       
        Serial.print("SHM: ");
        Serial.println(SHM); 
        Serial.println("");
        #endif   
//-------------------------------------------------------------  
        MAX = 0;// присвоение переменной 0, чтобы максимум не запоминался 
}

Думаю для начала что-нибудь полегче взять. Мне не понятно, как правильно совместить этот код, например, со скетчем из примеров Blink without delay?

inspiritus
Offline
Зарегистрирован: 17.12.2012

Ну не нравится мне миллис!

а нравится мне библиотека SimpleTimer , с ее помощью организую псевдопроцесс, вызваемый раз в 1-5-10 секунд, где опрашиваю 18в20 и после опроса запускаю следующее определение температуры. Когда прихожу через означенное время , новая температура уже созрела.

в остальное время можно другим псевдопроцессом выводить на экран, третьим опрашивать кнопки....

b707
Offline
Зарегистрирован: 26.05.2017

опять некропостинг....

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

b707 пишет:

опять некропостинг....

Здесь хоть ожидаемо, очень давно уже адвентисты 750-ой миллисекунды не забредали, с год-два назад прямо косяком перли. Скоро наверно секта 50-го дня миллиса подтянется.)))
А читать все равно не желают.((((