Na modułach ESP z 4MB flash i większych (a przecież np Wemosów z 32MB nie brakuje, a kosztują ledwo 4$) - można by dodać możliwość wrzucenia przez www (jednego lub kilku) plików .wav ( czy innego małego pliku audio niekompresowanego, nie mp3, by już nie kompilować sprawy) i "odtwarzanie" audio w postaci wypuszczania PWMu na gpio pod wpływem wyzwalania lokalnego lub zdalnego (tak samo, jakby to był kanał przekaźnika).
Aby to miało sens - trzeba by zwiększyć częstotliwość PWMu (obecnie jest default 1kHz) = analogWriteFreq(new_frequency); (btw - na ustawianie tej częstotliwości dla modułów, przez WWW konfigurator, wrzucam osobne issue)
można i 40kHz dać, co pozwoliłoby całkiem przyzwoicie brzmieć plikowi .wav z 8bit i 10kHz sampling, do zrobienia "gong" czy innego "ti-tu-ta" na okazję otwarcia bramy, czy zakończenia działania mikrofalówki, albo czytelny komunikat słowny "brama otwiera się" - w wielu zastosowaniach wystarczy dzwięk jak z chińskiej zabawki, nie musi być hi-fi.
Sprawdzony kod, który gra mi .WAV (8bit, mono, 8KHz) na esp:
void timerCallback(void *pArg) {if (f.position()>=(f.size()-1)) {stopPlayback();//Serial.println("Finished");return;}/*if (micros()-oldmicros>500000)//Uncomment for debugging{Serial.print(oldmicros);Serial.print(" Pos ");Serial.print(f.position());Serial.print(" Size ");Serial.println(f.size());oldmicros=micros();}*/analogWrite(speakerPin,buffer1[0]);f.readBytes(buffer1,1);} // End of timerCallback
void startPlayback(){//oldmicros=0;analogWriteRange(255);//8 BitanalogWriteFreq(32000);//Multiple of the sample ratebPlaying=true;os_timer_setfn(&PMCtimer, timerCallback, NULL);ets_timer_arm_new(&PMCtimer,125,1,0);//125us corresponds to 8000 samples/secSerial.println("timer started");//For debugging only//Serial.print("File size in startPlayback");Serial.println(f.size());//For debugging only}void stopPlayback(){os_timer_disarm(&PMCtimer);Serial.println("timer disarmed");//For debugging onlyanalogWrite(speakerPin, 0);bPlaying=false;}void setup() {Serial.begin(115200);Serial.println("start");SPIFFS.begin();Serial.println("SPIFFS started");bPlaying=false;}
void loop() {f = SPIFFS.open("/Regal.wav", "r");if (!f) {Serial.println("file open failed");} else {Serial.println("file opened");}analogWriteRange(255);//8 BitanalogWriteFreq(32000);//Multiple of the sample rateSerial.print("File size ");Serial.println(f.size());//For debugging onlystartPlayback();//Insert code here that will be executed while the sound file is played in the backgroundwhile(bPlaying) delay(40); //use this to make sure playback is finished before closing the filef.close();}
Plusy - w zasadzie zerowy nakład na hardware, nie potrzeba specjalistycznego DACa żadnego, zajmuje jeden pin (w przeciwieństwie do DACów wszelkich, gdzie przynajmniej i2c 2 piny trzeba by), wystarczy w najprostrzej wersji tranzystor i przetwornik piezo, albo filtr opornik-kondensator i wzmacniacz klasy D za 1$, zasilany 5v wspólnym, a dałoby to ~1W na głośniczek.
Na modułach ESP z 4MB flash i większych (a przecież np Wemosów z 32MB nie brakuje, a kosztują ledwo 4$) - można by dodać możliwość wrzucenia przez www (jednego lub kilku) plików .wav ( czy innego małego pliku audio niekompresowanego, nie mp3, by już nie kompilować sprawy) i "odtwarzanie" audio w postaci wypuszczania PWMu na gpio pod wpływem wyzwalania lokalnego lub zdalnego (tak samo, jakby to był kanał przekaźnika).
Aby to miało sens - trzeba by zwiększyć częstotliwość PWMu (obecnie jest default 1kHz) = analogWriteFreq(new_frequency); (btw - na ustawianie tej częstotliwości dla modułów, przez WWW konfigurator, wrzucam osobne issue) można i 40kHz dać, co pozwoliłoby całkiem przyzwoicie brzmieć plikowi .wav z 8bit i 10kHz sampling, do zrobienia "gong" czy innego "ti-tu-ta" na okazję otwarcia bramy, czy zakończenia działania mikrofalówki, albo czytelny komunikat słowny "brama otwiera się" - w wielu zastosowaniach wystarczy dzwięk jak z chińskiej zabawki, nie musi być hi-fi.
Sprawdzony kod, który gra mi .WAV (8bit, mono, 8KHz) na esp:
extern "C" {
#include "os_type.h"
}
//use GPIO5
#define speakerPin 5
#define BufferSize 1
#include "FS.h"
File f;
os_timer_t PMCtimer;
int oldmicros;
bool bPlaying;
char buffer1[BufferSize];
void timerCallback(void *pArg) {
if (f.position()>=(f.size()-1)) {
stopPlayback();
//Serial.println("Finished");
return;
}
/*if (micros()-oldmicros>500000)//Uncomment for debugging
{
Serial.print(oldmicros);Serial.print(" Pos ");Serial.print(f.position());
Serial.print(" Size ");Serial.println(f.size());
oldmicros=micros();
}*/
analogWrite(speakerPin,buffer1[0]);
f.readBytes(buffer1,1);
} // End of timerCallback
void startPlayback()
{
//oldmicros=0;
analogWriteRange(255);//8 Bit
analogWriteFreq(32000);//Multiple of the sample rate
bPlaying=true;
os_timer_setfn(&PMCtimer, timerCallback, NULL);
ets_timer_arm_new(&PMCtimer,125,1,0);//125us corresponds to 8000 samples/sec
Serial.println("timer started");//For debugging only
//Serial.print("File size in startPlayback");Serial.println(f.size());//For debugging only
}
void stopPlayback()
{
os_timer_disarm(&PMCtimer);
Serial.println("timer disarmed");//For debugging only
analogWrite(speakerPin, 0);
bPlaying=false;
}
void setup() {
Serial.begin(115200);
Serial.println("start");
SPIFFS.begin();
Serial.println("SPIFFS started");
bPlaying=false;
}
void loop() {
f = SPIFFS.open("/Regal.wav", "r");
if (!f) {
Serial.println("file open failed");
} else {Serial.println("file opened");}
analogWriteRange(255);//8 Bit
analogWriteFreq(32000);//Multiple of the sample rate
Serial.print("File size ");Serial.println(f.size());//For debugging only
startPlayback();
//Insert code here that will be executed while the sound file is played in the background
while(bPlaying) delay(40); //use this to make sure playback is finished before closing the file
f.close();
}
Plusy - w zasadzie zerowy nakład na hardware, nie potrzeba specjalistycznego DACa żadnego, zajmuje jeden pin (w przeciwieństwie do DACów wszelkich, gdzie przynajmniej i2c 2 piny trzeba by), wystarczy w najprostrzej wersji tranzystor i przetwornik piezo, albo filtr opornik-kondensator i wzmacniacz klasy D za 1$, zasilany 5v wspólnym, a dałoby to ~1W na głośniczek.