Вопрос по некоторым аспектам в програмировании...

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем exposity, 30 окт 2012.

  1. exposity

    exposity Нуб

    Подскажите почему именно число 255 является максимальной скоростью для мотора. Столкнулся с таким моментом: решил поставить более низкое число для скорости моего мотора, ставлю 200 - крутится медленней, ставлю 150 - еще медленней, ставлю 110 - не крутится совсем. Связано ли это со скоростными возможностями моего мотора или дело в чем-то другом?

    Второй момент: установил параметры вращения в одну сторону 60000 (1мин) после чего мотор должен остановится на 1сек. и начать вращение в обратную сторону - он проигнорировал это и продолжал врвщатся в первоначальном направлении. При значении 30000 - программа работает исправно. Означает ли это, что ардуино понимает только отрезки до 30сек.? Более 30сек. мотор игнорирует инструкции скетча приходится дублировать указание двигатся в положеном направлении еще 30сек., чтобы достичь желаемой минуты.
     
  2. nailxx

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

    То, о чём вы говорите — фишки вычислительной арифметики и моторы тут совсем не причём.

    255 — это максимальное число, которое может быть представлено одним байтом. В байте 8 бит, поэтому максимум: 2^8 - 1 = 255. Именно одним байтом определяется скважность ШИМ-сигнала для управления мотором. 0 — это 0%, 255 — это 100%. Поставив скорость 255 вы обозначаете, что хотите включить мотор на полную, постоянно подавать напряжение без всяких провалов.

    Моторы — тяжёлые, инертные устройства, которые нужно разгонять. Поэтому до некоторого порога скважности они не будут вращаться, а только пищать и гудеть: в метро или в электричке вы слашали этот эффект при разгоне.

    Теперь о 30000. Функция delay принимает в качестве параметра значение типа int. int для Arduino — это 2 байта, причём со знаком (на знак отводится один старший бит), поэтому максимальное значение: 2^15 - 1 = 32767. Передавая 60000 вы провоцируете перевод значения из беззнакового в знаковое и на самом деле получаете эквивалент задержки на: 32767 - 60000 = -27233. То есть хотите поспать минус 27 секунд, то есть вы уже проспали, то есть сразу едем дальше.

    Решение — воспользоваться длинным типом данных long и написать обёртку:

    Код (Text):

    void longDelay(long seconds)
    {
        while (seconds--)
            delay(1000);
    }
     
    И используйте её вместо простого `delay` где это уместно.
     
    patamushta и aysheka нравится это.
  3. exposity

    exposity Нуб

    спасибо. все очень доступно.
     
  4. kulver

    kulver Нерд

    а чем такая обёртка лучше банального:
    Код (Text):
    unsigned long some_time = 60 000;
    delay(some_time);
    ?
     
  5. nailxx

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

    В том, что от этого функция delay не станет принимать unsigned long. Она принимает int: так заложено в сигнатуре. Если сделаете как написали, в момент вызова unsigned long будет неявно преобразован в signed int и получится всё то же самое.
     
  6. Unixon

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

    Вообще то сейчас (v1.0.1) функция delay() уже объявлена как void delay(unsigned long) ...
    Вот кусок wiring.c:
    Код (Text):

    void delay(unsigned long ms)
    {
            uint16_t start = (uint16_t)micros();
     
            while (ms > 0) {
                    if (((uint16_t)micros() - start) >= 1000) {
                            ms--;
                            start += 1000;
                    }
            }
    }
     
     
    patamushta и nailxx нравится это.
  7. nailxx

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

    Отличное замечание! У меня устаревшие данные.