Hi, I'm working on an audio project where I am using an IS31FL3236A I2C LED driver alongside the Teensy 4.1 audio library with the CS42448 TDM codec.
When running my code I get the expected visual behavior, but with a lot of I2C transmit errors, then at a certain point the I2C just stops working entirely and returns an error for every write. I have used the Audio library alongside i2c_t3 with the same LED driver before and this worked really well, but I'm now having to switch over to wire on 4.1 and it's creating a lot of problems.
In order to get around the blocking writes that Wire does I am doing one write every millisecond, and updating the LED buffer every 40 milliseconds (for a refresh rate of 25hz), so that timing critical stuff can happen between writes.
Here is my project code, any idea what might be causing this? Would the Teensy4_i2c library improve this behavior in any way? (wanted to avoid using this because of conflicts with the audio library, but willing to try...):
When running my code I get the expected visual behavior, but with a lot of I2C transmit errors, then at a certain point the I2C just stops working entirely and returns an error for every write. I have used the Audio library alongside i2c_t3 with the same LED driver before and this worked really well, but I'm now having to switch over to wire on 4.1 and it's creating a lot of problems.
In order to get around the blocking writes that Wire does I am doing one write every millisecond, and updating the LED buffer every 40 milliseconds (for a refresh rate of 25hz), so that timing critical stuff can happen between writes.
Here is my project code, any idea what might be causing this? Would the Teensy4_i2c library improve this behavior in any way? (wanted to avoid using this because of conflicts with the audio library, but willing to try...):
Code:
#include <Audio.h>
#include <Wire.h>
AudioSynthWaveformSine sine[8];
AudioOutputTDM tdm_out;
AudioControlCS42448 codec;
AudioConnection pc_out0(sine[0], 0, tdm_out, 0);
AudioConnection pc_out1(sine[1], 0, tdm_out, 2);
AudioConnection pc_out2(sine[2], 0, tdm_out, 4);
AudioConnection pc_out3(sine[3], 0, tdm_out, 6);
AudioConnection pc_out4(sine[4], 0, tdm_out, 8);
AudioConnection pc_out5(sine[5], 0, tdm_out, 10);
AudioConnection pc_out6(sine[6], 0, tdm_out, 12);
AudioConnection pc_out7(sine[7], 0, tdm_out, 14);
#define IS31_ADDR 0x3C
#define EN_PIN 22
uint8_t data_buf[37] = {};
uint8_t led_default[36] = {};
inline void write_is31_byte(uint8_t reg, uint8_t data){
Wire1.beginTransmission(IS31_ADDR);
Wire1.write(reg);
Wire1.write(data);
int err = Wire1.endTransmission();
if(err != 0){ Serial.print("I2C_Error: "); Serial.println(err); }
}
inline void write_is31_buffer(uint8_t reg, uint8_t *data, int len){
for(int i = 0; i < len; ++i){
write_is31_byte(reg+i, data[i]);
}
}
inline void write_is31_pwm(uint8_t *data){
write_is31_buffer(0x01, data, 37);
}
void init_is31( void ){
pinMode(EN_PIN, OUTPUT);
digitalWriteFast(EN_PIN, HIGH);
for(int i = 0; i < 36; ++i){ led_default[i] = 1; }
delay(10);
write_is31_byte(0x00, 0x01);
delay(10);
write_is31_byte(0x4B, 0x01);
delay(10);
write_is31_buffer(0x26, led_default, 36);
delay(10);
}
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
AudioMemory(256);
codec.enable();
codec.volume(1);
for(int i = 0; i < 8; ++i){
sine[i].amplitude(1);
sine[i].frequency(100 + i * 50);
}
delay(1000);
Wire1.begin();
init_is31();
delay(1000);
}
int light = 0;
unsigned long led_timer = 0;
unsigned long i2c_timer = 0;
unsigned long update_timer = 0;
int i2c_index = 0;
void loop() {
if(millis() > led_timer + 250){
led_timer = millis();
for(int i = 0; i < 36; ++i){
data_buf[i] = (i == light) ? 255 : random(100);
}
data_buf[36] = 0; //update leds register write
light = (light + 1) % 36;
}
if(millis() > update_timer + 40){
update_timer = millis();
i2c_index = 0;
}
if(millis() != i2c_timer && i2c_index < 37){
i2c_timer = millis();
write_is31_byte(0x01 + i2c_index, data_buf[i2c_index]);
++i2c_index;
}
}