Trouble с шаговиком

Никитичъ
Offline
Зарегистрирован: 23.05.2017

 Здравствуйте. Есть траблы. Суть задумки в том, чтобы считывать кол-во оборотов с вала двигателя (на внешней системе) путем простого подсчета импульсов на цифровом входе, и при достижении значения в 2000 оборотов и более сделать 300 шагов шаговым двигателем. Отдельно код для двигателя проверял, для тахометра проверял, но когда склеил их пишет ошибку. Пробовал без else. Пробовал в тело if вместо horizontal.step подставлять serial.print. Работает. в чем прикол?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Никитичъ пишет:

 в чем прикол?

В неуважении к Форуму на который Вы пришли.

Вы всерьёз думаете, что на Вашей картинке что-то видно?

Вставьте код как положено, тогда и поговорим.

Никитичъ
Offline
Зарегистрирован: 23.05.2017

Прошу прощения

#include <Stepper.h>

const int inPin = 2;

void setup() {
  Stepper horizontal(200, 8, 9, 10, 11);
  horizontal.setSpeed(60);
  Serial.begin(9600);
 pinMode(inPin, INPUT);
 digitalWrite(inPin, HIGH);
}
void loop() {
int rpm=get_rpm();
Serial.print("ob/min: ");
Serial.println(rpm);
if(rpm>=2000)
{horizontal.step(300);}
}
int get_rpm()
{
int acct=0;
boolean IR=LOW;
unsigned long Time=0;
unsigned long sTime=millis();
while (Time<=1000)
{
if (digitalRead(inPin)==HIGH)
  {IR=HIGH;}
if (digitalRead(inPin)==LOW && IR==HIGH)
{
acct++;
IR=LOW;
}
Time=millis()-sTime;
}
int acct2 = int(60000./float(1000))*acct;
return acct2;
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, если бы Вы ещё и скопипастили сообщение об ошибке - цены б не было.

У меня пишет ошибку в строке 17 

kaka.ino: In function 'void loop()':
kaka:17: error: 'horizontal' was not declared in this scope
'horizontal' was not declared in this scope

У Вас так же?

Если также, то непонятно, что Вас смущает. У Вас переменная horizontal описана в функции setup (строка 6). А использовать её Вы пытаетесь в функции loop (строка 17). А в функци loop она не существует.

Изучаем "Правила области видимости" вот здесь (зодно и весь пост читаем) и всё станет на свои места. Можно, конечно просто перенести строку 6 выше строки 5, но если тупо перенесёте, не изучив матчасть, то это до следующих граблей.

 

Никитичъ
Offline
Зарегистрирован: 23.05.2017

ЕвгенийП пишет:

Изучаем "Правила области видимости" вот здесь (зодно и весь пост читаем) и всё станет на свои места. Можно, конечно просто перенести строку 6 выше строки 5, но если тупо перенесёте, не изучив матчасть, то это до следующих граблей.

 

Спасибо, изучил. Все таки, я объявил horizontal глобальной переменной (вынес за void setup), потому что нигде ничего экранировать не придется. Но суть понял. Теперь скетч залился в плату с 3-его раза, а в сериал монитор не поступают действительные значения, только нули и скачки от наводок, создаваемых магнитным полем трансформатора при коммутации (рядом стоит). Может это проблемы с портом?... 

З.Ы.: за kaka.ino немного обидно... но он наверно и в правду не очень...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Никитичъ пишет:

З.Ы.: за kaka.ino немного обидно... но он наверно и в правду не очень...

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

Никитичъ
Offline
Зарегистрирован: 23.05.2017

ЕвгенийП пишет:

 

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

Действительно практично, взял на заметку.

Теперь появилась новая проблема... Функция под if выполняется все время, пока выполняется условие... Я понимаю, что так и должно быть, но мне необходимо, чтобы эта функция выполнилась один раз.

Я пытался организовать 2 решения.

1. Через if. Код приводить не буду, ибо ересь. Ничего не ругалось, но и ничего не работало. Суть в том, чтобы взять некую константу int x=0, и при выполнении условия rpm>2000 к этой константе прибавлялась единица (int x=x+1)

Все таки код:

#include <Stepper.h>

const int inPin = 2;
Stepper horizontal(200, 8, 9, 10, 11);
void setup() {
  
  horizontal.setSpeed(60);
  Serial.begin(9600);
 pinMode(inPin, INPUT);
 digitalWrite(inPin, HIGH);

}
void loop() {
  int x=0;
int rpm=get_rpm();
Serial.print("ob/min: ");
Serial.println(rpm);
if(rpm>=2000 && x==0)
{horizontal.step(300);
int x=x+1;
}
}
int get_rpm()
{
int acct=0;
boolean IR=LOW;
unsigned long Time=0;
unsigned long sTime=millis();
while (Time<=1000)
{
if (digitalRead(inPin)==HIGH)
  {IR=HIGH;}
if (digitalRead(inPin)==LOW && IR==HIGH)
{
acct++;
IR=LOW;
}
Time=millis()-sTime;
}
int acct2 = int(60000./float(1000))*acct;
return acct2;
}

Логика подсказывает, что действие x+1 происходит раньше, чем step. Или же, поскольку int x=0 задано в теле loop, программа забывает, что в теле if произошло x=x+1. Либо же я не понял синтаксис, и так делать вообще нельзя.

2. Пробовал for, но еще не разобрался как он работает(там не происходит вообще ничего, либо пишет ошибку, что get_rpm не задана в этой области).

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

Никитичъ
Offline
Зарегистрирован: 23.05.2017

Никитичъ пишет:

 

Логика подсказывает, что действие x+1 происходит раньше, чем step. Или же, поскольку int x=0 задано в теле loop, программа забывает, что в теле if произошло x=x+1. Либо же я не понял синтаксис, и так делать вообще нельзя.

 

Скорее вообще не происходит потому что: вынес int x=0 из void loop() в void setup(), а в loop прописал int x. Показания в сериал порт адекватные, шаговик все еще шагает на каждый отсчет

 

T.Rook
Offline
Зарегистрирован: 05.03.2016

Никитичъ пишет:

Скорее вообще не происходит потому что: вынес int x=0 из void loop() в void setup(), а в loop прописал int x. Показания в сериал порт адекватные, шаговик все еще шагает на каждый отсчет

как Вам уже сказал ЕвгенийП : изучаем пост с "Правила области видимости", в этот раз обращая внимание на часть про "статические переменные".

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы много всего в одну кучу свалили, попробуем по пунктам

Никитичъ пишет:

Теперь появилась новая проблема... Функция под if выполняется все время, пока выполняется условие... Я понимаю, что так и должно быть, но мне необходимо, чтобы эта функция выполнилась один раз.

Ну, заведите переменную флаг и сделайте, чтобы условие выполнялось только один раз.

static bool firstTime = true;
...
if (<Ваше условие> && firstTime) {
    firstTime = false;
    .....
}

Такое комбинированное условие будет истинным только при первом выполнении Вашего условия. А потом оно всегда будет ложным, т.к. firstTime уже false.

Никитичъ пишет:

void loop() {
  int x=0;
  int rpm=get_rpm();
  Serial.print("ob/min: ");
  Serial.println(rpm);
  if (rpm>=2000 && x==0) {
     horizontal.step(300);
     int x=x+1;
   }
}

Логика подсказывает

Нет, логика на самом деле подсказывает, что "x" в строках 2, 6 и справа от "=" в строке 8 - это одна переменная, а "х" в левой части оператора присваивания в строке 8 - совершенно другая. Они имеют одно имя, но не более того - это совершенно разные переменные. Изучите вот эту статью, особенно обратите внимание на концепцию "экранирования переменных" - это тот самы случай. Когда изучите, поймёте как исправить и тогда "х" будет нормально изменяться.

Да и ещё, я не особо разбирался в логике, хочу только отметить, что x в строке 2 будет получать значение 0 всякий раз при входе в loop. Если Вы хотите, что значение x сохранялось между вызовами loop (типа с прошлого раза оставалось), то ... ответ в той же статье.

 

Никитичъ
Offline
Зарегистрирован: 23.05.2017

ЕвгенийП пишет:

 Изучите вот эту статью, особенно обратите внимание на концепцию "экранирования переменных" - это тот самы случай. Когда изучите, поймёте как исправить и тогда "х" будет нормально изменяться.

 

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

Функция действительно нормально заработала, когда в теле loop была объявлена статическая переменная.