Thanks Frank. I think I will now be able to follow your instructions. I, of course, looked at src, but it made absolutely no sense to me. The description next to TFT_eSPI - fixed backslash character - kind of put me off. I will let you know how I make out. As you said, it’s a good learning experience.
@kfixman and @frankprindle thanks for being in this discussion - it’s where real learning happens!
Now back to the topic.
Since MAKERphone itself uses a few open-source libraries that are widely used (like the one for the display and for the buttons), they aren’t really CircuitMess’ libraries. Unfortunately, there isn’t an easy reference manual for these anywhere online, which makes it a bit tricky to figure out what they really do, especially for someone with little experience.
The way Frank described it is the only one - just looking through the code and trying to figure out what does what. Also, testing every function just to see what it does is the way to go. It’s a slow process, but ultimately it will teach you how do functions like these really work and how are these libraries being written.
Glad to see you finding a solution.
Cheers,
Robert
I would have used the Adafruit library…it should be compatible…
Thanks to Frank, Robert, and the examples from 8bitRobert, I have my program running pretty much as I want it. It is simply an app selected with my initials in a .bmp file and two loops that say this phone belongs to me with my name scrolling, and the LEDs flashing . I can return the phone to its firmware by pushing the home button. To complete the app, I will add another loop for sounds (right now it’s the happy birthday tune) from the oscillator. I will post the code when I am done, and it is at least presentable.
Unfortunately, the processor is designed to run the loops sequentially in core 1 . I want to be able to run the two loops in parallel, using core 0 as well as core 1. I have played with the following:
TaskHandle_t Task1;
xTaskCreatePinnedToCore(
Task1code,
“Task1”,
10000,
NULL,
1,
&Task1,
0);
void Task1code( void * pvParameters )
But my code with the Task() functions added won’t compile for the Ringo.
I have incorporated the Adafruit library for Arduino but I might not have the right library to use both cores of the ESP32 processor. I am thinking I need mp. functions to make it work.
I really don’t have the experience, although I have tried, to search existing code, as Frank suggested.
Any help much appreciated.
I’ve never been very good at running parallel tasks using C.
From what I’ve encountered, it is an unregistered skill.
I’m sure there is at least one video on the subject. However, I have seen many come forth on such an objective. I would think there would be more public concern on the matter.
Hey Kent,
Yes, tasks aren’t really something we have focused on during Ringo development. Therefore, there aren’t any “easy way” functions implemented.
As we’re making some of the new products, we have discovered great value of tasks and have implemented them in pretty much everything. They are somewhat limited since the ESP32 itself has its physical limitations, but at least you can control some parts of your work.
If you can send me a more detailed error report along with some explanation of what you’re really trying to do, I might be able to help more and we might get to the solution in one way or another.
Cheers,
Robert
Robert, here is a little project I have been working on, made up of code from you, Frank, and 8bitRobot. It is intended to be an app on the SD card that just shows who’s phone it is. I am sure the code can be refined and condensed, but it works.
#include <MAKERphone.h>
#include <FastLED/FastLED.h>
#include <FastLED/pixeltypes.h>
CRGB leds[8];
MAKERphone mp;
void setup(){
Serial.begin(115200);
mp.begin(0);
mp.pixelsBrightness = 2;
}
void loop() {
for(int i = 0; i < 8; i++){
for(int j = 0; j <= i; j++){
mp.leds[j] = CRGB(random(0,255),random(0,255),random(0,255));
}
delay(500);
mp.update();
}
mp.display.setTextWrap(false);
for(int i = 0; i < 160; i++){
mp.display.fillScreen(TFT_BLACK);
mp.display.fillCircle(80, 64, 63, TFT_WHITE);
mp.display.setTextColor(TFT_RED);
mp.display.setCursor(50, 15);
mp.display.setTextFont(2);
mp.display.setTextSize(2);
mp.display.print(“JOE”);
mp.display.setCursor(40, 85);
mp.display.setTextColor(TFT_GREEN);
mp.display.print(“PHONE”);
if(mp.buttons.released(BTN_HOME)) mp.loader();
mp.display.setCursor(i, 50);
mp.display.setTextColor(TFT_BLUE);
mp.display.setTextFont(2);
mp.display.setTextSize(2);
mp.display.print(“RINGO’S”);
mp.display.pushSprite(0, 0);
delay(25);
mp.buttons.update(); while(mp.buttons.states[BTN_HOME]) mp.update();
}
}
I would like to run each of the two loops in a separate core of the processor because I think it would look better, and just because it can be done. The following is my attempt to run one of the loops in core 0 instead of the default core 1. It gets pretty far through the process, but won’t complete the compile.
#include <Arduino.h>
#include <MAKERphone.h>
TaskHandle_t Task1;
MAKERphone mp;
void setup() {
Serial.begin(115200);
xTaskCreatePinnedToCore(
Task1code,
“Task1”,
10000,
NULL,
1,
&Task1,
0);
delay(500);
}
void Task1code( void * pvParameters ){
mp.display.setTextWrap(false);
for(int i = 0; i < 160; i++){
mp.display.fillScreen(TFT_BLACK);
mp.display.fillCircle(80, 64, 63, TFT_WHITE);
mp.display.setTextColor(TFT_RED);
mp.display.setCursor(50, 15);
mp.display.setTextFont(2);
mp.display.setTextSize(2);
mp.display.print(“JOE”);
mp.display.setCursor(40, 85);
mp.display.setTextColor(TFT_GREEN);
mp.display.print(“PHONE”);
if(mp.buttons.released(BTN_HOME)) mp.loader();
mp.display.setCursor(i, 50);
mp.display.setTextColor(TFT_BLUE);
mp.display.setTextFont(2);
mp.display.setTextSize(2);
mp.display.print(“RINGO’S”);
mp.display.pushSprite(0, 0);
delay(25);
mp.buttons.update(); while(mp.buttons.states[BTN_HOME]) mp.update();
}
}
void loop() {
}
Okay, I’ve got everything now - except the error!
Please, send me the full error report so I can tell you what to do next.
Robert
The file is too big to upload with the Arduino - “Show verbose output during compilation” checked, so here it is without that additional information.
Arduino: 1.8.12 (Windows 10), Board: “Ringo by CircuitMess, Minimal SPIFFS (Large APPS with OTA), 80MHz, 921600, None”
In file included from C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src/MAKERphone.h:31:0,
from C:\Kent's .INO Code\Combo2_task\Combo2_task.ino:3:
C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src/FastLED/FastLED.h:14:21: note: #pragma message: FastLED version 3.002.001
pragma message “FastLED version 3.002.001”
^
In file included from C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src/FastLED/FastLED.h:65:0,
from C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src/MAKERphone.h:31,
from C:\Kent's .INO Code\Combo2_task\Combo2_task.ino:3:
C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src/FastLED/fastspi.h:110:23: note: #pragma message: No hardware SPI pins defined. All SPI access will default to bitbanged output
pragma message “No hardware SPI pins defined. All SPI access will default to bitbanged output”
^
In file included from C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src\MAKERphone.h:31:0,
from C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src\MAKERphone.cpp:20:
C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src\FastLED/FastLED.h:14:21: note: #pragma message: FastLED version 3.002.001
pragma message “FastLED version 3.002.001”
^
In file included from C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src\FastLED/FastLED.h:65:0,
from C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src\MAKERphone.h:31,
from C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src\MAKERphone.cpp:20:
C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src\FastLED/fastspi.h:110:23: note: #pragma message: No hardware SPI pins defined. All SPI access will default to bitbanged output
pragma message “No hardware SPI pins defined. All SPI access will default to bitbanged output”
^
libraries\Ringo\MAKERphone.cpp.o: In function `Task1code(void*)’:
C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src/MAKERphone.cpp:71: multiple definition of `Task1code(void*)’
sketch\Combo2_task.ino.cpp.o:C:\Kent’s .INO Code\Combo2_task/Combo2_task.ino:24: first defined here
libraries\Ringo\MAKERphone.cpp.o:(.bss.Task1+0x0): multiple definition of `Task1’
sketch\Combo2_task.ino.cpp.o:(.bss.Task1+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
Multiple libraries were found for “WiFi.h”
Used: C:\Users\Nicholson\AppData\Local\Arduino15\packages\cm\hardware\esp32\1.0.5\libraries\WiFi
Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
Multiple libraries were found for “MAKERphone.h”
Used: C:\Users\Nicholson\Documents\Arduino\libraries\Ringo
Not used: C:\Users\Nicholson\Documents\Arduino\libraries\Ringo_by_CircuitMess_Library
Multiple libraries were found for “SD.h”
Used: C:\Users\Nicholson\AppData\Local\Arduino15\packages\cm\hardware\esp32\1.0.5\libraries\SD
Not used: C:\Program Files (x86)\Arduino\libraries\SD
Not used: C:\Users\Nicholson\Documents\Arduino\libraries\SD
exit status 1
Error compiling for board Ringo by CircuitMess.
This report would have more information with
“Show verbose output during compilation”
option enabled in File -> Preferences.
Hey Kent,
I’ve done a bit of snooping around it and fixed your problem.
Most of these are not errors, but warnings, and they actually don’t effect anything. The thing that is actually stopping your program is this
C:\Users\Nicholson\Documents\Arduino\libraries\Ringo\src/MAKERphone.cpp:71: multiple definition of `Task1code(void*)’
Somewhere in the Makerphone.h there is already defined Task1code(void*) and Task1, so when you’re trying to re-define it, it throws out an error.
I’ve fixed your errors and it is all working now, not ideal, but enough for you to continue working on it if you want to.
KentProgram.zip (799 Bytes)
It’s important to look at this function vTaskDelay(1) - this has to be in there because it allows other processes to run inside of that same core when this task is not doing anything (either waiting or something passive). Also, when limiting how many times something is called or just when you want to create a delay, it’s much better to use millis() than delay, since it doesn’t stop the whole flow of the program. If you’re unfamiliar with this technique, please tell me so I can show you a few examples.
Hope this helps,
Robert
Thank you Robert. Now I can get back to playing/learning. I am familiar with millis() and have used it in this same program when trying to speed everything up, but it didn’t make a difference. I will put it back instead of the delay.
Thanks again, and stay safe.
I have the little two core program working pretty well thanks to all you guys that helped. It is fast, and both programs ( scrolling text and pulsating LEDs) run at the same time instead of sequentially like they did when they both were running in core 1.
I have been able to find out about the vTaskDelay() function, but I am at a loss about the doo() function. What doo it do?
Glad to hear that!
Honestly, I’ve never heard of this function and I’m pretty sure we’re not using it anywhere in the code (just checked once again). Can you please throw a little bit more details about it? Which library is it from? Where is it used?
Thanks!
Robert
Robert, it came from you in the KentProgram.zip (about 4 posts back) that helped me with the two core problem. I tried to leave it out, but it needs to be in the program. I, of course, tried Google, but couldn’t find any reference to it.
The code says it displays a white circle with JOE, PHONE, and RINGO’S in various colors, moving the RINGO’S to the right.
Frank, the code is working well. It scrolls my name in the white circle with colors, and at the same time, in the other processor core, the LEDs flash sequentially. I can then get back to the Ringo firmware by pushing the A button. So I am happy with the program. Robert provided some additions to my program to get it to work properly in both cores. This function was added, and I am at a loss as to what it does.
{
while (true)
doo();
}
void doo( ){
It does exactly what I (and the code) said it does, displays some text and a circle. It’s exactly the code between the line “void doo(){” and the corresponding closing brace.
That’s not good enough for me. I have lots of other working examples (in fact this exact same code) that displays the text and the circle and scrolls the name without the doo() function. In order to use both cores, this code was added. It was not needed when I was running the same program successfully in one core. Why is it needed for two core programming.
Kent,
doo() function is not a universal function from some library. It’s just an example function I created in order to showcase you how to work with two cores.
The reason why I added it is simple - looking at this part of the code
void Task2289code(void *pvParameters)
{
while (true)
doo();
}
it is much more clear what is going on when there isn’t too much mess. So instead of putting all of this code for scrolling your text and showing everything you want, I just put it in the doo()
function so that you can get a better understanding of how it all works.
Task2289 (a random number I chose) is calling a function Task2289code all the time, and while the argument is true, which is always, it will call the function doo() which will then print out your name!
So to clear the things once again - doo() is not a special function, I just called it like that for no real reason and now it’s confusing you in some way, so sorry.
Is everything clear now?
Robert
Thanks Robert. I use Task2 (instead of 2289) since Task1 is already defined and is problematic. I now have a better understanding of what you did, and can work to get rid of the doo() function No offense intended, but the doo() function is beyond my skill level at this time. I will try and return the code to what I can currently understand. Been at it for about three months now, and learning all the time – just not very fast.