tasks.ino 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. xTaskCreate(
  99. SecondaryController, // Task function
  100. "secondary", // Task name
  101. 2048, // Stack size
  102. NULL, // Task parameters
  103. 3, // Task priority
  104. &secondaryTask // Task handle
  105. );
  106. vTaskStartScheduler();
  107. }
  108. //For movement in development mode
  109. void SecondaryController(void* pvParameters) {
  110. Serial.println("Secondary logic process started on core " + String(xPortGetCoreID()));
  111. while (1) {
  112. if (movingActive) {
  113. if (movingDirection == 0) {
  114. forward(1);
  115. } else if (movingDirection == 1) {
  116. backward(1);
  117. } else if (movingDirection == 2) {
  118. rotateAntiClockwise(1);
  119. } else if (movingDirection == 3) {
  120. rotateClockwise(1);
  121. } else {
  122. // Unknown direction
  123. delay(100);
  124. return;
  125. }
  126. } else {
  127. // Delay for a while before checking again
  128. delay(100);
  129. }
  130. }
  131. }
  132. //For movement and primary logics
  133. void PrimaryController(void* pvParameters) {
  134. Serial.println("Primary logic process started on core " + String(xPortGetCoreID()));
  135. if (!initPrimaryLogicNetworkMode()) {
  136. /* Switch is off during power on. Use automatic mode */
  137. int seqCounter = 0; //Modify this value to change start state of seq
  138. bool switchPushed = false;
  139. while (1) {
  140. switchPushed = getSwitchState();
  141. if (switchPushed) {
  142. //Switch pushed
  143. executePushAnimationSequence(seqCounter);
  144. seqCounter++;
  145. }
  146. delay(1);
  147. }
  148. } else {
  149. while (1) {
  150. dnsServer.processNextRequest();
  151. delay(1);
  152. }
  153. }
  154. }
  155. //For animation rendering
  156. void AnimationController(void* pvParameters) {
  157. Serial.println("Animation render started on core " + String(xPortGetCoreID()));
  158. while (1) {
  159. char anicode = getAnimationCode();
  160. handleAnimationRendering(anicode);
  161. delay(1);
  162. }
  163. }