arduino uno + servo == звуки USB подключения

Тема в разделе "Arduino & Shields", создана пользователем d00m, 19 ноя 2012.

  1. d00m

    d00m Гик

    доброго времени суток.
    у меня arduino uno rev3 и пара сервов из этого магазина - FS90
    так же есть Troyka Shield.
    сервы прикрепил друг к другу и на них поставил веб-камеру.
    в идеале хочу сделать простую вебстраничку с контролами для управления сервами, а пока просто тестирую как оно крутится..

    подключаю сервы через Troyka Shield. проверяю простой код:

    Код (Text):

     
    #include <Servo.h>
    Servo servo1, servo2;
     
    void setup()
    {
      servo1.attach(10);
      servo2.attach(9);
    }
     
    void loop()
    {
       servo1.write(0);  
       delay(1000);        
       
       servo2.write(0);  
       delay(1000);        
       
     
    }
     
    все вроде работает, сервы крутятся, но както странно.
    при первом включении 2 серв поворачивается туда-сюда и начинает гудеть..
    потом, при нажатии кнопки Upload он снова крутится туда-сюда и гудение прекращается..
    странно что 1 серв не крутится..


    и почемуто постоянно в колонках играет звук подключения и отключения USB устройства. как будто в мой комп ктото регулярно вставляет какоето USB устройство и через пару сек достает его. и так постоянно..
    Но самое странное - что эти звуки както не регулярно звучат. Иногда после каждого поворота серва. Иногда пропускает и звука нет..

    Но если я снимаю Troyka Shield и подключаю один серв напрямую к ардуине - такого эффекта нет.

    понимаю что описание проблем весьма туманное, но вот пока могу только так..
    надеюсь, что ктото уже сталкивался с подобными проблемами и подскажет куда смотреть.
    где бы почитать как рулить сервами правильно..
    пока я просто хочу из Arduino IDE крутить камерой - то есть менять в коде значения градусов и аплоадить его на ардуино чтобы она крутила сервами. но эти странные звуки жужжания от сервов (как будто держишь пальцами подключенный моторчик) и странные звуки windows меня чесно говоря смущают.. может я чтото не так делаю..
    еще иногда после таких вот подключений-отключений USB и при последующей попытке аплоада кода, IDE мне пишет что COM порт на котором висист arduino - занят ! хотя я конечно же кабель не трогал и ничего не отсоединял..
     
  2. nailxx

    nailxx Официальный Нерд Администратор

    Сервы — это моторы. Моторы кушают много тока. Ваш USB быть может столько не выдаёт. Бывают концентраторы с ограничением 100 мА, бывают 500 мА. У вас, видимо, первый вариант. При одновременном включении обоих серв питание просаживается, Arduino выключается, USB-коннект теряется, питание нормализуется, Arduino включается, USB-коннект появляется и поехали по кругу.

    Выход — использовать внешнее питание, попробовать другой USB-порт или использовать активный USB-хаб.
     
    Marco и Злая Птичка нравится это.
  3. d00m

    d00m Гик

    вас понял.. может действительно проблема в этом.
    правда у меня ноут dell 6520 - вроде не самый плохой.. и еще пробовал usb порт на его родной докстанции - там то по идее usb хаб должен быть мощный, ведь док станция питается от розетки.. но все равно эффект тот же.
    и кстати, сервы то самые маленькие - http://amperka.ru/collection/Mehanika/product/mikrosiervoprivod-fs90
     
  4. d00m

    d00m Гик

    нашел БП - 5v 2A от какогото свича.
    подключил МК через него. вроде все ok стало..
    но только сервы гудят иногда. правда бывает что после отработки поворота качельки - тихо. а бывает - он гудит как трансформатор.. это нормально ? и можно списать на "простоту" серва или я чтото напутал опять ?
    так же похоже нужно искать некое дефолтное положение серва. тот 0 градусов от которого все отсчитывается..
     
  5. nailxx

    nailxx Официальный Нерд Администратор

    То, что они гудят может свидетельствовать о недокалиброванности: в метод attach можно помимо пина передать длительности импульсов для крайних положений (0° и 180°). По умолчанию используются 544 и 2400 мкс. Под конкретную серву лучше подобрать значения отдельно.
     
  6. Unixon

    Unixon Оракул Модератор

    У этих серв только в теории 0° и 180° граница, а реально может быть 2° и 179° например. Это можно выяснить только экспериментально. Происходит это потому, что передаточный механизм сервы не дает двигателю докрутиться до нужного положения, а гудит серва от того, что контроллер все равно пытается загнать двигатель в это недостижимое положение. Ну и способы решения: (а) смириться с диапазоном 176°..177° и косячными границами, (б) разобрать серву и устранить производственные дефекты механики.
     
  7. d00m

    d00m Гик

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

    Unixon Оракул Модератор

    Что вы еще хотите про них прочитать? У меня есть пара серв от Амперки, из тех что привозили первыми, когда их было только по одному виду. Диапазон проверял экспериментально. Закончилось тем, что просто отрезал крайних 2 градуса с обоих сторон и успокоился. Сервы не разбирал.
     
  9. d00m

    d00m Гик

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

    просто хотелось понять основательно как ними быть.. иногда бывает при запуске скетча дергает тот серв, который совсем не используется в коде.. видимо некий init происходит - но в реале это пару градусов смещения. это странно.
    а вобще было б гуд если бы ткнули какойнить мануал где описано как сервами можно рулить из веб страницы..
    а то сейчас просто редактирую в разделе setup значения углов и запускаю постоянно.
    хотелось бы желать это с веб морды. то есть надо понять как передавать в МК эти данные..
     
  10. передавать по Serial
    принимать - Serial.read
     
  11. Код (Text):
    недокод удалён
    Передавать так :
    первый мотор:
    oугол
    второй мотор:
    tугол
    Например, посылаете в Serial Monitor:
    o10
    t20
    И 1 серва встает в угол 10, 2 - в угол 20.
    Поправьте меня, если что-то не так!
     
  12. d00m

    d00m Гик

    спасибо, но чет не проходит проверку ваш код.. разбираюсь
     
  13. Код (Text):
    недокод удалён
    Вот, так попробуйте.
     
  14. d00m

    d00m Гик

    спасибо, оно вроде работает, но один раз только команду принимает. после этого не реагирует на команды.. причем я закоментил "обработчик" для одного серва, так как непонятно как вводить ему данные для двух сервов сразу.
     
  15. d00m

    d00m Гик

    похоже ошибка в функции readSerialInt()
    она всегда возвращает 0
     
  16. d00m

    d00m Гик

    и каким образом оно конвертирует байт в цифру ?

    допустим я ввожу в Serial Monitor цифру "70" и хочу проверить что же я ввел:

    #include <Servo.h>
    Servo servo1, servo2;

    void setup()
    {
    Serial.begin(9600);
    Serial.println("Ready");
    }

    int readSerialInt()
    {
    int result = 0;
    while (Serial.available())
    result = result * 10 + (Serial.read() - '0');
    return result;
    }
    void loop() {

    while (Serial.available() == 0);
    int test = readSerialInt();
    Serial.print("received: ");
    Serial.println(test);

    }

    получаю на выходе
    Ready
    received: 7
    received: 0

    а по идее должен получить 70... или я чтото путаю ?
     
  17. Ну да, должен получить 70.
    А вообще, это код nailxx`а, у него и спросите.
     
  18. nailxx

    nailxx Официальный Нерд Администратор

    Ну тут дело вот в чём. Когда вы посылаете что-то с компа на Arduino не факт, что в буфере окажется всё сразу. Поэтому Serial.available() может вернуть ноль посредь разбора. Как у вас тут. Правильнее ориентироваться на символ переноса строки.

    Код (Text):

    int readSerialInt()
    {
        char c;
        int result = 0;
     
        for (;;) {
            if (!Serial.available())
                continue;
     
            c = Serial.read();
            if (c == '\r')
                continue;
     
            if (c == '\n')
                return result;
     
            result = result * 10 + (c - '0');
        }
    }