Пытаюсь заставить работать DFPlayer MP3 Mini и Сервопривод. Есть вопросы.

swa
Offline
Зарегистрирован: 28.03.2014

Добрый день.

Делаю радиоуправляемый автомобиль на 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!!!");
}

 

udavst
udavst аватар
Offline
Зарегистрирован: 29.11.2013

Нашли выход?

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

PS Понятно, много времени прошло, но может кто повторять будет, и отзовётся тут, у самого пинов не хватает на 8266, хочу такой вариант испробовать, но в командировке нет возможности.

swa
Offline
Зарегистрирован: 28.03.2014

Добрый день.

Проект пока отложен. Решения не нашел, но склоняюсь к использованию Ардуино Мега, там хардовых портов хватит на все

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

DF MP3 и через Software Serial работает прекрасна.  Просто ноги поменятьна те, которые не используются таймером сервы. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

DetSimen пишет:

DF MP3 и через Software Serial работает прекрасна.  Просто ноги поменятьна те, которые не используются таймером сервы. 

а я все три  таймера использую в режиме PWM, не мешают, по крайней мере миллис и микрос  отрабатывает нормально, видимо надо библиотеку servo править...

sadman41
Offline
Зарегистрирован: 19.10.2016

DetSimen пишет:

DF MP3 и через Software Serial работает прекрасна.  Просто ноги поменятьна те, которые не используются таймером сервы. 

Ну, тут как попадёшь...

SoftwareSerial::write() делает cli() и в Servo.h на краткое время прекращается программная генерация ШИМ. Серву начинает дёргать.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

sadman41 пишет:

DetSimen пишет:

DF MP3 и через Software Serial работает прекрасна.  Просто ноги поменятьна те, которые не используются таймером сервы. 

Ну, тут как попадёшь...

SoftwareSerial::write() делает cli() и в Servo.h на краткое время прекращается программная генерация ШИМ. Серву начинает дёргать.

Да, точно.  Ну, значить, Мегу нада брать. 

sadman41
Offline
Зарегистрирован: 19.10.2016

328PB ещё выручает.

swa
Offline
Зарегистрирован: 28.03.2014

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