/* Multi-core Task Handler*/ TaskHandle_t primaryTask; TaskHandle_t animationTask; SemaphoreHandle_t animationMutex; /* Semaphore for handling mutex */ void createSemaphore() { animationMutex = xSemaphoreCreateMutex(); xSemaphoreGive(animationMutex); } void mutexLock() { xSemaphoreTake(animationMutex, portMAX_DELAY); } void mutexUnlock() { xSemaphoreGive(animationMutex); } //Set the animation code, suppose to be used in core 0 only void setAnimationCode(char filename) { Serial.println("Updating animation frame to " + String(filename)); mutexLock(); animation = filename; mutexUnlock(); } //Get the animation code, suppose to be used in core 1 only char getAnimationCode() { char anicode = 'a'; mutexLock(); anicode = animation; mutexUnlock(); return anicode; } //Get the current state of the switch // true = After human pushed // false = After robot pushed bool getSwitchState() { int switchState = digitalRead(TOGGLE_SWITCH); return (switchState == 1); } /* Multi-core process definations */ void startCoreTasks() { //core 1 xTaskCreatePinnedToCore( AnimationController, /* Task function. */ "animator", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ &animationTask, /* Task handle to keep track of created task */ 1 ); delay(500); //core 0 xTaskCreatePinnedToCore( PrimaryController, /* Task function. */ "primary", /* name of task. */ 10000, /* Stack size of task */ NULL, /* parameter of the task */ 1, /* priority of the task */ &primaryTask, /* Task handle to keep track of created task */ 0 ); /* pin task to core 0 */ } //Core 0 code, for movement and primary logics void PrimaryController( void * pvParameters ) { Serial.println("Primary logic process started on core " + String(xPortGetCoreID())); clearFrame(); bool switchPushed = getSwitchState(); if (switchPushed) { /* Switch was on when device power on. Start WiFi & Web Server */ //Set display to AP icon setAnimationCode('w'); //Start AP and web server WiFi.softAP(AP_SSID, NULL); Serial.print("Manual mode started. SSID=" + String(AP_SSID) + " listening on : "); Serial.println(WiFi.softAPIP()); registerAPIEndpoints(); //Setup DNS Server dnsServer.setErrorReplyCode(DNSReplyCode::NoError); dnsServer.start(53, "*", WiFi.softAPIP()); // Start the server server.begin(); for (;;) { dnsServer.processNextRequest(); server.handleClient(); } } else { /* Switch is off during power on. Use automatic mode */ int seqCounter = 0; //Modify this value to change start state of seq for (;;) { switchPushed = getSwitchState(); if (switchPushed) { //Switch pushed executePushAnimationSequence(seqCounter); seqCounter++; } else { //Prevent crashing due to infinite loop delay(100); } } } } //Core 1 code, for animation rendering void AnimationController( void * pvParameters ) { Serial.println("Animation render started on core " + String(xPortGetCoreID())); for (;;) { char anicode = getAnimationCode(); handleAnimationRendering(anicode); } }