Шаговый не крутится, если в void loop появляются еще строки
- Войдите на сайт для отправки комментариев
Ср, 19/04/2017 - 17:51
Всем доброго дня. Помогите, пожалуйста разобраться с проблемой. В приведенном ниже скетче, шаговый nema17 не хочет крутится, а просто жужжит
#include "DHT.h"
#include <AccelStepper.h>
#include <OLED_I2C.h>
AccelStepper Stepper1(1,3,4); //использует пин 3 и 4 для dir и step, 1 - режим "external driver"
OLED myOLED(8, 9, 8); // SDA - 8pin, SCL - 9pin
extern uint8_t RusFont[]; // Русский шрифт
extern uint8_t SmallFont[];
int TempOpen = 29;
int TempClose = 27;
int Rele1 = 7;
int dir = 1; //используется для смены направления
#define DHTPIN 2 // what digital pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);
void setup() {
pinMode(Rele1, OUTPUT);
dht.begin();
myOLED.begin();
digitalWrite(Rele1, LOW);
Stepper1.setMaxSpeed(700); //устанавливаем максимальную скорость вращения ротора двигателя (шагов/секунду)
Stepper1.setAcceleration(500); //устанавливаем ускорение (шагов/секунду^2)
}
void loop() {
// Wait a few seconds between measurements.
delay(2000);
float h = dht.readHumidity();
float t = dht.readTemperature();
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t)) {
myOLED.clrScr(); // Стираем все с экрана
myOLED.setFont(RusFont);
myOLED.print("Не удается считать показания", LEFT, 0);
return;
}
myOLED.clrScr(); // Стираем все с экрана
myOLED.setFont(RusFont);
// Выводим показания влажности и температуры
myOLED.print("Ntvg= ", 0, 6); // Выводим текст
myOLED.printNumI(t,33,6); // Выводим на экран значение температуры
myOLED.setFont(SmallFont);
myOLED.print("~C", 45, 6);
myOLED.setFont(RusFont);
myOLED.print("Jnrh=", 65, 0); // Выводим текст
myOLED.printNumI(TempOpen, 97, 0); // Выводим текст
myOLED.print("Pfrh=", 65, 13); // Выводим текст
myOLED.printNumI(TempClose, 97, 13); // Выводим текст
myOLED.print("Dkf;=", 0, 26); // Выводим текст
myOLED.printNumI(h,33,26); // Выводим значение влажности
myOLED.setFont(SmallFont);
myOLED.print("%", 45, 26);
myOLED.update();// Обновляем информацию на дисплее
delay(3000); // Пауза 3 секунды
if(t >= TempOpen){digitalWrite(Rele1, LOW);}
if(t <= TempClose){digitalWrite(Rele1, HIGH);}
if(Stepper1.distanceToGo()==0){ //проверка, отработал ли двигатель предыдущее движение
Stepper1.move(15000*dir); //устанавливает перемещение(если dir равен -1 будет перемещаться в противоположное направление)
dir = dir*(-1); //отрицательное значение dir, благодаря чему реализуется вращение в противоположном направлении
delay(1000); //задержка на 1 секунду
}
Stepper1.run(); //запуск шагового двигателя. Эта строка повторяется вновь и вновь для непрерывного вращения двигателя
}
НО если закомментить в void loop строки не относящиеся к шаговому, т.е. оставить только:
if(Stepper1.distanceToGo()==0){ //проверка, отработал ли двигатель предыдущее движение
Stepper1.move(15000*dir); //устанавливает перемещение(если dir равен -1 будет перемещаться в противоположное направление)
dir = dir*(-1); //отрицательное значение dir, благодаря чему реализуется вращение в противоположном направлении
delay(1000); //задержка на 1 секунду
}
Stepper1.run(); //запуск шагового двигателя. Эта строка повторяется вновь и вновь для непрерывного вращения двигателя
то шаговый крутится как надо. Даже если расскомментить чтение температуры float t = dht.readTemperature();, то шаговый начинает странно крутится, с паузами. Если у кого есть мысли, подскажите плз, направьте. Сам только начал изучать ардуино
Не работал с библиотекой AccelStepper, но, очевидно, надо как минимум избавляться от всех delay...
Может как то по другому работать с шаговым? У меня nema17 через drv8825, в дальнейшем вообще планирую 2 таких шаговых подключить к одной ардуино.
Всем доброго дня. При чтении float t = dht.readTemperature(); шаговый не крутится как надо, может есть у кого мысли как их разнести? Я начал использовать millis, т.е. разнес по времени чтение даных с датчиков, вывод данных на экран и сам шаговый. Все стало норм, шаговый крутится как надо. Но, мне нужно создать условие для старта шаговика в зависимости от темп и если я в этом условии использую переменную t считанную ранее в отдельной ф-ии millis, то такой код даже не компилится, ругается на переменную t. Т.е. мне ее снова нужно читать в ф-ии millis используемого для шаговика, а это снова приводит к странной работе шаговика.В программировании не силен, может есть идеи как применять переменную tсчитанную в одном из millis в разных функциях millis (наверное правильнее это называется так: как сделать t глобальной переменной)
Объявить её вверху, до setup(), где уже есть объявленные переменные float t;.
А в коде уже используете t = dht.readTemperature();
Ну и тут , наверное, почитать будет полезно.
Ну при использовании t = dht.readTemperature(); это же опять обращение к датчику и чтение его данных, поэтому двигатель опять будет заикаться на этом моменте.
Вы ж спросили - "как сделать t глобальной" ))
Выше же Вам посоветовали - избавляйтесь от дилэев, их в коде аж на 6 секунд, убирать нужно ВСЕ.
Делайте всё через millis() - с одной периодичностью читайте датчик, с другой управляйте моторами, с третьей обновляйте экран.
Примерно так -
void loop() { static uint32_t prevDmillis = millis(); static uint32_t prevTmillis = millis(); static uint32_t prevDispMillis = millis(); if (millis() - prevDmillis > 200) { prevDmillis = millis(); //Тут раз в 0,2 сек. рулим движками } if (millis() - prevTmillis > 3000) { prevTmillis = millis(); //Тут раз в 3 сек. читаем температуру } if (millis() - prevDispMillis > 500) { prevDispMillis = millis(); //Тут раз в 0.5 сек. обновляем дисплей } }Я так и сделал, но в той периодичности, что управляем двигателями, мне снова приходится читать значение t, т.к. оно почему-то не подтягивается из той периодичности, где уже прочитали датчик (даже не компилится, пока в периодичности с двигателями снова не прочитаю датчик).
Вот нифига не понятно. Покажите код, как сделали, что ли...
OlegK, большое спасибо за ваши комментарии. У меня сейчас нет под рукой своего кода, давайте на вашем покажу:
void loop() { static uint32_t prevDmillis = millis(); static uint32_t prevTmillis = millis(); static uint32_t prevDispMillis = millis(); if (millis() - prevDmillis > 200) { prevDmillis = millis(); //Тут раз в 0,2 сек. рулим движками if (t>25) { // если значение переменной больше t, то крутим двигатель Stepper1.move(4000); //крутим двигатель } } if (millis() - prevTmillis > 3000) { prevTmillis = millis(); //Тут раз в 3 сек. читаем температуру float t = dht.readTemperature(); // читаем значение температуры и присваиваем его переменной t } if (millis() - prevDispMillis > 500) { prevDispMillis = millis(); //Тут раз в 0.5 сек. обновляем дисплей } }и вот на условие на переменную t в условии if (t>25) ругается при компиляции. Т.к. как я понял, значение этой переменной актуально для данного millis: if (millis() - prevTmillis > 3000) и ее можно использовать только в этой периодичности millis
Как только установить в millis периодичности 200 новое чтение температуры float t = dht.readTemperature();, то компиляция пройдет, но шаговик заикается на время чтения датчика.
Ну и правильно ругается... Вы всё же по ссылке почитайте, что я привёл ))
Выше Вы спросили про "как сделать глобальную t".
Так и сделайте её глобальную, как я писал в сообщении 4.
Вверху, где у Вас переменные TempOpen и прочие описаны - они же глобальные, т.е. имеют область видимости везде, в коде.
Там и объявите свою t, а в лупе просто в неё читайте температуру.
И ещё учтите, что двигатель начнёт реагировать на температуру лишь спустя 3 секунды, когда обновится значение температуры.
Можете первый раз её в setup() прочитать, если это критично.
Заикается, потому, что в библиотеке DHT тоже дилэи понапиханы...
Тут придётся избавляться от этой библиотеки и считывать температуру с реализацией задержек на millis.
Понял свою ошибку, я просто почему то думал, что при объявлении глобальной переменной я ей там и значение сразу должен присвоить, т.е. там же и прочитать датчик и у меня в голове не укладывается как же оно будет меняться. А нужно просто объявить t например с нулевым значением, она станет доступна всему коду, а при старте, через 3 сек этой переменной присвоится значение датчика. Сегодня опробуют, спасибо огромное за разъяснения.