arduino 28BYJ-48 stepper только жужжит, не вращается

Edit, на этот вопрос ответил крисл в комментариях, а также после повторного тестирования кода с delay (), который показал, что я забыл обновить свою переменную lastupdate(eerst), я ответил на него в комментариях, и крисл, возможно, также опубликует свои выводы в ответе TLDR - 28BYJ-48 униполярный 5в не работает только ноет. запустите с помощью транзисторов и кода в нижней части поста. транзисторы, подключенные к 5 В, и резисторы в диапазоне от 100 Ом до 1000 Ом пытались от Arduino до транзисторов триггера/затвора. - КОНЕЦ TLDR

Более подробно У меня есть несколько однополярных шаговых двигателей 5v и 12v 28BYJ-48,(я подключаю только один к Arduino за раз) общий(проверенный с помощью измерителя сопротивления) подключен к +, а остальные контакты подключены к одному транзистору BC336 на вывод, так что всего 4. эти транзисторы должны обрабатывать 0,8 А за штуку, и я измерил максимальную силу тока, используемую катушками, чтобы быть 0,2+-0,02 А для версии 5 В при 5 В и 0,045 +- 0,001 А для версии 12 В при 5 В. Это имеет смысл, если версия 12 В не работает при 5 В, я просто хотел чтобы проверить его, нужно иметь шаговый двигатель сверхмалой мощности. однако версия 5v должна работать, моя установка допускает более высокое падение напряжения в катушках двигателя и может выдерживать более высокую силу тока, чем обычный драйвер, однако это ограничено сопротивлением двигателя ofcource. Я веду его в соответствии с шагами в таблице данных стандартным методом. и упростил свой код, чтобы исключить все лишние вещи и даже жестко закодировать значения, но все равно он только временно и не запускает двигатель. Я использую Arduino 5v для запуска шагового двигателя, но согласно таблице данных и моим измерениям, вы можете управлять более чем одним шаговым двигателем на выводе 5v, даже при работе от USB-питания. Я также установил его очень медленно, чтобы он работал(на основе таблицы данных). Я хочу, чтобы это работало так, потому что я работаю над пользовательским бюджетным шаговым драйвером для Arduino, который позволяет гораздо проще управлять, и который намного дешевле, чем текущие драйверы, а также то, что он по умолчанию может запускать шаговые двигатели более высокого напряжения, а также одну очень специфическую функциональность, которую почти все, кто когда-либо использовал один шаговый двигатель или несколько надеялся, что их драйвер шагового двигателя был.

Я использовал контакты 8 9 10 и 11 Сломанный код:

unsigned long eerst=0;
unsigned long nu=0;
int state=0;
byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//сделал hardcoderd aray, чтобы убедиться, что ошибка не была в циклическом сдвиге битов

void setup() {
  //0b76543210 portD <-- direction right is low num left is high num, продолжайте путать это, так как оно отличается на некоторых платформах и некоторое время не использовало arduino
  DDRB=DDRB | 0b00001111;//только установите 8,9,10, 11 в качестве выхода не меняйте resst.
  PORTB=0b00000000;//упрощено от поворота только 8,9,10,11 до поворота всей
  delay(1000);
  eerst=millis();
}

void loop() 
{
  nu=millis();
  if(nu-20>=eerst)
  {

//забыл обновить здесь PORTB=vals[состояние]; состояние++; if(state>7)//сбрасывает состояние { состояние=0; } } }

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

unsigned long TimeOfLastStep=0;
unsigned long CurrentTime=0;
int step=0;
byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//сделал hardcoderd aray, чтобы убедиться, что ошибка не была в циклическом сдвиге битов

void setup() {
  DDRB=DDRB | 0b00001111;//только установите 8,9,10, 11 в качестве выхода не меняйте resst.
  PORTB=0b00000000;
  CurrentTime=millis();
}

void loop() 
{
  CurrentTime=millis();
  if(CurrentTime-2>=TimeOfLastStep)//увеличена скорость с задержки 20 мс до 2 мс
  {
    TimeOfLastStep=CurrentTime;//забыл это
    PORTB=vals[state];
    state++;
    if(state>7)//сбрасывает состояние
      {
        state=0;
      }
  }
}

, 👍0

Обсуждение

Я думаю, что "eerst" должен быть переменной метки времени. Вам нужно установить это внутри оператора if. В настоящее время вы работаете так быстро, как может Arduino, вероятно, слишком быстро для двигателя. Кроме того, вы должны обработать строку оператора if в примере BlinkWithoutDelay if(nu - eerst >= 20). Затем внутри оператора if сделайте eerst += 20;. Пожалуйста, проверьте это. Я напишу ответ, если это решит проблему, @chrisl

да, вы правы, вскоре после публикации я тоже увидел проблему, и мои тайминги были такими, так как я предполагал 100 шагов за вращение, так что движение было бы очень медленным, если бы оно что-то сделало. Так что теперь я знаю, что мне не удалось: это был один из тех типичных случаев, когда вы что-то думаете и думаете напечатать, но потом забываете, что на самом деле еще не напечатали., @TeD van Loon

@chrisl Вы хотите отредактировать его непосредственно в операторе if, как вы это делаете в цикле for? или вы имеете в виду то, что касается порядка размещения переменных для неблокирующего кода, чтобы предотвратить зависание кода или неправильное поведение/пропуск, когда беззнаковое длинное переворачивается(передается его максимальное значение). если это так, то это было бы очень полезно и почему/какое значение, чтобы использовать его для бесконечных сумм без необходимости перезапуска, чтобы предотвратить возможные проблемы., @TeD van Loon

@chrisl то, что вы имеете в виду во втором случае, это if(nu-eerst>=2), а не if(nu-2>=eerst). верно? Я проверил это с помощью некоторой математики, и мой драгоценный код действительно не был доказательством опрокидывания(странное поведение, когда вы выходите за пределы максимального значения беззнаковой переменной и возвращаетесь к самому низкому., @TeD van Loon


1 ответ


2

Я нашел проблему(ы) в своем дизайне, все было правильно, но я забыл добавить eerst=nu;(first=now;, использовал другой язык, потому что теперь используется arduino ide). Кроме того, я не читал таблицу данных должным образом и поэтому предположил, что 100step/revolution заставляет меня использовать задержки, которые где-то велики, и поэтому, даже если бы это сработало, движение было бы очень медленным и, возможно, пропущенным.

Новый рабочий код:

unsigned long eerst=0;
unsigned long nu=0;
int state=0;
byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//сделал hardcoderd aray, чтобы убедиться, что ошибка не была в циклическом смещении битов.
//в PortB у вас есть контакты 8,9,10,11,12,13. вы начинаете с конца байта, так что если 0b00000001, то включен только вывод 8. если 0b00000010, то горит только вывод 9, если 0b00000011, то горят выводы 8 и 9. PortB имеет 8 бит, но только 6 устанавливаемых выводов, поэтому не меняйте первые 2 бита. это должно быть сделано при использовании порта D, так как он подключен к последовательному порту. однако для простоты я не добавил этот код сюда, вы можете попросить его, и я, вероятно, отвечу на него.

void setup() { since it differs on some platforms and not having used arduino for a while
  DDRB=DDRB | 0b00001111;//только установите 8,9,10, 11 в качестве выхода не меняйте resst.
  PORTB=0b00000000; // отключение всех выходов порта B
  eerst=millis();//eerstm означает first, установить first в milis, чтобы иметь задержку без приостановки кода.
}

void loop() 
{
  nu=millis();//nu is now, store это позволяет коду знать, как долго arduino работал в миллисекундах, необходимых для неблокирующей задержки, нужен только один now/nu.
  if(nu-2>=eerst)// если прошло 2 миллисекунды(было ожидание), выполните следующий код.
  {
    eerst=nu;//сброс неблокирующего таймера задержки
    PORTB=vals[state];//Жестко закодированные значения в массиве выше, это включает и выключает контакты и намного быстрее, чем цифровая запись, выбирает элемент под номером [state] aray.
    state++;//перейти к следующему состоянию/шагу
    if(state>7)//сбрасывает состояние
      {
        state=0;//сбрасывает состояние/возвращается в состояние 0(1 из 8)
      }
  }
}

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

,

У меня работает мой новый драйвер, в настоящее время мой текущий дизайн стоит около 15 центов, чтобы сделать себя любителем, и он позволяет гораздо больше, чем традиционный драйвер, а также то, что он может управлять 2 шаговыми двигателями отдельно и не требует столько контактов. однако мне все еще нужно провести некоторые тесты и немного улучшить вещи, чтобы повысить эффективность и тому подобное, особенно когда вы заменяете детали на пользовательские детали. в настоящее время он примерно такой же мощный на двигатель, как и обычный драйвер, но в ходе тестов я обнаружил, что могу достичь гораздо большей эффективности, чем оригинальный., @TeD van Loon

с моей нынешней настройкой я мог бы сделать рабочую литографическую машину за €1,65(исключая arduino). В этом дизайне я использую металлолом для таких вещей, как рамка и объектив, точность ультрафиолетового луча может быть изменена только вручную в этом дизайне, я рассчитал его, используя цены, которые я заплатил за детали, это исключает доставку, и я получил детали в больших количествах, однако я также включил детали в эта цена, которую вы, вероятно, уже имеете, лежит вокруг, как резисторы, транзисторы, конденсатор для стабилизации мощности и т. Д. Я ожидал, что у одного будут кабели. Я, наверное, опубликую, как сделать эту штуку., @TeD van Loon