Advertisement
Guest User

Untitled

a guest
Dec 13th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.92 KB | None | 0 0
  1. #include <SPI.h>
  2. #include <SD.h>
  3. #include <LiquidCrystal_I2C.h>
  4.  
  5. const int WIDTH = 20;
  6. const int HEIGHT = 4;
  7.  
  8. LiquidCrystal_I2C lcd0(0x27, WIDTH, HEIGHT);
  9. LiquidCrystal_I2C lcd1(0x23, WIDTH, HEIGHT);
  10.  
  11. const int TRIGPIN = 2;
  12. const int ECHOPIN = 3;
  13. const int RESET_PIN = A0;
  14.  
  15.  
  16. // New Stuff
  17. const int LEDAPIN = 7;
  18. const int LEDBPIN = 6;
  19. const int LEDCPIN = 5;
  20. const int LEDDPIN = 4;
  21.  
  22.  
  23. const int ANS_CHANGE_THRESHOLD = 2000;
  24. const int SCREEN_CHANGE_THRESHOLD = 1500;
  25. const int INITIAL_SCREEN_FACTOR = 2;
  26. const int EXTRA_SCROLLS = 2;
  27. const int OPTION_CHANGE_THRESHOLD = 500;
  28. const int NUM_QS = 1703;
  29.  
  30.  
  31. File file;
  32.  
  33. const int arrayLength = 5;
  34. int lines = 0;
  35. String qArray[arrayLength];
  36. int perm[arrayLength - 1];
  37.  
  38. void setup()
  39. {
  40.   digitalWrite(RESET_PIN, HIGH);
  41.   pinMode(TRIGPIN, OUTPUT);
  42.   pinMode(ECHOPIN, INPUT);
  43.   pinMode(RESET_PIN, OUTPUT);
  44.   // New Stuff
  45.   pinMode(LEDAPIN, OUTPUT);
  46.   pinMode(LEDBPIN, OUTPUT);
  47.   pinMode(LEDCPIN, OUTPUT);
  48.   pinMode(LEDDPIN, OUTPUT);
  49.  
  50.   digitalWrite(RESET_PIN, HIGH);
  51.   Serial.begin(9600);
  52.   delay(analogRead(A2));
  53.   randomSeed(analogRead(A1)*analogRead(A2)+ analogRead(A3));
  54.   Serial.println();
  55.  
  56.   lcd0.init();
  57.   lcd0.backlight();
  58.   lcd0.home();
  59.   lcd0.noAutoscroll();
  60.  
  61.   lcd1.init();
  62.   lcd1.backlight();
  63.   lcd1.home();
  64.   lcd1.noAutoscroll();
  65.  
  66.   while (!Serial) {
  67.     ; // wait for serial port to connect. Needed for native USB port only
  68.   }
  69.   Serial.print("Initializing SD card...");
  70.   if (!SD.begin(10)) {
  71.     while (1);
  72.   }
  73.  
  74.   //open the file here
  75.   lines = loadQuestions(String(random(NUM_QS)) + ".TXT", qArray);
  76.   permute(lines - 1, perm);
  77.   lcd0.setCursor(0, 0);
  78.   //scrollQ(qArray[0]);
  79.   displayAns(qArray, perm, lines, 0);
  80. }
  81.  
  82. void loop() {
  83.   //scroll answers
  84.   static int screenInd = 0;
  85.   static long lastS = 0;
  86.   int numofScreens = INITIAL_SCREEN_FACTOR + qArray[0].length() / (WIDTH) - HEIGHT + EXTRA_SCROLLS;
  87.   if (millis() - lastS > SCREEN_CHANGE_THRESHOLD) {
  88.     lastS = millis();
  89.     if (screenInd == 0 || screenInd > INITIAL_SCREEN_FACTOR) {
  90.       printQScreen(qArray[0], max(screenInd - INITIAL_SCREEN_FACTOR, 0));
  91.     }
  92.     screenInd = (screenInd + 1) % (numofScreens);
  93.   }
  94.  
  95.   //scroll questions
  96.   static int optOffset = 0;
  97.   static long lastScroll = 0;
  98.   if (millis() - lastScroll > OPTION_CHANGE_THRESHOLD) {
  99.     lastScroll = millis();
  100.     displayAns(qArray, perm, lines, optOffset);
  101.     optOffset++;
  102.   }
  103.  
  104.   //lock in on choices
  105.   static long lastChange = millis();
  106.   static int lastChoice = 0;
  107.   int dist = getDist();
  108.   int choice = map(dist, 0, 120, 0, 6);
  109.   if (lastChoice != choice) {
  110.     lastChange = millis();
  111.   }
  112.  
  113.   if (1 <= choice && choice < lines) {
  114.     lcd1.cursor();
  115.     lcd1.blink();
  116.     lcd1.setCursor(19, choice - 1);
  117.     if (millis() - lastChange > ANS_CHANGE_THRESHOLD) {
  118.       feedbackAndReset(perm[choice - 1] == 0, qArray[1]);
  119.     }
  120.   } else {
  121.     lcd1.noCursor();
  122.     lcd1.noBlink();
  123.   }
  124.  
  125.   lightLEDs(choice);
  126.  
  127.   lastChoice = choice;
  128.   delay(100);
  129. }
  130.  
  131.  
  132. int loadQuestions(String path, String arr[]) {
  133.   file = SD.open(path, FILE_READ);
  134.   int index = 0;
  135.   while (file.available()) {
  136.     //A inconsistent line length may lead to heap memory fragmentation
  137.     arr[index] = file.readStringUntil('\n');
  138.     arr[index].trim();
  139.  
  140.     index++;
  141.   }
  142.   file.close();
  143.   return index;
  144. }
  145.  
  146.  
  147. void permute(int n, int perm[]) {
  148.   int ord[n];
  149.   for (int i = 0; i < n; i++) {
  150.     ord[i] = i;
  151.   }
  152.   for (int i = 0; i < n; i++) {
  153.     int ind = random(n - i);
  154.     perm[i] = ord[ind];
  155.     for (int j = ind; j < n - 1; j++) {
  156.       ord[j] = ord[j + 1];
  157.     }
  158.   }
  159. }
  160.  
  161. int getDist() {
  162.   digitalWrite(TRIGPIN, LOW);
  163.   delayMicroseconds(5);
  164.   digitalWrite(TRIGPIN, HIGH);
  165.   delayMicroseconds(10);
  166.   digitalWrite(TRIGPIN, LOW);
  167.   long duration = pulseIn(ECHOPIN, HIGH);
  168.   int distance = duration * 0.34 / 2;
  169.   Serial.println(distance);
  170.   return distance;
  171. }
  172.  
  173. void displayAns(String qArray[], int perm[], int lines, int offset) {
  174.   for (int i = 0; i < lines - 1; i++) {
  175.     lcd1.setCursor(0, i);
  176.     int scrollsNeeded =
  177.       qArray[perm[i] + 1].length() - (WIDTH - 2) + INITIAL_SCREEN_FACTOR + EXTRA_SCROLLS;
  178.     if (scrollsNeeded <= INITIAL_SCREEN_FACTOR + EXTRA_SCROLLS) {
  179.       lcd1.print(qArray[perm[i] + 1]);
  180.     } else {
  181.       int cur_off = offset % (scrollsNeeded) - INITIAL_SCREEN_FACTOR;
  182.  
  183.       if (-INITIAL_SCREEN_FACTOR < cur_off && cur_off < 1) {
  184.         continue;
  185.       }
  186.  
  187.       cur_off = max(cur_off, 0);
  188.       lcd1.print("                   ");
  189.       lcd1.setCursor(0, i);
  190.       lcd1.print(qArray[perm[i] + 1].substring(cur_off, cur_off + WIDTH - 2));
  191.     }
  192.   }
  193. }
  194.  
  195. void feedbackAndReset(bool correct, String ans) {
  196.   lcd1.noCursor();
  197.   lcd1.noBlink();
  198.   lcd1.clear();
  199.   lcd1.home();
  200.  
  201.   if (correct) {
  202.     lcd1.print("Correct!");
  203.   } else {
  204.     lcd1.print("Incorrect.");
  205.     lcd1.setCursor(0, 1);
  206.     lcd1.print("Correct Answer is:");
  207.     lcd1.setCursor(0, 2);
  208.     lcd1.print(ans);
  209.   }
  210.  
  211.   delay(1000);
  212.   digitalWrite(RESET_PIN, LOW);
  213. }
  214.  
  215. void printQScreen(String q, int s) {
  216.   int qLen = q.length();
  217.   int area = WIDTH * HEIGHT;
  218.  
  219.   if (qLen <= area) {
  220.     for (int i = 0; i < qLen; i++) {
  221.       int x = i % WIDTH;
  222.       int y = i / WIDTH;
  223.       lcd0.setCursor(x, y);
  224.       lcd0.print(q[i]);
  225.     }
  226.     return;
  227.   }
  228.  
  229.   lcd0.clear();
  230.   for (int i = 0; i < area && ((s * WIDTH) + i) < qLen; i++) {
  231.     int x = i % WIDTH;
  232.     int y = i / WIDTH;
  233.     lcd0.setCursor(x, y);
  234.     lcd0.print(q[(s * WIDTH) + i]);
  235.   }
  236. }
  237.  
  238. void lightLEDs(int choice) {
  239.   digitalWrite(LEDAPIN, LOW);
  240.   digitalWrite(LEDBPIN, LOW);
  241.   digitalWrite(LEDCPIN, LOW);
  242.   digitalWrite(LEDDPIN, LOW);
  243.   switch (choice)
  244.   {
  245.     case 1:
  246.       digitalWrite(LEDAPIN, HIGH);
  247.       break;
  248.     case 2:
  249.       digitalWrite(LEDBPIN, HIGH);
  250.       break;
  251.     case 3:
  252.       digitalWrite(LEDCPIN, HIGH);
  253.       break;
  254.     case 4:
  255.       digitalWrite(LEDDPIN, HIGH);
  256.       break;
  257.     default:
  258.       break;
  259.   }
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement