Воспроизведение звука на Ардуино

Дм Бел
Offline
Зарегистрирован: 22.11.2016

Всем добрый день. Использую ардуино для модуля автоматики. Нужно, среди прочего, воспроизводить некоторое музыкальное сопровождение. Есть флеш модуль под SD карты, хочу воспроизводить файлы, закачанные на флешку. Всё было бы хорошо, но проблема в том, что цифровые выходы у меня почти все заняты, остались только RX/TX (1 и 2) и аналоговых несколько штук. Пытаюсь использовать библиотеку TMRpcm:

https://github.com/TMRh20/TMRpcm

скажите, может у кого-то есть подобный опыт?

Волшебник
Offline
Зарегистрирован: 22.12.2016

В описании библиотеки сказано, что на Уно она использует таймер-1, и соответственно пины 9 & 10. Вариантов 2, перенести то что подключено к этим пинам на аналоговые ( они могут быть инициализированы как цифровые), или добавлять внешние хардваре ресурсы, типа ЦАПа / декодеры для воспроизведения звука "классическим" способом

Дм Бел
Offline
Зарегистрирован: 22.11.2016

Спасибо за ответ. Ардуино у меня - Нано. В данном смысле, я так думаю, будет аналогично Уно.

"Они могут быть инициализированы как цифровые."

Скажите, как это сделать? Мне нужно инициализация как цифровой вход. То есть - у меня и 9 и 10-ка являются входами. Я бы их перенес на аналоговые пины.

Дм Бел
Offline
Зарегистрирован: 22.11.2016

Еще вопрос. Вы пишете - 9 и 10. То есть - динамик нужно подключать между двумя пинами?

SLKH
Offline
Зарегистрирован: 17.08.2015

Дм Бел пишет:

Спасибо за ответ. Ардуино у меня - Нано. В данном смысле, я так думаю, будет аналогично Уно.

аналогично, но не равно. у наны (и про мини) на 2 аналоговых входа больше.

 

Цитата:
"Они могут быть инициализированы как цифровые."

Скажите, как это сделать? Мне нужно инициализация как цифровой вход. То есть - у меня и 9 и 10-ка являются входами. Я бы их перенес на аналоговые пины.

RTFM: http://arduino.ru/Tutorial/AnalogInputPins

olegtur77
Offline
Зарегистрирован: 09.04.2015

Вот похожая реализация модуля, есть исходники, можно глянуть тут http://www.getchip.net/posts/087-attiny2313-sd-card-talking-device/ или тут http://www.parkflyer.ru/ru/blogs/view_entry/9979/ 

Дм Бел
Offline
Зарегистрирован: 22.11.2016

Пробую разобраться со звуком пока что. Увы, но не работает. SD подключил по вот такой схеме (кард ридер такой же):

http://zelectro.cc/SD_card_module_Arduino

пробую код, похожий на basic.ino, звука нет. Подключение флешки прозвонил, 5 и 3.3 вольта проверил, всё в норме. Флешка (4gb, silicon power, sdhc) записана в формате fat32, файл 'music' есть и нормально проигрывается винампом на компьютере. Брал его из audio_samples. Подключал динамик как между 9 и 10 так и между 9 и землей.

Волшебник
Offline
Зарегистрирован: 22.12.2016

Трудно сказать не видя скетча, возможно переопределение пинов, надо пробовать "голый" пример из библиотеки - не модифицирую ни чего. Я посмотрел, у Нано Д9 и Д10 как и у ардуино Уно, пины ассоциированы с таймером-1. 

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

Дм Бел
Offline
Зарегистрирован: 22.11.2016

Победил кажется!!! :) Заработало, проблема была в том, что не вызвал 'SD.begin'. Насчет усилителя в курсе. Мне пока что хотя бы проверить нужно было. Я поставил динамик между 9 и общим проводом, последовательно - резистор 200 Ом, что бы не перегружать выход. Всё нормально заработало, на 10-ку сажать не обязательно, разницы с общим проводом нет.  Всем огромное спасибо!

Дм Бел
Offline
Зарегистрирован: 22.11.2016

Новые данные :) 10-ка, похоже, тоже завязана алгоритмом. Возможно, что противофазно всё таки работают.

Волшебник
Offline
Зарегистрирован: 22.12.2016

Стерео?

Дм Бел
Offline
Зарегистрирован: 22.11.2016

Судя по wav файлам и описанию - моно, скорее всего в противофазе с 9 кой работают. На 10й выход у меня было подключено реле через ключ-транзистор. Получилось весело :) Кто баловался когда-то дисководами, тот помнит, что ими можно музыку играть. Оказалось, что и реле вполне пригодны :)

Как я понимаю - то в либе есть шанс и стерео сделать, не знаю только, хватит ли скорости процессора. Генератор работает хитро. Ткнул осцилограф на выход, генерирует поднесущую порядка 68 кгц и по ней - звук. Звук получается при том довольно чистый. Можно было бы несущую хорошо зафильтровать, должно стать еще лучше.

olegtur77
Offline
Зарегистрирован: 09.04.2015

А я тут с мр3 (DFplayer mini mp3) модулем поигрался , оказалось немного интереснее.Ну и не нужно ктому же нагружать проц обработкой звука.

https://yadi.sk/d/7wGV32MX3EEBvn  файлы

https://www.youtube.com/watch?v=5h1367vmld4&t=18s видео

,Правда при повторе трека есть пауза.

код

#include <Servo.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>

int prevThrottle = 0; //предыдущее значение газа
int currThrottle = 0; // текущее значение газа
int playingSound = 0; // текущий трек
int potpin = 0;  // вход для потенциометра, газ
int pos = 90;    // начально положение сервы "шасси"
int val;    // переменная ацп
int buttonPin = 4;     // вход управления сервой шасси, тумлер
//int motor =  5;      // выход ШИМ для колекторного мотора, газ
int ledPin =  7;      // индикатор шасси поднято/опущено, один свд на землю, другой на +5
int buttonState = 0;  
Servo gear;  // объект серво "шасси"
Servo motor;  // объект серво "мотор" для управления станд регулятором оборотов

void setup(){
    gear.attach(6);  // объект"шасси"
    motor.attach(5);  // объект "мотор"
    pinMode(ledPin, OUTPUT);  // initialize the pushbutton pin as an input:
    //pinMode(motor, OUTPUT);  // initialize the pushbutton pin as an input:
    pinMode(buttonPin, INPUT_PULLUP);//тумблер, с подтяжкой
    Serial.begin(9600);
    mp3_set_serial (Serial);  //set Serial for DFPlayer-mini mp3 module 
    mp3_set_volume (20);//выставляем громкость модуля мр3
  }
  
  void loop(){
      
buttonState = digitalRead(buttonPin);//читаем состояние тумблера шасси и отрабатываем, если оно противоположно.
  
if (buttonState == LOW) {
        digitalWrite(ledPin, HIGH);
        while ( pos < 90){
        gear.write(pos);
        pos++;              
        delay(20);  
        }
        }
     else {
        digitalWrite(ledPin, LOW);
        while( pos >  0){
        gear.write(pos); 
        pos --;
        delay(20);
        }
        }
  

  val = analogRead(potpin); //читаем аналоговый вход, положение газа
  /*
   val = map(val, 0, 1023, 0, 255);     // обычный ШИМ регулятор для коллекторного мотора, через полевик
  analogWrite(motor,val);                  // преобразовываем значение от ацп в шим 0..255 
  */
  
  val = map(val, 0, 1023, 0, 180);     // или преобразовываем значение от ацп в шим 0..180грд,мин-макс газа регулятора
  motor.write(val);                
   
     if(val <= 20){   // положение газа минимум(0) - молчим
        currThrottle = 0;
     }
     if((val > 20) && (val <= 50)){
        currThrottle = 1; // газ 1 диапазон
        // mp3_play (); // если трек игрался, повторяем его
      
     }
      if((val > 51) && (val <= 80)){
        currThrottle = 2;// газ 2 диапазон
        }
      if((val > 81) && (val <= 110)){
        currThrottle = 3;// газ 3 диапазон
        }
      if((val > 111) && (val <= 140)){
        currThrottle = 4; // газ 4 диапазон
        }
      if((val > 141) && (val <= 170)){
        currThrottle = 5;// газ 5 диапазон
        }
      if((val > 171) && (val <= 200)){
        currThrottle = 6;// газ 6 диапазон
        }
      if(val > 201){
        currThrottle = 7;// газ 7 диапазон
        }
  
      
      if(currThrottle != prevThrottle){ // проверяется текущее и предыдущее значение газа, если оно изменилось
        
        if((currThrottle == 0) && (prevThrottle > 0)){
             mp3_play (8);//shut...трек "сброс газа и глушение мотора", если газ перешел с бОльшего значения на меньшее
             prevThrottle = currThrottle;//играем трек8, на карте как 0008.мр3
        }
        if(currThrottle == 1){
             if(currThrottle > prevThrottle){
             mp3_play (1);//start....трек "заводим мотор ", если газ перешел с меньшего значения на большее
             }            //играем трек1, на карте как 0001.мр3
             playingSound = 1;
             prevThrottle = currThrottle;//сохраняем текущее значение газа как предыдущее
        }
        if(currThrottle == 2){
          mp3_play (2);//играем трек2, на карте как 0002.мр3
          prevThrottle = currThrottle;
          playingSound = 2;
        }
        if(currThrottle == 3){
          mp3_play (3);
          prevThrottle = currThrottle;
          playingSound = 3;
        }
        if(currThrottle == 4){
          mp3_play (4);
          prevThrottle = currThrottle;
         playingSound = 4;
        }
         if(currThrottle == 5){
          mp3_play (5);
          prevThrottle = currThrottle;
         playingSound = 5;
        }
         if(currThrottle == 6){
          mp3_play (6);
          prevThrottle = currThrottle;
         playingSound = 6;
         }
         if(currThrottle == 7){
          mp3_play (7);
          prevThrottle = currThrottle;
         playingSound = 7;
        }
        }
    if(currThrottle = prevThrottle){
       mp3_play ();// если трек игрался, повторяем его
    }
    
}