I am extremely new to any sort of physical technologies like an Arduino. I have been programming for four years and working with an Arduino for four weeks. I am trying to find a way to use the wire library for its i2c functionality and the RGBmatrixPanel library to drive a RGB matrix. I am using an arduino Uno and a 32x32 RGB matrix panel. The RGBmatrixPanel library is located on the adafruit website.
Here is a link to both libraries required to run the RGBmatrixPanel:
The examples work great and I have made some pretty cool patterns in the displays.
Once I import the wire.h library the panel becomes unresponsive. I have done a simple test where I make the panel white. (code at bottom). With the Wire library commented out the panel works fine. Once the wire library is imported the panel becomes unresponsive.
I know of one other thread that seems to be along the same line but it seems like there was no conclusive response and then the creator of the thread decided to change devices. RGB Matrix Library - Programming Questions - Arduino Forum
I am trying to understand if there is a way I can modify the current library or create another library so that I can use the RGB matrix and the Wire library for i2c
Thank you very much!
#include <RGBmatrixPanel.h>
#include <Wire.h>
#define CLK 8
#define OE 9
#define LAT 10
#define A A0
#define B A1
#define C A2
#define D A3
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);
void setup() {
// put your setup code here, to run once:
matrix.beginMatrix();
matrix.fillRect(0, 0, 32, 32, matrix.Color333(7, 7, 7));
delay(500);
}
void loop() {
// put your main code here, to run repeatedly:
}
I am using the a4 and a5 pins or the i2c but these are not used by the LEDmatrixPanel library. I thought that maybe they both used a begin function and maybe arduino does not distinguish object functions differently so i changed one and tried again and go the same unresponsiveness. From the post before someone thought it was something to do with an interrupt. "Anyway, i think the issue is in the use of the interrupts by both libraries (Timer1 in the the RGBmatrix.h)" I am not really sure what that means. I could not find anything regarding a Timer1 int eh RGBmatrix.h file. Which that file does not even really exist there is an RGBmatixPanel.h. There is something in the RGBmatrixPanel.cpp file however
#if defined(ARDUINO_ARCH_ESP32)
timer_config_t tim_config;
tim_config.divider = 2; // Run Timer at 40 MHz
tim_config.counter_dir = TIMER_COUNT_UP;
tim_config.counter_en = TIMER_PAUSE;
tim_config.alarm_en = true;
tim_config.auto_reload = true;
tim_config.intr_type = TIMER_INTR_LEVEL;
timer_init(TIMER_GROUP_1, TIMER_0, &tim_config);
/* Timer's counter will initially start from value below.
Also, if auto_reload is set, this value will be automatically reload on alarm */
timer_set_counter_value(TIMER_GROUP_1, TIMER_0, 0x00000000ULL);
/* Configure the alarm value and the interrupt on alarm. */
timer_set_alarm_value(TIMER_GROUP_1, TIMER_0, 10000);
timer_enable_intr(TIMER_GROUP_1, TIMER_0);
timer_isr_register(TIMER_GROUP_1, TIMER_0, IRQ_HANDLER,
(void *) TIMER_0, ESP_INTR_FLAG_IRAM, NULL);
timer_start(TIMER_GROUP_1, TIMER_0);
#endif
#if defined(__AVR__)
// Set up Timer1 for interrupt:
TCCR1A = _BV(WGM11); // Mode 14 (fast PWM), OC1A off
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // Mode 14, no prescale
ICR1 = 100;
TIMSK1 |= _BV(TOIE1); // Enable Timer1 interrupt
sei(); // Enable global interrupts
#endif
#if defined(ARDUINO_ARCH_SAMD)
#ifdef __SAMD51__
// Set up generic clock gen 2 as source for TC4
// Datasheet recommends setting GENCTRL register in a single write,
// so a temp value is used here to more easily construct a value.
GCLK_GENCTRL_Type genctrl;
genctrl.bit.SRC = GCLK_GENCTRL_SRC_DFLL_Val; // 48 MHz source
genctrl.bit.GENEN = 1; // Enable
genctrl.bit.OE = 1;
genctrl.bit.DIVSEL = 0; // Do not divide clock source
genctrl.bit.DIV = 0;
GCLK->GENCTRL[2].reg = genctrl.reg;
while(GCLK->SYNCBUSY.bit.GENCTRL1 == 1);
GCLK->PCHCTRL[TIMER_GCLK_ID].bit.CHEN = 0;
while(GCLK->PCHCTRL[TIMER_GCLK_ID].bit.CHEN); // Wait for disable
GCLK_PCHCTRL_Type pchctrl;
pchctrl.bit.GEN = GCLK_PCHCTRL_GEN_GCLK2_Val;
pchctrl.bit.CHEN = 1;
GCLK->PCHCTRL[TIMER_GCLK_ID].reg = pchctrl.reg;
while(!GCLK->PCHCTRL[TIMER_GCLK_ID].bit.CHEN); // Wait for enable
// Counter must first be disabled to configure it
TIMER->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
while(TIMER->COUNT16.SYNCBUSY.bit.STATUS);
TIMER->COUNT16.CTRLA.reg = // Configure timer counter
TC_CTRLA_PRESCALER_DIV1 | // 1:1 Prescale
TC_CTRLA_MODE_COUNT16; // 16-bit counter mode
TIMER->COUNT16.WAVE.bit.WAVEGEN = 1; // Match frequency mode (MFRQ)
TIMER->COUNT16.CTRLBSET.reg = TCC_CTRLBCLR_DIR; // Count DOWN
while(TIMER->COUNT16.SYNCBUSY.bit.CTRLB);
TIMER->COUNT16.CC[0].reg = 10000; // Compare value for channel 0
while(TIMER->COUNT16.SYNCBUSY.bit.CC0);
TIMER->COUNT16.INTENSET.reg = TC_INTENSET_OVF; // Enable overflow interrupt
NVIC_DisableIRQ(IRQN);
NVIC_ClearPendingIRQ(IRQN);
NVIC_SetPriority(IRQN, 0); // Top priority
NVIC_EnableIRQ(IRQN);
// Enable TCx
TIMER->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
while(TIMER->COUNT16.SYNCBUSY.bit.STATUS);
#else
// Enable GCLK for TC4 and COUNTER (timer counter input clock)
GCLK->CLKCTRL.reg = (uint16_t)(GCLK_CLKCTRL_CLKEN |
GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5));
while(GCLK->STATUS.bit.SYNCBUSY == 1);
// Counter must first be disabled to configure it
TIMER->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
while(TIMER->COUNT16.STATUS.bit.SYNCBUSY);
TIMER->COUNT16.CTRLA.reg = // Configure timer counter
TC_CTRLA_PRESCALER_DIV1 | // 1:1 Prescale
TC_CTRLA_WAVEGEN_MFRQ | // Match frequency generation mode (MFRQ)
TC_CTRLA_MODE_COUNT16; // 16-bit counter mode
while(TIMER->COUNT16.STATUS.bit.SYNCBUSY);
// TIMER->COUNT16.CTRLBCLR.reg = TCC_CTRLBCLR_DIR; // Count up
TIMER->COUNT16.CTRLBSET.reg = TCC_CTRLBCLR_DIR; // Count DOWN
while(TIMER->COUNT16.STATUS.bit.SYNCBUSY);
TIMER->COUNT16.CC[0].reg = 10000; // Compare value for channel 0
while(TIMER->COUNT16.STATUS.bit.SYNCBUSY);
TIMER->COUNT16.INTENSET.reg = TC_INTENSET_OVF; // Enable overflow interrupt
NVIC_DisableIRQ(IRQN);
NVIC_ClearPendingIRQ(IRQN);
NVIC_SetPriority(IRQN, 0); // Top priority
NVIC_EnableIRQ(IRQN);
// Enable TCx
TIMER->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
while(TIMER->COUNT16.STATUS.bit.SYNCBUSY);
#endif // SAMD21
#endif // ARDUINO_ARCH_SAMD
}
I understand enough to get why its having a problem but not enough to fix it. Please let me know if you have an ideas or suggestions.
I poked around in the matrix code and I saw some comments about it using the entire PORT for efficiency, even though not all the pins are used. You are using analog pins which is PORTC which is also where the i2c SCL/SDA lines are. Can you move your matrix off of PORTC?