Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new device - inmp441max98357afastled #116

Merged
merged 1 commit into from
Dec 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion PlatformIO/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ lib_deps =

[env:esp32dev]

;supported: M5ATOMECHO=0, MATRIXVOICE=1, AUDIOKIT=2, INMP441=3, INMP441MAX98357A=4
;supported: M5ATOMECHO=0, MATRIXVOICE=1, AUDIOKIT=2, INMP441=3, INMP441MAX98357A=4, ESP32_POE_ISO=5, TAUDIO=6, INMP441MAX98357AFASTLED=7

[env:m5atomecho]
build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=0
Expand All @@ -67,3 +67,6 @@ build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=5

[env:taudio]
build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=6

[env:inmp441max98357afastled]
build_flags = ${env.build_flags} -DPI_DEVICE_TYPE=7
2 changes: 1 addition & 1 deletion PlatformIO/settings.ini.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
hostname=192.168.43.140
deployhost=192.168.43.24
siteId=satellite
;supported: M5ATOMECHO=0, MATRIXVOICE=1, AUDIOKIT=2, INMP441=3, INMP441MAX98357A=4, ESP32_POE_ISO=5, TAUDIO=6
;supported: M5ATOMECHO=0, MATRIXVOICE=1, AUDIOKIT=2, INMP441=3, INMP441MAX98357A=4, ESP32_POE_ISO=5, TAUDIO=6, INMP441MAX98357AFASTLED=7
device_type=4
Romkabouter marked this conversation as resolved.
Show resolved Hide resolved
;network_type: 0: WiFi, 1: Ethernet
network_type=0
Expand Down
4 changes: 4 additions & 0 deletions PlatformIO/src/Satellite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
#define INMP441MAX98357A 4
#define ESP32_POE_ISO 5
#define TAUDIO 6
#define INMP441MAX98357AFASTLED 7

#ifdef PI_DEVICE_TYPE
#undef DEVICE_TYPE
Expand Down Expand Up @@ -163,6 +164,9 @@
#elif DEVICE_TYPE == TAUDIO
#include "devices/TAudio.hpp"
TAudio *device = new TAudio();
#elif DEVICE_TYPE == INMP441MAX98357AFASTLED
#include "devices/Inmp441Max98357aFastLed.hpp"
Inmp441Max98357aFastLED *device = new Inmp441Max98357aFastLED();
#else
#error DEVICE_TYPE is out of range
#endif
Expand Down
237 changes: 237 additions & 0 deletions PlatformIO/src/devices/Inmp441Max98357aFastLed.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
#pragma once
#include <Arduino.h>
#include <device.h>

#include "IndicatorLight.h"
#include <driver/i2s.h>

#include <FastLED.h>

// Led strip
#define LED_PIN 26
#define NUM_LEDS 5
CRGB leds[NUM_LEDS];

// I2S pins on ESp32cam MIC
// GPIO2 <--> WS
// GPIO14 <--> SCK
// GPIO15 <--> SD
#define I2S_SCK 25
#define I2S_WS 32
#define I2S_SD 33
#define I2S_PORT I2S_NUM_0

// I2S pins on ESp32Cam Speakers
// GPIO16 <--> LRC
// GPIO13 <--> BCLK
// GPIO12 <--> DIN
#define I2S_LRC 12
#define I2S_BCLK 14
#define I2S_DIN 27

#define I2S_PORT_TX I2S_NUM_1

#define I2S_OUTPUT_SAMPLE_RATE (22050)
#define I2S_SAMPLE_RATE (16000)
#define I2S_SAMPLE_BITS (16)
#define I2S_READ_LEN 512
// LEDs
#define LED_FLASH 4

#define KEY1_GPIO GPIO_NUM_34
#define KEY_LISTEN KEY1_GPIO

class Inmp441Max98357aFastLED : public Device
{
public:
Inmp441Max98357aFastLED() = default;

void init();
bool readAudio(uint8_t *data, size_t size);

void setWriteMode(int sampleRate, int bitDepth, int numChannels);
void writeAudio(uint8_t *data, size_t size, size_t *bytes_written);

int numAmpOutConfigurations()
{
return 1;
}

void updateColors(StateColors colors);
void updateBrightness(int brightness);

bool animationSupported()
{
return true;
}
bool runningSupported()
{
return true;
}
bool blinkingSupported()
{
return true;
}

void animate(StateColors colors, int mode);
void animateRunning(StateColors colors);
void animateBlinking(StateColors colors);

private:
char *i2s_read_buff = (char *)calloc(I2S_READ_LEN, sizeof(char));
long currentMillis, startMillis;
};

void Inmp441Max98357aFastLED::init()
{
esp_err_t err = ESP_OK;
Serial.printf("Connect to Inmp441... \n");

// Speakers
i2s_config_t i2sConfig_tx = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = I2S_OUTPUT_SAMPLE_RATE, // I2S_SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_STAND_I2S),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 2,
.dma_buf_len = 512,
.tx_desc_auto_clear = true,
};

i2s_pin_config_t pin_config_tx = {
.bck_io_num = I2S_BCLK, .ws_io_num = I2S_LRC, .data_out_num = I2S_DIN, .data_in_num = -1};

err += i2s_driver_install(I2S_PORT_TX, &i2sConfig_tx, 0, NULL);
if (err != ESP_OK) {
Serial.printf("Failed installing headphone driver: %d\n", err);
while (true)
;
}

err += i2s_set_pin(I2S_PORT_TX, &pin_config_tx);
if (err != ESP_OK) {
Serial.printf("Failed setting headphone pin: %d\n", err);
while (true)
;
}
Serial.println("I2S headphone driver installed.\n");

i2s_config_t i2s_config = {.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = I2S_SAMPLE_RATE,
.bits_per_sample = i2s_bits_per_sample_t(I2S_SAMPLE_BITS),
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_STAND_I2S),
.intr_alloc_flags = 0,
.dma_buf_count = 2,
.dma_buf_len = 512,
.use_apll = 1};

i2s_pin_config_t pin_config = {.bck_io_num = I2S_SCK, .ws_io_num = I2S_WS, .data_out_num = -1, .data_in_num = I2S_SD};

err += i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
if (err != ESP_OK) {
Serial.printf("Failed installing mic driver: %d\n", err);
while (true)
;
}

err += i2s_set_pin(I2S_PORT, &pin_config);
if (err != ESP_OK) {
Serial.printf("Failed setting mic pin: %d\n", err);
while (true)
;
}
Serial.println("I2S driver mic installed.");

FastLED.addLeds<NEOPIXEL, LED_PIN>(leds, NUM_LEDS);

return;
}

void Inmp441Max98357aFastLED::updateColors(StateColors colors)
{
if (colors == StateColors::COLORS_IDLE) {
fill_solid(leds, NUM_LEDS, CRGB::Black);
FastLED.show();
} else {
fill_solid(leds, NUM_LEDS, CRGB(ColorMap[colors][0], ColorMap[colors][1], ColorMap[colors][2]));
FastLED.show();
}
}

void Inmp441Max98357aFastLED::animate(StateColors colors, int mode)
{
switch (mode) {
case AnimationMode::RUN:
animateRunning(colors);
break;
case AnimationMode::BLINK:
animateBlinking(colors);
break;
default:
break;
}
}

void Inmp441Max98357aFastLED::animateRunning(StateColors colors)
{
static uint8_t current_position = 0;
currentMillis = millis();
if (currentMillis - startMillis > 50) {
fill_solid(leds, NUM_LEDS, CRGB::Black);
leds[current_position] = CRGB(ColorMap[colors][0], ColorMap[colors][1], ColorMap[colors][2]);
FastLED.show();
++current_position %= NUM_LEDS;
startMillis = millis();
}
}

void Inmp441Max98357aFastLED::animateBlinking(StateColors colors)
{
static bool currently_on = false;
currentMillis = millis();
if (currentMillis - startMillis > 300) {
if (currently_on) {
fill_solid(leds, NUM_LEDS, CRGB::Black);
} else {
fill_solid(leds, NUM_LEDS, CRGB(ColorMap[colors][0], ColorMap[colors][1], ColorMap[colors][2]));
}
FastLED.show();
currently_on = !currently_on;
startMillis = millis();
}
}

void Inmp441Max98357aFastLED::setWriteMode(int sampleRate, int bitDepth, int numChannels)
{
if (sampleRate > 0) {
i2s_set_clk(I2S_PORT_TX, sampleRate, static_cast<i2s_bits_per_sample_t>(bitDepth),
static_cast<i2s_channel_t>(numChannels));
}
}

void Inmp441Max98357aFastLED::writeAudio(uint8_t *data, size_t size, size_t *bytes_written)
{
i2s_write(I2S_PORT_TX, data, size, bytes_written, portMAX_DELAY);
}

bool Inmp441Max98357aFastLED::readAudio(uint8_t *data, size_t size)
{
size_t bytes_read;
i2s_read(I2S_PORT, (void *)i2s_read_buff, size, &bytes_read, portMAX_DELAY);
uint32_t j = 0;
uint32_t dac_value = 0;
for (int i = 0; i < size; i += 2) {
dac_value = ((((uint16_t)(i2s_read_buff[i + 1] & 0xff) << 8) | ((i2s_read_buff[i + 0]))));
data[j++] = 0;
data[j++] = dac_value * 256 / 2048;
}
return true;
}

void Inmp441Max98357aFastLED::updateBrightness(int brightness)
{
FastLED.setBrightness(brightness);
}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Support for Snips is dropped.

[ESP32-POE-ISO](Esp32-poe-iso.md)

[INMP441MAX98357AFASTLED](inmp441max98357afastled.md)

## MQTT commands

The ESP32 Satellite is subscribed to various topics.
Expand Down
10 changes: 10 additions & 0 deletions inmp441max98357afastled.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Get Started for INMP441, MAX98357a and FastLED
- Set the device_type to 7 in the settings.ini
- Configure pins on /devices/Inmp441Max98357aFastLed.hpp
- Flash the esp32 using usb to uart converter
- First flash, set "upload" as method under the OTA section in the settings.ini. After that you can set it to "ota" as well
- Build and flash the project with PlatformIO, for example run `pio run --target upload` from the commandline


## More info
https://github.com/ProrokWielki/HomeAssistantSpeaker