Can't import <i2s.h> on library

I can’t include <i2s.h> if I try to do it in a library, but it works fine if I do it in main.cpp

here is the output of tree (folder structure)

.
├── include
│   └── README
├── lib
│   ├── Microphone
│   │   ├── Microphone.cpp
│   │   └── Microphone.h
│   └── README
├── platformio.ini
├── src
│   └── main.cpp
└── test
    └── README

here is main.cpp

#include <Arduino.h>

#include "Microphone.h"

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly:
}

here is lib/Microphone.h

#include <i2s.h>

here is lib/Microphone.cpp

#include "Microphone.h"

here is platformio.ini

[env:d1_mini_lite]
platform = espressif8266
board = d1_mini_lite
framework = arduino

and this is the error I get when building

Processing d1_mini_lite (platform: espressif8266; board: d1_mini_lite; framework: arduino)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/d1_mini_lite.html
PLATFORM: Espressif 8266 2.2.2 > WeMos D1 mini Lite
HARDWARE: ESP8266 80MHz, 80KB RAM, 1MB Flash
PACKAGES: toolchain-xtensa 2.40802.190218 (4.8.2), tool-esptool 1.413.0 (4.13), tool-esptoolpy 1.20600.0 (2.6.0), framework-arduinoespressif8266 2.20502.0 (2.5.2)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 29 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Microphone>
Compiling .pio\build\d1_mini_lite\src\main.cpp.o
Generating LD script .pio\build\d1_mini_lite\ld\local.eagle.app.v6.common.ld
Compiling .pio\build\d1_mini_lite\libcaf\Microphone\Microphone.cpp.o
Archiving .pio\build\d1_mini_lite\libFrameworkArduinoVariant.a
Compiling .pio\build\d1_mini_lite\FrameworkArduino\Esp-frag.cpp.o
In file included from lib\Microphone\Microphone.h:1:0,
                 from lib\Microphone\Microphone.cpp:1:
C:\Users\Joe\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/i2s.h:46:19: error: variable or field 'i2s_set_rate' declared void
 void i2s_set_rate(uint32_t rate);//Sample Rate in Hz (ex 44100, 48000)
                   ^
C:\Users\Joe\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/i2s.h:46:19: error: 'uint32_t' was not declared in this scope
C:\Users\Joe\.platformio\packages\framework-arduinoespressif8266\cores\esp8266/i2s.h:47:23: error: variable or field 'i2s_set_dividers' declared void
 void i2s_set_dividers(uint8_t div1, uint8_t div2);//Direct control over output rate

...
Compiling .pio\build\d1_mini_lite\FrameworkArduino\Esp.cpp.o
Compiling .pio\build\d1_mini_lite\FrameworkArduino\FS.cpp.o
*** [.pio\build\d1_mini_lite\libcaf\Microphone\Microphone.cpp.o] Error 1
=============================================================================================== [ERROR] Took 1.67 seconds ===============================================================================================
The terminal process terminated with exit code: 1

my setup

Name: PlatformIO IDE
Id: platformio.platformio-ide
Description: Development environment for IoT, Arduino, ARM mbed, Espressif (ESP8266/ESP32), AVR, RISC-V, STM32, PIC32, nRF51/nRF52, MSP430, MCS-51 (8051), FPGA, FreeRTOS, ESP-IDF, CMSIS, SPL
Version: 1.7.1
Publisher: PlatformIO
VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide

Why I can’t import <i2s.h> from a custom library?

It’s not that you can’t import it, it needs something else… put #include <Arduino.h> before #include <i2s.h> in your Microphone.h . The first error doesn’t give much away in my mind (although when you realise what one of the parameters of the function is uint32_t, it makes sense), but as soon as it started saying error: 'uint32_t' was not declared in this scope … basically the compiler is saying you really need #include <stdint.h> so that things like uint32_t and int16_t get defined but Arduino.h includes it for you anyway, so might as well just use that.

Thanks for providing all the info… made this really easy to reproduce :slight_smile:

1 Like

thanks for the quick reply!

I understand the fact is missing uint32_t but why is not available for the library if was already included in main.cpp?

Maybe my lack of experience in CPP is taking a toll on me, but can you explain it?, if this is a bigger issue can you redirect me on documentation or keywords I need to search in order to understand better what happened?

my suspiction is that libraries are compiled independently, that means, they do not nothing about main.cpp because it is suposed to be reused in other project that maybe do not include <Arduino.h>

adding #include <Arduino.h> before #include <i2s.h> in Microphone.h works fine, but I would not like to depend on <Arduino.h>, so I replaced that with #include <stdint.h> and also worked fine

how did you conclude #include <stdint.h> would also work?, maybe I am doing noobs questions at this point but it will be very helpful thanks for the response!

PS: sorry my english is not perfect yet

Simply because I happen to know that the uint8/16/32 and int8/16/32 style fixed width variable types were introduced by that library (was introduced as part of the C++11 standard in 2011) :wink: It’s also one of the top includes in Arduino.h. Which is OK to rely on, unless you intend your library to not work with the Arduino core at some point.

I’ve never really delved into the compiler process itself, but I am in the same belief as you… that each library is self-contained… and should #include everything it needs - it won’t be inherited from anywhere else.

General practise when writing libraries using any Arduino keywords is to simply #include it also… since it has the include guard (below), it doesn’t matter how many times it gets mentioned in your code - it’ll only be pulled in the once.

#ifndef Arduino_h
#define Arduino_h
#endif
1 Like

Thanks!

<20 character limitter bypass>

1 Like