News:

SMF for DIYStompboxes.com!

Main Menu

More Arduino fun

Started by patrick398, September 18, 2020, 10:07:17 AM

Previous topic - Next topic

patrick398

I've been messing around with this super simple sketch that completely annihilates my guitar signal which i love. I have to feed a pretty big signal into it, (i'm running a blues driver volume and gain maxed into the arduino) and it's using the tone function to output a signal which is just super subby noise. It's great.
When i try it on an attiny85 chip however it sounds different, nowhere near as subby, and i can hear guitar notes though they have a ring mod quality to them. Is there any obvious reason for the difference in sound here?

Here's the arduino sketch:

void setup() {
}

void loop() {
  // read the sensor:
  int sensorReading = analogRead(A0);
  int thisPitch = map(sensorReading, 10, 1500, 120, 150);
  // play the pitch:
  tone(9, thisPitch);

}


And the ATtiny85 sketch:

void setup() {
}

void loop() {
  // read the sensor:
  int sensorReading = analogRead(2); //attiny pin 3
  int thisPitch = map(sensorReading, 10, 1500, 120, 150);
  // play the pitch:
  tone(0, thisPitch); //out pin 5
 
}

niektb

#1
First obvious question: what arduino were you using? Is the ADC resolution the same? What is the core clock frequency?

Blackaddr

Quote from: niektb on September 19, 2020, 05:41:44 AM
First obvious question: what arduino were you using? Is the ADC resolution the same? What is the core clock frequency?

Agree, if you are using the low-fi ADC built into the Arduino board you are likely dealing with completely different ADC designs / configurations. It may be difficult to get the same sound on two different low-fi ADCs.

@patrick398If you are interested at all in a consistent, hi-fi Arduino platform for guitar effects I make a guitar audio board for Arduino Teensy here:

https://www.tindie.com/products/blackaddr/arduino-teensy-guitar-audio-shield/
Blackaddr Audio
Digital Modelling Enthusiast
www.blackaddr.com

anotherjim

ADC is one thing the AT Mega and Tiny parts all have in common. It's 10bit SAR. The conversion rate is dependant on a divider ratio of the system clock. The headroom is dependent on the Aref used for the ADC.

If the Arduino sketch is compiled knowing the Tiny85 actual clock speed, it maybe will produce code that produces the expected timings of a normal 16Mhz Mega based board, but the compiler will have no idea what Aref the Tiny85 has. If the sketch expects an external Aref voltage, have you provided one? Ok, well the Tiny85 Aref pin is shared with an I/O pin so you would naturally expect an internal reference will be selected in the code since you might need the I/O function, if only for programming it. A Mega328 Uno has a dedicated external Aref pin and you might expect an external one to be provided and used although it can have the same internal options as the Tiny.

I've not tried to run Arduino code on anything other than a Mega based board, but a search for info on how to allow for chips with different capabilities didn't find much beyond sketch downloading.



patrick398

Sorry for the slow response, thanks for the replies!

Quote from: niektb on September 19, 2020, 05:41:44 AM
First obvious question: what arduino were you using? Is the ADC resolution the same? What is the core clock frequency?

I'm using an Arduino Uno, so i think it's a 16mhz clock right? I've tried using the 16mhz clock when i set up the tiny before uploading but that didn't seem to make any difference.


Quote from: Blackaddr on September 19, 2020, 08:09:28 AM

@patrick398If you are interested at all in a consistent, hi-fi Arduino platform for guitar effects I make a guitar audio board for Arduino Teensy here:

https://www.tindie.com/products/blackaddr/arduino-teensy-guitar-audio-shield/

Yes very interested, i have been looking at going down the teensy route but i feel i need to build up my basic knowledge of coding first. But i like the look of the teensy audio library.

Quote from: anotherjim on September 21, 2020, 04:57:20 AM
ADC is one thing the AT Mega and Tiny parts all have in common. It's 10bit SAR. The conversion rate is dependant on a divider ratio of the system clock. The headroom is dependent on the Aref used for the ADC.

If the Arduino sketch is compiled knowing the Tiny85 actual clock speed, it maybe will produce code that produces the expected timings of a normal 16Mhz Mega based board, but the compiler will have no idea what Aref the Tiny85 has. If the sketch expects an external Aref voltage, have you provided one? Ok, well the Tiny85 Aref pin is shared with an I/O pin so you would naturally expect an internal reference will be selected in the code since you might need the I/O function, if only for programming it. A Mega328 Uno has a dedicated external Aref pin and you might expect an external one to be provided and used although it can have the same internal options as the Tiny.

I've not tried to run Arduino code on anything other than a Mega based board, but a search for info on how to allow for chips with different capabilities didn't find much beyond sketch downloading.


So i need to ensure the actual clock speed of the uno and the tiny are the same? Sorry it went slightly over my head. So i could provide the same Aref to both uno and tiny in order to hopefully get similar sounds at the end? Or perhaps i could use an external timing crystal?

Thanks again

potul

As far as I remember, attiny85 runs at max at 8Mhz  (and can also run 1Mhz, so check your configuration) with internal clock, while your UNO probably runs at 16Mhz with a crystal. I would try to get both the same and see if this makes any difference.

You can add an external crystal to the attiny, but you lose 2 precious pins!! I think there is some kind of hack to run it at 16Mhz with internal clock, but I have never tried.

What you can do is lower the clock of the UNO to match the attiny and see if this makes any difference. If not, probably you need to look somewhere else.


patrick398

Quote from: potul on September 21, 2020, 08:50:37 AM
As far as I remember, attiny85 runs at max at 8Mhz  (and can also run 1Mhz, so check your configuration) with internal clock, while your UNO probably runs at 16Mhz with a crystal. I would try to get both the same and see if this makes any difference.

You can add an external crystal to the attiny, but you lose 2 precious pins!! I think there is some kind of hack to run it at 16Mhz with internal clock, but I have never tried.

What you can do is lower the clock of the UNO to match the attiny and see if this makes any difference. If not, probably you need to look somewhere else.

Ok i'll give that a try, thank you

anotherjim

There is some speed control register in the chips that let you slow the clock in your code. This lets you run a standard 16Mhz Arduino board slower which might be convenient when  developing code intended to run on a slower device.
void setup() {
  CLKPR = 0x80; // (1000 0000) enable change in clock frequency
  CLKPR = 0x01; // (0000 0001) use clock division factor 2 to reduce the frequency from 16 MHz to 8 MHz
}

From...
https://diyi0t.com/arduino-reduce-power-consumption/
...and you comment that out when you upload the sketch to the slower target.

Alternatively, use the Tiny85 clock boost feature to run at 16Mhz...
QuoteThe ATtiny85 is almost unique among the AVR chips in having an internal PLL (Phase-Locked Loop) that can multiply up the internal 8MHz clock by a factor of 8 to 64MHz, for use by Timer/Counter1. By programming a fuse you can choose to use the PLL divided by four as the system clock, giving a clock speed of 16MHz.
...from
http://www.technoblogy.com/show?1ZIY

Don't forget a new Tiny85 will be set by internal "fuses" to run with the internal RC 8Mhz clock Div8 which is only 1Mhz. To get 8Mhz you have to change Div8 fuse with a programmer -  your code can't do it in run time.
I have no idea what a Tiny85 supplied with Arduino bootloader would be "fused" to run at. I would hope it is at least 8Mhz but never assume!

Further to earlier mentioned stuff, I found a library that adds a Fast analog read function to the Arduino language...
https://avdweb.nl/arduino/adc-dac/fast-10-bit-adc
21us instead of 435us. That allows most AVR chips sample audio useably - although at lower quality than a proper audio "codec".



patrick398

Thanks for all that great info Jim, i'll try messing around with it today and see if i can get anywhere with it

patrick398

I tried reducing the arduino clock speed to 8mhz but it sounded much the same (really cool!)
I also tried clocking the attiny85 at 16mhz but it sounded the same as when at 8mhz (not really cool)
Also tried the fast analog read function but that made no difference either...i kind of feel like thats moving in the wrong direction, feels like a want to read the input at a much lower sampling rate so it just mangles the signal.
Back to the drawing board!

potul

I'm thinking maybe it has some relationship with the PWM frequency in both being different? And this might be the "ring modulator" you are hearing? I'm assuming that the function "tone" is using PWM....

You can try to speed up the PWM frequency of the attiny, I've done it in some projects, you just need to be careful because some timers get affected by it and you need to compensate.

https://www.electroschematics.com/attiny85-pwm-primer-tutorial-using-arduino/

patrick398

Thanks Mat, I'll look into that. I think I might go right back to basics as well and just get the most basic tone function working the same on the attiny85 as the arduino

anotherjim

Arduino tone is square wave...
https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
To make it sound more interesting, stick the output into a flip-flop divider, diode gate the two octaves together for a 25% pulse.

If all you want is simple detection of an input signal, I wouldn't bother with ADC. Use a digital input without pull-up. Put a voltage divider across the pin to bias it half way. The chips port inputs already contain a Schmitt trigger so doesn't mind hanging in the middle during silence. AC couple a preamp into it or DC couple if the amp bias is about 2.5v. It won't need a lot of gain in the preamp to hit the high & low logic thresholds. That's the trick really, bias it in the middle so its more likely for the signal peaks to register in the logic. It will be gated on note tails, but you're sure to get silence when it should be.



ElectricDruid

Quote from: anotherjim on September 22, 2020, 04:43:43 PM
Arduino tone is square wave...
https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
To make it sound more interesting, stick the output into a flip-flop divider, diode gate the two octaves together for a 25% pulse.

If all you want is simple detection of an input signal, I wouldn't bother with ADC. Use a digital input without pull-up. Put a voltage divider across the pin to bias it half way. The chips port inputs already contain a Schmitt trigger so doesn't mind hanging in the middle during silence. AC couple a preamp into it or DC couple if the amp bias is about 2.5v. It won't need a lot of gain in the preamp to hit the high & low logic thresholds. That's the trick really, bias it in the middle so its more likely for the signal peaks to register in the logic. It will be gated on note tails, but you're sure to get silence when it should be.

Yeah, this is a good idea. I used to do stuff like this with CMOS logic back in the day, but Arduino offers similar things with a ton more options. Once you've got your input as a simple digital signal (it's either high or low, right! Fantastic!) then you can generate /2 and /4 signals (did the input go high? Toggle the /2 state. Did /2 go high? Toggle the /4 state). By mixing those you have a lot of tonal options. And you can output them all on separate pins (after all, they're digital signals too) or you can mix them digitally and use some more sophisticated "analog" output option (PWM/PDM/DAC of some type).
You could add a square wave oscillator to your code and do a simple XOR ring-modulator. Given the threshold of the Schmitt input, it should have decent noise rejection (the usual problem with ring mods) and given two square waves to work with, the output tone will be some crazy synthy mayhem.

patrick398

I got somewhere nearer with this today. Firstly, the original attiny core i was using (dave mellis or something like that) didn't support the tone function. I've installed a few others that do and after playing around with some of the settings and the code it's closer to how it was

Quote from: anotherjim on September 22, 2020, 04:43:43 PM
Arduino tone is square wave...
https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/
To make it sound more interesting, stick the output into a flip-flop divider, diode gate the two octaves together for a 25% pulse.

If all you want is simple detection of an input signal, I wouldn't bother with ADC. Use a digital input without pull-up. Put a voltage divider across the pin to bias it half way. The chips port inputs already contain a Schmitt trigger so doesn't mind hanging in the middle during silence. AC couple a preamp into it or DC couple if the amp bias is about 2.5v. It won't need a lot of gain in the preamp to hit the high & low logic thresholds. That's the trick really, bias it in the middle so its more likely for the signal peaks to register in the logic. It will be gated on note tails, but you're sure to get silence when it should be.

This is a really good idea, i think i'll try this out tomorrow. I should have thought to bias the input at half supply, makes sense. Using a digital input also saves me the hassle of trying to figure out which pins on the attiny85 can do analogRead...i'm sure it's obvious to you guys but i always seem to struggle knowing which pin number to reference in the code.

Quote from: ElectricDruid on September 22, 2020, 06:40:43 PM
Yeah, this is a good idea. I used to do stuff like this with CMOS logic back in the day, but Arduino offers similar things with a ton more options. Once you've got your input as a simple digital signal (it's either high or low, right! Fantastic!) then you can generate /2 and /4 signals (did the input go high? Toggle the /2 state. Did /2 go high? Toggle the /4 state). By mixing those you have a lot of tonal options. And you can output them all on separate pins (after all, they're digital signals too) or you can mix them digitally and use some more sophisticated "analog" output option (PWM/PDM/DAC of some type).
You could add a square wave oscillator to your code and do a simple XOR ring-modulator. Given the threshold of the Schmitt input, it should have decent noise rejection (the usual problem with ring mods) and given two square waves to work with, the output tone will be some crazy synthy mayhem.

Sorry Tom, what do you mean by /2 and /4 signals here? Are they divisions of the square wave output? So octaves?

Thanks!

ElectricDruid

Quote from: patrick398 on September 23, 2020, 04:20:29 PM
Sorry Tom, what do you mean by /2 and /4 signals here? Are they divisions of the square wave output? So octaves?

Yes, exactly. Octaves down are dead easy to do, since you just toggle the state when an input pulse arrives. So it's simple enough to get /2  (one octave down) and /4 (two octaves down) tones as well as your fundamental.

patrick398

Ok great that opens up some possibilities! I take it *2 is not as straightforward?