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

Тема в разделе "Arduino & Shields", создана пользователем itehno, 18 апр 2015.

  1. itehno

    itehno Нерд

    Всем доброго времени суток.

    Прошу помощи у гуру.
    К Arduino Uno подключены:
    1. Сервопривод управляемый с помощью потенциометра
    2. Два температурных датчика

    Проблема заключается в том, что при одновременной работе датчиков и сервопривода, последний начинает постоянно подёргиваться, нет плавности хода. Если закоментировать все строки, связанные с датчиками температуры, то все работает прекрасно.
    Может есть идеи? Заранее спасибо.


    Вот мой код:

    #include <OneWire.h> //Подключаем библиотеку температурных датчиков
    #include <DallasTemperature.h> //Подключаем библиотеку температурных датчиков
    #define ONE_WIRE_BUS 10 //Объясняем контроллеру, на какой порт подключены температурные датчики
    OneWire oneWire(ONE_WIRE_BUS); //Настройка OneWire для работы с OneWire устройствами
    DallasTemperature sensors(&oneWire); //Передача данных oneWire в dallasTemperature
    DeviceAddress Thermometer1 = {
    0x28, 0xA8, 0xB9, 0x89, 0x06, 0x00, 0x00, 0xC4 }; //Адресс датчика
    DeviceAddress Thermometer2 = {
    0x28, 0x0C, 0xB3, 0x89, 0x06, 0x00, 0x00, 0xF9 }; //Адресс датчика
    #include <Servo.h> //Подключаем библиотеку сервопривода
    Servo myservo; //Присваиваем имя сервоприводу
    #define potenciometr A0 //Объясняем контроллеру, на какой порт подключен переменный резистор
    int temp_1, temp_2; //Объявляем переменные температурных датчиков
    int val; //Создаем переменную val

    void setup()
    {
    sensors.begin(); //Запуск библиотеки
    sensors.setResolution(Thermometer1, 10); //Установка разрешения 10 бит
    sensors.setResolution(Thermometer2, 10); //Установка разрешения 10 бит
    myservo.attach(11); //Указываем пин, к которому подключен сервопривод
    pinMode(potenciometr, INPUT); //Определение режима работы вывода
    Serial.begin(9600); //Открывам COM Port на скорости 9600
    }
    void printTemperature(DeviceAddress deviceAddress,const char* NumSensor ) //Функция вывода температуры для устройства
    {
    int tempC = sensors.getTempC(deviceAddress);
    Serial.print(NumSensor); //Вывод значений
    Serial.println(tempC); //Перенос на новую строку
    }

    void loop()
    {
    sensors.requestTemperatures(); //Отправляем команду для получения температуры
    printTemperature(Thermometer1,"1 "); //Выводим значения первого датчика, начинающиеся с символов 1 + пробел
    printTemperature(Thermometer2,"2 "); //Выводим значения второго датчика, начинающиеся с символов 2 + пробел
    temp_1= sensors.getTempC(Thermometer1); //Получение данных в переменную с термометра 1
    temp_2= sensors.getTempC(Thermometer2); //Получение данных в переменную с термометра 2

    val = analogRead(potenciometr); //Считывает значение потенциометра (величина между 0 и 1023)
    val = map(val, 0, 1023, 0, 179); //Масштабирует его для использования с сервоприводом (значение между 0 и 180)
    myservo.write(val); //Устанавливает позицию серво в соответствии с масштабируемым значением
    }





    ------------------Я заметил, что проблема в этом участке кода-------------------
    sensors.requestTemperatures();
    printTemperature(Thermometer1,"1 ");
    printTemperature(Thermometer2,"2 ");
    temp_1= sensors.getTempC(Thermometer1);
    temp_2= sensors.getTempC(Thermometer2);
     
    Последнее редактирование: 18 апр 2015
  2. понаблюдайте за значениями с датчиков и от потенциометра, кто гадит?

    А не пробовали считывать по 10 значений с каждого датчика и отбрасывать те значения, которые слишком сильно отличаются друг от друга?
    А может у вас шумит потенциометр, то при вращении его может быть например такой ряд значений:
    5 ,6, 5, 7, 60, 6, 7, 123, 5, 6

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

    Ну как-то так.
     
  3. ИгорьК

    ИгорьК Гуру

    Проблемы здесь две.
    1. Пожалуйста, научитесь правильно оформлять код. Это чтобы народ не ломал глаза, глядя на него.
    2. sensors.requestTemperatures(); - занимает тучу времени. Сколько - надо копать библиотеку. В принципе - с этим можно справиться, соединив датчики тремя, а не двумя проводами и уменьшив время задержки в библиотеке до приемлемого уровня, когда данные получаются.
    По даташиту, датчику нужно 750 мс для преобразования. Полагаю, именно такая задержка там и стоит. Но это для двухпроводного соединения. Используя трехпроводное - ее можно уменьшить до 50-70.
    3. Можно вообще отказаться от этой библиотеки. Добывать данные "вручную" с запаздыванием их получения. Для этого Вам нужно разобраться с логикой работы датчика по даташиту. В Инете, кстати, есть хороший перевод на русский язык.

    Или если кратко - то здесь: http://forum.amperka.ru/threads/ds18b20-повторим-пройденное.4013/
    А если не ожидаются отрицательные температуры - можно еще код сократить, там понятно какой кусок.
     
    Последнее редактирование: 27 май 2015