Проблема с совмещением экрана

Enlan
Offline
Зарегистрирован: 17.04.2016

Есть датчик света 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();
*/
}
Enlan
Offline
Зарегистрирован: 17.04.2016

Извиняюсь может не в том розделе тема...

sadman41
Offline
Зарегистрирован: 19.10.2016

Дак вы работу с дисплеем занесите в if(), зачем в лупе-то долбите его. И вызывайте этот кусок для вывода на дисплей, если скорость действительно изменилась (еще одна переменная нужна).

Enlan
Offline
Зарегистрирован: 17.04.2016

Можете пожалуйста показать пример как это должно выглядеть?

sadman41
Offline
Зарегистрирован: 19.10.2016

Пример не смогу - слишком далеко нахожусь. Но опишу: выделяете строки 45-56, Ctrl-C, переходите в строку 40, Ctrl-V.

 

Enlan
Offline
Зарегистрирован: 17.04.2016
#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();

}

так же пробовал двигатель не реагирует на показания и вращается еле еле... я же

b707
Offline
Зарегистрирован: 26.05.2017

я бы еще добавил проверку, изменились ли показания датчика, что-то типа if (lux != diameter) и выполнял бы все действия с мотором и экраном только внутри этого условия.

 

Enlan
Offline
Зарегистрирован: 17.04.2016

так не чего не работает Я же написал что в такой комбинации двигатель дормозит и не реагирует на показания датчика

Enlan
Offline
Зарегистрирован: 17.04.2016
#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();

}

В такой комбинации  все работает в порт выводятся данные двигатель вращяется как положено но экран пишет:

Enlan
Offline
Зарегистрирован: 17.04.2016

Я понимаю что для вас Я "хомячек" над которым можно посмеятся...

И вижу что для етого наверное и существует етот форум...

sadman41
Offline
Зарегистрирован: 19.10.2016

Да больно нам надо смеяться над вами.

На детские ошибки вам указали. Почему не крутится мотор... ну, сейчас спецы по аксельстепу подойдут и подскажут что-нить. Я, к примеру, мотор так кручу, без аксельстепа, поэтому не вижу, чему тут тормозить. Поставьте временно i в 1000, положим. Если будет побыстрее, то надо сделать как я вам писал и b707 тоже.

Enlan
Offline
Зарегистрирован: 17.04.2016

Тоесть проблема может быть в несовместимости библиотеки <AccelStepper.h>

Enlan
Offline
Зарегистрирован: 17.04.2016

А как тогда нужно написать код без этой библиотеки чтобы переменная nemaSpeed управляла скоростю вращения двигателя

Я вот смотрю на этот пример и понимаю что не чего не понимаю...

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну,, смотрите:

У вас есть драйвер, у которого STEP и DIR подключены к ардуино пинам 2, 4 например.

Делаете digitalWrite(4, LOW) - мотор будет готов крутится в одну сторону. digitalWrite(4, HIGH) -  в другую. 

Делаете digitalWrite(2, HIGH); delayMicroseconds(5); digitalWrite(2, LOW); - мотор делает шаг в заданную сторону.

Пауза между шагами - величина обратная к скорости. Чем меньше пауза - тем быстрее будет шагать двигатель.

Теперь у вас задача такая (сделайте простой скетч): выставляйте направление и в цикле степайте с паузой (delay). Как только с паузой получилось, делайте как в строке 40 последнего скетча, только вместо замера люксов в этом условии делайте степ. 

Вот вам будет скетч, степающий без блокировки. Справитесь - пишите, будем учиться интегрировать его в код с люксметром.

 
b707
Offline
Зарегистрирован: 26.05.2017

Enlan, для начала продейлайте такой тест - возьмите свой скетч из сообщения #5 и поменяйте строку 14 на byte i =255; Больше ничего не трогайте!

Проделайте это и отпишитесь - стал ли мотор вращаться быстрее. На вывод на дисплей и реацию на датчик не обращайте внимания.

Enlan
Offline
Зарегистрирован: 17.04.2016
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); 
}

Вот так у меня получилось его запустить вращятся в одну сторону а что дальше как управлять скоростю?

Enlan
Offline
Зарегистрирован: 17.04.2016

b707, ну в правильном направлении

да двигатель начал вращятся как нужно но тормозит каждых 255 милисекунд и при этом так же тормозят показания на экране но все уже  хоть так работает

Enlan
Offline
Зарегистрирован: 17.04.2016

но мне нужна задержка для изменения ускорения двигателя... как быть?

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

Enlan
Offline
Зарегистрирован: 17.04.2016

Снова все кудато пропали...

дело в том что у меня все это работало только без дисплея все выводилось просто в порт

а вот после попытки подключить дисплей получаются такие траблы...

b707
Offline
Зарегистрирован: 26.05.2017

Enlan пишет:

b707, ну в правильном направлении

да двигатель начал вращятся как нужно но тормозит каждых 255 милисекунд и при этом так же тормозят показания на экране но все уже  хоть так работает

это означает, что проблема не в библиотеке Stepper. а в библиотке Display. Видимо вывод на экран слишком медленный. Я бы вам посоветовал для начала выяснить, сколько по времени выполняется каждая строчка работы с дисплеем, например вставив до и после КАЖДОГО оператора Display. вывод значения миллис в монитор. Справитесь?

Enlan
Offline
Зарегистрирован: 17.04.2016
#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();

}

так ?

117
117
117
117
117
117
117
117
117
117
117
117
234
234
234
234
234
234
234
234
234
234
234
234
352
352
352
352
352
352
352
352
352
352
352
352
470
470
470
470
470
470
470
470
470
470
470
470
587
587
587
587
587
587
587
587
587
587
587
587
704
704
704
704
704
704
704
704
704
704
704
704
822
822
822
822
822
822
822
822
822
822
822
822
940
940
940
940
940
940
940
940
940
940
940
940
1057
1057
1057
1057
1057
1057
1057
1057
1057
1057
1057
1057
1174
1174
1174
1174
1174
1174
1174
1174
1174
1174
1174
1174
1292
1292
1292
1292
1292
1292
1292
1292
1292
1292
1292
1292
1410
1410
1410
1410
1410
1410
1410
1410
1410
1410
1410
1410
1527
1527
1527
1527
1527
1527
1527
1527
1527
1527
1527
1527
1644
1644
1644
1644
1644
1644
1644
1644
1644
1644
1644
1644
1762
1762
1762
1762
1762
1762
1762
1762
1762
1762
1762
1762
1880
1880
1880
1880
1880
1880
1880
1880
1880
1880
1880
1880
1997
1997
1997
1997
1997
1997
1997
1997
1997
1997
1997
1997
2114
2114
2114
2114
2114
2114
2114
2114
2114
2114
2114
2114
2232
2232
2232
2232
2232
2232
2232
2232
2232
2232
2232
2232
2350
2350
2350
2350
2350
2350
2350
2350
2350
2350
2350
2350

 

 

b707
Offline
Зарегистрирован: 26.05.2017

нет, так вы будете всегда одно и то же значение миллис выводить. Везде поставьте Serial.println(millis());

Enlan
Offline
Зарегистрирован: 17.04.2016
117
117
117
117
118
120
120
121
121
122
124
145
234
234
234
234
235
237
237
238
238
239
241
262
352
352
352
352
353
355
355
356
356
357
359
379
470
470
470
470
471
473
473
474
474
475
477
497
587
587
587
587
588
590
590
591
591
592
594
615
704
704
704
704
705
707
707
708
708
709
711
732
822
822
822
822
823
825
825
826
826
827
829
849
940
940
940
940
941
943
943
944
944
945
947
967
1057
1057
1057
1058
1058
1060
1060
1061
1061
1063
1064
1086
1174
1174
1174
1175
1175
1177
1177
1178
1178
1180
1181
1203
1292
1292
1292
1293
1293
1295
1295
1296
1296
1298
1299
1320
1410
1410
1410
1411
1411
1413
1413
1414
1414
1416
1417
1438
1527
1527
1527
1528
1528
1530
1530
1531
1531
1533
1534
1556
1644
1644
1644
1645
1645
1647
1647
1648
1648
1650
1651
1673
1762
1762
1762
1763
1763
1765
1765
1766
1766
1768
1769
1790
1880
1880
1880
1881
1881
1883
1883
1884
1884
1886
1887
1908
1997
1997
1997
1998
1998
2000
2000
2001
2001
2003
2004
2026
2114
2114
2114
2115
2115
2117
2117
2118
2118
2120
2121
2143
2232
2232
2232
2233
2233
2235
2235
2236
2236
2238
2239
2260
2350
2350
2350
2351
2351
2353
2353
2354
2354
2356
2357
2378
2467
2467
2467
2468
2468
2470
2470
2471
2471
2473
2475
2496
2584
2584
2584
2585
2585
2587
2587
2588
2588
2590
2591
2613
2702
2702
2702
2703
2703
2705
2705
2706
2706
2708
2709
2731

 

b707
Offline
Зарегистрирован: 26.05.2017

ну вот и смотрите, всего ваш вывод на экран занимает 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мс, что неприлично много.

Вывод - работу с дисплеем надо кардинально переписывать.

sadman41
Offline
Зарегистрирован: 19.10.2016

...или делать степ в прерывании таймера. Если, конечно, дисплейная либа их не запрещает.

Enlan
Offline
Зарегистрирован: 17.04.2016

Типа using namespace ....?