Search for info about electronic components, technologies, and the electronics industry in articles, product highlights, videos, PTMs, blogs, and more.
Use this wiki (maintained by Digi-Key’s Applications Engineers) to share knowledge and learn about products, resources, projects, tools, technologies, and more.
Product Training Modules (PTMs) from Digi-Key and supplier partners offer electronic component tutorials based on the latest products and technologies.
Digi-Key’s community forum, technical resource, and a place for further discussion on topics ranging from how-tos to questions about electronics principles.
Digi-Key's value-added services utilize the expertise of Digi-Key's technical and product distribution teams with a broad selection of inventory available for customization.
Digi-Key’s tools are uniquely paired with access to the world’s largest selection of electronic components to help you meet your design challenges head-on.
Access pre-curated content, solutions, and resources from industry professionals, as well as your peers, to help guide you from concept through production.
Review available materials, capabilities, and pricing from various board houses. Upload a Gerber file and make a few selections to place a custom PCB order.
Use Scheme-it’s comprehensive electronic symbol library and an integrated Digi-Key component catalog to design and share electronic circuit diagrams.
Incoterms: UPS freight pre-paid: DDP (Duty and customs paid by Digi-Key)
FedEx or DHL freight pre-paid: CPT (Duty, customs, and VAT due at time of delivery)
Most orders delivered within 48 hours
PAYMENT TYPES
Credit account for qualified institutions and businesses
Payment in Advance by Wire Transfer
Another Ambassador Moment: Building an Arduino Alarm Clock
This project was designed by one of Digi-Key’s own university ambassador students. Check out how it works in the video below!
As students, it can often be hard to focus on schoolwork with so many distractions -- including smartphones. Most phones double as alarm clocks, reminding us when to get up in the morning or when certain events are happening throughout the day. Because of this, they are usually with us 24/7. Although smartphones might be the most convenient alarm clock option, setting time aside to be away from phones to avoid distraction and allow more time to focus on school assignments can be extremely beneficial.
For this reason, I’ve decided to create a digital alarm clock using Arduino to avoid using my smartphone as the sole timekeeping device in my room.
Project Planning
The first step in this project was to plan the functionality. I decided that I wanted a clock that could:
Set and keep time,
Set and run short-timers, and
Run a Pomodoro timer.
Throughout the entire design process, this functionality was kept in mind to narrow down the project’s focus and prevent overcomplexity.
The next step was to choose components. With an Adafruit monochrome OLED, 8-ohm speaker, and an Arduino Uno on hand, I decided to use them and select components that would work with them.
It was unclear how much space would be needed on the Arduino, so the sound system was created as separate as possible, with only a few bytes worth of short interrupts and booleans stored on the Arduino to run the sound effects of the clock. Instead, I relied on a soundboard capable of running entirely independently of the clock. This decision (in hindsight) was probably not necessary but worked for this project’s purpose.
I choose to use two pushbuttons and a rotary encoder as my inputs and utilized more expensive all-metal buttons to give the clock a nicer feel. This clock’s navigation system uses the encoder as a scroll wheel for setting time and navigating the function menu. It also uses one button as a “select/enter” button and the other as a “cancel” button.
CAD
Once the electrical components were chosen, a wiring diagram was created using Autodesk Eagle to sort out and record which components needed to be connected to which pins on the Arduino.
Note that 0.1 uF decoupling capacitors were used on the encoder and ten kOhm resistors on the buttons to improve the circuit’s reliability for correctly sending signals to the Arduino.
With the wiring realized, Fusion 360 was used to design the case of the clock.
Special care was taken to sketch out how I wanted the clock to look. That design was then translated to CAD to determine the clock’s specific dimensions and form the internal structures that would hold the components in place.
Various specifications were required to incorporate each component of the clock:
For the buttons: A hole
For the encoder: A hole and square inset bracket
For the Arduino and soundboard: Short posts with mounting holes
For the speaker: A flat angle slope
For the OLED panel: Two brackets with screw holes for securing and adjusting the screen height below a rectangular cutout
Code
The code for the clock includes three main sections. At the top were the variable and pin declarations, as well as the setup function. Then came the loop where all of the logic and input recording was carried out. Lastly was the function to populate the OLED display based on the state and values in the clock.
The code was set up to be as modular as possible, resulting in many switch statements and a large block of small variables to track the state of the clock’s menu, time tracking, and extra functions.
Conclusion
If you want to use the code or other parts of my project in your project, a complete record of my project can be found on GitHub and a project overview video that includes recordings on the clock functioning.
A clock is a well-defined but extremely customizable device, meaning it is a great starter project for anyone looking to try their hand at product design and get something useful out of it.
//// screen definitions // dimentions #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 64 // OLED display height, in pixels // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Time, clock function, and menu related variables:
Copy Code
/// screen display arrays // 0: no menu, 1: main menu, 2: set time (minutes), 3: set time (hours), 4: set alarm (time select screen), 5: set pomodoro timer (work time select screen), 6: set pomodoro timer (rest time select screen) short int menuDisplay = 0; // 0: no menu, 1: first option, 2: second option 3: third option short int menuOptionHighlight = 0; // false: no menu settings (left = menu, right = ____), true: in a menu or menu item (left = entr, right = back) bool buttonDisplay = false; // (Timer/Alarm window) 0: none, 1: timer, 2: alarm, 3: sounding alarm/timer short int TAwindow = 0;
//// time declarations //unsigned long currentMillis; decalred in loop unsigned long previousMillis = 0; unsigned long previousMillisSound = 0; const unsigned long period = 60000; //the value is a number of milliseconds, ie 60 seconds
short int curTimeHour = 0; // hours portion of the current time short int curTimeMin = 0; // minutes portion of the current time char curTimeChar[5] = {'0', '0', ':', '0', '0'}; // displayable text of the time bool AM = true; // true if the time is AM, false if it is PM /// timer and alarm variables short int alarmTime = 0; // minutes left in the timer short int timerWorkTime = 0; // minutes set for work timer short int timerWorkTimeRemaining = 0; // minutes left in the timer short int timerBreakTime = 0; // minutes set for break timer short int timerBreakTimeRemaining = 0; // minutes left in the timer char timerChar[2] = {'0', '0'}; // the first and second characters representing the remaining time in minutes (timers and alarms can be a max of 1 hour in this clock screen design) char alarmChar[2] = {'0', '0'}; // the first and second characters representing the remaining time in minutes (timers and alarms can be a max of 1 hour in this clock screen design) char TAwindowSym = 'w'; // ' ': none, 'w': timer (work section), 'b': timer (break section), 'a': alarm short int TAwindowProgress = 25; // percent of the time left (out of the max progress bar length: 25)
Variables and interrupt function for encoder and buttons:
// Interrupt Service Routine for a change to encoder pin A void isr () { if (digitalRead (encoderPinA)) up = digitalRead (encoderPinB); else up = !digitalRead (encoderPinB);
if(digitalRead (encoderPinA)){ fired = true; } } // end of isr
bool scroll = false; // this determines if the encoder needs to be read. // it will be true if there is a scrollable menu open
//// button declarations #define buttonA 9 // pin 9 is the left button output #define buttonB 8 // pin 8 is the right button output bool pressedA = false; // for use in activating button activated code and to prevent multifiring on one press bool pressedB = false; // for use in activating button activated code and to prevent multifiring on one press
Sound effect variables:
Copy Code
//// sound declarations #define clickA 10 // the sound for making a menu selection #define clickB 11 // the sound for finishing the setting of the clock, alarm, or timer #define alarmEnd 12 // the sound that plays when an alarm finishes bool soundPlaying = false; // keeps track of whether a sound is being played short int curSoundPlaying = 0; // 0: no sound, 1: clickA, 2: clickB, 3: alarmEnd
Setup function: Sets up pins for all but the soundboard and starts the display
Copy Code
void setup() { // put your setup code here, to run once:
/// OLED screen setup // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64 Serial.println(F("SSD1306 allocation failed")); for(;;); // Don't proceed, loop forever } // Show initial display buffer contents on the screen -- // the library initializes this with an Adafruit splash screen. display.display(); delay(1000); // Pause for 2 seconds // Clear the buffer display.clearDisplay();
Serial.begin (9600); // not sure if this is the best serial pace to use
}
The loop:
static encoder tracking variables:
Copy Code
void loop() { // the main code which runs repeatedly:
static long rotaryCount = 0; // declare the counter for the encoder static long previousRotaryCount = 0; // declare the previous count counter for the encoder
Time tracking and update section:
Copy Code
// time incrementing unsigned long currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started) if (currentMillis - previousMillis >= period) //test whether the period has elapsed { previousMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
//// update that a minute has passed /// clock curTimeMin++; // add a mimute to the curent time minute variable // if the current minute count is 60 (or higher for some reason) increase the hour by one and rollover the minute count if (curTimeMin >= 60){ curTimeMin = curTimeMin - 60; curTimeHour++; // if the current hour count is 12 (or higher for some reason) rollover the hour count and flip the state of AM if (curTimeHour >= 12){ curTimeHour = curTimeHour - 12; AM = !AM; } }
/// timer/alarm // only adjusts if the alarm/timer variables are greater than zero // if it sets an alarm of timer to zero the alarm done screen is activated for a second and a sound is played // if a timer is what finished then swap the timer value over to the next phase of the pomodoro set // check if an alarm is active if (alarmTime > 0){ alarmTime--; // if the alarm has just been set to zero show th alarm sounding icon, reset the timer window symbol, and play the alarm sound if (alarmTime == 0){ TAwindow = 3; TAwindowSym = ' '; //ring the alarm <-- //0: none, 1: clickA, 2: clickB, 3: alarmEnd curSoundPlaying = 3; } }
if (timerWorkTimeRemaining > 0){ timerWorkTimeRemaining--; // if the work Time has just been set to zero swap to the break countdown by setting the timer window symbol to 'b', reset the work timer, and play the timer sound if (timerWorkTimeRemaining == 0){ TAwindowSym = 'b'; timerWorkTimeRemaining = timerWorkTime; //ring the timer <-- //0: none, 1: clickA, 2: clickB, 3: alarmEnd curSoundPlaying = 3; } }
if (timerBreakTimeRemaining > 0){ timerBreakTimeRemaining--; // if the work Time has just been set to zero swap to the work countdown by setting the timer window symbol to 'w', reset the break timer, and play the timer sound if (timerBreakTimeRemaining == 0){ TAwindowSym = 'w'; timerBreakTimeRemaining = timerBreakTime; //ring the timer <-- //0: none, 1: clickA, 2: clickB, 3: alarmEnd curSoundPlaying = 3; } }
}
Encoder and button input tracking section:
Copy Code
// encoder reading // If there is a scrollable menu open the loop will check the encoder for updates // and will modify encoderCounter accordingly if (scroll){ // if the interrupt has been activated the encoder has been "fired" if (fired){ if (up){ // rotaryCount++; rotaryCount--; // reversed to correct rotation direction } else { // rotaryCount--; rotaryCount++; // reversed to correct rotation direction } fired = false;
// check button A for presses if (digitalRead(buttonA) == HIGH){ // show future code that button A has been pressed // Serial.println ("button A pressed"); pressedA = true; delay(500); //0: none, 1: clickA, 2: clickB, 3: alarmEnd //curSoundPlaying = 2; currently disabled until better sounds are found } else { pressedA = false; }
// check button B for presses if (digitalRead(buttonB) == HIGH){ // show future code that button B has been pressed // Serial.println ("button B pressed"); pressedB = true; delay(500); //0: none, 1: clickA, 2: clickB, 3: alarmEnd //curSoundPlaying = 1; currently disabled until better sounds are found } else { pressedB = false; }
The menu-based actions: This is where the clock chooses how to adjust what it displays and how it adjusts its time based variables as a result of the current variable values and any inputs from the buttons or encoder.
Copy Code
/// menu actions switch (menuDisplay) { case 0: // no menu // if button A is pressed then open the menu screen if (pressedA){ // activate menu option 1 menuDisplay = 1; // reset and activate relevant variables menuOptionHighlight = 0; rotaryCount = 0; previousRotaryCount = 0; scroll = true; pressedA = false; buttonDisplay = true; } break;
case 1: /// main menu //if the encoder has rotated to the right move the highlight to the right //if the encoder has rotated to the left move the highlight to the left // if button B is pressed exit the main menu (imediately break from this case since the menu is now closed) if (pressedB){ menuDisplay = 0; pressedB = false; pressedA = false; scroll = false; rotaryCount = 0; previousRotaryCount = 0; buttonDisplay = false; } else { // if the count has gone down or up change the menu highlight accordingly if (previousRotaryCount < rotaryCount){ switch (menuOptionHighlight) { case 0: menuOptionHighlight = 1; break; case 1: menuOptionHighlight = 2; break; case 2: menuOptionHighlight = 0; break; } } else if (previousRotaryCount > rotaryCount){ switch (menuOptionHighlight) { case 0: menuOptionHighlight = 2; break; case 1: menuOptionHighlight = 0; break; case 2: menuOptionHighlight = 1; break; } } // set the new previous rotary encoder count previousRotaryCount = rotaryCount; } /// draw the selection box around the currently highlighed box with the switch below switch (menuOptionHighlight) { case 0: // option 1 if (pressedA){ // activate menu option 1 menuDisplay = 2; // reset and activate relevant variables rotaryCount = 0; previousRotaryCount = 0; scroll = true; pressedA = false; } break;
case 1: // option 2 if (pressedA){ // activate menu option 2 menuDisplay = 4; // reset and activate relevant variables rotaryCount = 0; previousRotaryCount = 0; scroll = true; pressedA = false; //set the alarm to 0 and delete any running alarms or timers } break;
case 2: // option 3 if (pressedA){ // activate menu option 3 menuDisplay = 5; // reset and activate relevant variables rotaryCount = 0; previousRotaryCount = 0; scroll = true; pressedA = false; //set the timer to 0 and delete any running alarms or timers } break; } break;
case 2: /// set time (minutes) if (pressedB){ menuDisplay = 0; pressedB = false; pressedA = false; scroll = false; rotaryCount = 0; previousRotaryCount = 0; buttonDisplay = false; }
// update the munites based on the encoder value curTimeMin = curTimeMin + rotaryCount; // reset encoder value rotaryCount = 0; // if the current set minutes is greater than 60 remove 60 from it and check again until it is less than 60 while (curTimeMin > 59){ // subtract the rollover curTimeMin = curTimeMin - 60; } // if the current set minutes is less than 0 add 60 to it and check again until it is greater than 0 while (curTimeMin < 0){ // remove the rollover curTimeMin = curTimeMin + 60; }
// if button A is pressed move on to selecting the hour if (pressedA){ // move on to adjusting the hour time menuDisplay = 3; // reset and activate relevant variables rotaryCount = 0; previousRotaryCount = 0; scroll = true; pressedA = false; } break;
case 3: /// set time (hours) if (pressedB){ menuDisplay = 0; pressedB = false; pressedA = false; scroll = false; rotaryCount = 0; previousRotaryCount = 0; buttonDisplay = false; }
// update the munites based on the encoder value curTimeHour = curTimeHour + rotaryCount; // reset encoder value rotaryCount = 0; // if the current set minutes is greater than 60 remove 60 from it and check again until it is less than 60 while (curTimeHour > 12){ // subtract the rollover curTimeHour = curTimeHour - 12; // flip AM AM = !AM; } // if the current set minutes is less than 0 add 60 to it and check again until it is greater than 0 while (curTimeHour <= 0){ // remove the rollover curTimeHour = curTimeHour + 12; // flip AM AM = !AM; }
// if button A is pressed move on to selecting the hour if (pressedA){ // finish the clock setting and return to main screen menuDisplay = 0; // reset and activate relevant variables pressedB = false; pressedA = false; scroll = false; rotaryCount = 0; previousRotaryCount = 0; buttonDisplay = false; } break;
case 4: /// set alarm (time select screen) // display the timer as it is set TAwindow = 2; TAwindowSym = 'a';
// update the minutes based on the encoder value alarmTime = alarmTime + rotaryCount; // reset encoder value rotaryCount = 0; // if the current set minutes is greater than 60 remove 60 from it and check again until it is less than 60 while (alarmTime > 60){ // subtract the rollover alarmTime = alarmTime - 60; } // if the current set minutes is less than 0 add 60 to it and check again until it is greater than 0 while (alarmTime < 0){ // remove the rollover alarmTime = alarmTime + 60; }
// if button A is pressed move on to selecting the hour if (pressedA){ // finish the alarm setting and return to main screen menuDisplay = 0; TAwindow = 2; TAwindowSym = 'a'; // set the progress bar to its full length TAwindowProgress = 25; // reset and activate relevant variables pressedB = false; pressedA = false; scroll = false; rotaryCount = 0; previousRotaryCount = 0; buttonDisplay = false; } break;
case 5: /// set pomodoro timer (work time select screen) // display the timer as it is set TAwindow = 1; TAwindowSym = 'w';
// update the minutes based on the encoder value timerWorkTime = timerWorkTime + rotaryCount; // reset encoder value rotaryCount = 0; // if the current set minutes is greater than 60 remove 60 from it and check again until it is less than 60 while (timerWorkTime > 60){ // subtract the rollover timerWorkTime = timerWorkTime - 60; } // if the current set minutes is less than 0 add 60 to it and check again until it is greater than 0 while (timerWorkTime < 0){ // remove the rollover timerWorkTime = timerWorkTime + 60; }
// if button A is pressed move on to selecting the hour if (pressedA){ // finish the work timer setting and move to the break timer select menuDisplay = 6; TAwindow = 1; timerWorkTimeRemaining = timerWorkTime; // set the progress bar to its full length TAwindowProgress = 12; // reset and activate relevant variables pressedB = false; pressedA = false; scroll = true; rotaryCount = 0; previousRotaryCount = 0; buttonDisplay = true; } break;
case 6: /// set pomodoro timer (rest time select screen) // display the timer as it is set TAwindow = 1; TAwindowSym = 'b';
// update the minutes based on the encoder value timerBreakTime = timerBreakTime + rotaryCount; // reset encoder value rotaryCount = 0; // if the current set minutes is greater than 60 remove 60 from it and check again until it is less than 60 while (timerBreakTime > 60){ // subtract the rollover timerBreakTime = timerBreakTime - 60; } // if the current set minutes is less than 0 add 60 to it and check again until it is greater than 0 while (timerBreakTime < 0){ // remove the rollover timerBreakTime = timerBreakTime + 60; }
// if button A is pressed move on to selecting the hour if (pressedA){ // finish the break timer setting, activate the work timer, and return to main screen menuDisplay = 0; TAwindow = 1; timerBreakTimeRemaining = timerBreakTime; TAwindowSym = 'w'; // set the progress bar to its full length TAwindowProgress = 25; // reset and activate relevant variables pressedB = false; pressedA = false; scroll = false; rotaryCount = 0; previousRotaryCount = 0; buttonDisplay = false; } //if the encoder has rotated to the right move the break timer one minute up //if the encoder has rotated to the left move the break timer one minute down //if button A is pressed start the timer (begining with a work cycle) and menuDisplay = 0 and buttonDisplay = false //if button B is pressed cancel the timer and menuDisplay = 1 break; }
The section for making sure any alarms or timers are displayed correctly:
case 3: // ringing alarm (no progess bar or variable numbers) break; }
The sound effects section: Tracks the time at a faster rate than the section for updating the clock and alarm time and manages the sending of signals to the external sound module. (Note: I only use one of the sounds in my clock because I decided I didn’t need, or really want, clicking feedback from the buttons or menu.)
Copy Code
if (currentMillis - previousMillisSound >= 130) //test whether the time it takes to activate a sound (+10 miliseconds to ensure reliability) has elapsed { previousMillisSound = currentMillis; //IMPORTANT to save the start time of the current LED state.
if (soundPlaying){ curSoundPlaying = 0; } //// update the sound switch (curSoundPlaying) { //0: none, 1: clickA, 2: clickB, 3: alarmEnd case 0: // turn off all sound channels // set all sound pins to input to emulate an open drain pin pinMode(10, INPUT); pinMode(11, INPUT); pinMode(12, INPUT); soundPlaying = false; break;
case 1: // play clickA (10) and turn off all sound channels pinMode(10, OUTPUT); digitalWrite(10, LOW); pinMode(11, INPUT); pinMode(12, INPUT); soundPlaying = true; break;
case 2: // play clickB (11) and turn off all sound channels pinMode(10, INPUT); pinMode(11, OUTPUT); digitalWrite(11, LOW); pinMode(12, INPUT); soundPlaying = true; break;
case 3: // play alarmEnd (12) and turn off all sound channels pinMode(10, INPUT); pinMode(11, INPUT); pinMode(12, OUTPUT); digitalWrite(12, LOW); soundPlaying = true; break; }
}
The end of the loop activates the last section of my code:
Copy Code
/// draw the screen drawScreen();
} // end loop
The drawScreen() function:
This function sorts through the variables regulating the clock and then displays active information onto the OLED screen. This approach makes the displayed content highly modular and customizable but requires the mass of variables set at the start of the code in order to function.
Copy Code
//// function for drawing the screen void drawScreen() { /// clear display display.clearDisplay();
display.setTextColor(SSD1306_WHITE); // Draw white text display.cp437(true); // Use full 256 char 'Code Page 437' font
/// draw the constant outlines display.drawRect(0, 0, display.width(), 25, SSD1306_WHITE); // top rectangle display.drawLine(93, 1, 93, 24, SSD1306_WHITE); // clock/timer separation line display.drawRect(0, 52, 39, 11, SSD1306_WHITE); // left button action box display.drawRect(88, 52, 39, 11, SSD1306_WHITE); // right button action box display.drawLine(39, 52, 87, 52, SSD1306_WHITE); // button box area close in line
/// draw the clock specific content display.setTextSize(2); // clock text size display.setCursor(3, 5); // upper right
for (int i = 0; i < 5; i++) { display.write(curTimeChar[i]); } // if length can change use sizeof(xyz)/sizeof(xyz[0]) to get the length of array xyz display.setCursor(68, 5); // after numbers on upper right if (AM) { display.write("AM"); } else { display.write("PM"); }
/// draw the alarm/timer // draw the rectangle switch (TAwindow) { //0: none, 1: timer, 2: alarm, 3: sounding alarm/timer case 0: // display nothing break;
case 1: // timer display.setCursor(97, 4); // upper right display.write(timerChar[0]); // digit one of current timer value display.write(timerChar[1]); // digit two of current timer value display.setTextSize(1); // symbol text size display.setCursor(121, 3); // upper left display.write(TAwindowSym); // current timer symbol // draw the progress bar break;
case 2: // alarm display.setCursor(97, 4); // upper right display.write(alarmChar[0]); // digit one of current alarm value display.write(alarmChar[1]); // digit two of current alarm value display.setTextSize(1); // symbol text size display.setCursor(121, 3); // upper left display.write(TAwindowSym); // alarm symbol break;
case 3: // ringing alarm (no progess bar or symbols) display.setCursor(97, 4); // upper right display.write("00"); // digit one of current alarm value break; }
/// draw the menu switch (menuDisplay) { case 0: // no menu break;
case 1: /// main menu /// draw the three boxes and lables for t-set, alarm, and timer for(int i = 0; i < 3; i++){ display.drawPixel(2 + (42*i), 31, SSD1306_WHITE); display.drawPixel(3 + (42*i), 31, SSD1306_WHITE); display.drawPixel(2 + (42*i), 32, SSD1306_WHITE);
/// draw the text for the menu options display.setTextSize(1); display.setCursor(8, 34); display.write("t-set"); display.setCursor(50, 34); display.write("alarm"); display.setCursor(92, 34); display.write("timer");
/// draw the selection box around the currently highlighed box with the switch below switch (menuOptionHighlight) { case 0: // option 1 display.drawLine(5, 31, 38, 31, SSD1306_WHITE); // top line display.drawLine(5, 43, 38, 43, SSD1306_WHITE); // bottom line display.drawLine(2, 34, 2, 40, SSD1306_WHITE); // left line display.drawLine(41, 34, 41, 40, SSD1306_WHITE); // right line break;
case 1: // option 2 display.drawLine(47, 31, 80, 31, SSD1306_WHITE); // top line display.drawLine(47, 43, 80, 43, SSD1306_WHITE); // bottom line display.drawLine(44, 34, 44, 40, SSD1306_WHITE); // left line display.drawLine(83, 34, 83, 40, SSD1306_WHITE); // right line break;
case 2: // option 3 display.drawLine(89, 31, 122, 31, SSD1306_WHITE); // top line display.drawLine(89, 43, 122, 43, SSD1306_WHITE); // bottom line display.drawLine(86, 34, 86, 40, SSD1306_WHITE); // left line display.drawLine(125, 34, 125, 40, SSD1306_WHITE); // right line break; } break;
// white pixel for arm center display.drawPixel(63, 38, 0); break;
case 4: /// set alarm (time select screen) display.drawLine(0, 38, 54, 38, SSD1306_WHITE); display.drawLine(72, 38, 127, 38, SSD1306_WHITE); display.drawCircle(63, 38, 8, SSD1306_WHITE); display.drawLine(62, 38, 66, 38, SSD1306_WHITE); display.drawLine(63, 33, 63, 39, SSD1306_WHITE); display.drawPixel(63, 38, 0); // draw a readout of the current alarm time break;
case 5: /// set pomodoro timer (work time select screen) display.drawLine(0, 38, 54, 38, SSD1306_WHITE); display.drawLine(72, 38, 127, 38, SSD1306_WHITE); display.drawCircle(63, 38, 8, SSD1306_WHITE); display.drawLine(62, 38, 66, 38, SSD1306_WHITE); display.drawLine(63, 33, 63, 39, SSD1306_WHITE); display.drawPixel(63, 38, 0); // draw a readout of the current timer time and indication that this is the "work" time break;
case 6: /// set pomodoro timer (rest time select screen) display.drawLine(0, 38, 54, 38, SSD1306_WHITE); display.drawLine(72, 38, 127, 38, SSD1306_WHITE); display.drawCircle(63, 38, 8, SSD1306_WHITE); display.drawLine(62, 38, 66, 38, SSD1306_WHITE); display.drawLine(63, 33, 63, 39, SSD1306_WHITE); display.drawPixel(63, 38, 0); // draw a readout of the current timer time and indication that this is the "break" time break; }
/// draw the buttons //draw the two rectangles switch (buttonDisplay) { case false: // no menu settings (left = menu, right = ____) // draw the text display.setTextSize(1); display.setCursor(8, 53); // lower left display.write("menu"); display.setCursor(96, 53); // lower right display.write("____"); break;
case true: // in a menu or menu item (left = entr, right = back) // draw the text display.setTextSize(1); display.setCursor(8, 53); // lower left display.write("entr"); display.setCursor(96, 53); // lower right display.write("back"); break; }
/// show the screen display.display(); }
Hope you learned and/or were inspired to make something!
By using the Co-Browse feature, you are agreeing to allow a support representative from Digi-Key to view your browser remotely. When the Co-Browse window opens, give the session ID that is located in the toolbar to the representative.
Digi-Key respects your right to privacy. For more information please see our Privacy Notice and Cookie Notice.