Hey there, I'm working on an OLED timer that utilizes a rotary encoder and a button to change to different states to execute the reset, set time, and start time functions. I built it out on my Arduino Uno because it's a little easier to work with. And it works PERFECTLY. But now I'm wanting to shrink it down to work out the physical aspects of it and I've loaded everything onto the Seeeduino Xiao and the button interrupt feature no longer works. I've double (triple) checked the wiring, everything is 1 for 1 exactly the same. I even tried all new components, wires, breadboard, and a different Seeeduino board.
Does anyone have any experience working with these boards? Is this a common issue? Seeeduino claims that all pins can be used for an interrupt.
I have been tinkering with it for several days and I'm at my wit's end.
I'm a sporadic "maker" and know enough to be dangerous. Any help is greatly appreciated!
Here's my code:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
int Buzzer = 8;
int minutes_change=0;
int minutes=0;
int Current_Frame=1;
int buttonPin = 3;
const int ledPin = LED_BUILTIN;
//encoder pins and variables
int clkPin = 7;
int dtPin = 6;
int encoderCount = 0;
int clkPinLast = LOW;
int clkPinCurrent = LOW;
// State values:
//0 =reset
//1 =setup
//2 =countdown
int State=0;
long Timestamp_Button_Pressed;
unsigned long Countdown_start;
// Declaration for SSD1306 display connected using software SPI
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//Images:
// 'TIMES_UP', 128x32px
const unsigned char TIMES_UP [] PROGMEM = {
0xdf, 0xff, 0xff, 0xef, 0xef, 0xef, 0xff, 0xf7, 0xf7, 0xf7, 0xf7, 0xff, 0xfb, 0xfb, 0xfb, 0xfb,
0x8f, 0xcf, 0xcf, 0xc7, 0xc7, 0xc7, 0xe7, 0xe7, 0xe3, 0xe3, 0xe3, 0xf3, 0xf3, 0xf1, 0xf1, 0xf1,
0xcf, 0xcf, 0xcf, 0xcf, 0xc7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf1, 0xf9,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x38, 0x7e, 0x3c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x38, 0x7c, 0x3c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x38, 0x7c, 0x3c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0x38, 0x3c, 0x3c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x38, 0x38, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x38, 0x38, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x38, 0x38, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x38, 0x38, 0x1c, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x38, 0x10, 0x1c, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x38, 0x10, 0x1c, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x30, 0x10, 0x1c, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x30, 0x10, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x30, 0x00, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x30, 0x80, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x30, 0x82, 0x1c, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x30, 0x82, 0x1c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x30, 0xc2, 0x1c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x30, 0xc6, 0x1c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xfc, 0x78, 0xe7, 0x1c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xcf, 0xcf, 0xcf, 0xcf, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe3, 0xf3, 0xf3, 0xf3, 0xf3, 0xf1, 0xf9,
0x8f, 0xcf, 0xcf, 0xc7, 0xc7, 0xc7, 0xe7, 0xe7, 0xe3, 0xe3, 0xe3, 0xf3, 0xf3, 0xf1, 0xf1, 0xf1,
0xdf, 0xdf, 0xef, 0xef, 0xef, 0xef, 0xef, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xfb, 0xfb, 0xfb, 0xfb
};
//Functions:
//Timer start:
void Press_B_Button(){
if (millis() - Timestamp_Button_Pressed>200){
if (State==1){//add minutes mode
Countdown_start=millis();
State=2; //start countdown mode
digitalWrite(ledPin, HIGH);
}
else{//if state is 2(count) then go to state 1(add minute) and "minutes"=0
State=0;//reset mode
delay(2000);
Serial.println((String)"Button B Press");
}
}
}
void Ring_Bell(int Frame =0){
display.clearDisplay();
int analogValue = analogRead(A0);
if (analogValue<=50){
display.clearDisplay();
display.invertDisplay(true);
}
else{
display.clearDisplay();
display.invertDisplay(false);
}
if (Frame==1||2||3||4)display.drawBitmap(0,0,TIMES_UP,128,32,1);
display.display();
if (Frame>1){
delay(200);
digitalWrite(Buzzer,LOW);
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(Buzzer,HIGH);
digitalWrite(ledPin, LOW);
delay(1000);
}
}
//Current time function
String CurrentTime(unsigned long MsLeft){
String Result;
int M;
int S;
M=(long)MsLeft/60000;
Serial.print(MsLeft);
Serial.print(";");
Serial.println(M);
if (M<10) Result=(String)"0"+ M + ":";else Result=(String)M+":";
S=(long)((MsLeft-M*60000)/1000);
if (S<10) Result=(String)Result + "0"+ S ;else Result=(String)Result +S;
return Result;
}
////////////////////////////
void setContrast(int contr){
int prech;
int brigh;
switch (contr){
case 000 ... 255: prech= 0; brigh= contr; break;
default: prech= 16; brigh= 255; break;}
display.ssd1306_command(SSD1306_SETPRECHARGE);
display.ssd1306_command(prech);
display.ssd1306_command(SSD1306_SETCONTRAST);
display.ssd1306_command(brigh);
}
void setup() {
attachInterrupt(digitalPinToInterrupt(3), Press_B_Button,RISING);
//Encoder pin setup:
pinMode(clkPin, INPUT);
pinMode(dtPin, INPUT);
//Button pin setup:
pinMode(buttonPin, INPUT); //init button pin to input
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output:
Timestamp_Button_Pressed=millis();
//Buzzer pin setup:
pinMode(Buzzer, OUTPUT);
digitalWrite(Buzzer, LOW);
int Frame =0;
//OLED Pin setup:
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3c
Serial.begin(9600);
display.clearDisplay();
display.display();
}
void loop() {
//Set contrast level
int analogValue = analogRead(A0);// variable resistor adjusts OLED brightness
if (analogValue <=600){
setContrast(analogValue);
}
//////////////////Reset//////////////////////////
if (State==0){//reset state
digitalWrite(Buzzer,LOW);
digitalWrite(ledPin, LOW);
minutes = 0;
display.invertDisplay(false);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(5,0);
display.setTextColor(SSD1306_WHITE);
display.println((String)minutes+" min");
display.display();
State=1;
}
////////////////////Encoder////////////////////////
if (State==1){//set time mode
clkPinCurrent = digitalRead(clkPin);
if ((clkPinLast == LOW) && (clkPinCurrent == HIGH)) {
if (digitalRead(dtPin) == HIGH) {
if(minutes<=0){ //don't count below 0
minutes=0; //
} //
else {
minutes=minutes-1;//decrease minutes
}
}
else {
minutes=minutes+1;//increase minutes
}
display.clearDisplay();
display.setTextSize(2);
display.setCursor(5,0);
display.setTextColor(SSD1306_WHITE);
display.println((String)minutes+" min");
display.display();
Serial.println(minutes);
}
clkPinLast = clkPinCurrent;
}
///////////////////////countdown/////////////////////////////
if(State==2){
if(minutes*60000 >(millis()-Countdown_start)){
display.clearDisplay();
display.setCursor(5,0);
display.setTextSize(4);
display.setTextColor(SSD1306_WHITE);
display.println(CurrentTime((minutes*60000-(millis()-Countdown_start))));
display.display();
}
else {
Ring_Bell(Current_Frame);
Current_Frame=Current_Frame+1;
if (Current_Frame==5) Current_Frame=1;
}
}
}