ARDUINO Наливатор. Обсуждение проекта

Anatolyj

★✩✩✩✩✩✩
30 Янв 2020
134
16
Собрал наливатор, крайняя прошивка от Levonti. Странное поведение сервы. Ставлю первую рюмку нажимаю налить, серва едет к первой рюмке, тутже возвращается к 4-ой и там наливает, ставлю 4-ю рюмку серва уезжает в стороню не намного и возвращается к четвертой и наливает, аналогично со второй и третьей рюмкой, т.е. налив идет постоянно в последнюю рюмку

Серва приходит в определенную позицию и вместо того, чтобы наливать в этой позиции уходит в 0 и там начинает наливать. Где поправить в прошивке от Levonti. Пробовал ставить новый скетч от Гайвер, подпихивал ноувую библиотеку все работает правильно. Но уменя уже корпус по лсд напечатан. Где поправить в прошивке от Levonti эту проблему
 

Obormot

✩✩✩✩✩✩✩
17 Дек 2019
2
2
Хочу заменить серву на шаговый двигатель 24BYJ48 с модулем ULN2003A (очень уж плавно и без тряски работает по сравнению с сервой). Отдельно скетч сделал с помощью библиотеки AccelStepper, но ввиду слабого понимания в программировании не могу четко понять как полностью исключить из кода серву, а вместо нее воткнуть код для управления шаговиком. Может кто-нибудь подскажет?
 
  • Лойс +1
Реакции: konoev и slavikslk

дрим93

✩✩✩✩✩✩✩
16 Ноя 2018
34
3
Подскажите где Проблема может быть,всё загрузил вроде всё хорошо,на ручном режиме выставляю 4 рюмки сразу нажимаю кнопку и разливает не по центу рюмок,либо вообще мимо рюмок,если ставлю по 1 рюмке наливает правильно,куда копать?
Если на автомате ставлю иногда хорошо наливает,но бывает и мимо как на ручном режиме
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,227
1,292
Москва
@Obormot, Как минимум 2 человека знают как использовать этот шаговик вместо сервы. Но я подключил концевик для него криво и надо переделывать модель для 3д принтера, поэтому пока не готов что то выкладывать - не опробовал толком.
Если в 2-х словах, то надо искать servo.write(pos) и менять на управление шаговиком с заданной дельтой угла (или углом) и направлением.
Так же есть определенная сложность в том, что не известно положение в конкретный момент. Т.е. рассчитать его можно, но гарантированное обнуление будет только если вернуть шаговик в нулевое положение.
Все это выбивается из привычной для сервы работы. указать угол и забыть обо всем
 
  • Лойс +1
Реакции: Obormot

VICLER

★★★★★★✩
9 Дек 2019
801
660
Hamburg
@Obormot, сейчас работаю над этим как появляется свободное время. Сначала хотелось бы корпус полностью собрать, а потом уже писать код.
На данный момент написал пока неплохую библиотеку для работы с шаговиком при помощи драйверов со STEP/DIR управлением (любой типа A4988, DRV8825 или TMC2100, TMC2208 и тд.). Пришлось писать, так как не нашёл ничего толкового. Все библиотеки, что находил, не позволяли управлять шаговиком как серводвигателем. В итоге управление получилось быстрее и точнее чем у аналогов. В принципе концевик тут даже не обязателен. Можно например рукой поставить кран в парковочное положение перед включением либо после включения отправить шаговик в сторону парковки на время, за которое он проходит от одного конечного положения до другого ну и подождать. Во втором варианте правда кран может биться о борт некоторое время.
 
  • Лойс +1
Реакции: Obormot

Старик Похабыч

★★★★★★★
14 Авг 2019
4,227
1,292
Москва
Биться о борт.. и еще клюшкой по репе. Не, это не наш метод :)
Самое интересно, что AsyncStepper имеет переменную _currentStep , но приватную. Она показывает текущий угол, но опять же по часовой стрелке! А серва работает в математической системе, т.е. против. И эта самая _currentStep НЕ инициируется, т.е. нулевое положение задается созданием переменной и начальным положением вала.
Попробую сегодня переписать... нет, Внести корректировку в библиотеку так, что бы она могла работать именно как серва. Это именно для стандартного комплекта с ULN2003A .
А придет драйвер - буду ждать посмотреть. что напишет @VICLER, чего два раза одно и то же писать ? и не факт , что лучше :)
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,227
1,292
Москва
Ну даже что то получилось. Прикрепил архив - это та же библиотека , но с добавленными несколькими функциями. Старые функции все без изменений.
Ниже в примере подключен шаговик при помощи ULN2003A на мины 8,9,10,11
На пин 2 подключен концевик, на нем же недолго (только в сетапе) висит прерываение. Считается, что концевик справа от вала, т.е. система отсчета угла математическая.
Как только концевик замыкает , то вал отворачивается от него на 2 градуса и это положение объявляется нулевым, все отсчеты будут от этого положения высчитываться. Далее вал поворачивается на угол 90 градусов, используя стандартную процедуру write и далее в цикле после завершения движения идет пауза (да, использую delay, это же пример) идет перемещение вала к случайному углу от 0 до 270 градусов. Движение сервы исключительно в первых 3-х четвертях.
Пример - измененный стандартный пример библиотеки.
Добавленные функции:
unsigned int GetCurrentAngleMath() const; - выдает угол в мат. СК , целое число, несмотря на то, что можно определять точнее. но для эуляции сервы так проще.
unsigned int GetGoalStep() const; - выдает число шагов для завершения работы. как только тут 0, то движение вала завершается.
void SetZerro(); - устанавливает текущее положение вала как 0
void Write(unsigned int angle); - аналог функции сервы, задает новый угол.

C++:
/***************************************************
  Copyright (c) 2017 Luis Llamas
  (www.luisllamas.es)

  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License
****************************************************/

#include "AsyncStepperLib.h"
#include <Stepper.h>

const int motorPin1 = 8;
const int motorPin2 = 9;
const int motorPin3 = 10;
const int motorPin4 = 11;
const int numSteps = 8;
const int stepsLookup[8] = { B1000, B1100, B0100, B0110, B0010, B0011, B0001, B1001 };
int stepCounter = 0;


bool is_stop = false;

void clockwise()
{
  stepCounter++;
  if (stepCounter >= numSteps) stepCounter = 0;
  setOutput(stepCounter);
}

void anticlockwise()
{
  stepCounter--;
  if (stepCounter < 0) stepCounter = numSteps - 1;
  setOutput(stepCounter);
}

void setOutput(int step)
{
  digitalWrite(motorPin1, bitRead(stepsLookup[step], 0));
  digitalWrite(motorPin2, bitRead(stepsLookup[step], 1));
  digitalWrite(motorPin3, bitRead(stepsLookup[step], 2));
  digitalWrite(motorPin4, bitRead(stepsLookup[step], 3));
}

const int stepsPerRevolution = 4076;
AsyncStepper stepper1(stepsPerRevolution,
[]() {
  clockwise();
},
[]() {
  anticlockwise();
}
                     );

void rotateCW()
{
  delay(1000);
  stepper1.Rotate(30, AsyncStepper::CW, rotateCCW);
}

void rotateCCW()
{
  delay(1000);
  stepper1.Rotate(30, AsyncStepper::CCW, rotateCW);
}

void StopStepper()
{
  if (is_stop) return;
  stepper1.Stop();
  is_stop = true;
  detachInterrupt(0);
}

void setup()
{
  Serial.begin(115200);

  pinMode(2, INPUT_PULLUP);

  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);

  attachInterrupt(0, StopStepper, FALLING );

  stepper1.SetSpeedRpm(12);
  stepper1.RotateContinuos(AsyncStepper::CW);



  while (!is_stop) {stepper1.Update();};

  Serial.println("Stop");
  Serial.println(stepper1.GetCurrentAngleMath());

  stepper1.Rotate(2, AsyncStepper::CCW);

  while (stepper1.GetGoalStep()>0) {
    stepper1.Update();
  };

  stepper1.SetZerro();
  Serial.print("Zerro="); Serial.println(stepper1.GetCurrentAngleMath());

  stepper1.Write(90);
}



void loop()
{
  if (stepper1.GetGoalStep()>0)
    {
    stepper1.Update();
    }
  else
    {
      delay(1000);
      uint16_t new_ugol=random(0,270);  
      Serial.print("Go to ");Serial.println(new_ugol);
      stepper1.Write(new_ugol);
    }
}

Может данный пост и выбивается несколько из темы, но отношение к ней имеет непосредственное


А так можно сделать без использования аппаратного прерывания , на любом пине. в данном случае на 7-ом, меняется только setup
C++:
void setup()
{
  Serial.begin(115200);
  opStepper, FALLING );

  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);



  stepper1.SetSpeedRpm(12);
  stepper1.RotateContinuos(AsyncStepper::CW);


  pinMode(7, INPUT_PULLUP);
  while (digitalRead(7)) {
    stepper1.Update();
  };

  Serial.println("Stop");
  Serial.println(stepper1.GetCurrentAngleMath());

  stepper1.Rotate(2, AsyncStepper::CCW);

  while (stepper1.GetGoalStep() > 0) {
    stepper1.Update();
  };

  stepper1.SetZerro();
  Serial.print("Zerro="); Serial.println(stepper1.GetCurrentAngleMath());

  stepper1.Write(320);
}
 

Вложения

  • 2.3 KB Просмотры: 25
Изменено:

VICLER

★★★★★★✩
9 Дек 2019
801
660
Hamburg
@Старик Похабыч, вот дело уже пошло)
я сегодня тоже немного допилил библиотеку. Сделал пару примеров. Вот один с концевиком для обнуления позиции, может кому-нибудь понадобится:
C++:
#include "StepMot.h"

#define STEPS_PER_REVOLUTION 2037.88642 // 28BYJ-48 geared stepper motor
#define MICROSTEPS  1
#define STEP_PIN  16
#define DIR_PIN   10
#define EN_PIN    14

#define ENDSTOP_PIN 7 // концевик с активным низким уровнем

StepMot motor(STEPS_PER_REVOLUTION * MICROSTEPS, STEP_PIN, DIR_PIN, EN_PIN);

void setup() {
  Serial.begin(9600);
  pinMode(ENDSTOP_PIN, INPUT_PULLUP);

  motor.enable();              // подача питания на мотор
  motor.setRPM(5);             // скорость в оборотах в минуту
  motor.rotate(CCW);           // двигаемся в сторону нулевой позиции
  while(digitalRead(ENDSTOP_PIN) && motor.update)) {}    // двигаемся до тех пор, пока не сработает концевик
  motor.resetPos();            // сброс начальной позиции
  motor.setMode(ABSOLUTE);     // режим абсолютного позиционирования.
  motor.setRPM(10);
}

void loop() {

  if(!motor.update()) {       // пришли к цели, отдохнули и задали новую
    uint16_t angle = random(0,360);
    motor.setAngle(angle);
    Serial.print("Цель -> ");
    Serial.println(angle);
    delay(1000);
  }
}
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,227
1,292
Москва
@VICLER, у меня концевик мешает круговому движению - очень уж большой. Сейчас максимум примерно 320 градусов. Для наливатора хватит. Если учесть подводящую трубу , то круговой налив вообще затруднителен, тогда проще задуматься о поворотном столе. Ну а так - суть та же, найти ноль и плясать от него. Что хорошо в моем случае - можно прервать движение и знать я буду знать на каком месте. А так же возможность выполнять другие действия во время движения. На сервоприводе это делалось несколько сложнее, причем там приходилось отключать серву от управления
 

VICLER

★★★★★★✩
9 Дек 2019
801
660
Hamburg
@Старик Похабыч, если поставите концевик горизонтально, то круговому движению мешать не будет. Попробуйте
Да, у шаговика есть свои плюсы. Для меня важнейшим является шум, точнее его отсутствие, а также плавность и точность движений. Единственный минус по сравнению с серво, это отсутствие обратной связи. Но если мотор достаточно мощный для поставленной задачи, то это и не особо нужно, так как можно отслеживать моментальное положение. В StepMot так же реализованно постоянное слежение за актуальным положением и возможность заниматься другими вещами во время движения. В AsyncStepper вообще тоже есть возможность управлять StepStick подобными драйверами, правда там это как-то криво и с ошибками реализованно, что в итоге ничего не работает.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,227
1,292
Москва
@VICLER, Горизонтальное размещение сразу увеличивает либо габариты , либо высоту над мотором. И того и другого хотелось бы избежать. Но подумаю, порисую как бы это выглядело, спасибо.
PS. Вспомнил про кнопку в убитой нано. Можно ее приспособить и она достаточно мелкая!
 
Изменено:

RomaT

★✩✩✩✩✩✩
5 Ноя 2019
104
38
Притулите на ось шаговика переменной сопротивление, не сложно сделать, считывайте через аналоговый вход состояние и получите обратную связь, типа эмуляция серво.
Занялся бы, но времени сейчас нет(
И не забывайте с шаговика снимать напругу как только это можно. Под напругой он начинает жрать и греться.
 

VICLER

★★★★★★✩
9 Дек 2019
801
660
Hamburg
@RomaT, если уж так нужна обратная связь, я бы лучше взял цифровой абсолютный энкодер типа AS5600. Выход с энкодера может быть либо аналоговый либо цифра i2c. Точность гораздо выше, никакой дополнительной нагрузки на мотор. Если i2c то экономится ещё один выход, итого три dir, step, enable. Концевик естественно не нужен.
Отключать питание нужно обязательно. Пока не замерял потребление, но где-то читал, что около 300mA от 5V. Сначала думал может просто включать только тогда, когда именно нужно крутить мотор, в остальное время отключать, но возможно, что шланг будет смещать кран при отключении питания. Тесты ещё покажут. Возможность автоматического отключения питания в библиотеку добавил на всякий случай.

Upd: вспомнил про потенциометры с отверстием. В принципе довольно просто получится. Просто надеть на вал и приклеить.

1412321750-292667701.jpg
 
Изменено:

RomaT

★✩✩✩✩✩✩
5 Ноя 2019
104
38
@VICLER, энкодер это хорошо, но тогда и так не дешевый проект становится ещё дороже)
Кстати спасибо за наводку, почитаю что за хрень, может на координатник прикручу как нибудь, очень хочется обратную связь поиметь, задолбался фрезы ломать(
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,227
1,292
Москва
Есть вот такой "датчик" по сути потенциометр, но у него ограничен угол поворота.

Если после налива возвращать "носик" в нулевую точку, то выключать будет легче. Оставил дергающийся мотор примерно на час . Был ощутимо теплый, но не горячий. При этом он всегда двигался по скетчу. движение, секундная пауза , новое движение.
 

VICLER

★★★★★★✩
9 Дек 2019
801
660
Hamburg
@VICLER,@Старик Похабыч, а насколько толстый этот потенциометр?
Я вот у себя нашёл такой:
IMG_20200324_214714.jpg
Ход 260 градусов
но он толстоватый. Тогда нужно крепление делать иначе. Может нарезать резьбу в валу.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,227
1,292
Москва
4 мм , это с платой, общий размер 25 на 13

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

Хирург

✩✩✩✩✩✩✩
17 Мар 2020
12
7
Здесь не чат. Сообщения можно редактировать
Притулите на ось шаговика переменной сопротивление, не сложно сделать, считывайте через аналоговый вход состояние и получите обратную связь, типа эмуляция серво.
Занялся бы, но времени сейчас нет(
И не забывайте с шаговика снимать напругу как только это можно. Под напругой он начинает жрать и греться.
В STEP/DIR драйверах используется 3 сигнала:
  • STEP – импульс, который инициирует поворот на шаг/часть шага в зависимости от режима. От частоты следования импульсов будет определяться скорость вращения двигателя.
  • DIR – сигнал, который задает направление вращения. Обычно при подаче высокого сигнала производится вращение по часовой стрелке. Этот тип сигнала формируется перед импульсом STEP.
  • ENABLE – разрешение/запрет работы драйвера. С помощью этого сигнала можно остановить работу двигателя в режиме без тока удержания.

Экодер можно использовать от поломаной мышки (энкодер колесика)

Но мне вместо энкодеров видится простой концевик (механический или оптический) положения трубки. Он должен быть " нулем" Старт только от нуля с обязательным возвратом на ноль
 
Изменено:

VICLER

★★★★★★✩
9 Дек 2019
801
660
Hamburg
всё же не удержался и собрал прошивку под работу с шаговым двигателем:)
за отсутствием наливатора, проверял прошивку на макетке с подключенным шаговиком. Всё работает отлично!
В основе прошивки оригинальная и чистая версия 1.5 от Алекса. Из изменений только замена сервы шаговиком на драйвере с управлением по STEP/DIR (любой типа A4988, DRV8825 или TMC2100, TMC2208 и тд.). В такой конфигурации прошивка занимает на 5% меньше постоянной и оперативной памяти.

- подключение драйвера к соответствующим пинам Arduino: ENABLE к пину D2, DIR к пину D4 и STEP к пину D5

- установка парковочной позиции может быть двух видов: автоматическая (с концевиком) и ручная (без концевика)

Есть концевик? подключите его к пину D13

Если нет, то закомментируйте строку #define STEPPER_ENDSTOP 13. Нулевое положение выставляется любой конечностью перед включением устройства. Так же рекоммендуется в таком режиме использовать STEPPER_POWERSAFE OFF

- Сигнал при замыкании концевика можно инвертировать STEPPER_ENDSTOP_INVERT 1

- Направление вращения шагового двигателя так же можно инвертировать программно: INVERT_STEPPER 1

- Установка количества шагов на оборот двигателя STEPS_PER_REVOLUTION (по умолчанию уже стоит 28BYJ-48 мотор на 2037.88642 шагов/оборот )

- Установка микрошага, установленного на драйвере (1, 2, 4, 8, 16. 32..) MICROSTEPS 1

- Функция энергосбережения STEPPER_POWERSAFE. Если включено, питание на мотор будет подаваться только при движении. Приехал к рюмке - отключил питание.

- Установка угла для парковочной позиции: #define PARKING_POS
Для работы прошивки требуется установить библиотеку StepMot
Сама прошивка
тут
 
Изменено:

VICLER

★★★★★★✩
9 Дек 2019
801
660
Hamburg
@Anatolyj, у Вас точно OLED? На oled дисплеях не бывает подсветки, там каждый пиксель светится сам