Проблема с совмещением экрана
- Войдите на сайт для отправки комментариев
Ср, 21/03/2018 - 14:20
Есть датчик света BH 1750, шаговый двигатель с драйвером А4988 и экранкик SSD1306 oled
Опоказаний датчика света зависит скорость вращения двигателя и в порт выводятся соответствующие показания, но при подключении дисплея шаговик вращяется очень медленно с одной скоростю и не как не реагирует на показания датчика...
если закоментировать часть кода которая выводит данные на дисплей то все работает но соответственно дисплей не работает, если переместить эту часть кода в void setup то двигатель работает но на дисплее в место показаний светится "0" "0"
Как заставить его работать?
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#include <Wire.h>
#include <BH1750.h>
BH1750 lightMeter(0x23);
#include <AccelStepper.h>
AccelStepper nema17(1, 10, 11);
int miniSpeed = 1000; //Минимальная скорость
int maxiSpeed = 2700; //Максимальная скорость
int nemaSpeed; //Скорость вращения двигателя в зависимости от показаний датчика
int diameter; //Показание прибора
byte i = 16; //задержка, мс (скорость изменения скорости вращения)
unsigned long v;
void setup() {
//Serial.begin(9600);
nema17.setMaxSpeed(maxiSpeed);
Wire.begin();
if (lightMeter.begin(BH1750::ONE_TIME_LOW_RES_MODE));
display.begin(SSD1306_SWITCHCAPVCC);
}
void loop() {
if (millis() - v > i) {
uint16_t lux = lightMeter.readLightLevel();
diameter = lux;
if (diameter > 285) nemaSpeed--;
else if (diameter < 270) nemaSpeed++;
if (nemaSpeed > maxiSpeed) nemaSpeed = maxiSpeed;
if (nemaSpeed < miniSpeed) nemaSpeed = miniSpeed;
//Serial.print("Diameter: ");
//Serial.println(diameter);
//Serial.print("Speed: ");
//Serial.println(nemaSpeed);
v = millis();
}
nema17.setSpeed(nemaSpeed);
nema17.runSpeed();
/*
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(1, 1);
display.print("Diameter");
display.setCursor(60, 1);
display.print(diameter);
display.setCursor(1, 16);
display.print("Speed");
display.setCursor(50, 16);
display.print(nemaSpeed);
display.display();
*/
}
Извиняюсь может не в том розделе тема...
Дак вы работу с дисплеем занесите в if(), зачем в лупе-то долбите его. И вызывайте этот кусок для вывода на дисплей, если скорость действительно изменилась (еще одна переменная нужна).
Можете пожалуйста показать пример как это должно выглядеть?
Пример не смогу - слишком далеко нахожусь. Но опишу: выделяете строки 45-56, Ctrl-C, переходите в строку 40, Ctrl-V.
#include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); #include <Wire.h> #include <BH1750.h> BH1750 lightMeter(0x23); #include <AccelStepper.h> AccelStepper nema17(1, 10, 11); int miniSpeed = 1000; //Минимальная скорость int maxiSpeed = 2700; //Максимальная скорость int nemaSpeed; //Скорость вращения двигателя в зависимости от показаний датчика int diameter; //Показание прибора byte i = 16; //задержка, мс (скорость изменения скорости вращения) unsigned long v; void setup() { //Serial.begin(9600); nema17.setMaxSpeed(maxiSpeed); Wire.begin(); if (lightMeter.begin(BH1750::ONE_TIME_LOW_RES_MODE)); display.begin(SSD1306_SWITCHCAPVCC); } void loop() { if (millis() - v > i) { uint16_t lux = lightMeter.readLightLevel(); diameter = lux; if (diameter > 285) nemaSpeed--; else if (diameter < 270) nemaSpeed++; if (nemaSpeed > maxiSpeed) nemaSpeed = maxiSpeed; if (nemaSpeed < miniSpeed) nemaSpeed = miniSpeed; //Serial.print("Diameter: "); //Serial.println(diameter); //Serial.print("Speed: "); //Serial.println(nemaSpeed); v = millis(); display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(1, 1); display.print("Diameter"); display.setCursor(60, 1); display.print(diameter); display.setCursor(1, 16); display.print("Speed"); display.setCursor(50, 16); display.print(nemaSpeed); display.display(); } nema17.setSpeed(nemaSpeed); nema17.runSpeed(); }так же пробовал двигатель не реагирует на показания и вращается еле еле... я же
я бы еще добавил проверку, изменились ли показания датчика, что-то типа if (lux != diameter) и выполнял бы все действия с мотором и экраном только внутри этого условия.
так не чего не работает Я же написал что в такой комбинации двигатель дормозит и не реагирует на показания датчика
#include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); #include <Wire.h> #include <BH1750.h> BH1750 lightMeter(0x23); #include <AccelStepper.h> AccelStepper nema17(1, 10, 11); int miniSpeed = 1000; //Минимальная скорость int maxiSpeed = 2700; //Максимальная скорость int nemaSpeed; //Скорость вращения двигателя в зависимости от показаний датчика //int diameter; //Показание прибора byte i = 16; //задержка, мс (скорость изменения скорости вращения) unsigned long v; uint16_t lux; void setup() { Serial.begin(9600); nema17.setMaxSpeed(maxiSpeed); Wire.begin(); if (lightMeter.begin(BH1750::ONE_TIME_LOW_RES_MODE)); display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(1, 1); display.print("Diameter"); display.setCursor(60, 1); display.print(lux); display.setCursor(1, 16); display.print("Speed"); display.setCursor(50, 16); display.print(nemaSpeed); display.display(); } void loop() { if (millis() - v > i) { lux = lightMeter.readLightLevel(); if (lux > 285) nemaSpeed--; else if (lux < 270) nemaSpeed++; if (nemaSpeed > maxiSpeed) nemaSpeed = maxiSpeed; if (nemaSpeed < miniSpeed) nemaSpeed = miniSpeed; Serial.print("Diameter: "); Serial.println(lux); Serial.print("Speed: "); Serial.println(nemaSpeed); v = millis(); } nema17.setSpeed(nemaSpeed); nema17.runSpeed(); }В такой комбинации все работает в порт выводятся данные двигатель вращяется как положено но экран пишет:
Я понимаю что для вас Я "хомячек" над которым можно посмеятся...
И вижу что для етого наверное и существует етот форум...
Да больно нам надо смеяться над вами.
На детские ошибки вам указали. Почему не крутится мотор... ну, сейчас спецы по аксельстепу подойдут и подскажут что-нить. Я, к примеру, мотор так кручу, без аксельстепа, поэтому не вижу, чему тут тормозить. Поставьте временно i в 1000, положим. Если будет побыстрее, то надо сделать как я вам писал и b707 тоже.
Тоесть проблема может быть в несовместимости библиотеки
<AccelStepper.h>А как тогда нужно написать код без этой библиотеки чтобы переменная nemaSpeed управляла скоростю вращения двигателя
Я вот смотрю на этот пример и понимаю что не чего не понимаю...
Ну,, смотрите:
У вас есть драйвер, у которого STEP и DIR подключены к ардуино пинам 2, 4 например.
Делаете digitalWrite(4, LOW) - мотор будет готов крутится в одну сторону. digitalWrite(4, HIGH) - в другую.
Делаете digitalWrite(2, HIGH); delayMicroseconds(5); digitalWrite(2, LOW); - мотор делает шаг в заданную сторону.
Пауза между шагами - величина обратная к скорости. Чем меньше пауза - тем быстрее будет шагать двигатель.
Теперь у вас задача такая (сделайте простой скетч): выставляйте направление и в цикле степайте с паузой (delay). Как только с паузой получилось, делайте как в строке 40 последнего скетча, только вместо замера люксов в этом условии делайте степ.
Вот вам будет скетч, степающий без блокировки. Справитесь - пишите, будем учиться интегрировать его в код с люксметром.
Enlan, для начала продейлайте такой тест - возьмите свой скетч из сообщения #5 и поменяйте строку 14 на byte i =255; Больше ничего не трогайте!
Проделайте это и отпишитесь - стал ли мотор вращаться быстрее. На вывод на дисплей и реацию на датчик не обращайте внимания.
int stp = 10; int dir = 11; void setup() { pinMode(stp, OUTPUT); pinMode(dir, OUTPUT); } void loop() { digitalWrite(11,HIGH); digitalWrite(10,HIGH); digitalWrite(10,LOW); delay(1); }Вот так у меня получилось его запустить вращятся в одну сторону а что дальше как управлять скоростю?
b707, ну в правильном направлении
да двигатель начал вращятся как нужно но тормозит каждых 255 милисекунд и при этом так же тормозят показания на экране но все уже хоть так работает
но мне нужна задержка для изменения ускорения двигателя... как быть?
и еще одно после таких изменений не правильно работает остальной код, двигатель вращается только с увеличением скорости если показания ниже он всеравно продолжает набирать скорость...
Снова все кудато пропали...
дело в том что у меня все это работало только без дисплея все выводилось просто в порт
а вот после попытки подключить дисплей получаются такие траблы...
b707, ну в правильном направлении
да двигатель начал вращятся как нужно но тормозит каждых 255 милисекунд и при этом так же тормозят показания на экране но все уже хоть так работает
это означает, что проблема не в библиотеке Stepper. а в библиотке Display. Видимо вывод на экран слишком медленный. Я бы вам посоветовал для начала выяснить, сколько по времени выполняется каждая строчка работы с дисплеем, например вставив до и после КАЖДОГО оператора Display. вывод значения миллис в монитор. Справитесь?
#include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); #include <Wire.h> #include <BH1750.h> BH1750 lightMeter(0x23); #include <AccelStepper.h> AccelStepper nema17(1, 10, 11); int miniSpeed = 1000; //Минимальная скорость int maxiSpeed = 2700; //Максимальная скорость int nemaSpeed; //Скорость вращения двигателя в зависимости от показаний датчика byte i = 100; //задержка, мс (скорость изменения скорости вращения) unsigned long v; void setup() { Serial.begin(9600); nema17.setMaxSpeed(maxiSpeed); Wire.begin(); if (lightMeter.begin(BH1750::ONE_TIME_LOW_RES_MODE)); display.begin(SSD1306_SWITCHCAPVCC); } void loop() { if (millis() - v > i) { uint16_t lux = lightMeter.readLightLevel(); if (lux > 285) nemaSpeed--; else if (lux < 270) nemaSpeed++; if (nemaSpeed > maxiSpeed) nemaSpeed = maxiSpeed; if (nemaSpeed < miniSpeed) nemaSpeed = miniSpeed; //Serial.print("Diameter: "); //Serial.println(lux); //Serial.print("Speed: "); //Serial.println(nemaSpeed); v = millis(); Serial.println(v); display.clearDisplay(); Serial.println(v); display.setTextColor(WHITE); Serial.println(v); display.setTextSize(1); Serial.println(v); display.setCursor(1, 1); Serial.println(v); display.print("Diameter"); Serial.println(v); display.setCursor(60, 1); Serial.println(v); display.print(lux); Serial.println(v); display.setCursor(1, 16); Serial.println(v); display.print("Speed"); display.setCursor(50, 16); Serial.println(v); display.print(nemaSpeed); Serial.println(v); display.display(); Serial.println(v); } nema17.setSpeed(nemaSpeed); nema17.runSpeed(); }так ?
нет, так вы будете всегда одно и то же значение миллис выводить. Везде поставьте Serial.println(millis());
ну вот и смотрите, всего ваш вывод на экран занимает 28 мс. Неудивительно, что когда вы ставите обновление экрана каждые 16мс - у вас ничего не работает.
Вот я вам расписал. сколько мсек занимает каждая строка:
display.clearDisplay(); <1 display.setTextColor(WHITE); <1 display.setTextSize(1); <1 display.setCursor(1, 1); <1 display.print("Diameter"); 1 display.setCursor(60, 1); <1 display.print(lux); 2 <<<< много display.setCursor(1, 16); <1 display.print("Speed"); 1 display.setCursor(50, 16); <1 display.print(nemaSpeed); 2 <<<< много display.display(); 21 <<<< очень много!!!Видно, что в первую очередь надо разбираться с методом display(). Но даже если его удасться просто выкинуть - все равно остальной вывод занимает 7мс, что неприлично много.
Вывод - работу с дисплеем надо кардинально переписывать.
...или делать степ в прерывании таймера. Если, конечно, дисплейная либа их не запрещает.
Типа using namespace ....?