This is my first post on the forum, so I apologize if I make any mistakes. I'm also very new to making things like this, so forgive me if I use the wrong terminology.
My Goal: I am trying to make a program that turns the LED on and off after a button press.
The Problem: The pin attached to the green LED always outputs HIGH. It doesn't matter if I switch to a different pin or swap the order of the LEDs, but as long as I have pinMode(GREEN, OUTPUT) enabled in my code, the output of that corresponding pin will always be HIGH.
Schematic
Photo
(In case my schematic wasn't drawn correctly)
Specs: I am using a common anode 3W RGB led and an ItsyBitsy M0 Express, based on SAMD21. The push button is a push button.
Code
#include <SPI.h>
#include <Arduino.h>
#include <stdlib.h>
#define BUTTON 13
#define RED 12
#define GREEN 10
#define BLUE 11
// Timer Interrupt
#define CPU_HZ 48000000
#define TIMER_PRESCALER_DIV 1024
void setColor(int red, int green, int blue) {
analogWrite(RED, 255-red);
analogWrite(GREEN, 255-green);
analogWrite(BLUE, 255-blue);
}
void led_off(){
setColor(0, 0, 0);
}
void led_on(){
setColor(255, 255, 255);
}
#define MAX_LIGHT_STATES 1
volatile int cur_light_state;
void change_light_state(void) {
cur_light_state = (cur_light_state == MAX_LIGHT_STATES) ? 0 : (cur_light_state + 1);
}
void TC3_Handler(void){
switch(cur_light_state){
case 0:
Serial.println("OFF");
led_off(); // Off statae
break;
case 1:
Serial.println("ON");
led_on(); // Solid color on
break;
}
TC3->COUNT16.INTFLAG.bit.MC0 = 1;
}
void setup() {
Serial.begin(9600);
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
setColor(0,0,0);
// set up button
pinMode(BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON), change_light_state, FALLING);
// Configure asynchronous clock source
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID_TCC2_TC3_Val; // select TC3 peripheral channel
GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_GEN_GCLK0; // select source GCLK_GEN[0]
GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_CLKEN; // enable generic clock
while(GCLK->STATUS.bit.SYNCBUSY){}; // status syncbusy set when write starts
// Synchronous bus clock is enabled by default
TC3->COUNT16.CTRLA.bit.ENABLE = 0; // disable clock to write to it
while(TC3->COUNT16.STATUS.bit.SYNCBUSY);
Serial.println("Clock disabled");
// Configure Count Mode (16-bit)
TC3->COUNT16.CTRLA.bit.MODE = 0x0;
// Configure Compare Mode for TC
TC3->COUNT16.CTRLA.bit.WAVEGEN = 0x1; // 0x1 is Match Frequency mode
// Configure prescaler for DIV32
TC3->COUNT16.CTRLA.bit.PRESCALER = 0x6;
// Initialize compare value for 100mS @ 500kHz
TC3->COUNT16.CC[0].reg = 50000;
while(TC3->COUNT16.STATUS.bit.SYNCBUSY );
// Enable TC3 compare mode interrupt generation
TC3->COUNT16.INTENSET.bit.MC0 = 0x1; // Enable match interrupts on compare channel 0
// Enable TC3
TC3->COUNT16.CTRLA.bit.ENABLE = 1;
while(TC3->COUNT16.STATUS.bit.SYNCBUSY);
Serial.println("TC3 enabled");
NVIC_SetPriority(TC3_IRQn, 3); // 4 priority levels 0-3, higher number is higher priority
NVIC_EnableIRQ(TC3_IRQn);
}
void loop() {
// put your main code here, to run repeatedly:
}
To explain my code in more detail, I am using the timer counter to update whether my LED is on or off based on the variable "cur_light_state" at ~250 ms intervals. The tracker variable changes based on an interrupt generated from a button press.
When the board is on, I've noticed that the LED flashes at the rate I've set the timer counter to. I have a suspicion that the two are linked somehow, though I can't see a reason why it would "follow" the green LED.
Note that I've also tried switching TC3 out for TC4 with the same results.
I am aware there are better, more simple ways to code this with the same functionality, but that is neither here nor there. This is a simplified test version of my original code for debugging purposes, there is a reason to my madness. The only problem I seek answer for is why the green LED is always on. Thank you for reading this far, by the way.




