Hello there,
I'm having trouble with machine.freq().
I'm using the esp32 with devkit C V4 from AZ-delivery.
I'm reading(with the I2C Bus)/and then sending ~23 messages/s to my server with a cpu frequency of 160MHz,
But when im adjusting the frequency to 240MHz I'm only sending around ~20 messages/s.
I've meassured the time for how long it takes to read from my sensor (MPU6050)
-> With 240MHz it takes the esp around ~1ms longer to read 2Bytes.
Does anybody know what the potential problem may be?
Best regards.
I2C speed
Re: I2C speed
can you post a small example which reproduces the issue please? use the code tags to get nice formatting (the </> button will bring up code tags for you).
Re: I2C speed
Sorry for the late response.
These are basically my results.
With 16MHz
With 24MHz
(I2C Bus speed set to 400KHz on both tests)
I was unable to cut down my code because of an error I would then receive and I dont know how to fix it.
(Object with buffer protocol required)
Please have a look at my github instead:
https://github.com/JakobWeitzlab/Flugsi ... 32/main.py
Basically down at the bottom, when I call "main()", I manually set the speed of the CPU to either 24MHz or 16MHz.
Code for the receiving end can be seen here.
https://github.com/JakobWeitzlab/Flugsi ... PServer.py
At the time the server only receives messages and then prints out "messages/sec".
These are basically my results.
With 16MHz
With 24MHz
(I2C Bus speed set to 400KHz on both tests)
I was unable to cut down my code because of an error I would then receive and I dont know how to fix it.
(Object with buffer protocol required)
Please have a look at my github instead:
https://github.com/JakobWeitzlab/Flugsi ... 32/main.py
Basically down at the bottom, when I call "main()", I manually set the speed of the CPU to either 24MHz or 16MHz.
Code: Select all
def main():
machine.freq(160000000) #set frequency
print(machine.freq())
wifi = Wifi()
wifi.loop()
https://github.com/JakobWeitzlab/Flugsi ... PServer.py
At the time the server only receives messages and then prints out "messages/sec".
Re: I2C speed
Thank you for also posting the server. That error may indicate you need a bytes/bytearray instead of a normal string. (e.g. string.encode('ascii') or similar).
I don't see anything obvious as to what is causing that slowdown. I would expect the performance to be limited by the i2c bus. Do you have a scope to confirm the bus timing? Always good to check if you can.
Do you have average timings for _Acc()? Looks like you were timing it, would be helpful to know how much time is spend there.
I suggest sending constant test packets of the same length usually returned by _Acc() in a loop, eliminating the call to _Acc. See if the slowdown is reproduced. Perhaps also introduce a blocking delay of the same average time as a call to _Acc().
You can also use wireshark or similar to see if the packets are really stuck on the MCU or perhaps elsewhere. (I doubt this, but it's nice to know the problem is definitely on the MCU).
With the timings spent in _Acc and the above tests there should be a good indication of which part of the system is slowing down.
I don't see anything obvious as to what is causing that slowdown. I would expect the performance to be limited by the i2c bus. Do you have a scope to confirm the bus timing? Always good to check if you can.
Do you have average timings for _Acc()? Looks like you were timing it, would be helpful to know how much time is spend there.
I suggest sending constant test packets of the same length usually returned by _Acc() in a loop, eliminating the call to _Acc. See if the slowdown is reproduced. Perhaps also introduce a blocking delay of the same average time as a call to _Acc().
You can also use wireshark or similar to see if the packets are really stuck on the MCU or perhaps elsewhere. (I doubt this, but it's nice to know the problem is definitely on the MCU).
With the timings spent in _Acc and the above tests there should be a good indication of which part of the system is slowing down.
Re: I2C speed
Unfortunately I dont have a scope.
Time spend in _Acc() =>
160 MHz results:
min 26ms
max 58ms
average 40,375ms
240 MHz results:
min 23ms
max 59ms
average 43,65ms
Wireshark results:
I already tried reading reading the sensor data with my raspberry and got results that where like 10x better.
Cable length 20cm between mpu and esp
Power delivery cant be a problem right?, because then the esp would crash.
I've tried the I2C slow mode (100kHz) and fast mode (400kHz) (both supported by the mpu)
100kHz -> 20 messages/s
400kHz -> 24 messages/s
I just saw a different forum post aswell discussing on how to get the most out of I2C.
They where talking about reading directly from FIFO.
The MPU supports FIFO "caching".
Is it worth a try?
Time spend in _Acc() =>
160 MHz results:
min 26ms
max 58ms
average 40,375ms
240 MHz results:
min 23ms
max 59ms
average 43,65ms
Wireshark results:
I already tried reading reading the sensor data with my raspberry and got results that where like 10x better.
Cable length 20cm between mpu and esp
Power delivery cant be a problem right?, because then the esp would crash.
I've tried the I2C slow mode (100kHz) and fast mode (400kHz) (both supported by the mpu)
100kHz -> 20 messages/s
400kHz -> 24 messages/s
I just saw a different forum post aswell discussing on how to get the most out of I2C.
They where talking about reading directly from FIFO.
The MPU supports FIFO "caching".
Is it worth a try?
Re: I2C speed
ah, is your complaint that both are slow? I thought you were just looking at the expectation that running at 240MHz should be faster than 160MHz. it certainly shouldn't be slower. I misunderstood your initial question as being the relative performance.
Considering the average timing in _Acc, 40.375 * 23 = 923.3 ms. so clearly the i2c communication is dominating. The wireshark timings show a variance that seems like it matches with the variance in the i2c.
Anything you can do to speed that up will help. If FIFO caching speeds that up, then yes, i suggest you try it. Sorry, I'm not familiar with the MP6050 (I hooked one up once and that was about it). i know its common so perhaps there are people on the forum who can help. It does seem to me the issue is in the i2c communication. Quickly reading of the MP6050 datasheet, i would expect data to be available at all times via an i2c read of the registers, so I'm not sure FIFO will help here.
Here's a good explanation of cables wrt to i2c: https://electronics.stackexchange.com/q ... -2m-cables
I rarely use i2c over cables beyond prototyping so I don't know limitations there.
I doubt it's power, you should confirm your supply is rated 2x the max expected draw.
If I have some time I can take a look at i2c bus timings, but it wouldn't be till later this week.
Considering the average timing in _Acc, 40.375 * 23 = 923.3 ms. so clearly the i2c communication is dominating. The wireshark timings show a variance that seems like it matches with the variance in the i2c.
Anything you can do to speed that up will help. If FIFO caching speeds that up, then yes, i suggest you try it. Sorry, I'm not familiar with the MP6050 (I hooked one up once and that was about it). i know its common so perhaps there are people on the forum who can help. It does seem to me the issue is in the i2c communication. Quickly reading of the MP6050 datasheet, i would expect data to be available at all times via an i2c read of the registers, so I'm not sure FIFO will help here.
Here's a good explanation of cables wrt to i2c: https://electronics.stackexchange.com/q ... -2m-cables
I rarely use i2c over cables beyond prototyping so I don't know limitations there.
I doubt it's power, you should confirm your supply is rated 2x the max expected draw.
If I have some time I can take a look at i2c bus timings, but it wouldn't be till later this week.
Re: I2C speed
I initially wanted to know why my esp project "works better" with a lower clock frequency and/or if the clock frequncy may interfere with the I2C bus.
Anyway, Thank you very much for your support
Anyway, Thank you very much for your support
Re: I2C speed
Unfortunately I don't have an answer for why the code is slightly slower at 240 MHz, but here's a follow up anyways.
Checking with a scope on a devkit-C v4, reading 8 bits, i see the following timings.
CPU: 160MHz, i2c clock: 100kHz -> 240 us
CPU: 160MHz, i2c clock: 400kHz -> 100 us
CPU: 240MHz, i2c clock: 100kHz -> 231 us
CPU: 240MHz, i2c clock: 400kHz -> 86 us
when i do something like this:
that's about 3ms for 6 register reads.
so 5 ms is spent building that string.
fyi this is faster:
But, it think the real story here is that the python statements are always going to be slower than the equivalent C code. The i2c reading is doing what it should be doing, and the i2c reads are mostly limited by the i2c bus speed. You might be able to speed things up by reading the i2c directly into the socket and having the server reconstruct the data as you need to see it. I personally aim for zero data manipulation on the device unless strictly necessary. I do all data manipulation on the server, as it's much easier to update the server and the server has far more resources. clearly that's not always possible, just an approach i prefer w/ sensor data being reported instead of consumed by the device.
Checking with a scope on a devkit-C v4, reading 8 bits, i see the following timings.
CPU: 160MHz, i2c clock: 100kHz -> 240 us
CPU: 160MHz, i2c clock: 400kHz -> 100 us
CPU: 240MHz, i2c clock: 100kHz -> 231 us
CPU: 240MHz, i2c clock: 400kHz -> 86 us
when i do something like this:
Code: Select all
def test():
for _ in range(6):
i2c.readfrom_mem(36, 0x01, 1)
>>> st = time.ticks_us();test();et=time.ticks_us();print(et-st)
3187
Code: Select all
>>> def test2():
... ret = str(v1) + " " + str(v2) + " " + str(v3)
... return ret
>>> print(test2())
255 187 96
>>> st = time.ticks_us();test2();et = time.ticks_us(); print(et - st)
'255 187 96'
5223
fyi this is faster:
Code: Select all
>>> st = time.ticks_us();out = "{} {} {}".format(v1, v2, v3);et = time.ticks_us(); print(et - st)
3673