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.

245 lines
9.6 KiB

  1. class Graph{ //ContentType (1)
  2. private:
  3. String title;
  4. char graphType; //'a' Vertical Bar, 'b' Horizontal Bar, 'c' Cartesian Graph
  5. //Assign whatever value in "configure(..." if a parameter is not required for the specified graphType
  6. double value; //For: Vertical Bar Horizontal Bar Cartesian
  7. double xpos; //For: Vertical Bar Horizontal Bar Cartesian
  8. double ypos; //For: Vertical Bar Horizontal Bar Cartesian
  9. double height; //For: Vertical Bar Horizontal Bar Cartesian
  10. double width; //For: Vertical Bar Horizontal Bar Cartesian
  11. double yminimum; //For: Vertical Bar Cartesian
  12. double ymaximum; //For: Vertical Bar Cartesian
  13. double xminimum; //For: Horizontal Bar Cartesian
  14. double xmaximum; //For: Horizontal Bar Cartesian
  15. double yStepSize; //For: Vertical Bar Cartesian
  16. double xStepSize; //For: Horizontal Bar Cartesian
  17. int digit; //For: Vertical Bar Horizontal Bar Cartesian
  18. double x;
  19. double yrange;
  20. double xrange;
  21. double ox;
  22. double oy;
  23. double count;
  24. double graphScale;
  25. bool redraw = true;
  26. int previousScreen = 0;
  27. int previousContentType = 0;
  28. public:
  29. //This method configures the graph created, defines its parameters according the type of graph selected.
  30. void configure(String title, char graphType, double xpos, double ypos, double width, double height,
  31. double yminimum, double ymaximum, double xminimum, double xmaximum, double yStepSize, double xStepSize, int digit){
  32. this->title = title;
  33. this->graphType = graphType;
  34. this->yminimum = yminimum;
  35. this->ymaximum = ymaximum;
  36. this->xminimum = xminimum;
  37. this->count = xminimum;
  38. this->xmaximum = xmaximum;
  39. this->height = height;
  40. this->width = width;
  41. this->yStepSize = yStepSize;
  42. this->xStepSize = xStepSize;
  43. this->digit = digit;
  44. this->xpos = xpos;
  45. this->ypos = ypos;
  46. switch(graphType){
  47. case 'a':
  48. this->yrange = ymaximum - yminimum;
  49. this->graphScale = (yStepSize) * (height / this->yrange) - .001; //Adjusts the scale of the graph, according to the range and the size of the step
  50. break;
  51. case 'b':
  52. this->xrange = xmaximum - xminimum;
  53. this->graphScale = (xStepSize) * (width / this->xrange) - .001; //Adjusts the scale of the graph, according to the range and the size of the step
  54. break;
  55. case 'c':
  56. this->yrange = ymaximum - yminimum;
  57. this->xrange = xmaximum - xminimum;
  58. break;
  59. }
  60. }
  61. void drawGraph(){
  62. double level, data, i;
  63. switch(graphType){
  64. case 'a':
  65. double my;
  66. if (this->redraw) { //Prints the labels
  67. display.clearDisplay();
  68. this->redraw = false;
  69. display.fillRect(0, 0, 127 , 14, SSD1306_WHITE);
  70. display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  71. display.setTextSize(1);
  72. display.setCursor(2, 4);
  73. display.println(this->title);
  74. for (i = 0; i <= this->height; i += this->graphScale) {
  75. my = this->ypos - this->height + i;
  76. display.drawFastHLine(this->xpos + this->width + 1, my, 5, SSD1306_WHITE);
  77. // draw lables
  78. display.setTextSize(1);
  79. display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  80. display.setCursor(this->xpos + this->width + 12, my - 3 );
  81. data = this->ymaximum - ( i * (this->yStepSize / this->graphScale));
  82. display.print(data, this->digit);
  83. }
  84. }
  85. // compute level of bar graph that is scaled to the height and the hi and low vals
  86. // this is needed to accompdate for +/- range
  87. level = (this->height * (((this->value - this->yminimum) / (this->yrange))));
  88. // draw the bar graph
  89. // write a upper and lower bar to minimize flicker cause by blanking out bar and redraw on update
  90. display.drawRect(this->xpos, this->ypos - this->height, this->width, this->height, SSD1306_WHITE);
  91. display.fillRect(this->xpos, this->ypos - this->height, this->width, this->height - level, SSD1306_BLACK);
  92. display.drawRect(this->xpos, this->ypos - this->height, this->width, this->height, SSD1306_WHITE);
  93. display.fillRect(this->xpos, this->ypos - level, this->width, level, SSD1306_WHITE);
  94. // up until now print sends data to a video buffer NOT the screen
  95. // this call sends the data to the screen
  96. display.display();
  97. break;
  98. case 'b':
  99. if (this->redraw) {
  100. display.clearDisplay();
  101. this->redraw = false;
  102. display.fillRect(0, 0, 127 , 16, SSD1306_WHITE);
  103. display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  104. display.setTextSize(1);
  105. display.setCursor(2, 4);
  106. display.println(this->title);
  107. // draw the text
  108. for (i = 0; i <= this->width; i += this->graphScale) {
  109. display.drawFastVLine(i + this->xpos , this->ypos , 5, SSD1306_WHITE);
  110. // draw lables
  111. display.setTextSize(1);
  112. display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  113. display.setCursor(i + this->xpos , this->ypos + 10);
  114. // addling a small value to eliminate round off errors
  115. // this val may need to be adjusted
  116. data = ( i * (this->xStepSize / this->graphScale)) + this->xminimum + 0.00001;
  117. display.print(data, this->digit);
  118. }
  119. }
  120. // compute level of bar graph that is scaled to the width and the hi and low vals
  121. // this is needed to accompdate for +/- range capability
  122. // draw the bar graph
  123. // write a upper and lower bar to minimize flicker cause by blanking out bar and redraw on update
  124. level = (this->width * (((this->value - this->xminimum) / (this->xmaximum - this->xminimum))));
  125. display.fillRect(this->xpos + level, this->ypos - this->height, this->width - level, this->height, SSD1306_BLACK);
  126. display.drawRect(this->xpos, this->ypos - this->height, this->width, this->height, SSD1306_WHITE);
  127. display.fillRect(this->xpos, this->ypos - this->height, level, this->height, SSD1306_WHITE);
  128. // up until now print sends data to a video buffer NOT the screen
  129. // this call sends the data to the screen
  130. display.display();
  131. break;
  132. case 'c':
  133. double temp;
  134. if (this->redraw == true) {
  135. this->redraw = false;
  136. display.clearDisplay();
  137. display.fillRect(0, 0, 127 , 16, SSD1306_WHITE);
  138. display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
  139. display.setTextSize(1);
  140. display.setCursor(2, 4);
  141. display.println(title);
  142. this->ox = (this->count - this->xminimum) * (this->width) / (this->xrange) + this->xpos;
  143. this->oy = (this->value - this->yminimum) * (- this->height) / (this->yrange) + this->ypos;
  144. // draw y scale
  145. display.setTextSize(1);
  146. display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  147. for ( i = this->yminimum; i <= this->ymaximum; i += this->yStepSize) {
  148. // compute the transform
  149. // note my transform funcition is the same as the map function, except the map uses long and we need doubles
  150. temp = (i - this->yminimum) * (- this->height) / (this->ymaximum - this->yminimum) + this->ypos;
  151. if (i == 0) {
  152. display.drawFastHLine(this->xpos - 3, temp, this->width + 3, SSD1306_WHITE);
  153. }
  154. else {
  155. display.drawFastHLine(this->xpos - 3, temp, 3, SSD1306_WHITE);
  156. }
  157. display.setCursor(this->xpos - 27, temp - 3);
  158. display.println(i, this->digit);
  159. }
  160. // draw x scale
  161. for (i = this->xminimum; i <= this->xmaximum; i += this->xStepSize) {
  162. // compute the transform
  163. display.setTextSize(1);
  164. display.setTextColor(SSD1306_WHITE, SSD1306_BLACK);
  165. temp = (i - this->xminimum) * (this->width) / (this->xrange) + this->xpos;
  166. if (i == 0) {
  167. display.drawFastVLine(temp, this->ypos - this->height, this->height + 3, SSD1306_WHITE);
  168. }
  169. else {
  170. display.drawFastVLine(temp, this->ypos, 3, SSD1306_WHITE);
  171. }
  172. display.setCursor(temp, this->ypos + 6);
  173. display.println(i, this->digit);
  174. }
  175. }
  176. // graph drawn now plot the data
  177. // the entire plotting code are these few lines...
  178. this->x = (this->count - this->xminimum) * (this->width) / (this->xrange) + this->xpos;
  179. this->value = (this->value - this->yminimum) * (- this->height) / (this->yrange) + this->ypos;
  180. display.drawLine(this->ox, this->oy, this->x, this->value, SSD1306_WHITE);
  181. display.drawLine(this->ox, this->oy - 1, this->x, this->value - 1, SSD1306_WHITE);
  182. this->ox = this->x;
  183. this->oy = this->value;
  184. // up until now print sends data to a video buffer NOT the screen
  185. // this call sends the data to the screen
  186. display.display();
  187. this->count += 1;
  188. if(this->ox >= (this->xpos + this->width)){
  189. this->redraw = true;
  190. this->count = xminimum;
  191. }
  192. }
  193. }
  194. void redrawFlag(){ // Activates the redraw bool to get the graph printed correctly
  195. this->redraw = true;
  196. this->count = xminimum;
  197. }
  198. void setPreviousScreen(int prev){
  199. this->previousScreen = prev;
  200. }
  201. void setPreviousContentType(int prev){
  202. this->previousContentType = prev;
  203. }
  204. int getPreviousScreen(){
  205. int prev = this->previousScreen;
  206. return prev;
  207. }
  208. int getPreviousContentType(){
  209. int prev = this->previousContentType;
  210. return prev;
  211. }
  212. void assignValue(double value){
  213. this->value = value;
  214. }
  215. void reset(){
  216. this->x = 0;
  217. }
  218. };