/*
Name: EXAM2_WIRING_TEST_STUB.ino
Created: 11/5/2022 7:46:06 PM
Author: nbliz
*/
/*
EECT222 Exam Wiring
David Alan Spoelstra
3AH-Fall 2022-Intro to Microcontrollers
November 5, 2022 at 1:25am
Students-
You may hookup and test the following hardware before the test on Zoom Monday:
Ultrasonic rangefinder
Photoresistor
Two pushbuttons wired to interrupts
IR Receiver and Transmitter
Piezo speaker
LCD display with an I2C backpack.
*/
/* wiring test
connect PB_1 to pin2 INT0
connect PB_2 to pin3 INT1
install LCD I2C library, instantiate lcd object,
connect LCD I2C to A4 SDA, A5 SCL, test with HelloWorld -- tests OK
write a stub to test PB1_ & PB_2 functions by flipping bool flags when pressed (debounce with futureTime delays) -- tests OK
install NewTone library, instantiinstall LCD I2C librarym, instantiate sonar object,
hook up buzzer to pin ~4 pwm, test with
*/
//led globals
const byte lcdRows = 2;
const byte lcdColumns = 16;
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows); // lcd checks ok
const int DELAY1 = 1000; // msec
const int DELAY2 = 1000; // msec
volatile unsigned long futureTime1 = millis(); // getting current time for 1st ISR call
volatile unsigned long futureTime2 = millis(); // getting current time for 2nd ISR call
volatile bool PB1_Flag = true;
volatile bool PB2_Flag = true;
const byte PB_1 = 2; // INT0
const byte PB_2 = 3; // INT1
//piezo tone generator globals
#include <NewTone.h>
// buzzer parameters
const byte BUZZER_PIN = 4; // note -- install 100 Ohm resistor or it interfers with the interrupts(?)
const int FREQUENCY = 1000; // one KHz = 1000 cycles per second
const int DURATION = 1000; // duraction in msec
const int DELAY_DURATION = 2000; // duration of delays during while loops
//sonar globals
#include <NewPing.h>
const byte TRIGGER_PIN = 12;
const byte ECHO_PIN = 11;
const byte MAX_DISTANCE = 400;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
const bool IN = false; // inch flag
const bool CM = !IN; // cm or anything but IN
bool scaleFlag = IN; // initialize
const byte DEBOUNCE_TIME = 100;
const byte NUM_READINGS = 8; // sampling
// IR receiver globals (NOTE - must substitute correct hex codes)
#include <IRremote.hpp> // VS and Vmicro required this vs IRremote.h to resolve references
const byte IR_RECEIVE_PIN = 13; // Signal Pin of IR receiver, PROFS was 12
// byte colorNumber;
// byte lastcolorNumber;
const bool PRINTFLAG = true;
const bool FORWARD = true;
const bool REVERSE = !FORWARD;
bool POWER_flag = false;
bool firstPowerOn = false;
const byte RED = 0;
const byte DARK = 10;
const byte NUM_COLORS = 10; // dont count the 11th black color
const bool ON = true;
const bool OFF = !ON;
void setup() {
Serial.begin(9600); // for diagnostics
// set pin modes for PB1 & PB2 and attach ISRs for each
pinMode(PB_1, INPUT_PULLUP);
pinMode(PB_2, INPUT_PULLUP);
// set pin modes for sonar
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(PB_1), PB1_Routine, CHANGE);
attachInterrupt(digitalPinToInterrupt(PB_2), PB2_Routine, CHANGE);
//lcd.begin(); // remember to UNCOMMENT this unless using Wokwi
lcd.init(); // remember to COMMENT this unless using Wokwi
lcd.backlight();
lcd.clear();
testLCD(); // tests ok as wired
}
void loop() {
// put your main code here, to run repeatedly:
printPB1_Flag();
printPB2_Flag();
// buzzer logic
buzzersOnorOff();
long futureTime = millis() + DELAY_DURATION;
while (millis() < futureTime) {
// do nothing
} // duration of delay needs to be long enough to allow buzzer to finish
// calls for distance
lcd.clear();
int distance = getAverageDistance(NUM_READINGS);
printDistance(distance);
futureTime = millis() + DELAY_DURATION;
while (millis() < futureTime) {
// do nothing
}
lcd.clear();
delay(500);
}
// test stub for lcd
void testLCD() {
lcd.setCursor(0, 0);
lcd.print("Hello World!");
lcd.setCursor(0, 1);
lcd.print("This is a test");
delay(2000);
lcd.clear();
}
// PB1 routine
void PB1_Routine() {
if (millis() > futureTime1) { // millis() has correct time when ISR called
futureTime1 = millis() + DELAY1; // if more than Delay1 milliseconds has elapsed, execute this block
//NewTone(PIEZO, ONE_KHZ, TWO_SECONDS);
PB1_Flag = ! PB1_Flag; // toggle flag for PB1
}
} // tests OK
// PB2 routine
void PB2_Routine() {
if (millis() > futureTime2) { // millis() has correct time when ISR called
futureTime2 = millis() + DELAY2; // if more than Delay2 milliseconds has elapsed, execute this block
//NewTone(PIEZO, ONE_KHZ, TWO_SECONDS);
PB2_Flag = ! PB2_Flag; // toggle flag for PB2
}
} // tests OK
void printPB1_Flag() {
lcd.setCursor(0, 0);
lcd.print("PB1_Flag =");
lcd.print(PB1_Flag);
} // tests OK
void printPB2_Flag() {
lcd.setCursor(0, 1);
lcd.print("PB2_Flag =");
lcd.print(PB2_Flag);
} // tests OK
// routine to buzz the piezo buzzer
void buzzBuzzer(byte buzzerPin, int frequency, int duration) {
NewTone(buzzerPin, frequency, duration);
}
void buzzersOnorOff() {
if (PB1_Flag) {
buzzBuzzer(BUZZER_PIN, FREQUENCY * 2, DURATION / 2); // just to get a different tone and duration
}
long futureTime = millis() + DELAY_DURATION;
while (millis() < futureTime) {
// do nothing
}
//delay(DURATION);
if (PB2_Flag) {
buzzBuzzer(BUZZER_PIN, FREQUENCY, DURATION);
}
}
// sonar calls
int getAverageDistance(byte numReadings) {
unsigned long pingTime = sonar.ping_median(numReadings);
//Serial.println(pingTime);
return (scaleFlag == IN) ? sonar.convert_in(pingTime) : sonar.convert_cm(pingTime); // TERNARY USED
}
void printDistance(int distance) {
lcd.setCursor(0, 0);
lcd.print("Distance: ");
printPaddedNumber(distance);
lcd.print((scaleFlag == IN) ? " in" : " cm"); // TERNARY USED
}
void printPaddedNumber(int num) {
if (num < 100) lcd.print(" ");
if (num < 10) lcd.print(" ");
lcd.print(num);
}