Проблема с аудио модулем DFPlayer mini и инфракрасным датчиком движения HC-SR501

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

Здравствуйте!

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

1. Задействовано 6 модулей по 8 RGB  светодиодов WS2812, но больше 4 модулей последовательно подключить не получается. Первые 4 работают исправно, оставшиеся 2 с переменным успехом. Двумя параллельными линиями тоже не получается запустить: первая линия из 3х модулей работает исправно, а во второй только первый модуль срабатывает. Как можно решить это?

2. В тестовом режиме загрузила на флешку 3 mp3 файла проверить аудио модуль DFPlayer mini, но проблема в том, что каждая композиция играет всего 3-5 секунд и переключается сразу на другую, хотя в скетче указывала проигрывать полностью композиции друг за другом.

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

Задействовано: Arduino Uno R3, 6 модулей по 8 RGB  светодиодов WS2812, инфракрасный датчик движения HC-SR501, аудио модуль DFPlayer mini.

Вот скетч 

 
#include <mp3TF.h>
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define count_led 32
Adafruit_NeoPixel strip = Adafruit_NeoPixel(count_led, PIN, NEO_GRB + NEO_KHZ800); 
 
mp3TF mp3tf = mp3TF ();
 
//VSS, OUT, GND => 5VC, Digital pin 4, GND
int pirPin = 4;               
int  mp3Pin =  1;              
int val = 0;  
 
//
void setup () {
Serial.begin (9600);
    mp3tf.init (&Serial);
    mp3tf.setVolume (20);
    
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  
Serial.begin(9600);           
pinMode(pirPin, INPUT);      
pinMode(mp3Pin, OUTPUT);  
}
 
//
void loop () {
  
mp3tf.play (1);
       mp3tf.next ();
       mp3tf.play (2);
       mp3tf.next ();
       mp3tf.play (3);
       
 
 
 // Some example procedures showing how to display to the pixels:
  rainbowCycle(2); // change for speed
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait)
{
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
       delay(wait);
  }
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait)
{
  uint16_t i, j;
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  
val = digitalRead(pirPin); 
if (val == HIGH) {            
digitalWrite(mp3Pin, HIGH); 
Serial.println("Motion!");    
}
else {
digitalWrite(mp3Pin, LOW);    
Serial.println("No motion");  
}
}
 
 
Что я делаю не так?
Буду очень признательная за советы и помощь.
Aleks_neofit
Aleks_neofit аватар
Offline
Зарегистрирован: 28.12.2016

Yanot, в таком виде ваш код читать неудобно - http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

выложите схему подключения (можно воспользоваться Fritzing - http://fritzing.org/download/?donation=0 )

 

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017
#include <mp3TF.h>
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define count_led 32
Adafruit_NeoPixel strip = Adafruit_NeoPixel(count_led, PIN, NEO_GRB + NEO_KHZ800); 
 
mp3TF mp3tf = mp3TF ();
 
//VSS, OUT, GND => 5VC, Digital pin 4, GND
int pirPin = 4;               
int  mp3Pin =  1;              
int val = 0;  
 
//
void setup () {
Serial.begin (9600);
    mp3tf.init (&Serial);
    mp3tf.setVolume (20);
    
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  
Serial.begin(9600);           
pinMode(pirPin, INPUT);      
pinMode(mp3Pin, OUTPUT);  
}
 
//
void loop () {
  
mp3tf.play (1);
       mp3tf.next ();
       mp3tf.play (2);
       mp3tf.next ();
       mp3tf.play (3);
       
 
 
 // Some example procedures showing how to display to the pixels:
  rainbowCycle(2); // change for speed
}
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait)
{
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
       delay(wait);
  }
}
// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait)
{
  uint16_t i, j;
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  
val = digitalRead(pirPin); 
if (val == HIGH) {            
digitalWrite(mp3Pin, HIGH); 
Serial.println("Motion!");    
}
else {
digitalWrite(mp3Pin, LOW);    
Serial.println("No motion");  
}
}

 

Aleks_neofit
Aleks_neofit аватар
Offline
Зарегистрирован: 28.12.2016

Yanot, откройте секрет  

- дайте ссылку на сайт где вы брали схему подключения

- откуда берёте питание для  WS2812? (параметры желательно)

- маркировка WS2812 без букв B, C, S  ?

Yanot, у вас подключено 48 светодиодов,  -   #define numPixels 48;     #define count_led 32    

если маркировка WS2812 - тогда каждый светодиод потребляет до 20 мА, когда включен один из цветов RGB, соответственно, если включить белый цвет на полную мощность, то потребление в пике будет 60 мА. Таким образом, вы должны умножить 20 мА на то количество светодиодов, которые вы подключаете — это будет величина тока при включенном одном цвете на всех светодиодах. У вас 48 светодиодов, поэтому 48*20=0,96A. А если включить белый цвет на всех светодиодах, то получается 48*60=2,88A. поэтому интересует питание светодиодов.

Rip датчику обычно дают время для калибровки  (10-60 сек. по даташиту)   int calibrationTime = 30; 

Yanot, если мои вопросы ставят вас в тупик или они для вас детские - спрашивайте, пишите не стесняйтесь.

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

Alex_neofit, секрета и нет никакого.

1.За основу взят проект интерактивного светилька грозовая туча от дизайнера Ричарда Кларксона, посмотрела, из чего состоит вся электронная начинка и стала подключать  все по описаниям подключения составных частей.

Схему подключения могу показать на фотографии. Как ее рисовать не знаю, увы не сильна в этом, только учусь.

2. Питание для модулей светодиодов идет от платы. К ней подключен powerbank на 1 ампер.

3. Маркировок никаких нет, прям так и называется модуль из 8 RGB  светодиодов с чипом адресной адресации WS2812  в формфакторе 5050.

Подключено все же 32 светодиода, это я, видимо, не досмотрела при редактировании скетча из библиотеки.

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

Остается теперь момент с плеером.Почему он так себя ведет, перескакивая с композиции на композицию?

 

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

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

Yanot пишет:

2. Питание для модулей светодиодов идет от платы. К ней подключен powerbank на 1 ампер.

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

Питание от платы не есть гуд!
Давненько здесь не появлялись ТС с литературным русским )))

да, два раза порт незачем инициализировать, удалите строку 23

 

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

 Ну а куда ж без русского и литературного).

На контроллере стоит еще сенсор шилд, но от него дополнительно питается плеер.

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

Yanot пишет:

 Ну а куда ж без русского и литературного).

ссылкой не поделитесь, откуда брали код

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

Код для светодиодов брала  из библиотеки Adafruit_NeoPixel  из примеров. Вот ссылка https://github.com/adafruit/Adafruit_NeoPixel

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

 

Aleks_neofit
Aleks_neofit аватар
Offline
Зарегистрирован: 28.12.2016

Yanot, 36 светодиодов марки WS2812 - потребляют максимум 2,16А.  у вас 1А.

Дабы уменьшить потребление тока поставьте яркость 50%    #define BRIGHTNESS 50;

С мр3 плеером непонятно условие: в цикле он включен постоянно - 

29 void loop () {
30   
31 mp3tf.play (1);

а что он должен делать по сработке RIP - 

76 val = digitalRead(pirPin);
77 if (val == HIGH) {           
78 digitalWrite(mp3Pin, HIGH);

Мызыка должна играть постоянно    или   включается и меняется при сработке RIP?

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

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

mp3 файлики имя не более 8 символов и лaтиницей?

OlegK
OlegK аватар
Онлайн
Зарегистрирован: 26.11.2014

Yanot
Вы уверены, что этот участок кода должен находиться в функции Wheel?

val = digitalRead(pirPin); 
if (val == HIGH) {            
digitalWrite(mp3Pin, HIGH); 
Serial.println("Motion!");    
}
else {
digitalWrite(mp3Pin, LOW);    
Serial.println("No motion");  
}

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

Aleks_neofit
Aleks_neofit аватар
Offline
Зарегистрирован: 28.12.2016

ua6em Да для этой библиотеки всё так.

У меня с Дью мр3 модуль заработал только с библиотекой DFRobotDFPlayerMini

главное чтоб название файла начиналось с 0001 ***. mp3

  • 0001.mp3
  • 0002Chasing The Sun.mp3
Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

Alex_neofit, спасибо за совет с яркостью. Не задумывалась про это даже. Буду знать теперь. То есть, если я подключу светодиоды напрямую к powerbank с нужной мощностью, то заработает вся сеть?
С подключением mp3 модуля была целная эпопея, перепробовала разные библиотеки.
Про датчик движения. Не понимаю как в коде прописать условие срабатывание музыки(громыхание грома/мелодии) на появление движения либо приближение к светильнику. Модуль mp3 должен получается не всегда должен быть включен?
Спасибо вам большое за отклик и помощь!)

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

Ua6em, mp3 файлы названы 0001, 0002, 0003.

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

OlegK, видимо, я неправильно скомпелировала скетчи. Как это можно изменить и в какой части кода разместить?

OlegK
OlegK аватар
Онлайн
Зарегистрирован: 26.11.2014

Yanot пишет:
Как это можно изменить и в какой части кода разместить?

Ну, судя по всему, там определяется движение от датчика присутствия и, взависимости от этого, происходит включение-выключение "озвучивания". И раз это должно выполняться всегда, то опрашивать в loop.
mp3Pin у вас для чего служит?

И не нужно постоянно запускать mp3tf.play() - обнаружили движение, запустили первый файл (один раз!) и  просто проверяете состояние пина Busy (плата плеера) - низкий уровень "играем", высокий - "не играем". Обнаружили низкий уровень - включаете след. трек mp3tf.next().
Нет движения или нужно остановить - mp3tf.stop();

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

OlegK, спасибо за пояснения. Попробую утром переписать код в соответствии с вашими замечаниями. Надеюсь, получится запустить.
А как проверить состояние пина Busy, через монитор порт?

OlegK
OlegK аватар
Онлайн
Зарегистрирован: 26.11.2014

Можно прицепить выход мп3-платы "busy" к свободному пину дуины и читайть - digitalRead(этот_пин). Если лог. 0, то что-то проигрывается, если 1, то не проигрывается. Так сказано в мануале на плату DFPlayer.

Как-нибудь так попробовать.
Более опытные товарищи наверняка что-то поинтереснее бы придумали...
Естественно, дополните своими функциями, которые я пропустил и пины пронумеруйте как нужно.
Дополню ещё, что лучше использовать для подключения платы плеера софтовый сериал (добавил в код ниже), а хардварный будете использовать для вывода информационных сообщений.

На пальцах: раз в полсекунды проверяете датчик движения и при наличии такового, запускаете первый трек и взводите флаг, что бы это было один раз. Затем мониторите состояние пина busy и если плеер уже не проигрывает, а движение всё ещё имеется, то запускается след. трек. Если движение прекратилось, останавливаем воспроизведение и сбрасываем флаг. До след. срабатывания...

#include <SoftwareSerial.h>
#define pirPin 4
#define mp3Pin 5
#define busyPin 6

SoftwareSerial SoftSerial(10,>11);// RX,TX

void setup() {
   SoftSerial.begin(9600);
   mp3tf.begin(SoftSerial);
}

void loop () {
  static boolean flag = false;

  /* Update with 500ms interval */
  static uint32_t prevMillis = millis();
  if (millis() - prevMillis > 500) {
    prevMillis = millis();

    //Check PIR-sensor
    boolean motion = digitalRead(pirPin);
    if (motion && !flag) {
      digitalWrite(mp3Pin, motion);
      flag = true;
      mp3tf.play(1); //start once!
    }

    //delay(10); //maybe it need set small delay here...

    //Check busy pin
    boolean isPlayStopped = digitalRead(busyPin);
    if (isPlayStopped && flag) {//not playing
      if (motion) { //still motion detected
        mp3tf.next(); //play next
      } else {
        mp3tf.stop();// no motion, stop
        flag = false; //allow work to next time
      }
    }
    rainbowCycle(2); // change for speed
  }
}
Aleks_neofit
Aleks_neofit аватар
Offline
Зарегистрирован: 28.12.2016

Yanot, могу предложить простой вариант - запустил у себя на Дью - 

#include "DFRobotDFPlayerMini.h"
DFRobotDFPlayerMini Player; // сокращаем для удобства
int pirPin = 4;  // инициализируем пин для получения сигнала от пир

void setup()
{
  Serial2.begin(9600);
  pinMode(pirPin, INPUT); //Устанавливаем PIR как вход
  digitalWrite(pirPin, LOW);//По умолчанию PIR в состояние 0
  pinMode(50, INPUT);//Любой свободный пин подключаем на busy (16 pin mp3 модуля)
  Player.begin(Serial2);//Запускаем плеер
  Player.volume(20);  //Устанавливаем громкость от 0 до 30
  Player.play(1);  //При включении чудо-светильника лёгкий звуковой сигнал ))
}

void loop(){
  if(digitalRead(pirPin)==HIGH && digitalRead(50)==HIGH){ //Если сработал PIR и плеер свободен
          Player.next(); //следующая композиция
          } else return; //если в комнате никто не двигается - музыка не надо.
}
   

Библиотека, которой я пользуюсь мне нравится - скачать можно здесь - https://github.com/DFRobot/DFRobotDFPlayerMini/archive/1.0.1.zip  

Описание и тестовые скетчи - https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299

Yanot
Yanot аватар
Offline
Зарегистрирован: 19.03.2017

Alex_neofit, большое спасибо! Сейчас опробую все и отпишусь что получилось.

Aleks_neofit
Aleks_neofit аватар
Offline
Зарегистрирован: 28.12.2016

 Извиняюсь, вам на UNO нужен программный порт

   
#include "DFRobotDFPlayerMini.h"
#include "SoftwareSerial.h" // программный порт
DFRobotDFPlayerMini Player; // сокращаем для удобства
int pirPin = 4;  // инициализируем пин для получения сигнала от пир

void setup()
{
  SoftwareSerial Serial2(10, 11); // RX, TX
  Serial2.begin(9600);
  pinMode(pirPin, INPUT); //Устанавливаем PIR как вход
  digitalWrite(pirPin, LOW);//По умолчанию PIR в состояние 0
  pinMode(50, INPUT);//Любой свободный пин подключаем на busy (16 pin mp3 модуля)
  Player.begin(Serial2);//Запускаем плеер
  Player.volume(20);  //Устанавливаем громкость от 0 до 30
  Player.play(1);  //При включении чудо-светильника лёгкий звуковой сигнал ))
}

void loop(){
  if(digitalRead(pirPin)==HIGH && digitalRead(50)==HIGH){ //Если сработал PIR и плеер свободен
          Player.next(); //следующая композиция
          } else return; //если в комнате никто не двигается - музыка не надо.
}
   

подключите резистор 1k между Arduino Tx и MP3 RX , так как напряжение работающего модуля Mini DFPlayer является 3.3V.

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

Yanot пишет:
видимо, я неправильно скомпелировала

"пилите, Шура, пилите" )))