Display SSD1306 for ESP32
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

703 lines
24 KiB

  1. #include <SPI.h>
  2. #include <Wire.h>
  3. #include <Adafruit_GFX.h>
  4. #include <Adafruit_SSD1306.h>
  5. #define __DEBUG__
  6. //The following constants are used to configure the behaviour of the interface
  7. // MAX_OPTIONS defines the maximum number of options a menu can hold
  8. // MAX_MENUS declares the maximum number of menu screens in the interface
  9. // MAX_GRAPHS is the maximum number of graphs to create
  10. // DISP_WIDTH and DISP_HEIGHT are hardware specific (SSD1306)
  11. // REFRESH: is the time in miliseconds the interface will take in refreshing (this time affects the loop, keep that in mind)
  12. #define MAX_OPTIONS 10 //Maximum number of options for each menu
  13. #define MAX_MENUS 3
  14. #define MAX_GRAPH 3
  15. #define DISP_WIDTH 128 // OLED display width
  16. #define DISP_HEIGHT 64 // OLED display height
  17. #define REFRESH 10 //Refresh time in ms
  18. Adafruit_SSD1306 display(DISP_WIDTH, DISP_HEIGHT, &Wire, -1);
  19. int i = 0;
  20. class Option{
  21. private:
  22. int sizex; //Defines the size it will occupy in the x axis (width), this value is gotten from the menu
  23. int sizey; //Defines the height of the option (this value is gotten from the menu it belongs to)
  24. String content; //Text of the option
  25. int pos; //Defines the position it has in the menu
  26. int textSpacing; //According to the height, defines the space for the text, so that it's vertically centered
  27. bool fill = false; //In case an option is not selected this should be false
  28. bool disp = false; //In case an option is not configured, it should be false and, thus hidden
  29. int destinationType; //Defines what the option leads to (another menu, graph, something else)
  30. int destinationIndex; //Defines where the option leads to (index of the destination)
  31. public:
  32. //Option(){}
  33. //Method to configure an option, all attributes are assigned, and disp is true, so the option can be displayed
  34. void configure(String content, int sizex, int sizey, int pos, int destinationType, int destinationIndex){
  35. this->sizex = sizex;
  36. this->sizey = sizey;
  37. this->content = content;
  38. this->pos = pos;
  39. this->destinationType = destinationType;
  40. this->destinationIndex = destinationIndex;
  41. this->disp = true;
  42. this->textSpacing = ((sizey - 7)/2) + 7;
  43. }
  44. int getDestinationType(){
  45. int destinationType = this->destinationType;
  46. return destinationType;
  47. }
  48. int getDestinationIndex(){
  49. int destinationIndex = this->destinationIndex;
  50. return destinationIndex;
  51. }
  52. //This method draws each option
  53. void drawopt(int page, int pos, int optPPage){
  54. if(this->disp){ //Checks if the option was configured and, as a result, is displayable
  55. if(this->pos == pos){ //If the position of the option corresponds to the position passed to the function, then it should be selected
  56. display.fillRect(0, (this->sizey)*(this->pos) + 1 - (page*optPPage*this->sizey), this->sizex, this->sizey, WHITE);
  57. display.setTextColor(SSD1306_BLACK);
  58. display.setCursor(5, (this->sizey)*(this->pos + 1) - (page*optPPage*this->sizey) - this->textSpacing);
  59. display.print(this->content);
  60. display.setTextColor(SSD1306_WHITE);
  61. }
  62. else{ //If the option is not selected, the rectangle containing it shouldn't be filled
  63. display.drawRect(0, (this->sizey)*(this->pos) + 1 - (page*optPPage*this->sizey), this->sizex, this->sizey, WHITE);
  64. display.setCursor(5, (this->sizey)*(this->pos + 1) - (page*optPPage*this->sizey) - this->textSpacing);
  65. display.print(this->content);
  66. }
  67. }
  68. }
  69. };
  70. class Menu{ //ContentTypeMenu true, it is a menu
  71. private:
  72. int sizex; //X size for each option in the menu
  73. int sizey; //Y size of each option in the menu
  74. int options = 0; //This indicates the number of options created
  75. int pos = 0; //This indicates the position of the cursor
  76. int page = 0; //If the menu is too long, this indicates the page that is being displayed
  77. Option opt[MAX_OPTIONS];
  78. int optPPage;
  79. int previousScreen = 0;
  80. int previousContentType = 0;
  81. public:
  82. void configure(int sizex, int sizey){ //This method configures the menu created from Screen
  83. this->sizex = sizex;
  84. this->sizey = sizey;
  85. this->optPPage = DISP_HEIGHT / this->sizey;
  86. }
  87. //The following method is used to created an option for the menu
  88. void createOption(String content, bool destinationTypeMenu, int destinationIndex){
  89. //The option takes the place in the array defined by the options number variable (options), which is later increased.
  90. this->opt[this->options].configure(content, this->sizex, this->sizey, this->options++, destinationTypeMenu, destinationIndex);
  91. }
  92. int extractDestinationType(){
  93. int destinationType = this->opt[this->pos].getDestinationType();
  94. return destinationType;
  95. }
  96. int extractDestinationIndex(){
  97. int destinationIndex = this->opt[this->pos].getDestinationIndex();
  98. return destinationIndex;
  99. }
  100. void drawMenu(){
  101. display.clearDisplay();
  102. this->page = pos/this->optPPage;
  103. for(int i = 0; i < options; i++){
  104. this->opt[i].drawopt(this->page, this->pos, this->optPPage);
  105. }
  106. display.display();
  107. }
  108. int extractPos(){
  109. return(this->pos);
  110. }
  111. int extractOptNumber(){
  112. return(this->options);
  113. }
  114. void increasePos(){
  115. this->pos++;
  116. }
  117. void decreasePos(){
  118. this->pos--;
  119. }
  120. void setPreviousScreen(int prev){
  121. this->previousScreen = prev;
  122. }
  123. void setPreviousContentType(int prev){
  124. this->previousContentType = prev;
  125. }
  126. int getPreviousScreen(){
  127. int prev = this->previousScreen;
  128. return prev;
  129. }
  130. int getPreviousContentType(){
  131. int prev = this->previousContentType;
  132. return prev;
  133. }
  134. };
  135. class Graph{ //ContentTypeMenu false, it is not a menu
  136. private:
  137. String title;
  138. char graphType; //'a' Vertical Bar, 'b' Horizontal Bar, 'c' Cartesian Graph
  139. //Assign whatever value in "configure(..." if a parameter is not required for the specified graphType
  140. double value; //For: Vertical Bar Horizontal Bar Cartesian
  141. double xpos; //For: Vertical Bar Horizontal Bar Cartesian
  142. double ypos; //For: Vertical Bar Horizontal Bar Cartesian
  143. double height; //For: Vertical Bar Horizontal Bar Cartesian
  144. double width; //For: Vertical Bar Horizontal Bar Cartesian
  145. double yminimum; //For: Vertical Bar Cartesian
  146. double ymaximum; //For: Vertical Bar Cartesian
  147. double xminimum; //For: Horizontal Bar Cartesian
  148. double xmaximum; //For: Horizontal Bar Cartesian
  149. double yStepSize; //For: Vertical Bar Cartesian
  150. double xStepSize; //For: Horizontal Bar Cartesian
  151. double digit; //For: Vertical Bar Horizontal Bar Cartesian
  152. double x;
  153. double yrange;
  154. double xrange;
  155. double ox;
  156. double oy;
  157. double count;
  158. double graphScale;
  159. bool redraw = true;
  160. int previousScreen = 0;
  161. int previousContentType = 0;
  162. public:
  163. void configure(String title, char graphType, double xpos, double ypos, double width, double height,
  164. double yminimum, double ymaximum, double xminimum, double xmaximum, double yStepSize, double xStepSize, double digit){
  165. this->title = title;
  166. this->graphType = graphType;
  167. this->yminimum = yminimum;
  168. this->ymaximum = ymaximum;
  169. this->xminimum = xminimum;
  170. this->count = xminimum;
  171. this->xmaximum = xmaximum;
  172. this->height = height;
  173. this->width = width;
  174. this->yStepSize = yStepSize;
  175. this->xStepSize = xStepSize;
  176. this->digit = digit;
  177. this->xpos = xpos;
  178. this->ypos = ypos;
  179. switch(graphType){
  180. case 'a':
  181. this->yrange = ymaximum - yminimum;
  182. this->graphScale = (yStepSize) * (height / this->yrange) - .001; //Adjusts the scale of the graph, according to the range and the size of the step
  183. break;
  184. case 'b':
  185. this->xrange = xmaximum - xminimum;
  186. this->graphScale = (xStepSize) * (width / this->xrange) - .001; //Adjusts the scale of the graph, according to the range and the size of the step
  187. break;
  188. case 'c':
  189. this->yrange = ymaximum - yminimum;
  190. this->xrange = xmaximum - xminimum;
  191. break;
  192. }
  193. }
  194. void drawGraph(){
  195. double level, data, i;
  196. switch(graphType){
  197. case 'a':
  198. double my;
  199. if (this->redraw) {
  200. display.clearDisplay();
  201. this->redraw = false;
  202. display.fillRect(0, 0, 127 , 14, SSD1306_WHITE);
  203. display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  204. display.setTextSize(1);
  205. display.setCursor(2, 4);
  206. display.println(this->title);
  207. for (i = 0; i <= this->height; i += this->graphScale) {
  208. my = this->ypos - this->height + i;
  209. display.drawFastHLine(this->xpos + this->width + 1, my, 5, SSD1306_WHITE);
  210. // draw lables
  211. display.setTextSize(1);
  212. display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  213. display.setCursor(this->xpos + this->width + 12, my - 3 );
  214. data = this->ymaximum - ( i * (this->yStepSize / this->graphScale));
  215. display.print(data, this->digit);
  216. }
  217. }
  218. // compute level of bar graph that is scaled to the height and the hi and low vals
  219. // this is needed to accompdate for +/- range
  220. level = (this->height * (((this->value - this->yminimum) / (this->yrange))));
  221. // draw the bar graph
  222. // write a upper and lower bar to minimize flicker cause by blanking out bar and redraw on update
  223. display.drawRect(this->xpos, this->ypos - this->height, this->width, this->height, SSD1306_WHITE);
  224. display.fillRect(this->xpos, this->ypos - this->height, this->width, this->height - level, SSD1306_BLACK);
  225. display.drawRect(this->xpos, this->ypos - this->height, this->width, this->height, SSD1306_WHITE);
  226. display.fillRect(this->xpos, this->ypos - level, this->width, level, SSD1306_WHITE);
  227. // up until now print sends data to a video buffer NOT the screen
  228. // this call sends the data to the screen
  229. display.display();
  230. break;
  231. case 'b':
  232. if (this->redraw) {
  233. display.clearDisplay();
  234. this->redraw = false;
  235. display.fillRect(0, 0, 127 , 16, SSD1306_WHITE);
  236. display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  237. display.setTextSize(1);
  238. display.setCursor(2, 4);
  239. display.println(this->title);
  240. // draw the text
  241. for (i = 0; i <= this->width; i += this->graphScale) {
  242. display.drawFastVLine(i + this->xpos , this->ypos , 5, SSD1306_WHITE);
  243. // draw lables
  244. display.setTextSize(1);
  245. display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  246. display.setCursor(i + this->xpos , this->ypos + 10);
  247. // addling a small value to eliminate round off errors
  248. // this val may need to be adjusted
  249. data = ( i * (this->xStepSize / this->graphScale)) + this->xminimum + 0.00001;
  250. display.print(data, this->digit);
  251. }
  252. }
  253. // compute level of bar graph that is scaled to the width and the hi and low vals
  254. // this is needed to accompdate for +/- range capability
  255. // draw the bar graph
  256. // write a upper and lower bar to minimize flicker cause by blanking out bar and redraw on update
  257. level = (this->width * (((this->value - this->xminimum) / (this->xmaximum - this->xminimum))));
  258. display.fillRect(this->xpos + level, this->ypos - this->height, this->width - level, this->height, SSD1306_BLACK);
  259. display.drawRect(this->xpos, this->ypos - this->height, this->width, this->height, SSD1306_WHITE);
  260. display.fillRect(this->xpos, this->ypos - this->height, level, this->height, SSD1306_WHITE);
  261. // up until now print sends data to a video buffer NOT the screen
  262. // this call sends the data to the screen
  263. display.display();
  264. break;
  265. case 'c':
  266. double temp;
  267. if (this->redraw == true) {
  268. this->redraw = false;
  269. display.clearDisplay();
  270. display.fillRect(0, 0, 127 , 16, SSD1306_WHITE);
  271. display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  272. display.setTextSize(1);
  273. display.setCursor(2, 4);
  274. display.println(title);
  275. this->ox = (this->count - this->xminimum) * (this->width) / (this->xrange) + this->xpos;
  276. this->oy = (this->value - this->yminimum) * (- this->height) / (this->yrange) + this->ypos;
  277. // draw y scale
  278. display.setTextSize(1);
  279. display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  280. for ( i = this->yminimum; i <= this->ymaximum; i += this->yStepSize) {
  281. // compute the transform
  282. // note my transform funcition is the same as the map function, except the map uses long and we need doubles
  283. temp = (i - this->yminimum) * (- this->height) / (this->ymaximum - this->yminimum) + this->ypos;
  284. if (i == 0) {
  285. display.drawFastHLine(this->xpos - 3, temp, this->width + 3, SSD1306_WHITE);
  286. }
  287. else {
  288. display.drawFastHLine(this->xpos - 3, temp, 3, SSD1306_WHITE);
  289. }
  290. display.setCursor(this->xpos - 27, temp - 3);
  291. display.println(i, this->digit);
  292. }
  293. // draw x scale
  294. for (i = this->xminimum; i <= this->xmaximum; i += this->xStepSize) {
  295. // compute the transform
  296. display.setTextSize(1);
  297. display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  298. temp = (i - this->xminimum) * (this->width) / (this->xrange) + this->xpos;
  299. if (i == 0) {
  300. display.drawFastVLine(temp, this->ypos - this->height, this->height + 3, SSD1306_WHITE);
  301. }
  302. else {
  303. display.drawFastVLine(temp, this->ypos, 3, SSD1306_WHITE);
  304. }
  305. display.setCursor(temp, this->ypos + 6);
  306. display.println(i, this->digit);
  307. }
  308. }
  309. // graph drawn now plot the data
  310. // the entire plotting code are these few lines...
  311. this->x = (this->count - this->xminimum) * (this->width) / (this->xrange) + this->xpos;
  312. this->value = (this->value - this->yminimum) * (- this->height) / (this->yrange) + this->ypos;
  313. display.drawLine(this->ox, this->oy, this->x, this->value, SSD1306_WHITE);
  314. display.drawLine(this->ox, this->oy - 1, this->x, this->value - 1, SSD1306_WHITE);
  315. this->ox = this->x;
  316. this->oy = this->value;
  317. // up until now print sends data to a video buffer NOT the screen
  318. // this call sends the data to the screen
  319. display.display();
  320. this->count += 1;
  321. if(this->ox >= (this->xpos + this->width)){
  322. this->redraw = true;
  323. this->count = xminimum;
  324. }
  325. }
  326. }
  327. void redrawFlag(){
  328. this->redraw = true;
  329. }
  330. void setPreviousScreen(int prev){
  331. this->previousScreen = prev;
  332. }
  333. void setPreviousContentType(int prev){
  334. this->previousContentType = prev;
  335. }
  336. int getPreviousScreen(){
  337. int prev = this->previousScreen;
  338. return prev;
  339. }
  340. int getPreviousContentType(){
  341. int prev = this->previousContentType;
  342. return prev;
  343. }
  344. void assignValue(double value){
  345. this->value = value;
  346. }
  347. void reset(){
  348. this->x = 0;
  349. }
  350. };
  351. class Screen{
  352. private:
  353. Menu menu[MAX_MENUS];
  354. Graph graph[MAX_GRAPH];
  355. int counterM = 0;
  356. int counterG = 0;
  357. bool redraw = true;
  358. int currentScreen = 0;
  359. int contentType = 0;
  360. public:
  361. void configure(bool fullsetting){
  362. if(fullsetting){
  363. //Adafruit_SSD1306 display(DISP_WIDTH, DISP_HEIGHT, &Wire, -1);
  364. Serial.begin(115200);
  365. if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  366. #ifdef __DEBUG__
  367. Serial.println("Display not found!");
  368. #endif
  369. while (true);
  370. }
  371. }
  372. display.clearDisplay();
  373. // Text size
  374. display.setTextSize(2);
  375. // Text color
  376. display.setTextColor(SSD1306_WHITE);
  377. // Text position
  378. display.setCursor(25, 20);
  379. display.println("Welcome");
  380. display.setTextSize(1);
  381. display.display();
  382. delay(5000);
  383. }
  384. void createMenu(int sizex, int sizey){
  385. this->menu[counterM].configure(sizex, sizey);
  386. this->counterM++;
  387. }
  388. void createOption(int menuIndex, String content, bool destinationTypeMenu, int destinationIndex){
  389. this->menu[menuIndex].createOption(content, destinationTypeMenu, destinationIndex);
  390. }
  391. void createVGraph(String title, double xpos, double ypos, double width, double height,
  392. double yminimum, double ymaximum, double yStepSize, double digit){
  393. this->graph[counterG].configure(title, 'a', xpos, ypos, width, height, yminimum, ymaximum, 0, 0, yStepSize, 0, digit);
  394. this->counterG++;
  395. }
  396. void createHGraph(String title, double xpos, double ypos, double width, double height,
  397. double xminimum, double xmaximum, double xStepSize, double digit){
  398. this->graph[counterG].configure(title, 'b', xpos, ypos, width, height, 0, 0, xminimum, xmaximum, 0, xStepSize, digit);
  399. counterG++;
  400. }
  401. void createCGraph(String title, double xpos, double ypos, double width, double height,
  402. double yminimum, double ymaximum, double xminimum, double xmaximum, double yStepSize, double xStepSize, double digit){
  403. this->graph[counterG].configure(title, 'c', xpos, ypos, width, height, yminimum, ymaximum, xminimum, xmaximum, yStepSize, xStepSize, digit);
  404. counterG++;
  405. }
  406. /*
  407. void redrawFlag(){
  408. this->redraw = true;
  409. }
  410. */
  411. void graphAssignValue(int graphIndex, double value){
  412. this->graph[graphIndex].assignValue(value);
  413. this->redraw = true;
  414. }
  415. void control(){
  416. if (redraw){
  417. if (contentType == 0){
  418. menu[currentScreen].drawMenu();
  419. }
  420. else if (contentType == 1){
  421. graph[currentScreen].drawGraph();
  422. }
  423. this->redraw = false;
  424. }
  425. }
  426. void increasePos(){
  427. if(this->menu[this->currentScreen].extractPos() < this->menu[this->currentScreen].extractOptNumber() - 1)
  428. this->menu[this->currentScreen].increasePos();
  429. }
  430. void decreasePos(){
  431. if(this->menu[this->currentScreen].extractPos() > 0)
  432. this->menu[this->currentScreen].decreasePos();
  433. }
  434. void goTo(){
  435. if(this->contentType == 0){
  436. int newScreen = this->menu[this->currentScreen].extractDestinationIndex();
  437. int newContentType = this->menu[this->currentScreen].extractDestinationType();
  438. if (newContentType == 0){
  439. this->menu[newScreen].setPreviousScreen(this->currentScreen);
  440. this->menu[newScreen].setPreviousContentType(this->contentType);
  441. }
  442. else if(newContentType == 1){
  443. this->graph[newScreen].setPreviousScreen(this->currentScreen);
  444. this->graph[newScreen].setPreviousContentType(this->contentType);
  445. this->graph[newScreen].reset();
  446. this->graph[newScreen].redrawFlag();
  447. }
  448. else if(newContentType == 2){
  449. }
  450. this->contentType = newContentType;
  451. this->currentScreen = newScreen;
  452. this->redraw = true;
  453. }
  454. }
  455. void goBack(){
  456. if(contentType == 0){
  457. //Gets indexes from previous screen saved in actual screen if it is a menu, and sets them as the current indexes
  458. this->currentScreen = this->menu[this->currentScreen].getPreviousScreen();
  459. this->contentType = this->menu[this->currentScreen].getPreviousContentType();
  460. }
  461. else if(contentType == 1){
  462. //Gets indexes from previous screen saved in actual screen if it is a graph, and sets them as the current indexes
  463. this->currentScreen = this->graph[this->currentScreen].getPreviousScreen();
  464. this->contentType = this->graph[this->currentScreen].getPreviousContentType();
  465. }
  466. }
  467. void plusAction(){
  468. if(contentType == 0){
  469. increasePos();
  470. }
  471. }
  472. void minusAction(){
  473. if(contentType == 0){
  474. decreasePos();
  475. }
  476. }
  477. };
  478. class Keyboard{
  479. private:
  480. byte goTo;
  481. byte goBack;
  482. byte plus;
  483. byte minus;
  484. byte debounceTime;
  485. Screen *screen;
  486. public:
  487. Keyboard(byte goTo, byte goBack, byte plus, byte minus, byte debounceTime, Screen * screen){
  488. this->goTo = goTo;
  489. this->goBack = goBack;
  490. this->plus = plus;
  491. this->minus = minus;
  492. this->debounceTime = debounceTime;
  493. this->screen = screen;
  494. pinMode(goTo, INPUT_PULLUP);
  495. pinMode(goBack, INPUT_PULLUP);
  496. pinMode(plus, INPUT_PULLUP);
  497. pinMode(minus, INPUT_PULLUP);
  498. }
  499. void checkGoTo(){
  500. static char cont;
  501. if(digitalRead(this->goTo) == LOW)
  502. cont++;
  503. else
  504. cont = 0;
  505. if(cont == debounceTime/REFRESH){
  506. cont = 0;
  507. this->screen->goTo();
  508. while(digitalRead(this->goTo) == LOW){
  509. }
  510. }
  511. }
  512. void checkGoBack(){
  513. static char cont;
  514. if(digitalRead(this->goBack) == LOW){
  515. cont++;
  516. }
  517. else
  518. cont = 0;
  519. if(cont == debounceTime/REFRESH){
  520. cont = 0;
  521. this->screen->goBack();
  522. while(digitalRead(this->goBack) == LOW){
  523. }
  524. }
  525. }
  526. void checkPlus(){
  527. static char cont;
  528. if(digitalRead(this->plus) == LOW)
  529. cont++;
  530. else
  531. cont = 0;
  532. if(cont == debounceTime/REFRESH){
  533. cont = 0;
  534. this->screen->plusAction();
  535. while(digitalRead(this->plus) == LOW){
  536. }
  537. }
  538. }
  539. void checkMinus(){
  540. static char cont;
  541. if(digitalRead(this->minus) == LOW)
  542. cont++;
  543. else
  544. cont = 0;
  545. if(cont == debounceTime/REFRESH){
  546. cont = 0;
  547. this->screen->minusAction();
  548. while(digitalRead(this->minus) == LOW){
  549. }
  550. }
  551. }
  552. void control(){
  553. this->checkGoTo();
  554. this->checkGoBack();
  555. this->checkPlus();
  556. this->checkMinus();
  557. }
  558. };
  559. Screen screen;
  560. Keyboard keyboard(13, 12, 14, 27, 30, &screen);
  561. void setup(){
  562. screen.configure(true);
  563. screen.createMenu(128, 13); //Menu 0
  564. screen.createMenu(128, 13); //Menu 1
  565. /*String title, char graphType, double xpos, double ypos, double width, double height,
  566. double yminimum, double ymaximum, double xminimum, double xmaximum, double yStepSize, double xStepSize, double digit*/
  567. screen.createVGraph("Grafica 1", 25, 60, 40, 40, 0, 100, 10, 0); //Graph 0
  568. screen.createHGraph("Grafica 2", 10, 40, 100, 20, 0, 100, 10, 0); //Graph 1
  569. screen.createCGraph("Grafica 3", 30, 50, 75, 30, 0, 100, 0, 1000, 25, 250, 0); //Graph 2
  570. screen.createOption(0, "Vertical graph", 1, 0);
  571. //Creates the first option in Menu 0, directing to a graph (contentType = 1 (Graph)), 0 (Graph 0)
  572. screen.createOption(0, "Horizontal graph", 1, 1);
  573. screen.createOption(0, "Cartesian graph", 1, 2);
  574. screen.createOption(0, "Extra option", 0, 1);
  575. screen.createOption(1, "Test", 1, 3);
  576. screen.createOption(1, "Working?", 1, 4);
  577. // screen.increasePos();
  578. // screen.increasePos();
  579. // screen.goTo();
  580. // screen.graphAssignValue(2, 50);
  581. // screen.goBack();
  582. // screen.increasePos();
  583. // screen.goTo();
  584. // screen.goBack();
  585. // screen.decreasePos();
  586. }
  587. void loop(){
  588. screen.control(); //Controls the screen and redraws if needed
  589. keyboard.control();
  590. if(i <= 100){
  591. screen.graphAssignValue(1, i); //Assigning a demo value to Graph 1
  592. screen.graphAssignValue(2, i); //Assigning a demo value to Graph 2
  593. i++;
  594. }
  595. else
  596. i = 0;
  597. delay(REFRESH); //Refresh time (approx)
  598. }