Помогите отредактировать код

KeriLs
Offline
Зарегистрирован: 31.07.2016

Здравствуйте. Написал скетч для управления мотором постоянного тока через ИК датчик. Работает. Но вот теперь хочу внести некоторые изменения. Мне нужно чтобы при нажатии на одну из кнопок на пульте мотор начинал работать, а как только отпускаю кнопку - прекращал. Вот схема подключения:

В моём скетче, при поступлении сигнала на датчик, мотор  вращается непрерыно - до тех пор пока не поступит другая команда.

#include <IRremote.h>
#include <IRremoteInt.h>
#include <AFMotor.h>

IRrecv irrecv(2); // указываем вывод, к которому подключен приемник
decode_results results;

// создаем объект motor №2, ШИМ 64 кГц
AF_DCMotor motor2(2, MOTOR12_64KHZ);

void setup() {
  irrecv.enableIRIn(); // запускаем прием

Serial.begin(9600); // устанавливаем скорость передачи по посл. порту 9600 бод
motor2.setSpeed(200); // устанавливаем скорость вращения 200/255

}

void loop() {
  if ( irrecv.decode( &results )) { // если данные пришли
    switch ( results.value ) {
    case 0xFD00FF: // нажимаем кнопку "1"
        motor2.run(FORWARD); // вращение вперед
        break;
    case 0xFD807F: // нажимаем кнопку "2"
        motor2.run(BACKWARD); // в другую сторону
        break;
    } 
    irrecv.resume(); // принимаем следующую команду
  }
}

Я пытался сам внести изменения, но программа бракует мои труды.

#include <IRremote.h>
#include <IRremoteInt.h>
#include <AFMotor.h>

IRrecv irrecv(2); // указываем вывод, к которому подключен приемник
decode_results results;

// создаем объект motor №2, ШИМ 64 кГц
AF_DCMotor motor2(2, MOTOR12_64KHZ);

char BUTTON_1 = "FD00FF";
char BUTTON_2 = "FD807F";

void setup() {
  irrecv.enableIRIn(); // запускаем прием

Serial.begin(9600); // устанавливаем скорость передачи по посл. порту 9600 бод
motor2.setSpeed(200); // устанавливаем скорость вращения 200/255

}

void loop() {
  if (digitalRead(BUTTON_1) == HIGH) { // нажимаем кнопку "1"
     digitalWrite(motor2.run == FORWARD); // вращение вперед
     }
  else {
     digitalWrite(motor2.run == RELEASE);
     }
  if (digitalRead(BUTTON_2) == HIGH) { // нажимаем кнопку "2"
     digitalWrite(motor2.run == BACKWARD); // вращение назад
     }
  else {
     digitalWrite(motor2.run == RELEASE);
     } 
    irrecv.resume(); // принимаем следующую команду
}

 

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

KeriLs пишет:

программа бракует мои труды.

Не объясните в чём проблема? Самим догадываться?

Кстати, а что это у Вас в строках 11 и 12. Описано как одиночный символ, а присваивается целая строка. Это для чего? Что Вы хотели этими строками сказать?

KeriLs
Offline
Зарегистрирован: 31.07.2016

Не объясните в чём проблема? Самим догадываться?

Вот проблема:

Arduino: 1.6.11 (Windows 7), Плата:"Arduino/Genuino Uno"
 
D:\Documents\Arduino\shild_motor_i_datchick2\shild_motor_i_datchick2.ino:11:17: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]
 
 char BUTTON_1 = "FD00FF";
 
                 ^
 
D:\Documents\Arduino\shild_motor_i_datchick2\shild_motor_i_datchick2.ino:12:17: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]
 
 char BUTTON_2 = "FD807F";
 
                 ^
 
In file included from D:\Documents\Arduino\shild_motor_i_datchick2\shild_motor_i_datchick2.ino:3:0:
 
D:\Documents\Arduino\shild_motor_i_datchick2\shild_motor_i_datchick2.ino: In function 'void loop()':
 
C:\Program Files\Arduino\libraries\adafruit-Adafruit-Motor-Shield-library-fb5b17c/AFMotor.h:108:17: error: invalid use of member function (did you forget the '()' ?)
 
 #define FORWARD 1
 
                 ^
 
D:\Documents\Arduino\shild_motor_i_datchick2\shild_motor_i_datchick2.ino:24:33: note: in expansion of macro 'FORWARD'
 
      digitalWrite(motor2.run == FORWARD); // вращение вперед
 
                                 ^
 
C:\Program Files\Arduino\libraries\adafruit-Adafruit-Motor-Shield-library-fb5b17c/AFMotor.h:111:17: error: invalid use of member function (did you forget the '()' ?)
 
 #define RELEASE 4
 
                 ^
 
D:\Documents\Arduino\shild_motor_i_datchick2\shild_motor_i_datchick2.ino:27:33: note: in expansion of macro 'RELEASE'
 
      digitalWrite(motor2.run == RELEASE);
 
                                 ^
 
C:\Program Files\Arduino\libraries\adafruit-Adafruit-Motor-Shield-library-fb5b17c/AFMotor.h:109:18: error: invalid use of member function (did you forget the '()' ?)
 
 #define BACKWARD 2
 
                  ^
 
D:\Documents\Arduino\shild_motor_i_datchick2\shild_motor_i_datchick2.ino:30:33: note: in expansion of macro 'BACKWARD'
 
      digitalWrite(motor2.run == BACKWARD); // вращение назад
 
                                 ^
 
C:\Program Files\Arduino\libraries\adafruit-Adafruit-Motor-Shield-library-fb5b17c/AFMotor.h:111:17: error: invalid use of member function (did you forget the '()' ?)
 
 #define RELEASE 4
 
                 ^
 
D:\Documents\Arduino\shild_motor_i_datchick2\shild_motor_i_datchick2.ino:33:33: note: in expansion of macro 'RELEASE'
 
      digitalWrite(motor2.run == RELEASE);
 
                                 ^
 
exit status 1
Ошибка компиляции для платы Arduino/Genuino Uno.
 
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"
 
 
Кстати, а что это у Вас в строках 11 и 12. Описано как одиночный символ, а присваивается целая строка. Это для чего? Что Вы хотели этими строками сказать?
 
Я хотел этим сказать то,  что мне нужно задать программе переменные в виде сигналов "FD00FF" и "FD807F". В разделе "Тип данных" я перепробовал почти все команды. Больше всего подходит "char" т.к. понимает и цифры и буквы. Но, к сожалению, я узнал позже что её можно задавать только 1 символ.
 
KeriLs
Offline
Зарегистрирован: 31.07.2016

Ещё мне сказали что "digitalRead" считывает состояние пина, т.е. применим только для физически подключенных проводами кнопок. Для команд с пульта это не подходит

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

KeriLs пишет:

Я хотел этим сказать то,  что мне нужно задать программе переменные в виде сигналов "FD00FF" и "FD807F".

 
Вот смотрите, Вы в 11 строке определяете BUTTON_1 как Вы выражаетсяь "в виде сигнала". А в строке 23 Вы этот "сигнал" используете в качестве номера пина для digitalRead.
 
Понимаете, что у Вас мешанина, причём мешанина в первую очередь не в программе, а в голове.
 
Давайте сделаем так: Вы спокойно и внятно словами (просто русскими словами) напишете, что Вы хотите сделать. Покажете, я сделаю замечания и мы доведём это до настоящего строго описания будущей программы. А вот тогда, Вы только начнёте писать программу и увидите нсколько это легче - писать программу по хорошо описанноум алгоритму.
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

KeriLs пишет:

Ещё мне сказали что "digitalRead" считывает состояние пина, т.е. применим только для физически подключенных проводами кнопок. Для команд с пульта это не подходит

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

KeriLs
Offline
Зарегистрирован: 31.07.2016

Хорошо. У меня есть ардуино, мотор шилд, мотор постоянного тока, ИК датчик и пульт к нему. Я хочу с помощью пульта управлять мотором, но так чтобы при нажатии на одну кнопку он вращался в нужном направлении, а при отпускании прекращал работу. Представьте себе процесс управления радиоуправляемой машинкой. Мне нужно что-то подобное, но пока что на ИК датчике.

Всё подключил как показано на этом рисунке:

Схема работает, проверял на этом скетче:

#include <IRremote.h>
#include <IRremoteInt.h>
#include <AFMotor.h>

IRrecv irrecv(2); // указываем вывод, к которому подключен приемник
decode_results results;

// создаем объект motor №2, ШИМ 64 кГц
AF_DCMotor motor2(2, MOTOR12_64KHZ);

void setup() {
  irrecv.enableIRIn(); // запускаем прием

Serial.begin(9600); // устанавливаем скорость передачи по посл. порту 9600 бод
motor2.setSpeed(200); // устанавливаем скорость вращения 200/255

}

void loop() {
  if ( irrecv.decode( &results )) { // если данные пришли
    switch ( results.value ) {
    case 0xFD00FF: // нажимаем кнопку "1"
        motor2.run(FORWARD); // вращение вперед
        break;
    case 0xFD807F: // нажимаем кнопку "2"
        motor2.run(BACKWARD); // в другую сторону
        break;
    } 
    irrecv.resume(); // принимаем следующую команду
  }
}

[/quote]

 
Вот смотрите, Вы в 11 строке определяете BUTTON_1 как Вы выражаетсяь "в виде сигнала". А в строке 23 Вы этот "сигнал" используете в качестве номера пина для digitalRead.

[/quote]

Так будет правильнее?

void loop() {
  if (digitalRead(2, BUTTON_1) == HIGH) { // нажимаем кнопку "1"
     digitalWrite(motor2.run == FORWARD); // вращение вперед
     }
  else {
     digitalWrite(motor2.run == RELEASE);
     }
  if (digitalRead(2, BUTTON_2) == HIGH) { // нажимаем кнопку "2"
     digitalWrite(motor2.run == BACKWARD); // вращение назад
     }
  else {
     digitalWrite(motor2.run == RELEASE);
     } 
    irrecv.resume(); // принимаем следующую команду
}

Вот алгоритм, как вы просили:

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

Ага, ну это уже лучше, но надо дальше работать. Там нужно не "жмём кнопку", а "полуен сигнал от ПДУ". Правильно?

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

Скажите, правильно ли я понимаю, что Вы хотите нажимать кнупку на ПДУ, который передаёт инфракрасный сигнал и, пока она нажата, вращать двигатель, а когда её отпустили, двигатель останваливать. Так?

Если так, то Вам для начала (прежде, чем придумывать алгоритм) неплохо бы изучить особенности своего оборудования. Я не знаю, что у Вас за ПДУ, но скорее всего (я их много видел) там всё не так просто. Может быть Вам повезло, но это большая редкость.

Итак, запустите вот такой скетч

template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }

#include "IRremote.h"

IRrecv irrecv(2);

void setup() {
	Serial.begin(115200);
	Serial << "Fun begins!!!\n";
	irrecv.enableIRIn();
}

enum STATES { BTN_PRESSED, BTN_RELEASED };

void loop() {
	static STATES state = BTN_RELEASED;
	decode_results results;
	
 	if (irrecv.decode(&results)) {
		if (state == BTN_RELEASED) {
			state = BTN_PRESSED;
			Serial << "Button pressed\n";
		}
		irrecv.resume();
	} else {
		if (state == BTN_PRESSED) {
			state = BTN_RELEASED;
			Serial << "Button released\n";
		}
  }
}

Он говорит когда, по мнению Ардуины, кнопка на Вашем ПДУ нажата, а когда отпущена.

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

Почти уверен, что результат Вас несколько удивит и Вы поймёте, что алгоритм должен быть совсем другим. Может, конечно, Вам повезёт, но я сомневаюсь.

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