Шаговый двигатель + тензодатчик = дозатор -нужна помощь.

Тема в разделе "Arduino & Shields", создана пользователем Valik, 23 окт 2018.

  1. ostrov

    ostrov Гуру

    Ой не, не сегодня. )
     
    parovoZZ нравится это.
  2. DIYMan

    DIYMan Guest

    Почему? Про обёртку над первым таймером в виде класса TimerOne ;) Он удобный просто.
     
  3. Valik

    Valik Нерд

    Я бы не догадался бы как написать. Еще раз спасибо. Вы реально помогли.
    Может подскажите еще один момен, у меня пока процесс отладки. Залил скетьч, движок включился и крутится невзирая на ves, вот код:
    void Timer1_action_1()
    {
    if (ves <=50) {
    digitalWrite(9, !digitalRead(9));
    }
    но когда вес перевалил за отметку 50грамм, шаговик остановился и больше не запускается если после этого вес стал 30 грамм или 0 грамм. Хотя во втором коде if (ves >=50 && ves <=100), шаговик работает с пониженой скоростью :D, останавливается при выходе из граници до 50 и свыше 100 и включается если VES в указанном интервале.
     
  4. DIYMan

    DIYMan Guest

    Объявите переменную ves с модификатором volatile ;)
     
  5. Valik

    Valik Нерд

    Возможно я неправильно что то в настройках указал. Смогли бы вы просмотрть? Когда было указано два таймера. А также хотел спросить сколько Timer1.setPeriod () можно указывать? Можно их указать 2 или 3?

    volatile int ves; ------ к сожаленью не помогло. :(


    void setup()
    {
    //////////////////////////////////////// 1-й таймер
    Timer1.initialize(100); // скорость вращения быстрая
    Timer1.pwm(9, 512);
    pinMode(9, OUTPUT);
    Timer1.attachInterrupt(Timer1_action);
    /////////////////////////////////////////// 2-й таймер
    Timer1.setPeriod (500); // скорость вращения медленная
    Timer1.setPwmDuty(9, 512);
    pinMode(9, OUTPUT);
    Timer1.attachInterrupt(Timer1_action_1);
    ////////////////////////////////////////*.*дальше есть остальной код но я его не указал,он таймеру не относится.
    void Timer1_action()
    {
    if (ves < 49) {digitalWrite(9, !digitalRead(9)); } // вес больше 50 грамм, происходит переход к 2-у таймеру и скорость вращения двигателя уменьшается, а со 2-го на 1-й не происходит.
    }
    void Timer1_action_1()
    {
    if ( ves > 50 && ves < 100) {digitalWrite(9, !digitalRead(9));}
    }
    void loop()
     
    Последнее редактирование: 26 окт 2018
  6. DIYMan

    DIYMan Guest

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

    Вам нужен ШИМ на таймере, вы уверены? Короче, код простейший:

    Код (C++):

    volatile int ves = 0;
    volatile bool vesUpdated = false;

    void Timer1_action()
    {
     if(!vesUpdated)
        return;

        vesUpdated = false;

        if (ves > 50 && ves < 100)
        {
            // ставим среднюю скорость, когда вес в диапазоне (50,100)
            Timer1.setPeriod(200);
        }
        else if(ves >= 100)
        {
            // ставим маленькую скорость, когда вес в диапазоне [100,бесконечность)
            Timer1.setPeriod(400);
        }
        else
        {
            // ставим быструю скорость, когда вес в диапазоне [0,50]
            Timer1.setPeriod(100);
        }

    }

    void setup()
    {
        Timer1.initialize(100); // скорость вращения быстрая
        Timer1.attachInterrupt(Timer1_action);
    }

    void loop()
    {
        int oldVes = ves;
        ves = ...; // тут как-то получаем в переменную ves значение
        vesUpdated = (ves != oldVes); // говорим обработчику таймера, что значение веса изменилось, если реально были изменения
       
    }
     
    Что может быть проще - я не знаю.
     
    Последнее редактирование модератором: 26 окт 2018
  7. Valik

    Valik Нерд

    Для меня понятен процесс, но написание самого кода требует определенных знаний, умений и навыков. Нигде даже близко не было примера о том как и где указывать setPeriod. Из того, что я увидел, прочитал в документации и как понял - я написал, но оно оказалось абсолютно неверным. Я понимаю, что данный уровень владения програмирования многово стоит и ВАМ БОЛЬШОЕ СПАСИБО, что помогли.
    Да и ещё, вот эта ветка ::
    if(!vesUpdated)
    return;
    vesUpdated =false;
    с ней работа не получается, не знаю почему, шаговик не работает. Ее убрал и вроде бы все заработало.
     
  8. DIYMan

    DIYMan Guest

    Потому что этот флаг надо устанавливать тогда, когда вес изменился. Тогда не будет лишнего и совершенно ненужного дёрганья setPeriod. И, ЕСТЕСТВЕННО, до этой проверки надо шагать шаговиком:
    Код (C++):

    void Timer1_action()
    {
    // ВОТ ТУТ ШАГАЕМ ШАГОВИКОМ!!!!!!!!!

    if(!vesUpdated)
        return;

        vesUpdated = false;

        if (ves > 50 && ves < 100)
        {
            // ставим среднюю скорость, когда вес в диапазоне (50,100)
            Timer1.setPeriod(200);
        }
        else if(ves >= 100)
        {
            // ставим маленькую скорость, когда вес в диапазоне [100,бесконечность)
            Timer1.setPeriod(400);
        }
        else
        {
            // ставим быструю скорость, когда вес в диапазоне [0,50]
            Timer1.setPeriod(100);
        }

    }
     
  9. Valik

    Valik Нерд

    Добрый вечер, подскажите еще один момент, когда вес находится в этом диапазоне от 100 грамм скорость уменьшается, но когда вес превышает 150 грамм шаговик не останавливается и продолжает работать.
    else if (ves >= 100 && ves <=150) { // ставим маленькую скорость, когда вес в диапазоне, по идеи шаговик должен остановится при выходе за граници указанного веса?
    Timer1.setPeriod(400);

    Я конечно данную команду удалил бо после преодаления 150 грамм шаговик переходил на быструю скорость.

    В этом коде я указал аппаратное отключение ШД:
    else if (ves >= 150){
    digitalWrite(enPin, HIGH), //принудительно выключает шаговик подовая высокий сигнал.
     
  10. DIYMan

    DIYMan Guest

    Таймер кто останавливать будет, когда шагать не надо?
     
  11. Valik

    Valik Нерд

    Я даже не знаю. Все завязано на одной переменной - "ves". Можно как либо остановить таймер при достижении заданной величины "ves"? Допустим 200грамм, а потом кнопкой запустить.
     
  12. DIYMan

    DIYMan Guest

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

    Открываем вот это: https://github.com/PaulStoffregen/TimerOne/blob/master/TimerOne.h - и видим, что там есть методы start, stop, resume - их названия о чём-то вам говорят?
     
  13. Valik

    Valik Нерд

    Вы совершенно правы, сейчас вы были для меня подсказкой, палочкой выручалочкой - за что вам ОГРОМНОЕ СПАСИБО. Я не знаю, что бы я делал, если бы вы не помогли. Я далеко не програмист и вникать в "высшие материи" без навыков и знаний, это ..., это..., это..., даже слов нет. :confused:.
    С Божьей помощью, собрал своими руками кофе обжарочную машину, собирал полностью с нуля. Сначала на 2кг, после на 5кг, после на 12кг закладки. Научился жарить кофе без учителя и наставников, конечно кг 50 кофе попросту испортил.
    Когда фасовать руками устал, решил что нужно сделать дозатор. Купить его конечно можно как и кофемашину - но цены просто космос. Да и точность дозировки у них храмает +- 10грамм, что не очень то и гуд.
    И тут как раз есть ардуино, шаговик и руки, а вот мозгов для програмирования нету. Куда идти, куда податся? Вот и пришел сюда.
    Спасибо, будет чем на досуге занятся.
     
  14. DIYMan

    DIYMan Guest

    Для начала - надо почитать/посмотреть основы программирования. Лучшим вариантом будет - почитать. Потом - потихоньку учиться разбираться и читать документацию и заголовочные файлы к библиотекам. Попутно - настраивая мозг на программистское мышление. И всё получится, со временем. Единственное, чего вот точно не стоит делать - это браться сразу за более-менее сложные проекты, обманувшись кажущейся лёгкостью освоения платформы.

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

    Код (C++):
    // читаем с датчика
    // если значение в диапазоне 0-100, то
    // включаем светодиод,
    // уменьшаем скорость шагания.

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

    Применительно к вашей задаче этот псевдокод выглядит так:

    Код (C++):
    int weight = 0; // вес предмета
    bool isTimerRunning = false; // флаг того, что двигатель шагает

    void timerAction() // обработчик тика таймера
    {
        // шагаем двигателем
        stepper.step();
    }

    void setup()
    {
        // настраиваем таймер
        timer.initialize(100);
        timer.attachInterrupt(timerAction);
     
        // запускаем таймер
        isTimerRunning = true;
        timer.start();
    }

    void loop()
    {
        // получаем текущий вес
        int currentWeight = getWeight();
     
        if(currentWeight != weight) // вес изменился, надо проанализировать, что сделать
        {
            weight = currentWeight; // сохраняем текущий вес
         
            if(weight < 50) // слишком маленький вес, надо остановить двигатель
            {
                isTimerRunning = false;
                timer.stop();
            }
            else if(weight < 100) // вес в диапазоне 50-99
            {
                // надо установить быструю скорость
                timer.setPeriod(100);
            }
            else if(weight < 200) // вес в диапазоне 100-199
            {
                // надо установить среднюю скорость
                timer.setPeriod(200);
            }
            else if(weight < 500) // вес в диапазоне 200-499
            {
                // надо установить маленькую скорость
                timer.setPeriod(400);
            }
        }
     
        // обрабатываем нажатие условной кнопки
        if(button.isClicked())
        {
            // кнопку кликнули. Допустим, у нас по клику кнопки надо запускать двигатель,
            // а по повторному клику - останавливать.
            if(isTimerRunning)
            {
                isTimerRunning = false;
                timer.stop();
            }
            else
            {
                isTimerRunning = true;
                timer.start();
            }
        }
    }
    Вот и вся ваша задача, собственно. Осталось только чуть подправить наполнение - и алгоритм будет работать, реагируя на смену веса. Ну и плюс ещё на кнопку реагировать ;)

    Такие дела, короче.
     
    DetSimen нравится это.
  15. parovoZZ

    parovoZZ Гуру

    не проще ли сразу блоками нарисовать? Гораздо нагляднее.
     
  16. DIYMan

    DIYMan Guest

    Ну рисую я диаграммы UML иногда - дык джуниоры часто просто не вдупляют, совсем. Хотя и картинка. А вот ткнуть в псевдокод, пущай учатся читать именно код, а не картинки - лучше доходит ;)
     
  17. DetSimen

    DetSimen Guest

    Джуниоры, закончившие профильный ВУЗ, зачастую даже в псевдокод не вдупляют ( многараз в жизни встречался с таким). В таких случаях, я всегда советовал съездить в судмедэкспертизу при областной больнице, и купить себе мозг, чтобы хотькакойнить был.
     
    DIYMan нравится это.
  18. parovoZZ

    parovoZZ Гуру

    UML это что? Есть же стандартные блоки алгоритмизации.
     
  19. DetSimen

    DetSimen Guest

    это унифицированный язык моделирования. каждый IT скудент, мнящий себя будущим говнокодером, должен знать его на 3+ хотя бы.
     
    DIYMan нравится это.
  20. DIYMan

    DIYMan Guest

    Паровоз, ты меня удивляешь. UML стандартнее некуда, тащемта. На всякий случай оставлю это здесь: https://ru.wikipedia.org/wiki/UML