Неверное считывание данных.

memfise
Offline
Зарегистрирован: 30.06.2012

Итак имеются 6 DS18B20, подключенных по трем проводам, а так же 3 DHT11. Все вроде бы работает, но проблема в том, через некоторое время все датчики разом показывают не то, что неверную температуру и влажность, так вообще непонятно что. Это мой первый опыт с ардуиной, так что прошу на понимание. Вот непосредственно сам код.

/**/
#include "DHT.h" //библиотека для работы с датчиками влажности и температуры DHT11
#define DHTTYPE DHT11   //DHT 11
#define DHT_1_PIN 2 //датчик DHT11 подключен ко 2 pin arduino
#define DHT_2_PIN 3 //датчик DHT11 подключен ко 3 pin arduino
#define DHT_3_PIN 4 //датчик DHT11 подключен ко 4 pin arduino

#define bath_pir_Pin 15 //датчик движения на 15 pin (аналоговый пин)
#define test_pir_Pin 16
#define fire_pir_Pin 17

#include <OneWire.h> //библиотека для работы по шине OneWire
#include <DallasTemperature.h> //библиотека для работы с датчиками температуры DS18B20
#define ONE_WIRE_BUS 10 //шина ONE_WIRE_BUS установлена на 10 pin arduino

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;
int number_device;
float Ctemp_DS = 0.00; // значение температуры поумолчанию 0 градусов
float T_maxi = 60.00;
float T_mini = -60.00;

int led_pin = 13; // определили pin 13 для светодиода
int led_status = 0; //ствтус светодиода
//переменные для реле
int relepin = 7; //пин для релюхи канал 1
//int relepin = 8; //пин для релюхи канал 2
//int PhotoSensorPin   = 0;            // устанавливаем входную ногу для АЦП
//unsigned int PhotoResistorValue  = 0;  // цифровое значение фоторезистора

//здесь рпределим все адреса датчиков
//byte addr[8];
//все адреса наших датчиков DS18B20 запишем в массивым переменных
char DS1[8] = {
  '28', 'F4', '4B', 'C4', '3', '0', '0', 'FA'}; //первый датчик DS18B20
char DS2[8] = { 
  '28', '7B', '5B', 'C4', '3', '0', '0', '48'}; //второй датчик DS18B20
char DS3[8] = {
  '28', '47', 'F1', 'D5', '3', '0', '0', 'E1'}; //третий датчик DS18B20
char DS4[8] = {
  '28', '32', 'D4', 'D5', '3', '0', '0', 'B8'}; //четвертый датчик DS18B20
char DS5[8] = {
  '28', 'E1', 'CE', 'D5', '3', '0', '0', 'E4'}; //пятый датчик DS18B20
char DS6[8] = {
  '28', 'B9', 'D3', 'D5', '3', '0', '0', 'FB'}; //шестой датчик DS18B20

int incomingByte = 0;   // для входящей информации изначально устанавливаем 0

long previousMillis = 0;        // храним время последнего переключения светодиода
long interval = 500;           // интервал между запросами информации с датчиков (0.5 минут)
// интервал подбирается в зависимости от применения датчиков. Если планируется просто мониторить уличную температуру, то, думаю не им
//нет смысла ставить интервал меньше 5 минут
// вопрос с интервалом запросов приведен для ускорения вывода информации в порт
DHT dht_1(DHT_1_PIN, DHTTYPE); //датчик на 2 пине
DHT dht_2(DHT_2_PIN, DHTTYPE); //датчик на 3 пине
DHT dht_3(DHT_3_PIN, DHTTYPE); //датчик на 4 пине

void setup (void) {
  Serial.begin  (9600);
  Serial.flush();
  pinMode(9, OUTPUT);	// устанавливаем 9 ногу как выход 
  pinMode(led_pin, OUTPUT); // устанавливаем 13 ногу как выход
  pinMode(bath_pir_Pin, INPUT); //установили bath_pir_Pin на выход значений
  digitalWrite(bath_pir_Pin, LOW); //по умолчанию датчик не активен
  pinMode(relepin, OUTPUT);
  sensors.begin();
  sensors.setResolution(TEMP_12_BIT); //устанавливаем разрешение 12 бит
  sensors.setWaitForConversion(true);
  dht_1.begin();
  dht_2.begin();
  dht_3.begin();  //Serial.println(sensors.getDeviceCount(), DEC); //посчитали количество датчиков на шине
  delay(1000);
}

void loop (void) {
  // посылаем запрос только после появления информации на порту
  if (Serial.available() > 0 ){
    number_device = sensors.getDeviceCount(); // посчитаем количество датчиков на шине OneWire
    /*unsigned long currentMillis = millis(); 
     if(currentMillis - previousMillis > interval) { //если время от последнего запроса превышает интервал то выполняем следующий запрос
     previousMillis = currentMillis; //сохраняем время последнего запроса
     }*/
    // считаем значение с com порта, для определения с какого датчика температуры выводить температуру
    incomingByte = Serial.read(); //читаем данные порта 
    if (incomingByte > 48){ //На случай проверки в терминалах нужно уменьшать на 48, тк дальнейший скрипт принимает только 1 или 2, а с терминала приходит ascii
      //beep (50);
      //последовательность
      incomingByte = incomingByte - 48;
    }
    if (incomingByte == 1) {
      sensors.requestTemperatures(); //опрашиваем градусники
      for (int colDS = 0; colDS <= number_device - 1; colDS++){ //пробегаем по всем температурным датчикам

        /*if (sensors.getAddress(tempDeviceAddress, colDS)){
         //вывод адреса датчика
         printAddress(tempDeviceAddress);
         Serial.println (" ");
         //  bool requestTemperaturesByAddress(uint8_t*);*/
        GetTempDS18X20(colDS); //функция запрашивает и выводит температуру
        //Serial.println (Ctemp_DS);
        //}
      }   
      GetTempDHT11();
      //Serial.println (number_device);
      /*здесь будет обработчик для вентилятора, датчика температуры и влажности, 
       а так же реле, находящихся в ванной комнатах
       если нашли движение, необходимо переключить реле и дать напряжение для включения света, а так же включить вентилятор*/
      boolean bath_fan_status = 0; //статус вентилятора в ванной - выключен
      boolean bath_pir_status = 0; //статус датчика движения в ванной - выключен
      boolean bath_light_status = 0; //статус света в ванной - выключен
      boolean bath_rozetka_status = 0; //статус розетки в ванной - выключен
      float DHT1_humiditi = dht_1.readHumidity(); //влажность с DHT11

      if (DHT1_humiditi > 29) { //проверим значение влажности для включения или отключения вентилятора
        //Serial.println("ventiliator - start");
        bath_fan_status  = 1; //необходимо включить вентилятор в ванной комнате
      }

      int bath_pir_motion = analogRead(bath_pir_Pin); //считаем значения датчика движения
      if ((bath_pir_motion >= 600) || (bath_fan_status = 1)){ //если движение есть и если bath_fan_status = 1
        digitalWrite(led_pin, HIGH); // включаем светодиод
        bath_pir_status = 1; //установим статус pir
        //beep(200); // будет пищать короткими гудками
        //Serial.println ("Motion Detected");
        //Serial.print (" ");
        //Serial.println(bath_pir_motion);
        //вентилятор и свет должны работать
        bath_light_status = 1;
        //bath_rozetka_status = 1;
      }
      else {
        digitalWrite(led_pin,LOW);
        bath_light_status = 0;
      }
    }
  }
  int test_pir_motion = analogRead(test_pir_Pin); //считаем значения датчика движения
  if (test_pir_motion >= 600) { //если движение есть и если bath_fan_status = 1
    //digitalWrite(relepin, HIGH);
    digitalWrite(led_pin, HIGH); // включаем светодиод
    //beep (50);
  } 
  else {
    //digitalWrite(relepin, LOW);
    digitalWrite(led_pin, LOW); // включаем светодиод
  }
  //fire_alarm();
  Serial.flush(); //очистим порт на всякий
}

//---------------------ФУНКЦИИ-------------------------------//
//функция считывания значения с датчика огня
void fire_alarm(){
  int fire_state = analogRead(fire_pir_Pin);
  //Serial.println (fire_state);
  //if (fire_state <= 1000)  //если значения датчика огня уменьшились
  //Serial.println ("D-A-N-G-E-R");
}


//функция оповещения звуком срабатывания датчика движения
void beep(unsigned char delayms){
  analogWrite(9, 20);      // значение должно находится между 0 и 255
  // поэкспериментируйте для получения хорошего тона
  delay(delayms);          // пауза delayms мс
  analogWrite(9, 0);       // 0 - выключаем пьезо
  delay(delayms);          // пауза delayms мс   
}

void GetTempDHT11()//Читаем температуру с градусника
{
  //считаем значения температуры и влажности с датчиков DHT11
  float DHT1_temp = dht_1.readTemperature(); //влажность с DHT11
  //надо придумать проверку от левых значений
  if (DHT1_temp == 0.00){
    delay(500);
    DHT1_temp = dht_1.readTemperature();
    beep(200);
  }

  float DHT1_humiditi = dht_1.readHumidity(); //температура с DHT11
  if (DHT1_humiditi == 0.00){
    delay(500);
    DHT1_humiditi = dht_1.readHumidity();
    beep(200);
  }

  float DHT2_temp = dht_2.readTemperature(); //влажность с DHT11
  if (DHT2_temp == 0.00){
    delay(500);
    DHT2_temp = dht_2.readTemperature();
    beep(200);
  }
  float DHT2_humiditi = dht_2.readHumidity(); //температура с DHT11
  if (DHT2_humiditi == 0.00){
    delay(500);
    beep(200);
  }
  float DHT3_temp = dht_3.readTemperature() /*+ 1.00*/; //влажность с DHT11
  if (DHT3_temp == 0.00){
    DHT3_temp = dht_3.readTemperature();
    delay(500);
    beep(200);
  }
  float DHT3_humiditi = dht_3.readHumidity() /*+ 2.00*/; //температура с DHT11 
  if (DHT3_humiditi == 0.00){
    DHT3_humiditi = dht_3.readHumidity();
    delay(500);
    beep(200);
  }
  Serial.print(DHT1_temp); //выведем показания температуры с DHT11
  Serial.print(" ");        
  Serial.print(DHT1_humiditi); //выведем показания влажности с DHT11
  Serial.println(" ");
  Serial.print(DHT2_temp); //выведем показания температуры с DHT11
  Serial.print(" ");        
  Serial.print(DHT2_humiditi); //выведем показания влажности с DHT11
  Serial.println(" ");
  Serial.print(DHT3_temp); //выведем показания температуры с DHT11
  Serial.print(" ");        
  Serial.print(DHT3_humiditi); //выведем показания влажности с DHT11
  Serial.println(" ");
}

void GetTempDS18X20(int id_DS)//Читаем температуру с градусника
{

  float temp = sensors.getTempCByIndex(id_DS);
  int i = 0;
  //градусник может быть не один
  while (temp == 85.00 || temp == -127.00 || temp == 0.00 && 
    i <= 20){
    sensors.requestTemperatures();
    temp = sensors.getTempCByIndex(id_DS); //запрос температуры по индексу
    i++;
  }
  Ctemp_DS = temp; //присваиваем температуру
  Serial.println(Ctemp_DS);
}


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



 

memfise
Offline
Зарегистрирован: 30.06.2012

Немного поясню по коду...дуина подключена к компу на котором крутиться mysql, с него периодически происходит запрос к дуине (в виде отправки единици в serial). Дуину в свою очередь при приеме этого значения опрашивает датчики температуры и влажности и отсылает компьютеру через порт, который все это пишет в базу. В общем температура пишется нормально, но не всегда, например бывает так ".00 3" "225" "625" "02" - в кавычка сами неверные значения.  Представленный код выше, конечно, не идеален и содержит много мусора, т.к. работа в самом разгаре :)

 

leshak
Offline
Зарегистрирован: 29.09.2011

 

memfise пишет:

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

Ну вот и начните с его уборки :) А то вглядыватся в мусор что-бы понять "что не так" - тяжело. Очень вероятность что на "красивом коде" и сами увидите проблему. Держать код "идельным" обычно для того и требуют. Не что-бы пощекотать свой перфекционизм, а что-бы работать с ним было проще. Сопровождать, находить ошибки и т.п.
Как минимум нужно убрать кучу дублирующегося кода. У вас же работа со всеми датчиками идентичная. Зачем ее повторять? Сделайте цикл. Тогда любые правки будут относится сразу ко всем трем датчикам.
Выведите в Serial, не только данные датчиков, но и название/номер датчика. Тогда будет проще понять "кто врет", в какой кусок кода нужно вглядываться "повнимательней".
На форум, имело смысл дать не только "ошибочные данные", но и "верные". Что-бы сравнить что вы ожидаете с тем что получаете. Иначе как догадатся "а как же правильно?". Только по коду, а в его "правильности" - сомнения.
Вставлять "примеры данных", тоже лучше не "руками набирать", а копипастать прямо из сериал монтора и вставлять сюда так же как код.
Теперь по поводу "того что видно": "на вскидку" видятся два момента к которым стоит приглядется:

1. Если с датчика получены не верные данные, то выполняете еще 20-ть попыток его прочитать (temp == 85.00 || temp == -127.00 || temp == 0.00). Но... а что произойдет если данные так и не будут прочитаны и за 20-ть попыток? А все равно выведутся. IMHO, лучше бы выводить "а не получилось прочитать" (а еще лучше, добавить в лог-что топа "датчкик номер XXX, попытка повторного чтения номер NNN", тогда будете видеть насколько часто такое случается).

2. Возможно нужно делать паузу между попытками читать данные. 

3. Для DS18B20 вы какую-никакую проверку удачности чтения делаете (и повторяете в случае неудачи), а для DHT11 - нет. Возможно стоит это сделать.

memfise
Offline
Зарегистрирован: 30.06.2012

->Как минимум нужно убрать кучу дублирующегося кода.

какие действия вы имеете ввиду?

->У вас же работа со всеми датчиками идентичная. Зачем ее повторять? Сделайте цикл. Тогда любые правки будут относится сразу ко всем трем датчикам.

для датчиков постарался написать некие функции для обработки их значений, но при проверке DHT11 аналогично  DS18B20 (типа

DHT1_temp = dht_1.readTemperature();
  while (DHT1_temp =0.00){
  delay(500);
  DHT1_temp = dht_1.readTemperature();
}

ошибки начинают валиться сразу же...с if такого нет

->На форум, имело смысл дать не только "ошибочные данные", но и "верные". Что-бы сравнить что вы ожидаете с тем что получаете. Иначе как догадатся "а как же правильно?". Только по коду, а в его "правильности" - сомнения.

25.69
25.81
25.75
25.62
25.75
25.62
26.00 31.00 
26.00 31.00 
26.00 29.00

вот те самые правильные данные (температура с DS, далее температура и влажность с DHT)

26.
28.0
25.
26.
26.
26.
26. 025
25. 0 30
29.0 00 29

вот неправильные

 самое интересное в том, что когда через сериал монитор пробую отправить 1 дуине, в ответ все нормально (температура и влажность), а когда циклом через каждые 15 секунд начинается разнобой, опять же периодически

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 >какие действия вы имеете ввиду?

Ну вот то что и написал ниже, дублирование работы с dht_N? чем логика работы с dht_1 отличается от логики dht_2. В чем отлчие, например строк 174-187 от 182-194. Только в имени переменной. Почему не сделать массив dht[i] и не пробегать по нему? 

Попробуйте убрать Serial.flush();

>а когда циклом через каждые 15 секунд начинается разнобой

А где этот цикл? Не вижу его в коде.

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

Еще бы схему подключения неплохо показать. Вдруг там "что-то нет так". На пины D0,D1 ничего не привесили? Ну и "традиционно": меряли вольтметром что у вас на 5v пине? Просадок напряжения нет? На шину подтягивающие резисторы не забыли привесить? А если не забыли, то не нависели-ли лишних? У вас по одному резистору на линию или не пожадничали и для каждого датчика свой резистор примонстрячили?

правильно - только один нужен

memfise
Offline
Зарегистрирован: 30.06.2012

 >Ну вот то что и написал ниже, дублирование работы с dht_N? чем логика работы с dht_1 отличается от логики dht_2. В чем отлчие, например строк 174-187 от 182-194. Только в имени переменной. Почему не сделать массив dht[i] и не пробегать по нему?

c этим полностью согласен, данный кусок кода мне самому не нравиться. Пытался записать (не очень еще шарю)

char* dht[3] = {  
  "dht1", "dht2", "dht3"};

 

float DHTtemp = 0.00;
  for (int d = 0; d <= 2; d++){ 
    char* strind = dht[d];
    DHTtemp = strind.readTemperature(); 

ошибка error: request for member 'readTemperature' in 'strind', which is of non-class type 'char*'

>раз вы ищите причину проблемы - заведите отдельный скетч

так и делал, куски кода и датчики отключал, переставлял местам - пока никак не работает

>Еще бы схему подключения неплохо показать.

нарисовать не смогу, под рукой пока ничего нет....так на пальцах:

1. все DS18B20  1 нога к земле, м/у 2 и 3  R на 4.7К, вторая нога на 10 пин, третья на +5v. Все остальные параллельно (если можно  так сказать).

2. DHT11 занмают со 2 по 4 цифровые пины подключены к первым , м/у 1 и 2 ногами датчика R 10К, вторая нога +5, третьья - земля

>А где этот цикл? Не вижу его в коде.

цикл я осуществляю запуском внешнего файла, который инициирует отправку данных в ком порт ардуино (время задается произвольное)

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

 

leshak
Offline
Зарегистрирован: 29.09.2011

 

>ошибка error: request for member 'readTemperature' in 'strind',

Воспользуйтесь поиском вверху сайта - пару недель назад была тема про массивы строк. Ну или гуглом поищите про массивы сишных строк.

Только я как-то совсем не понял, зачем вам тут строки? Ну предположим вы объяввите "массив строк". Вы же потом пытаетесь у строки вызвать метод readTemperature()? Откуда он у строки возмется? В оригинальном же скетче переменная dht_1 имеет тип DHT. Ну значит и массив у вас должен быть "массивом объектов DHT": DHT dht[3];

>так и делал, куски кода и датчики отключал

Ну вот и сюда-бы показали "минимально не работающие". Чем сильнее вы сузите круг поиска тем скорее что-нибудь заметим. Чем больше "левого кода" - тем все сложней (большинство даже просто обламаются вникать. одно дело на 10-ть строк взгялнуть, другое - эмулировать в голове 150).

>нарисовать не смогу, под рукой пока ничего нет

А нагуглить, что-нибудь? Это вообще кому нужно? Я-то, на самом деле и без схемы проживу :) Ну вот, хотя-бы, навскидку. Поставить - дело 2-х минут http://fritzing.org/  (возможно что-то и лучше есть, просто что 5 сек нашлось).

Или вы считаете что лучше мне сейчас начать смотреть даташиты, выяснять какая нога что значит....

Вообщем другие же как-то рисуют.

да и по вашему поисанию не ясно. Вот, например, пишите "R на 4.7К". Но DS18B20 - у вас 6-ть штук. А резиторов на 4.7K сколько штук у вас? Вы так и не ответили. "Одна штука" или тоже 6-ть штук?

>а вольтметра у меня нет, просадку шины не проверял

А вот это мне уже не понять никак. Ладно я понимаю отсуствие логического анализатора или осцилографа - денег стоят. Но заниматся электроникой без тестера? Силой мысли определять проблемы в железе?

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 И еще, маленький коммент. Крутится по массивам можно и так как вы делаете "for (int d = 0; d <= 2; d++)"

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

for (int d = 0; d < 3; d++)

Было-бы, IMHO наглядней, да и  

 for (int colDS = 0; colDS < number_device ; colDS++)

лучше смотрится чем

 for (int colDS = 0; colDS <= number_device - 1; colDS++)

 

memfise
Offline
Зарегистрирован: 30.06.2012

постарался максимально отбросить все лишнее 

#include "DHT.h" 
#define DHTTYPE DHT11   //DHT 11
#define DHT_1_PIN 2 
#define DHT_2_PIN 3 
#define DHT_3_PIN 4 

#include <OneWire.h> 
#include <DallasTemperature.h> 
#define ONE_WIRE_BUS 10 

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempDeviceAddress;

int number_device;
float Ctemp_DS = 0.00; 
int incomingByte = 0;   

DHT dht1(DHT_1_PIN, DHTTYPE); 
DHT dht2(DHT_2_PIN, DHTTYPE); 
DHT dht3(DHT_3_PIN, DHTTYPE); 

byte d[] = { 
  'DHT dht1', 
  'DHT dht2', 'DHT dht3'};

void setup (void) {
  Serial.begin  (9600);
  pinMode(9, OUTPUT);	 
  sensors.begin();
  sensors.setResolution(TEMP_12_BIT); 
  sensors.setWaitForConversion(true);
  dht1.begin();
  dht2.begin();
  dht3.begin();  
}

void loop (void) {
  if (Serial.available() > 0 ){
    number_device = sensors.getDeviceCount(); 
    incomingByte = Serial.read(); 
    if (incomingByte > 48){ 
      incomingByte = incomingByte - 48;
    }
    if (incomingByte == 1) {
      GetTempAll(); 
    }
  }
}
void GetTempAll()
{
  float temp = 0.00;
  int i = 0;
   sensors.requestTemperatures(); //опрашиваем градусники
  for (int colDS = 0; colDS <= number_device - 1; colDS++){ 
    while (temp == 85.00 || temp == -127.00 || temp == 0.00 && 
      i <= 100){
      delay(750);  
      sensors.requestTemperatures();
      i++;
    }
    Ctemp_DS = sensors.getTempCByIndex(colDS);
    Serial.println (Ctemp_DS);
  }
  //float DHTtemp = 0.00;
  for (int j = 0; j <= 2; j++){ 
    float  DHTtemp = d[j].readTemperature();
    Serial.println (DHTtemp);
  }
  float DHT1_temp = dht1.readTemperature(); 
  float DHT1_humiditi = dht1.readHumidity(); 
  float DHT2_temp = dht2.readTemperature(); 
  float DHT2_humiditi = dht2.readHumidity(); 
  float DHT3_temp = dht3.readTemperature() ; 
  float DHT3_humiditi = dht3.readHumidity() ; 
  Serial.print(DHT1_temp); 
  Serial.print(" ");        
  Serial.print(DHT1_humiditi); 
  Serial.println(" ");
  Serial.print(DHT2_temp); 
  Serial.print(" ");        
  Serial.print(DHT2_humiditi); 
  Serial.println(" ");
  Serial.print(DHT3_temp); 
  Serial.print(" ");        
  Serial.print(DHT3_humiditi); 
  Serial.println(" ");
}







 

memfise
Offline
Зарегистрирован: 30.06.2012

  с массивом пока не не ясно..изучаю...так что там еще не правильно.

Резистор на шине один, вольтметр отремонтировал, проверил - показывает 5.02..5.03 - в общем вроде просадок нет

картинку (схему нарисовал нет пока возможности вставить)
 

 получилось...ну вот как то так

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Так. Первое. Давайте разделим мухи и котлеты. Мухами у нас будут DS1820, а котлетами DHT11.

Вначале разберемся с мухами. Отключаем-убираем DHT11 (и с платы и из скетча).  Когда добъемся "четкой работы" DS1820 - отдельно разберемся с DHT11, а уж потом "все вместе".

"Из нарисованного" - правильно подключен только первый (самый левый) DS. У остальных, почему-то, закорочены вторая и третяя нога. То есть питание они берут прямо с линии. Да еще "всей толпой" :(  Уберите эту перемычку и запитайте их от 5v. Вообщем все подключены должны быть как первый. За исключением  резистора 4.7K, он, действительно нужен только на пером.

leshak
Offline
Зарегистрирован: 29.09.2011

 Вообщем как-то такЖ

P.S. Обратите внимение что на вашей и моей схеме шины питание и земли - поменяны местами. У меня земля - нижняя. Это не принципиально, просто "так нарисовалось".

P.S.S А в вашей схеме вы вообще землю и питание замкнули. В левом нижнем угла макетки (я понимаю что это просто "огрехи рисования")

memfise
Offline
Зарегистрирован: 30.06.2012

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

void loop (void) {
  if (Serial.available() > 0 ){
    number_device = sensors.getDeviceCount(); 
    incomingByte = Serial.read(); 
    if (incomingByte > 48){ 
      incomingByte = incomingByte - 48;
    }
    if (incomingByte == 1) {
      GetTempAll(); 
    }
  }
}
void GetTempAll()
{
  float temp = 0.00;
  int i = 0;
   sensors.requestTemperatures(); 
  for (int colDS = 0; colDS <= number_device - 1; colDS++){ 
    while (temp == 85.00 || temp == -127.00 || temp == 0.00 && 
      i <= 100){
      delay(750);  
      sensors.requestTemperatures();
      i++;
    }
    Ctemp_DS = sensors.getTempCByIndex(colDS);
    Serial.println (Ctemp_DS);
  }
}

вот код для DS ок, проверяю на анличие ошибок

leshak
Offline
Зарегистрирован: 29.09.2011

 >согласен у меня немного перепутано, схемы под рукой не было рисовал из головы

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

По коду: а setup() куда потерялось? Даже если он пустой - лучше его показывать. Во первых сразу отсекаются вопросы "а может что-то в setup не так?", во вторых можно ваш код скопипастить и скомпилить.... а так его еще "подправлять нужно". То же самое относится к инклудам. Не видно какие библиотеки вы используете. Каким типом объявлена incomingByte и т.п. Если не хочется "Раздвувать ветку" - можете делать для кода "свернуть" (вторая владка когда добавляете)

Далее строки 05-07 - лишние. Это не обязательно делать (если только вы не собиралсь сделать поддержку одновременно и бинарного и текстового протокола). Вполне можно в сразу делать incomingByte = Serial.read()-48;

Далее. Строки 18-24 - а что вы тут делаете? Вы же крутите цикл "вхолостую".

Смотрите что вы делаете: 

  1. Обнулили temp
  2. Начали крутить цикл while пока temp==0
  3. Внутри цикла делаете requestTemperatures, но.... temp-то вы не обновляете.

То есть вы в любом случае прокрутите его, зачем-то 100 раз заставляя датчики мерять температуру но не пользуетесь этими данными. temp у вас вообще, всегда, будет равень нулю.

Кстати для теста можно не сочинять свой код, а взять пример из библиотеки. С библиотекой DallasTemperatureControl идет пример, например, Multiple. Можно его пустить что-бы убедится "датчики работают нормально".

И еще. На работоспособность не влияет, но я бы не рекомендовал, особенно с такой тучей датчиков, пользовать getTempCByIndex(). Загляните в ее реализцию. Каждый ее вызов, приводит к повторному поиску всех устройст на шине, выяснения их адреса и т.п. и все-только что-бы понять "кто же у нас по таким индексом висит". Я бы пользовался getTempC, выяснив адреса устройств в setup один раз (в примере Multiple видно как это делать), а потом спрашивал бы датчик уже по адресу.

 

 

 

memfise
Offline
Зарегистрирован: 30.06.2012

 >а setup() куда потерялось?

да, конечно. вот он

void setup (void) {
  Serial.begin  (9600);
  pinMode(9, OUTPUT);	// устанавливаем 9 ногу как выход 
  sensors.begin();
  sensors.setResolution(TEMP_12_BIT); //устанавливаем разрешение 12 бит
  sensors.setWaitForConversion(true);
  dht1.begin();
  dht2.begin();
  dht3.begin();  
}

 вот так пока работает, и ни одного сбоя..пока (тьфу-тьфу)

     sensors.requestTemperatures(); //опрашиваем градусники
  ///////цикл по DS18X20 /////////
  for (int colDS = 0; colDS <= number_device - 1; colDS++){ //пробегаем по всем температурным датчикам
    Ctemp_DS = sensors.getTempCByIndex(colDS);//присваиваем температуру переменной
    //проверка значений температуры
    while (temp == 85.00 || temp == -127.00 || temp == 0.00 && 
      i <= 100){
      delay(750);  
      sensors.requestTemperatures();
      temp = sensors.getTempCByIndex(colDS);
      Ctemp_DS = temp;
      i++;
    }
    Serial.println (Ctemp_DS);
  }




>я бы не рекомендовал, особенно с такой тучей датчиков, пользовать getTempCByIndex()

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

leshak
Offline
Зарегистрирован: 29.09.2011

 >да, конечно. вот он

А остальное? объявление переменных, подключение библиотек? Вот могу я взять ваш пример целиком вставить к себе и скомпилировать? Или нужно "по кусочкам" из кучи постов собирать?

Дайте скетч целиком. Вам же самому меньше работы ctrl-a, ctrl-c, ctrl-v и все :), чем "выбирать кусочки" и вставлять кучу раз.

И еще "ошметки" dht в setup затесались. Давайте все-таки, добъемся "идеала и чистоты" от DS. В чисто отельном скетче.

>вот так пока работает

Ну и хорошо. Давайте скетч, попробуем его "отполировать" (что-бы и красивы выглядело и потом "стыковать" с другими частями проще было, и понимать "что происходит").

memfise
Offline
Зарегистрирован: 30.06.2012

 

#include "DHT.h" //библиотека для работы с датчиками влажности и температуры 

#define DHTTYPE DHT11   //DHT 11
#define DHTPIN2 2 //датчик DHT11 подключен ко 2 pin arduino
#define DHTPIN3 3 //датчик DHT11 подключен ко 3 pin arduino
#define DHTPIN4 4 //датчик DHT11 подключен ко 4 pin arduino

#include <OneWire.h> //библиотека для работы по шине OneWire
#include <DallasTemperature.h> //библиотека для работы с датчиками температуры DS18B20
#define ONE_WIRE_BUS 10 //шина ONE_WIRE_BUS установлена на 10 pin arduino

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

int number_device;
float Ctemp_DS = 0.00; // значение температуры поумолчанию 0 градусов
int incomingByte = 0;   // для входящей информации изначально устанавливаем 0

DHT dht1(DHTPIN2, DHTTYPE); //датчик на 2 пине
DHT dht2(DHTPIN3, DHTTYPE); //датчик на 3 пине
DHT dht3(DHTPIN4, DHTTYPE); //датчик на 4 пине
//DHT d[] = {'DHT dht1', 'DHT dht2', 'DHT dht3'}; 


void setup (void) {
  Serial.begin  (9600);
  pinMode(9, OUTPUT);	// устанавливаем 9 ногу как выход 
  sensors.begin();
  sensors.setResolution(TEMP_12_BIT); //устанавливаем разрешение 12 бит
  sensors.setWaitForConversion(true);
  dht1.begin();
  dht2.begin();
  dht3.begin();  //Serial.println(sensors.getDeviceCount(), DEC); //посчитали количество датчиков на шине
}

void loop (void) {
  // посылаем запрос только после появления информации на порту
  if (Serial.available() > 0 ){
    number_device = sensors.getDeviceCount(); // посчитаем количество датчиков на шине OneWire
    incomingByte = Serial.read()-48; //читаем данные порта 

    if (incomingByte == 1) {
      GetTempAll(); //здесь будем запрашивать всю температуру
    }
  }
}
//функция запроса температуры со всех датчиков температуры
void GetTempAll()
{
  float temp = 0.00;
  int i = 0;
  //сначала запросим температуру с DS18X20 
  sensors.requestTemperatures(); //опрашиваем градусники
  ///////цикл по DS18X20 /////////
  for (int colDS = 0; colDS <= number_device - 1; colDS++){ //пробегаем по всем температурным датчикам
    Ctemp_DS = sensors.getTempCByIndex(colDS);//присваиваем температуру переменной
    //проверка значений температуры
    while (temp == 85.00 || temp == -127.00 || temp == 0.00 && 
      i <= 100){
      delay(750);  
      sensors.requestTemperatures();
      temp = sensors.getTempCByIndex(colDS);
      Ctemp_DS = temp;
      i++;
    }
    Serial.println (Ctemp_DS);
  }
  // //затем с DHT11
  ///////цикл по DHT11 /////////
  /*char  Ctemp_DHT = 0.00;
   for (int j = 0; j <= 2; j++){ //пробегаем по всем температурным датчикам
   Serial.println (d[j].readTemperature());
   Serial.println (Ctemp_DHT);
   
   }
   
   //надо придумать проверку от левых значений
   //считаем значения температуры и влажности с датчиков 
}







 

memfise
Offline
Зарегистрирован: 30.06.2012

 вот

leshak
Offline
Зарегистрирован: 29.09.2011

memfise пишет:

 вот

А DHT так и оставили :(  Ладно, вычищу сам ;)

memfise
Offline
Зарегистрирован: 30.06.2012

 пытался с массивами заставить работать еще в процессе

leshak
Offline
Зарегистрирован: 29.09.2011

 Вот попробуйте. Компилируется, но железа для проверки нет под рукой (все-таки тоже человек, мог и очепятнутся).

#include <OneWire.h> //библиотека для работы по шине OneWire
#include <DallasTemperature.h> //библиотека для работы с датчиками температуры DS18B20
#define ONE_WIRE_BUS 10 //шина ONE_WIRE_BUS установлена на 10 pin arduino



#define SERIAL_SPEED 9600 // скорость com-порта
#define MAX_ATTEMPTS 100  // максимальное количество повторных попытк если датчик не удается прочитать
#define ATTEMPTS_DELAY 750 // задержка между попытками

#define INVALID_CTEMP (Ctemp_DS == 85.00 || Ctemp_DS == -127.00 || Ctemp_DS == 0.00)  // условие "неправильной температуры"

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

int number_device;
float Ctemp_DS = 0.00; // значение температуры поумолчанию 0 градусов
int incomingByte = 0;   // для входящей информации изначально устанавливаем 0




void setup (void) {
  Serial.begin(SERIAL_SPEED);

  ds_init(); // инициализируем ds1820 датчики
}

void loop (void) {
  readSerialCommands(); // читаем и выполняем комманды из Serial порта
}

void readSerialCommands(){
    // посылаем запрос только после появления информации на порту
  if (Serial.available() > 0 ){
   
    incomingByte = Serial.read()-48; //читаем данные порта, сразу переводим "в цифру"

    switch(incomingByte){ //выясняем что это за команда
      case 1:
            ds_print_all(); //здесь будем запрашивать всю температуру
            break;
      case 2: 
             //а тут место для будущей команды чтения DHT
             break;
             
      default: Serial.println("Unknown command");
    }

  }
}


/* --------------------------- DS1820 region START ---------------------------  */

// инициализация датчиков DS1820
void ds_init(){
  sensors.begin();
  sensors.setResolution(TEMP_12_BIT); //устанавливаем разрешение 12 бит
  sensors.setWaitForConversion(true);
}


//функция запроса температуры со всех датчиков температуры
void ds_print_all() // бывшая GetTempAll
{
   number_device = sensors.getDeviceCount(); // посчитаем количество датчиков на шине OneWire, луче это делать тут. Вдруг какой-то датчик "отвалился" с прошлого раза
  
  //сначала запросим температуру с DS18X20 
  sensors.requestTemperatures(); //опрашиваем градусники
  

  
  ///////цикл по DS18X20 /////////
  for (int colDS = 0; colDS <number_device ; colDS++){ //пробегаем по всем температурным датчикам
    Ctemp_DS = sensors.getTempCByIndex(colDS);//присваиваем температуру переменной
    //проверка значений температуры
    
    for(int i=0; INVALID_CTEMP && i< MAX_ATTEMPTS;i++){ //  если температура неправильная - делаем еще MAX_ATTEMPTS попыток.

      delay(ATTEMPTS_DELAY);   // Пауза между попытками
 
      Serial.print("attempt #");Serial.print(i);Serial.print(" for ");Serial.println(colDS); // выводим для какого датчика возникли проблемы и какая это попытка
      
      sensors.requestTemperatures();
      Ctemp_DS = sensors.getTempCByIndex(colDS);
    }

    Serial.print("DS");Serial.print(colDS);Serial.print("=");  // выводим имя датчика
    
    // Выводим температуру
    if(INVALID_CTEMP)Serial.print("fail");// все таки не удалось прочитать датчик
    else Serial.print(Ctemp_DS); // удалось
    
    // добавляем пробелы между датчиками и перевод строки в конце
    if(colDS==(number_device-1))Serial.println();  else  Serial.print(", ");
    
    
  }
  
    Serial.println(); // еще один перевод строки, что-бы данные "визуально" отделялись
    
}

/* --------------------------- DS1820 region END ---------------------------  */

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

memfise
Offline
Зарегистрирован: 30.06.2012

 выдает 

DS0=25.5625000000
, 
DS1=25.5000000000
, 
DS2=25.6250000000
, 
DS3=25.6250000000
, 
DS4=25.4375000000
, 
DS5=25.3125000000
leshak
Offline
Зарегистрирован: 29.09.2011

memfise пишет:

 выдает 

DS0=25.5625000000
, 
DS1=25.5000000000
, 
DS2=25.6250000000
, 
DS3=25.6250000000
, 
DS4=25.4375000000
, 
DS5=25.3125000000

Парочку, println вместо print сделал. Поправил, попробуйте еще раз скетч из #20 (вообщем похоже что работает, только "внешний вид" чуток поправить. Что-бы "в одноу строку" выводило).

memfise
Offline
Зарегистрирован: 30.06.2012

 да, теперь все в одной сторе

DS0=25.69, DS1=25.69, DS2=25.69, DS3=25.69, DS4=25.62, DS5=25.56

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну, по крайней мере теперь видно какой датчик что выдает. И будет видно когда "прочитать не удалось". 

Можно еще, по вкусу, в строку 72 добавить Serial.print(millis());Serial.print(": ");

Что-бы выводить текущие время ардуиновское. Чисто для удобства (это не обязательно).

Погоняйте его. Убедитесь что проблема "не правильных данных" не возникает. Если все нормально и датчики читаются стабильно - переходим к котлетам ;)  Откладываем, пока,  этот скетч, в сторону. отключаем DS датчики, подключаем DHT и пишем для них аналогичный скетч.

Кстати, было-бы не плохо, если -бы дали ссылочку на либу DHT , бо она тоже бывает разная.

memfise
Offline
Зарегистрирован: 30.06.2012

 уже, честно не помню где брал, вроде здесь https://github.com/adafruit/DHT-sensor-library

а с датчиками исполизовалась эта статья http://www.ladyada.net/wiki//tutorials/learn/sensors/dht.html

memfise
Offline
Зарегистрирован: 30.06.2012

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

 //надо придумать проверку от левых значений
   //считаем значения температуры и влажности с датчиков DHT11
   float DHT1_temp = dht1.readTemperature(); //влажность с DHT11
   float DHT1_humiditi = dht1.readHumidity(); //температура с DHT11
   float DHT2_temp = dht2.readTemperature(); //влажность с DHT11
   float DHT2_humiditi = dht2.readHumidity(); //температура с DHT11
   float DHT3_temp = dht3.readTemperature() ; //влажность с DHT11
   float DHT3_humiditi = dht3.readHumidity() ; //температура с DHT11 
   Serial.print(DHT1_temp); //выведем показания температуры с DHT11
   Serial.print(" ");        
   Serial.print(DHT1_humiditi); //выведем показания влажности с DHT11
   Serial.println(" ");
   Serial.print(DHT2_temp); //выведем показания температуры с DHT11
   Serial.print(" ");        
   Serial.print(DHT2_humiditi); //выведем показания влажности с DHT11
   Serial.println(" ");
   Serial.print(DHT3_temp); //выведем показания температуры с DHT11
   Serial.print(" ");        
   Serial.print(DHT3_humiditi); //выведем показания влажности с DHT11
   Serial.println(" ");

 

leshak
Offline
Зарегистрирован: 29.09.2011

memfise пишет:

 уже, честно не помню где брал, вроде здесь https://github.com/adafruit/DHT-sensor-library

а с датчиками исполизовалась эта статья http://www.ladyada.net/wiki//tutorials/learn/sensors/dht.html

Ага. Ну хорошо. Пригодится "для справки". Например сразу ясно что не нужно придумывать каких-то "особых температур" при неправильно чтении. Все функции возвращают NAN если не удалось прочитать (и сами плюют сообщение об ошибке в Serial).

Вообщем тестируйте DS-сы под нагрузкой, если все нормально - переходите к DHT (отдельный скетч). Раз "массивы не даются" - сделайте как получится. Фиг с ним сдублированием. Пусть заработает (и кидайте сюда), а потом и в массивы перекрутить попробуем.

memfise
Offline
Зарегистрирован: 30.06.2012

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

leshak
Offline
Зарегистрирован: 29.09.2011

>сейчас использую данный код,

Ну опять "за рыбу гроши". Вы что трафик экономите? Почему не дать "целиком"? Если я возьму этот кусок - он мне просто раскажет про кучу не знакомых переменных.

>//надо придумать проверку от левых значений

Не нужно придумывать. В предыдущем посте я писал что NAN функции возвращают. Загляните в исходник библиотеки. Ну и в любом случае, если бы там были проблемы чтения - вы бы уже увидили "Read fail" в сериале. Библиотека сама об этом говорит.

Но эти проверки "можно отложить на потом", раз пока fail-лов не видно, значит датчики читаются нормально (если у вас действительно эта версия библиотеки).

memfise
Offline
Зарегистрирован: 30.06.2012
#include "DHT.h" //библиотека для работы с датчиками влажности и температуры DHT11
#define DHTTYPE DHT11   //DHT 11
#define DHT_1_PIN 2 //датчик DHT11 подключен ко 2 pin arduino
#define DHT_2_PIN 3 //датчик DHT11 подключен ко 3 pin arduino
#define DHT_3_PIN 4 //датчик DHT11 подключен ко 4 pin arduino

DHT dht_1(DHT_1_PIN, DHTTYPE); //датчик на 2 пине
DHT dht_2(DHT_2_PIN, DHTTYPE); //датчик на 3 пине
DHT dht_3(DHT_3_PIN, DHTTYPE); //датчик на 4 пине

void setup (void) {
  Serial.begin  (9600);
  Serial.flush();
  dht_1.begin();
  dht_2.begin();
  dht_3.begin();  
}

void loop (void) {
      GetTempDHT11();
}

void GetTempDHT11()//Читаем температуру с градусника
{
  //считаем значения температуры и влажности с датчиков DHT11
  float DHT1_temp = dht_1.readTemperature(); //температура с DHT11
  float DHT1_humiditi = dht_1.readHumidity() ; //влажность с DHT11
  float DHT2_temp = dht_2.readTemperature(); //температура с DHT11
  float DHT2_humiditi = dht_2.readHumidity(); //влажность с DHT11
  float DHT3_temp = dht_3.readTemperature(); //температура с DHT11
  float DHT3_humiditi = dht_3.readHumidity(); //влажность с DHT11

  Serial.print(DHT1_temp); //выведем показания температуры с DHT11
  Serial.print(" ");        
  Serial.print(DHT1_humiditi); //выведем показания влажности с DHT11
  Serial.println(" ");
  Serial.print(DHT2_temp); //выведем показания температуры с DHT11
  Serial.print(" ");        
  Serial.print(DHT2_humiditi); //выведем показания влажности с DHT11
  Serial.println(" ");
  Serial.print(DHT3_temp); //выведем показания температуры с DHT11
  Serial.print(" ");        
  Serial.print(DHT3_humiditi); //выведем показания влажности с DHT11
  Serial.println(" ");
}

 отредактировано (убрал 1wire)

memfise
Offline
Зарегистрирован: 30.06.2012

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

leshak
Offline
Зарегистрирован: 29.09.2011

 О... вот теперь "зашибись". Все видно, ничего "не относящегося к сути". Ну согласитесь что искать тараканов в таком коде легче чем в стартовом скетче :)  (пока их не видно).

Щас попробуем причесать.

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну "ничего не относящегося" чуток погорячился. OneWire и DallasTemperature все-таки затесалось. Но то уже мелочи. Тем более новичку не просто сразу понять какие инклуды к кому относятся.

Попробуйте как вот это будет работать.

#include "DHT.h" //библиотека для работы с датчиками влажности и температуры DHT11
#define DHTTYPE DHT11   //DHT 11


void setup (void) {
  Serial.begin  (9600);
  Serial.flush();
  
  dht_init();
  
}

void loop (void) {
   ds_print_all();
}

/* --------------------------- DHT11 region START ---------------------------  */


#define DHT_1_PIN 2 //датчик DHT11 подключен ко 2 pin arduino
#define DHT_2_PIN 3 //датчик DHT11 подключен ко 3 pin arduino
#define DHT_3_PIN 4 //датчик DHT11 подключен ко 4 pin arduino


DHT dht_1(DHT_1_PIN, DHTTYPE); //датчик на 2 пине
DHT dht_2(DHT_2_PIN, DHTTYPE); //датчик на 3 пине
DHT dht_3(DHT_3_PIN, DHTTYPE); //датчик на 4 пине

#define DHT_COUNT 3 // количество датчиков
DHT *dhts[DHT_COUNT]={&dht_1,&dht_2,&dht_3}; // делаем массив ссылок на датчики что-бы было удобней в цикле по ним бегать


// инициализирует DHT11
void dht_init(){
  for(byte i=0;i<DHT_COUNT;i++)dhts[i]->begin();
}

//Выводит температуру и влажность со всех DHT11 датчиков
void ds_print_all()//бывшая GetTempDHT11
{
  for(int i=0;i<DHT_COUNT;i++){
     // выводим температуру
     Serial.print("DHT");Serial.print(i);Serial.print("_temp=");
     Serial.print(dhts[i]->readTemperature());
     
     //выводим влажность
     Serial.print(",DHT");Serial.print(i);Serial.print("_hum=");
     Serial.print(dhts[i]->readHumidity());
     
     // между датчиками пробелы или перевод строки после последнего
     if(i==DHT_COUNT-1)Serial.println();
     else Serial.print("  ");
  }
  Serial.println();// еще одна отбивочка "пустая строка"

}

/* --------------------------- DHT11 region END ---------------------------  */

 

 

memfise
Offline
Зарегистрирован: 30.06.2012

все выдается аналогично первого варианта.

DHT0_temp=24.00,DHT0_hum=28.00  DHT1_temp=25.00,DHT1_hum=27.00  DHT2_temp=25.00,
DHT2_hum=24.00

 

memfise
Offline
Зарегистрирован: 30.06.2012

 

#define DHT_COUNT 3 // количество датчиков
DHT *dhts[DHT_COUNT]={&dht_1,&dht_2,&dht_3}; // делаем массив ссылок на датчики что-бы было удобней в цикле по ним бегать

до этого яб долго додумывался

leshak
Offline
Зарегистрирован: 29.09.2011

memfise пишет:

 

#define DHT_COUNT 3 // количество датчиков
DHT *dhts[DHT_COUNT]={&dht_1,&dht_2,&dht_3}; // делаем массив ссылок на датчики что-бы было удобней в цикле по ним бегать

до этого яб долго додумывался

А я не уверен что это самый красивый способ инициализации массива объектов (вернее я "обошел это" использовав массив ссылок). Просто первое что попалось в качестве примера из старых проектов. 

Есть как минимум еще один, более компактный способ. Где инициализация выглядить более "традиционно", без указателей и оператора -> , но она требует заведение отдельного .h файла. Не захотел просто морочится с объяснением "как большой скетч разбивать на файлы".

Может и еще более красивый способ есть, но лень счас искать.

Так работает или нет? Что выводит?

leshak
Offline
Зарегистрирован: 29.09.2011

memfise пишет:

все выдается аналогично первого варианта.

DHT0_temp=24.00,DHT0_hum=28.00  DHT1_temp=25.00,DHT1_hum=27.00  DHT2_temp=25.00,
DHT2_hum=24.00

 

Ага. Проглядел. "Под нагрузкой все хорошо"? Неверные данные не попадаются?

То есть мы на данный момент имеем два скетча, для DS1820 и DHT11, каждый из которых, по отдельности работает абсолютно правильно? Подтвертиде это. Тогда будем пытаться их "объеденить" ;)

memfise
Offline
Зарегистрирован: 30.06.2012

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

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну значит тогда пытаемся "объедененное"

#include <OneWire.h> //библиотека для работы по шине OneWire
#include <DallasTemperature.h> //библиотека для работы с датчиками температуры DS18B20
#define ONE_WIRE_BUS 10 //шина ONE_WIRE_BUS установлена на 10 pin arduino
OneWire oneWire(ONE_WIRE_BUS);


#include "DHT.h" //библиотека для работы с датчиками влажности и температуры DHT11
#define DHTTYPE DHT11   //DHT 11


#define SERIAL_SPEED 9600 // скорость com-порта
int incomingByte = 0;   // для входящей информации изначально устанавливаем 0

#define CMD_PRINT_DS '1' // команда в Serial для вывода температу DS1820 датчиков
#define CMD_PRINT_DHT '2' // команда в Serial для вывода температу DS11 датчиков
#define CMD_PRINT_DS_DHT '3' // команда в Serial для вывода температу DS1820 и  DS11 датчиков




void setup (void) {
  Serial.begin(SERIAL_SPEED);

  ds_init(); // инициализируем ds1820 датчики
  dht_init(); // инициализируем dht датчики
}

void loop (void) {
  readSerialCommands(); // читаем и выполняем комманды из Serial порта
}

void readSerialCommands(){
    // посылаем запрос только после появления информации на порту
  if (Serial.available() > 0 ){
   
    incomingByte = Serial.read(); //читаем данные порта

    switch(incomingByte){ //выясняем что это за команда
    
        case CMD_PRINT_DS:
              ds_print_all(); // выводим DS1820 датчики
              break;
              
        case CMD_PRINT_DHT:  // выводи DHT11 датчики
               //а тут место для будущей команды чтения DHT
                dht_print_all();
               break;
               
         case CMD_PRINT_DS_DHT: // выводим все данные со всех датчиков
                 ds_print_all(); 
                 dht_print_all();
                 break;
         
             
      default: Serial.println("Unknown command");
    }
    
     Serial.println(); // еще один перевод строки, что-бы данные "визуально" отделялись

  }
}


/* --------------------------- DS1820 region START ---------------------------  */

#define MAX_ATTEMPTS 100  // максимальное количество повторных попытк если датчик не удается прочитать
#define ATTEMPTS_DELAY 750 // задержка между попытками

#define INVALID_CTEMP (Ctemp_DS == 85.00 || Ctemp_DS == -127.00 || Ctemp_DS == 0.00)  // условие "неправильной температуры"


DallasTemperature sensors(&oneWire);

int number_device;
float Ctemp_DS = 0.00; // значение температуры поумолчанию 0 градусов



// инициализация датчиков DS1820
void ds_init(){
  sensors.begin();
  sensors.setResolution(TEMP_12_BIT); //устанавливаем разрешение 12 бит
  sensors.setWaitForConversion(true);
}


//функция запроса температуры со всех датчиков температуры
void dht_print_all() // бывшая GetTempAll
{
   number_device = sensors.getDeviceCount(); // посчитаем количество датчиков на шине OneWire, луче это делать тут. Вдруг какой-то датчик "отвалился" с прошлого раза
  
  //сначала запросим температуру с DS18X20 
  sensors.requestTemperatures(); //опрашиваем градусники
  

  
  ///////цикл по DS18X20 /////////
  for (int colDS = 0; colDS <number_device ; colDS++){ //пробегаем по всем температурным датчикам
    Ctemp_DS = sensors.getTempCByIndex(colDS);//присваиваем температуру переменной
    //проверка значений температуры
    
    for(int i=0; INVALID_CTEMP && i< MAX_ATTEMPTS;i++){ //  если температура неправильная - делаем еще MAX_ATTEMPTS попыток.

      delay(ATTEMPTS_DELAY);   // Пауза между попытками
 
      Serial.print("attempt #");Serial.print(i);Serial.print(" for ");Serial.println(colDS); // выводим для какого датчика возникли проблемы и какая это попытка
      
      sensors.requestTemperatures();
      Ctemp_DS = sensors.getTempCByIndex(colDS);
    }

    Serial.print("DS");Serial.print(colDS);Serial.print("=");  // выводим имя датчика
    
    // Выводим температуру
    if(INVALID_CTEMP)Serial.print("fail");// все таки не удалось прочитать датчик
    else Serial.print(Ctemp_DS); // удалось
    
    // добавляем пробелы между датчиками и перевод строки в конце
    if(colDS==(number_device-1))Serial.println();  else  Serial.print(", ");
    
    
  }
  

    
}

/* --------------------------- DS1820 region END ---------------------------  */





/* --------------------------- DHT11 region START ---------------------------  */


#define DHT_1_PIN 2 //датчик DHT11 подключен ко 2 pin arduino
#define DHT_2_PIN 3 //датчик DHT11 подключен ко 3 pin arduino
#define DHT_3_PIN 4 //датчик DHT11 подключен ко 4 pin arduino


DHT dht_1(DHT_1_PIN, DHTTYPE); //датчик на 2 пине
DHT dht_2(DHT_2_PIN, DHTTYPE); //датчик на 3 пине
DHT dht_3(DHT_3_PIN, DHTTYPE); //датчик на 4 пине

#define DHT_COUNT 3 // количество датчиков
DHT *dhts[DHT_COUNT]={&dht_1,&dht_2,&dht_3}; // делаем массив ссылок на датчики что-бы было удобней в цикле по ним бегать


// инициализирует DHT11
void dht_init(){
  for(byte i=0;i<DHT_COUNT;i++)dhts[i]->begin();
}

//Выводит температуру и влажность со всех DHT11 датчиков
void ds_print_all()//бывшая GetTempDHT11
{
  for(int i=0;i<DHT_COUNT;i++){
     // выводим температуру
     Serial.print("DHT");Serial.print(i);Serial.print("_temp=");
     Serial.print(dhts[i]->readTemperature());
     
     //выводим влажность
     Serial.print(",DHT");Serial.print(i);Serial.print("_hum=");
     Serial.print(dhts[i]->readHumidity());
     
     // между датчиками пробелы или перевод строки после последнего
     if(i==DHT_COUNT-1)Serial.println();
     else Serial.print("  ");
  }

}

/* --------------------------- DHT11 region END ---------------------------  */

 

Шлем в сериал комманды

1 - вывести DS1820, 2- вывести DHT11, 3 - и тех и других.

Я выкинул преобразование " цифру" (отнимание 48 ми при чтении из Serial). Не нужно оно тут.  Так легче, если будет нужно, перейти на бинарные команды, да и кроме цифр, прямо сейчас можно будет использовать буквы. Если команд много будет, или захочется сменить на 's'- вывести DS, 'h' - вывести DHT, 'a' - вывести все.

 

 

memfise
Offline
Зарегистрирован: 30.06.2012

почему при выводе попадает на строку 55 

вот данные для 1, 2 и 3 (с закоментированными все нормально -без uknown command)


DHT0_temp=24.00,DHT0_hum=28.00  DHT1_temp=24.00,DHT1_hum=27.00  DHT2_temp=24.00,DHT2_hum=25.00

Unknown command

Unknown command

DS0=26.12, DS1=26.06, DS2=26.25, DS3=26.31, DS4=25.94, DS5=25.87

Unknown command

Unknown command

DHT0_temp=25.00,DHT0_hum=28.00  DHT1_temp=25.00,DHT1_hum=28.00  DHT2_temp=25.00,DHT2_hum=25.00
DS0=26.19, DS1=26.06, DS2=26.25, DS3=26.31, DS4=25.94, DS5=25.81

Unknown command

Unknown command

 

leshak
Offline
Зарегистрирован: 29.09.2011

>почему при выводе попадает на строку 55

Ну это значит что пришел символ которые не '1', не '2' и не '3'.

Судя по тому что "идут они парами" это, к гадалке не ходи, символы \r \n  (перевод строки и перевод каретки).

Тут есть два пути - не посылать их со стороны компа или игнорировать со стороны ардуины.

Что выбираете? :)

leshak
Offline
Зарегистрирован: 29.09.2011
Serial.print("Unknown command="); Serial.println(incomingByte);

Тогда вы увидите что же это за "неизвестная команда". На 99% уверен что там мы увидим

Unknown command=10
Unknown command=13

 

memfise
Offline
Зарегистрирован: 30.06.2012

 это я увидел, но самое инттересное это то, что это выскакивает после того как отработает код по 1 или два или три, без нажатия другого символа. Т.е. программа запсывает в сериал еще что-то, которое не 1,2 или 3 и сама попадает сюда

leshak
Offline
Зарегистрирован: 29.09.2011

 > программа запсывает в сериал еще что-то

Ну что значит "что-то"? Вы же сами сказали "это я увидел". Если вы видите =10 и =13, то вот это и есть "что-то" что оно посылает.

А символы с кодами 10 и 13 это символы "перевод каретки" и "возврат строки".

То есть, когда вы с компа посылаете '1', на самом деле отправляется строка '1\r\n'. Первый символ у вас обрабатывается, а что делать с остальными - дуина не знает (вот я специально и вставил в default сообщения об этом, что-бы сразу "ловить" ситуации которые "мы не предусмотрели", что-бы "не полагатся на случай").

Смотрите, вот когда наоборот, с дуины вы делаете Serial.print("bla-bla") и Serial.println("bla-bla) чем они отличаются? А тем что первый пошлет в сериал только "bla-bla", а второй "bla-bla\r\n", а терминал, приняв эту строку и увидив символы \r\n поймет что дальше данные нужно выводить с новой строки.

Поэтому, если вы действительно "увидели" эти 10,13 (\r\n) - осталось решить каким путем вы собираетесь "боротся с ними". Варианта два: 

  1. Не посылать их с компа 
  2. Обрабатывать их на стороне ардуины (то есть сделать так что-бы она воспригинмала их как "допустимые", но ничего не делала при их получении)

Скажите какой вариант вам больше нравится.

 

 

 

 

memfise
Offline
Зарегистрирован: 30.06.2012

второй вариант думаю лучше

leshak
Offline
Зарегистрирован: 29.09.2011

 Ну тогда просто добавлет эти символы в switch который команды опознает

    switch(incomingByte){ //выясняем что это за команда
    
        case CMD_PRINT_DS:
              ds_print_all(); // выводим DS1820 датчики
              break;
              
        case CMD_PRINT_DHT:  // выводи DHT11 датчики
               //а тут место для будущей команды чтения DHT
                dht_print_all();
               break;
               
         case CMD_PRINT_DS_DHT: // выводим все данные со всех датчиков
                 ds_print_all(); 
                 dht_print_all();
                 break;
         
          case '\r':
          case '\n':
                     // на переводы строки ничего не делаем
                  break;
          
             
      default: Serial.print("Unknown command=");Serial.println(incomingByte);
    }

 

memfise
Offline
Зарегистрирован: 30.06.2012

 все отлично работает, мне разбираться еще долго :). спасибо

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

39.00
24.8
24.8
24.9
24.8
24.7
24.6 24.
43.00 24.
45.00 25.

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

leshak
Offline
Зарегистрирован: 29.09.2011

 

memfise пишет:

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

А что это за "шифрограмма в центр"?

memfise пишет:

предпологаю, что глючит какой-то датчик и из за него происходит сбой

Так а зачем предполагать? Вроде же специально все переписали что-бы и видеть какие датчики что посылают. И иметь возможность "по отдельности" их запускать. По логу же должно быть видно "кто выкаблучивается".

memfise
Offline
Зарегистрирован: 30.06.2012

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

leshak
Offline
Зарегистрирован: 29.09.2011

Что-бы не выслеживать "баловника" глазами - можно просто добавить if который будет следить за правильностью данных. что-то типа

// в setup() добавить pinMode(LED_BUILTIN,OUTPUT);
// будем его зажигать при неправильно температуре, что-бы не пялится
// постоянно в Serial

if(Ctemp_DS>30 || Ctemp_DS<10){ // температура которую считаем ошибочной
  Serial.print("Wrong temp on DS");Serial.println(colDS);
  digitalWrite(LED_BUILTIN,HIGH);// зажигаем диод-ошибку
}

 

Если не хочется в Serial писать "всяких слов лишних". Можно убрать Serial.print и мигать диодом - показывая "кто у нас глючит". Типа 3 раза мигнули пауза 5 сек, опять три раза - пауза - значит глючит третий датчик. Если глючит DS мигание быстрые сделать, елси DHT - более длинные (ну что-бы на глаз различать).