ESP32 + PCM5102A — интернет радио (2) (Arduino)

Ранее в статье http://rcl-radio.ru/?p=111051 рассматривался пример создания интернет-радио на основе ESP32 (ESP32 DevKit v1 Wi-Fi Bluetooth ESP32-WROOM-32) и звукового ЦАП PMC5102A с использованием дисплея LCD1602 + I2C, в этой статье аналогичный пример, но с использованием дисплея 0.96′ I2C 128X64 OLED.

В Интернет радио использованы следующие компоненты:

  • ESP32 DevKit v1 Wi-Fi Bluetooth ESP32-WROOM-32
  • DAC PCM5102A
  • 0.96′ I2C 128X64 OLED
  • Энкодер KY-040 (модуль)
  • Тактовая кнопка  — 2 шт

В OLED дисплее отсутствует дополнительный слой подсветки всей поверхности экрана. Каждый пиксел, формирующий изображение, испускает самостоятельное свечение. При этом картинка получается яркой и контрастной.

Управление OLED дисплеем в данном примере осуществляется при помощи шины I2C.

Параметры дисплея SSD1306:

  • Технология дисплея: OLED
  • Разрешение дисплея: 128 на 64 точки
  • Диагональ дисплея: 0,96 дюйма
  • Угол обзора: 160°
  • Напряжение питания: 2.8 В ~ 5.5 В
  • Мощность: 0,08 Вт
  • Габариты: 27.3 мм х 27.8 мм х 3.7 мм

ESP32

ESP32 — серия недорогих микроконтроллеров с низким энергопотреблением. Представляют собой систему на кристалле с интегрированным Wi-Fi и Bluetooth контроллерами и антеннами. В серии ESP32 используется микроконтроллерное ядро Tensilica Xtensa LX6 в вариантах с двумя и одним ядром. В систему интегрирован радиочастотный тракт: симметрирующий трансформатор, встроенные антенные коммутаторы, радиочастотные компоненты, малошумящий усилитель, усилитель мощности, фильтры и модули управления питанием. ESP32 создан и разработан компанией Espressif Systems, китайской компанией, расположенной в Шанхае, а производится компанией TSMC по техпроцессу 40 нм. Серия является преемником микроконтроллеров ESP8266.

Характеристики ESP32 DevKit v1:

  • микроконтроллер: ESP32-WROOM-32
  • процессор: 2-ядерный Xtensa Dual-Core 32-bit LX6
  • тактовая частота процессора: 80, 160 или 240 МГц
  • оперативная память: 520 Кбайт;
  • флэш-память: 448 Кбайт;
  • преобразователь USB – UART
  • количество выводов платы: 30;
  • Bluetooth: спецификации 4.2 с функциями  BR/EDR и Low Energy
  • WiFi: стандарта IEEE 802.11b/g/n/e/i безопасность WFA, WPA/WPA2 и WAPI на частоте 2,4 ГГц со скоростью до 150 Мбит/с, встроенный стек TCP/IP
  • антенна: PCB
  • режимы беспроводной связи: STA/AP/STA+AP
  • расстояние приема/передачи в идеальных условиях: 400 м;
  • периферия: АЦП 12 бит до 18 каналов, ЦАП 8 бит 2 канала, датчик температуры, 4x SPI, 2x I2S, 2x I2C, 3x UART, Ethernet контроллер, CAN 2.0, ведущий SD/eMMC/SDIO, ведомый SDIO/SPI, инфракрасный приемопередатчик, ШИМ до 16 каналов, датчик Холла, аналоговый предусилитель, шифровальщики, хешеры, генератор случайных чисел
  • поддерживаемые среды разработки: Arduino IDE, PlatformIO, Espressif IDF (IoT Development Framework), Micropython, JavaScript, LUA

PCM5102A

  • Напряжение однополярное … 3,3 В
  • Отношение сигнал/шум … 112 дБ
  • Динамический диапазон … 112 дБ
  • Уровень нелинейных искажений (THD+N) … -93 дБ
  • Выходное напряжение … 2.1 Vrms
  • Поддерживаемая частота дискретизации от 8 кГц до 384 кГц
  • Поддержка входных форматов данных … I2S, Left-Justified / 16, 24 и 32 бит

Схема Интернет радио

На дисплей 0.96′ I2C 128X64 OLED выводится информация в три строки:

  1. Название станции (бегущая строка)
  2. Номер станции и скорость потока
  3. Настройки радио:
    • Громкость (0…22 уровень)
    • Баланс (±16 дБ)
    • Bass (-40…+16 дБ)
    • Middle (-40…+16 дБ)
    • Treble (-40…+16 дБ)

Интернет радио не содержит WEB страницы, все параметры и url адреса станций необходимо заносить в скетч:

авторизация в сети

  String ssid =     "Keenetic-9009";     // ssid сети WI-FI
  String password = "32481975";     // пароль от сети WI-FI

список станций

  "https://rusradio.hostingradio.ru/rusradio96.aacp",
  "https://str.pcradio.ru/funradio_sk_80s90s-hi",
  "http://radio.promodj.com:8000/186mph-192",
  "http://live.novoeradio.by:8000/narodnoe-radio-128k",
  "http://listen1.myradio24.com:9000/3355",
  "http://101.ru/api/channel/getServers/192/channel/AAC/128/dataFormat/mobile",

кол-во станций

#define CH             6  // кол-во станций

Управление Интернет радио осуществляется при помощи энкодера и двух кнопок. Кнопки позволяют переключать каналы станций, а энкодер регулировать параметры громкости, баланса и тембра. Кнопка энкодера осуществляет переход по пунктам меню.

Как добавить ESP32 в среду Ardiuno IDE можно узнать на странице http://rcl-radio.ru/?p=92558

Версия платы должна быть не ниже 1.0.5

Плата ESP32 Dev Module

#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"             // https://github.com/schreibfaul1/ESP32-audioI2S.git
#include <Wire.h> 
#include <SSD1306.h>           // https://github.com/LilyGO/ESP32-OLED0.96-ssd1306.git
#include <ESP32Encoder.h>      // https://github.com/madhephaestus/ESP32Encoder.git
#include <EEPROM.h>
 
#define I2S_DOUT      25  // DIN connection
#define I2S_BCLK      27  // Bit clock
#define I2S_LRC       26  // Left Right Clock
#define CLK           18  // CLK ENCODER
#define DT            19  // DT ENCODER
#define SW             5  // SW ENCODER  
#define CH_UP         13  // CH_UP BUTTON 
#define CH_DOWN       12  // CH_DOWN BUTTON    
 
#define CH             6  // кол-во станций
 
  Audio audio;
  SSD1306  display(0x3c, 21, 22);
  ESP32Encoder encoder;
  String ssid =     "Keenetic-9009";     // ssid сети WI-FI
  String password = "32481975";     // пароль от сети WI-FI
  String ch = "connection      ";
  String bitr;
  String url;
  unsigned long oldPosition  = -999,newPosition,times1,times_ch;
  bool w=1,w1,ball_1,bass_1,mid_1,treb_1,vol_1;
  int ct,old_ct = 1,menu,ball,bass,mid,treb,vol=15;
  bool e_vol,e_ball,e_bass,e_mid,e_treb,e_ct;
  int i_ch,t_ch,tic_ch;
 
  const char *listch[]{
  "https://rusradio.hostingradio.ru/rusradio96.aacp",
  "https://str.pcradio.ru/funradio_sk_80s90s-hi",
  "http://radio.promodj.com:8000/186mph-192",
  "http://live.novoeradio.by:8000/narodnoe-radio-128k",
  "http://listen1.myradio24.com:9000/3355",
  "http://101.ru/api/channel/getServers/192/channel/AAC/128/dataFormat/mobile",
  };
 
void setup() {
  ESP32Encoder::useInternalWeakPullResistors=UP;
  encoder.attachHalfQuad(DT, CLK);
  encoder.setCount(0);
  Serial.begin(9600);
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid.c_str(), password.c_str());
  Wire.begin();Wire.setClock(400000L);
  display.init();
  display.flipScreenVertically();
  display.setContrast(100);
  display.clear();
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 10, "ESP32  RADIO");
  display.drawString(0, 25, "PCM5102A");
  display.display();
  delay(2000);
  while (WiFi.status() != WL_CONNECTED) delay(100);
  display.drawString(0, 40, "IP:" + WiFi.localIP().toString());
  display.display();
  delay(2000);
  EEPROM.begin(10);
  vol = EEPROM.read(0);
  ball = EEPROM.read(1)-16;
  bass = EEPROM.read(2)-40;
  mid = EEPROM.read(3)-40;
  treb = EEPROM.read(4)-40;
  ct = EEPROM.read(5);
  if(vol>21){vol=0;}
  if(ball>16){ball=0;}
  if(bass>16){bass=0;}
  if(mid>16){mid=0;}
  if(treb>16){treb=0;}
  if(ct>CH-1){ct=0;}
  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
  delay(2000);
  display.clear();
  display.display();
  audio.setBalance(ball);//+-16
  audio.setVolume(vol); // 0...21
  audio.setTone(bass,mid,treb);//-40+16
  pinMode(CH_UP, INPUT_PULLUP);
  pinMode(CH_DOWN, INPUT_PULLUP);
  pinMode(SW,INPUT);          // ENCODER SW 
}
 
void loop(){   
   newPosition = encoder.getCount()/2;
 
//// ENCODER VOLUME ////////////////////////////////////////////// 
 if(menu==0){ 
 if(newPosition != oldPosition){oldPosition = newPosition;vol=vol-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(vol>21){vol=21;}if(vol<0){vol=0;}audio.setVolume(vol);vol_1=1;e_vol=1;times_ch=millis();}
    if(vol_1==1){vol_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Volume " + String(vol) + " ");display.display();
    }}
///// ENCODER BALANCE ////////////////////////////////////////////
 if(menu==1){ 
 if(newPosition != oldPosition){oldPosition = newPosition;ball=ball-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(ball>16){ball=16;}if(ball<-16){ball=-16;}audio.setBalance(ball);ball_1=1;e_ball=1;times_ch=millis();}
    if(ball_1==1){ball_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Balance " + String(ball) + " dB ");display.display();
    }}   
///// ENCODER BASS ////////////////////////////////////////////
 if(menu==2){ 
 if(newPosition != oldPosition){oldPosition = newPosition;bass=bass-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(bass>16){bass=16;}if(bass<-40){bass=-40;}audio.setTone(bass,mid,treb);bass_1=1;e_bass=1;times_ch=millis();}
    if(bass_1==1){bass_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Bass " + String(bass) + " dB ");display.display();
    }}
///// ENCODER MIDDLE ////////////////////////////////////////////
 if(menu==3){ 
 if(newPosition != oldPosition){oldPosition = newPosition;mid=mid-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(mid>16){mid=16;}if(mid<-40){mid=-40;}audio.setTone(bass,mid,treb);mid_1=1;e_mid=1;times_ch=millis();}
    if(mid_1==1){mid_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Middle " + String(mid) + " dB ");display.display();
    }}      
///// ENCODER TREBLE ////////////////////////////////////////////
 if(menu==4){ 
 if(newPosition != oldPosition){oldPosition = newPosition;treb=treb-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(treb>16){treb=16;}if(treb<-40){treb=-40;}audio.setTone(bass,mid,treb);treb_1=1;e_treb=1;times_ch=millis();}
    if(treb_1==1){treb_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Treble " + String(treb) + " dB ");display.display();
    }}   
 
//// BUTTON //////////////////////////////////////////////   
 if (digitalRead(13)==LOW){ct++;if(ct>CH-1){ct=0;}w=1;times1=millis();w1=1;ch="connection      ";
 delay(200);w=1;w1=1;times_ch=millis();display.clear();menu=0;vol_1=1;e_ct=1;Serial.println(ct);}
 
 if (digitalRead(12)==LOW){ct--;if(ct<0){ct=CH-1;}w=1;times1=millis();w1=1;ch="connection      ";
 delay(200);w=1;w1=1;times_ch=millis();display.clear();menu=0;vol_1=1;e_ct=1;Serial.println(ct);}
 
 if (digitalRead(5)==LOW){menu++;if(menu>4){menu=0;}times1=millis();w=1;w1=1;display.clear();vol_1=1;ball_1=1;bass_1=1;mid_1=1;treb_1=1;if(menu==0){w=1;}delay(300);}
////////////////////////////////////////////////////////// 
 if (ct != old_ct) {ch!="connection      ";audio.connecttohost(listch[ct]);Serial.println(ct);old_ct = ct;w=1;}
 
  if(w==1&&ch!="connection      "){
  w=0;
  display.setFont(ArialMT_Plain_16);
  display.drawString(0, 20, "CH" + String(ct));
  display.drawString(40,20, String(bitr.toInt()/1000) + "k");
  display.display();
  }
 
  if(millis()-times_ch>500){
    display.setColor(BLACK);
    display.fillRect(0, 0, 128, 19);
    display.setColor(WHITE);
    times_ch=millis();
    int n_ch = ch.length();
    String s1 = ch.substring(i_ch,n_ch);
    display.setFont(ArialMT_Plain_16);
    display.drawString(0, 0, s1);
    display.display();
    tic_ch++;if(tic_ch>n_ch+5){tic_ch=0;}
    if(tic_ch>4){i_ch++;}if(i_ch>n_ch){i_ch=0;}
  }
 
  audio.loop();
 
//// EEPROM ///////////////////////////////////
  if(millis()-times1>5000&&w1==1){
  if(e_vol==1){e_vol=0;EEPROM.write(0,vol);}
  if(e_ball==1){e_ball=0;EEPROM.write(1,ball+16);}
  if(e_bass==1){e_bass=0;EEPROM.write(2,bass+40);}
  if(e_mid==1){e_mid=0;EEPROM.write(3,mid+40);}
  if(e_treb==1){e_treb=0;EEPROM.write(4,treb+40);}
  if(e_ct==1){e_ct=0;EEPROM.write(5,ct);}
  EEPROM.commit();}
  if(millis()-times1>10000&&w1==1){
  w1=0;if(menu!=0){w=1;menu=0;}}
 
} // loop
 
void audio_showstation(const char *info) {Serial.print("station     "); ch=info; Serial.println(info);}
void audio_showstreamtitle(const char *info) {Serial.print("streamtitle ");url=info; Serial.println(info);}
void audio_bitrate(const char *info) {Serial.print("bitrate     ");bitr = info; Serial.println(info);}
void audio_icyurl(const char *info) {Serial.print("icyurl      ");Serial.println(info);}
void audio_lasthost(const char *info) {Serial.print("lasthost    "); Serial.println(info);}

Доработка

Сохранение списка станций (адресов) на сервере. 

Для удобства использования интернет радио был разработан небольшой онлайн сервис позволяющий создавать файл (html) в котором будут хранится адреса потоков интернет станций. Файл с адресами можно обновлять. При включении интернет радио ESP32 сделает запрос к Вашему файлу со списком станций и загрузит его в память.

Онлайн приложение — http://forum.rcl-radio.ru/internet_radio_esp32.php

Придумайте уникальное название Вашего файла, далее укажите список из 10 станций, адреса должны быть разделены запятыми. Далее запишите файл, проверьте чтение файла.

Для обновления списка станций нужно указать имя файла, нажать кнопку «Прочитать», после получения списка станций в нижнем поле, копировать их и вставить в верхнее поле, отредактировать список станций и нажать кнопку «Записать».

В скетче поменяйте строку:

const String endpoint = «http://forum.rcl-radio.ru/internet_radio_esp32/data.html»;

data — это название файла.

Далее загрузите со всеми изменениями (указать логин и пароль Вашей сети, отредактировать строку со списком станций) скетч для 10 станций:

#include "Arduino.h"
#include "WiFi.h"
#include "Audio.h"             // https://github.com/schreibfaul1/ESP32-audioI2S.git
#include <Wire.h> 
#include <SSD1306.h>           // https://github.com/LilyGO/ESP32-OLED0.96-ssd1306.git
#include <ESP32Encoder.h>      // https://github.com/madhephaestus/ESP32Encoder.git
#include <EEPROM.h>
#include <HTTPClient.h>
 
#define I2S_DOUT      25  // DIN connection
#define I2S_BCLK      27  // Bit clock
#define I2S_LRC       26  // Left Right Clock
#define CLK           18  // CLK ENCODER
#define DT            19  // DT ENCODER
#define SW             5  // SW ENCODER  
#define CH_UP         13  // CH_UP BUTTON 
#define CH_DOWN       12  // CH_DOWN BUTTON    
 
 
#define CH            10  // кол-во станций
const String endpoint = "http://forum.rcl-radio.ru/internet_radio_esp32/data.html";
 
 
  Audio audio;
  SSD1306  display(0x3c, 21, 22);
  ESP32Encoder encoder;
  String ssid =     "Redmi Note 3";     // ssid сети WI-FI
  String password = "32481975";     // пароль от сети WI-FI
 
  String payload;
 
  String ch = "connection      ";
  String bitr;
  String url;
  unsigned long oldPosition  = -999,newPosition,times1,times_ch;
  bool w=1,w1,ball_1,bass_1,mid_1,treb_1,vol_1;
  int ct,old_ct = 1,menu,ball,bass,mid,treb,vol=15;
  bool e_vol,e_ball,e_bass,e_mid,e_treb,e_ct;
  int i_ch,t_ch,tic_ch;
  const char *listch[CH];
  String xval[CH];
 
 
void setup() {
  ESP32Encoder::useInternalWeakPullResistors=UP;
  encoder.attachHalfQuad(DT, CLK);
  encoder.setCount(0);
  Serial.begin(9600);
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid.c_str(), password.c_str());
  Wire.begin();Wire.setClock(400000L);
  display.init();
  display.flipScreenVertically();
  display.setContrast(100);
  display.clear();
  display.setFont(ArialMT_Plain_10);
  display.drawString(0, 10, "ESP32  RADIO");
  display.drawString(0, 25, "PCM5102A");
  display.display();
  delay(2000);
  while (WiFi.status() != WL_CONNECTED) delay(100);
  display.drawString(0, 40, "IP:" + WiFi.localIP().toString());
  display.display();
  delay(2000);
  EEPROM.begin(10);
  vol = EEPROM.read(0);
  ball = EEPROM.read(1)-16;
  bass = EEPROM.read(2)-40;
  mid = EEPROM.read(3)-40;
  treb = EEPROM.read(4)-40;
  ct = EEPROM.read(5);
  if(vol>21){vol=0;}
  if(ball>16){ball=0;}
  if(bass>16){bass=0;}
  if(mid>16){mid=0;}
  if(treb>16){treb=0;}
  if(ct>CH-1){ct=0;}
  audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
  delay(2000);
  display.clear();
  display.display();
  audio.setBalance(ball);//+-16
  audio.setVolume(vol); // 0...21
  audio.setTone(bass,mid,treb);//-40+16
  pinMode(CH_UP, INPUT_PULLUP);
  pinMode(CH_DOWN, INPUT_PULLUP);
  pinMode(SW,INPUT);          // ENCODER SW 
 
  HTTPClient http;
  http.begin(endpoint);
  int httpCode = http.GET();
  if (httpCode > 0) {payload = http.getString();}
  http.end();  
 
  for(int kol_i=0;kol_i<CH;kol_i++){
  xval[kol_i] = getValue(payload, ',', kol_i);
  Serial.println(xval[kol_i]);
  }
  Serial.println();
  for(int kol_i=0;kol_i<CH;kol_i++){
  listch[kol_i] = xval[kol_i].c_str();
  }
}
 
String getValue(String data1, char separator, int index){
    int found = 0;
    int strIndex[] = { 0, -1 };
    int maxIndex = data1.length() - 1;
    for (int i = 0; i <= maxIndex && found <= index; i++) {
        if (data1.charAt(i) == separator || i == maxIndex) {
            found++;
            strIndex[0] = strIndex[1] + 1;
            strIndex[1] = (i == maxIndex) ? i+1 : i;
        }}
    return found > index ? data1.substring(strIndex[0], strIndex[1]) : "";
}
 
void loop(){   
   newPosition = encoder.getCount()/2;
 
//// ENCODER VOLUME ////////////////////////////////////////////// 
 if(menu==0){ 
 if(newPosition != oldPosition){oldPosition = newPosition;vol=vol-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(vol>21){vol=21;}if(vol<0){vol=0;}audio.setVolume(vol);vol_1=1;e_vol=1;times_ch=millis();}
    if(vol_1==1){vol_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Volume " + String(vol) + " ");display.display();
    }}
///// ENCODER BALANCE ////////////////////////////////////////////
 if(menu==1){ 
 if(newPosition != oldPosition){oldPosition = newPosition;ball=ball-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(ball>16){ball=16;}if(ball<-16){ball=-16;}audio.setBalance(ball);ball_1=1;e_ball=1;times_ch=millis();}
    if(ball_1==1){ball_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Balance " + String(ball) + " dB ");display.display();
    }}   
///// ENCODER BASS ////////////////////////////////////////////
 if(menu==2){ 
 if(newPosition != oldPosition){oldPosition = newPosition;bass=bass-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(bass>16){bass=16;}if(bass<-40){bass=-40;}audio.setTone(bass,mid,treb);bass_1=1;e_bass=1;times_ch=millis();}
    if(bass_1==1){bass_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Bass " + String(bass) + " dB ");display.display();
    }}
///// ENCODER MIDDLE ////////////////////////////////////////////
 if(menu==3){ 
 if(newPosition != oldPosition){oldPosition = newPosition;mid=mid-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(mid>16){mid=16;}if(mid<-40){mid=-40;}audio.setTone(bass,mid,treb);mid_1=1;e_mid=1;times_ch=millis();}
    if(mid_1==1){mid_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Middle " + String(mid) + " dB ");display.display();
    }}      
///// ENCODER TREBLE ////////////////////////////////////////////
 if(menu==4){ 
 if(newPosition != oldPosition){oldPosition = newPosition;treb=treb-newPosition;encoder.setCount(0);
    newPosition=0;times1=millis();w1=1;if(treb>16){treb=16;}if(treb<-40){treb=-40;}audio.setTone(bass,mid,treb);treb_1=1;e_treb=1;times_ch=millis();}
    if(treb_1==1){treb_1=0;display.setFont(ArialMT_Plain_16);
    display.setColor(BLACK);display.fillRect(0, 40, 128, 19);display.setColor(WHITE);
    display.drawString(0, 40, "Treble " + String(treb) + " dB ");display.display();
    }}   
 
//// BUTTON //////////////////////////////////////////////   
 if (digitalRead(13)==LOW){ct++;if(ct>CH-1){ct=0;}w=1;times1=millis();w1=1;ch="connection      ";
 delay(300);w=1;w1=1;times_ch=millis();display.clear();menu=0;vol_1=1;e_ct=1;Serial.println(ct);}
 
 if (digitalRead(12)==LOW){ct--;if(ct<0){ct=CH-1;}w=1;times1=millis();w1=1;ch="connection      ";
 delay(300);w=1;w1=1;times_ch=millis();display.clear();menu=0;vol_1=1;e_ct=1;Serial.println(ct);}
 
 if (digitalRead(5)==LOW){menu++;if(menu>4){menu=0;}times1=millis();w=1;w1=1;display.clear();vol_1=1;ball_1=1;bass_1=1;mid_1=1;treb_1=1;if(menu==0){w=1;}delay(300);}
////////////////////////////////////////////////////////// 
 if (ct != old_ct) {ch!="connection      ";audio.connecttohost(listch[ct]);Serial.println(ct);old_ct = ct;w=1;}
 
  if(w==1&&ch!="connection      "){
  w=0;
  display.setFont(ArialMT_Plain_16);
  display.drawString(0, 20, "CH" + String(ct));
  display.drawString(40,20, String(bitr.toInt()/1000) + "k");
  display.display();
  }
 
  if(millis()-times_ch>500){
    display.setColor(BLACK);
    display.fillRect(0, 0, 128, 19);
    display.setColor(WHITE);
    times_ch=millis();
    int n_ch = ch.length();
    String s1 = ch.substring(i_ch,n_ch);
    display.setFont(ArialMT_Plain_16);
    display.drawString(0, 0, s1);
    display.display();
    tic_ch++;if(tic_ch>n_ch+5){tic_ch=0;}
    if(tic_ch>4){i_ch++;}if(i_ch>n_ch){i_ch=0;}
  }
 
  audio.loop();
 
//// EEPROM ///////////////////////////////////
  if(millis()-times1>5000&&w1==1){
  if(e_vol==1){e_vol=0;EEPROM.write(0,vol);}
  if(e_ball==1){e_ball=0;EEPROM.write(1,ball+16);}
  if(e_bass==1){e_bass=0;EEPROM.write(2,bass+40);}
  if(e_mid==1){e_mid=0;EEPROM.write(3,mid+40);}
  if(e_treb==1){e_treb=0;EEPROM.write(4,treb+40);}
  if(e_ct==1){e_ct=0;EEPROM.write(5,ct);}
  EEPROM.commit();}
  if(millis()-times1>10000&&w1==1){
  w1=0;if(menu!=0){w=1;menu=0;}}
 
} // loop
 
void audio_showstation(const char *info) {Serial.print("station     "); ch=info; Serial.println(info);}
void audio_showstreamtitle(const char *info) {Serial.print("streamtitle ");url=info; Serial.println(info);}
void audio_bitrate(const char *info) {Serial.print("bitrate     ");bitr = info; Serial.println(info);}
void audio_icyurl(const char *info) {Serial.print("icyurl      ");Serial.println(info);}
void audio_lasthost(const char *info) {Serial.print("lasthost    "); Serial.println(info);}

Форум — http://forum.rcl-radio.ru/viewtopic.php?id=435

Comments

Добавить комментарий

Войти с помощью: