v0.4.315
This commit is contained in:
11
README.md
11
README.md
@@ -198,13 +198,20 @@ download _http://\<yoradioip\>/data/playlist.csv_ and _http://\<yoradioip\>/data
|
|||||||
|
|
||||||
---
|
---
|
||||||
## Version history
|
## Version history
|
||||||
|
#### v0.4.315
|
||||||
|
- added support for digital buttons for the IR control \
|
||||||
|
(num keys - enter number of station, ok - play, hash - cancel)
|
||||||
|
- added buttons for exporting settings from the web interface
|
||||||
|
- added MUTE_PIN to be able to control the audio output
|
||||||
|
- fixed js/html bugs (a [full update](#update) is required)
|
||||||
|
|
||||||
#### v0.4.298
|
#### v0.4.298
|
||||||
- fixed playlist scrollbar in Chrome
|
- fixed playlist scrollbar in Chrome (required [full update](#update))
|
||||||
|
|
||||||
#### v0.4.297
|
#### v0.4.297
|
||||||
- fix _"Could not decode a text frame as UTF-8"_ websocket error _//Thanks for [Verholazila](https://4pda.to/forum/index.php?s=&showtopic=1010378&view=findpost&p=113551446)_
|
- fix _"Could not decode a text frame as UTF-8"_ websocket error _//Thanks for [Verholazila](https://4pda.to/forum/index.php?s=&showtopic=1010378&view=findpost&p=113551446)_
|
||||||
- fix display of non-latin characters in the web interface
|
- fix display of non-latin characters in the web interface
|
||||||
- fix css in Chrome
|
- fix css in Chrome (a [full update](#update) is required)
|
||||||
|
|
||||||
#### v0.4.293
|
#### v0.4.293
|
||||||
- IR repeat fix
|
- IR repeat fix
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "Arduino.h"
|
||||||
#include "controls.h"
|
#include "controls.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -71,6 +72,7 @@ void initControls() {
|
|||||||
btnright.attachDoubleClick(onRightDoubleClick);
|
btnright.attachDoubleClick(onRightDoubleClick);
|
||||||
#endif
|
#endif
|
||||||
#if IR_PIN!=255
|
#if IR_PIN!=255
|
||||||
|
pinMode(IR_PIN, INPUT);
|
||||||
assert(irutils::lowLevelSanityCheck() == 0);
|
assert(irutils::lowLevelSanityCheck() == 0);
|
||||||
#if DECODE_HASH
|
#if DECODE_HASH
|
||||||
irrecv.setUnknownThreshold(kMinUnknownSize);
|
irrecv.setUnknownThreshold(kMinUnknownSize);
|
||||||
@@ -112,6 +114,27 @@ void encoderLoop() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IR_PIN!=255
|
#if IR_PIN!=255
|
||||||
|
|
||||||
|
void irBlink() {
|
||||||
|
if (player.mode == STOPPED) {
|
||||||
|
for(byte i=0; i<7; i++) {
|
||||||
|
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
|
||||||
|
delay(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void irNum(byte num) {
|
||||||
|
uint16_t s;
|
||||||
|
if (display.numOfNextStation == 0 && num == 0) return;
|
||||||
|
if (display.mode == PLAYER) display.swichMode(NUMBERS);
|
||||||
|
if (display.numOfNextStation > UINT16_MAX / 10) return;
|
||||||
|
s = display.numOfNextStation * 10 + num;
|
||||||
|
if (s > config.store.countStation) return;
|
||||||
|
display.numOfNextStation = s;
|
||||||
|
display.drawNextStationNum(s);
|
||||||
|
}
|
||||||
|
|
||||||
void irLoop() {
|
void irLoop() {
|
||||||
if (irrecv.decode(&irResults)) {
|
if (irrecv.decode(&irResults)) {
|
||||||
if (IR_DEBUG) {
|
if (IR_DEBUG) {
|
||||||
@@ -133,6 +156,13 @@ void irLoop() {
|
|||||||
}
|
}
|
||||||
switch (irResults.value) {
|
switch (irResults.value) {
|
||||||
case IR_CODE_PLAY: {
|
case IR_CODE_PLAY: {
|
||||||
|
irBlink();
|
||||||
|
if (display.mode == NUMBERS) {
|
||||||
|
display.swichMode(PLAYER);
|
||||||
|
player.play(display.numOfNextStation);
|
||||||
|
display.numOfNextStation = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
onEncClick();
|
onEncClick();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -155,15 +185,64 @@ void irLoop() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IR_CODE_HASH: {
|
case IR_CODE_HASH: {
|
||||||
|
if (display.mode == NUMBERS) {
|
||||||
|
display.swichMode(PLAYER);
|
||||||
|
display.numOfNextStation = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
display.swichMode(display.mode == PLAYER ? STATIONS : PLAYER);
|
display.swichMode(display.mode == PLAYER ? STATIONS : PLAYER);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IR_CODE_NUM0: {
|
||||||
|
irNum(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM1: {
|
||||||
|
irNum(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM2: {
|
||||||
|
irNum(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM3: {
|
||||||
|
irNum(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM4: {
|
||||||
|
irNum(4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM5: {
|
||||||
|
irNum(5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM6: {
|
||||||
|
irNum(6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM7: {
|
||||||
|
irNum(7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM8: {
|
||||||
|
irNum(8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IR_CODE_NUM9: {
|
||||||
|
irNum(9);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void onEncClick() {
|
void onEncClick() {
|
||||||
|
if (display.mode == NUMBERS) {
|
||||||
|
display.numOfNextStation = 0;
|
||||||
|
display.swichMode(PLAYER);
|
||||||
|
}
|
||||||
if (display.mode == PLAYER) {
|
if (display.mode == PLAYER) {
|
||||||
player.toggle();
|
player.toggle();
|
||||||
}
|
}
|
||||||
@@ -183,6 +262,10 @@ void onEncLPStart() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void controlsEvent(bool toRight) {
|
void controlsEvent(bool toRight) {
|
||||||
|
if (display.mode == NUMBERS) {
|
||||||
|
display.numOfNextStation = 0;
|
||||||
|
display.swichMode(PLAYER);
|
||||||
|
}
|
||||||
if (display.mode != STATIONS) {
|
if (display.mode != STATIONS) {
|
||||||
display.swichMode(VOL);
|
display.swichMode(VOL);
|
||||||
player.stepVol(toRight);
|
player.stepVol(toRight);
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ void onEncDoubleClick();
|
|||||||
void onEncLPStart();
|
void onEncLPStart();
|
||||||
void encoderLoop();
|
void encoderLoop();
|
||||||
void irLoop();
|
void irLoop();
|
||||||
|
void irNum(byte num);
|
||||||
|
void irBlink();
|
||||||
void controlsEvent(bool toRight);
|
void controlsEvent(bool toRight);
|
||||||
|
|
||||||
void onLeftClick();
|
void onLeftClick();
|
||||||
|
|||||||
2
yoRadio/data/data/.gitignore
vendored
Normal file
2
yoRadio/data/data/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
|
|||||||
|
@@ -67,34 +67,37 @@
|
|||||||
</div><!--player-->
|
</div><!--player-->
|
||||||
<div id="settings"%NOTAPMODE%>
|
<div id="settings"%NOTAPMODE%>
|
||||||
<h2>WiFi Settings</h2>
|
<h2>WiFi Settings</h2>
|
||||||
|
<form autocomplete="off">
|
||||||
<ul id="credentialwrap">
|
<ul id="credentialwrap">
|
||||||
<li class="credentialitem">
|
<li class="credentialitem">
|
||||||
<span>1.</span>
|
<span>1.</span>
|
||||||
<div class="textinput"><label for="ssid0">SSID</label><input name="ssid" id="ssid0" type="text" value="%SSID%" maxlength="20"/ ></div>
|
<div class="textinput"><label for="ssid0">SSID</label><input name="ssid" id="ssid0" type="text" value="%SSID%" maxlength="20"/ ></div>
|
||||||
<div class="textinput"><label for"pass0">Password</label><input name="pass" id="pass0" type="password" value="%PASS%" maxlength="40" /></div>
|
<div class="textinput"><label for"pass0">Password</label><input name="pass" id="pass0" type="text" data-pass="%PASS%" placeholder="**********" value="" maxlength="40" autocomplete="off" readonly="readonly" onfocus="this.removeAttribute('readonly');" /></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="credentialitem">
|
<li class="credentialitem">
|
||||||
<span>2.</span>
|
<span>2.</span>
|
||||||
<div class="textinput"><label for="ssid1">SSID</label><input name="ssid" id="ssid1" type="text" value="%SSID%" maxlength="20" /></div>
|
<div class="textinput"><label for="ssid1">SSID</label><input name="ssid" id="ssid1" type="text" value="%SSID%" maxlength="20" /></div>
|
||||||
<div class="textinput"><label for"pass1">Password</label><input name="pass" id="pass1" type="password" value="%PASS%" maxlength="40" /></div>
|
<div class="textinput"><label for"pass1">Password</label><input name="pass" id="pass1" type="text" data-pass="%PASS%" placeholder="**********" value="" maxlength="40" autocomplete="off" readonly="readonly" onfocus="this.removeAttribute('readonly');" /></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="credentialitem">
|
<li class="credentialitem">
|
||||||
<span>3.</span>
|
<span>3.</span>
|
||||||
<div class="textinput"><label for="ssid2">SSID</label><input name="ssid" id="ssid2" type="text" value="%SSID%" maxlength="20" /></div>
|
<div class="textinput"><label for="ssid2">SSID</label><input name="ssid" id="ssid2" type="text" value="%SSID%" maxlength="20" /></div>
|
||||||
<div class="textinput"><label for"pass2">Password</label><input name="pass" id="pass2" type="password" value="%PASS%" maxlength="40" /></div>
|
<div class="textinput"><label for"pass2">Password</label><input name="pass" id="pass2" type="text" data-pass="%PASS%" placeholder="**********" value="" maxlength="40" autocomplete="off" readonly="readonly" onfocus="this.removeAttribute('readonly');" /></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="credentialitem">
|
<li class="credentialitem">
|
||||||
<span>4.</span>
|
<span>4.</span>
|
||||||
<div class="textinput"><label for="ssid3">SSID</label><input name="ssid" id="ssid3" type="text" value="%SSID%" maxlength="20" /></div>
|
<div class="textinput"><label for="ssid3">SSID</label><input name="ssid" id="ssid3" type="text" value="%SSID%" maxlength="20" /></div>
|
||||||
<div class="textinput"><label for"pass3">Password</label><input name="pass" id="pass3" type="password" value="%PASS%" maxlength="40" /></div>
|
<div class="textinput"><label for"pass3">Password</label><input name="pass" id="pass3" type="text" data-pass="%PASS%" placeholder="**********" value="" maxlength="40" autocomplete="off" readonly="readonly" onfocus="this.removeAttribute('readonly');" /></div>
|
||||||
</li>
|
</li>
|
||||||
<li class="credentialitem">
|
<li class="credentialitem">
|
||||||
<span>5.</span>
|
<span>5.</span>
|
||||||
<div class="textinput"><label for="ssid4">SSID</label><input name="ssid" id="ssid4" type="text" value="%SSID%" maxlength="20" /></div>
|
<div class="textinput"><label for="ssid4">SSID</label><input name="ssid" id="ssid4" type="text" value="%SSID%" maxlength="20" /></div>
|
||||||
<div class="textinput"><label for"pass4">Password</label><input name="pass" id="pass4" type="password" value="%PASS%" maxlength="40" /></div>
|
<div class="textinput"><label for"pass4">Password</label><input name="pass" id="pass4" type="text" data-pass="%PASS%" placeholder="**********" value="" maxlength="40" autocomplete="off" readonly="readonly" onfocus="this.removeAttribute('readonly');" /></div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
</form>
|
||||||
<div class="formbuttons">
|
<div class="formbuttons">
|
||||||
|
<div class="button" id="wifiexport_button" onclick="doWifiExport()"%APMODE%>Export</div>
|
||||||
<div class="button" id="cancel_button" onclick="doCancel()"%APMODE%>Cancel</div>
|
<div class="button" id="cancel_button" onclick="doCancel()"%APMODE%>Cancel</div>
|
||||||
<div class="button" id="save_button" onclick="submitWiFi()">Save</div>
|
<div class="button" id="save_button" onclick="submitWiFi()">Save</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
var gateway = `ws://${window.location.hostname}/ws`;
|
var gateway = `ws://${window.location.hostname}/ws`;
|
||||||
var websocket;
|
var websocket;
|
||||||
var currentItem = 0;
|
var currentItem = 0;
|
||||||
|
var wserrcnt = 0;
|
||||||
|
var wstimeout;
|
||||||
|
|
||||||
window.addEventListener('load', onLoad);
|
window.addEventListener('load', onLoad);
|
||||||
function initWebSocket() {
|
function initWebSocket() {
|
||||||
|
clearTimeout(wstimeout);
|
||||||
console.log('Trying to open a WebSocket connection...');
|
console.log('Trying to open a WebSocket connection...');
|
||||||
websocket = new WebSocket(gateway);
|
websocket = new WebSocket(gateway);
|
||||||
websocket.onopen = onOpen;
|
websocket.onopen = onOpen;
|
||||||
@@ -12,13 +15,14 @@ function initWebSocket() {
|
|||||||
}
|
}
|
||||||
function onOpen(event) {
|
function onOpen(event) {
|
||||||
console.log('Connection opened');
|
console.log('Connection opened');
|
||||||
|
wserrcnt=0;
|
||||||
}
|
}
|
||||||
function onClose(event) {
|
function onClose(event) {
|
||||||
console.log('Connection closed');
|
//console.log('Connection closed');
|
||||||
|
wserrcnt++;
|
||||||
document.getElementById('playbutton').setAttribute("class", "stopped");
|
document.getElementById('playbutton').setAttribute("class", "stopped");
|
||||||
setTimeout(initWebSocket, 2000);
|
wstimeout=setTimeout(initWebSocket, wserrcnt<10?2000:120000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMessage(event) {
|
function onMessage(event) {
|
||||||
var data = JSON.parse(event.data);
|
var data = JSON.parse(event.data);
|
||||||
if(data.nameset) document.getElementById('nameset').innerHTML = data.nameset;
|
if(data.nameset) document.getElementById('nameset').innerHTML = data.nameset;
|
||||||
@@ -138,7 +142,6 @@ function setVolRangeValue(el, val=null){
|
|||||||
var value = (el.value-el.min)/(el.max-el.min)*100;
|
var value = (el.value-el.min)/(el.max-el.min)*100;
|
||||||
el.style.background = 'linear-gradient(to right, #bfa73e 0%, #bfa73e ' + value + '%, #272727 ' + value + '%, #272727 100%)';
|
el.style.background = 'linear-gradient(to right, #bfa73e 0%, #bfa73e ' + value + '%, #272727 ' + value + '%, #272727 100%)';
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRangeVolChange(value) {
|
function onRangeVolChange(value) {
|
||||||
xhr = new XMLHttpRequest();
|
xhr = new XMLHttpRequest();
|
||||||
xhr.open("POST","/",true);
|
xhr.open("POST","/",true);
|
||||||
@@ -162,10 +165,12 @@ function onRangeBalChange(el){
|
|||||||
}
|
}
|
||||||
function showSettings(){
|
function showSettings(){
|
||||||
document.getElementById('pleditorwrap').hidden=true;
|
document.getElementById('pleditorwrap').hidden=true;
|
||||||
|
document.getElementById('equalizerbg').hidden=true;
|
||||||
document.getElementById('settings').hidden=false;
|
document.getElementById('settings').hidden=false;
|
||||||
}
|
}
|
||||||
function showEditor(){
|
function showEditor(){
|
||||||
document.getElementById('settings').hidden=true;
|
document.getElementById('settings').hidden=true;
|
||||||
|
document.getElementById('equalizerbg').hidden=true;
|
||||||
initPLEditor();
|
initPLEditor();
|
||||||
document.getElementById('pleditorwrap').hidden=false;
|
document.getElementById('pleditorwrap').hidden=false;
|
||||||
}
|
}
|
||||||
@@ -176,6 +181,10 @@ function doCancel() {
|
|||||||
function doExport() {
|
function doExport() {
|
||||||
window.open("/data/playlist.csv");
|
window.open("/data/playlist.csv");
|
||||||
}
|
}
|
||||||
|
function doWifiExport() {
|
||||||
|
document.getElementById('settings').hidden=true;
|
||||||
|
window.open("/data/wifi.csv");
|
||||||
|
}
|
||||||
function doUpload(finput) {
|
function doUpload(finput) {
|
||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
formData.append("plfile", finput.files[0]);
|
formData.append("plfile", finput.files[0]);
|
||||||
@@ -231,7 +240,8 @@ function submitWiFi(){
|
|||||||
for (var i = 0; i <= items.length - 1; i++) {
|
for (var i = 0; i <= items.length - 1; i++) {
|
||||||
inputs=items[i].getElementsByTagName("input");
|
inputs=items[i].getElementsByTagName("input");
|
||||||
if(inputs[0].value == "") continue;
|
if(inputs[0].value == "") continue;
|
||||||
output+=inputs[0].value+"\t"+inputs[1].value+"\n";
|
let ps=inputs[1].value==""?inputs[1].getAttribute('data-pass'):inputs[1].value;
|
||||||
|
output+=inputs[0].value+"\t"+ps+"\n";
|
||||||
}
|
}
|
||||||
if(output!=""){ // Well, let's say, quack.
|
if(output!=""){ // Well, let's say, quack.
|
||||||
xhr = new XMLHttpRequest();
|
xhr = new XMLHttpRequest();
|
||||||
|
|||||||
@@ -204,6 +204,9 @@ void Display::swichMode(displayMode_e newmode) {
|
|||||||
if (newmode == VOL) {
|
if (newmode == VOL) {
|
||||||
dsp.frameTitle("VOLUME");
|
dsp.frameTitle("VOLUME");
|
||||||
}
|
}
|
||||||
|
if (newmode == NUMBERS) {
|
||||||
|
dsp.frameTitle("STATION");
|
||||||
|
}
|
||||||
if (newmode == STATIONS) {
|
if (newmode == STATIONS) {
|
||||||
currentPlItem = config.store.lastStation;
|
currentPlItem = config.store.lastStation;
|
||||||
plCurrent.reset();
|
plCurrent.reset();
|
||||||
@@ -235,6 +238,10 @@ void Display::drawPlaylist() {
|
|||||||
plCurrent.setText(dsp.utf8Rus(buf, true));
|
plCurrent.setText(dsp.utf8Rus(buf, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Display::drawNextStationNum(uint16_t num) {
|
||||||
|
dsp.drawNextStationNum(num);
|
||||||
|
}
|
||||||
|
|
||||||
void Display::loop() {
|
void Display::loop() {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PLAYER: {
|
case PLAYER: {
|
||||||
@@ -245,6 +252,9 @@ void Display::loop() {
|
|||||||
drawVolume();
|
drawVolume();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NUMBERS: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
case STATIONS: {
|
case STATIONS: {
|
||||||
plCurrent.loop();
|
plCurrent.loop();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include <Ticker.h>
|
#include <Ticker.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
enum displayMode_e { PLAYER, VOL, STATIONS };
|
enum displayMode_e { PLAYER, VOL, STATIONS, NUMBERS };
|
||||||
|
|
||||||
class Scroll {
|
class Scroll {
|
||||||
public:
|
public:
|
||||||
@@ -42,6 +42,7 @@ class Display {
|
|||||||
uint16_t screenwidth, screenheight;
|
uint16_t screenwidth, screenheight;
|
||||||
displayMode_e mode;
|
displayMode_e mode;
|
||||||
uint16_t currentPlItem;
|
uint16_t currentPlItem;
|
||||||
|
uint16_t numOfNextStation;
|
||||||
public:
|
public:
|
||||||
Display() {};
|
Display() {};
|
||||||
void init();
|
void init();
|
||||||
@@ -58,6 +59,7 @@ class Display {
|
|||||||
void ip();
|
void ip();
|
||||||
void swichMode(displayMode_e newmode);
|
void swichMode(displayMode_e newmode);
|
||||||
void drawPlaylist();
|
void drawPlaylist();
|
||||||
|
void drawNextStationNum(uint16_t num);
|
||||||
private:
|
private:
|
||||||
Ticker timer;
|
Ticker timer;
|
||||||
Scroll meta, title1, title2, plCurrent;
|
Scroll meta, title1, title2, plCurrent;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#ifndef options_h
|
#ifndef options_h
|
||||||
#define options_h
|
#define options_h
|
||||||
|
|
||||||
#define VERSION "0.4.298"
|
#define VERSION "0.4.315"
|
||||||
|
|
||||||
#if __has_include("myoptions.h")
|
#if __has_include("myoptions.h")
|
||||||
#include "myoptions.h" // <- write your variable values here
|
#include "myoptions.h" // <- write your variable values here
|
||||||
@@ -115,6 +115,13 @@
|
|||||||
#define VOL_STEP 1 // Encoder vol step
|
#define VOL_STEP 1 // Encoder vol step
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MUTE_PIN
|
||||||
|
#define MUTE_PIN 255 // MUTE Pin
|
||||||
|
#endif
|
||||||
|
#ifndef MUTE_VAL
|
||||||
|
#define MUTE_VAL HIGH // Write this to MUTE_PIN when player is stopped
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*** ST7735 display submodel ***
|
*** ST7735 display submodel ***
|
||||||
INITR_BLACKTAB // 1.8' https://aliexpress.ru/item/1005002822797745.html
|
INITR_BLACKTAB // 1.8' https://aliexpress.ru/item/1005002822797745.html
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ Player::Player() {}
|
|||||||
|
|
||||||
|
|
||||||
void Player::init() {
|
void Player::init() {
|
||||||
|
if(MUTE_PIN!=255) pinMode(MUTE_PIN, OUTPUT);
|
||||||
#if I2S_DOUT!=255
|
#if I2S_DOUT!=255
|
||||||
setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
|
setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT);
|
||||||
#else
|
#else
|
||||||
@@ -55,7 +56,8 @@ void Player::loop() {
|
|||||||
Audio::loop();
|
Audio::loop();
|
||||||
} else {
|
} else {
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
digitalWrite(LED_BUILTIN, LOW);
|
//digitalWrite(LED_BUILTIN, LOW);
|
||||||
|
setOutputPins(false);
|
||||||
display.title("[stopped]");
|
display.title("[stopped]");
|
||||||
stopSong();
|
stopSong();
|
||||||
stopInfo();
|
stopInfo();
|
||||||
@@ -84,9 +86,15 @@ void Player::zeroRequest() {
|
|||||||
request.doSave = false;
|
request.doSave = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::play(byte stationId) {
|
void Player::setOutputPins(bool isPlaying) {
|
||||||
|
digitalWrite(LED_BUILTIN, isPlaying);
|
||||||
|
if(MUTE_PIN!=255) digitalWrite(MUTE_PIN, isPlaying?!MUTE_VAL:MUTE_VAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::play(uint16_t stationId) {
|
||||||
stopSong();
|
stopSong();
|
||||||
digitalWrite(LED_BUILTIN, LOW);
|
//digitalWrite(LED_BUILTIN, LOW);
|
||||||
|
setOutputPins(false);
|
||||||
display.title("[connecting]");
|
display.title("[connecting]");
|
||||||
telnet.printf("##CLI.META#: %s\n", config.station.title);
|
telnet.printf("##CLI.META#: %s\n", config.station.title);
|
||||||
config.loadStation(stationId);
|
config.loadStation(stationId);
|
||||||
@@ -97,7 +105,8 @@ void Player::play(byte stationId) {
|
|||||||
mode = PLAYING;
|
mode = PLAYING;
|
||||||
config.setSmartStart(1);
|
config.setSmartStart(1);
|
||||||
netserver.requestOnChange(MODE, 0);
|
netserver.requestOnChange(MODE, 0);
|
||||||
digitalWrite(LED_BUILTIN, HIGH);
|
//digitalWrite(LED_BUILTIN, HIGH);
|
||||||
|
setOutputPins(true);
|
||||||
requesToStart = true;
|
requesToStart = true;
|
||||||
}else{
|
}else{
|
||||||
Serial.println("Some Unknown Bug...");
|
Serial.println("Some Unknown Bug...");
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class Player: public Audio {
|
|||||||
void init();
|
void init();
|
||||||
void loop();
|
void loop();
|
||||||
void zeroRequest();
|
void zeroRequest();
|
||||||
void play(byte stationId);
|
void play(uint16_t stationId);
|
||||||
void prev();
|
void prev();
|
||||||
void next();
|
void next();
|
||||||
void toggle();
|
void toggle();
|
||||||
@@ -35,6 +35,7 @@ class Player: public Audio {
|
|||||||
void setVol(byte volume, bool inside);
|
void setVol(byte volume, bool inside);
|
||||||
byte volToI2S(byte volume);
|
byte volToI2S(byte volume);
|
||||||
void stopInfo();
|
void stopInfo();
|
||||||
|
void setOutputPins(bool isPlaying);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Player player;
|
extern Player player;
|
||||||
|
|||||||
@@ -137,6 +137,10 @@ void DisplayDummy::drawVolumeBar(bool withNumber) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayDummy::drawNextStationNum(uint16_t num) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void DisplayDummy::frameTitle(const char* str) {
|
void DisplayDummy::frameTitle(const char* str) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class DisplayDummy {
|
|||||||
void printClock(const char* timestr);
|
void printClock(const char* timestr);
|
||||||
void displayHeapForDebug();
|
void displayHeapForDebug();
|
||||||
void drawVolumeBar(bool withNumber);
|
void drawVolumeBar(bool withNumber);
|
||||||
|
void drawNextStationNum(uint16_t num);
|
||||||
char* utf8Rus(const char* str, bool uppercase);
|
char* utf8Rus(const char* str, bool uppercase);
|
||||||
void drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg);
|
void drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg);
|
||||||
void getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth);
|
void getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth);
|
||||||
|
|||||||
@@ -250,6 +250,21 @@ void DisplayN5110::drawVolumeBar(bool withNumber) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayN5110::drawNextStationNum(uint16_t num) {
|
||||||
|
setTextSize(1);
|
||||||
|
setTextColor(TFT_FG);
|
||||||
|
char numstr[7];
|
||||||
|
uint16_t wv, hv;
|
||||||
|
int16_t x1, y1;
|
||||||
|
sprintf(numstr, "%d", num);
|
||||||
|
setFont(&DS_DIGI15pt7b);
|
||||||
|
getTextBounds(numstr, 0, 0, &x1, &y1, &wv, &hv);
|
||||||
|
fillRect(TFT_FRAMEWDT, 24-10, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG);
|
||||||
|
setCursor((swidth - wv) / 2, 24+8);
|
||||||
|
print(numstr);
|
||||||
|
setFont();
|
||||||
|
}
|
||||||
|
|
||||||
void DisplayN5110::frameTitle(const char* str) {
|
void DisplayN5110::frameTitle(const char* str) {
|
||||||
setTextSize(1);
|
setTextSize(1);
|
||||||
centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG);
|
centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class DisplayN5110: public Adafruit_PCD8544 {
|
|||||||
void printClock(const char* timestr);
|
void printClock(const char* timestr);
|
||||||
void displayHeapForDebug();
|
void displayHeapForDebug();
|
||||||
void drawVolumeBar(bool withNumber);
|
void drawVolumeBar(bool withNumber);
|
||||||
|
void drawNextStationNum(uint16_t num);
|
||||||
char* utf8Rus(const char* str, bool uppercase);
|
char* utf8Rus(const char* str, bool uppercase);
|
||||||
void drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg);
|
void drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg);
|
||||||
void getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth);
|
void getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth);
|
||||||
|
|||||||
@@ -245,6 +245,19 @@ void DisplaySSD1306::drawVolumeBar(bool withNumber) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplaySSD1306::drawNextStationNum(uint16_t num) {
|
||||||
|
setTextSize(2);
|
||||||
|
setTextColor(TFT_FG);
|
||||||
|
char numstr[7];
|
||||||
|
uint16_t wv, hv;
|
||||||
|
int16_t x1, y1;
|
||||||
|
sprintf(numstr, "%d", num);
|
||||||
|
getTextBounds(numstr, 0, 0, &x1, &y1, &wv, &hv);
|
||||||
|
fillRect(TFT_FRAMEWDT, 24, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG);
|
||||||
|
setCursor((swidth - wv) / 2, 24);
|
||||||
|
print(numstr);
|
||||||
|
}
|
||||||
|
|
||||||
void DisplaySSD1306::frameTitle(const char* str) {
|
void DisplaySSD1306::frameTitle(const char* str) {
|
||||||
setTextSize(2);
|
setTextSize(2);
|
||||||
centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG);
|
centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class DisplaySSD1306: public Adafruit_SSD1306 {
|
|||||||
void printClock(const char* timestr);
|
void printClock(const char* timestr);
|
||||||
void displayHeapForDebug();
|
void displayHeapForDebug();
|
||||||
void drawVolumeBar(bool withNumber);
|
void drawVolumeBar(bool withNumber);
|
||||||
|
void drawNextStationNum(uint16_t num);
|
||||||
char* utf8Rus(const char* str, bool uppercase);
|
char* utf8Rus(const char* str, bool uppercase);
|
||||||
void drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg);
|
void drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg);
|
||||||
void getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth);
|
void getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth);
|
||||||
|
|||||||
@@ -275,6 +275,21 @@ void DisplayST7735::drawVolumeBar(bool withNumber) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayST7735::drawNextStationNum(uint16_t num) {
|
||||||
|
setTextSize(1);
|
||||||
|
setTextColor(TFT_FG);
|
||||||
|
setFont(&DS_DIGI28pt7b);
|
||||||
|
char numstr[7];
|
||||||
|
uint16_t wv, hv;
|
||||||
|
int16_t x1, y1;
|
||||||
|
sprintf(numstr, "%d", num);
|
||||||
|
getTextBounds(numstr, 0, 0, &x1, &y1, &wv, &hv);
|
||||||
|
fillRect(TFT_FRAMEWDT, 48, swidth - TFT_FRAMEWDT / 2, hv + 3, TFT_BG);
|
||||||
|
setCursor((swidth - wv) / 2, 48 + hv);
|
||||||
|
print(numstr);
|
||||||
|
setFont();
|
||||||
|
}
|
||||||
|
|
||||||
void DisplayST7735::frameTitle(const char* str) {
|
void DisplayST7735::frameTitle(const char* str) {
|
||||||
setTextSize(2);
|
setTextSize(2);
|
||||||
centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG);
|
centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ class DisplayST7735: public Adafruit_ST7735 {
|
|||||||
void printClock(const char* timestr);
|
void printClock(const char* timestr);
|
||||||
void displayHeapForDebug();
|
void displayHeapForDebug();
|
||||||
void drawVolumeBar(bool withNumber);
|
void drawVolumeBar(bool withNumber);
|
||||||
|
void drawNextStationNum(uint16_t num);
|
||||||
char* utf8Rus(const char* str, bool uppercase);
|
char* utf8Rus(const char* str, bool uppercase);
|
||||||
void drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg);
|
void drawScrollFrame(uint16_t texttop, uint16_t textheight, uint16_t bg);
|
||||||
void getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth);
|
void getScrolBbounds(const char* text, const char* separator, byte textsize, uint16_t &tWidth, uint16_t &tHeight, uint16_t &sWidth);
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ void Telnet::on_input(const char* str, byte clientId) {
|
|||||||
printf(clientId, "> ");
|
printf(clientId, "> ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t sb;
|
uint16_t sb;
|
||||||
if (sscanf(str, "play(%d)", &sb) == 1 || sscanf(str, "cli.play(\"%d\")", &sb) == 1 || sscanf(str, "play %d", &sb) == 1 ) {
|
if (sscanf(str, "play(%d)", &sb) == 1 || sscanf(str, "cli.play(\"%d\")", &sb) == 1 || sscanf(str, "play %d", &sb) == 1 ) {
|
||||||
if (sb < 1) sb = 1;
|
if (sb < 1) sb = 1;
|
||||||
if (sb >= config.store.countStation) sb = config.store.countStation;
|
if (sb >= config.store.countStation) sb = config.store.countStation;
|
||||||
|
|||||||
@@ -13,10 +13,11 @@
|
|||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
pinMode(LED_BUILTIN, OUTPUT);
|
||||||
digitalWrite(LED_BUILTIN, LOW);
|
//digitalWrite(LED_BUILTIN, LOW);
|
||||||
config.init();
|
config.init();
|
||||||
display.init();
|
display.init();
|
||||||
player.init();
|
player.init();
|
||||||
|
player.setOutputPins(false);
|
||||||
network.begin();
|
network.begin();
|
||||||
if (network.status != CONNECTED) {
|
if (network.status != CONNECTED) {
|
||||||
netserver.begin();
|
netserver.begin();
|
||||||
|
|||||||
Reference in New Issue
Block a user