In my application, I occasionally send realtime data to a display over I2C. This sometimes results in pops and dropouts, which are especially noticeable at high input levels. I'm using the Audio Library in slave mode. Not sure that's related.
Here's the relevant code:
Here's the relevant code:
#include <Arduino.h>
#include <Audio.h>
#include <Wire.h>
AudioInputI2Sslave i2sInput; // Audio input from I2S
AudioOutputI2Sslave i2sOutput; // Audio output to I2S
AudioAnalyzeRMS rms; // RMS analyzer
AudioConnection patchCord1(i2sInput, 0, rms, 0); // Connect input to RMS analyzer
AudioConnection myPatchCord1(i2sInput, 0, i2sOutput, 0); // Connect input to output left channel
AudioConnection myPatchCord2(i2sInput, 1, i2sOutput, 1); // Connect input to output right channel
void setup() {
// put your setup code here, to run once:
AudioMemory(12);
Wire.begin(); // Join I2C bus as master
Serial.begin(115000);
delay(1000); // Wait for serial to initialize
Serial.println("Starting I2S Slave Audio Example");
//i2sInput.begin();
//i2sOutput.begin();
}
#define FILTER_BANDS 5
typedef struct {
uint8_t packetType;
uint8_t selectedFilterBand;
uint8_t displayMode;
uint8_t reserved[1]; // Padding for alignment
union {
struct {
uint8_t reserved[3]; // Padding for alignment
uint32_t b0; // Encoded as network order float. Use htonf() to convert.
uint32_t b1;
uint32_t b2;
uint32_t a1;
uint32_t a2;
} coeffs[FILTER_BANDS];
struct {
uint8_t filterType;
uint8_t reserved[3]; // Padding for alignment
uint32_t frequency;
uint32_t Q;
uint32_t gain;
} params[FILTER_BANDS];
struct {
uint32_t peakLevel;
uint32_t rmsLevel;
} status;
struct {
uint32_t sampleRate;
uint8_t stable;
uint8_t bits;
uint8_t reserved[2]; // Padding for alignment
} sampleRateInfo;
struct {
uint8_t clipped;
uint8_t reserved[3]; // Padding for alignment
} clipAlert;
} data;
uint32_t checksum; // Network order checksum of all previous bytes in the packet
} Packet;
#define PACKET_CLIP_ALERT 0x05
uint32_t htonl(uint32_t hostlong) {
#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
return __builtin_bswap32(hostlong);
#elif ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
return hostlong;
#else
#error "integer byte order could not be determined!"
#endif
}
uint32_t crc32Buffer(const uint8_t *data, size_t length) {
uint32_t crc = 0xFFFFFFFF;
for (size_t i = 0; i < length; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 1) {
crc = (crc >> 1) ^ 0xEDB88320;
} else {
crc >>= 1;
}
}
}
return ~crc;
}
void sendToDisplay(Packet *packet)
{
packet->checksum = htonl(crc32Buffer((uint8_t *)packet, sizeof(Packet) - 4));
Wire.beginTransmission(0xb1ce);
Wire.send((uint8_t *)packet, sizeof(Packet));
Wire.endTransmission();
}
void loop() {
Packet p;
p.packetType = PACKET_CLIP_ALERT;
p.data.clipAlert.clipped = 1;
sendToDisplay(&p);
delay(100);
p.data.clipAlert.clipped = 0;
sendToDisplay(&p);
delay(100);
Serial.println("Hello");
}