├── Arduino Programming Basics - Recap.pdf ├── Arduino circuits ├── arduino_circuit_1_led.png ├── arduino_circuit_3_leds.png ├── arduino_circuit_final_project.png ├── arduino_circuit_ir_remote.png ├── arduino_circuit_lcd_screen.png ├── arduino_circuit_photoresistor.png ├── arduino_circuit_potentiometer.png ├── arduino_circuit_push_button.png └── arduino_circuit_ultrasonic_sensor.png ├── Final Project - Arduino For Beginners.pdf.pdf ├── LICENSE ├── List of Materials - Arduino For Beginners.pdf.pdf ├── Pins Recap - Arduino For Beginners.pdf.pdf ├── Programming Basics Recap - Arduino For Beginners.pdf.pdf ├── README.md ├── activities ├── activity1 │ └── activity1.ino ├── activity10 │ └── activity10.ino ├── activity11 │ └── activity11.ino ├── activity12 │ └── activity12.ino ├── activity13 │ └── activity13.ino ├── activity14 │ └── activity14.ino ├── activity15 │ └── activity15.ino ├── activity16 │ └── activity16.ino ├── activity17 │ └── activity17.ino ├── activity18_v2 │ └── activity18_v2.ino ├── activity18_v3 │ └── activity18_v3.ino ├── activity19 │ └── activity19.ino ├── activity2 │ └── activity2.ino ├── activity20 │ └── activity20.ino ├── activity3 │ └── activity3.ino ├── activity4 │ └── activity4.ino ├── activity5 │ └── activity5.ino ├── activity6 │ └── activity6.ino ├── activity7 │ └── activity7.ino ├── activity8 │ └── activity8.ino └── activity9 │ └── activity9.ino └── final_project ├── final_project_step1 └── final_project_step1.ino ├── final_project_step10 └── final_project_step10.ino ├── final_project_step11 └── final_project_step11.ino ├── final_project_step11_v2 └── final_project_step11_v2.ino ├── final_project_step2 └── final_project_step2.ino ├── final_project_step3 └── final_project_step3.ino ├── final_project_step4 └── final_project_step4.ino ├── final_project_step5 └── final_project_step5.ino ├── final_project_step6 └── final_project_step6.ino ├── final_project_step7 └── final_project_step7.ino ├── final_project_step8 └── final_project_step8.ino └── final_project_step9 └── final_project_step9.ino /Arduino Programming Basics - Recap.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino Programming Basics - Recap.pdf -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_1_led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_1_led.png -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_3_leds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_3_leds.png -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_final_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_final_project.png -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_ir_remote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_ir_remote.png -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_lcd_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_lcd_screen.png -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_photoresistor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_photoresistor.png -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_potentiometer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_potentiometer.png -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_push_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_push_button.png -------------------------------------------------------------------------------- /Arduino circuits/arduino_circuit_ultrasonic_sensor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Arduino circuits/arduino_circuit_ultrasonic_sensor.png -------------------------------------------------------------------------------- /Final Project - Arduino For Beginners.pdf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Final Project - Arduino For Beginners.pdf.pdf -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /List of Materials - Arduino For Beginners.pdf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/List of Materials - Arduino For Beginners.pdf.pdf -------------------------------------------------------------------------------- /Pins Recap - Arduino For Beginners.pdf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Pins Recap - Arduino For Beginners.pdf.pdf -------------------------------------------------------------------------------- /Programming Basics Recap - Arduino For Beginners.pdf.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Arduino-for-Beginners---2023-Complete-Course/c67c7a9c60b8e81ac7b9696a4d984eb555446c04/Programming Basics Recap - Arduino For Beginners.pdf.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Arduino-For-Beginners---2023-Complete-Course 5 | Arduino For Beginners - 2023 Complete Course, By Packt Publishing 6 | 7 | -------------------------------------------------------------------------------- /activities/activity1/activity1.ino: -------------------------------------------------------------------------------- 1 | void setup() { 2 | Serial.begin(9600); 3 | pinMode(13, OUTPUT); 4 | } 5 | 6 | void loop() { 7 | Serial.println("LED on"); 8 | digitalWrite(13, HIGH); 9 | delay(2000); 10 | Serial.println("LED off"); 11 | digitalWrite(13, LOW); 12 | delay(1000); 13 | } 14 | -------------------------------------------------------------------------------- /activities/activity10/activity10.ino: -------------------------------------------------------------------------------- 1 | #define LED_1_PIN 12 2 | #define LED_2_PIN 11 3 | #define LED_3_PIN 10 4 | 5 | #define BUTTON_PIN 2 6 | 7 | #define POTENTIOMETER_PIN A2 8 | 9 | unsigned long previousTimeLED1Blink = millis(); 10 | unsigned long blinkDelayLED1 = 500; 11 | 12 | int LED1State = LOW; 13 | 14 | void setup() { 15 | Serial.begin(115200); 16 | Serial.setTimeout(10); 17 | 18 | pinMode(LED_1_PIN, OUTPUT); 19 | pinMode(LED_2_PIN, OUTPUT); 20 | pinMode(LED_3_PIN, OUTPUT); 21 | 22 | pinMode(BUTTON_PIN, INPUT); 23 | } 24 | 25 | void loop() { 26 | // action 1 27 | if (Serial.available() > 0) { 28 | int data = Serial.parseInt(); 29 | if ((data >= 100) && (data <= 4000)) { 30 | blinkDelayLED1 = data; 31 | } 32 | } 33 | 34 | // action 2 35 | unsigned long timeNow = millis(); 36 | if (timeNow - previousTimeLED1Blink > blinkDelayLED1) { 37 | if (LED1State == LOW) { 38 | LED1State = HIGH; 39 | } 40 | else { 41 | LED1State = LOW; 42 | } 43 | digitalWrite(LED_1_PIN, LED1State); 44 | previousTimeLED1Blink += blinkDelayLED1; 45 | } 46 | 47 | // action 3 48 | int potentiometerValue = analogRead(POTENTIOMETER_PIN); 49 | int intensity = potentiometerValue / 4; 50 | analogWrite(LED_2_PIN, intensity); 51 | 52 | // action 4 53 | if (digitalRead(BUTTON_PIN) == HIGH) { 54 | digitalWrite(LED_3_PIN, HIGH); 55 | } 56 | else { 57 | digitalWrite(LED_3_PIN, LOW); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /activities/activity11/activity11.ino: -------------------------------------------------------------------------------- 1 | #define LED_1_PIN 12 2 | #define LED_2_PIN 11 3 | #define LED_3_PIN 10 4 | 5 | #define BUTTON_PIN 2 6 | 7 | unsigned long lastTimeLED1Blinked = millis(); 8 | unsigned long blinkDelayLED1 = 1000; 9 | byte LED1State = LOW; 10 | 11 | unsigned long lastTimeButtonChanged = millis(); 12 | unsigned long debounceDelay = 50; 13 | byte buttonState = LOW; 14 | 15 | int toggleLEDState = 1; 16 | 17 | void setup() { 18 | pinMode(LED_1_PIN, OUTPUT); 19 | pinMode(LED_2_PIN, OUTPUT); 20 | pinMode(LED_3_PIN, OUTPUT); 21 | 22 | pinMode(BUTTON_PIN, INPUT); 23 | buttonState = digitalRead(BUTTON_PIN); 24 | } 25 | 26 | void blinkLED1() 27 | { 28 | if (LED1State == HIGH) { 29 | LED1State = LOW; 30 | } 31 | else { 32 | LED1State = HIGH; 33 | } 34 | digitalWrite(LED_1_PIN, LED1State); 35 | } 36 | 37 | void toggleOtherLEDs() 38 | { 39 | if (toggleLEDState == 1) { 40 | toggleLEDState = 2; 41 | digitalWrite(LED_2_PIN, LOW); 42 | digitalWrite(LED_3_PIN, HIGH); 43 | } 44 | else { 45 | toggleLEDState = 1; 46 | digitalWrite(LED_2_PIN, HIGH); 47 | digitalWrite(LED_3_PIN, LOW); 48 | } 49 | } 50 | 51 | void loop() { 52 | unsigned long timeNow = millis(); 53 | 54 | // blink LED1 55 | if (timeNow - lastTimeLED1Blinked > blinkDelayLED1) { 56 | lastTimeLED1Blinked += blinkDelayLED1; 57 | blinkLED1(); 58 | } 59 | 60 | // toggle LED 2-3 61 | if (timeNow - lastTimeButtonChanged > debounceDelay) { 62 | byte newButtonState = digitalRead(BUTTON_PIN); 63 | if (newButtonState != buttonState) { 64 | lastTimeButtonChanged = timeNow; 65 | buttonState = newButtonState; 66 | if (buttonState == HIGH) { 67 | toggleOtherLEDs(); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /activities/activity12/activity12.ino: -------------------------------------------------------------------------------- 1 | #define BUTTON_PIN 2 2 | 3 | volatile unsigned long lastTimeButtonPressed = millis(); 4 | unsigned long debounceDelay = 50; 5 | 6 | volatile bool buttonPressed = false; 7 | 8 | int counter = 0; 9 | 10 | void buttonPressedInterrupt() 11 | { 12 | unsigned long timeNow = millis(); 13 | if (timeNow - lastTimeButtonPressed > debounceDelay) { 14 | lastTimeButtonPressed = timeNow; 15 | buttonPressed = true; 16 | } 17 | } 18 | 19 | void setup() { 20 | Serial.begin(115200); 21 | pinMode(BUTTON_PIN, INPUT); 22 | attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), 23 | buttonPressedInterrupt, 24 | RISING); 25 | } 26 | 27 | void loop() { 28 | if (buttonPressed) { 29 | buttonPressed = false; 30 | counter++; 31 | Serial.print("Counter is : "); 32 | Serial.println(counter); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /activities/activity13/activity13.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LED_PIN 10 4 | #define POTENTIOMETER_PIN A2 5 | 6 | #define EEPROM_ADDRESS_MAX_BRIGHTNESS 350 7 | #define MAX_BRIGHTNESS_DEFAULT 255 8 | 9 | byte maxBrightness; 10 | 11 | void setup() { 12 | Serial.begin(115200); 13 | Serial.setTimeout(10); 14 | pinMode(LED_PIN, OUTPUT); 15 | 16 | maxBrightness = EEPROM.read(EEPROM_ADDRESS_MAX_BRIGHTNESS); 17 | if (maxBrightness == 0) { 18 | maxBrightness = MAX_BRIGHTNESS_DEFAULT; 19 | } 20 | } 21 | 22 | void loop() { 23 | if (Serial.available() > 0) { 24 | int data = Serial.parseInt(); 25 | if ((data >= 0) && (data < 256)) { 26 | EEPROM.write(EEPROM_ADDRESS_MAX_BRIGHTNESS, data); 27 | maxBrightness = data; 28 | } 29 | } 30 | 31 | byte LEDBrightness = analogRead(POTENTIOMETER_PIN) / 4; 32 | if (LEDBrightness > maxBrightness) { 33 | LEDBrightness = maxBrightness; 34 | } 35 | analogWrite(LED_PIN, LEDBrightness); 36 | } 37 | -------------------------------------------------------------------------------- /activities/activity14/activity14.ino: -------------------------------------------------------------------------------- 1 | #define ECHO_PIN 3 2 | #define TRIGGER_PIN 4 3 | 4 | unsigned long lastTimeUltrasonicTrigger = millis(); 5 | unsigned long ultrasonicTriggerDelay = 100; 6 | 7 | void triggerUltrasonicSensor() 8 | { 9 | digitalWrite(TRIGGER_PIN, LOW); 10 | delayMicroseconds(2); 11 | digitalWrite(TRIGGER_PIN, HIGH); 12 | delayMicroseconds(10); 13 | digitalWrite(TRIGGER_PIN, LOW); 14 | } 15 | 16 | double getUltrasonicDistance() 17 | { 18 | unsigned long timeBegin = micros(); 19 | double durationMicros = pulseIn(ECHO_PIN, HIGH); 20 | unsigned long timeEnd = micros(); 21 | unsigned long codeDuration = timeEnd - timeBegin; 22 | Serial.print("Duration :"); 23 | Serial.println(codeDuration); 24 | double distance = durationMicros / 58.0; // cm (148.0: inches) 25 | return distance; 26 | } 27 | 28 | void setup() { 29 | Serial.begin(115200); 30 | pinMode(ECHO_PIN, INPUT); 31 | pinMode(TRIGGER_PIN, OUTPUT); 32 | } 33 | 34 | void loop() { 35 | unsigned long timeNow = millis(); 36 | 37 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 38 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 39 | triggerUltrasonicSensor(); 40 | Serial.println(getUltrasonicDistance()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /activities/activity15/activity15.ino: -------------------------------------------------------------------------------- 1 | #define LED_1_PIN 12 2 | #define LED_2_PIN 11 3 | #define LED_3_PIN 10 4 | #define ECHO_PIN 3 5 | #define TRIGGER_PIN 4 6 | 7 | unsigned long lastTimeUltrasonicTrigger = millis(); 8 | unsigned long ultrasonicTriggerDelay = 60; 9 | 10 | volatile unsigned long pulseInTimeBegin; 11 | volatile unsigned long pulseInTimeEnd; 12 | volatile bool newDistanceAvailable = false; 13 | 14 | double previousDistance = 400.0; 15 | 16 | void triggerUltrasonicSensor() 17 | { 18 | digitalWrite(TRIGGER_PIN, LOW); 19 | delayMicroseconds(2); 20 | digitalWrite(TRIGGER_PIN, HIGH); 21 | delayMicroseconds(10); 22 | digitalWrite(TRIGGER_PIN, LOW); 23 | } 24 | 25 | double getUltrasonicDistance() 26 | { 27 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 28 | double distance = durationMicros / 58.0; // cm (148.0: inches) 29 | if (distance > 400.0) { 30 | return previousDistance; 31 | } 32 | distance = previousDistance * 0.7 + distance * 0.3; 33 | previousDistance = distance; 34 | return distance; 35 | } 36 | 37 | void echoPinInterrupt() 38 | { 39 | if (digitalRead(ECHO_PIN) == HIGH) { // start measuring 40 | pulseInTimeBegin = micros(); 41 | } 42 | else { // stop measuring 43 | pulseInTimeEnd = micros(); 44 | newDistanceAvailable = true; 45 | } 46 | } 47 | 48 | void powerLEDsFromDistance(double distance) 49 | { 50 | if (distance >= 100) { 51 | digitalWrite(LED_1_PIN, LOW); 52 | digitalWrite(LED_2_PIN, LOW); 53 | digitalWrite(LED_3_PIN, HIGH); 54 | } 55 | else if (distance >= 15) { 56 | digitalWrite(LED_1_PIN, LOW); 57 | digitalWrite(LED_2_PIN, HIGH); 58 | digitalWrite(LED_3_PIN, LOW); 59 | } 60 | else { 61 | digitalWrite(LED_1_PIN, HIGH); 62 | digitalWrite(LED_2_PIN, LOW); 63 | digitalWrite(LED_3_PIN, LOW); 64 | } 65 | } 66 | 67 | void setup() { 68 | Serial.begin(115200); 69 | pinMode(ECHO_PIN, INPUT); 70 | pinMode(TRIGGER_PIN, OUTPUT); 71 | pinMode(LED_1_PIN, OUTPUT); 72 | pinMode(LED_2_PIN, OUTPUT); 73 | pinMode(LED_3_PIN, OUTPUT); 74 | 75 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 76 | echoPinInterrupt, 77 | CHANGE); 78 | } 79 | 80 | void loop() { 81 | unsigned long timeNow = millis(); 82 | 83 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 84 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 85 | triggerUltrasonicSensor(); 86 | } 87 | 88 | if (newDistanceAvailable) { 89 | newDistanceAvailable = false; 90 | double distance = getUltrasonicDistance(); 91 | powerLEDsFromDistance(distance); 92 | Serial.println(distance); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /activities/activity16/activity16.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LCD_RS_PIN A5 4 | #define LCD_E_PIN A4 5 | #define LCD_D4_PIN 6 6 | #define LCD_D5_PIN 7 7 | #define LCD_D6_PIN 8 8 | #define LCD_D7_PIN 9 9 | 10 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 11 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 12 | 13 | int cursorLine = 0; 14 | 15 | void printUserTextOnDisplay(String text) 16 | { 17 | // validate text 18 | if (text.length() > 16) { 19 | text = "Text too long."; 20 | } 21 | for (int i = text.length(); i < 16; i++ ) { 22 | text += " "; 23 | } 24 | // set cursor line O or 1 25 | lcd.setCursor(0, cursorLine); 26 | // print text 27 | lcd.print(text); 28 | if (cursorLine == 0) { 29 | cursorLine = 1; 30 | } 31 | else { 32 | cursorLine = 0; 33 | } 34 | } 35 | 36 | void setup() { 37 | Serial.begin(115200); 38 | Serial.setTimeout(10); 39 | lcd.begin(16, 2); 40 | } 41 | 42 | void loop() { 43 | if (Serial.available() > 0) { 44 | String text = Serial.readString(); 45 | printUserTextOnDisplay(text); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /activities/activity17/activity17.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define LCD_RS_PIN A5 4 | #define LCD_E_PIN A4 5 | #define LCD_D4_PIN 6 6 | #define LCD_D5_PIN 7 7 | #define LCD_D6_PIN 8 8 | #define LCD_D7_PIN 9 9 | 10 | #define ECHO_PIN 3 11 | #define TRIGGER_PIN 4 12 | 13 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 14 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 15 | 16 | int cursorLine = 0; 17 | 18 | unsigned long lastTimeUltrasonicTrigger = millis(); 19 | unsigned long ultrasonicTriggerDelay = 60; 20 | 21 | volatile unsigned long pulseInTimeBegin; 22 | volatile unsigned long pulseInTimeEnd; 23 | volatile bool newDistanceAvailable = false; 24 | 25 | double previousDistance = 400.0; 26 | 27 | void triggerUltrasonicSensor() 28 | { 29 | digitalWrite(TRIGGER_PIN, LOW); 30 | delayMicroseconds(2); 31 | digitalWrite(TRIGGER_PIN, HIGH); 32 | delayMicroseconds(10); 33 | digitalWrite(TRIGGER_PIN, LOW); 34 | } 35 | 36 | double getUltrasonicDistance() 37 | { 38 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 39 | double distance = durationMicros / 58.0; // cm (148.0: inches) 40 | if (distance > 400.0) { 41 | return previousDistance; 42 | } 43 | distance = previousDistance * 0.7 + distance * 0.3; 44 | previousDistance = distance; 45 | return distance; 46 | } 47 | 48 | void echoPinInterrupt() 49 | { 50 | if (digitalRead(ECHO_PIN) == HIGH) { // start measuring 51 | pulseInTimeBegin = micros(); 52 | } 53 | else { // stop measuring 54 | pulseInTimeEnd = micros(); 55 | newDistanceAvailable = true; 56 | } 57 | } 58 | 59 | void printDistanceOnLCD(double distance) 60 | { 61 | lcd.setCursor(0, 1); 62 | lcd.print("Distance: "); 63 | lcd.print(distance); 64 | lcd.print(" "); 65 | } 66 | 67 | void setup() { 68 | pinMode(ECHO_PIN, INPUT); 69 | pinMode(TRIGGER_PIN, OUTPUT); 70 | lcd.begin(16, 2); 71 | lcd.setCursor(0, 0); 72 | lcd.print("Rate: "); 73 | lcd.print(ultrasonicTriggerDelay); 74 | lcd.print(" ms."); 75 | 76 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 77 | echoPinInterrupt, 78 | CHANGE); 79 | } 80 | 81 | void loop() { 82 | unsigned long timeNow = millis(); 83 | 84 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 85 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 86 | triggerUltrasonicSensor(); 87 | } 88 | 89 | if (newDistanceAvailable) { 90 | newDistanceAvailable = false; 91 | double distance = getUltrasonicDistance(); 92 | printDistanceOnLCD(distance); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /activities/activity18_v2/activity18_v2.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define LCD_RS_PIN A5 5 | #define LCD_E_PIN A4 6 | #define LCD_D4_PIN 6 7 | #define LCD_D5_PIN 7 8 | #define LCD_D6_PIN 8 9 | #define LCD_D7_PIN 9 10 | 11 | #define LED_1_PIN 12 12 | #define LED_2_PIN 11 13 | #define LED_3_PIN 10 14 | 15 | #define IR_RECEIVE_PIN 5 16 | 17 | #define IR_BUTTON_0 0xFD30CF 18 | #define IR_BUTTON_1 0xFD08F7 19 | #define IR_BUTTON_2 0xFD8877 20 | #define IR_BUTTON_3 0xFD48B7 21 | #define IR_BUTTON_FUNC_STOP 0xFD40BF 22 | 23 | #define LED_ARRAY_SIZE 3 24 | 25 | byte LEDArray[LED_ARRAY_SIZE] = 26 | { LED_1_PIN, LED_2_PIN, LED_3_PIN }; 27 | byte LEDStateArray[LED_ARRAY_SIZE] = { LOW, LOW, LOW }; 28 | 29 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 30 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 31 | 32 | IRrecv irrecv(IR_RECEIVE_PIN); 33 | decode_results results; 34 | 35 | void initLEDModes() 36 | { 37 | for (int i = 0; i < LED_ARRAY_SIZE; i++) { 38 | pinMode(LEDArray[i], OUTPUT); 39 | } 40 | } 41 | 42 | void powerOffAllLEDs() 43 | { 44 | for (int i = 0; i < LED_ARRAY_SIZE; i++) { 45 | LEDStateArray[i] = LOW; 46 | digitalWrite(LEDArray[i], LOW); 47 | } 48 | } 49 | 50 | void toggleLEDFromIndex(int index) 51 | { 52 | if (index >= LED_ARRAY_SIZE) { 53 | return; 54 | } 55 | if (LEDStateArray[index] == HIGH) { 56 | LEDStateArray[index] = LOW; 57 | } 58 | else { 59 | LEDStateArray[index] = HIGH; 60 | } 61 | digitalWrite(LEDArray[index], LEDStateArray[index]); 62 | } 63 | 64 | void printCommandOnLCD(long command) 65 | { 66 | lcd.setCursor(0, 0); 67 | lcd.print(command); 68 | lcd.print(" "); 69 | } 70 | 71 | void printActionOnLCD(String action) 72 | { 73 | lcd.setCursor(0, 1); 74 | lcd.print(action); 75 | } 76 | 77 | void setup() { 78 | irrecv.enableIRIn(); 79 | initLEDModes(); 80 | lcd.begin(16, 2); 81 | } 82 | 83 | void loop() { 84 | if (irrecv.decode(&results)) { 85 | irrecv.resume(); 86 | long command = results.value; 87 | switch (command) { 88 | case IR_BUTTON_0: { 89 | powerOffAllLEDs(); 90 | printCommandOnLCD(command); 91 | printActionOnLCD("Power off LEDs. "); 92 | break; 93 | } 94 | case IR_BUTTON_1: { 95 | toggleLEDFromIndex(0); 96 | printCommandOnLCD(command); 97 | printActionOnLCD("Toggle LED 1. "); 98 | break; 99 | } 100 | case IR_BUTTON_2: { 101 | toggleLEDFromIndex(1); 102 | printCommandOnLCD(command); 103 | printActionOnLCD("Toggle LED 2. "); 104 | break; 105 | } 106 | case IR_BUTTON_3: { 107 | toggleLEDFromIndex(2); 108 | printCommandOnLCD(command); 109 | printActionOnLCD("Toggle LED 3. "); 110 | break; 111 | } 112 | case IR_BUTTON_FUNC_STOP: { 113 | lcd.clear(); 114 | break; 115 | } 116 | default: { 117 | printCommandOnLCD(command); 118 | printActionOnLCD("Not recognized. "); 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /activities/activity18_v3/activity18_v3.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define LCD_RS_PIN A5 5 | #define LCD_E_PIN A4 6 | #define LCD_D4_PIN 6 7 | #define LCD_D5_PIN 7 8 | #define LCD_D6_PIN 8 9 | #define LCD_D7_PIN 9 10 | 11 | #define LED_1_PIN 12 12 | #define LED_2_PIN 11 13 | #define LED_3_PIN 10 14 | 15 | #define IR_RECEIVE_PIN 5 16 | 17 | #define IR_BUTTON_0 22 18 | #define IR_BUTTON_1 12 19 | #define IR_BUTTON_2 24 20 | #define IR_BUTTON_3 94 21 | #define IR_BUTTON_FUNC_STOP 71 22 | 23 | #define LED_ARRAY_SIZE 3 24 | 25 | byte LEDArray[LED_ARRAY_SIZE] = 26 | { LED_1_PIN, LED_2_PIN, LED_3_PIN }; 27 | byte LEDStateArray[LED_ARRAY_SIZE] = { LOW, LOW, LOW }; 28 | 29 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 30 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 31 | 32 | void initLEDModes() 33 | { 34 | for (int i = 0; i < LED_ARRAY_SIZE; i++) { 35 | pinMode(LEDArray[i], OUTPUT); 36 | } 37 | } 38 | 39 | void powerOffAllLEDs() 40 | { 41 | for (int i = 0; i < LED_ARRAY_SIZE; i++) { 42 | LEDStateArray[i] = LOW; 43 | digitalWrite(LEDArray[i], LOW); 44 | } 45 | } 46 | 47 | void toggleLEDFromIndex(int index) 48 | { 49 | if (index >= LED_ARRAY_SIZE) { 50 | return; 51 | } 52 | if (LEDStateArray[index] == HIGH) { 53 | LEDStateArray[index] = LOW; 54 | } 55 | else { 56 | LEDStateArray[index] = HIGH; 57 | } 58 | digitalWrite(LEDArray[index], LEDStateArray[index]); 59 | } 60 | 61 | void printCommandOnLCD(int command) 62 | { 63 | lcd.setCursor(0, 0); 64 | lcd.print(command); 65 | lcd.print(" "); 66 | } 67 | 68 | void printActionOnLCD(String action) 69 | { 70 | lcd.setCursor(0, 1); 71 | lcd.print(action); 72 | } 73 | 74 | void setup() { 75 | IrReceiver.begin(IR_RECEIVE_PIN); 76 | initLEDModes(); 77 | lcd.begin(16, 2); 78 | } 79 | 80 | void loop() { 81 | if (IrReceiver.decode()) { 82 | IrReceiver.resume(); 83 | int command = IrReceiver.decodedIRData.command; 84 | switch (command) { 85 | case IR_BUTTON_0: { 86 | powerOffAllLEDs(); 87 | printCommandOnLCD(command); 88 | printActionOnLCD("Power off LEDs. "); 89 | break; 90 | } 91 | case IR_BUTTON_1: { 92 | toggleLEDFromIndex(0); 93 | printCommandOnLCD(command); 94 | printActionOnLCD("Toggle LED 1. "); 95 | break; 96 | } 97 | case IR_BUTTON_2: { 98 | toggleLEDFromIndex(1); 99 | printCommandOnLCD(command); 100 | printActionOnLCD("Toggle LED 2. "); 101 | break; 102 | } 103 | case IR_BUTTON_3: { 104 | toggleLEDFromIndex(2); 105 | printCommandOnLCD(command); 106 | printActionOnLCD("Toggle LED 3. "); 107 | break; 108 | } 109 | case IR_BUTTON_FUNC_STOP: { 110 | lcd.clear(); 111 | break; 112 | } 113 | default: { 114 | printCommandOnLCD(command); 115 | printActionOnLCD("Not recognized. "); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /activities/activity19/activity19.ino: -------------------------------------------------------------------------------- 1 | #define PHOTORESISTOR_PIN A0 2 | #define LED_1_PIN 12 3 | #define LED_2_PIN 10 4 | 5 | #define LUMINOSITY_NIGHT_TRESHOLD 330 6 | 7 | void setup() { 8 | pinMode(LED_1_PIN, OUTPUT); 9 | pinMode(LED_2_PIN, OUTPUT); 10 | } 11 | 12 | void loop() { 13 | int luminosity = analogRead(PHOTORESISTOR_PIN); 14 | 15 | if (luminosity < LUMINOSITY_NIGHT_TRESHOLD) { 16 | digitalWrite(LED_1_PIN, HIGH); 17 | } 18 | else { 19 | digitalWrite(LED_1_PIN, LOW); 20 | } 21 | 22 | int brightness = 255 - luminosity / 4; 23 | analogWrite(LED_2_PIN, brightness); 24 | } 25 | -------------------------------------------------------------------------------- /activities/activity2/activity2.ino: -------------------------------------------------------------------------------- 1 | #define LED_PIN 11 2 | 3 | void setup() { 4 | // Serial.begin(9600); 5 | pinMode(LED_PIN, OUTPUT); 6 | } 7 | 8 | void loop() { 9 | for (int i = 0; i <= 255; i++) { 10 | // Serial.println(i); 11 | analogWrite(LED_PIN, i); 12 | delay(5); 13 | } 14 | 15 | for (int i = 255; i >= 0; i--) { 16 | // Serial.println(i); 17 | analogWrite(LED_PIN, i); 18 | delay(5); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /activities/activity20/activity20.ino: -------------------------------------------------------------------------------- 1 | #define PHOTORESISTOR_PIN A0 2 | 3 | #define LUMINOSITY_SAMPLES_SIZE 100 4 | 5 | int luminositySamples[LUMINOSITY_SAMPLES_SIZE] = { 0 }; 6 | int indexCounter = 0; 7 | 8 | unsigned long lastTimeReadLuminosity = millis(); 9 | unsigned long luminositySampleDelay = 50; 10 | 11 | int computeAverageLuminosity() 12 | { 13 | long sum = 0; 14 | for (int i = 0; i < LUMINOSITY_SAMPLES_SIZE; i++) { 15 | sum += luminositySamples[i]; 16 | } 17 | return sum / LUMINOSITY_SAMPLES_SIZE; 18 | } 19 | 20 | void printAverageLuminosity() 21 | { 22 | int average = computeAverageLuminosity(); 23 | Serial.println(""); 24 | Serial.print("Average luminosity for "); 25 | Serial.print(LUMINOSITY_SAMPLES_SIZE); 26 | Serial.print(" samples, taken every "); 27 | Serial.print(luminositySampleDelay); 28 | Serial.print(" milliseconds: "); 29 | Serial.println(average); 30 | } 31 | 32 | void setup() { 33 | Serial.begin(115200); 34 | } 35 | 36 | void loop() { 37 | unsigned long timeNow = millis(); 38 | if (timeNow - lastTimeReadLuminosity > luminositySampleDelay) { 39 | lastTimeReadLuminosity += luminositySampleDelay; 40 | if (indexCounter == LUMINOSITY_SAMPLES_SIZE) { 41 | indexCounter = 0; 42 | printAverageLuminosity(); 43 | } 44 | luminositySamples[indexCounter] = analogRead(PHOTORESISTOR_PIN); 45 | indexCounter++; 46 | Serial.print("."); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /activities/activity3/activity3.ino: -------------------------------------------------------------------------------- 1 | #define LED_PIN 11 2 | #define BUTTON_PIN 2 3 | 4 | void setup() { 5 | pinMode(LED_PIN, OUTPUT); 6 | pinMode(BUTTON_PIN, INPUT); 7 | } 8 | 9 | void loop() { 10 | if (digitalRead(BUTTON_PIN) == HIGH) { 11 | digitalWrite(LED_PIN, HIGH); 12 | } 13 | else { 14 | digitalWrite(LED_PIN, LOW); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /activities/activity4/activity4.ino: -------------------------------------------------------------------------------- 1 | #define LED_PIN 11 2 | #define POTENTIOMETER_PIN A2 3 | 4 | void setup() { 5 | pinMode(LED_PIN, OUTPUT); 6 | } 7 | 8 | void loop() { 9 | int potentiometerValue = analogRead(POTENTIOMETER_PIN); 10 | int LEDBrightness = potentiometerValue / 4; 11 | analogWrite(LED_PIN, LEDBrightness); 12 | } 13 | -------------------------------------------------------------------------------- /activities/activity5/activity5.ino: -------------------------------------------------------------------------------- 1 | #define LED_1_PIN 12 2 | #define LED_2_PIN 11 3 | #define LED_3_PIN 10 4 | 5 | void setup() { 6 | pinMode(LED_1_PIN, OUTPUT); 7 | pinMode(LED_2_PIN, OUTPUT); 8 | pinMode(LED_3_PIN, OUTPUT); 9 | 10 | digitalWrite(LED_1_PIN, LOW); 11 | digitalWrite(LED_2_PIN, LOW); 12 | digitalWrite(LED_3_PIN, LOW); 13 | } 14 | 15 | void loop() { 16 | digitalWrite(LED_1_PIN, HIGH); 17 | digitalWrite(LED_2_PIN, LOW); 18 | digitalWrite(LED_3_PIN, LOW); 19 | delay(3000); 20 | digitalWrite(LED_1_PIN, LOW); 21 | digitalWrite(LED_2_PIN, LOW); 22 | digitalWrite(LED_3_PIN, HIGH); 23 | delay(3000); 24 | digitalWrite(LED_1_PIN, LOW); 25 | digitalWrite(LED_2_PIN, HIGH); 26 | digitalWrite(LED_3_PIN, LOW); 27 | delay(1000); 28 | } 29 | -------------------------------------------------------------------------------- /activities/activity6/activity6.ino: -------------------------------------------------------------------------------- 1 | #define LED_1_PIN 12 2 | #define LED_2_PIN 11 3 | #define LED_3_PIN 10 4 | 5 | #define BUTTON_PIN 2 6 | 7 | int LEDBlinkState = 1; 8 | 9 | void setup() { 10 | pinMode(BUTTON_PIN, INPUT); 11 | 12 | pinMode(LED_1_PIN, OUTPUT); 13 | pinMode(LED_2_PIN, OUTPUT); 14 | pinMode(LED_3_PIN, OUTPUT); 15 | 16 | digitalWrite(LED_1_PIN, LOW); 17 | digitalWrite(LED_2_PIN, LOW); 18 | digitalWrite(LED_3_PIN, LOW); 19 | } 20 | 21 | void loop() { 22 | if (digitalRead(BUTTON_PIN) == LOW) { 23 | if (LEDBlinkState == 1) { 24 | digitalWrite(LED_1_PIN, HIGH); 25 | digitalWrite(LED_2_PIN, LOW); 26 | digitalWrite(LED_3_PIN, HIGH); 27 | LEDBlinkState = 2; 28 | } 29 | else { 30 | digitalWrite(LED_1_PIN, LOW); 31 | digitalWrite(LED_2_PIN, HIGH); 32 | digitalWrite(LED_3_PIN, LOW); 33 | LEDBlinkState = 1; 34 | } 35 | delay(300); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /activities/activity7/activity7.ino: -------------------------------------------------------------------------------- 1 | #define LED_1_PIN 12 2 | #define LED_2_PIN 11 3 | #define LED_3_PIN 10 4 | 5 | #define BUTTON_PIN 2 6 | 7 | #define LED_PIN_ARRAY_SIZE 3 8 | 9 | int LEDBlinkState = 1; 10 | 11 | byte LEDPinArray[LED_PIN_ARRAY_SIZE] = 12 | {LED_1_PIN, LED_2_PIN, LED_3_PIN}; 13 | 14 | void setLEDPinModes() 15 | { 16 | for (int i = 0; i < LED_PIN_ARRAY_SIZE; i++) { 17 | pinMode(LEDPinArray[i], OUTPUT); 18 | } 19 | } 20 | 21 | void turnOffAllLEDs() 22 | { 23 | for (int i = 0; i < LED_PIN_ARRAY_SIZE; i++) { 24 | digitalWrite(LEDPinArray[i], LOW); 25 | } 26 | } 27 | 28 | void toggleLEDs() 29 | { 30 | if (LEDBlinkState == 1) { 31 | digitalWrite(LED_1_PIN, HIGH); 32 | digitalWrite(LED_2_PIN, LOW); 33 | digitalWrite(LED_3_PIN, HIGH); 34 | LEDBlinkState = 2; 35 | } 36 | else { 37 | digitalWrite(LED_1_PIN, LOW); 38 | digitalWrite(LED_2_PIN, HIGH); 39 | digitalWrite(LED_3_PIN, LOW); 40 | LEDBlinkState = 1; 41 | } 42 | } 43 | 44 | void setup() { 45 | pinMode(BUTTON_PIN, INPUT); 46 | 47 | setLEDPinModes(); 48 | turnOffAllLEDs(); 49 | } 50 | 51 | void loop() { 52 | if (digitalRead(BUTTON_PIN) == LOW) { 53 | toggleLEDs(); 54 | delay(300); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /activities/activity8/activity8.ino: -------------------------------------------------------------------------------- 1 | #define LED_PIN 12 2 | 3 | int blinkDelay = 500; 4 | 5 | int LEDState = LOW; 6 | 7 | void setup() { 8 | Serial.begin(115200); 9 | Serial.setTimeout(10); 10 | 11 | pinMode(LED_PIN, OUTPUT); 12 | } 13 | 14 | void loop() { 15 | if (Serial.available() > 0) { 16 | int data = Serial.parseInt(); 17 | if ((data >= 100) && (data <= 4000)) { 18 | blinkDelay = data; 19 | } 20 | } 21 | 22 | if (LEDState == LOW) { 23 | LEDState = HIGH; 24 | } 25 | else { 26 | LEDState = LOW; 27 | } 28 | digitalWrite(LED_PIN, LEDState); 29 | delay(blinkDelay); 30 | } 31 | -------------------------------------------------------------------------------- /activities/activity9/activity9.ino: -------------------------------------------------------------------------------- 1 | #define LED_PIN 12 2 | 3 | unsigned long previousTimeLEDBlink = millis(); 4 | unsigned long blinkDelay = 500; 5 | 6 | int LEDState = LOW; 7 | 8 | void setup() { 9 | Serial.begin(115200); 10 | Serial.setTimeout(10); 11 | 12 | pinMode(LED_PIN, OUTPUT); 13 | } 14 | 15 | void loop() { 16 | if (Serial.available() > 0) { 17 | int data = Serial.parseInt(); 18 | if ((data >= 100) && (data <= 4000)) { 19 | blinkDelay = data; 20 | } 21 | } 22 | 23 | unsigned long timeNow = millis(); 24 | if (timeNow - previousTimeLEDBlink > blinkDelay) { 25 | if (LEDState == LOW) { 26 | LEDState = HIGH; 27 | } 28 | else { 29 | LEDState = LOW; 30 | } 31 | digitalWrite(LED_PIN, LEDState); 32 | previousTimeLEDBlink += blinkDelay; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /final_project/final_project_step1/final_project_step1.ino: -------------------------------------------------------------------------------- 1 | #define ECHO_PIN 3 2 | #define TRIGGER_PIN 4 3 | 4 | unsigned long lastTimeUltrasonicTrigger = millis(); 5 | unsigned long ultrasonicTriggerDelay = 60; 6 | 7 | volatile unsigned long pulseInTimeBegin; 8 | volatile unsigned long pulseInTimeEnd; 9 | volatile bool newDistanceAvailable = false; 10 | 11 | double previousDistance = 400.0; 12 | 13 | void triggerUltrasonicSensor() 14 | { 15 | digitalWrite(TRIGGER_PIN, LOW); 16 | delayMicroseconds(2); 17 | digitalWrite(TRIGGER_PIN, HIGH); 18 | delayMicroseconds(10); 19 | digitalWrite(TRIGGER_PIN, LOW); 20 | } 21 | 22 | double getUltrasonicDistance() 23 | { 24 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 25 | double distance = durationMicros / 58.0; 26 | if (distance > 400.0) { 27 | return previousDistance; 28 | } 29 | distance = previousDistance * 0.6 + distance * 0.4; 30 | previousDistance = distance; 31 | return distance; 32 | } 33 | 34 | void echoPinInterrupt() 35 | { 36 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 37 | pulseInTimeBegin = micros(); 38 | } 39 | else { // pulse stoped 40 | pulseInTimeEnd = micros(); 41 | newDistanceAvailable = true; 42 | } 43 | } 44 | 45 | void setup() { 46 | Serial.begin(115200); 47 | pinMode(ECHO_PIN, INPUT); 48 | pinMode(TRIGGER_PIN, OUTPUT); 49 | 50 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 51 | echoPinInterrupt, 52 | CHANGE); 53 | } 54 | 55 | void loop() { 56 | unsigned long timeNow = millis(); 57 | 58 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 59 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 60 | triggerUltrasonicSensor(); 61 | } 62 | 63 | if (newDistanceAvailable) { 64 | newDistanceAvailable = false; 65 | double distance = getUltrasonicDistance(); 66 | Serial.println(distance); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /final_project/final_project_step10/final_project_step10.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define IR_RECEIVE_PIN 5 6 | 7 | #define ECHO_PIN 3 8 | #define TRIGGER_PIN 4 9 | 10 | #define WARNING_LED_PIN 11 11 | #define ERROR_LED_PIN 12 12 | 13 | #define BUTTON_PIN 2 14 | 15 | #define LCD_RS_PIN A5 16 | #define LCD_E_PIN A4 17 | #define LCD_D4_PIN 6 18 | #define LCD_D5_PIN 7 19 | #define LCD_D6_PIN 8 20 | #define LCD_D7_PIN 9 21 | 22 | #define LOCK_DISTANCE 10.0 23 | #define WARNING_DISTANCE 50.0 24 | 25 | // IR button mapping 26 | #define IR_BUTTON_PLAY 64 27 | #define IR_BUTTON_OFF 69 28 | #define IR_BUTTON_EQ 25 29 | #define IR_BUTTON_UP 9 30 | #define IR_BUTTON_DOWN 7 31 | 32 | // distance unit 33 | #define DISTANCE_UNIT_CM 0 34 | #define DISTANCE_UNIT_IN 1 35 | #define CM_TO_INCHES 0.393701 36 | #define EEPROM_ADDRESS_DISTANCE_UNIT 50 37 | 38 | // lcd mode 39 | #define LCD_MODE_DISTANCE 0 40 | #define LCD_MODE_SETTINGS 1 41 | 42 | // lcd 43 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 44 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 45 | 46 | // ultrasonic 47 | unsigned long lastTimeUltrasonicTrigger = millis(); 48 | unsigned long ultrasonicTriggerDelay = 60; 49 | 50 | volatile unsigned long pulseInTimeBegin; 51 | volatile unsigned long pulseInTimeEnd; 52 | volatile bool newDistanceAvailable = false; 53 | 54 | double previousDistance = 400.0; 55 | 56 | // warning LED 57 | unsigned long lastTimeWarningLEDBlinked = millis(); 58 | unsigned long warningLEDDelay = 500; 59 | byte warningLEDState = LOW; 60 | 61 | // error LED 62 | unsigned long lastTimeErrorLEDBlinked = millis(); 63 | unsigned long errorLEDDelay = 300; 64 | byte errorLEDState = LOW; 65 | 66 | // push button 67 | unsigned long lastTimeButtonChanged = millis(); 68 | unsigned long buttonDebounceDelay = 50; 69 | byte buttonState; 70 | 71 | bool isLocked = false; 72 | 73 | int distanceUnit = DISTANCE_UNIT_CM; 74 | int lcdMode = LCD_MODE_DISTANCE; 75 | 76 | void triggerUltrasonicSensor() 77 | { 78 | digitalWrite(TRIGGER_PIN, LOW); 79 | delayMicroseconds(2); 80 | digitalWrite(TRIGGER_PIN, HIGH); 81 | delayMicroseconds(10); 82 | digitalWrite(TRIGGER_PIN, LOW); 83 | } 84 | 85 | double getUltrasonicDistance() 86 | { 87 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 88 | double distance = durationMicros / 58.0; 89 | if (distance > 400.0) { 90 | return previousDistance; 91 | } 92 | distance = previousDistance * 0.6 + distance * 0.4; 93 | previousDistance = distance; 94 | return distance; 95 | } 96 | 97 | void echoPinInterrupt() 98 | { 99 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 100 | pulseInTimeBegin = micros(); 101 | } 102 | else { // pulse stoped 103 | pulseInTimeEnd = micros(); 104 | newDistanceAvailable = true; 105 | } 106 | } 107 | 108 | void toggleErrorLED() 109 | { 110 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 111 | digitalWrite(ERROR_LED_PIN, errorLEDState); 112 | } 113 | 114 | void toggleWarningLED() 115 | { 116 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 117 | digitalWrite(WARNING_LED_PIN, warningLEDState); 118 | } 119 | 120 | void setWarningLEDBlinkRateFromDistance(double distance) 121 | { 122 | // 0 .. 400 cm -> 0 .. 1600 ms 123 | warningLEDDelay = distance * 4; 124 | // Serial.println(warningLEDDelay); 125 | } 126 | 127 | void lock() 128 | { 129 | if (!isLocked) { 130 | // Serial.println("Locking"); 131 | isLocked = true; 132 | warningLEDState = LOW; 133 | errorLEDState = LOW; 134 | } 135 | } 136 | 137 | void unlock() 138 | { 139 | if (isLocked) { 140 | // Serial.println("Unlocking"); 141 | isLocked = false; 142 | errorLEDState = LOW; 143 | digitalWrite(ERROR_LED_PIN, errorLEDState); 144 | lcd.clear(); 145 | } 146 | } 147 | 148 | void printDistanceOnLCD(double distance) 149 | { 150 | if (isLocked) { 151 | lcd.setCursor(0, 0); 152 | lcd.print("!!! Obstacle !!! "); 153 | lcd.setCursor(0, 1); 154 | lcd.print("Press to unlock. "); 155 | } 156 | else if (lcdMode == LCD_MODE_DISTANCE) { 157 | lcd.setCursor(0, 0); 158 | lcd.print("Dist: "); 159 | if (distanceUnit == DISTANCE_UNIT_IN) { 160 | lcd.print(distance * CM_TO_INCHES); 161 | lcd.print(" in "); 162 | } 163 | else { 164 | lcd.print(distance); 165 | lcd.print(" cm "); 166 | } 167 | 168 | lcd.setCursor(0, 1); 169 | if (distance > WARNING_DISTANCE) { 170 | lcd.print("No obstacle. "); 171 | } 172 | else { 173 | lcd.print("!! Warning !! "); 174 | } 175 | } 176 | } 177 | 178 | void toggleDistanceUnit() 179 | { 180 | if (distanceUnit == DISTANCE_UNIT_CM) { 181 | distanceUnit = DISTANCE_UNIT_IN; 182 | } 183 | else { 184 | distanceUnit = DISTANCE_UNIT_CM; 185 | } 186 | EEPROM.write(EEPROM_ADDRESS_DISTANCE_UNIT, distanceUnit); 187 | } 188 | 189 | void toggleLCDScreen() 190 | { 191 | switch (lcdMode) { 192 | case LCD_MODE_DISTANCE: { 193 | lcdMode = LCD_MODE_SETTINGS; 194 | break; 195 | } 196 | case LCD_MODE_SETTINGS: { 197 | lcdMode = LCD_MODE_DISTANCE; 198 | break; 199 | } 200 | default: { 201 | lcdMode = LCD_MODE_DISTANCE; 202 | } 203 | } 204 | 205 | lcd.clear(); 206 | 207 | if (lcdMode == LCD_MODE_SETTINGS) { 208 | lcd.setCursor(0, 0); 209 | lcd.print("Press on OFF to"); 210 | lcd.setCursor(0, 1); 211 | lcd.print("reset settings."); 212 | } 213 | } 214 | 215 | void resetSettingsToDefault() 216 | { 217 | if (lcdMode == LCD_MODE_SETTINGS) { 218 | distanceUnit = DISTANCE_UNIT_CM; 219 | EEPROM.write(EEPROM_ADDRESS_DISTANCE_UNIT, distanceUnit); 220 | lcd.clear(); 221 | lcd.setCursor(0, 0); 222 | lcd.print("Settings have"); 223 | lcd.setCursor(0, 1); 224 | lcd.print("been reset."); 225 | } 226 | } 227 | 228 | void handleIRCommand(long command) 229 | { 230 | switch (command) { 231 | case IR_BUTTON_PLAY: { 232 | unlock(); 233 | break; 234 | } 235 | case IR_BUTTON_OFF: { 236 | resetSettingsToDefault(); 237 | break; 238 | } 239 | case IR_BUTTON_EQ: { 240 | toggleDistanceUnit(); 241 | break; 242 | } 243 | case IR_BUTTON_UP: { 244 | toggleLCDScreen(); 245 | break; 246 | } 247 | case IR_BUTTON_DOWN: { 248 | toggleLCDScreen(); 249 | break; 250 | } 251 | default: { 252 | // do nothing 253 | } 254 | } 255 | } 256 | 257 | void setup() { 258 | Serial.begin(115200); 259 | lcd.begin(16,2); 260 | IrReceiver.begin(IR_RECEIVE_PIN); 261 | pinMode(ECHO_PIN, INPUT); 262 | pinMode(TRIGGER_PIN, OUTPUT); 263 | pinMode(WARNING_LED_PIN, OUTPUT); 264 | pinMode(ERROR_LED_PIN, OUTPUT); 265 | pinMode(BUTTON_PIN, INPUT); 266 | 267 | buttonState = digitalRead(BUTTON_PIN); 268 | 269 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 270 | echoPinInterrupt, 271 | CHANGE); 272 | 273 | distanceUnit = EEPROM.read(EEPROM_ADDRESS_DISTANCE_UNIT); 274 | if (distanceUnit == 255) { 275 | distanceUnit = DISTANCE_UNIT_CM; 276 | } 277 | 278 | lcd.print("Initializing..."); 279 | delay(1000); 280 | lcd.clear(); 281 | } 282 | 283 | void loop() { 284 | unsigned long timeNow = millis(); 285 | 286 | if (isLocked) { 287 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 288 | lastTimeErrorLEDBlinked += errorLEDDelay; 289 | toggleErrorLED(); 290 | toggleWarningLED(); 291 | } 292 | 293 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 294 | byte newButtonState = digitalRead(BUTTON_PIN); 295 | if (newButtonState != buttonState) { 296 | lastTimeButtonChanged = timeNow; 297 | buttonState = newButtonState; 298 | if (buttonState == LOW) { // released 299 | unlock(); 300 | } 301 | } 302 | } 303 | } 304 | else { 305 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 306 | lastTimeWarningLEDBlinked += warningLEDDelay; 307 | toggleWarningLED(); 308 | } 309 | } 310 | 311 | if (IrReceiver.decode()) { 312 | IrReceiver.resume(); 313 | long command = IrReceiver.decodedIRData.command; 314 | handleIRCommand(command); 315 | // Serial.println(command); 316 | } 317 | 318 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 319 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 320 | triggerUltrasonicSensor(); 321 | } 322 | 323 | if (newDistanceAvailable) { 324 | newDistanceAvailable = false; 325 | double distance = getUltrasonicDistance(); 326 | setWarningLEDBlinkRateFromDistance(distance); 327 | printDistanceOnLCD(distance); 328 | if (distance < LOCK_DISTANCE) { 329 | lock(); 330 | } 331 | // Serial.println(distance); 332 | } 333 | } 334 | -------------------------------------------------------------------------------- /final_project/final_project_step11/final_project_step11.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define IR_RECEIVE_PIN 5 6 | 7 | #define ECHO_PIN 3 8 | #define TRIGGER_PIN 4 9 | 10 | #define WARNING_LED_PIN 11 11 | #define ERROR_LED_PIN 12 12 | #define LIGHT_LED_PIN 10 13 | 14 | #define BUTTON_PIN 2 15 | 16 | #define PHOTORESISTOR_PIN A0 17 | 18 | #define LCD_RS_PIN A5 19 | #define LCD_E_PIN A4 20 | #define LCD_D4_PIN 6 21 | #define LCD_D5_PIN 7 22 | #define LCD_D6_PIN 8 23 | #define LCD_D7_PIN 9 24 | 25 | #define LOCK_DISTANCE 10.0 26 | #define WARNING_DISTANCE 50.0 27 | 28 | // IR button mapping 29 | #define IR_BUTTON_PLAY 64 30 | #define IR_BUTTON_OFF 69 31 | #define IR_BUTTON_EQ 25 32 | #define IR_BUTTON_UP 9 33 | #define IR_BUTTON_DOWN 7 34 | 35 | // distance unit 36 | #define DISTANCE_UNIT_CM 0 37 | #define DISTANCE_UNIT_IN 1 38 | #define CM_TO_INCHES 0.393701 39 | #define EEPROM_ADDRESS_DISTANCE_UNIT 50 40 | 41 | // lcd mode 42 | #define LCD_MODE_DISTANCE 0 43 | #define LCD_MODE_SETTINGS 1 44 | #define LCD_MODE_LUMINOSITY 2 45 | 46 | // lcd 47 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 48 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 49 | 50 | // ultrasonic 51 | unsigned long lastTimeUltrasonicTrigger = millis(); 52 | unsigned long ultrasonicTriggerDelay = 60; 53 | 54 | volatile unsigned long pulseInTimeBegin; 55 | volatile unsigned long pulseInTimeEnd; 56 | volatile bool newDistanceAvailable = false; 57 | 58 | double previousDistance = 400.0; 59 | 60 | // warning LED 61 | unsigned long lastTimeWarningLEDBlinked = millis(); 62 | unsigned long warningLEDDelay = 500; 63 | byte warningLEDState = LOW; 64 | 65 | // error LED 66 | unsigned long lastTimeErrorLEDBlinked = millis(); 67 | unsigned long errorLEDDelay = 300; 68 | byte errorLEDState = LOW; 69 | 70 | // photoresistor 71 | unsigned long lastTimeReadLuminosity = millis(); 72 | unsigned long readLuminosityDelay = 100; 73 | 74 | // push button 75 | unsigned long lastTimeButtonChanged = millis(); 76 | unsigned long buttonDebounceDelay = 50; 77 | byte buttonState; 78 | 79 | bool isLocked = false; 80 | 81 | int distanceUnit = DISTANCE_UNIT_CM; 82 | int lcdMode = LCD_MODE_DISTANCE; 83 | 84 | void triggerUltrasonicSensor() 85 | { 86 | digitalWrite(TRIGGER_PIN, LOW); 87 | delayMicroseconds(2); 88 | digitalWrite(TRIGGER_PIN, HIGH); 89 | delayMicroseconds(10); 90 | digitalWrite(TRIGGER_PIN, LOW); 91 | } 92 | 93 | double getUltrasonicDistance() 94 | { 95 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 96 | double distance = durationMicros / 58.0; 97 | if (distance > 400.0) { 98 | return previousDistance; 99 | } 100 | distance = previousDistance * 0.6 + distance * 0.4; 101 | previousDistance = distance; 102 | return distance; 103 | } 104 | 105 | void echoPinInterrupt() 106 | { 107 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 108 | pulseInTimeBegin = micros(); 109 | } 110 | else { // pulse stoped 111 | pulseInTimeEnd = micros(); 112 | newDistanceAvailable = true; 113 | } 114 | } 115 | 116 | void toggleErrorLED() 117 | { 118 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 119 | digitalWrite(ERROR_LED_PIN, errorLEDState); 120 | } 121 | 122 | void toggleWarningLED() 123 | { 124 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 125 | digitalWrite(WARNING_LED_PIN, warningLEDState); 126 | } 127 | 128 | void setWarningLEDBlinkRateFromDistance(double distance) 129 | { 130 | // 0 .. 400 cm -> 0 .. 1600 ms 131 | warningLEDDelay = distance * 4; 132 | // Serial.println(warningLEDDelay); 133 | } 134 | 135 | void lock() 136 | { 137 | if (!isLocked) { 138 | // Serial.println("Locking"); 139 | isLocked = true; 140 | warningLEDState = LOW; 141 | errorLEDState = LOW; 142 | } 143 | } 144 | 145 | void unlock() 146 | { 147 | if (isLocked) { 148 | // Serial.println("Unlocking"); 149 | isLocked = false; 150 | errorLEDState = LOW; 151 | digitalWrite(ERROR_LED_PIN, errorLEDState); 152 | lcd.clear(); 153 | } 154 | } 155 | 156 | void printDistanceOnLCD(double distance) 157 | { 158 | if (isLocked) { 159 | lcd.setCursor(0, 0); 160 | lcd.print("!!! Obstacle !!! "); 161 | lcd.setCursor(0, 1); 162 | lcd.print("Press to unlock. "); 163 | } 164 | else if (lcdMode == LCD_MODE_DISTANCE) { 165 | lcd.setCursor(0, 0); 166 | lcd.print("Dist: "); 167 | if (distanceUnit == DISTANCE_UNIT_IN) { 168 | lcd.print(distance * CM_TO_INCHES); 169 | lcd.print(" in "); 170 | } 171 | else { 172 | lcd.print(distance); 173 | lcd.print(" cm "); 174 | } 175 | 176 | lcd.setCursor(0, 1); 177 | if (distance > WARNING_DISTANCE) { 178 | lcd.print("No obstacle. "); 179 | } 180 | else { 181 | lcd.print("!! Warning !! "); 182 | } 183 | } 184 | } 185 | 186 | void toggleDistanceUnit() 187 | { 188 | if (distanceUnit == DISTANCE_UNIT_CM) { 189 | distanceUnit = DISTANCE_UNIT_IN; 190 | } 191 | else { 192 | distanceUnit = DISTANCE_UNIT_CM; 193 | } 194 | EEPROM.write(EEPROM_ADDRESS_DISTANCE_UNIT, distanceUnit); 195 | } 196 | 197 | void toggleLCDScreen(bool next) 198 | { 199 | switch (lcdMode) { 200 | case LCD_MODE_DISTANCE: { 201 | lcdMode = (next) ? LCD_MODE_SETTINGS : LCD_MODE_LUMINOSITY; 202 | break; 203 | } 204 | case LCD_MODE_SETTINGS: { 205 | lcdMode = (next) ? LCD_MODE_LUMINOSITY : LCD_MODE_DISTANCE; 206 | break; 207 | } 208 | case LCD_MODE_LUMINOSITY: { 209 | lcdMode = (next) ? LCD_MODE_DISTANCE : LCD_MODE_SETTINGS; 210 | break; 211 | } 212 | default: { 213 | lcdMode = LCD_MODE_DISTANCE; 214 | } 215 | } 216 | 217 | lcd.clear(); 218 | 219 | if (lcdMode == LCD_MODE_SETTINGS) { 220 | lcd.setCursor(0, 0); 221 | lcd.print("Press on OFF to"); 222 | lcd.setCursor(0, 1); 223 | lcd.print("reset settings."); 224 | } 225 | } 226 | 227 | void resetSettingsToDefault() 228 | { 229 | if (lcdMode == LCD_MODE_SETTINGS) { 230 | distanceUnit = DISTANCE_UNIT_CM; 231 | EEPROM.write(EEPROM_ADDRESS_DISTANCE_UNIT, distanceUnit); 232 | lcd.clear(); 233 | lcd.setCursor(0, 0); 234 | lcd.print("Settings have"); 235 | lcd.setCursor(0, 1); 236 | lcd.print("been reset."); 237 | } 238 | } 239 | 240 | void handleIRCommand(long command) 241 | { 242 | switch (command) { 243 | case IR_BUTTON_PLAY: { 244 | unlock(); 245 | break; 246 | } 247 | case IR_BUTTON_OFF: { 248 | resetSettingsToDefault(); 249 | break; 250 | } 251 | case IR_BUTTON_EQ: { 252 | toggleDistanceUnit(); 253 | break; 254 | } 255 | case IR_BUTTON_UP: { 256 | toggleLCDScreen(true); 257 | break; 258 | } 259 | case IR_BUTTON_DOWN: { 260 | toggleLCDScreen(false); 261 | break; 262 | } 263 | default: { 264 | // do nothing 265 | } 266 | } 267 | } 268 | 269 | void setLightLEDFromLuminosity(int luminosity) 270 | { 271 | byte brightness = 255 - luminosity / 4; 272 | analogWrite(LIGHT_LED_PIN, brightness); 273 | } 274 | 275 | void printLuminosityOnLCD(int luminosity) 276 | { 277 | if (!isLocked && lcdMode == LCD_MODE_LUMINOSITY) { 278 | lcd.setCursor(0, 0); 279 | lcd.print("Luminosity: "); 280 | lcd.print(luminosity); 281 | lcd.print(" "); 282 | } 283 | } 284 | 285 | void setup() { 286 | Serial.begin(115200); 287 | lcd.begin(16,2); 288 | IrReceiver.begin(IR_RECEIVE_PIN); 289 | pinMode(ECHO_PIN, INPUT); 290 | pinMode(TRIGGER_PIN, OUTPUT); 291 | pinMode(WARNING_LED_PIN, OUTPUT); 292 | pinMode(ERROR_LED_PIN, OUTPUT); 293 | pinMode(LIGHT_LED_PIN, OUTPUT); 294 | pinMode(BUTTON_PIN, INPUT); 295 | 296 | buttonState = digitalRead(BUTTON_PIN); 297 | 298 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 299 | echoPinInterrupt, 300 | CHANGE); 301 | 302 | distanceUnit = EEPROM.read(EEPROM_ADDRESS_DISTANCE_UNIT); 303 | if (distanceUnit == 255) { 304 | distanceUnit = DISTANCE_UNIT_CM; 305 | } 306 | 307 | lcd.print("Initializing..."); 308 | delay(1000); 309 | lcd.clear(); 310 | } 311 | 312 | void loop() { 313 | unsigned long timeNow = millis(); 314 | 315 | if (isLocked) { 316 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 317 | lastTimeErrorLEDBlinked += errorLEDDelay; 318 | toggleErrorLED(); 319 | toggleWarningLED(); 320 | } 321 | 322 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 323 | byte newButtonState = digitalRead(BUTTON_PIN); 324 | if (newButtonState != buttonState) { 325 | lastTimeButtonChanged = timeNow; 326 | buttonState = newButtonState; 327 | if (buttonState == LOW) { // released 328 | unlock(); 329 | } 330 | } 331 | } 332 | } 333 | else { 334 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 335 | lastTimeWarningLEDBlinked += warningLEDDelay; 336 | toggleWarningLED(); 337 | } 338 | } 339 | 340 | if (IrReceiver.decode()) { 341 | IrReceiver.resume(); 342 | long command = IrReceiver.decodedIRData.command; 343 | handleIRCommand(command); 344 | // Serial.println(command); 345 | } 346 | 347 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 348 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 349 | triggerUltrasonicSensor(); 350 | } 351 | 352 | if (newDistanceAvailable) { 353 | newDistanceAvailable = false; 354 | double distance = getUltrasonicDistance(); 355 | setWarningLEDBlinkRateFromDistance(distance); 356 | printDistanceOnLCD(distance); 357 | if (distance < LOCK_DISTANCE) { 358 | lock(); 359 | } 360 | // Serial.println(distance); 361 | } 362 | 363 | if (timeNow - lastTimeReadLuminosity > readLuminosityDelay) { 364 | lastTimeReadLuminosity += readLuminosityDelay; 365 | int luminosity = analogRead(PHOTORESISTOR_PIN); 366 | setLightLEDFromLuminosity(luminosity); 367 | printLuminosityOnLCD(luminosity); 368 | } 369 | } 370 | -------------------------------------------------------------------------------- /final_project/final_project_step11_v2/final_project_step11_v2.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define IR_RECEIVE_PIN 5 6 | 7 | #define ECHO_PIN 3 8 | #define TRIGGER_PIN 4 9 | 10 | #define WARNING_LED_PIN 11 11 | #define ERROR_LED_PIN 12 12 | #define LIGHT_LED_PIN 10 13 | 14 | #define BUTTON_PIN 2 15 | 16 | #define PHOTORESISTOR_PIN A0 17 | 18 | #define LCD_RS_PIN A5 19 | #define LCD_E_PIN A4 20 | #define LCD_D4_PIN 6 21 | #define LCD_D5_PIN 7 22 | #define LCD_D6_PIN 8 23 | #define LCD_D7_PIN 9 24 | 25 | #define LOCK_DISTANCE 20.0 26 | #define WARNING_DISTANCE 50.0 27 | 28 | // IR button mapping 29 | #define IR_BUTTON_PLAY 0xFDA05F 30 | #define IR_BUTTON_OFF 0XFD00FF 31 | #define IR_BUTTON_EQ 0xFDB04F 32 | #define IR_BUTTON_UP 0xFD50AF 33 | #define IR_BUTTON_DOWN 0xFD10EF 34 | 35 | // distance unit 36 | #define DISTANCE_UNIT_CM 0 37 | #define DISTANCE_UNIT_IN 1 38 | #define CM_TO_INCHES 0.393701 39 | #define EEPROM_ADDRESS_DISTANCE_UNIT 50 40 | 41 | // lcd mode 42 | #define LCD_MODE_DISTANCE 0 43 | #define LCD_MODE_SETTINGS 1 44 | #define LCD_MODE_LUMINOSITY 2 45 | 46 | // lcd 47 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 48 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 49 | 50 | // ultrasonic 51 | unsigned long lastTimeUltrasonicTrigger = millis(); 52 | unsigned long ultrasonicTriggerDelay = 60; 53 | 54 | volatile unsigned long pulseInTimeBegin; 55 | volatile unsigned long pulseInTimeEnd; 56 | volatile bool newDistanceAvailable = false; 57 | 58 | double previousDistance = 400.0; 59 | 60 | // warning LED 61 | unsigned long lastTimeWarningLEDBlinked = millis(); 62 | unsigned long warningLEDDelay = 500; 63 | byte warningLEDState = LOW; 64 | 65 | // error LED 66 | unsigned long lastTimeErrorLEDBlinked = millis(); 67 | unsigned long errorLEDDelay = 300; 68 | byte errorLEDState = LOW; 69 | 70 | // photoresistor 71 | unsigned long lastTimeReadLuminosity = millis(); 72 | unsigned long readLuminosityDelay = 100; 73 | 74 | // push button 75 | unsigned long lastTimeButtonChanged = millis(); 76 | unsigned long buttonDebounceDelay = 50; 77 | byte buttonState; 78 | 79 | // ir remote 80 | IRrecv irrecv(IR_RECEIVE_PIN); 81 | decode_results results; 82 | 83 | bool isLocked = false; 84 | 85 | int distanceUnit = DISTANCE_UNIT_CM; 86 | int lcdMode = LCD_MODE_DISTANCE; 87 | 88 | void triggerUltrasonicSensor() 89 | { 90 | digitalWrite(TRIGGER_PIN, LOW); 91 | delayMicroseconds(2); 92 | digitalWrite(TRIGGER_PIN, HIGH); 93 | delayMicroseconds(10); 94 | digitalWrite(TRIGGER_PIN, LOW); 95 | } 96 | 97 | double getUltrasonicDistance() 98 | { 99 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 100 | double distance = durationMicros / 58.0; 101 | if (distance > 400.0) { 102 | return previousDistance; 103 | } 104 | distance = previousDistance * 0.6 + distance * 0.4; 105 | previousDistance = distance; 106 | return distance; 107 | } 108 | 109 | void echoPinInterrupt() 110 | { 111 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 112 | pulseInTimeBegin = micros(); 113 | } 114 | else { // pulse stoped 115 | pulseInTimeEnd = micros(); 116 | newDistanceAvailable = true; 117 | } 118 | } 119 | 120 | void toggleErrorLED() 121 | { 122 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 123 | digitalWrite(ERROR_LED_PIN, errorLEDState); 124 | } 125 | 126 | void toggleWarningLED() 127 | { 128 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 129 | digitalWrite(WARNING_LED_PIN, warningLEDState); 130 | } 131 | 132 | void setWarningLEDBlinkRateFromDistance(double distance) 133 | { 134 | // 0 .. 400 cm -> 0 .. 1600 ms 135 | warningLEDDelay = distance * 4; 136 | // Serial.println(warningLEDDelay); 137 | } 138 | 139 | void lock() 140 | { 141 | if (!isLocked) { 142 | // Serial.println("Locking"); 143 | isLocked = true; 144 | warningLEDState = LOW; 145 | errorLEDState = LOW; 146 | } 147 | } 148 | 149 | void unlock() 150 | { 151 | if (isLocked) { 152 | // Serial.println("Unlocking"); 153 | isLocked = false; 154 | errorLEDState = LOW; 155 | digitalWrite(ERROR_LED_PIN, errorLEDState); 156 | lcd.clear(); 157 | } 158 | } 159 | 160 | void printDistanceOnLCD(double distance) 161 | { 162 | if (isLocked) { 163 | lcd.setCursor(0, 0); 164 | lcd.print("!!! Obstacle !!! "); 165 | lcd.setCursor(0, 1); 166 | lcd.print("Press to unlock. "); 167 | } 168 | else if (lcdMode == LCD_MODE_DISTANCE) { 169 | lcd.setCursor(0, 0); 170 | lcd.print("Dist: "); 171 | if (distanceUnit == DISTANCE_UNIT_IN) { 172 | lcd.print(distance * CM_TO_INCHES); 173 | lcd.print(" in "); 174 | } 175 | else { 176 | lcd.print(distance); 177 | lcd.print(" cm "); 178 | } 179 | 180 | lcd.setCursor(0, 1); 181 | if (distance > WARNING_DISTANCE) { 182 | lcd.print("No obstacle. "); 183 | } 184 | else { 185 | lcd.print("!! Warning !! "); 186 | } 187 | } 188 | } 189 | 190 | void toggleDistanceUnit() 191 | { 192 | if (distanceUnit == DISTANCE_UNIT_CM) { 193 | distanceUnit = DISTANCE_UNIT_IN; 194 | } 195 | else { 196 | distanceUnit = DISTANCE_UNIT_CM; 197 | } 198 | EEPROM.write(EEPROM_ADDRESS_DISTANCE_UNIT, distanceUnit); 199 | } 200 | 201 | void toggleLCDScreen(bool next) 202 | { 203 | switch (lcdMode) { 204 | case LCD_MODE_DISTANCE: { 205 | lcdMode = (next) ? LCD_MODE_SETTINGS : LCD_MODE_LUMINOSITY; 206 | break; 207 | } 208 | case LCD_MODE_SETTINGS: { 209 | lcdMode = (next) ? LCD_MODE_LUMINOSITY : LCD_MODE_DISTANCE; 210 | break; 211 | } 212 | case LCD_MODE_LUMINOSITY: { 213 | lcdMode = (next) ? LCD_MODE_DISTANCE : LCD_MODE_SETTINGS; 214 | break; 215 | } 216 | default: { 217 | lcdMode = LCD_MODE_DISTANCE; 218 | } 219 | } 220 | 221 | lcd.clear(); 222 | 223 | if (lcdMode == LCD_MODE_SETTINGS) { 224 | lcd.setCursor(0, 0); 225 | lcd.print("Press on OFF to"); 226 | lcd.setCursor(0, 1); 227 | lcd.print("reset settings."); 228 | } 229 | } 230 | 231 | void resetSettingsToDefault() 232 | { 233 | if (lcdMode == LCD_MODE_SETTINGS) { 234 | distanceUnit = DISTANCE_UNIT_CM; 235 | EEPROM.write(EEPROM_ADDRESS_DISTANCE_UNIT, distanceUnit); 236 | lcd.clear(); 237 | lcd.setCursor(0, 0); 238 | lcd.print("Settings have"); 239 | lcd.setCursor(0, 1); 240 | lcd.print("been reset."); 241 | } 242 | } 243 | 244 | void handleIRCommand(long command) 245 | { 246 | switch (command) { 247 | case IR_BUTTON_PLAY: { 248 | unlock(); 249 | break; 250 | } 251 | case IR_BUTTON_OFF: { 252 | resetSettingsToDefault(); 253 | break; 254 | } 255 | case IR_BUTTON_EQ: { 256 | toggleDistanceUnit(); 257 | break; 258 | } 259 | case IR_BUTTON_UP: { 260 | toggleLCDScreen(true); 261 | break; 262 | } 263 | case IR_BUTTON_DOWN: { 264 | toggleLCDScreen(false); 265 | break; 266 | } 267 | default: { 268 | // do nothing 269 | } 270 | } 271 | } 272 | 273 | void setLightLEDFromLuminosity(int luminosity) 274 | { 275 | byte brightness = 255 - luminosity / 4; 276 | analogWrite(LIGHT_LED_PIN, brightness); 277 | } 278 | 279 | void printLuminosityOnLCD(int luminosity) 280 | { 281 | if (!isLocked && lcdMode == LCD_MODE_LUMINOSITY) { 282 | lcd.setCursor(0, 0); 283 | lcd.print("Luminosity: "); 284 | lcd.print(luminosity); 285 | lcd.print(" "); 286 | } 287 | } 288 | 289 | void setup() { 290 | Serial.begin(115200); 291 | lcd.begin(16,2); 292 | irrecv.enableIRIn(); 293 | pinMode(ECHO_PIN, INPUT); 294 | pinMode(TRIGGER_PIN, OUTPUT); 295 | pinMode(WARNING_LED_PIN, OUTPUT); 296 | pinMode(ERROR_LED_PIN, OUTPUT); 297 | pinMode(LIGHT_LED_PIN, OUTPUT); 298 | pinMode(BUTTON_PIN, INPUT); 299 | 300 | buttonState = digitalRead(BUTTON_PIN); 301 | 302 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 303 | echoPinInterrupt, 304 | CHANGE); 305 | 306 | distanceUnit = EEPROM.read(EEPROM_ADDRESS_DISTANCE_UNIT); 307 | if (distanceUnit == 255) { 308 | distanceUnit = DISTANCE_UNIT_CM; 309 | } 310 | 311 | lcd.print("Initializing..."); 312 | delay(1000); 313 | lcd.clear(); 314 | } 315 | 316 | void loop() { 317 | unsigned long timeNow = millis(); 318 | 319 | if (isLocked) { 320 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 321 | lastTimeErrorLEDBlinked += errorLEDDelay; 322 | toggleErrorLED(); 323 | toggleWarningLED(); 324 | } 325 | 326 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 327 | byte newButtonState = digitalRead(BUTTON_PIN); 328 | if (newButtonState != buttonState) { 329 | lastTimeButtonChanged = timeNow; 330 | buttonState = newButtonState; 331 | if (buttonState == LOW) { // released 332 | unlock(); 333 | } 334 | } 335 | } 336 | } 337 | else { 338 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 339 | lastTimeWarningLEDBlinked += warningLEDDelay; 340 | toggleWarningLED(); 341 | } 342 | } 343 | 344 | if (irrecv.decode(&results)) { 345 | irrecv.resume(); 346 | long command = results.value; 347 | handleIRCommand(command); 348 | // Serial.println(command); 349 | } 350 | 351 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 352 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 353 | triggerUltrasonicSensor(); 354 | } 355 | 356 | if (newDistanceAvailable) { 357 | newDistanceAvailable = false; 358 | double distance = getUltrasonicDistance(); 359 | setWarningLEDBlinkRateFromDistance(distance); 360 | printDistanceOnLCD(distance); 361 | if (distance < LOCK_DISTANCE) { 362 | lock(); 363 | } 364 | // Serial.println(distance); 365 | } 366 | 367 | if (timeNow - lastTimeReadLuminosity > readLuminosityDelay) { 368 | lastTimeReadLuminosity += readLuminosityDelay; 369 | int luminosity = analogRead(PHOTORESISTOR_PIN); 370 | setLightLEDFromLuminosity(luminosity); 371 | printLuminosityOnLCD(luminosity); 372 | } 373 | } 374 | -------------------------------------------------------------------------------- /final_project/final_project_step2/final_project_step2.ino: -------------------------------------------------------------------------------- 1 | #define ECHO_PIN 3 2 | #define TRIGGER_PIN 4 3 | 4 | #define WARNING_LED_PIN 11 5 | 6 | // ultrasonic 7 | unsigned long lastTimeUltrasonicTrigger = millis(); 8 | unsigned long ultrasonicTriggerDelay = 60; 9 | 10 | volatile unsigned long pulseInTimeBegin; 11 | volatile unsigned long pulseInTimeEnd; 12 | volatile bool newDistanceAvailable = false; 13 | 14 | double previousDistance = 400.0; 15 | 16 | // warning LED 17 | unsigned long lastTimeWarningLEDBlinked = millis(); 18 | unsigned long warningLEDDelay = 500; 19 | byte warningLEDState = LOW; 20 | 21 | void triggerUltrasonicSensor() 22 | { 23 | digitalWrite(TRIGGER_PIN, LOW); 24 | delayMicroseconds(2); 25 | digitalWrite(TRIGGER_PIN, HIGH); 26 | delayMicroseconds(10); 27 | digitalWrite(TRIGGER_PIN, LOW); 28 | } 29 | 30 | double getUltrasonicDistance() 31 | { 32 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 33 | double distance = durationMicros / 58.0; 34 | if (distance > 400.0) { 35 | return previousDistance; 36 | } 37 | distance = previousDistance * 0.6 + distance * 0.4; 38 | previousDistance = distance; 39 | return distance; 40 | } 41 | 42 | void echoPinInterrupt() 43 | { 44 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 45 | pulseInTimeBegin = micros(); 46 | } 47 | else { // pulse stoped 48 | pulseInTimeEnd = micros(); 49 | newDistanceAvailable = true; 50 | } 51 | } 52 | 53 | void toggleWarningLED() 54 | { 55 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 56 | digitalWrite(WARNING_LED_PIN, warningLEDState); 57 | } 58 | 59 | void setWarningLEDBlinkRateFromDistance(double distance) 60 | { 61 | // 0 .. 400 cm -> 0 .. 1600 ms 62 | warningLEDDelay = distance * 4; 63 | Serial.println(warningLEDDelay); 64 | } 65 | 66 | void setup() { 67 | Serial.begin(115200); 68 | pinMode(ECHO_PIN, INPUT); 69 | pinMode(TRIGGER_PIN, OUTPUT); 70 | pinMode(WARNING_LED_PIN, OUTPUT); 71 | 72 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 73 | echoPinInterrupt, 74 | CHANGE); 75 | } 76 | 77 | void loop() { 78 | unsigned long timeNow = millis(); 79 | 80 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 81 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 82 | triggerUltrasonicSensor(); 83 | } 84 | 85 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 86 | lastTimeWarningLEDBlinked += warningLEDDelay; 87 | toggleWarningLED(); 88 | } 89 | 90 | if (newDistanceAvailable) { 91 | newDistanceAvailable = false; 92 | double distance = getUltrasonicDistance(); 93 | setWarningLEDBlinkRateFromDistance(distance); 94 | // Serial.println(distance); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /final_project/final_project_step3/final_project_step3.ino: -------------------------------------------------------------------------------- 1 | #define ECHO_PIN 3 2 | #define TRIGGER_PIN 4 3 | 4 | #define WARNING_LED_PIN 11 5 | #define ERROR_LED_PIN 12 6 | 7 | #define LOCK_DISTANCE 10.0 8 | 9 | // ultrasonic 10 | unsigned long lastTimeUltrasonicTrigger = millis(); 11 | unsigned long ultrasonicTriggerDelay = 60; 12 | 13 | volatile unsigned long pulseInTimeBegin; 14 | volatile unsigned long pulseInTimeEnd; 15 | volatile bool newDistanceAvailable = false; 16 | 17 | double previousDistance = 400.0; 18 | 19 | // warning LED 20 | unsigned long lastTimeWarningLEDBlinked = millis(); 21 | unsigned long warningLEDDelay = 500; 22 | byte warningLEDState = LOW; 23 | 24 | // error LED 25 | unsigned long lastTimeErrorLEDBlinked = millis(); 26 | unsigned long errorLEDDelay = 300; 27 | byte errorLEDState = LOW; 28 | 29 | bool isLocked = false; 30 | 31 | void triggerUltrasonicSensor() 32 | { 33 | digitalWrite(TRIGGER_PIN, LOW); 34 | delayMicroseconds(2); 35 | digitalWrite(TRIGGER_PIN, HIGH); 36 | delayMicroseconds(10); 37 | digitalWrite(TRIGGER_PIN, LOW); 38 | } 39 | 40 | double getUltrasonicDistance() 41 | { 42 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 43 | double distance = durationMicros / 58.0; 44 | if (distance > 400.0) { 45 | return previousDistance; 46 | } 47 | distance = previousDistance * 0.6 + distance * 0.4; 48 | previousDistance = distance; 49 | return distance; 50 | } 51 | 52 | void echoPinInterrupt() 53 | { 54 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 55 | pulseInTimeBegin = micros(); 56 | } 57 | else { // pulse stoped 58 | pulseInTimeEnd = micros(); 59 | newDistanceAvailable = true; 60 | } 61 | } 62 | 63 | void toggleErrorLED() 64 | { 65 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 66 | digitalWrite(ERROR_LED_PIN, errorLEDState); 67 | } 68 | 69 | void toggleWarningLED() 70 | { 71 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 72 | digitalWrite(WARNING_LED_PIN, warningLEDState); 73 | } 74 | 75 | void setWarningLEDBlinkRateFromDistance(double distance) 76 | { 77 | // 0 .. 400 cm -> 0 .. 1600 ms 78 | warningLEDDelay = distance * 4; 79 | Serial.println(warningLEDDelay); 80 | } 81 | 82 | void lock() 83 | { 84 | if (!isLocked) { 85 | isLocked = true; 86 | warningLEDState = LOW; 87 | errorLEDState = LOW; 88 | } 89 | } 90 | 91 | void setup() { 92 | Serial.begin(115200); 93 | pinMode(ECHO_PIN, INPUT); 94 | pinMode(TRIGGER_PIN, OUTPUT); 95 | pinMode(WARNING_LED_PIN, OUTPUT); 96 | pinMode(ERROR_LED_PIN, OUTPUT); 97 | 98 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 99 | echoPinInterrupt, 100 | CHANGE); 101 | } 102 | 103 | void loop() { 104 | unsigned long timeNow = millis(); 105 | 106 | if (isLocked) { 107 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 108 | lastTimeErrorLEDBlinked += errorLEDDelay; 109 | toggleErrorLED(); 110 | toggleWarningLED(); 111 | } 112 | } 113 | else { 114 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 115 | lastTimeWarningLEDBlinked += warningLEDDelay; 116 | toggleWarningLED(); 117 | } 118 | } 119 | 120 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 121 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 122 | triggerUltrasonicSensor(); 123 | } 124 | 125 | if (newDistanceAvailable) { 126 | newDistanceAvailable = false; 127 | double distance = getUltrasonicDistance(); 128 | setWarningLEDBlinkRateFromDistance(distance); 129 | if (distance < LOCK_DISTANCE) { 130 | lock(); 131 | } 132 | // Serial.println(distance); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /final_project/final_project_step4/final_project_step4.ino: -------------------------------------------------------------------------------- 1 | #define ECHO_PIN 3 2 | #define TRIGGER_PIN 4 3 | 4 | #define WARNING_LED_PIN 11 5 | #define ERROR_LED_PIN 12 6 | 7 | #define BUTTON_PIN 2 8 | 9 | #define LOCK_DISTANCE 10.0 10 | 11 | // ultrasonic 12 | unsigned long lastTimeUltrasonicTrigger = millis(); 13 | unsigned long ultrasonicTriggerDelay = 60; 14 | 15 | volatile unsigned long pulseInTimeBegin; 16 | volatile unsigned long pulseInTimeEnd; 17 | volatile bool newDistanceAvailable = false; 18 | 19 | double previousDistance = 400.0; 20 | 21 | // warning LED 22 | unsigned long lastTimeWarningLEDBlinked = millis(); 23 | unsigned long warningLEDDelay = 500; 24 | byte warningLEDState = LOW; 25 | 26 | // error LED 27 | unsigned long lastTimeErrorLEDBlinked = millis(); 28 | unsigned long errorLEDDelay = 300; 29 | byte errorLEDState = LOW; 30 | 31 | // push button 32 | unsigned long lastTimeButtonChanged = millis(); 33 | unsigned long buttonDebounceDelay = 50; 34 | byte buttonState; 35 | 36 | bool isLocked = false; 37 | 38 | void triggerUltrasonicSensor() 39 | { 40 | digitalWrite(TRIGGER_PIN, LOW); 41 | delayMicroseconds(2); 42 | digitalWrite(TRIGGER_PIN, HIGH); 43 | delayMicroseconds(10); 44 | digitalWrite(TRIGGER_PIN, LOW); 45 | } 46 | 47 | double getUltrasonicDistance() 48 | { 49 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 50 | double distance = durationMicros / 58.0; 51 | if (distance > 400.0) { 52 | return previousDistance; 53 | } 54 | distance = previousDistance * 0.6 + distance * 0.4; 55 | previousDistance = distance; 56 | return distance; 57 | } 58 | 59 | void echoPinInterrupt() 60 | { 61 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 62 | pulseInTimeBegin = micros(); 63 | } 64 | else { // pulse stoped 65 | pulseInTimeEnd = micros(); 66 | newDistanceAvailable = true; 67 | } 68 | } 69 | 70 | void toggleErrorLED() 71 | { 72 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 73 | digitalWrite(ERROR_LED_PIN, errorLEDState); 74 | } 75 | 76 | void toggleWarningLED() 77 | { 78 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 79 | digitalWrite(WARNING_LED_PIN, warningLEDState); 80 | } 81 | 82 | void setWarningLEDBlinkRateFromDistance(double distance) 83 | { 84 | // 0 .. 400 cm -> 0 .. 1600 ms 85 | warningLEDDelay = distance * 4; 86 | // Serial.println(warningLEDDelay); 87 | } 88 | 89 | void lock() 90 | { 91 | if (!isLocked) { 92 | // Serial.println("Locking"); 93 | isLocked = true; 94 | warningLEDState = LOW; 95 | errorLEDState = LOW; 96 | } 97 | } 98 | 99 | void unlock() 100 | { 101 | if (isLocked) { 102 | // Serial.println("Unlocking"); 103 | isLocked = false; 104 | errorLEDState = LOW; 105 | digitalWrite(ERROR_LED_PIN, errorLEDState); 106 | } 107 | } 108 | 109 | void setup() { 110 | Serial.begin(115200); 111 | pinMode(ECHO_PIN, INPUT); 112 | pinMode(TRIGGER_PIN, OUTPUT); 113 | pinMode(WARNING_LED_PIN, OUTPUT); 114 | pinMode(ERROR_LED_PIN, OUTPUT); 115 | pinMode(BUTTON_PIN, INPUT); 116 | 117 | buttonState = digitalRead(BUTTON_PIN); 118 | 119 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 120 | echoPinInterrupt, 121 | CHANGE); 122 | } 123 | 124 | void loop() { 125 | unsigned long timeNow = millis(); 126 | 127 | if (isLocked) { 128 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 129 | lastTimeErrorLEDBlinked += errorLEDDelay; 130 | toggleErrorLED(); 131 | toggleWarningLED(); 132 | } 133 | 134 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 135 | byte newButtonState = digitalRead(BUTTON_PIN); 136 | if (newButtonState != buttonState) { 137 | lastTimeButtonChanged = timeNow; 138 | buttonState = newButtonState; 139 | if (buttonState == LOW) { // released 140 | unlock(); 141 | } 142 | } 143 | } 144 | } 145 | else { 146 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 147 | lastTimeWarningLEDBlinked += warningLEDDelay; 148 | toggleWarningLED(); 149 | } 150 | } 151 | 152 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 153 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 154 | triggerUltrasonicSensor(); 155 | } 156 | 157 | if (newDistanceAvailable) { 158 | newDistanceAvailable = false; 159 | double distance = getUltrasonicDistance(); 160 | setWarningLEDBlinkRateFromDistance(distance); 161 | if (distance < LOCK_DISTANCE) { 162 | lock(); 163 | } 164 | // Serial.println(distance); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /final_project/final_project_step5/final_project_step5.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ECHO_PIN 3 4 | #define TRIGGER_PIN 4 5 | 6 | #define WARNING_LED_PIN 11 7 | #define ERROR_LED_PIN 12 8 | 9 | #define BUTTON_PIN 2 10 | 11 | #define LCD_RS_PIN A5 12 | #define LCD_E_PIN A4 13 | #define LCD_D4_PIN 6 14 | #define LCD_D5_PIN 7 15 | #define LCD_D6_PIN 8 16 | #define LCD_D7_PIN 9 17 | 18 | #define LOCK_DISTANCE 10.0 19 | 20 | // lcd 21 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 22 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 23 | 24 | // ultrasonic 25 | unsigned long lastTimeUltrasonicTrigger = millis(); 26 | unsigned long ultrasonicTriggerDelay = 60; 27 | 28 | volatile unsigned long pulseInTimeBegin; 29 | volatile unsigned long pulseInTimeEnd; 30 | volatile bool newDistanceAvailable = false; 31 | 32 | double previousDistance = 400.0; 33 | 34 | // warning LED 35 | unsigned long lastTimeWarningLEDBlinked = millis(); 36 | unsigned long warningLEDDelay = 500; 37 | byte warningLEDState = LOW; 38 | 39 | // error LED 40 | unsigned long lastTimeErrorLEDBlinked = millis(); 41 | unsigned long errorLEDDelay = 300; 42 | byte errorLEDState = LOW; 43 | 44 | // push button 45 | unsigned long lastTimeButtonChanged = millis(); 46 | unsigned long buttonDebounceDelay = 50; 47 | byte buttonState; 48 | 49 | bool isLocked = false; 50 | 51 | void triggerUltrasonicSensor() 52 | { 53 | digitalWrite(TRIGGER_PIN, LOW); 54 | delayMicroseconds(2); 55 | digitalWrite(TRIGGER_PIN, HIGH); 56 | delayMicroseconds(10); 57 | digitalWrite(TRIGGER_PIN, LOW); 58 | } 59 | 60 | double getUltrasonicDistance() 61 | { 62 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 63 | double distance = durationMicros / 58.0; 64 | if (distance > 400.0) { 65 | return previousDistance; 66 | } 67 | distance = previousDistance * 0.6 + distance * 0.4; 68 | previousDistance = distance; 69 | return distance; 70 | } 71 | 72 | void echoPinInterrupt() 73 | { 74 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 75 | pulseInTimeBegin = micros(); 76 | } 77 | else { // pulse stoped 78 | pulseInTimeEnd = micros(); 79 | newDistanceAvailable = true; 80 | } 81 | } 82 | 83 | void toggleErrorLED() 84 | { 85 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 86 | digitalWrite(ERROR_LED_PIN, errorLEDState); 87 | } 88 | 89 | void toggleWarningLED() 90 | { 91 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 92 | digitalWrite(WARNING_LED_PIN, warningLEDState); 93 | } 94 | 95 | void setWarningLEDBlinkRateFromDistance(double distance) 96 | { 97 | // 0 .. 400 cm -> 0 .. 1600 ms 98 | warningLEDDelay = distance * 4; 99 | // Serial.println(warningLEDDelay); 100 | } 101 | 102 | void lock() 103 | { 104 | if (!isLocked) { 105 | // Serial.println("Locking"); 106 | isLocked = true; 107 | warningLEDState = LOW; 108 | errorLEDState = LOW; 109 | } 110 | } 111 | 112 | void unlock() 113 | { 114 | if (isLocked) { 115 | // Serial.println("Unlocking"); 116 | isLocked = false; 117 | errorLEDState = LOW; 118 | digitalWrite(ERROR_LED_PIN, errorLEDState); 119 | } 120 | } 121 | 122 | void setup() { 123 | Serial.begin(115200); 124 | lcd.begin(16,2); 125 | pinMode(ECHO_PIN, INPUT); 126 | pinMode(TRIGGER_PIN, OUTPUT); 127 | pinMode(WARNING_LED_PIN, OUTPUT); 128 | pinMode(ERROR_LED_PIN, OUTPUT); 129 | pinMode(BUTTON_PIN, INPUT); 130 | 131 | buttonState = digitalRead(BUTTON_PIN); 132 | 133 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 134 | echoPinInterrupt, 135 | CHANGE); 136 | 137 | lcd.print("Initializing..."); 138 | delay(1000); 139 | lcd.clear(); 140 | } 141 | 142 | void loop() { 143 | unsigned long timeNow = millis(); 144 | 145 | if (isLocked) { 146 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 147 | lastTimeErrorLEDBlinked += errorLEDDelay; 148 | toggleErrorLED(); 149 | toggleWarningLED(); 150 | } 151 | 152 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 153 | byte newButtonState = digitalRead(BUTTON_PIN); 154 | if (newButtonState != buttonState) { 155 | lastTimeButtonChanged = timeNow; 156 | buttonState = newButtonState; 157 | if (buttonState == LOW) { // released 158 | unlock(); 159 | } 160 | } 161 | } 162 | } 163 | else { 164 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 165 | lastTimeWarningLEDBlinked += warningLEDDelay; 166 | toggleWarningLED(); 167 | } 168 | } 169 | 170 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 171 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 172 | triggerUltrasonicSensor(); 173 | } 174 | 175 | if (newDistanceAvailable) { 176 | newDistanceAvailable = false; 177 | double distance = getUltrasonicDistance(); 178 | setWarningLEDBlinkRateFromDistance(distance); 179 | if (distance < LOCK_DISTANCE) { 180 | lock(); 181 | } 182 | // Serial.println(distance); 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /final_project/final_project_step6/final_project_step6.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ECHO_PIN 3 4 | #define TRIGGER_PIN 4 5 | 6 | #define WARNING_LED_PIN 11 7 | #define ERROR_LED_PIN 12 8 | 9 | #define BUTTON_PIN 2 10 | 11 | #define LCD_RS_PIN A5 12 | #define LCD_E_PIN A4 13 | #define LCD_D4_PIN 6 14 | #define LCD_D5_PIN 7 15 | #define LCD_D6_PIN 8 16 | #define LCD_D7_PIN 9 17 | 18 | #define LOCK_DISTANCE 10.0 19 | #define WARNING_DISTANCE 50.0 20 | 21 | // lcd 22 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 23 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 24 | 25 | // ultrasonic 26 | unsigned long lastTimeUltrasonicTrigger = millis(); 27 | unsigned long ultrasonicTriggerDelay = 60; 28 | 29 | volatile unsigned long pulseInTimeBegin; 30 | volatile unsigned long pulseInTimeEnd; 31 | volatile bool newDistanceAvailable = false; 32 | 33 | double previousDistance = 400.0; 34 | 35 | // warning LED 36 | unsigned long lastTimeWarningLEDBlinked = millis(); 37 | unsigned long warningLEDDelay = 500; 38 | byte warningLEDState = LOW; 39 | 40 | // error LED 41 | unsigned long lastTimeErrorLEDBlinked = millis(); 42 | unsigned long errorLEDDelay = 300; 43 | byte errorLEDState = LOW; 44 | 45 | // push button 46 | unsigned long lastTimeButtonChanged = millis(); 47 | unsigned long buttonDebounceDelay = 50; 48 | byte buttonState; 49 | 50 | bool isLocked = false; 51 | 52 | void triggerUltrasonicSensor() 53 | { 54 | digitalWrite(TRIGGER_PIN, LOW); 55 | delayMicroseconds(2); 56 | digitalWrite(TRIGGER_PIN, HIGH); 57 | delayMicroseconds(10); 58 | digitalWrite(TRIGGER_PIN, LOW); 59 | } 60 | 61 | double getUltrasonicDistance() 62 | { 63 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 64 | double distance = durationMicros / 58.0; 65 | if (distance > 400.0) { 66 | return previousDistance; 67 | } 68 | distance = previousDistance * 0.6 + distance * 0.4; 69 | previousDistance = distance; 70 | return distance; 71 | } 72 | 73 | void echoPinInterrupt() 74 | { 75 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 76 | pulseInTimeBegin = micros(); 77 | } 78 | else { // pulse stoped 79 | pulseInTimeEnd = micros(); 80 | newDistanceAvailable = true; 81 | } 82 | } 83 | 84 | void toggleErrorLED() 85 | { 86 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 87 | digitalWrite(ERROR_LED_PIN, errorLEDState); 88 | } 89 | 90 | void toggleWarningLED() 91 | { 92 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 93 | digitalWrite(WARNING_LED_PIN, warningLEDState); 94 | } 95 | 96 | void setWarningLEDBlinkRateFromDistance(double distance) 97 | { 98 | // 0 .. 400 cm -> 0 .. 1600 ms 99 | warningLEDDelay = distance * 4; 100 | // Serial.println(warningLEDDelay); 101 | } 102 | 103 | void lock() 104 | { 105 | if (!isLocked) { 106 | // Serial.println("Locking"); 107 | isLocked = true; 108 | warningLEDState = LOW; 109 | errorLEDState = LOW; 110 | } 111 | } 112 | 113 | void unlock() 114 | { 115 | if (isLocked) { 116 | // Serial.println("Unlocking"); 117 | isLocked = false; 118 | errorLEDState = LOW; 119 | digitalWrite(ERROR_LED_PIN, errorLEDState); 120 | } 121 | } 122 | 123 | void printDistanceOnLCD(double distance) 124 | { 125 | if (isLocked) { 126 | lcd.setCursor(0, 0); 127 | lcd.print("!!! Obstacle !!! "); 128 | lcd.setCursor(0, 1); 129 | lcd.print("Press to unlock. "); 130 | } 131 | else { 132 | lcd.setCursor(0, 0); 133 | lcd.print("Dist: "); 134 | lcd.print(distance); 135 | lcd.print(" cm "); 136 | 137 | lcd.setCursor(0, 1); 138 | if (distance > WARNING_DISTANCE) { 139 | lcd.print("No obstacle. "); 140 | } 141 | else { 142 | lcd.print("!! Warning !! "); 143 | } 144 | } 145 | } 146 | 147 | void setup() { 148 | Serial.begin(115200); 149 | lcd.begin(16,2); 150 | pinMode(ECHO_PIN, INPUT); 151 | pinMode(TRIGGER_PIN, OUTPUT); 152 | pinMode(WARNING_LED_PIN, OUTPUT); 153 | pinMode(ERROR_LED_PIN, OUTPUT); 154 | pinMode(BUTTON_PIN, INPUT); 155 | 156 | buttonState = digitalRead(BUTTON_PIN); 157 | 158 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 159 | echoPinInterrupt, 160 | CHANGE); 161 | 162 | lcd.print("Initializing..."); 163 | delay(1000); 164 | lcd.clear(); 165 | } 166 | 167 | void loop() { 168 | unsigned long timeNow = millis(); 169 | 170 | if (isLocked) { 171 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 172 | lastTimeErrorLEDBlinked += errorLEDDelay; 173 | toggleErrorLED(); 174 | toggleWarningLED(); 175 | } 176 | 177 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 178 | byte newButtonState = digitalRead(BUTTON_PIN); 179 | if (newButtonState != buttonState) { 180 | lastTimeButtonChanged = timeNow; 181 | buttonState = newButtonState; 182 | if (buttonState == LOW) { // released 183 | unlock(); 184 | } 185 | } 186 | } 187 | } 188 | else { 189 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 190 | lastTimeWarningLEDBlinked += warningLEDDelay; 191 | toggleWarningLED(); 192 | } 193 | } 194 | 195 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 196 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 197 | triggerUltrasonicSensor(); 198 | } 199 | 200 | if (newDistanceAvailable) { 201 | newDistanceAvailable = false; 202 | double distance = getUltrasonicDistance(); 203 | setWarningLEDBlinkRateFromDistance(distance); 204 | printDistanceOnLCD(distance); 205 | if (distance < LOCK_DISTANCE) { 206 | lock(); 207 | } 208 | // Serial.println(distance); 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /final_project/final_project_step7/final_project_step7.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define IR_RECEIVE_PIN 5 5 | 6 | #define ECHO_PIN 3 7 | #define TRIGGER_PIN 4 8 | 9 | #define WARNING_LED_PIN 11 10 | #define ERROR_LED_PIN 12 11 | 12 | #define BUTTON_PIN 2 13 | 14 | #define LCD_RS_PIN A5 15 | #define LCD_E_PIN A4 16 | #define LCD_D4_PIN 6 17 | #define LCD_D5_PIN 7 18 | #define LCD_D6_PIN 8 19 | #define LCD_D7_PIN 9 20 | 21 | #define LOCK_DISTANCE 10.0 22 | #define WARNING_DISTANCE 50.0 23 | 24 | // IR button mapping 25 | #define IR_BUTTON_PLAY 64 26 | #define IR_BUTTON_OFF 69 27 | #define IR_BUTTON_EQ 25 28 | #define IR_BUTTON_UP 9 29 | #define IR_BUTTON_DOWN 7 30 | 31 | // lcd 32 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 33 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 34 | 35 | // ultrasonic 36 | unsigned long lastTimeUltrasonicTrigger = millis(); 37 | unsigned long ultrasonicTriggerDelay = 60; 38 | 39 | volatile unsigned long pulseInTimeBegin; 40 | volatile unsigned long pulseInTimeEnd; 41 | volatile bool newDistanceAvailable = false; 42 | 43 | double previousDistance = 400.0; 44 | 45 | // warning LED 46 | unsigned long lastTimeWarningLEDBlinked = millis(); 47 | unsigned long warningLEDDelay = 500; 48 | byte warningLEDState = LOW; 49 | 50 | // error LED 51 | unsigned long lastTimeErrorLEDBlinked = millis(); 52 | unsigned long errorLEDDelay = 300; 53 | byte errorLEDState = LOW; 54 | 55 | // push button 56 | unsigned long lastTimeButtonChanged = millis(); 57 | unsigned long buttonDebounceDelay = 50; 58 | byte buttonState; 59 | 60 | bool isLocked = false; 61 | 62 | void triggerUltrasonicSensor() 63 | { 64 | digitalWrite(TRIGGER_PIN, LOW); 65 | delayMicroseconds(2); 66 | digitalWrite(TRIGGER_PIN, HIGH); 67 | delayMicroseconds(10); 68 | digitalWrite(TRIGGER_PIN, LOW); 69 | } 70 | 71 | double getUltrasonicDistance() 72 | { 73 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 74 | double distance = durationMicros / 58.0; 75 | if (distance > 400.0) { 76 | return previousDistance; 77 | } 78 | distance = previousDistance * 0.6 + distance * 0.4; 79 | previousDistance = distance; 80 | return distance; 81 | } 82 | 83 | void echoPinInterrupt() 84 | { 85 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 86 | pulseInTimeBegin = micros(); 87 | } 88 | else { // pulse stoped 89 | pulseInTimeEnd = micros(); 90 | newDistanceAvailable = true; 91 | } 92 | } 93 | 94 | void toggleErrorLED() 95 | { 96 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 97 | digitalWrite(ERROR_LED_PIN, errorLEDState); 98 | } 99 | 100 | void toggleWarningLED() 101 | { 102 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 103 | digitalWrite(WARNING_LED_PIN, warningLEDState); 104 | } 105 | 106 | void setWarningLEDBlinkRateFromDistance(double distance) 107 | { 108 | // 0 .. 400 cm -> 0 .. 1600 ms 109 | warningLEDDelay = distance * 4; 110 | // Serial.println(warningLEDDelay); 111 | } 112 | 113 | void lock() 114 | { 115 | if (!isLocked) { 116 | // Serial.println("Locking"); 117 | isLocked = true; 118 | warningLEDState = LOW; 119 | errorLEDState = LOW; 120 | } 121 | } 122 | 123 | void unlock() 124 | { 125 | if (isLocked) { 126 | // Serial.println("Unlocking"); 127 | isLocked = false; 128 | errorLEDState = LOW; 129 | digitalWrite(ERROR_LED_PIN, errorLEDState); 130 | } 131 | } 132 | 133 | void printDistanceOnLCD(double distance) 134 | { 135 | if (isLocked) { 136 | lcd.setCursor(0, 0); 137 | lcd.print("!!! Obstacle !!! "); 138 | lcd.setCursor(0, 1); 139 | lcd.print("Press to unlock. "); 140 | } 141 | else { 142 | lcd.setCursor(0, 0); 143 | lcd.print("Dist: "); 144 | lcd.print(distance); 145 | lcd.print(" cm "); 146 | 147 | lcd.setCursor(0, 1); 148 | if (distance > WARNING_DISTANCE) { 149 | lcd.print("No obstacle. "); 150 | } 151 | else { 152 | lcd.print("!! Warning !! "); 153 | } 154 | } 155 | } 156 | 157 | void setup() { 158 | Serial.begin(115200); 159 | lcd.begin(16,2); 160 | IrReceiver.begin(IR_RECEIVE_PIN); 161 | pinMode(ECHO_PIN, INPUT); 162 | pinMode(TRIGGER_PIN, OUTPUT); 163 | pinMode(WARNING_LED_PIN, OUTPUT); 164 | pinMode(ERROR_LED_PIN, OUTPUT); 165 | pinMode(BUTTON_PIN, INPUT); 166 | 167 | buttonState = digitalRead(BUTTON_PIN); 168 | 169 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 170 | echoPinInterrupt, 171 | CHANGE); 172 | 173 | lcd.print("Initializing..."); 174 | delay(1000); 175 | lcd.clear(); 176 | } 177 | 178 | void loop() { 179 | unsigned long timeNow = millis(); 180 | 181 | if (isLocked) { 182 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 183 | lastTimeErrorLEDBlinked += errorLEDDelay; 184 | toggleErrorLED(); 185 | toggleWarningLED(); 186 | } 187 | 188 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 189 | byte newButtonState = digitalRead(BUTTON_PIN); 190 | if (newButtonState != buttonState) { 191 | lastTimeButtonChanged = timeNow; 192 | buttonState = newButtonState; 193 | if (buttonState == LOW) { // released 194 | unlock(); 195 | } 196 | } 197 | } 198 | } 199 | else { 200 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 201 | lastTimeWarningLEDBlinked += warningLEDDelay; 202 | toggleWarningLED(); 203 | } 204 | } 205 | 206 | if (IrReceiver.decode()) { 207 | IrReceiver.resume(); 208 | long command = IrReceiver.decodedIRData.command; 209 | Serial.println(command); 210 | } 211 | 212 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 213 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 214 | triggerUltrasonicSensor(); 215 | } 216 | 217 | if (newDistanceAvailable) { 218 | newDistanceAvailable = false; 219 | double distance = getUltrasonicDistance(); 220 | setWarningLEDBlinkRateFromDistance(distance); 221 | printDistanceOnLCD(distance); 222 | if (distance < LOCK_DISTANCE) { 223 | lock(); 224 | } 225 | // Serial.println(distance); 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /final_project/final_project_step8/final_project_step8.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define IR_RECEIVE_PIN 5 5 | 6 | #define ECHO_PIN 3 7 | #define TRIGGER_PIN 4 8 | 9 | #define WARNING_LED_PIN 11 10 | #define ERROR_LED_PIN 12 11 | 12 | #define BUTTON_PIN 2 13 | 14 | #define LCD_RS_PIN A5 15 | #define LCD_E_PIN A4 16 | #define LCD_D4_PIN 6 17 | #define LCD_D5_PIN 7 18 | #define LCD_D6_PIN 8 19 | #define LCD_D7_PIN 9 20 | 21 | #define LOCK_DISTANCE 10.0 22 | #define WARNING_DISTANCE 50.0 23 | 24 | // IR button mapping 25 | #define IR_BUTTON_PLAY 64 26 | #define IR_BUTTON_OFF 69 27 | #define IR_BUTTON_EQ 25 28 | #define IR_BUTTON_UP 9 29 | #define IR_BUTTON_DOWN 7 30 | 31 | // lcd 32 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 33 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 34 | 35 | // ultrasonic 36 | unsigned long lastTimeUltrasonicTrigger = millis(); 37 | unsigned long ultrasonicTriggerDelay = 60; 38 | 39 | volatile unsigned long pulseInTimeBegin; 40 | volatile unsigned long pulseInTimeEnd; 41 | volatile bool newDistanceAvailable = false; 42 | 43 | double previousDistance = 400.0; 44 | 45 | // warning LED 46 | unsigned long lastTimeWarningLEDBlinked = millis(); 47 | unsigned long warningLEDDelay = 500; 48 | byte warningLEDState = LOW; 49 | 50 | // error LED 51 | unsigned long lastTimeErrorLEDBlinked = millis(); 52 | unsigned long errorLEDDelay = 300; 53 | byte errorLEDState = LOW; 54 | 55 | // push button 56 | unsigned long lastTimeButtonChanged = millis(); 57 | unsigned long buttonDebounceDelay = 50; 58 | byte buttonState; 59 | 60 | bool isLocked = false; 61 | 62 | void triggerUltrasonicSensor() 63 | { 64 | digitalWrite(TRIGGER_PIN, LOW); 65 | delayMicroseconds(2); 66 | digitalWrite(TRIGGER_PIN, HIGH); 67 | delayMicroseconds(10); 68 | digitalWrite(TRIGGER_PIN, LOW); 69 | } 70 | 71 | double getUltrasonicDistance() 72 | { 73 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 74 | double distance = durationMicros / 58.0; 75 | if (distance > 400.0) { 76 | return previousDistance; 77 | } 78 | distance = previousDistance * 0.6 + distance * 0.4; 79 | previousDistance = distance; 80 | return distance; 81 | } 82 | 83 | void echoPinInterrupt() 84 | { 85 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 86 | pulseInTimeBegin = micros(); 87 | } 88 | else { // pulse stoped 89 | pulseInTimeEnd = micros(); 90 | newDistanceAvailable = true; 91 | } 92 | } 93 | 94 | void toggleErrorLED() 95 | { 96 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 97 | digitalWrite(ERROR_LED_PIN, errorLEDState); 98 | } 99 | 100 | void toggleWarningLED() 101 | { 102 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 103 | digitalWrite(WARNING_LED_PIN, warningLEDState); 104 | } 105 | 106 | void setWarningLEDBlinkRateFromDistance(double distance) 107 | { 108 | // 0 .. 400 cm -> 0 .. 1600 ms 109 | warningLEDDelay = distance * 4; 110 | // Serial.println(warningLEDDelay); 111 | } 112 | 113 | void lock() 114 | { 115 | if (!isLocked) { 116 | // Serial.println("Locking"); 117 | isLocked = true; 118 | warningLEDState = LOW; 119 | errorLEDState = LOW; 120 | } 121 | } 122 | 123 | void unlock() 124 | { 125 | if (isLocked) { 126 | // Serial.println("Unlocking"); 127 | isLocked = false; 128 | errorLEDState = LOW; 129 | digitalWrite(ERROR_LED_PIN, errorLEDState); 130 | } 131 | } 132 | 133 | void printDistanceOnLCD(double distance) 134 | { 135 | if (isLocked) { 136 | lcd.setCursor(0, 0); 137 | lcd.print("!!! Obstacle !!! "); 138 | lcd.setCursor(0, 1); 139 | lcd.print("Press to unlock. "); 140 | } 141 | else { 142 | lcd.setCursor(0, 0); 143 | lcd.print("Dist: "); 144 | lcd.print(distance); 145 | lcd.print(" cm "); 146 | 147 | lcd.setCursor(0, 1); 148 | if (distance > WARNING_DISTANCE) { 149 | lcd.print("No obstacle. "); 150 | } 151 | else { 152 | lcd.print("!! Warning !! "); 153 | } 154 | } 155 | } 156 | 157 | void handleIRCommand(long command) 158 | { 159 | switch (command) { 160 | case IR_BUTTON_PLAY: { 161 | unlock(); 162 | break; 163 | } 164 | case IR_BUTTON_OFF: { 165 | // todo 166 | break; 167 | } 168 | case IR_BUTTON_EQ: { 169 | // todo 170 | break; 171 | } 172 | case IR_BUTTON_UP: { 173 | // todo 174 | break; 175 | } 176 | case IR_BUTTON_DOWN: { 177 | // todo 178 | break; 179 | } 180 | default: { 181 | // do nothing 182 | } 183 | } 184 | } 185 | 186 | void setup() { 187 | Serial.begin(115200); 188 | lcd.begin(16,2); 189 | IrReceiver.begin(IR_RECEIVE_PIN); 190 | pinMode(ECHO_PIN, INPUT); 191 | pinMode(TRIGGER_PIN, OUTPUT); 192 | pinMode(WARNING_LED_PIN, OUTPUT); 193 | pinMode(ERROR_LED_PIN, OUTPUT); 194 | pinMode(BUTTON_PIN, INPUT); 195 | 196 | buttonState = digitalRead(BUTTON_PIN); 197 | 198 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 199 | echoPinInterrupt, 200 | CHANGE); 201 | 202 | lcd.print("Initializing..."); 203 | delay(1000); 204 | lcd.clear(); 205 | } 206 | 207 | void loop() { 208 | unsigned long timeNow = millis(); 209 | 210 | if (isLocked) { 211 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 212 | lastTimeErrorLEDBlinked += errorLEDDelay; 213 | toggleErrorLED(); 214 | toggleWarningLED(); 215 | } 216 | 217 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 218 | byte newButtonState = digitalRead(BUTTON_PIN); 219 | if (newButtonState != buttonState) { 220 | lastTimeButtonChanged = timeNow; 221 | buttonState = newButtonState; 222 | if (buttonState == LOW) { // released 223 | unlock(); 224 | } 225 | } 226 | } 227 | } 228 | else { 229 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 230 | lastTimeWarningLEDBlinked += warningLEDDelay; 231 | toggleWarningLED(); 232 | } 233 | } 234 | 235 | if (IrReceiver.decode()) { 236 | IrReceiver.resume(); 237 | long command = IrReceiver.decodedIRData.command; 238 | handleIRCommand(command); 239 | // Serial.println(command); 240 | } 241 | 242 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 243 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 244 | triggerUltrasonicSensor(); 245 | } 246 | 247 | if (newDistanceAvailable) { 248 | newDistanceAvailable = false; 249 | double distance = getUltrasonicDistance(); 250 | setWarningLEDBlinkRateFromDistance(distance); 251 | printDistanceOnLCD(distance); 252 | if (distance < LOCK_DISTANCE) { 253 | lock(); 254 | } 255 | // Serial.println(distance); 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /final_project/final_project_step9/final_project_step9.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define IR_RECEIVE_PIN 5 6 | 7 | #define ECHO_PIN 3 8 | #define TRIGGER_PIN 4 9 | 10 | #define WARNING_LED_PIN 11 11 | #define ERROR_LED_PIN 12 12 | 13 | #define BUTTON_PIN 2 14 | 15 | #define LCD_RS_PIN A5 16 | #define LCD_E_PIN A4 17 | #define LCD_D4_PIN 6 18 | #define LCD_D5_PIN 7 19 | #define LCD_D6_PIN 8 20 | #define LCD_D7_PIN 9 21 | 22 | #define LOCK_DISTANCE 10.0 23 | #define WARNING_DISTANCE 50.0 24 | 25 | // IR button mapping 26 | #define IR_BUTTON_PLAY 64 27 | #define IR_BUTTON_OFF 69 28 | #define IR_BUTTON_EQ 25 29 | #define IR_BUTTON_UP 9 30 | #define IR_BUTTON_DOWN 7 31 | 32 | #define DISTANCE_UNIT_CM 0 33 | #define DISTANCE_UNIT_IN 1 34 | #define CM_TO_INCHES 0.393701 35 | #define EEPROM_ADDRESS_DISTANCE_UNIT 50 36 | 37 | // lcd 38 | LiquidCrystal lcd(LCD_RS_PIN, LCD_E_PIN, LCD_D4_PIN, 39 | LCD_D5_PIN, LCD_D6_PIN, LCD_D7_PIN); 40 | 41 | // ultrasonic 42 | unsigned long lastTimeUltrasonicTrigger = millis(); 43 | unsigned long ultrasonicTriggerDelay = 60; 44 | 45 | volatile unsigned long pulseInTimeBegin; 46 | volatile unsigned long pulseInTimeEnd; 47 | volatile bool newDistanceAvailable = false; 48 | 49 | double previousDistance = 400.0; 50 | 51 | // warning LED 52 | unsigned long lastTimeWarningLEDBlinked = millis(); 53 | unsigned long warningLEDDelay = 500; 54 | byte warningLEDState = LOW; 55 | 56 | // error LED 57 | unsigned long lastTimeErrorLEDBlinked = millis(); 58 | unsigned long errorLEDDelay = 300; 59 | byte errorLEDState = LOW; 60 | 61 | // push button 62 | unsigned long lastTimeButtonChanged = millis(); 63 | unsigned long buttonDebounceDelay = 50; 64 | byte buttonState; 65 | 66 | bool isLocked = false; 67 | 68 | int distanceUnit = DISTANCE_UNIT_CM; 69 | 70 | void triggerUltrasonicSensor() 71 | { 72 | digitalWrite(TRIGGER_PIN, LOW); 73 | delayMicroseconds(2); 74 | digitalWrite(TRIGGER_PIN, HIGH); 75 | delayMicroseconds(10); 76 | digitalWrite(TRIGGER_PIN, LOW); 77 | } 78 | 79 | double getUltrasonicDistance() 80 | { 81 | double durationMicros = pulseInTimeEnd - pulseInTimeBegin; 82 | double distance = durationMicros / 58.0; 83 | if (distance > 400.0) { 84 | return previousDistance; 85 | } 86 | distance = previousDistance * 0.6 + distance * 0.4; 87 | previousDistance = distance; 88 | return distance; 89 | } 90 | 91 | void echoPinInterrupt() 92 | { 93 | if (digitalRead(ECHO_PIN) == HIGH) { // pulse started 94 | pulseInTimeBegin = micros(); 95 | } 96 | else { // pulse stoped 97 | pulseInTimeEnd = micros(); 98 | newDistanceAvailable = true; 99 | } 100 | } 101 | 102 | void toggleErrorLED() 103 | { 104 | errorLEDState = (errorLEDState == HIGH) ? LOW : HIGH; 105 | digitalWrite(ERROR_LED_PIN, errorLEDState); 106 | } 107 | 108 | void toggleWarningLED() 109 | { 110 | warningLEDState = (warningLEDState == HIGH) ? LOW : HIGH; 111 | digitalWrite(WARNING_LED_PIN, warningLEDState); 112 | } 113 | 114 | void setWarningLEDBlinkRateFromDistance(double distance) 115 | { 116 | // 0 .. 400 cm -> 0 .. 1600 ms 117 | warningLEDDelay = distance * 4; 118 | // Serial.println(warningLEDDelay); 119 | } 120 | 121 | void lock() 122 | { 123 | if (!isLocked) { 124 | // Serial.println("Locking"); 125 | isLocked = true; 126 | warningLEDState = LOW; 127 | errorLEDState = LOW; 128 | } 129 | } 130 | 131 | void unlock() 132 | { 133 | if (isLocked) { 134 | // Serial.println("Unlocking"); 135 | isLocked = false; 136 | errorLEDState = LOW; 137 | digitalWrite(ERROR_LED_PIN, errorLEDState); 138 | } 139 | } 140 | 141 | void printDistanceOnLCD(double distance) 142 | { 143 | if (isLocked) { 144 | lcd.setCursor(0, 0); 145 | lcd.print("!!! Obstacle !!! "); 146 | lcd.setCursor(0, 1); 147 | lcd.print("Press to unlock. "); 148 | } 149 | else { 150 | lcd.setCursor(0, 0); 151 | lcd.print("Dist: "); 152 | if (distanceUnit == DISTANCE_UNIT_IN) { 153 | lcd.print(distance * CM_TO_INCHES); 154 | lcd.print(" in "); 155 | } 156 | else { 157 | lcd.print(distance); 158 | lcd.print(" cm "); 159 | } 160 | 161 | lcd.setCursor(0, 1); 162 | if (distance > WARNING_DISTANCE) { 163 | lcd.print("No obstacle. "); 164 | } 165 | else { 166 | lcd.print("!! Warning !! "); 167 | } 168 | } 169 | } 170 | 171 | void toggleDistanceUnit() 172 | { 173 | if (distanceUnit == DISTANCE_UNIT_CM) { 174 | distanceUnit = DISTANCE_UNIT_IN; 175 | } 176 | else { 177 | distanceUnit = DISTANCE_UNIT_CM; 178 | } 179 | EEPROM.write(EEPROM_ADDRESS_DISTANCE_UNIT, distanceUnit); 180 | } 181 | 182 | void handleIRCommand(long command) 183 | { 184 | switch (command) { 185 | case IR_BUTTON_PLAY: { 186 | unlock(); 187 | break; 188 | } 189 | case IR_BUTTON_OFF: { 190 | // todo 191 | break; 192 | } 193 | case IR_BUTTON_EQ: { 194 | toggleDistanceUnit(); 195 | break; 196 | } 197 | case IR_BUTTON_UP: { 198 | // todo 199 | break; 200 | } 201 | case IR_BUTTON_DOWN: { 202 | // todo 203 | break; 204 | } 205 | default: { 206 | // do nothing 207 | } 208 | } 209 | } 210 | 211 | void setup() { 212 | Serial.begin(115200); 213 | lcd.begin(16,2); 214 | IrReceiver.begin(IR_RECEIVE_PIN); 215 | pinMode(ECHO_PIN, INPUT); 216 | pinMode(TRIGGER_PIN, OUTPUT); 217 | pinMode(WARNING_LED_PIN, OUTPUT); 218 | pinMode(ERROR_LED_PIN, OUTPUT); 219 | pinMode(BUTTON_PIN, INPUT); 220 | 221 | buttonState = digitalRead(BUTTON_PIN); 222 | 223 | attachInterrupt(digitalPinToInterrupt(ECHO_PIN), 224 | echoPinInterrupt, 225 | CHANGE); 226 | 227 | distanceUnit = EEPROM.read(EEPROM_ADDRESS_DISTANCE_UNIT); 228 | if (distanceUnit == 255) { 229 | distanceUnit = DISTANCE_UNIT_CM; 230 | } 231 | 232 | lcd.print("Initializing..."); 233 | delay(1000); 234 | lcd.clear(); 235 | } 236 | 237 | void loop() { 238 | unsigned long timeNow = millis(); 239 | 240 | if (isLocked) { 241 | if (timeNow - lastTimeErrorLEDBlinked > errorLEDDelay) { 242 | lastTimeErrorLEDBlinked += errorLEDDelay; 243 | toggleErrorLED(); 244 | toggleWarningLED(); 245 | } 246 | 247 | if (timeNow - lastTimeButtonChanged > buttonDebounceDelay) { 248 | byte newButtonState = digitalRead(BUTTON_PIN); 249 | if (newButtonState != buttonState) { 250 | lastTimeButtonChanged = timeNow; 251 | buttonState = newButtonState; 252 | if (buttonState == LOW) { // released 253 | unlock(); 254 | } 255 | } 256 | } 257 | } 258 | else { 259 | if (timeNow - lastTimeWarningLEDBlinked > warningLEDDelay) { 260 | lastTimeWarningLEDBlinked += warningLEDDelay; 261 | toggleWarningLED(); 262 | } 263 | } 264 | 265 | if (IrReceiver.decode()) { 266 | IrReceiver.resume(); 267 | long command = IrReceiver.decodedIRData.command; 268 | handleIRCommand(command); 269 | // Serial.println(command); 270 | } 271 | 272 | if (timeNow - lastTimeUltrasonicTrigger > ultrasonicTriggerDelay) { 273 | lastTimeUltrasonicTrigger += ultrasonicTriggerDelay; 274 | triggerUltrasonicSensor(); 275 | } 276 | 277 | if (newDistanceAvailable) { 278 | newDistanceAvailable = false; 279 | double distance = getUltrasonicDistance(); 280 | setWarningLEDBlinkRateFromDistance(distance); 281 | printDistanceOnLCD(distance); 282 | if (distance < LOCK_DISTANCE) { 283 | lock(); 284 | } 285 | // Serial.println(distance); 286 | } 287 | } 288 | --------------------------------------------------------------------------------