С помощью пульта на 433 мгц и шаговика easydriver заставить крутиться мотор

Sliva
Offline
Зарегистрирован: 18.01.2017

задача:

с помощью пульта на 433 мгц и шаговика easydriver заставить крутиться мотор

вот код 

#define DISTANCE 3200
int StepCounter = 0;
int Stepping = false;
 
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();

void setup() {
 
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2
  
pinMode(8, OUTPUT); 
pinMode(9, OUTPUT);
digitalWrite (8,LOW);
digitalWrite (9,LOW);

  
}

void loop() {
 if (mySwitch.available()) {
   int value = mySwitch.getReceivedValue();
   if (value == 0) {
      Serial.println("error de codigo");
    } else {
      Serial.print("codigo Recibido");
      Serial.println(value);
      Serial.println( mySwitch.getReceivedValue() );
    
   
      if(value == 13248 && Stepping ==  false)
    
    {
     
    Stepping =   true;
    }
    if (Stepping == true)
    {
     digitalWrite(9, HIGH);
delay(1); 
digitalWrite(9, LOW); 
delay(1);

StepCounter = StepCounter + 1;

if (StepCounter == DISTANCE)
{ 
StepCounter = 0;
Stepping = false;
    
   
}  
  
   
    
       mySwitch.resetAvailable();
      }
 }
}
}

подскажите что не правильно я делаю. мотор крутиться еле еле когда я держу кнопку пульта 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Так спроси у испанца, который автор кода ;)

Sliva
Offline
Зарегистрирован: 18.01.2017

Автор кода я. Вот только в программировании я дуб дубом. Можете указать на ошибки. Заранее спасибо

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Если вы - автор кода, то вам не составит труда объяснить, что этот код делает? Прежде всего - себе объяснить. Обычными человеческими словами.

Я вам подскажу, конечно: на каждый принятый сигнал с пульта - вы делаете один шаг двигателем. И только тогда, когда сигнал с пульта принят. Помимо этого - там задержки и вывод в Serial. Как итог - всё это мееедленно и работает, т.к. делает ровно то, как написано.

Псевдокод того, как должно быть:

void loop()
{
	int code = IR.getCode();
	if(code > 0 && code == MY_CODE)
	{
		lastReceivedTime = millis();
		stepping = true;
	}

	if(millis() - lastReceivedTime > 1000)
	{
		stepping = false;
	}

	if(stepping)
	{
		step();
	}
}

Думаю, разберётесь и увидите разницу в подходе. Но в моём коде - тоже недоработка: мотор будет двигаться с максимально возможной скоростью шагания :)

Sliva
Offline
Зарегистрирован: 18.01.2017

int code =IR.getCode();

я очень извиняюсь. но эта строчка мне не понятна и  arduino IDE ругается. если можно объяснить 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Sliva пишет:


int code =IR.getCode();

я очень извиняюсь. но эта строчка мне не понятна и  arduino IDE ругается. если можно объяснить 

Вам слово "псевдокод" что-нибудь говорит? Точнее, его приставка "псевдо-"? Это не такой код, который будет компилироваться - это просто выражение алгоритма, чтобы был понятен принцип его построения, всё. На основе псевдокода можно написать конкретный код под конкретный компилятор, конкретные библиотеки и т.п.

В частности, приведённая строчка - это указание "получить код нажатой клавиши с пульта".  IR - это некий объект, описывающий приёмник (например, инфракрасный, или, в вашем случае, на 433 МГц), getCode - условный метод для получения кода с приемника, очевидно. Каким конкретно образом это будет сделано в том или ином случае - неважно, тут лишь продемонстрирован принцип, который не зависит от конкретных библиотек и типов приемников.

Далее - идёт сравнение кода с условным значением: условно считается, что если некий условный метод getCode вернул значение больше нуля - значит, какая-то клавиша нажата. И если это так - идёт сравнение с некой константой MY_CODE, тоже - условное сравнение, т.к. вариантов конкретного представления кода, нажатого на пульте - может быть масса. Ну и далее по списку - тоже просто демонстрация алгоритма, не более того.

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

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Sliva пишет:


int code =IR.getCode();

я очень извиняюсь. но эта строчка мне не понятна и  arduino IDE ругается. если можно объяснить 

Я могу и по-другому описать алгоритм, чтобы было больше слов. Обратите внимание, как устроены блоки кода, сравните со своими, точнее - с их вложенностью друг в друга:

void loop()
{

	if(myReceiver.receivedCodeDetected()) // если есть команда с пульта
	{
		Code code = myReceiver.getReceivedCode(); // получаем команду с пульта

		if(code == MY_CODE) // сравниваем её с нашим кодом, если это он, то
		{
			lastReceivedTime = millis(); // запоминаем время получения кода
			stepping = true; // выставляем флаг шагания мотором
		}

		myReceiver.clearReceivedCode(); // просим приёмник сделать вид, что полученного кода больше нет
	}


	if(millis() - lastReceivedTime > 1000) // если больше секунды не было команд с пульта, то
	{
		stepping = false; // больше не шагаем мотором
	}

	if(stepping) // если шагаем
	{
		stepMotor(); // делаем шаг, без учёта частоты шагания, т.е. настолько быстро, насколько можем
	}
}

 

Sliva
Offline
Зарегистрирован: 18.01.2017

Спасибо вам за коментарии. Теперь буду дальше изучать сам. Вот ещё один вопрос. Не подскажете где этому учат. А то по видео трудно что то понять

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Sliva пишет:
Спасибо вам за коментарии. Теперь буду дальше изучать сам. Вот ещё один вопрос. Не подскажете где этому учат. А то по видео трудно что то понять

Алгоритмике? Не знаю, мне кажется, для этого достаточно только определённого склада мышления, и всё. Первое, что вы должны делать перед тем, как писать любую программу - это объяснить самому себе, как эта программа должна работать. Специфика, конечно, присутствует везде, и псевдокод не может быт полностью оторван от неё, однако - это общее правило: если вы поймёте пошагово, как должна работать программа - то реализовать это дело на конкретном языке программирования - уже на порядок проще.

Вот смотрите, применительно к платформе Ардуино: эта платформа предоставляет в ваше распоряжение набор методов типа digitalWrite и пр. (чтобы спрятать от вас низкоуровневую работу с железом), и парочку функций - setup и loop. Всё, что вам нужно для первоначального понимания - это уяснить, что код, расположенный внутри setup - выполняется однократно при старте микроконтроллера, а код, расположенный в loop - вызывается постоянно с очень высокой частотой.

Далее, беря во внимание эти нюансы - вы и пишете алгоритм, излагая его на любом понятном вам языке, чтобы в дальнейшем перевести этот алгоритм на язык, понятный компилятору. При этом, естественно, берёте во внимание указанные во втором абзаце особенности вызова функций setup и loop, т.е. сразу понимаете, что обеспечением какого-либо нужного состояния вашей системы (например, "ожидание", "работа", "авария" и пр.) - вы занимаетесь сами, посредством любого доступного вам инструментария, например - введения различных флагов.

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

Флаг работаМотора : ложь;
КодПульта мойКод : 123456;
Приемник433МГц мойПриемник;
длинноеБеззнаковоеЦелое времяПоследнегоПриема;
ШаговыйДвигатель мотор;

void setup()
{
	пин(13), настроить(на выход);
	податьУровень(высокий), наПин(13);
}


void loop()
{

	если(мойПриемник.полученКод()) // если есть команда с пульта
	{
		КодПульта принятыйКод = мойПриемник.значениеПолученногоКода(); // получаем команду с пульта

		если(принятыйКод равен мойКод) // сравниваем её с нашим кодом, если это он, то
		{
			времяПоследнегоПриема = времяСНачалаРаботы(); // запоминаем время получения кода
			работаМотора = истина; // выставляем флаг шагания мотором
		}

		мойПриемник.очиститьПринятыйКод(); // просим приёмник сделать вид, что полученного кода больше нет
	}


	 если(разница между времяСНачалаРаботы() и времяПоследнегоПриема  больше секунды) // если больше секунды не было команд с пульта, то
	{
		работаМотора = ложь; // больше не шагаем мотором
	}

	если(работаМотора равно истина) // если шагаем
	{
		мотор.Шагнуть(); // делаем шаг, без учёта частоты шагания, т.е. настолько быстро, насколько можем
	}
}

Подобный псевдокод - учитывает особенности экосистемы, под которую планируется его реализовать, в данном случае - тот факт, что вызовы loop идут постоянно, и нам надо иметь флаг - крутить мотор или нет. Далее - имея такое описание алгоритма - не составит труда формализовать его под любой тип приёмника, как видите.

Sliva
Offline
Зарегистрирован: 18.01.2017

Спасибо. За разъяснения. Теперь понятно куда копать надо