/*Mohammed Ali , Student ID: 300370238
Third exercise, Servo Oscillator when Button C is pressed
arduino uno. Component list as follows:
Button_a - Pin 2
Button_b - Pin 12
Button_c - Pin 8
Button_d - Pin 7
Amber LED - Pin5
Blue LED - Pin6
Green LED - Pin10
Red LED - Pin9
Servo - Pin 11 */
#include <Arduino.h>
#include <Servo.h> //calling the servo library so that the servo works and its features can be used
void redButton();
void greenButton();
void blueButton();
void yellowButton();
Servo myservo; //declared servo as myservo
long randNum;
int LEDcolour[]={5,6,9,10};
int buttonPin[]={2,7,8,12};
const int SERVO_INTERVAL = 500; //change this to make servo sequence in main loop go faster or slower
const int BLINK_SPEED = 300; //change to blink LEDs faster or slower
int ledState[] = {HIGH, HIGH, HIGH, HIGH};
int buttonState[] = {LOW, LOW, LOW, LOW};
unsigned long previousMillis = 0;
unsigned long previousMillisLED[] = {0, 0, 0, 0};
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(buttonPin[i], INPUT);
pinMode(LEDcolour[i], OUTPUT);
digitalWrite(LEDcolour[i], HIGH);
}
myservo.attach(11);
Serial.begin(9600);
//Only digital pins 2 and 3 allowed for interrupts on the UNO
//yellowButton is the function void yellowButton() below
attachInterrupt(digitalPinToInterrupt(2), yellowButton, RISING);
}
void loop() {
//This servo sequence in the main loop is just to demo how to use millis() with variables currentMillis and
//previousMillis to do timing instead of using delay
//Normally, I'd put something like this in its own function, but you can use this technique in the main
//loop and also within functions
unsigned long currentMillis = millis();
static int servoStage = 0;
//only execute this code when a certain time interval has elapsed
if (currentMillis - previousMillis >= SERVO_INTERVAL) {
if (servoStage == 0) {
myservo.write(9); //set servo position to 9 degrees
} else if (servoStage == 1 || servoStage == 3) {
myservo.write(55);
} else if (servoStage == 2) {
myservo.write(100);
}
servoStage++;
if (servoStage == 4) {
servoStage = 0;
}
//If Nakul asks you to put a whole sequence of blinking LEDs or moving the servo onto a button,
//you can do different stages of the sequence, i.e. blink red twice then green twice, by using
//a static int variable like servoStage above
//Then again, I'm assuming Nakul intends for the sequences to stop as soon as the button is
//released, so I might be overcomplicating things
//Make sure you update previousMillis at the end of the if statement
previousMillis = currentMillis;
}
if (digitalRead(buttonPin[1]) == HIGH) {
greenButton();
}
if (digitalRead(buttonPin[2]) == HIGH) {
redButton();
}
if (digitalRead(buttonPin[3]) == HIGH) {
blueButton();
}
}
//This is the interrupt function that is triggered by the rising edge of the yellow button
//Notice how it's not called at all in the main loop, only in the setup as part of the
//attachInterrupt function
void yellowButton() {
Serial.println("YELLOW");
for (int i = 0; i < 4; i++) {
digitalWrite(LEDcolour[i], HIGH);
}
myservo.write(5);
}
//Blinks the green LED while green button pressed
void greenButton() {
unsigned long currentMillis = millis();
Serial.println("GREEN");
if (currentMillis - previousMillisLED[3] >= BLINK_SPEED) {
ledState[3] = !ledState[3];
digitalWrite(LEDcolour[3], ledState[3]);
previousMillisLED[3] = currentMillis;
}
}
//Blinks a random LED while the red button is pressed
void redButton() {
Serial.println("RED");
const int BLINKNUM = 4; //Double how many times LED will blink (4 means blinks twice)
//Double because one cycle for on, one cycle for off
unsigned long currentMillis = millis();
//This static int cycleNum is necessary because when a button is pressed,
//the HIGH signal is physical, so it can register multiple times in a short span
//Meaning without it, about 30 or so random numbers are generated per button press,
//which blinks all the lights
//cycleNum functions similarly to servoStage above
static int cycleNum = 0;
if(cycleNum == 0) {
randNum = random(0,4); //Generate random number
}
if ((currentMillis - previousMillisLED[randNum]) >= BLINK_SPEED) {
ledState[randNum] = !ledState[randNum];
digitalWrite(LEDcolour[randNum], ledState[randNum]);
previousMillisLED[randNum] = currentMillis;
cycleNum++;
if (cycleNum == BLINKNUM) {
cycleNum = 0;
}
}
}
//Blinks the blue LED while the blue button is pressed. Same as green button function
void blueButton() {
unsigned long currentMillis = millis();
Serial.println("BLUE");
if (currentMillis - previousMillisLED[1] >= BLINK_SPEED) {
ledState[1] = !ledState[1];
digitalWrite(LEDcolour[1], ledState[1]);
previousMillisLED[1] = currentMillis;
}
}
//close loop