Created
March 28, 2023 18:19
-
-
Save npdgm/2bec3b30c0933d09af83c4bd1efc7e18 to your computer and use it in GitHub Desktop.
Test : Arduino on ESP32 ; I2S output audio output (radio streaming) ; WS2812 LEDs driven by I2S method
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <Arduino.h> | |
| #include <WiFi.h> | |
| #include <Audio.h> | |
| #include <NeoPixelBus.h> | |
| #include <NeoPixelAnimator.h> | |
| #define I2S_DOUT 27 | |
| #define I2S_BCLK 32 | |
| #define I2S_LRC 33 | |
| #define LED_PIN 4 | |
| #define LED_COUNT 13 | |
| #define LED_SATURATION 128 | |
| String ssid = "*******"; | |
| String password = "*******"; | |
| Audio audio; | |
| //NeoPixelBus<NeoGrbFeature, NeoEsp32BitBangWs2812xMethod> strip(LED_COUNT, LED_PIN); | |
| //NeoPixelBus<NeoGrbFeature, NeoEsp32I2s0Ws2812xMethod> strip(LED_COUNT, LED_PIN); | |
| NeoPixelBus<NeoGrbFeature, NeoEsp32I2s1Ws2812xMethod> strip(LED_COUNT, LED_PIN); | |
| //NeoPixelBus<NeoGrbFeature, NeoEsp32I2sNWs2812xMethod> strip(LED_COUNT, LED_PIN); | |
| RgbColor red(LED_SATURATION, 0, 0); | |
| RgbColor green(0, LED_SATURATION, 0); | |
| RgbColor blue(0, 0, LED_SATURATION); | |
| RgbColor white(LED_SATURATION); | |
| RgbColor black(0); | |
| const uint16_t PixelCount = LED_COUNT - 1; | |
| const uint16_t AnimCount = PixelCount / 5 * 2 + 4; | |
| const uint16_t PixelFadeDuration = 800; | |
| const uint16_t NextPixelMoveDuration = 1000 / PixelCount; | |
| NeoGamma<NeoGammaTableMethod> colorGamma; | |
| struct MyAnimationState { | |
| RgbColor StartingColor; | |
| RgbColor EndingColor; | |
| uint16_t IndexPixel; | |
| }; | |
| NeoPixelAnimator animations(AnimCount); | |
| MyAnimationState animationState[AnimCount]; | |
| uint16_t frontPixel = 0; | |
| RgbColor frontColor; | |
| void SetRandomSeed() { | |
| uint32_t seed; | |
| seed = analogRead(0); | |
| delay(1); | |
| for (int shifts = 3; shifts < 31; shifts += 3) { | |
| seed ^= analogRead(0) << shifts; | |
| delay(1); | |
| } | |
| randomSeed(seed); | |
| } | |
| void FadeOutAnimUpdate(const AnimationParam& param) { | |
| // this gets called for each animation on every time step | |
| // progress will start at 0.0 and end at 1.0 | |
| // we use the blend function on the RgbColor to mix | |
| // color based on the progress given to us in the animation | |
| RgbColor updatedColor = RgbColor::LinearBlend( | |
| animationState[param.index].StartingColor, | |
| animationState[param.index].EndingColor, | |
| param.progress); | |
| // apply the color to the strip | |
| strip.SetPixelColor(animationState[param.index].IndexPixel, | |
| colorGamma.Correct(updatedColor)); | |
| } | |
| void LoopAnimUpdate(const AnimationParam& param) { | |
| if (param.state == AnimationState_Completed) { | |
| // done, time to restart this position tracking animation/timer | |
| animations.RestartAnimation(param.index); | |
| // pick the next pixel inline to start animating | |
| frontPixel = (frontPixel + 1) % PixelCount; // increment and wrap | |
| if (frontPixel == 0) { | |
| // we looped, lets pick a new front color | |
| frontColor = HslColor(random(360) / 360.0f, 1.0f, 0.5f); | |
| } | |
| uint16_t indexAnim; | |
| // do we have an animation available to use to animate the next front pixel? | |
| // if you see skipping, then either you are going to fast or need to increase | |
| // the number of animation channels | |
| if (animations.NextAvailableAnimation(&indexAnim, 1)) { | |
| animationState[indexAnim].StartingColor = frontColor; | |
| animationState[indexAnim].EndingColor = RgbColor(0, 0, 0); | |
| animationState[indexAnim].IndexPixel = frontPixel + 1; | |
| animations.StartAnimation(indexAnim, PixelFadeDuration, FadeOutAnimUpdate); | |
| } | |
| } | |
| } | |
| void setup() { | |
| Serial.begin(115200); | |
| log_i("Total heap: %d", ESP.getHeapSize()); | |
| log_i("Free heap: %d", ESP.getFreeHeap()); | |
| log_i("Total PSRAM: %d", ESP.getPsramSize()); | |
| log_i("Free PSRAM: %d", ESP.getFreePsram()); | |
| SetRandomSeed(); | |
| strip.Begin(); | |
| strip.ClearTo(black); | |
| strip.SetPixelColor(0, red); | |
| strip.Show(); | |
| WiFi.disconnect(); | |
| WiFi.mode(WIFI_STA); | |
| WiFi.begin(ssid.c_str(), password.c_str()); | |
| log_i("Connecting to WiFi..."); | |
| while (WiFi.status() != WL_CONNECTED) { | |
| strip.SetPixelColor(0, blue); | |
| strip.Show(); | |
| delay(1500); | |
| } | |
| strip.SetPixelColor(0, green); | |
| strip.Show(); | |
| log_i("WiFi connected!"); | |
| pinMode(25, OUTPUT); | |
| digitalWrite(25, LOW); | |
| audio.setPinout(I2S_BCLK, I2S_LRC, I2S_DOUT); | |
| audio.forceMono(true); | |
| audio.setVolume(21); | |
| digitalWrite(25, HIGH); | |
| //audio.connecttohost("http://icecast.radiofrance.fr/fip-lofi.aac"); // 32k aac | |
| //audio.connecttohost("http://icecast.radiofrance.fr/fip-midfi.aac"); // 96k aac | |
| audio.connecttohost("http://icecast.radiofrance.fr/fip-midfi.mp3"); // 128k mp3 | |
| //audio.connecttohost("http://icecast.radiofrance.fr/fip-hifi.aac"); // 196k aac | |
| //audio.connecttohost("http://europe2.lmn.fm/europe2.mp3"); // 128k mp3 | |
| animations.StartAnimation(0, NextPixelMoveDuration, LoopAnimUpdate); | |
| } | |
| void loop() { | |
| audio.loop(); | |
| animations.UpdateAnimations(); | |
| strip.Show(); | |
| } | |
| void audio_info(const char *info) { | |
| log_i("info = %s", info); | |
| } | |
| void audio_id3data(const char *info) { | |
| log_i("id3data = %s", info); | |
| } | |
| void audio_eof_mp3(const char *info) { | |
| log_i("eof_mp3 = %s", info); | |
| } | |
| void audio_showstation(const char *info) { | |
| log_i("station = %s", info); | |
| } | |
| void audio_showstreamtitle(const char *info) { | |
| log_i("streamtitle = %s", info); | |
| } | |
| void audio_bitrate(const char *info) { | |
| log_i("bitrate = %s", info); | |
| } | |
| void audio_commercial(const char *info) { | |
| log_i("commercial = %s ", info); | |
| } | |
| void audio_icyurl(const char *info) { | |
| log_i("icyurl = %s", info); | |
| } | |
| void audio_lasthost(const char *info) { | |
| log_i("lasthost = %s", info); | |
| } | |
| void audio_eof_speech(const char *info) { | |
| log_i("eof_speech = %s", info); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment