tasks.ino 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* Multi-core Task Handler*/
  2. TaskHandle_t primaryTask;
  3. TaskHandle_t secondaryTask;
  4. TaskHandle_t animationTask;
  5. SemaphoreHandle_t animationMutex;
  6. /* Semaphore for handling mutex */
  7. void createSemaphore() {
  8. animationMutex = xSemaphoreCreateMutex();
  9. xSemaphoreGive(animationMutex);
  10. }
  11. void mutexLock() {
  12. xSemaphoreTake(animationMutex, portMAX_DELAY);
  13. }
  14. void mutexUnlock() {
  15. xSemaphoreGive(animationMutex);
  16. }
  17. //Set the animation code, suppose to be used in core 0 only
  18. void setAnimationCode(char filename) {
  19. Serial.println("Updating animation frame to " + String(filename));
  20. mutexLock();
  21. animation = filename;
  22. mutexUnlock();
  23. }
  24. //Get the animation code, suppose to be used in core 1 only
  25. char getAnimationCode() {
  26. char anicode = 'a';
  27. mutexLock();
  28. anicode = animation;
  29. mutexUnlock();
  30. return anicode;
  31. }
  32. //Get the current state of the switch
  33. // true = After human pushed
  34. // false = After robot pushed
  35. bool getSwitchState() {
  36. int switchState = digitalRead(TOGGLE_SWITCH);
  37. return (switchState == 1);
  38. }
  39. //Set the WiFi interface mode of the ESP32 based on start flags or debug settings
  40. //Return true if developer mode, return false for default mode (auto mode)
  41. bool initPrimaryLogicNetworkMode() {
  42. clearFrame();
  43. bool switchPushed = getSwitchState();
  44. if (switchPushed || ENABLE_WIFI_DEBUG) {
  45. /* Switch was on when device power on. Start WiFi & Web Server */
  46. //Start AP and web server
  47. if (ENABLE_WIFI_DEBUG) {
  48. setAnimationCode('x'); //WiFi Error
  49. //Use WiFi client mode
  50. WiFi.mode(WIFI_STA); //Optional
  51. WiFi.begin(DEBUG_SSID, DEBUG_PWD);
  52. Serial.println("\nConnecting");
  53. while (WiFi.status() != WL_CONNECTED) {
  54. Serial.print(".");
  55. delay(100);
  56. }
  57. Serial.println("\nConnected to the WiFi network");
  58. Serial.print("Local IP: ");
  59. Serial.println(WiFi.localIP());
  60. setAnimationCode('w'); //WiFi Connected
  61. } else {
  62. //Set display to AP icon
  63. setAnimationCode('w');
  64. WiFi.softAP(AP_SSID, NULL);
  65. Serial.print("Manual mode started. SSID=" + String(AP_SSID) + " listening on : ");
  66. Serial.println(WiFi.softAPIP());
  67. //Setup DNS Server
  68. dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
  69. dnsServer.start(53, "*", WiFi.softAPIP());
  70. }
  71. // Start the web server
  72. registerAPIEndpoints();
  73. server.begin();
  74. return true;
  75. }
  76. return false;
  77. }
  78. /* Multi-core process definations */
  79. void startCoreTasks() {
  80. //Pin animation rendering routine to core 0
  81. xTaskCreatePinnedToCore(
  82. AnimationController, /* Task function. */
  83. "animator", /* name of task. */
  84. 8192, /* Stack size of task */
  85. NULL, /* parameter of the task */
  86. 2, /* priority of the task */
  87. &animationTask,
  88. 0);
  89. //Pin the primary task routine to core 1
  90. xTaskCreatePinnedToCore(
  91. PrimaryController, /* Task function. */
  92. "primary", /* name of task. */
  93. 24576, /* Stack size of task */
  94. NULL, /* parameter of the task */
  95. 1, /* priority of the task */
  96. &primaryTask, /* Task handle to keep track of created task */
  97. 1);
  98. //Pin secondary tasks to core 1 for handling AP movements
  99. xTaskCreate(
  100. SecondaryController,
  101. "secondary",
  102. 2048,
  103. NULL,
  104. 3,
  105. &secondaryTask
  106. );
  107. vTaskStartScheduler();
  108. }
  109. //For movement in development mode
  110. void SecondaryController(void* pvParameters) {
  111. Serial.println("Secondary logic process started on core " + String(xPortGetCoreID()));
  112. while (1) {
  113. if (movingActive) {
  114. if (movingDirection == 0) {
  115. forward(1);
  116. } else if (movingDirection == 1) {
  117. backward(1);
  118. } else if (movingDirection == 2) {
  119. rotateAntiClockwise(1);
  120. } else if (movingDirection == 3) {
  121. rotateClockwise(1);
  122. } else {
  123. // Unknown direction
  124. delay(100);
  125. return;
  126. }
  127. } else {
  128. // Delay for a while before checking again
  129. delay(100);
  130. }
  131. }
  132. }
  133. //For movement and primary logics
  134. void PrimaryController(void* pvParameters) {
  135. Serial.println("Primary logic process started on core " + String(xPortGetCoreID()));
  136. if (!initPrimaryLogicNetworkMode()) {
  137. /* Switch is off during power on. Use automatic mode */
  138. int seqCounter = 0; //Modify this value to change start state of seq
  139. bool switchPushed = false;
  140. while (1) {
  141. switchPushed = getSwitchState();
  142. if (switchPushed) {
  143. //Switch pushed
  144. executePushAnimationSequence(seqCounter);
  145. seqCounter++;
  146. }
  147. delay(1);
  148. }
  149. } else {
  150. while (1) {
  151. dnsServer.processNextRequest();
  152. delay(1);
  153. }
  154. }
  155. }
  156. //For animation rendering
  157. void AnimationController(void* pvParameters) {
  158. Serial.println("Animation render started on core " + String(xPortGetCoreID()));
  159. while (1) {
  160. char anicode = getAnimationCode();
  161. handleAnimationRendering(anicode);
  162. delay(1);
  163. }
  164. }