sensorium / Mozzi

sound synthesis library for Arduino
https://sensorium.github.io/Mozzi/
GNU Lesser General Public License v2.1
1.07k stars 186 forks source link

Teensy LC: conflict between I2C and ADC #139

Open ChrisVeigl opened 2 years ago

ChrisVeigl commented 2 years ago

Using the current master branch, I got some compile error when building for the Teensy 3.2 / LC boards, in particular I had to change lines

https://github.com/sensorium/Mozzi/blob/8df22c923f6a3040e715ab1c6abfbab587358057/MozziGuts.cpp#L399

to

adc->adc0->setAveraging(0); adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED);

to get the build done. But then, every sketch which uses the ADC hangs at mozziAnalogRead ...

I found that the hang does not happen when i prevent adc interrupts by commenting this line:

https://github.com/sensorium/Mozzi/blob/8df22c923f6a3040e715ab1c6abfbab587358057/mozzi_analog.cpp#L74

After that, mozziAnalogRead does not provide correct ADC results, but a workaround is to create your own adc instance in the Arduino sketch, and read the adc values by e.g.

ADC *myadc = new ADC(); (...) int value=myadc->adc0->analogRead(A1);

works fine in a Mozzi setup with 8 potentiometers ...

tfry-git commented 2 years ago

I know @tomcombriat has addressed at least the compilation problem in https://github.com/sensorium/Mozzi/pulls . Could you test whether that also fixes the hang?

tomcombriat commented 2 years ago

Hi, Both the compilation and ADC issues (alongside slightly off frequencies) should be solve by #138 when using the latest version of Teensyduino. When I have finished the last corrections it should be merged soon. I have tested on Teensy3.2 but not on LC. In all cases, always interested to know if that also works for you. If you want to try you can use the tomcombriat:Teensy4X branch, or the main mozzi branch once this is merged.

ChrisVeigl commented 2 years ago

Hi, I tried the tomcombriat:Teensy4X branch, but no luck with TeensyLC, ADC values do not change and i suppose also problems with audio generation... let me know if I can help with testing something in particular ... For now I will stay with my workaround as described above!

tomcombriat commented 2 years ago

Hi, That's weird, are you using the latest Teensyduino?

Also, you said:

no luck with TeensyLC

Does that means that the tomcombriat:Teensy4X branch works well with the Teensy 3.2?

I'll try to have a closer look tomorrow, probably will need a big dive into Teensy source code… The Teensy LC is slightly different from the 3.2, it has only one converter. I don't have a TeensyLC unfortunately but I'll already re-test that on the 3.2.

Best,

tomcombriat commented 2 years ago

Just to confirm: mozziAnalogRead() works here with Teensy 3.2. I'll look more into the differences with LC tomorrow. If working correctly this should be faster than int value=myadc->adc0->analogRead(A1); as mozziAnalogRead() is asynchroneous.

Just to comment: probably, just int value = analogRead(A1) should give the same results than your workarounds if you want to same some writing space ;).

I'm also wondering if Teensy LC has ever been tested before on Mozzi… It is not mentioned in the main page of Mozzi. Maybe @sensorium can enlighten us on this!

ChrisVeigl commented 2 years ago

i do not have Teensy 3.2 available here at the moment, only an LC, a 3.6 and a 4.0 ... so I could test with these!

I think the LC is a great platform for Mozzi, offering usbMidi and a powerful CPU at relatively low cost :)

ChrisVeigl commented 2 years ago

Hi, That's weird, are you using the latest Teensyduino?

yes, i am using Teensyduino 1.55 with Arduino 1.8.16

tomcombriat commented 2 years ago

I think the LC is a great platform for Mozzi, offering usbMidi and a powerful CPU at relatively low cost :)

I agree, but the import taxes here, it is nearly as expensive to buy a 3.2, that's why I never went for the LC unfortunately…

I still haven't understood why the 3.2 works here (with correct mozziAnalogRead at least for the extremum) but the LC for you… I actually have another question if you do not mind.

but no luck with TeensyLC, ADC values do not change and i suppose also problems with audio generation

Does that mean that it compiled ok on LC (without errors or warnings) and that it runs without hanging at the first mozziAnalogRead using tomcombriat:Teensy4X? ADC values do not change? In that case what it the value they give? You mentioned problems with audio generation? What exactly do you mean? (I am trying to debug this without an LC… I'll probably try to get one soon if I cannot put my finger on the problem remotely…).

Thanks!

ChrisVeigl commented 2 years ago

Hi,

I agree, but the import taxes here, it is nearly as expensive to buy a 3.2, that's why I never went for the LC unfortunately…

intersting... here in Austria we get the TeensyLC for ~11€, where the 3.2 costs ~20€ (both including taxes)!

but no luck with TeensyLC, ADC values do not change and i suppose also problems with audio generation

Does that mean that it compiled ok on LC (without errors or warnings)

yes - the code compiles/builds okay without changes.

and that it runs without hanging at the first mozziAnalogRead using tomcombriat:Teensy4X?

yes - mozziAnalogRead does not freeze anymore ...

ADC values do not change? In that case what it the value they give?

I made a small demo-sketch which prints the ADC-values of channels 0-8 using mozziAnalogRead in the updateContol() callback (with a CONTROL_RATE of 64). here the result:

chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40702 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40706 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40710 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40714 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40718 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40722 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40726 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40729 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40733 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40737 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40741 chn 5:0 chn 6:1003 chn 7:68 chn 8:757
chn 0:353637138 chn 1:22 chn 2:0 chn 3:334 chn 4:40745 chn 5:0 chn 6:1003 chn 7:68 chn 8:757

When i turn connected potentiometers, the changing voltages are not reflected in the ADC-readouts (which works when i use the plain analogRead() instead - thanks for the hint BTW!)

Note that chn4 shows constantly increasing values which seem to be milliseconds (!) - could be a timer register value, indicating a configuration problem of the ADC/Timer unit ?

You mentioned problems with audio generation? What exactly do you mean?

i heard a strange noise when i ran my synthesizer sketch using the Teensy4X-branch last time - however i can't reproduce this problem after the last pull - this one seems to be fixed :-)

or it was caused by a mistake at my end ;-)

tomcombriat commented 2 years ago

Wow, look at these values for channel 0 (I presume it is pin A0?)! Channel 4 indeed increases, and it is the only one… Seems indeed like a counter, but of what… Thanks very much for all these tests! At least it compiles ok…

I just commit my last trump card on tomcombriat:Teensy4X for fixing this problem remotely, if you have time to test one day. If that does not solve the problem I'll probably try to put my hand on a Teensy LC to understand the root of this…

Teensy are great platforms so the analogRead is indeed very fast (compared to Arduino), but getting this fixed would give more power for sound computing and it is always good to have a bit of headroom (and it annoys me not to understand why it does not work for the LC).

Thanks very much for all your testings and your detailed reports :) !

ChrisVeigl commented 2 years ago

hi,

I applied your recent change to mozzi_analog.cpp, but it did not change the situation...

Wow, look at these values for channel 0 (I presume it is pin A0?)!

yes. the printloop is

for (int i=0;i<9;i++) Serial.printf("chn %d:%d \t",i,mozziAnalogRead(A0+i));

if I replace mozziAnalogRead by analogRead it works and i get sane values, reflecting the potentiometer positions (although the maximum value is ~1005 and not 1023 as supposed, but that is a minor problem ...)

Channel 4 indeed increases, and it is the only one… Seems indeed like a counter, but of what…

it looks indeed as if the current value of the passed milliseconds is reflected in chn4 .....

Thanks very much for all your testings and your detailed reports :) !

no problem, this was no hassle at all! thanks for your work on this great library :)

tomcombriat commented 2 years ago

Hei again!

Arf, too bad, I had great hopes in this one! Well, I'll get my hands on a Teensy LC (probably in the next couple of weeks) and try to get it sorted. I kinda feel Teensy is trying its best to make all these 32bits boards compatible so I do not understand why this is not working. I feel it has something to do with the fact that there is only one ADC but even when there is two mozzi is only using one anyway…

it looks indeed as if the current value of the passed milliseconds is reflected in chn4 .....

I thing this is not increasing enough for a milliseconds count at control_rate… But it might be related to that! Like a count of CPU clock divided by something… Anyway, thanks very much for testing :D! I'll give it another try when I get this chip and let you know if you are interested :)!

tomcombriat commented 2 years ago

Hei, I put my hand on a TeensyLC. Indeed there is a problem, which actually might not be restricted to the LC. You can check #138 for the work in progress (not working, yet).

Best

tomcombriat commented 2 years ago

Should be solved by #138

ChrisVeigl commented 2 years ago

hi! thank you for having such a close look at the issue! i can confirm that ADC initialization and readings works now on a TeensyLC, unless the I2C1 (Wire1) interface is used... I still have problems with mozziAnalogRead() in my project, where i use I2C1 for controlling an LC display. The code hangs when mozziAnalogRead() is called. Normal analogRead() works.

tomcombriat commented 2 years ago

The never ending story…

At least the ADC works when no I2C interface is used. The I2C interface is obviously on the same pins than the ADC, there might be a conflict somewhere. I can try to see if I find the conflict (given that it is not deep down a Teensy library), I have to say that I am never using I2C on synths so that is something I did not test (I tested SPI thought).

In case you have a minimal non-working example in order for me to try to work on I would be grateful. Otherwise no big deal!