Digispark + ds18b20 + шим

Тема в разделе "Микроконтроллеры AVR", создана пользователем kirill_vector, 29 июн 2024.

  1. kirill_vector

    kirill_vector Нерд

    проект управляемого вентилятора радиатора моего автомобиля
    стандартный скетч на библиотеке OneWire не работает, красный светодиод не горит
    ШИМ на P1 датчик на P2
    -------------------------------------------------------------------------------

    #include <OneWire.h>

    OneWire ds(2); // Создаем объект OneWire для шины 1-Wire, с помощью которого будет осуществляться работа с датчиком

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

    void loop(){

    // Определяем температуру от датчика DS18b20
    byte data[2]; // Место для значения температуры

    ds.reset(); // Начинаем взаимодействие со сброса всех предыдущих команд и параметров
    ds.write(0xCC); // Даем датчику DS18b20 команду пропустить поиск по адресу. В нашем случае только одно устрйоство
    ds.write(0x44); // Даем датчику DS18b20 команду измерить температуру. Само значение температуры мы еще не получаем - датчик его положит во внутреннюю память

    delay(1000); // Микросхема измеряет температуру, а мы ждем.

    ds.reset(); // Теперь готовимся получить значение измеренной температуры
    ds.write(0xCC);
    ds.write(0xBE); // Просим передать нам значение регистров со значением температуры

    // Получаем и считываем ответ
    data[0] = ds.read(); // Читаем младший байт значения температуры
    data[1] = ds.read(); // А теперь старший

    // Формируем итоговое значение:
    // - сперва "склеиваем" значение,
    // - затем умножаем его на коэффициент, соответсвующий разрешающей способности (для 12 бит по умолчанию - это 0,0625)
    float temperature = ((data[1] << 8) | data[0]) * 0.0625;

    if (temperature > 87 && temperature <= 89) analogWrite(1, 50);
    if (temperature > 89 && temperature <= 91) analogWrite(1, 120);
    if (temperature > 91 && temperature <= 93) analogWrite(1, 200);
    if (temperature > 93) analogWrite(1, 230);
    }

    ---------------------------------------------------------------------
    если последний абзац сделать в виде
    ---------------------------------------------------------------------

    float temperature = ((data[1] << 8) | data[0]) * 0.0625;
    analogWrite(1, temperature * 2)
    }
    -----------------------------------------------------------------------
    то работает, и при нагреве датчика вплоть до 100 градусов понятно размер импульсов Шим
    пните горемыку, что я не так делаю.
     
  2. ИгорьК

    ИгорьК Гуру

    [​IMG]

    И объясни проблему понятно.
     
    kirill_vector нравится это.
  3. kirill_vector

    kirill_vector Нерд

    Задача: digispark Attiny 85 USB, датчик ds18b20 на 2-й ноге питание по 3 проводам резистор подтяжки 4.7 к стоит, выход ШИМ 1-я нога. ШИМом управляется вентилятор, который должен включаться при температуре выше 87 градусов и далее с ростом температуры повышается скорость вентилятора. Arduino IDE 2.3.2. Библиотека OneWire последняя версия.

    Проблема: не работает, красный светодиод на Дигиспарке, не горит

    Если поставить температуры ниже, к примеру от 30 до 50 градусов - то работает.

    Код (C++):
    #include <OneWire.h>

    OneWire ds(2); // Создаем объект OneWire для шины 1-Wire, с помощью которого будет осуществляться работа с датчиком

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

    void loop(){
     
      // Определяем температуру от датчика DS18b20
      byte data[2]; // Место для значения температуры

      ds.reset(); // Начинаем взаимодействие со сброса всех предыдущих команд и параметров
      ds.write(0xCC); // Даем датчику DS18b20 команду пропустить поиск по адресу. В нашем случае только одно устрйоство
      ds.write(0x44); // Даем датчику DS18b20 команду измерить температуру. Само значение температуры мы еще не получаем - датчик его положит во внутреннюю память

      delay(1000); // Микросхема измеряет температуру, а мы ждем.

      ds.reset(); // Теперь готовимся получить значение измеренной температуры
      ds.write(0xCC);
      ds.write(0xBE); // Просим передать нам значение регистров со значением температуры

      // Получаем и считываем ответ
      data[0] = ds.read(); // Читаем младший байт значения температуры
      data[1] = ds.read(); // А теперь старший

      // Формируем итоговое значение:
      //    - сперва "склеиваем" значение,
      //    - затем умножаем его на коэффициент, соответсвующий разрешающей способности (для 12 бит по умолчанию - это 0,0625)
      float temperature =  ((data[1] << 8) | data[0]) * 0.0625;

      if (temperature > 87 && temperature <= 89) analogWrite(1, 50); // 1-я ступень 87-89 градусов
      if (temperature > 89 && temperature <= 91) analogWrite(1, 120); // 2-я ступень 89-91 градусов
      if (temperature > 91 && temperature <= 93) analogWrite(1, 200); // 3-я ступень 91-93 градуса
      if (temperature > 93) analogWrite(1, 230); // 4-я ступень больше 93 градусов
    }
     
     
  4. Asper Daffy

    Asper Daffy Иксперд

    Сам-то понял? По каким трём проводам питание? Подтяжка к чему?
    А сейчас там что? Прямо так вентилятор к ноге и присобачен? Или как?
    О каком диоде речь и почему он должен гореть? На какой он ноге?

    Рисуй-ка нормальную схему!
     
  5. kirill_vector

    kirill_vector Нерд

    image (2).png
    На плате Digispark Attiny 85 распаены зелёный и красный светодиоды, зелёный - питание, красный - горит когда работает.
    у DS18b20 два вида питания, стандартное - "+" "-" "дата" (три провода), и паразитное питание "+-" и "дата" (два провода) и соответственно код управления DS18b20 разный резистор 4.7 к подтяжки с "+" на "дата" нужен по даташиту, ШИМ не напрямую управляет - через МосФеты. Проблема не в схеме, а в том, что в нужном диапазоне температур не работает.
     
  6. Asper Daffy

    Asper Daffy Иксперд

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

    И да, кстати, в дополнение к схеме, пожалуйста, спецификацию компонентов. Например,, RTC у Вас голая микросхема или модуль? Если модуль, то какой именно? Возможно, все подтяжки на нём уже есть
     
    DetSimen и parovoZZ нравится это.
  7. kirill_vector

    kirill_vector Нерд

    Пожалуйста прочитайте внимательно ! "ЕСЛИ СТАВИТЬ ДРУГОЙ ДИАПАЗОН ТЕМПЕРАТУР НАПРИМЕР 30-50 ГРАДУСОВ ВСЁ РАБОТАЕТ", если ставить выше - не работает.
     
  8. KindMan

    KindMan Гуру

    Из ваших постов не понятно, что не работает. Может быть просто температура не доходит до 80? У вас нет проверки на ошибки в получении данных, откуда вы можете быть уверены, что температура верная? Как вы вообще понимаете какая температура? Отладочная информация у вас не приложена.
     
  9. ИгорьК

    ИгорьК Гуру

    Там в коде для чтения данных датчика применён интересный алгоритм с участием массива двух байт.

    Полагаю дело в нем. Поищите другие варианты получения данных.

    Я вам не помогу с мобильника.
     
    kirill_vector нравится это.
  10. kirill_vector

    kirill_vector Нерд

    Всем спасибо.
    Решено переустановкой Arduino IDE, видать сбой в компиляторе
     
  11. KindMan

    KindMan Гуру

    Ох уж этот компилятор, сколько из-за него проблем.
     
    Asper Daffy и DetSimen нравится это.
  12. ИгорьК

    ИгорьК Гуру

    Остался у меня такой вопрос...
    Код (C++):

    byte data[2]; // Место для значения температуры

    data[0] = ds.read(); // Читаем младший байт значения температуры
    data[1] = ds.read(); // А теперь старший

    float temperature =  ((data[1] << 8) | data[0]) * 0.0625;
     
    Как может верно работать последняя строка кода => сдвиг влево байт на восемь битов? Или умный компилятор сам поменял байт на что-то другое?
     
  13. kirill_vector

    kirill_vector Нерд

    код взаимодействия с датчиком температуры DS18B20 взял отсюда https://arduinomaster.ru/datchiki-arduino/arduino-ds18b20/
    это аналогично :
    Код (C++):
    temp = (ds.read() | ds.read() << 8); // Принимаем два байта температуры
      temperature = (float)temp / 16.0;
     
    ИгорьК нравится это.
  14. ИгорьК

    ИгорьК Гуру

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

    А практически, "если работает - не трогай" :)
     
  15. kirill_vector

    kirill_vector Нерд

    Млин, на ассемблере Правец-8
    Сразу понятно кто тут "гуру", спасибо за понимание :rolleyes:
     
    ИгорьК нравится это.
  16. ИгорьК

    ИгорьК Гуру

    Да, некоторые люди иногда усложняют...

    Вот еще какие мысли, в виде совета.

    1. Есть "настоящие" DS18b20, а есть ненастоящие. Последних в последнее время больше. В настоящих разрешение по-умолчанию максимальное (12 бит, на память), а в ненастоящих - 11. Или еще сколько-то. Это, ясный пень, может влиять на ситуацию подсчета результата.

    2. Как замерил/посчитал температуру - выведи ее в консоль, так будет и забавно и понятно что к чему.
     
  17. KindMan

    KindMan Гуру

    Игорь, тут всё просто. Мы не двигаем саму data[1] , а помещаем результат сдвига в temperature, а она уже float.
     
    ИгорьК нравится это.
  18. ИгорьК

    ИгорьК Гуру

    Не хотелось бы выпускать на свободу сферического коня: "я все понял, но почему самолет летает и не машет крыльями".

    Я бы себе объяснил происходящее так: ситуация настолько типовая, что проще заставить компилятор ее решать, чем требовать от кодера соблюдения правил. (Там до помещения сдвига в результат еще есть "сложение И" точно не чисел float и умножение на число с точкой.)

    Да и шут с ним :)
     
  19. KindMan

    KindMan Гуру

    Я не учитель, и не профессионал, могу тоже "наплести про лес".
    Вот такая запись ведь не противоречит ничему?
    Код (C++):
    float temperature = 255 << 8;
     
    ИгорьК нравится это.
  20. parovoZZ

    parovoZZ Гуру

    да, умный компилятор выделит ещё один байт слева, а точнее положит результат в один из регистров РОН.

    ни в какой флоат ничего не помещается. Всё лежит в регистрах. А только после вычисления выражения происходит сборка флоат. Но микропроцессор дурины ничего не знает про флоат. Поэтому сборка полностью software.
     
    ИгорьК нравится это.