3 независимые импульса прямоугольной формы на выходе

Willka
Offline
Зарегистрирован: 29.05.2013

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

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

в общем, что надо еще раз, вкрате

- временные интервалы могут изменяться по последовательну порту в диапазоне  100 - 3000 мкс

- каждый поток стартует когда ему будет разрешено и выполняться определенное кол-во раз по принципу(простое представление)

if(Thread1Start)
{
  for(int i = 0; i < yyy; i++)
  {
    digitalWrite(xxx, 1);
    delay_time;
    digitalWrite(xxx, 0);
    delay_time;
  }
}

- может быть запущен сразу 1 поток или сразу 3, эта вся информация передается по порту

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

Willka
Offline
Зарегистрирован: 29.05.2013

Willka пишет:

- временные интервалы могут изменяться по последовательну порту в диапазоне  100 - 3000 мкс

вернее, интервалы для задержек задаются по порту и могут быть в интервале 100 - 3000 мкс

maksim
Offline
Зарегистрирован: 12.02.2012

Таймеры/счетчики.

Willka пишет:

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

Не нужно извращатся, нужно правильно стартовать. Так же почитайте про millis() - функция micros() имеет разрешение 4 микросекунды (возвращаемое значение всегда кратно 4)

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

Willka пишет:

в общем, что надо еще раз, вкрате

- временные интервалы могут изменяться по последовательну порту в диапазоне  100 - 3000 мкс

- каждый поток стартует когда ему будет разрешено и выполняться определенное кол-во раз по принципу(простое представление)

i

напрашивается работа с таймерами напрямую... иногда надо отходить от десткой ардуиновской песочницы...

примеров куча по работе с таймерами

Willka
Offline
Зарегистрирован: 29.05.2013

а при чем тут millis когда мне нужны микросекундные задержки????? Millis возврашает миллисекунды!!!!

maksim
Offline
Зарегистрирован: 12.02.2012

Да ни при чем. Ошибся!!! Конечно же micros.

Willka
Offline
Зарегистрирован: 29.05.2013

Michal пишет:

Willka пишет:

в общем, что надо еще раз, вкрате

- временные интервалы могут изменяться по последовательну порту в диапазоне  100 - 3000 мкс

- каждый поток стартует когда ему будет разрешено и выполняться определенное кол-во раз по принципу(простое представление)

i

напрашивается работа с таймерами напрямую... иногда надо отходить от десткой ардуиновской песочницы...

примеров куча по работе с таймерами

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

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

maksim
Offline
Зарегистрирован: 12.02.2012

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

Так же посмотрите в сторону функции tone() , а прежде чем говорить что это детский сад и выбрасывать, доростите до этого - изучив его от и до и научитесь им пользоваться. А по поводу софта, так знайте ограничений накаих нет, хоть на асме пишите.

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

во точно tone() можно использовать, тоьлко вот можно ли етой фнкцией сразу в 3 канала независимых выдавать сигнал...

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

 

maksim
Offline
Зарегистрирован: 12.02.2012

Да с тоном одновременно не получится. Тогда смотрите в сторону библиотек TimerOne и TimerTwo.

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

лучше для себя раз и навсегда с таймерами разобраться и не париться... дальше проблем меньше будет :)

Willka
Offline
Зарегистрирован: 29.05.2013

maksim пишет:

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

Так же посмотрите в сторону функции tone() , а прежде чем говорить что это детский сад и выбрасывать, доростите до этого - изучив его от и до и научитесь им пользоваться. А по поводу софта, так знайте ограничений накаих нет, хоть на асме пишите.

да я понял уже что я не умею.. иначе бы не спрашивал у вас ничего бы... не надо гворить об этом теперь повсюду, что я нуб...

 

если бы с Micros бы у меня все получалось бы.. я бы не задавал бы сюда вопросы...

 

ладно.. последую вашим советам, пойду снова смотреть тупо в справочники и дальше не понимать ...

 

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

 

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

maksim
Offline
Зарегистрирован: 12.02.2012

Вы наверное удивитесь, но вы и так пишите на СИ.

Willka
Offline
Зарегистрирован: 29.05.2013

maksim пишет:
если все таки устраивает ограничение micros(), а именно - возвращаемое значение всегда кратно 4 , то можно сделать и на micros() никакого кривого старта у нее нет, надо просто правльно ей пользоваться.

 

#define DIR_X  53 // зеленый
#define STP_X  51 // белый
#define ENB_X  49 // красный

void setup()
{
	pinMode(STP_X, OUTPUT); // шаг
	pinMode(DIR_X, OUTPUT); // направление
	pinMode(ENB_X, OUTPUT); // вкл/выкл

  Serial.begin(19200);
}

long CurrTime = 0;
long PrevTime = 0;
long DelayTime = 320;
int LoopSteps = 0;
int NeedSteps = 0;

void loop()
{
	String s;
	if (InputBuffer(s))
	{
		LoopSteps = s.toInt();

		if (LoopSteps > 0)
			digitalWrite(DIR_X, LOW);
		else
			digitalWrite(DIR_X, HIGH);

		digitalWrite(ENB_X, HIGH);
		NeedSteps = 0;
	}

	CurrTime = micros();
	if (CurrTime >= (PrevTime + DelayTime))
	{
		digitalWrite(STP_X, !digitalRead(STP_X));
		PrevTime = CurrTime;
		NeedSteps++;
		if (NeedSteps >= abs(LoopSteps))
		{
			NeedSteps = 0;
			digitalWrite(ENB_X, LOW);		
		}
	}
}

bool InputBuffer(String &Output)
{
  int i = 0;
  char Buff[100];

  bool State = false;

  if(Serial.available() > 0)
  {
    delay(15);
    while(Serial.available() && i < 99) 
    {
      Buff[i++] = Serial.read();
    }
    Buff[i++]='\0';
    State = true;
  }
  Output = Buff;
	Serial.flush();
  return State;
}

вот кусок, просто кусок с микрос, и только 1 "поток", можете мне объяснить почему на выходе шаговый двигатель делает то на несколько шагов больше, то на несколько шагов меньше??? А мне шаговиком нужно позиционировать угол.. и вот если я скажем запущу подряд несколько раз даже вот этот код, скажем нужно ротор провернуть на 360 градусов, то через 10-15 запусков.. по идее должно сделать 10-15 оборотов и встать на прежднее место, но у меня примерно на 45 градусов идет отклонение от того где должно быть, а если запустить в 8 раз больше? то уже на 1 оброт идет отклонение... если посмотреть в цикле выполнения разницу времени.. то оно, из 1000 скажем значений, будет первые 20-30 между 0 и 200, затем только разница будет равна

DelayTime

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

DelayTime

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

if (CurrTime >= (PrevTime + DelayTime))

вотя  не знаю, что делать...

 

а  уменя для позиционирования используются 3 шаговика... и если они все так ошибочно выставят мне угол.. тоя  врезультате получу совсем не то, что я хотел бы...

Willka
Offline
Зарегистрирован: 29.05.2013

оО что-то ради тупого эксперимена поставил в 40 строке        

PrevTime = micros();

вместо

PrevTime = CurrTime;

ошибка во вращении есть, но уже раз в 10 меньше!, хотя может это просто случайность получилась, не знаю

 

maksim
Offline
Зарегистрирован: 12.02.2012

А если не секрет, то зачем вы велосипед изобретаете? Нужно неблокирующее управление шаговым двигателем... так пожалуйста - AccelStepper, пример MultiStepper .

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

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

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

Willka
Offline
Зарегистрирован: 29.05.2013

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

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

да и проект... разглашению не подлежит.. поэтому и не описывал подробностей..

Willka
Offline
Зарегистрирован: 29.05.2013

Michal пишет:

 В теме уже окло 10ка сообщений, а оказывается мы тут шаговиками управляем :)

 

да тут еще пара десятков чем есть еще управлять.....

maksim
Offline
Зарегистрирован: 12.02.2012

Эта библиотека работает со всеми "нормальными" типами двигателей и со всеми драйверами. Умеет ускорять/тормозить с заданным ускорением двигатель.

И не надо тут жаловаться, что над вами кто-то смеется, потому что никто над вами не смеется, вам это кажется. А то что вы не знали об этой библиотеке означает, только одно - что не умеете пользовться поиском.

Если бы вы на этом форуме просмотрели темы касающихся шаговых двигателей, то обязательно бы наткнулись на эту библиотеку и как ей пользоваться и не заводили бы данную тему.

Вам всего то надо было в правом верхнем углу написать "ШД" и нажать Поиск.

http://arduino.ru/forum/apparatnye-voprosy/shd-i-biblioteka-stepper#comment-9151

http://arduino.ru/forum/apparatnye-voprosy/pomogite-chainiku-s-upravleniem-kontrollera-shd-cherez-stepdirenable-vkhody

http://arduino.ru/forum/apparatnye-voprosy/kak-uznat-kol-vo-shagov-u-shagovogo-dvigatelya

Willka
Offline
Зарегистрирован: 29.05.2013

да ладно уж там.... что я умею или нет :) я когда вообще искал, искал arduino stepper library то находил другую библиотеку всегда..

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

Мужики!!!! правда очень помогли этой библиотекой..!!!!!! БОЛЬШОЕ СПАСИБО!!!!

 

Только еше с ней разобраться надо, с этой библиотекой :)

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

maksim
Offline
Зарегистрирован: 12.02.2012

Конечно в шагах, скорость - в шагах в секунду, ускорение - в шагах в секунду в квадрате.

Описание функций можно посмотреть в файле AccelStepper.h.

Willka
Offline
Зарегистрирован: 29.05.2013

так, что-то я в одном месте разобраться не могу...

 

если запуск с ускорением тогда setMaxSpeed и run вызывать нужно???

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

ставлю просто setSpeed и вызываю его run'ом , мотор вытворяет чудеса

вызываю runSpeed, все нормально, но только не понятно на какой скорости он крутится, не реагирует ни на setSpeed ни на setMaxSpeed

 

если не сложно можно объяснить вот эти 2 чуда для меня

если выбран режим с ускорением

то я смогу регулировать скорость и ускорение

если выбран режим без ускорения

то я могу изменить скорость вращение движка

 

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

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

	if (Mot1.distanceToGo() == 0)
	{
		Mot1.disableOutputs();
	}

 

Willka
Offline
Зарегистрирован: 29.05.2013

не понял прикола... оставил и setSpeed и  setMaxSpeed теперь все регулируется норм, ах да еще вызвал runSpeedToPosition