From 66c5fbfc2b03f3a19892e4931e8da81fc86e9548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Araujo=20Galav=C3=ADz?= Date: Wed, 5 Apr 2023 15:51:20 +0000 Subject: [PATCH 1/6] =?UTF-8?q?=E2=80=9EReadme.md=E2=80=9C=20=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 718aa91..c72339d 100644 --- a/Readme.md +++ b/Readme.md @@ -156,4 +156,13 @@ Both methods are used to get the integers corresponding to the destination of th ##### drawMenu() -**drawMenu()** is used to draw all the options in the menu. \ No newline at end of file +**drawMenu()** is used to draw all the options in the menu. + + +### Graph class + +### Screen class + +### Keyboard class + +### Implementation \ No newline at end of file From af8bcb329f62fc6f11b654a96edde41adad9e022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Araujo=20Galav=C3=ADz?= Date: Sat, 8 Apr 2023 01:31:04 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=E2=80=9EReadme.md=E2=80=9C=20=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index c72339d..0522025 100644 --- a/Readme.md +++ b/Readme.md @@ -34,6 +34,10 @@ Macros are defined to help use the library easily, making possible to modify the * **DISP_WIDTH** and **DISP_HEIGHT** are hardware specific (SSD1306), it's possible to modify this values in the case that it's required to employ a different kind of display. * **REFRESH** is the time in milliseconds the interface will take in refreshing (this time affects the loop, keep that in mind) + +## Content types + + ## Classes In this section, the created classes are discussed, to better understand how each of them works. @@ -90,7 +94,7 @@ Methods accessed by others from Screen class. These return and integer correspon With this method, an option is drawn. This is another method that shouldn't be called directly, as there are other methods in the next classes that call it for all the options in a menu. This function requires the parameters shown in its prototype: - void drawopt(int page, int pos, int optPPage) + void drawOpt(int page, int pos, int optPPage) These parameters are obtained automatically from the method drawMenu in Menu that draws all the options within it. In this method, if the option is selected, then it will be printed in a filled rectangle, otherwise, it will appear as a black rectangle. @@ -156,11 +160,108 @@ Both methods are used to get the integers corresponding to the destination of th ##### drawMenu() -**drawMenu()** is used to draw all the options in the menu. +**drawMenu()** is used to draw all the options in the menu. It draws only the options that have been configured, thus ignores those within the array **opt** that haven't been used. To draw the options, it is important to provide the parameters for the drawOpt() method in Option, which are page, pos and optPPage, so first we get the page by getting the options per page, optPPage is calculated according to **sizey**, defined at the creation of the menu (this calculation takes into account the macro DISP_HEIGHT, discussed previously), pos is the attribute of the menu, which stores the current position of the cursor (option to display as selected by user). All the above is shown in the next lines: + + void drawMenu(){ + display.clearDisplay(); + this->page = pos/this->optPPage; + for(int i = 0; i < options; i++){ + this->opt[i].drawopt(this->page, this->pos, this->optPPage); + } + display.display(); + } + +In configure(): + + this->optPPage = DISP_HEIGHT / this->sizey; + + +##### extractPos() and extractOptNumber() +These methods are only used to extract values from the attributes of the objects of Menu. These data will be useful for knowing where the cursor is in regards to the number of options in the menu. That way, it's possible to prevent the cursor from moving beyond the options in the menu. These will be used in another method from Screen. + +##### increasePos() and decreasePos() + +These methods are accessed by Screen in order to increase or decrease the position of the cursor, since Screen serves as the controller of the whole interface, and keyboard interacts directly with its methods. + +##### Previous screen storing + +In order to store the previous screen, it's necessary to store the values that lead to it, both, index and type of content, thus four methods are implemented for that, two of them retrieve the values of the actual screen before changing to the new menu, the other two methods are called to store them in the latter, modifying the attributes **previousScreen** and **previousContentType**. + +**setPreviousScreen(int previousIndex)** and **setPreviousScreenType(int previousScreenType)** store the values of the previous screen passed from a Screen object, making it possible to go to the next menu and update the current Screen attributes, without losing the data of the previous screen. + +**getPreviousScreen()** and **getPreviousScreenType()** retrieve the data from **previousScreen** and **previousScreenType**, allowing the transition to a previous menu. ### Graph class +This class is for the creation of graphs. It allows the ploting of three types of graphs: vertical bar, horizontal bar and cartesian chart. + +#### Attributes + +To achieve the above stated the following attributes are used: + + private: + + String title; + char graphType; //'a' Vertical Bar, 'b' Horizontal Bar, 'c' Cartesian Graph + + //Assign whatever value in "configure(..." if a parameter is not required for the specified graphType + + double value; //For: Vertical Bar Horizontal Bar Cartesian + double xpos; //For: Vertical Bar Horizontal Bar Cartesian + double ypos; //For: Vertical Bar Horizontal Bar Cartesian + double height; //For: Vertical Bar Horizontal Bar Cartesian + double width; //For: Vertical Bar Horizontal Bar Cartesian + double yminimum; //For: Vertical Bar Cartesian + double ymaximum; //For: Vertical Bar Cartesian + double xminimum; //For: Horizontal Bar Cartesian + double xmaximum; //For: Horizontal Bar Cartesian + double yStepSize; //For: Vertical Bar Cartesian + double xStepSize; //For: Horizontal Bar Cartesian + int digit; //For: Vertical Bar Horizontal Bar Cartesian + double x; + double yrange; + double xrange; + double ox; + double oy; + double count; + double graphScale; + bool redraw = true; + + int previousScreen = 0; + int previousContentType = 0; + +* **title**: This string allocates the name of the graph to be displayed at the top of the display. +* **graphType**: The type of graph created 'a' means a vertical graph, 'b' a horizontal graph and 'c' a cartesian chart. +* **value**: It's the value to pass to the graph, there is method for that. This attribute is used by all types of graphs. +* **xpos**: This is the position in x of the bottom left corner of the graph. Required by all graph types. +* **ypos**: This is the position in y of the bottom left corner of the graph. Required by all graph types. +* **height**: Height of the graph (pixels). +* **width**: Width of the graph(pixels). +* **yminimum**: This is the minimum value to be graphed in the y axis. Required only for vertical graph and cartesian chart. +* **ymaximum**: Maximum value to graph in the y axis. Required only for vertical graph and cartesian chart. +* **xminimum**: This is the minimum value to be graphed in the x axis. Required only for horizontal graph and cartesian chart. +* **xmaximum**: Maximum value to graph in the x axis. Required only for horizontal graph and cartesian chart. +* **yStepSize**: Size of the step in the y axis. This is the interval in which the axis is going to be split. Required only for vertical graph and cartesian chart. +* **xStepSize**: Size of the step in the x axis. This is the interval in which the axis is going to be split. Required only for horizontal graph and cartesian chart. +* **digit**: Number of decimal digits to display in the axis labels. +* **x**: This is used to know the ending point of a line in the cartesian chart. +* **yrange**: Range in the y axis, depends on the maximum and minimum of this axis. +* **xrange**: Range in the x axis, depends on the maximum and minimum of this axis. +* **ox**: Starting point in x of a line to plot in the cartesian chart (Previous *x* value). +* **oy**: Starting point in y of a line to plot in the cartesian chart (Previous value received). +* **count**: Last iteration of the cartesian chart, in the x axis. +* **graphScale**: Scale of the graph (vertical or horizontal), according to its minimum and maximum. +* **redraw**: This boolean should only be true then the whole screen was cleared. It redraws the axes or the bars respectively. +* **previousScreen** and **previousContentType**: These integers keep the values of the screen that led to this graph, to make it possible to return to that screen. This values are assigned from a method in Graph, called from another one in Screen, which is used to control the interaction with the interface. This will be discussed later in this document, see Screen class. + +#### Methods +The following methods are applied to manage data from Graph. + +##### configure() + +This method sets up the new graph, its main attributes are defined here. The parameters passed in this case include all the attributes required for any kind of graph, however, as stated in some other methods, this one should not be called, there are some methods in Screen that call for this method and only require the parameters necessary for a certain type of graph (**createVGraph()**, **createHGraph()**, **createCGraph()**), these will be explained later. + ### Screen class ### Keyboard class From f27b751c407f09e7b65b8711f0f53e91d1b08618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Araujo=20Galav=C3=ADz?= Date: Sat, 8 Apr 2023 06:06:19 +0000 Subject: [PATCH 3/6] =?UTF-8?q?=E2=80=9EReadme.md=E2=80=9C=20=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 230 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 0522025..71ca322 100644 --- a/Readme.md +++ b/Readme.md @@ -23,16 +23,18 @@ Macros are defined to help use the library easily, making possible to modify the #define MAX_OPTIONS 10 //Maximum number of options for each menu #define MAX_MENUS 3 - #define MAX_GRAPH 3 + #define MAX_GRAPHS 3 #define DISP_WIDTH 128 // OLED display width #define DISP_HEIGHT 64 // OLED display height #define REFRESH 10 //Refresh time in ms + #define ADDRESS 0x3C //I2C address of the display * **MAX_OPTIONS** defines the maximum number of options a menu can hold, in this case, there can only be three menus in total, as there is only enough memory reserved for them. * **MAX_MENUS** declares the maximum number of menu screens in the interface, it's not possible to create more menus than this number. * **MAX_GRAPHS** is the maximum number of graphs to create. * **DISP_WIDTH** and **DISP_HEIGHT** are hardware specific (SSD1306), it's possible to modify this values in the case that it's required to employ a different kind of display. * **REFRESH** is the time in milliseconds the interface will take in refreshing (this time affects the loop, keep that in mind) +* **ADDRESS** address of the display ## Content types @@ -260,10 +262,236 @@ The following methods are applied to manage data from Graph. ##### configure() -This method sets up the new graph, its main attributes are defined here. The parameters passed in this case include all the attributes required for any kind of graph, however, as stated in some other methods, this one should not be called, there are some methods in Screen that call for this method and only require the parameters necessary for a certain type of graph (**createVGraph()**, **createHGraph()**, **createCGraph()**), these will be explained later. +This method sets up the new graph, its main attributes are defined here. The parameters passed in this case include all the attributes required for any kind of graph, however, as stated in some other methods, this one should not be called, there are some methods in Screen that call for this method and only require the parameters necessary for a certain type of graph (**createVGraph()**, **createHGraph()**, **createCGraph()**), these will be explained later. + +The prototype is: + + void configure(String title, char graphType, double xpos, double ypos, double width, double height, double yminimum, double ymaximum, double xminimum, double xmaximum, double yStepSize, double xStepSize, int digit) + +According to the type of graph configured, the next calculations are made: + + switch(graphType){ + case 'a': + this->yrange = ymaximum - yminimum; + this->graphScale = (yStepSize) * (height / this->yrange) - .001; + break; + + case 'b': + this->xrange = xmaximum - xminimum; + this->graphScale = (xStepSize) * (width / this->xrange) - .001; + break; + + case 'c': + this->yrange = ymaximum - yminimum; + this->xrange = xmaximum - xminimum; + break; + +##### drawGraph() + +To draw the graph and plot the values, **drawGraph()** is the method in graph applied. This method is called automatically from Screen when delay(REFRESH) expires. There is a swith case block that allows to print all types of graphs within this function, recognizing them by their **graphType** attribute. + +###### Vertical graph (graphType == 'a') + +For vertical bar graphs, the following code block is implemented for the creation of the labels: + + if (this->redraw) { + display.clearDisplay(); + this->redraw = false; + display.fillRect(0, 0, 127 , 14, SSD1306_WHITE); + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + display.setTextSize(1); + display.setCursor(2, 4); + display.println(this->title); + + for (i = 0; i <= this->height; i += this->graphScale) { + my = this->ypos - this->height + i; + display.drawFastHLine(this->xpos + this->width + 1, my, 5, SSD1306_WHITE); + display.setTextSize(1); + display.setTextColor(SSD1306_WHITE, SSD1306_BLACK); + display.setCursor(this->xpos + this->width + 12, my - 3 ); + data = this->ymaximum - ( i * (this->yStepSize / this->graphScale)); + display.print(data, this->digit); + } + } + +To graph the value received, two rectangles are display. A white one fills the portion of the bar occupied by the amount measured. A black rectangle fills the remaining part of the bar, as shown in the next block. This prevents flickering. + + level = (this->height * (((this->value - this->yminimum) / (this->yrange)))); + + display.drawRect(this->xpos, this->ypos - this->height, this->width, this->height, SSD1306_WHITE); + display.fillRect(this->xpos, this->ypos - this->height, this->width, this->height - level, SSD1306_BLACK); + display.drawRect(this->xpos, this->ypos - this->height, this->width, this->height, SSD1306_WHITE); + display.fillRect(this->xpos, this->ypos - level, this->width, level, SSD1306_WHITE); + +###### Horizontal graph (graphType == 'b') + +For horizontal graphs, the following code block is implemented to diplay the labels of the graph: + + if (this->redraw) { + display.clearDisplay(); + this->redraw = false; + display.fillRect(0, 0, 127 , 16, SSD1306_WHITE); + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + display.setTextSize(1); + display.setCursor(2, 4); + display.println(this->title); + // draw the text + + for (i = 0; i <= this->width; i += this->graphScale) { + display.drawFastVLine(i + this->xpos , this->ypos , 5, SSD1306_WHITE); + // draw lables + display.setTextSize(1); + display.setTextColor(SSD1306_WHITE, SSD1306_BLACK); + display.setCursor(i + this->xpos , this->ypos + 10); + // addling a small value to eliminate round off errors + // this val may need to be adjusted + data = ( i * (this->xStepSize / this->graphScale)) + this->xminimum + 0.00001; + display.print(data, this->digit); + } + } + +Like with the vertical bar, in this case, two rectangles are drawn to avoid flickering. The procedure is the same, only that it happens along the x axis. + +###### Cartesian chart + +In the following code, the axes are drawn as are their labels. + + if (this->redraw == true) { + this->redraw = false; + display.clearDisplay(); + display.fillRect(0, 0, 127 , 16, SSD1306_WHITE); + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + display.setTextSize(1); + display.setCursor(2, 4); + display.println(title); + this->ox = (this->count - this->xminimum) * (this->width) / (this->xrange) + this->xpos; + this->oy = (this->value - this->yminimum) * (- this->height) / (this->yrange) + this->ypos; + // draw y scale + display.setTextSize(1); + display.setTextColor(SSD1306_WHITE, SSD1306_BLACK); + for ( i = this->yminimum; i <= this->ymaximum; i += this->yStepSize) { + // compute the transform + // note my transform funcition is the same as the map function, except the map uses long and we need doubles + temp = (i - this->yminimum) * (- this->height) / (this->ymaximum - this->yminimum) + this->ypos; + if (i == 0) { + display.drawFastHLine(this->xpos - 3, temp, this->width + 3, SSD1306_WHITE); + } + else { + display.drawFastHLine(this->xpos - 3, temp, 3, SSD1306_WHITE); + } + display.setCursor(this->xpos - 27, temp - 3); + display.println(i, this->digit); + } + // draw x scale + for (i = this->xminimum; i <= this->xmaximum; i += this->xStepSize) { + // compute the transform + display.setTextSize(1); + display.setTextColor(SSD1306_WHITE, SSD1306_BLACK); + temp = (i - this->xminimum) * (this->width) / (this->xrange) + this->xpos; + if (i == 0) { + display.drawFastVLine(temp, this->ypos - this->height, this->height + 3, SSD1306_WHITE); + } + else { + display.drawFastVLine(temp, this->ypos, 3, SSD1306_WHITE); + } + display.setCursor(temp, this->ypos + 6); + display.println(i, this->digit); + } + } + +Two plot the data, the previous ending point of the graph is stored in **ox** and **oy**, and the new values are calculated depending on the value received and the scale of the graph. When the next point in the graph is greater than its width, the graph is redrawn and count is reset, in order to start graphing anew. + +##### redrawFlag() + +This method is accessed when necessary to redraw the whole interface of the graph. It only sets **redraw** to true. + +##### Previous screen storing + +It has the same methods as Menu for this, so it's recommended to read about them in the previous section of this document. + +##### assignValue() + +This method passes a value as a new attribute of the graph so it can be plotted. It has only one parameter, being it a double, corresponding to the value to receive. + +##### reset() + +Resets the position of x to redraw the cartesian chart when exiting and entering into it from the menus. ### Screen class +This class is the main class of this code, it's responsible for the control of the whole interface, allowing to switch between different menus and graphs, also for receiving data and interacting with the keyboard. + +#### Attributes + +Screen attributes are listed in the following code and explained afterwards. + + private: + + Menu menu[MAX_MENUS]; + Graph graph[MAX_GRAPHS]; + int counterM = 0; + int counterG = 0; + bool redraw = true; + int currentScreen = 0; + int contentType = 0; + +* **menu**: This array holds all the menus for the interface, limited by **MAX_MENUS**, see Macros. +* **graph**: This array holds all the graphs for the interface, limited by **MAX_GRAPHS**, see Macros. +* **counterM**: This is the number of menus created, it increases when a new menu is configured using the methods available from Screen. +* **counterG**: This is the number of graphs created, it increases when a new menu is configured using the methods available from Screen. +* **redraw**: Variable to control the redrawing of the interface. +* **currentScreen** and **contentType**: Variables where the current screen direction is stored, so that it's the only screen displayed. + +#### Methods + +To control the behaviour of the interface the following methods are used. + +##### configure() + +This method is used to set up the display and also print a welcome message, it is necessary to call this method once the object is created, in order to configure the direction of the display and allow communication. This configuration has place only if the parameter in configure is *true*, otherwise the display is only cleared and the welcome message is printed. Its prototype is shown in the following code block. + + void configure(bool fullsetting) + +##### createMenu() + +This method allows the creation of a new menu. Here is where configure() from Menu is called and the attributes of the object get their values. + + void createMenu(int sizex, int sizey) + +##### createOption() + +This is the recommended method for the creation of an option for a menu, it requires the index of the menu it belongs to, the destination index and type, and the message to show. Its prototype is: + + void createOption(int menuIndex, String content, bool destinationTypeMenu, int destinationIndex) + +##### Graph creation + +To create graphs, it is advisable to do it from Screen, using the methods **createVGraph()**, **createHGraph()** and **createCGraph()**. These allow the allocation of the graphs in the array of the Screen object, allowing them to interact with the interface. Their prototypes are: + + void createVGraph(String title, double xpos, double ypos, double width, double height, double yminimum, double ymaximum, double yStepSize, int digit) + + void createHGraph(String title, double xpos, double ypos, double width, double height, double xminimum, double xmaximum, double xStepSize, int digit) + + void createCGraph(String title, double xpos, double ypos, double width, double height, double yminimum, double ymaximum, double xminimum, double xmaximum, double yStepSize, double xStepSize, int digit) + +##### graphAssignValue() + +Using this method, it's possible to assing a value to a graph, specifying its index and the variable with the value to assign. This function should be called everytime that such value needs to be updated. + + void graphAssignValue(int graphIndex, double value) + +##### control() + +This method is the main method of Screen. It redraws the content and prints the actual screen when needed, all the interface depends on it. This method should be used in a loop in order to keep it running and refreshing the contents. It will be shown later in the Implementation section. + +##### increasePos() and decreasePos() + +These methods' sole task is to call the methods to increase or decrease the position of the cursor in the current menu displayed. This methods shouldn't be called directly, there is another method that uses them, though they can be used if we are in a menu screen, otherwise they might not work as expected. + +##### goTo() + +This method changes the screen and allows to enter a new screen if an option in a menu is currently selected, for that, it needs to check the content currently displayed and retrieve the destination indexes and types using the methods from Menu. Furthermore, it is in charge of storing the current screen as a previous screen inside of the screen to be displayed, where it makes use the other methods defined in Menu, Graph, etc. + ### Keyboard class ### Implementation \ No newline at end of file From d6c3edfa73d7d1375623d26a3c131961975b4833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Araujo=20Galav=C3=ADz?= Date: Sat, 8 Apr 2023 07:10:33 +0000 Subject: [PATCH 4/6] =?UTF-8?q?=E2=80=9EReadme.md=E2=80=9C=20=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 71ca322..bbac414 100644 --- a/Readme.md +++ b/Readme.md @@ -39,6 +39,15 @@ Macros are defined to help use the library easily, making possible to modify the ## Content types +This library depends on some indexes to display content, that's why it's important to keep in mind that all screens are described by two parameters: Content Type and Content Index. Indexes are assigned according to the order in which the elements were created. + +On the other hand, type is defined according to the following. + +1. Menu +2. Graph +3. Setting + +Those integer values are recognized by screen and lead to the different content screens configured. ## Classes @@ -490,8 +499,93 @@ These methods' sole task is to call the methods to increase or decrease the posi ##### goTo() -This method changes the screen and allows to enter a new screen if an option in a menu is currently selected, for that, it needs to check the content currently displayed and retrieve the destination indexes and types using the methods from Menu. Furthermore, it is in charge of storing the current screen as a previous screen inside of the screen to be displayed, where it makes use the other methods defined in Menu, Graph, etc. +This method changes the screen and allows to enter a new screen if an option in a menu is currently selected, for that, it needs to check the content currently displayed and retrieve the destination indexes and types using the methods from Menu. Furthermore, it is in charge of storing the current screen as a previous screen inside of the screen to be displayed, where it makes use the other methods defined in Menu, Graph, etc. That is done in the following lines: + + void goTo(){ + if(this->contentType == 0){ + int newScreen = this->menu[this->currentScreen].extractDestinationIndex(); + int newContentType = this->menu[this->currentScreen].extractDestinationType(); + if (newContentType == 0){ + this->menu[newScreen].setPreviousScreen(this->currentScreen); + this->menu[newScreen].setPreviousContentType(this->contentType); + } + else if(newContentType == 1){ + this->graph[newScreen].setPreviousScreen(this->currentScreen); + this->graph[newScreen].setPreviousContentType(this->contentType); + this->graph[newScreen].reset(); + this->graph[newScreen].redrawFlag(); + } + else if(newContentType == 2){ + + } + this->contentType = newContentType; + this->currentScreen = newScreen; + this->redraw = true; + } + } + +##### goBack() + +This method does the opposite to the previous one, it retrieves the data of the previous screen stored in the current screen and sets the former as the current screen in the attributes of the object Screen, that way it allows the user to return to a preceding screen. + +##### plusAction() and minusAction() + +Depending on the type of screen the user is at, this methods determine whether the options plus and minus increase or decrease positions or modify variables or do something else. This methods are planned to be used from Keyboard. ### Keyboard class -### Implementation \ No newline at end of file +This class permits the usage of buttons to control the interface. + +#### Attributes + +The attributes used in this class are: + + private: + + byte goTo; + byte goBack; + byte plus; + byte minus; + byte debounceTime; + + Screen *screen; + +Where: + +* **goTo**, **goBack**, **plus** and **minus**: This variables hold the pins where these buttons are configured. +* ***screen**: This is a pointer to the object Screen created, giving place to the interaction between both of them. + +#### Methods + +The methods listed below are defined for Keyboard: + +##### Keyboard + +This is the constructor for Keyboard, here the buttons are defined and the pointer to the Screen object is selected. The prototype is: + + Keyboard(byte goTo, byte goBack, byte plus, byte minus, byte debounceTime, Screen * screen) + +The debounceTime parameter is a number in milliseconds that the buttons are going to be checked by the debouncing methods. + +##### Debouncing functions + +This group of methods is used to eliminate the effect of physical buttons bouncing, waiting a specified number of millisenconds. This depends on REFRESH, as is shown belown: + + void checkGoTo(){ + static char cont; + if(digitalRead(this->goTo) == LOW) + cont++; + else + cont = 0; + if(cont == debounceTime/REFRESH){ + this->screen->goTo(); + } + } + +##### control() + +Finally, the debouncing methods are called in the main method of Keyboard, which is control(), this should run in a loop, to make it work continuously. + +### Implementation + +In the example... \ No newline at end of file From 2645edfcf1d5d6d11cb9d08e62f39497e212216e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Araujo=20Galav=C3=ADz?= Date: Sat, 8 Apr 2023 07:12:23 +0000 Subject: [PATCH 5/6] =?UTF-8?q?=E2=80=9EReadme.md=E2=80=9C=20=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index bbac414..78c267f 100644 --- a/Readme.md +++ b/Readme.md @@ -582,10 +582,11 @@ This group of methods is used to eliminate the effect of physical buttons bounci } } +These methods are **checkGoTo()**, **checkGoBack()**, **checkPlus()** and **checkMinus()**. ##### control() Finally, the debouncing methods are called in the main method of Keyboard, which is control(), this should run in a loop, to make it work continuously. ### Implementation -In the example... \ No newline at end of file +In the example provided... \ No newline at end of file From ee1a5c20a7a62eb3debfb57a59847cf169ebd92c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Araujo=20Galav=C3=ADz?= Date: Mon, 10 Apr 2023 02:29:14 +0000 Subject: [PATCH 6/6] =?UTF-8?q?=E2=80=9EReadme.md=E2=80=9C=20=C3=A4ndern?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Readme.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 78c267f..1777518 100644 --- a/Readme.md +++ b/Readme.md @@ -589,4 +589,62 @@ Finally, the debouncing methods are called in the main method of Keyboard, which ### Implementation -In the example provided... \ No newline at end of file +The library already includes the creation of the Adafruit_SSD1306 object as display. It can be modified to match other display controllers. + + Adafruit_SSD1306 display(DISP_WIDTH, DISP_HEIGHT, &Wire, -1); + +In the example provided, an integer variable *i* is declared to test the graphs. + + int i = 0; + +To use the interface, it is important to create a Screen and a Keyboard objects, in order to have full control of the interface, that is done in the lines below: + + Screen screen; + Keyboard keyboard(13, 12, 14, 27, 30, &screen); + +Then, in the setup() function of the program, it's necessary call the configure() method from screen to establish communication, afterwards, the menus and graphs are created. Finally the options in the menus are configured. + + screen.createMenu(128, 13); //Menu 0 + screen.createMenu(128, 13); //Menu 1 + + screen.createVGraph("Grafica 1", 25, 60, 40, 40, 0, 100, 10, 0); //Graph 0 + screen.createHGraph("Grafica 2", 10, 40, 100, 20, 0, 100, 10, 0); //Graph 1 + screen.createCGraph("Grafica 3", 30, 50, 75, 30, 0, 100, 0, 1000, 25, 250, 0); //Graph 2 + + screen.createOption(0, "Vertical graph", 1, 0); + //Creates the first option in Menu 0, directing to a graph (contentType = 1 (Graph)), 0 (Graph 0) + screen.createOption(0, "Horizontal graph", 1, 1); + screen.createOption(0, "Cartesian graph", 1, 2); + screen.createOption(0, "Extra option", 0, 1); + + screen.createOption(1, "Test", 1, 3); + screen.createOption(1, "Working?", 1, 4); + +There are some lines commented below which can be used to test the methods from Screen, to manipulate the interface. These can be tested with a keyboard if configured too. + + // screen.increasePos(); + // screen.increasePos(); + // screen.goTo(); + // screen.graphAssignValue(2, 50); + // screen.goBack(); + // screen.increasePos(); + // screen.goTo(); + // screen.goBack(); + // screen.decreasePos(); + +In the loop() function, we find the main methods of Screen and Keyboard, which need to be run continuously. And then, we also manipulate *i* to change its value and be able to plot a sawtooth signal. This value is passed to graph 1 and graph 2. + + screen.control(); //Controls the screen and redraws if needed + keyboard.control(); + + if(i <= 100){ + screen.graphAssignValue(1, i); //Assigning a demo value to Graph 1 + screen.graphAssignValue(2, i); //Assigning a demo value to Graph 2 + i++; + } + else + i = 0; + + delay(REFRESH); //Refresh time (approx) + +The last delay is the time at which the display will refresh. \ No newline at end of file