ARDUINO Кинетический стол

Бронников Юрий

✩✩✩✩✩✩✩
17 Фев 2025
1
0
Всем привет.
Попалось в интернете видео и люто захотелось сделать такое:
Ссылка в ВК-видео
Реверс-инженеринг: Ардуино, шаговики и сопутствующие. По форме понятно, что использована полярная система координат. Хотя можно и сложную систему ремней/роликов придумать. Я решил что будет проще заставить один шаговик вращаться. Поэтому сделал так:
photo_2025-02-17_21-12-21.jpg
Щетки-кольца. Работает норм (пришлось малость притирать, но норм. Пропусков шагов нет).
Как выставить рейку в нулевое положение тоже проблем не возникло. Оптический концевик на "барабан" и геркон на "рейку". Чтоб не "брякали" как механические.
Встал вопрос: а как красоту рисовать? Про китов как в видео пока не мечтаю. Но что-то простенькое хочу реализовать. Типа закинул уравнение и получил рисунок.
hello_html_m445dc78b.png
Не могу найти подход в Сашкиной библиотеке. Явно туплю где-то.
Прошу ткнуть носом.
Проектом занимаюсь уже года полтора по часу в месяц.
Код:
C++:
/*
   рейка 27800 шагов
   как ограничить ход рейки в обе стороны??? Герконами?
*/
#define PINR 7   // концевик угла
#define PINF 10   // концевик радиуса

#include "GyverPlanner.h"
Stepper<STEPPER2WIRE> stepper1(6, 3);
Stepper<STEPPER2WIRE> stepper2(5, 2);
GPlanner<STEPPER2WIRE, 2> planner;
float r = 1;
float f = 1;
long target[2] = {0, 0};              // 0 = барабан, 1 = рейка
uint32_t myTimer1;

void setup() {
  Serial.begin(115200);
  pinMode(11, OUTPUT);
  pinMode(PINF, INPUT_PULLUP);
  //добавляем шаговики на оси
  planner.addStepper(0, stepper1);    // барабан
  planner.addStepper(1, stepper2);    // рейка
  planner.setAcceleration(0);         // ускорение
  planner.setMaxSpeed(3000);          // максимальная скорость
  planner.setSpeed(0, 3000);
  planner.setSpeed(1, 3000);
  beginning();                      // стартовая функция - устанавливает шар в центр поля
}
void loop() {
  planner.tick();
  // if (Serial.available() > 0) {    // если пришли данные
  //   incomingByte = Serial.read();  // считываем байт
  // }
  cleaning ();
  //test2 ();
  //test3 ();
}
void test3() {
  planner.tick();
  if (digitalRead(PINF))planner.setSpeed(0, 3000);
  else   planner.setSpeed(1, 3000);
  Serial.println ("test3");
}

void test4() {

  if (millis() - myTimer1 >= 1000) {   // ищем разницу (500 мс)
    myTimer1 = millis();              // сброс таймера
    planner.setSpeed(0, -3000);
  }
  else {
    planner.setSpeed(0, -3000);
  }
  Serial.println ("test4");
}
void test2() {
  target [0] = 10000;
  target [1] = 3200;
  //global (target);
}

void cleaning() {   // сделано - подобрать количестко оборотов
  //if (millis() - myTimer1 >= 500) {   // ищем разницу (500 мс)
  // myTimer1 = millis();              // сброс таймера
  for (f = 0; f < 12800000 ; f++) {   //подобрать экспериментально или высчитать
    r = f/10; // уравнение
    global (f, r);
  }
  //}
}
//основная функция, которой передаются значения уравнений, здесь нужно задать максимальные и минимальные значения, или не здесь
void global (float a, float b) {  //нужно сообщать не точку, а отклонение?
  //if (planner.getCurrent(0) < 27800) {
  Serial.print (planner.getCurrent(1));
  Serial.print ("---");
  planner.tick();
  long target[] = {a, b};
  //target[1] = b;
  Serial.print (a);
  Serial.print ("//--/--//");
  Serial.print (planner.getCurrent(0));
  Serial.print ("---");
  Serial.println (b);
  if (planner.ready()) {
       planner.setTarget(target);
  }
}
void beginning() {      // стартовая функция - устанавливает шар в центр поля
  digitalWrite(11, HIGH);             // включаем светодиод
  if (analogRead(PINR) > 300) {       // если оптический концевик не нажат
    while (analogRead(PINR) > 300) {  // пока не нажат
      planner.setSpeed(0, 200);       // крутим барабан
      planner.tick();                 // крутим
      Serial.println (analogRead(PINR));
    }
    // концевик сработал - покидаем цикл
    planner.brake();                  // тормозим, приехали
  }
  digitalWrite(11, LOW);              // выключаем светодиод

  if (digitalRead(PINF)) {            // если геркон не сработал А если магнит в другой стороне????
    planner.setSpeed(1, -1500);       // толкаем рейку
    while (digitalRead(PINF)) {       // пока геркон молчит
      planner.tick();                 // толкаем
      Serial.println ("2");           // смотрим в мониторе
    }
    // кнопка нажалась - покидаем цикл
    planner.brake();                  // тормозим, приехали
  }
  planner.reset();    // сбрасываем координаты в 0
}
Тему создаю впервые. Если есть вопросы к оформлению, прошу пинать посильнее.
 
Изменено:

Bruzzer

★★★✩✩✩✩
23 Май 2020
515
152
Типа закинул уравнение и получил рисунок.
Наверно лучше начать с программного рисования. Гайвер зачастую отрабатывает алгоритмы, рисуя в Processing, но если знаете другие среды, то можно в них.
Перенести это потом на МЕДЛЕННОЕ рисование на ваше железо, ВРОДЕ не сложно.
Оптимизированное рисование железом, фактически выливается в написание собственного софта для 3D принтера в полярных координатах. И сделать это "с нуля" наверно не очень реально.
 
  • Лойс +1
Реакции: Юрий Саныч

poty

★★★★★★✩
19 Фев 2020
3,288
952

@Юрий Саныч, вся информация есть:
  • нулевая позиция по радиусу и углу;
  • шагов/расстояние, шагов/угол.
Далее - только обычная пропорция: задаёмся углом, вычисляем количество шагов по углу от текущего положения, вычисляем по формуле радиус, вычисляем количество шагов по радиусу от текущего положения.