Пытаюсь заставить работать DFPlayer MP3 Mini и Сервопривод. Есть вопросы.
- Войдите на сайт для отправки комментариев
Добрый день.
Делаю радиоуправляемый автомобиль на nRF24L01.
На данный момент в проекте есть:
- Arduino Nano ATmega168
- nRF24L01
- DFPlayer MP3 Mini
- сервопривод рулевого механизма
- драйвер двигателя постоянного тока
Все подключено стандартно, по-этому схемы нет, да и сути вопроса она не раскроет.
Без DFPlayer MP3 Mini все работает так как надо.
Для работы DFPlayer MP3 Mini использую библиотеку MP3TF (выбор именно этой библиотеки связан с наличием в ней функции playRepeatSingle(uint16_t track_num) для непрерывного воспроизведения заданного трека), которая использует SoftSerial.
О проблеме совместимости SoftwareSerial и Servo знаю. Поиск возможного решения вывел на связку двух библиотек: ServoTimer2.h и AltSoftSerial. AltSoftSerial использует Pin 8 и 9 и, судя по описанию библиотеки, изменить их нельзя.
А у меня Pin9 использует и библиотека RF24.h для nRF24L019. Информацию о возможности изменеия номеров Pin для этой библиотеки не нашел.
Возможные пути решения:
- использовать Serial (родной ардуиновские хардвайрный сериал) для работы DFPlayer MP3 Mini. Но тогда его надо отключать при прошивке Arduino и информации о работе MP3TF с ним нет.
- использовать другую библиотеку для работы с DFPlayer MP3 Mini, которая понимает Serial (родной ардуиновские хардвайрный сериал). Но тогда не решается вопрос "надо отключать при прошивке Arduino" и во всех мне известных библиотеках нет непрерывного проигрывания заданного трека
Прошу добавить в список "Возможные пути решения" Ваши варианты.
Благодарю!
Ниже код с использованием стандартного SoftSerial. Серва ведет себя неадекватно.
/*
*/
#define sound_starter 1 // звук стартера
#define sound_idling 2 // звук холостого хода
#define sound_limited_power 3 // балаболка ограничение мощности
#define sound_max_power 4 // балаболка максимальной мощности
#define sound_engine_starts 5 // балаболка двигатель завелся
const byte Joystic_min_sens = 123; // (настраивается экспериментально) "0 - Joystic_min_sens" это диапазон значения джойстика от центра в меньшую сторону
const byte Joystic_max_sens = 131; // (настраивается экспериментально) "Joystic_max_sens - 255" это диапазон значения джойстика от центра в большую сторону
const byte angle_steering_center = 110; // (настраивается экспериментально) угол сервы в центральном положении рулевых колес
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include <ServoTimer2.h>
ServoTimer2 steering_servo; // создание объекта servo
#include <SoftwareSerial.h>
#include <mp3TF.h>
#define READ_D2 ((PIND>>2) & 1)
mp3TF mp3tf = mp3TF (); // создание объекта MP3Player
SoftwareSerial SoundSerial(7,8);
//__________________PIN____________________
byte en_general = 5; // вход enable драйвера ходового двигателя
byte IN1_general = 4; // вход IN1 драйвера ходового двигателя
//_________________________________________
RF24 radio(9, 10); // "создать" модуль на пинах 9 и 10 Для Уно
byte recieved_data[3]; // массив принятых данных
byte direction_general_motor = 0; // 0-стоп, 1-вперед, 2-назавд
byte direction_steering_motor = 0; // 0-стоп, 1-влево, 2-вправо
byte speed_general_motor = 0; // скорость ходового мотора
byte angle_steering = 110; // угол поворота рулевой сервы в центральном положении
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
byte general_motor_speed_max = 100; // 0-255 ограничение скорости ходового двигателя
void setup() {
Serial.begin(9600); //открываем порт для связи с ПК
pinMode(2, INPUT); //пин 2 линия BUSY MP3Player
digitalWrite(2, HIGH);
steering_servo.attach(6);
steering_servo.write(angle_steering_center);// установка рулевой сервы в центральном положении
delay(200);
pinMode(en_general, OUTPUT); // настроить пин enable драйвера ходового двигателя как выход
pinMode(IN1_general, OUTPUT); // настроить пин IN1 драйвера ходового двигателя как выход
radio.begin(); //активировать модуль
radio.setAutoAck(1); //режим подтверждения приёма, 1 вкл 0 выкл
radio.setRetries(0, 15); //(время между попыткой достучаться, число попыток)
radio.enableAckPayload(); //разрешить отсылку данных в ответ на входящий сигнал
radio.setPayloadSize(32); //размер пакета, в байтах
radio.openReadingPipe(1, address[0]); //хотим слушать трубу 0
radio.setChannel(0x60); //выбираем канал (в котором нет шумов!)
radio.setPALevel (RF24_PA_MAX); //уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
radio.setDataRate (RF24_250KBPS); //скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS
//должна быть одинакова на приёмнике и передатчике!
//при самой низкой скорости имеем самую высокую чувствительность и дальность!!
radio.powerUp(); //начать работу
radio.startListening(); //начинаем слушать эфир, мы приёмный модуль
SoundSerial.begin(9600);
delay(100);
mp3tf.init (&SoundSerial); //инициализация MP3Player
delay(100);
mp3tf.playTrackPhisical(sound_starter);
while(!READ_D2) ; // wait while play track
mp3tf.playTrackPhisical(sound_idling);
delay (2000);
mp3tf.playTrackPhisical(sound_engine_starts);
while(!READ_D2) ;
mp3tf.playRepeatSingle(sound_idling);
}
void loop() {
byte pipeNo;
while ( radio.available(&pipeNo))
{ // слушаем эфир со всех труб
radio.read( &recieved_data, sizeof(recieved_data) ); // чиатем входящий сигнал
if (recieved_data[2] > Joystic_max_sens )
{
direction_general_motor = 1;
}
else if (recieved_data[2] < Joystic_min_sens )
{
direction_general_motor = 2;
}
else
{
direction_general_motor = 0;
}
GeneralMotor();
if (recieved_data[1] < Joystic_min_sens )
{
direction_steering_motor = 1;
}
else if (recieved_data[1] > Joystic_max_sens )
{
direction_steering_motor = 2;
}
else
{
direction_steering_motor = 0;
}
SteeringMotor();
if (recieved_data[0] == 1 )
{
change_max_speed_GeneralMotor();
}
}
}
void GeneralMotor()
{
switch (direction_general_motor)
{
case 1:
digitalWrite(IN1_general, HIGH);
speed_general_motor = map(recieved_data[2], Joystic_min_sens, 255, 0, general_motor_speed_max);
break;
case 2:
digitalWrite(IN1_general, LOW);
speed_general_motor = map(recieved_data[2], Joystic_max_sens, 0, 0, general_motor_speed_max);
break;
case 0:
speed_general_motor = 0;
mp3tf.playRepeatSingle(sound_idling);
break;
}
analogWrite(en_general, speed_general_motor);
}
void SteeringMotor()
{
switch (direction_steering_motor)
{
case 1:
angle_steering = map(recieved_data[1], Joystic_max_sens, 0, 110, 60);
break;
case 2:
angle_steering = map(recieved_data[1], Joystic_min_sens, 255, 110, 150);
break;
case 0:
angle_steering = 110;
break;
}
steering_servo.write(angle_steering);
}
void change_max_speed_GeneralMotor()
{
if (general_motor_speed_max == 100)
{
general_motor_speed_max = 250;
mp3tf.playRepeatSingle(sound_max_power);
}
else
{
general_motor_speed_max = 100;
mp3tf.playRepeatSingle(sound_limited_power);
}
Serial.println ("PIU!!!");
}
Нашли выход?
Может пожно использовать стандартный порт, без SoftSerial не отключая его? Модумаешь в порт будет немного мусора при управлении плеером, это как-то не страшно, в остальное время он ничего в порт не плюёт, при других операциях с портом он никак не отреагирует, тк проверяет контрольную сумму команды.
PS Понятно, много времени прошло, но может кто повторять будет, и отзовётся тут, у самого пинов не хватает на 8266, хочу такой вариант испробовать, но в командировке нет возможности.
Добрый день.
Проект пока отложен. Решения не нашел, но склоняюсь к использованию Ардуино Мега, там хардовых портов хватит на все
DF MP3 и через Software Serial работает прекрасна. Просто ноги поменятьна те, которые не используются таймером сервы.
DF MP3 и через Software Serial работает прекрасна. Просто ноги поменятьна те, которые не используются таймером сервы.
а я все три таймера использую в режиме PWM, не мешают, по крайней мере миллис и микрос отрабатывает нормально, видимо надо библиотеку servo править...
DF MP3 и через Software Serial работает прекрасна. Просто ноги поменятьна те, которые не используются таймером сервы.
Ну, тут как попадёшь...
SoftwareSerial::write() делает cli() и в Servo.h на краткое время прекращается программная генерация ШИМ. Серву начинает дёргать.
DF MP3 и через Software Serial работает прекрасна. Просто ноги поменятьна те, которые не используются таймером сервы.
Ну, тут как попадёшь...
SoftwareSerial::write() делает cli() и в Servo.h на краткое время прекращается программная генерация ШИМ. Серву начинает дёргать.
Да, точно. Ну, значить, Мегу нада брать.
328PB ещё выручает.
Решил немного повозиться с проектом.

в общем заработал первый вариант решения проблемы:
"- использовать Serial (родной ардуиновские хардвайрный сериал) для работы DFPlayer MP3 Mini. Но тогда его надо отключать при прошивке Arduino и информации о работе MP3TF с ним нет. "
Ничего отключать не надо, все работает как надо. Библиотеку MP3TF немного переделал для работы с хардвайрным сериалом.