ESP8266和VS1053制作简易网络收音机-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 8372|回复: 2

ESP8266和VS1053制作简易网络收音机

[复制链接]
发表于 2020-8-4 00:47 | 显示全部楼层 |阅读模式
本帖最后由 topdog 于 2020-11-18 00:14 编辑

用ESP8266模块、VS1053模块和一副耳机制作简易网络收音机,原理是ESP8266由WIFI路由器链接互联网的音乐网站获取mp3码流传给VS1053解析推动耳机,播放出美妙的音乐。分别用了两个库各做了一遍,下载地址:1,ESP_VS1053库文件     2,Adafruit_VS1053库文件 。开发环境:Arduino IDE 是1.8.13版本,Arduino core for ESP8266 WiFi chip是2.7.4版本。
大家先按照下图用杜邦线把两个模块连接起来,我的图片里面用了各种色彩的线,使大家能够一目了然接线的走势。

vs1053_esp8266_1.png

接线的重点是物理的SPI连接,VS1053 XRST要高电平使能就接在3.3v管脚上。ESP8266的管脚捉襟见肘,还留出了OLED I2C的GPIO5和GPIO4的接口方便拓展。

esp8266_vs1053_pin_1.png

esp8266烧录的配置情况,主要是把cpu频率调到160MHz。

160m频率.png

网络电台有很多,大家可以查找:https://www.xatworld.com/radio-search/  ,或者在  http://www.fmstream.org/  寻找链接,我是建议大家用64k码速的链接。


ESP_VS1053库文件做的程序如下:

#include <VS1053.h>

#include <ESP8266WiFi.h>
#define VS1053_DCS D10
#define VS1053_CS D6
#define VS1053_DREQ D2

uint8_t mp3buff[64];

const char *ssid = "WIFI名称";
const char *password = "WIFI密码";

const char *host = "lhttp.qingting.fm";
const char *path = "/live/20003/64k.mp3";
int httpPort = 80;

const int VOLUME = 90;

VS1053 player(VS1053_CS, VS1053_DCS, VS1053_DREQ);
WiFiClient client;

void setup()
{
    Serial.begin(115200);

    delay(3000);

    Serial.println("ESP_VS1053 Simple ESP8266 Internet radio");


    SPI.begin();


    player.begin();
    player.switchToMp3Mode();
    player.setVolume(VOLUME);


    Serial.print("Connecting to SSID ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);


    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }


    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());


    Serial.print("connecting to ");
    Serial.println(host);


    if (!client.connect(host, httpPort))
    {
        Serial.println("Connection failed");
        return;
    }


    Serial.print("Requesting stream: ");
    Serial.println(path);


    client.print(String("GET ") + path + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n\r\n");
}


void loop()
{
    if (!client.connected())
    {
        Serial.println("Reconnecting...");
        if (client.connect(host, httpPort))
        {
            client.print(String("GET ") + path + " HTTP/1.1\r\n" +
                         "Host: " + host + "\r\n" +
                         "Connection: close\r\n\r\n");
        }
    }


    if (client.available() > 0)
    {
        uint8_t bytesread = client.read(mp3buff, 64);
        player.playChunk(mp3buff, bytesread);
    }
}


Adafruit_VS1053库文件做的程序如下:

#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <ESP8266WiFi.h>


char *ssid = "WIFI名称";
const char *password = "WIFI密码";


const char *host = "lhttp.qingting.fm";
const char *path = "/live/20003/64k.mp3";
int httpPort = 80;


#define VS1053_MOSI D11
#define VS1053_MISO D12
#define VS1053_CLK D13
#define VS1053_RESET -1
#define VS1053_CS D6
#define VS1053_DCS D10
#define VS1053_DREQ D2


const int VOLUME = 10;


uint8_t mp3buff[32];


//Adafruit_VS1053 musicPlayer =  Adafruit_VS1053(VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ);
Adafruit_VS1053 musicPlayer = Adafruit_VS1053(VS1053_MOSI, VS1053_MISO, VS1053_CLK, VS1053_RESET, VS1053_CS, VS1053_DCS, VS1053_DREQ);


WiFiClient client;


void setup()
{
  Serial.begin(115200);
  Serial.println("Adafruit VS1053 Simple ESP8266 Internet radio");
  SPI.begin();
  if (!musicPlayer.begin())
  {
    Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
    while (1)
      delay(10);
  }


  Serial.println(F("VS1053 found"));
  musicPlayer.sineTest(0x44, 500);


  musicPlayer.setVolume(VOLUME, VOLUME);


  Serial.print("Connecting to SSID ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);


  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }


  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());


  Serial.print("connecting to ");
  Serial.println(host);


  if (!client.connect(host, httpPort))
  {
    Serial.println("Connection failed");
    return;
  }


  Serial.print("Requesting URL: ");
  Serial.println(path);


  client.print(String("GET ") + path + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
}


void loop()
{


  if (musicPlayer.readyForData())
  {


    if (client.available() > 0)
    {


      uint8_t bytesread = client.read(mp3buff, 32);


      musicPlayer.playData(mp3buff, bytesread);
    }
  }
}

希望能够抛砖引玉,期待对大家认识互联网收音机有所帮助。
(完)


发表于 2021-9-5 08:57 来自手机 | 显示全部楼层
换PCM5102A,有哪些需要修改的?
 楼主| 发表于 2021-9-5 21:49 | 显示全部楼层
本帖最后由 topdog 于 2021-9-5 22:23 编辑
BG5MVE 发表于 2021-9-5 08:57
换PCM5102A,有哪些需要修改的?

PCM5102A 是使用I2S协议的,可以在ESP8266上使用的。接线如下:
ESP8266      PCM5102A
IO15             BC(L)K
IO3               DIN
IO2               L(R)CK
3.3V             VIN
GND            GND

[pre]//ESP8266 Arduino单板支持包中包含ESP8266 I2S支持。头文件名为i2s.h和i2s_reg.h。
#include "ESP8266WiFi.h"
#include "i2s.h"
#include "i2s_reg.h"

#define RATE 44100
#define SINE_SAMPLES 512

const int c = 261;
const int d = 294;
const int e = 329;
const int f = 349;
const int g = 391;
const int gS = 415;
const int a = 440;
const int aS = 455;
const int b = 466;
const int cH = 523;
const int cSH = 554;
const int dH = 587;
const int dSH = 622;
const int eH = 659;
const int fH = 698;
const int fSH = 740;
const int gH = 784;
const int gSH = 830;
const int aH = 880;

int16_t sine[SINE_SAMPLES] = {
  0x0000, 0x0192, 0x0325, 0x04b8, 0x064a, 0x07dd, 0x096f, 0x0b00,
  0x0c92, 0x0e22, 0x0fb2, 0x1142, 0x12d1, 0x145f, 0x15ec, 0x1779,
  0x1905, 0x1a8f, 0x1c19, 0x1da1, 0x1f29, 0x20af, 0x2234, 0x23b7,
  0x253a, 0x26ba, 0x283a, 0x29b7, 0x2b33, 0x2cae, 0x2e27, 0x2f9d,
  0x3113, 0x3286, 0x33f7, 0x3566, 0x36d3, 0x383e, 0x39a7, 0x3b0e,
  0x3c72, 0x3dd4, 0x3f34, 0x4091, 0x41eb, 0x4343, 0x4499, 0x45ec,
  0x473c, 0x4889, 0x49d4, 0x4b1b, 0x4c60, 0x4da2, 0x4ee1, 0x501d,
  0x5155, 0x528b, 0x53bd, 0x54ec, 0x5618, 0x5741, 0x5866, 0x5987,
  0x5aa6, 0x5bc0, 0x5cd7, 0x5deb, 0x5efb, 0x6007, 0x6110, 0x6214,
  0x6315, 0x6413, 0x650c, 0x6601, 0x66f3, 0x67e0, 0x68c9, 0x69af,
  0x6a90, 0x6b6d, 0x6c46, 0x6d1b, 0x6deb, 0x6eb8, 0x6f80, 0x7044,
  0x7103, 0x71be, 0x7274, 0x7327, 0x73d4, 0x747e, 0x7522, 0x75c2,
  0x765e, 0x76f5, 0x7787, 0x7815, 0x789e, 0x7923, 0x79a3, 0x7a1e,
  0x7a94, 0x7b06, 0x7b73, 0x7bdb, 0x7c3e, 0x7c9d, 0x7cf6, 0x7d4b,
  0x7d9b, 0x7de6, 0x7e2c, 0x7e6e, 0x7eaa, 0x7ee2, 0x7f14, 0x7f42,
  0x7f6b, 0x7f8f, 0x7fae, 0x7fc8, 0x7fdd, 0x7fed, 0x7ff8, 0x7ffe,
  0x7fff, 0x7ffc, 0x7ff3, 0x7fe5, 0x7fd3, 0x7fbb, 0x7f9f, 0x7f7d,
  0x7f57, 0x7f2c, 0x7efc, 0x7ec6, 0x7e8c, 0x7e4e, 0x7e0a, 0x7dc1,
  0x7d74, 0x7d21, 0x7cca, 0x7c6e, 0x7c0d, 0x7ba7, 0x7b3d, 0x7ace,
  0x7a5a, 0x79e1, 0x7963, 0x78e1, 0x785a, 0x77cf, 0x773f, 0x76aa,
  0x7611, 0x7573, 0x74d0, 0x7429, 0x737e, 0x72ce, 0x721a, 0x7161,
  0x70a4, 0x6fe2, 0x6f1c, 0x6e52, 0x6d84, 0x6cb1, 0x6bda, 0x6aff,
  0x6a20, 0x693d, 0x6855, 0x676a, 0x667a, 0x6587, 0x6490, 0x6394,
  0x6295, 0x6193, 0x608c, 0x5f81, 0x5e73, 0x5d62, 0x5c4c, 0x5b33,
  0x5a17, 0x58f7, 0x57d4, 0x56ad, 0x5583, 0x5455, 0x5324, 0x51f1,
  0x50b9, 0x4f7f, 0x4e42, 0x4d02, 0x4bbe, 0x4a78, 0x492f, 0x47e3,
  0x4694, 0x4543, 0x43ee, 0x4298, 0x413e, 0x3fe2, 0x3e84, 0x3d23,
  0x3bc0, 0x3a5b, 0x38f3, 0x3789, 0x361d, 0x34af, 0x333f, 0x31cc,
  0x3058, 0x2ee2, 0x2d6a, 0x2bf1, 0x2a76, 0x28f9, 0x277a, 0x25fa,
  0x2479, 0x22f6, 0x2172, 0x1fec, 0x1e65, 0x1cdd, 0x1b54, 0x19ca,
  0x183f, 0x16b3, 0x1526, 0x1398, 0x120a, 0x107a, 0x0eea, 0x0d5a,
  0x0bc9, 0x0a38, 0x08a6, 0x0714, 0x0581, 0x03ef, 0x025c, 0x00c9,
  0xff36, 0xfda3, 0xfc10, 0xfa7e, 0xf8eb, 0xf759, 0xf5c7, 0xf436,
  0xf2a5, 0xf115, 0xef85, 0xedf5, 0xec67, 0xead9, 0xe94c, 0xe7c0,
  0xe635, 0xe4ab, 0xe322, 0xe19a, 0xe013, 0xde8d, 0xdd09, 0xdb86,
  0xda05, 0xd885, 0xd706, 0xd589, 0xd40e, 0xd295, 0xd11d, 0xcfa7,
  0xce33, 0xccc0, 0xcb50, 0xc9e2, 0xc876, 0xc70c, 0xc5a4, 0xc43f,
  0xc2dc, 0xc17b, 0xc01d, 0xbec1, 0xbd67, 0xbc11, 0xbabc, 0xb96b,
  0xb81c, 0xb6d0, 0xb587, 0xb441, 0xb2fd, 0xb1bd, 0xb080, 0xaf46,
  0xae0e, 0xacdb, 0xabaa, 0xaa7c, 0xa952, 0xa82b, 0xa708, 0xa5e8,
  0xa4cc, 0xa3b3, 0xa29d, 0xa18c, 0xa07e, 0x9f73, 0x9e6c, 0x9d6a,
  0x9c6b, 0x9b6f, 0x9a78, 0x9985, 0x9895, 0x97aa, 0x96c2, 0x95df,
  0x9500, 0x9425, 0x934e, 0x927b, 0x91ad, 0x90e3, 0x901d, 0x8f5b,
  0x8e9e, 0x8de5, 0x8d31, 0x8c81, 0x8bd6, 0x8b2f, 0x8a8c, 0x89ee,
  0x8955, 0x88c0, 0x8830, 0x87a5, 0x871e, 0x869c, 0x861e, 0x85a5,
  0x8531, 0x84c2, 0x8458, 0x83f2, 0x8391, 0x8335, 0x82de, 0x828b,
  0x823e, 0x81f5, 0x81b1, 0x8173, 0x8139, 0x8103, 0x80d3, 0x80a8,
  0x8082, 0x8060, 0x8044, 0x802c, 0x801a, 0x800c, 0x8003, 0x8000,
  0x8001, 0x8007, 0x8012, 0x8022, 0x8037, 0x8051, 0x8070, 0x8094,
  0x80bd, 0x80eb, 0x811d, 0x8155, 0x8191, 0x81d3, 0x8219, 0x8264,
  0x82b4, 0x8309, 0x8362, 0x83c1, 0x8424, 0x848c, 0x84f9, 0x856b,
  0x85e1, 0x865c, 0x86dc, 0x8761, 0x87ea, 0x8878, 0x890a, 0x89a1,
  0x8a3d, 0x8add, 0x8b81, 0x8c2b, 0x8cd8, 0x8d8b, 0x8e41, 0x8efc,
  0x8fbb, 0x907f, 0x9147, 0x9214, 0x92e4, 0x93b9, 0x9492, 0x956f,
  0x9650, 0x9736, 0x981f, 0x990c, 0x99fe, 0x9af3, 0x9bec, 0x9cea,
  0x9deb, 0x9eef, 0x9ff8, 0xa104, 0xa214, 0xa328, 0xa43f, 0xa559,
  0xa678, 0xa799, 0xa8be, 0xa9e7, 0xab13, 0xac42, 0xad74, 0xaeaa,
  0xafe2, 0xb11e, 0xb25d, 0xb39f, 0xb4e4, 0xb62b, 0xb776, 0xb8c3,
  0xba13, 0xbb66, 0xbcbc, 0xbe14, 0xbf6e, 0xc0cb, 0xc22b, 0xc38d,
  0xc4f1, 0xc658, 0xc7c1, 0xc92c, 0xca99, 0xcc08, 0xcd79, 0xceec,
  0xd062, 0xd1d8, 0xd351, 0xd4cc, 0xd648, 0xd7c5, 0xd945, 0xdac5,
  0xdc48, 0xddcb, 0xdf50, 0xe0d6, 0xe25e, 0xe3e6, 0xe570, 0xe6fa,
  0xe886, 0xea13, 0xeba0, 0xed2e, 0xeebd, 0xf04d, 0xf1dd, 0xf36d,
  0xf4ff, 0xf690, 0xf822, 0xf9b5, 0xfb47, 0xfcda, 0xfe6d, 0xffff
};

void writeNote(uint32 freq, uint32 duration)
{
  if (freq == 0 || duration == 0) {
    return;
  }
  
  uint32 totalSamples = (RATE * duration) / 1000;
  
  uint32 samplesPerPeriod = RATE / freq;
  
  totalSamples = (totalSamples / samplesPerPeriod) * samplesPerPeriod;

  for (uint32 i = 0; i < totalSamples; i++) {
      uint32 sampleIdx = map(i % samplesPerPeriod, 0, samplesPerPeriod, 0, SINE_SAMPLES);  
      i2s_write_lr( sine[sampleIdx],  sine[sampleIdx]);
  }

  delay(50);
}


void setup() {
  system_update_cpu_freq(160);

  i2s_begin();
  i2s_set_rate(RATE);

}

void loop()
{   
  firstSection();
  secondSection();
  
  writeNote(f, 250);  
  writeNote(gS, 500);  
  writeNote(f, 350);  
  writeNote(a, 125);
  writeNote(cH, 500);
  writeNote(a, 375);  
  writeNote(cH, 125);
  writeNote(eH, 650);

  delay(500);

  secondSection();
  
  writeNote(f, 250);  
  writeNote(gS, 500);  
  writeNote(f, 375);  
  writeNote(cH, 125);
  writeNote(a, 500);  
  writeNote(f, 375);  
  writeNote(cH, 125);
  writeNote(a, 650);  

  delay(650);  
}


void firstSection()
{
  writeNote(a, 500);
  writeNote(a, 500);   
  writeNote(a, 500);
  writeNote(f, 350);
  writeNote(cH, 150);  
  writeNote(a, 500);
  writeNote(f, 350);
  writeNote(cH, 150);
  writeNote(a, 650);

  delay(500);

  writeNote(eH, 500);
  writeNote(eH, 500);
  writeNote(eH, 500);  
  writeNote(fH, 350);
  writeNote(cH, 150);
  writeNote(gS, 500);
  writeNote(f, 350);
  writeNote(cH, 150);
  writeNote(a, 650);

  delay(500);
}

void secondSection()
{
  writeNote(aH, 500);
  writeNote(a, 300);
  writeNote(a, 150);
  writeNote(aH, 500);
  writeNote(gSH, 325);
  writeNote(gH, 175);
  writeNote(fSH, 125);
  writeNote(fH, 125);   
  writeNote(fSH, 250);

  delay(325);

  writeNote(aS, 250);
  writeNote(dSH, 500);
  writeNote(dH, 325);  
  writeNote(cSH, 175);  
  writeNote(cH, 125);  
  writeNote(b, 125);  
  writeNote(cH, 250);  

  delay(350);
}[/pre]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 02:47 , Processed in 0.170963 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表