Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SPI.h>
- #include <SD.h>
- #include <LiquidCrystal_I2C.h>
- const int WIDTH = 20;
- const int HEIGHT = 4;
- LiquidCrystal_I2C lcd0(0x27, WIDTH, HEIGHT);
- LiquidCrystal_I2C lcd1(0x23, WIDTH, HEIGHT);
- const int TRIGPIN = 2;
- const int ECHOPIN = 3;
- const int RESET_PIN = A0;
- // New Stuff
- const int LEDAPIN = 7;
- const int LEDBPIN = 6;
- const int LEDCPIN = 5;
- const int LEDDPIN = 4;
- const int ANS_CHANGE_THRESHOLD = 2000;
- const int SCREEN_CHANGE_THRESHOLD = 1500;
- const int INITIAL_SCREEN_FACTOR = 2;
- const int EXTRA_SCROLLS = 2;
- const int OPTION_CHANGE_THRESHOLD = 500;
- const int NUM_QS = 1703;
- File file;
- const int arrayLength = 5;
- int lines = 0;
- String qArray[arrayLength];
- int perm[arrayLength - 1];
- void setup()
- {
- digitalWrite(RESET_PIN, HIGH);
- pinMode(TRIGPIN, OUTPUT);
- pinMode(ECHOPIN, INPUT);
- pinMode(RESET_PIN, OUTPUT);
- // New Stuff
- pinMode(LEDAPIN, OUTPUT);
- pinMode(LEDBPIN, OUTPUT);
- pinMode(LEDCPIN, OUTPUT);
- pinMode(LEDDPIN, OUTPUT);
- digitalWrite(RESET_PIN, HIGH);
- Serial.begin(9600);
- delay(analogRead(A2));
- randomSeed(analogRead(A1)*analogRead(A2)+ analogRead(A3));
- Serial.println();
- lcd0.init();
- lcd0.backlight();
- lcd0.home();
- lcd0.noAutoscroll();
- lcd1.init();
- lcd1.backlight();
- lcd1.home();
- lcd1.noAutoscroll();
- while (!Serial) {
- ; // wait for serial port to connect. Needed for native USB port only
- }
- Serial.print("Initializing SD card...");
- if (!SD.begin(10)) {
- while (1);
- }
- //open the file here
- lines = loadQuestions(String(random(NUM_QS)) + ".TXT", qArray);
- permute(lines - 1, perm);
- lcd0.setCursor(0, 0);
- //scrollQ(qArray[0]);
- displayAns(qArray, perm, lines, 0);
- }
- void loop() {
- //scroll answers
- static int screenInd = 0;
- static long lastS = 0;
- int numofScreens = INITIAL_SCREEN_FACTOR + qArray[0].length() / (WIDTH) - HEIGHT + EXTRA_SCROLLS;
- if (millis() - lastS > SCREEN_CHANGE_THRESHOLD) {
- lastS = millis();
- if (screenInd == 0 || screenInd > INITIAL_SCREEN_FACTOR) {
- printQScreen(qArray[0], max(screenInd - INITIAL_SCREEN_FACTOR, 0));
- }
- screenInd = (screenInd + 1) % (numofScreens);
- }
- //scroll questions
- static int optOffset = 0;
- static long lastScroll = 0;
- if (millis() - lastScroll > OPTION_CHANGE_THRESHOLD) {
- lastScroll = millis();
- displayAns(qArray, perm, lines, optOffset);
- optOffset++;
- }
- //lock in on choices
- static long lastChange = millis();
- static int lastChoice = 0;
- int dist = getDist();
- int choice = map(dist, 0, 120, 0, 6);
- if (lastChoice != choice) {
- lastChange = millis();
- }
- if (1 <= choice && choice < lines) {
- lcd1.cursor();
- lcd1.blink();
- lcd1.setCursor(19, choice - 1);
- if (millis() - lastChange > ANS_CHANGE_THRESHOLD) {
- feedbackAndReset(perm[choice - 1] == 0, qArray[1]);
- }
- } else {
- lcd1.noCursor();
- lcd1.noBlink();
- }
- lightLEDs(choice);
- lastChoice = choice;
- delay(100);
- }
- int loadQuestions(String path, String arr[]) {
- file = SD.open(path, FILE_READ);
- int index = 0;
- while (file.available()) {
- //A inconsistent line length may lead to heap memory fragmentation
- arr[index] = file.readStringUntil('\n');
- arr[index].trim();
- index++;
- }
- file.close();
- return index;
- }
- void permute(int n, int perm[]) {
- int ord[n];
- for (int i = 0; i < n; i++) {
- ord[i] = i;
- }
- for (int i = 0; i < n; i++) {
- int ind = random(n - i);
- perm[i] = ord[ind];
- for (int j = ind; j < n - 1; j++) {
- ord[j] = ord[j + 1];
- }
- }
- }
- int getDist() {
- digitalWrite(TRIGPIN, LOW);
- delayMicroseconds(5);
- digitalWrite(TRIGPIN, HIGH);
- delayMicroseconds(10);
- digitalWrite(TRIGPIN, LOW);
- long duration = pulseIn(ECHOPIN, HIGH);
- int distance = duration * 0.34 / 2;
- Serial.println(distance);
- return distance;
- }
- void displayAns(String qArray[], int perm[], int lines, int offset) {
- for (int i = 0; i < lines - 1; i++) {
- lcd1.setCursor(0, i);
- int scrollsNeeded =
- qArray[perm[i] + 1].length() - (WIDTH - 2) + INITIAL_SCREEN_FACTOR + EXTRA_SCROLLS;
- if (scrollsNeeded <= INITIAL_SCREEN_FACTOR + EXTRA_SCROLLS) {
- lcd1.print(qArray[perm[i] + 1]);
- } else {
- int cur_off = offset % (scrollsNeeded) - INITIAL_SCREEN_FACTOR;
- if (-INITIAL_SCREEN_FACTOR < cur_off && cur_off < 1) {
- continue;
- }
- cur_off = max(cur_off, 0);
- lcd1.print(" ");
- lcd1.setCursor(0, i);
- lcd1.print(qArray[perm[i] + 1].substring(cur_off, cur_off + WIDTH - 2));
- }
- }
- }
- void feedbackAndReset(bool correct, String ans) {
- lcd1.noCursor();
- lcd1.noBlink();
- lcd1.clear();
- lcd1.home();
- if (correct) {
- lcd1.print("Correct!");
- } else {
- lcd1.print("Incorrect.");
- lcd1.setCursor(0, 1);
- lcd1.print("Correct Answer is:");
- lcd1.setCursor(0, 2);
- lcd1.print(ans);
- }
- delay(1000);
- digitalWrite(RESET_PIN, LOW);
- }
- void printQScreen(String q, int s) {
- int qLen = q.length();
- int area = WIDTH * HEIGHT;
- if (qLen <= area) {
- for (int i = 0; i < qLen; i++) {
- int x = i % WIDTH;
- int y = i / WIDTH;
- lcd0.setCursor(x, y);
- lcd0.print(q[i]);
- }
- return;
- }
- lcd0.clear();
- for (int i = 0; i < area && ((s * WIDTH) + i) < qLen; i++) {
- int x = i % WIDTH;
- int y = i / WIDTH;
- lcd0.setCursor(x, y);
- lcd0.print(q[(s * WIDTH) + i]);
- }
- }
- void lightLEDs(int choice) {
- digitalWrite(LEDAPIN, LOW);
- digitalWrite(LEDBPIN, LOW);
- digitalWrite(LEDCPIN, LOW);
- digitalWrite(LEDDPIN, LOW);
- switch (choice)
- {
- case 1:
- digitalWrite(LEDAPIN, HIGH);
- break;
- case 2:
- digitalWrite(LEDBPIN, HIGH);
- break;
- case 3:
- digitalWrite(LEDCPIN, HIGH);
- break;
- case 4:
- digitalWrite(LEDDPIN, HIGH);
- break;
- default:
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement