FactoryTest.ino 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. #include <M5Stack.h>
  2. #include "utility/MPU9250.h"
  3. #include "WiFi.h"
  4. extern const unsigned char gImage_logoM5[];
  5. extern const unsigned char m5stack_startup_music[];
  6. #ifndef min
  7. #define min(a,b) (((a) < (b)) ? (a) : (b))
  8. #endif
  9. MPU9250 IMU;
  10. void startupLogo() {
  11. static uint8_t brightness, pre_brightness;
  12. uint32_t length = strlen((char*)m5stack_startup_music);
  13. M5.Lcd.setBrightness(0);
  14. M5.Lcd.pushImage(0, 0, 320, 240, (uint16_t *)gImage_logoM5);
  15. for(int i=0; i<length; i++) {
  16. dacWrite(SPEAKER_PIN, m5stack_startup_music[i]>>2);
  17. delayMicroseconds(40);
  18. brightness = (i/157);
  19. if(pre_brightness != brightness) {
  20. pre_brightness = brightness;
  21. M5.Lcd.setBrightness(brightness);
  22. }
  23. }
  24. for(int i=255; i>=0; i--) {
  25. M5.Lcd.setBrightness(i);
  26. if(i<=32) {
  27. dacWrite(SPEAKER_PIN, i);
  28. }
  29. delay(2);
  30. }
  31. M5.Lcd.fillScreen(BLACK);
  32. delay(800);
  33. }
  34. //TF card test
  35. void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
  36. Serial.printf("Listing directory: %s\n", dirname);
  37. M5.Lcd.printf("Listing directory: %s\n", dirname);
  38. File root = fs.open(dirname);
  39. if(!root){
  40. Serial.println("Failed to open directory");
  41. M5.Lcd.println("Failed to open directory");
  42. return;
  43. }
  44. if(!root.isDirectory()){
  45. Serial.println("Not a directory");
  46. M5.Lcd.println("Not a directory");
  47. return;
  48. }
  49. File file = root.openNextFile();
  50. while(file){
  51. if(file.isDirectory()){
  52. Serial.print(" DIR : ");
  53. M5.Lcd.print(" DIR : ");
  54. Serial.println(file.name());
  55. M5.Lcd.println(file.name());
  56. if(levels){
  57. listDir(fs, file.name(), levels -1);
  58. }
  59. } else {
  60. Serial.print(" FILE: ");
  61. M5.Lcd.print(" FILE: ");
  62. Serial.print(file.name());
  63. M5.Lcd.print(file.name());
  64. Serial.print(" SIZE: ");
  65. M5.Lcd.print(" SIZE: ");
  66. Serial.println(file.size());
  67. M5.Lcd.println(file.size());
  68. }
  69. file = root.openNextFile();
  70. }
  71. }
  72. void readFile(fs::FS &fs, const char * path) {
  73. Serial.printf("Reading file: %s\n", path);
  74. M5.Lcd.printf("Reading file: %s\n", path);
  75. File file = fs.open(path);
  76. if(!file){
  77. Serial.println("Failed to open file for reading");
  78. M5.Lcd.println("Failed to open file for reading");
  79. return;
  80. }
  81. Serial.print("Read from file: ");
  82. M5.Lcd.print("Read from file: ");
  83. while(file.available()){
  84. int ch = file.read();
  85. Serial.write(ch);
  86. M5.Lcd.write(ch);
  87. }
  88. }
  89. void writeFile(fs::FS &fs, const char * path, const char * message){
  90. Serial.printf("Writing file: %s\n", path);
  91. M5.Lcd.printf("Writing file: %s\n", path);
  92. File file = fs.open(path, FILE_WRITE);
  93. if(!file){
  94. Serial.println("Failed to open file for writing");
  95. M5.Lcd.println("Failed to open file for writing");
  96. return;
  97. }
  98. if(file.print(message)){
  99. Serial.println("File written");
  100. M5.Lcd.println("File written");
  101. } else {
  102. Serial.println("Write failed");
  103. M5.Lcd.println("Write failed");
  104. }
  105. }
  106. void buttons_test() {
  107. if(M5.BtnA.wasPressed()) {
  108. M5.Lcd.printf("A");
  109. Serial.printf("A");
  110. }
  111. if(M5.BtnB.wasPressed()) {
  112. M5.Lcd.printf("B");
  113. Serial.printf("B");
  114. }
  115. if(M5.BtnC.wasPressed()) {
  116. M5.Lcd.printf("C");
  117. Serial.printf("C");
  118. }
  119. }
  120. void wifi_test() {
  121. WiFi.mode(WIFI_STA);
  122. WiFi.disconnect();
  123. delay(100);
  124. Serial.println("scan start");
  125. M5.Lcd.println("scan start");
  126. // WiFi.scanNetworks will return the number of networks found
  127. int n = WiFi.scanNetworks();
  128. Serial.println("scan done");
  129. M5.Lcd.println("scan done");
  130. if (n == 0) {
  131. Serial.println("no networks found");
  132. M5.Lcd.println("no networks found");
  133. } else {
  134. Serial.print(n);
  135. M5.Lcd.print(n);
  136. Serial.println(" networks found");
  137. M5.Lcd.println(" networks found");
  138. for (int i = 0; i < n; ++i) {
  139. // Print SSID and RSSI for each network found
  140. Serial.print(i + 1);
  141. M5.Lcd.print(i + 1);
  142. Serial.print(": ");
  143. M5.Lcd.print(": ");
  144. Serial.print(WiFi.SSID(i));
  145. M5.Lcd.print(WiFi.SSID(i));
  146. Serial.print(" (");
  147. M5.Lcd.print(" (");
  148. Serial.print(WiFi.RSSI(i));
  149. M5.Lcd.print(WiFi.RSSI(i));
  150. Serial.print(")");
  151. M5.Lcd.print(")");
  152. Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
  153. M5.Lcd.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
  154. delay(5);
  155. }
  156. }
  157. Serial.println("");
  158. M5.Lcd.println("");
  159. }
  160. /*
  161. bool gpio_test_flg = 0;
  162. void GPIO_test() {
  163. // uint8_t gpio_table[] = {23,19,18,3,16,21,2,12,15,26,1,17,22,5,13,0,34};
  164. uint8_t gpio_table[] = {12,2,21,16,3,18,19,23,15,0,13,5,22,17,1,26,25};
  165. // while(1)
  166. {
  167. for (int i = 0; i<=sizeof(gpio_table) / sizeof(gpio_table[0]); i++) {
  168. pinMode(gpio_table[i], OUTPUT);
  169. }
  170. for(int i=0; i<=sizeof(gpio_table)/sizeof(gpio_table[0]); i++) {
  171. digitalWrite(gpio_table[i], 1);
  172. delay(50);
  173. digitalWrite(gpio_table[i], 0);
  174. delay(50);
  175. digitalWrite(gpio_table[i], 1);
  176. delay(50);
  177. digitalWrite(gpio_table[i], 0);
  178. delay(50);
  179. }
  180. }
  181. }
  182. void adc_test() {
  183. int count = 10;
  184. pinMode(35, INPUT);
  185. pinMode(36, INPUT);
  186. pinMode(34, INPUT);
  187. M5.Lcd.fillScreen(BLACK);
  188. while(count--) {
  189. M5.Lcd.setCursor(0, 10);
  190. M5.Lcd.setTextColor(WHITE, BLACK);
  191. M5.Lcd.setTextSize(2);
  192. M5.Lcd.printf("ADC35:%d\r\nADC36:%d\r\nADC34:%d\r\n", analogRead(35), analogRead(36), analogRead(34));
  193. delay(500);
  194. }
  195. }
  196. */
  197. unsigned long testLines(uint16_t color)
  198. {
  199. unsigned long start, t;
  200. int x1, y1, x2, y2,
  201. w = M5.Lcd.width(),
  202. h = M5.Lcd.height();
  203. M5.Lcd.fillScreen(TFT_BLACK);
  204. x1 = y1 = 0;
  205. y2 = h - 1;
  206. start = micros();
  207. for (x2 = 0; x2 < w; x2 += 6)
  208. M5.Lcd.drawLine(x1, y1, x2, y2, color);
  209. x2 = w - 1;
  210. for (y2 = 0; y2 < h; y2 += 6)
  211. M5.Lcd.drawLine(x1, y1, x2, y2, color);
  212. t = micros() - start; // fillScreen doesn't count against timing
  213. M5.Lcd.fillScreen(TFT_BLACK);
  214. x1 = w - 1;
  215. y1 = 0;
  216. y2 = h - 1;
  217. start = micros();
  218. for (x2 = 0; x2 < w; x2 += 6)
  219. M5.Lcd.drawLine(x1, y1, x2, y2, color);
  220. x2 = 0;
  221. for (y2 = 0; y2 < h; y2 += 6)
  222. M5.Lcd.drawLine(x1, y1, x2, y2, color);
  223. t += micros() - start;
  224. M5.Lcd.fillScreen(TFT_BLACK);
  225. x1 = 0;
  226. y1 = h - 1;
  227. y2 = 0;
  228. start = micros();
  229. for (x2 = 0; x2 < w; x2 += 6)
  230. M5.Lcd.drawLine(x1, y1, x2, y2, color);
  231. x2 = w - 1;
  232. for (y2 = 0; y2 < h; y2 += 6)
  233. M5.Lcd.drawLine(x1, y1, x2, y2, color);
  234. t += micros() - start;
  235. M5.Lcd.fillScreen(TFT_BLACK);
  236. x1 = w - 1;
  237. y1 = h - 1;
  238. y2 = 0;
  239. start = micros();
  240. for (x2 = 0; x2 < w; x2 += 6)
  241. M5.Lcd.drawLine(x1, y1, x2, y2, color);
  242. x2 = 0;
  243. for (y2 = 0; y2 < h; y2 += 6)
  244. M5.Lcd.drawLine(x1, y1, x2, y2, color);
  245. return micros() - start;
  246. }
  247. unsigned long testFastLines(uint16_t color1, uint16_t color2)
  248. {
  249. unsigned long start;
  250. int x, y, w = M5.Lcd.width(), h = M5.Lcd.height();
  251. M5.Lcd.fillScreen(TFT_BLACK);
  252. start = micros();
  253. for (y = 0; y < h; y += 5)
  254. M5.Lcd.drawFastHLine(0, y, w, color1);
  255. for (x = 0; x < w; x += 5)
  256. M5.Lcd.drawFastVLine(x, 0, h, color2);
  257. return micros() - start;
  258. }
  259. unsigned long testRects(uint16_t color)
  260. {
  261. unsigned long start;
  262. int n, i, i2,
  263. cx = M5.Lcd.width() / 2,
  264. cy = M5.Lcd.height() / 2;
  265. M5.Lcd.fillScreen(TFT_BLACK);
  266. n = min(M5.Lcd.width(), M5.Lcd.height());
  267. start = micros();
  268. for (i = 2; i < n; i += 6)
  269. {
  270. i2 = i / 2;
  271. M5.Lcd.drawRect(cx - i2, cy - i2, i, i, color);
  272. }
  273. return micros() - start;
  274. }
  275. unsigned long testFilledRects(uint16_t color1, uint16_t color2)
  276. {
  277. unsigned long start, t = 0;
  278. int n, i, i2,
  279. cx = M5.Lcd.width() / 2 - 1,
  280. cy = M5.Lcd.height() / 2 - 1;
  281. M5.Lcd.fillScreen(TFT_BLACK);
  282. n = min(M5.Lcd.width(), M5.Lcd.height());
  283. for (i = n - 1; i > 0; i -= 6)
  284. {
  285. i2 = i / 2;
  286. start = micros();
  287. M5.Lcd.fillRect(cx - i2, cy - i2, i, i, color1);
  288. t += micros() - start;
  289. // Outlines are not included in timing results
  290. M5.Lcd.drawRect(cx - i2, cy - i2, i, i, color2);
  291. }
  292. return t;
  293. }
  294. unsigned long testFilledCircles(uint8_t radius, uint16_t color)
  295. {
  296. unsigned long start;
  297. int x, y, w = M5.Lcd.width(), h = M5.Lcd.height(), r2 = radius * 2;
  298. M5.Lcd.fillScreen(TFT_BLACK);
  299. start = micros();
  300. for (x = radius; x < w; x += r2)
  301. {
  302. for (y = radius; y < h; y += r2)
  303. {
  304. M5.Lcd.fillCircle(x, y, radius, color);
  305. }
  306. }
  307. return micros() - start;
  308. }
  309. unsigned long testCircles(uint8_t radius, uint16_t color)
  310. {
  311. unsigned long start;
  312. int x, y, r2 = radius * 2,
  313. w = M5.Lcd.width() + radius,
  314. h = M5.Lcd.height() + radius;
  315. // Screen is not cleared for this one -- this is
  316. // intentional and does not affect the reported time.
  317. start = micros();
  318. for (x = 0; x < w; x += r2)
  319. {
  320. for (y = 0; y < h; y += r2)
  321. {
  322. M5.Lcd.drawCircle(x, y, radius, color);
  323. }
  324. }
  325. return micros() - start;
  326. }
  327. unsigned long testTriangles()
  328. {
  329. unsigned long start;
  330. int n, i, cx = M5.Lcd.width() / 2 - 1,
  331. cy = M5.Lcd.height() / 2 - 1;
  332. M5.Lcd.fillScreen(TFT_BLACK);
  333. n = min(cx, cy);
  334. start = micros();
  335. for (i = 0; i < n; i += 5)
  336. {
  337. M5.Lcd.drawTriangle(
  338. cx, cy - i, // peak
  339. cx - i, cy + i, // bottom left
  340. cx + i, cy + i, // bottom right
  341. M5.Lcd.color565(0, 0, i));
  342. }
  343. return micros() - start;
  344. }
  345. unsigned long testFilledTriangles()
  346. {
  347. unsigned long start, t = 0;
  348. int i, cx = M5.Lcd.width() / 2 - 1,
  349. cy = M5.Lcd.height() / 2 - 1;
  350. M5.Lcd.fillScreen(TFT_BLACK);
  351. start = micros();
  352. for (i = min(cx, cy); i > 10; i -= 5)
  353. {
  354. start = micros();
  355. M5.Lcd.fillTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
  356. M5.Lcd.color565(0, i, i));
  357. t += micros() - start;
  358. M5.Lcd.drawTriangle(cx, cy - i, cx - i, cy + i, cx + i, cy + i,
  359. M5.Lcd.color565(i, i, 0));
  360. }
  361. return t;
  362. }
  363. unsigned long testRoundRects()
  364. {
  365. unsigned long start;
  366. int w, i, i2,
  367. cx = M5.Lcd.width() / 2 - 1,
  368. cy = M5.Lcd.height() / 2 - 1;
  369. M5.Lcd.fillScreen(TFT_BLACK);
  370. w = min(M5.Lcd.width(), M5.Lcd.height());
  371. start = micros();
  372. for (i = 0; i < w; i += 6)
  373. {
  374. i2 = i / 2;
  375. M5.Lcd.drawRoundRect(cx - i2, cy - i2, i, i, i / 8, M5.Lcd.color565(i, 0, 0));
  376. }
  377. return micros() - start;
  378. }
  379. unsigned long testFilledRoundRects()
  380. {
  381. unsigned long start;
  382. int i, i2,
  383. cx = M5.Lcd.width() / 2 - 1,
  384. cy = M5.Lcd.height() / 2 - 1;
  385. M5.Lcd.fillScreen(TFT_BLACK);
  386. start = micros();
  387. for (i = min(M5.Lcd.width(), M5.Lcd.height()); i > 20; i -= 6)
  388. {
  389. i2 = i / 2;
  390. M5.Lcd.fillRoundRect(cx - i2, cy - i2, i, i, i / 8, M5.Lcd.color565(0, i, 0));
  391. }
  392. return micros() - start;
  393. }
  394. // the setup routine runs once when M5Stack starts up
  395. void setup() {
  396. //gpio test
  397. // pinMode(BUTTON_A_PIN, INPUT_PULLUP);
  398. // if(digitalRead(BUTTON_A_PIN) == 0) {
  399. // gpio_test_flg = 1;
  400. // }
  401. // if (gpio_test_flg) {
  402. // GPIO_test();
  403. // }
  404. // initialize the M5Stack object
  405. M5.begin();
  406. /*
  407. Power chip connected to gpio21, gpio22, I2C device
  408. Set battery charging voltage and current
  409. If used battery, please call this function in your project
  410. */
  411. M5.Power.begin();
  412. // dac test
  413. // if (gpio_test_flg)
  414. // {
  415. // adc_test();
  416. // }
  417. startupLogo();
  418. Wire.begin();
  419. // Lcd display
  420. M5.Lcd.setBrightness(100);
  421. M5.Lcd.fillScreen(BLACK);
  422. M5.Lcd.setCursor(10, 10);
  423. M5.Lcd.setTextColor(WHITE);
  424. M5.Lcd.setTextSize(1);
  425. M5.Lcd.printf("Display Test!");
  426. delay(300);
  427. M5.Lcd.fillScreen(WHITE);
  428. delay(150);
  429. M5.Lcd.fillScreen(RED);
  430. delay(150);
  431. M5.Lcd.fillScreen(GREEN);
  432. delay(150);
  433. M5.Lcd.fillScreen(BLUE);
  434. delay(150);
  435. M5.Lcd.fillScreen(BLACK);
  436. delay(150);
  437. // draw graphic
  438. yield();
  439. Serial.print(F("Lines "));
  440. yield();
  441. Serial.println(testLines(TFT_CYAN));
  442. //total+=testLines(TFT_CYAN);
  443. //delay(500);
  444. yield();
  445. Serial.print(F("Horiz/Vert Lines "));
  446. yield();
  447. Serial.println(testFastLines(TFT_RED, TFT_BLUE));
  448. //total+=testFastLines(TFT_RED, TFT_BLUE);
  449. //delay(500);
  450. yield();
  451. Serial.print(F("Rectangles (outline) "));
  452. yield();
  453. Serial.println(testRects(TFT_GREEN));
  454. //total+=testRects(TFT_GREEN);
  455. //delay(500);
  456. yield();
  457. Serial.print(F("Rectangles (filled) "));
  458. yield();
  459. Serial.println(testFilledRects(TFT_YELLOW, TFT_MAGENTA));
  460. //total+=testFilledRects(TFT_YELLOW, TFT_MAGENTA);
  461. //delay(500);
  462. yield();
  463. Serial.print(F("Circles (filled) "));
  464. yield();
  465. Serial.println(testFilledCircles(10, TFT_MAGENTA));
  466. //total+= testFilledCircles(10, TFT_MAGENTA);
  467. yield();
  468. Serial.print(F("Circles (outline) "));
  469. yield();
  470. Serial.println(testCircles(10, TFT_WHITE));
  471. //total+=testCircles(10, TFT_WHITE);
  472. //delay(500);
  473. yield();
  474. Serial.print(F("Triangles (outline) "));
  475. yield();
  476. Serial.println(testTriangles());
  477. //total+=testTriangles();
  478. //delay(500);
  479. yield();
  480. Serial.print(F("Triangles (filled) "));
  481. yield();
  482. Serial.println(testFilledTriangles());
  483. //total += testFilledTriangles();
  484. //delay(500);
  485. yield();
  486. Serial.print(F("Rounded rects (outline) "));
  487. yield();
  488. Serial.println(testRoundRects());
  489. //total+=testRoundRects();
  490. //delay(500);
  491. yield();
  492. Serial.print(F("Rounded rects (filled) "));
  493. yield();
  494. Serial.println(testFilledRoundRects());
  495. //total+=testFilledRoundRects();
  496. //delay(500);
  497. yield();
  498. Serial.println(F("Done!"));
  499. yield();
  500. //rand draw
  501. int i = 250;
  502. while(--i) {
  503. M5.Lcd.fillTriangle(random(M5.Lcd.width()-1), random(M5.Lcd.height()-1), random(M5.Lcd.width()-1), random(M5.Lcd.height()-1), random(M5.Lcd.width()-1), random(M5.Lcd.height()-1), random(0xfffe));
  504. }
  505. for(int i=255; i>=0; i--) {
  506. M5.Lcd.setBrightness(i);
  507. delay(2);
  508. }
  509. //wifi test
  510. M5.Lcd.setCursor(0, 10);
  511. M5.Lcd.fillScreen(BLACK);
  512. for(int i=0; i<200; i++) {
  513. M5.Lcd.setBrightness(i);
  514. delay(2);
  515. }
  516. byte c = IMU.readByte(MPU9250_ADDRESS, WHO_AM_I_MPU9250);
  517. Serial.print("MPU9250 "); Serial.print("I AM "); Serial.print(c, HEX);
  518. Serial.print(" I should be "); Serial.println(0x71, HEX);
  519. Serial.println("");
  520. M5.Lcd.setCursor(20,0); M5.Lcd.print("MPU9250");
  521. M5.Lcd.setCursor(0,10); M5.Lcd.print("I AM");
  522. M5.Lcd.setCursor(0,20); M5.Lcd.print(c, HEX);
  523. M5.Lcd.setCursor(0,30); M5.Lcd.print("I Should Be");
  524. M5.Lcd.setCursor(0,40); M5.Lcd.println(0x71, HEX);
  525. M5.Lcd.println();
  526. delay(100);
  527. IMU.initMPU9250();
  528. // Initialize device for active mode read of acclerometer, gyroscope, and
  529. // temperature
  530. Serial.println("MPU9250 initialized for active data mode....");
  531. // Read the WHO_AM_I register of the magnetometer, this is a good test of
  532. // communication
  533. byte d = IMU.readByte(AK8963_ADDRESS, WHO_AM_I_AK8963);
  534. Serial.print("AK8963 "); Serial.print("I AM "); Serial.print(d, HEX);
  535. Serial.print(" I should be "); Serial.println(0x48, HEX);
  536. // M5.Lcd.fillScreen(BLACK);
  537. M5.Lcd.setCursor(20,100); M5.Lcd.print("AK8963");
  538. M5.Lcd.setCursor(0,110); M5.Lcd.print("I AM");
  539. M5.Lcd.setCursor(0,120); M5.Lcd.print(d, HEX);
  540. M5.Lcd.setCursor(0,130); M5.Lcd.print("I Should Be");
  541. M5.Lcd.setCursor(0,140); M5.Lcd.print(0x48, HEX);
  542. delay(1000);
  543. M5.Lcd.setCursor(0, 0);
  544. M5.Lcd.println("wifi test:");
  545. M5.Lcd.fillScreen(BLACK);
  546. wifi_test();
  547. delay(2000);
  548. // TF card test
  549. M5.Lcd.fillScreen(BLACK);
  550. M5.Lcd.setCursor(0, 10);
  551. M5.Lcd.printf("TF card test:\r\n");
  552. // digitalWrite(TFT_CS, 1);
  553. listDir(SD, "/", 0);
  554. writeFile(SD, "/hello.txt", "Hello world");
  555. readFile(SD, "/hello.txt");
  556. //Button test
  557. M5.Lcd.println();
  558. M5.Lcd.println();
  559. M5.Lcd.print("buttons Test:");
  560. M5.Lcd.setTextColor(RED);
  561. }
  562. // the loop routine runs over and over again forever
  563. void loop(){
  564. buttons_test();
  565. M5.update();
  566. }