Advertisement
Guest User

MINI12864 ESP32 template code

a guest
Jul 26th, 2024
367
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.78 KB | Source Code | 0 0
  1. #include <Arduino.h>
  2. #include "SPI.h"
  3. #include "SD.h"
  4. #include "U8g2lib.h"
  5. #include "FastLED.h"
  6. /*
  7. for pinouts detail, refer to https://github.com/makerbase-mks/MKS-MINI12864-V3
  8. */
  9. // EXP1
  10. #define BEEPER 2
  11. #define BTN_ENC 0
  12. #define LCD_EN 15 // LCD_CS
  13. #define LCD_RS 12 // LCD_DC
  14. // LCD_D4 to 3.3v
  15. #define LCD_D5 4 // WS2811 data line
  16. // EXP2
  17. #define SPI_MISO 19 // SD_MISO
  18. #define SPI_SCK 18 // SPI_CLK
  19. #define BTN_EN1 16
  20. #define SPI_CS 5 // SD_CS
  21. #define BTN_EN2 17
  22. #define SPI_MOSI 23
  23. #define SPI_DET 3 // SD detect switch (low = inserted)
  24. // RESET to EN for remote reset function
  25. // instructors
  26. U8G2_ST7567_ENH_DG128064I_F_4W_HW_SPI u8g2(U8G2_R2, LCD_EN, LCD_RS);
  27. CRGB leds[3];
  28. // variables
  29. String statusMessage = "ready";
  30. unsigned long looptime0 = 0;
  31. // beeper variables
  32. unsigned long beeperRef = 0;
  33. int beeperCountTrack = 0, beeperInterval, beeperCount;
  34. bool beeperState = false;
  35. // button variables
  36. String buttonState; // will flag shortbutton or longbutton
  37. const int longButtonThreshold = 300; // in ms
  38. unsigned long buttonReference;
  39. // encoder variables
  40. String encoderRotation; // will flag CW or CCW
  41. int encoderRate = 3; // encoderCount increment based on rotation speed (1 = linear)
  42. volatile int encoderCount;
  43. // sd card variables
  44. bool sdReady = false; // true when SD card is properly setup
  45. /*
  46. simple beeper function
  47. non-blocking with adjustable beep count and interval
  48. use callBeeper() to start a beeping sequence
  49. */
  50. void callBeeper(int interval, int count) { // runs once, sets the beeping interval and counts
  51. beeperRef = millis();
  52. beeperInterval = interval;
  53. beeperCount = count;
  54. beeperCountTrack = 0;
  55. beeperState = true;
  56. }
  57. // runs in the main loop
  58. void beeper() {
  59. unsigned long currentMillis = millis();
  60. if (currentMillis - beeperRef >= beeperInterval) {
  61. beeperRef = currentMillis;
  62. beeperState = !beeperState; // toggle the beeper state
  63. if(beeperState) beeperCountTrack++;
  64. if(beeperCountTrack >= beeperCount) beeperState = false;
  65. }
  66. digitalWrite(BEEPER, beeperState ? HIGH : LOW);
  67. }
  68. /*
  69. simple button detect function
  70. hardware debounce compulsory
  71. assigns "shortpress" or "longpress" on the variable buttonState
  72. */
  73. void buttonISR() { // called by interrupt
  74. if (!digitalRead(BTN_ENC) && !buttonCheck) { // time sampling when button is pressed
  75. buttonReference = millis();
  76. buttonCheck = true;
  77. }
  78. if (digitalRead(BTN_ENC) && buttonCheck) { // if button is released and longbutton hasn't been registered
  79. buttonState = "shortpress";
  80. callBeeper(40, 1);
  81. buttonCheck = false;
  82. }
  83. }
  84. // runs in the main loop
  85. void button() {
  86. if (millis() - buttonReference > longButtonThreshold && buttonCheck) { // if time diff is above threshold
  87. buttonState = "longpress";
  88. callBeeper(120, 1);
  89. buttonCheck = false; // prevents shortbutton from being registered
  90. }
  91. }
  92. /*
  93. reliable rotary encoder reading function
  94. variable rate of change based on rotation speed for much faster value seeking
  95. hardware debounce compulsory
  96. */
  97. void encoderISR() { // called when BTN_EN1 is changing through interrupt
  98. static volatile int encoderLastStatus;
  99. static volatile unsigned long encoderReference;
  100. int encoderCurrentStatus = digitalRead(BTN_EN1);
  101. // check if these conditions are met before registering one pulse
  102. if (encoderCurrentStatus != encoderLastStatus && encoderCurrentStatus == 1){
  103. // calculate the interval since last call to determine the rate of change
  104. unsigned long encoderInterval = min((unsigned long)150, (millis() - encoderReference));
  105. int encoderIncrement = map(encoderInterval, 150, 10, 1, encoderRate);
  106. // sensing which way the encoder is turning and registering values
  107. if (digitalRead(BTN_EN2) != encoderCurrentStatus) {
  108. encoderCount -= encoderIncrement;
  109. encoderRotation = "CCW"; // will stay CCW until manually reset
  110. } else {
  111. encoderCount += encoderIncrement;
  112. encoderRotation = "CW"; // will stay CW until manually reset
  113. }
  114. callBeeper(40, 1);
  115. encoderReference = millis(); // save current time for the next cycle
  116. }
  117. encoderLastStatus = encoderCurrentStatus; // save last encoder status
  118. }
  119. /*
  120. sd card setup sketch
  121. initiates SD.begin based on card insertion
  122. will flag sdReady true when successfully initiated
  123. */
  124. void sdSetup() {
  125. static bool initiateSD = true;
  126. if (!digitalRead(SPI_DET)) { // if SD card is inserted
  127. if (initiateSD) { // if initialization hasn't been done
  128. for (int attempts = 0; attempts < 5; attempts++) { // attempts to initialize SD card
  129. if (SD.begin(SPI_CS)) { // if SD.begin() successfully initiated
  130. statusMessage = "SD initiated";
  131. sdReady = true;
  132. break; // exit loop on success
  133. }
  134. }
  135. if (!sdReady) { // if SD.begin() fail to initiate
  136. statusMessage = "SD fail to initiate";
  137. }
  138. initiateSD = false; // allows one initialization per card insertion
  139. }
  140. } else if (!initiateSD) { // if SD card is removed after initialization attempt
  141. SD.end();
  142. statusMessage = "SD removed";
  143. sdReady = false;
  144. initiateSD = true;
  145. }
  146. }
  147.  
  148. void screenUpdate() {
  149. u8g2.clearBuffer();
  150. u8g2.setFont(u8g2_font_profont11_tf);
  151. u8g2.drawStr(1, 8, "button");
  152. u8g2.setCursor(68, 8);
  153. u8g2.print(buttonState);
  154. u8g2.drawStr(1, 17, "encoder count");
  155. u8g2.setCursor(110, 17);
  156. u8g2.print(encoderCount);
  157. u8g2.drawStr(1, 26, "encoder rotation");
  158. u8g2.setCursor(110, 26);
  159. u8g2.print(encoderRotation);
  160. u8g2.drawStr(1, 35, "SD inserted?");
  161. if(!digitalRead(SPI_DET)) u8g2.drawStr(110, 35, "yes");
  162. else u8g2.drawStr(110, 35, "no");
  163. u8g2.drawStr(1, 44, "SD ready?");
  164. if(sdReady == true) u8g2.drawStr(110, 44, "yes");
  165. else u8g2.drawStr(110, 44, "no");
  166. u8g2.drawStr(1, 62, statusMessage.c_str());
  167. u8g2.sendBuffer();
  168. }
  169.  
  170. void setup() {
  171. // pinmodes
  172. pinMode(BEEPER, OUTPUT);
  173. pinMode(SPI_DET, INPUT_PULLUP);
  174. pinMode(BTN_EN1, INPUT_PULLUP);
  175. pinMode(BTN_EN2, INPUT_PULLUP);
  176. pinMode(BTN_ENC, INPUT_PULLUP);
  177. // interrupts
  178. attachInterrupt(digitalPinToInterrupt(BTN_ENC), buttonISR, CHANGE);
  179. attachInterrupt(digitalPinToInterrupt(BTN_EN1), encoderISR, CHANGE);
  180. // initialize
  181. SPI.begin(SPI_SCK, SPI_MISO, SPI_MOSI, SPI_CS);
  182. u8g2.begin();
  183. u8g2.setContrast(225);
  184. FastLED.addLeds<WS2811, LCD_D5, RGB>(leds, 3);
  185. leds[0] = CRGB(230,240,110); // under display LED
  186. leds[1] = CRGB(0,0,0); // under knob LED #1
  187. leds[2] = CRGB(0,0,0); // under knob LED #2
  188. FastLED.show();
  189. }
  190.  
  191. void loop() {
  192. beeper();
  193. if (millis() - looptime0 >= 200) {
  194. looptime0 = millis();
  195. screenUpdate();
  196. button();
  197. sdSetup();
  198. }
  199. }
  200. /*
  201. favourite backlight colours (rgb)
  202. * neutral white 250, 140, 110
  203. * vfd green 230, 240, 110
  204. * golden yellow 250, 160, 20
  205. * contextual orange 250, 50, 0
  206. */
Tags: Arduino
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement