Hello my favorite member of this forum 
You just helped me again, a few hours ago.
I did not forget that thread, or to mark it as solved.
Was just really busy with programming...lol.
It works of course.(did not doubt).
I did experiment a bit with resistors, to lower the RPM, but managed only to shift the "dutyCycle" around. Physically no change. But I can get down to 6% DutyCycle.(Needs more to start of course) Which equals to around 2 rounds per second. Don't think it works any lower. But just in case, you have a trick up the sleeve, don't hold back 
Oh and yesterday I lost a whole day because havn't read the sensors for very long. I think last time when I was still using arduino. I thought I killed them with soldering heat, or my esp-idf program was wrong, or wiring, or GPIOS.?
[(Some just don't work)( I realized I can check all GPIOS Voltage, when all is default, and the ones with 3.3V(0,20,39) 0.06V(38,4) seem to be avoided, or need extra care I guess.]
I checked my soldered cable with 4pin connectors(first in my life
20 times, all worked.
Then today I realized it could be the cable length(2m)..lol.
Then found your post, put 2x 4.7k in sda and scl, and it worked.
But was not 100% accurate. sudden 2°C jumps sometimes.
But even with my basic understanding, I realized that the output of my esp32 of 3V instead of 3.3V is not helping to make it better...lol.
So sensor it's own 3.3V stable...voila! totally stable. 1hz - 30000hz.
Normal cable.
When not stresstesting, 100hz are totally fine.
Are there downsides going that low, except the obvious ones like delay and bandwidth?
Maybe even put a higher transistor than 4.7k? Since 100hz is 1000 times less than 10000.
So 10x should be safe. 50k?
I am just guessing, but better ask you beforehand.
But not that important. It works perfectly fine.
Maybe I have something to give back to you, or in general to the people here.
I have studied for month now with AI, about different ways of programming and patterns.
But the thing is, I discovered them mostly all by myself.
For example chatgpt mentioned a HAL layer the first time(Hardware Abstraction Layer), I talked "meta" with it.
First week of starting with everything. Arduino, hardware, mcu, esp-idf.
I thought "No no...not that complicated" don't need that. HAL...lol..naaa thx
I ended not only up with one HAL, but several layers of them, without even realizing it's called HAL.
Maybe it would be something for you, or others here. This will be my first publication when done. But not really sure, if there is interest here or in general. But I would think so.
Maybe you can give hint. Because the program is not only for me, but with other users in mind.
Not sure if I should skip that, but it's kinda fun. But would be tragic, if noone would even wanna look..lol
I make it very brief:
As easy to use as arduino, but for esp-idf. All functionality is still there, everything gets basically extended, made easier, and APIs provided. Nothing external used!
Two layers: Tools and myEsp32 Hardware layer.
The user starts fresh with his main.(Everything is hidden away)(Can even switch to other mains with hotkey(for testing, or other stuff)
The user simply has one entry point to all the hardware and tools.
No globals used, everything neat, fast and very easy to use.
Already a lot of classes:(Don't fit all on screen)
example.
myEsp32 has all physical hardware connections in one place(Before that, everything was in its own Manager, now even easier with the hardware initialization in one place.)
Pwm section:
(GPIO_NUM_16, LEDC_TIMER_0, LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, LEDC_TIMER_13_BIT, frequency);
All the user really needs to do is:
pwmGreen = _myEsp32.pwm.get(GPIO_NUM_16);
pwmGreen->setDutyCycle(60);
Everything that could be changed at runtime, and doesn't need hardware rewire is exposed, for hardware rewire see above.
Same goes for i2c, or keyEventsManager for example.
This is all that is needed, to send KeyStrokes to your program.
_myEsp32.keyEvents.subscribe([](const std::string& data) {
LOG_INFO("Keystroke: %s", data.c_str());
});
I may change that, so the syntax will get easier.
Maybe just _myEsp32.keyEvents.subscribe(Myfunction)
This works with no processing power used in the background, when no key is pressed.
Everything is optimized. Not one timecheck in several thousand lines.
or:
_myEsp32.taskManager.createTask(GrowController::task_handleLogic, "GrowControllerTask", 3096, this, 8, &_taskHandle);
You see same syntax as esp-idf.
That was important for me. It's a addition, not a reinterpretation.
Also a logger, similar to ESP_LOG(but better in my opinion so far), that has all the debug modes, but also filtering for files, and or modules.(LOG_ERROR_LOG_INFO, and many more stuff)
All get's filtered out at compile time, that was the big trick here.
The logger gives all to "Output", which is responsible for sending the streams to either serial monitor, file, or bluetooth.
But the user musn't look at all these things, thats the good part.
If someone really want to change buffer size of something, all is in a config file.
though I am not happy with that.
I think I want config file AND top of file where it is used. I already have a idea, but may need to break a rule for that, but it will be better.
Any many more tools, all VERY SIMPLE to use. All is basically ready to go , for anyone trying to try out esp-idf. I have programed everything multiple ways, and understand the pros and cons of every approach pretty well. I have several thousand pages written and read with AI about all these things.
The program is even aware of configurations in sdkconfig. In the end a user would only need his board.json, and is good to go! just need to decide on GPIOS, the rest is childsplay.
Everything is running perfectly on both cores and is really fast. Definitive a case of premature optimization...lol. But I have fun. It's about learning for me. Memory and background.
I just made a quick performance test(was done in 5 minutes)
-read all 4 sensors.
-DataManager makes systemsnapshot (pull from the different modules (4 sensor readings from SensorManager, systemerrors(There are no so far), controlData, statuses,) everything I want to safe as data for display.
-DataManager gives the Sensordata from SensorMnager to Growcontroller(simple via snapshot), who controls climate via hardware components of myEsp32.(Growcontrolelr is NOT part of the package, this is user level of course, cause not everybody programs Growcontroller)
Growcontroller gives the snapshot back with the control data of the pwm in the snapshot.
Snapshot in, snapshot out. I was also testing to give only single structures, instead of the whole snapshot, because the modules must not know about the snapshot structure.
But then on the other hand datamanager would get too much responsibility.
It acts as single source of truth for data, and is intended to be in tight loop with the performance hungriest of them all, the display.
But by dataManager just giving the modules the snapshot, we violate SRP principle, but then on the other hand, the modules are so well structured and easy, that this is the best choice. Here easy of use wins vs norms.
DataManager has then one "stream" of information, you can easily follow. Otherwise you need more queues and buffers in the background.
But my solution is even faster, and waaaay simpler. Even simpler than arduino with the "if millis < x" bullshit. All tasks have watchdogs, and nothings gets starved.
The advantages are simplicity,(only vTaskDelay used), no performance impact, and easier time of runtime managing. I think one disadvantage is though, the whole system drift temporal a bit. 5000ms can vary slightly. For performance reasons and easy of use, I have not spwaned a RTOS timer yet, only using ticks.(I guess performance impact is very low, and it can be simple implemented, and the user uses a perfectDelay instead of Delay or something.
The detailed error logging, is very simple done in each module via normal serial logging.
That can also be routed to local storage or network for detailed stuff.
(This is User level now btw. So my program. But I leave a basic working blueprint when making public. DataManger has several Buffers and saves and lazy loads history data from flash/sdCard.)
This is done in binary and aligned in memory. Fslittle.(Oh shit, that is maybe one external tool I used, not sure the definition)
Power outtage during writing to flash or sd card is no problem. All is handled and safe.
-This loop is ALL done 1000 times per second, and the cpu is basically idle!
And all on only ONE core.!! (This was just quick test / Both cores comes next, should straight up work, will see how careful I was.)
I know that I have basically nearly all CPU power left, because everytime the cpu is idle, it switches to performance_counter that increments a counter.(My first tool after the logger(that runs automatic in the background, and you see what takes how much CPU, without writing a single line for it).
I truly love it(People here did not get it's advantage after several pages discussion, so I won't start.(Now have the real arguments)) While all the above is happening 1000 times per second, it still counts to 12.800.000.(13.200.000 is max)
Could make the algorithm count to 40million/s(Have a better one), but that's not the point. So nearly all of the CPU power left.
The dip to 11.438.701 million in the screenshot is because of the long print on screen(tasks(print by pressing tab))
It goes back again afterwards.(Prints every second)
Of course for the user it shows 0-100 CPU, isntead of numbers, or user choice. Or deactivate it.
You can also print tasks or memory stats with hotkeys.
Only so little heap, because I tested 5000 systemsnapshots in memory.
Will add compression as well, so you can even faster, loads weeks of data(one systemsnapshot per second) ultra fast to show on display, or what ever.
Oh in the middle of all, I can even spam keys as much as I want(and print them to screen(printing to serial is slowest of all...lol), like staying on the button to spam it, while also printing tasks and memory, + all other logs. + 1000 times systemsnapshot a second, using it to control, and save all to flash/sdcard.
RTOS-SCORE: 12.437.874(of 13.200.000)..not bad right?
That means I should be able to handle 30 times the load(2 cores)..lol.
Or ONE display..lol(Was really unhappy with fps in arduino hav'nt tried in esp-idf yet, probably need to port)
I have not used any external profiling tools or anything, or even locked at other code..lol.
And I probably won't have to(except display), because doing things fast, but not complicated is not that difficult. I have tested nearly all new concepts as good as I could, and I have a pretty good feeling, what costs what.
Performance was not the main factor, but also ease of use. Kind best of both worlds.
A perfect C/C++ Symbiose

After benchamrking the difference of char* and std::string and having done and benchmarked both C/C++ at the start(could not decide which language to focus on) I asked chatgpt:
"Hey digga, would it make sense, to use std::string for transfering, and in the function I decide depending on the usecase if I wanna use char* or std::String inside the function, before returning it as std::String?"
"-Yes of course you can do that, like 90% of people do, that mix both languages"
lol.
The userlevel(My actual growcontroller) will have a demo, how to use super loops, with vTaskDelay only. I have a pretty good concept for that, sure it has a name though.
Splitting everything in tasks makes it harder to overview the flow. But my system combines both, so that the user can use a style even simpler than arduino.
I hope you have even read that, I think you don't like them long posts, but wanted to give you a first impression.
Would love to hear your opinion if you can.
Or anyone else, though I doubt anyone is still here. 
`