#avr | Logs for 2016-09-27

Back
[00:00:52] <rue_shop4> well, see if it works BEFORE you modify it
[00:01:07] <rue_shop4> then make one change at a time and see if each one has the desired effect
[00:01:23] <rue_shop4> you do that, I'm going to bed
[00:02:19] <dgriffi> I'm just trying to find something that makes tones on an attiny85. I can't just drop in the code from an ATmega328 and expect it to work.
[00:02:46] <rue_shop4> of, you want accurate tones, or just tones?
[00:02:59] <dgriffi> accurate ones preferably
[00:03:16] <_ami_> dgriffi: someone wrote a lib for this.. not sure if it was for arduino only?
[00:03:18] <_ami_> one min
[00:03:42] <dgriffi> _ami_: I did find a lib for it and yes, it's for arduino only
[00:03:52] <_ami_> dgriffi: https://github.com/connornishijima/arduino-volume
[00:03:55] <_ami_> this one?
[00:04:39] <_ami_> i once contributed a small patch to this library: https://github.com/connornishijima/arduino-volume/commit/4be625ff6e118f3831328aa0ac261813fa731fab
[00:05:17] <dgriffi> it was this: https://github.com/dzlonline/the_synth
[00:06:47] <_ami_> dgriffi: attiny85 have more than 2 timers so theoretically its possible to achieve this on t85s too
[00:07:07] <_ami_> more than or equal to 2*
[00:08:58] <dgriffi> maybe I have a hangup somewhere with not using the right combination of timers and oscillators?
[00:14:21] <_ami_> dgriffi: timers on t85s are weird in many ways. :P
[00:15:56] <sabor> dgriffi: you could let the hardware do more work for you by using PWM mode of the timer
[00:16:25] <dgriffi> so, this is what I have, and I'm getting a C, G, and high C played up and down with a quarter second interval. http://pastebin.com/UQMN79Za
[00:16:40] <dgriffi> sabor: examples?
[00:17:21] <dgriffi> the noises I'm getting out of this have nothing to do with what I'm telling it to do.
[00:20:10] <sabor> i don't have an example for tiny, but it's pretty straight forward, setup fastpwm, start the timer, load OCR with values
[00:24:46] <dgriffi> got an example for that?
[00:45:26] <sabor> dgriffi: TCCR0A = (1<<COM0A1) | (1<<WGM01) | (1<<WGM00); TCCR0B = (1<<CS00); OCR0A = 0x7F; DDRB |= 1;
[00:45:40] <sabor> then you should see a square wave on PB0
[00:46:25] <sabor> in the overflow interrupt you have a few cycles time to calculate the next OCR0A value and set it
[00:50:25] <dgriffi> just that in main()?
[00:52:40] <sabor> more or less, you have to also enable the overflow interrupt
[00:52:54] <sabor> and in that ISR you have to create the sine wave
[00:56:48] <dgriffi> I still have no idea what's going on
[01:13:41] <sabor> dgriffi: http://pastebin.com/eVraZEDd
[01:14:10] <sabor> you could try this code, it should create a 440Hz tone if your CPU clocked is at 8MHz
[01:14:27] <sabor> the code is untested, so no guarantee that it works
[01:14:56] <sabor> read the datasheet and try to understand all those registers used
[01:36:21] <dgriffi> okay, I get a tone
[01:37:05] <dgriffi> I think I'm going to have to add an amplifying transistor to my project
[01:37:31] <dgriffi> I'm doing an attiny85 on a breadboard with the audio going straight to a 3.5mm jack.
[01:38:12] <dgriffi> if I first send it thrhough a radio shack benchtop amplifier, I get tone, but not if I plug my earphones directly into the 3.5mm breakout jack
[01:50:36] <rue_bed2> sounds like your toggeling ddrx instead of portx
[01:52:20] <dgriffi> rue_bed2: you mean with sabor's example?
[01:57:20] <dgriffi> sabor: so... if I set bits 0, 1, and 2 for the TCCR0B register, that shuts off the timer and therefore can be used to turn off the oscillator?
[01:59:40] * dgriffi tries it and find that it works
[02:01:54] <sabor> dgriffi: no need to turn off the timer, just set always the same duty cycle and after filtering the output will be quiet
[02:02:34] <sabor> you need a low pass filter and depending on the load an aplifier
[02:02:39] <dgriffi> I'm looking at it as a way of toggling the sound on and off
[02:13:14] <dgriffi> sabor: why does your code produce 440 only for an 8mhz clock?
[02:17:39] <sabor> the timer runs with prescaler 1, so with 8MHz clock it overflows with 8MHz/256 = 22kHz
[02:18:36] <sabor> the counter counts to 71 so you have to divide 22kHz by 71 = 440Hz
[02:19:31] <sabor> but i made a mistake, the square wave changes with 440Hz, so the output frequency is just 1/2 of that = 220Hz
[02:19:58] <dgriffi> 22,000 / 71 == 309.86
[02:20:01] <dgriffi> ?
[02:20:42] <sabor> ooh, lol, integer division leads to errors ;)
[02:21:50] <dgriffi> I checked the crystal. it'6 16mhz. so, since your code would produce 220 at 8mhz, I got 440.
[02:21:58] <sabor> the timer overflows with 31kHz, this divided by 71 gives 440
[02:22:13] <sabor> heh, cool ;)
[02:22:47] <dgriffi> just checked the output of your code against a known good source of 440
[02:23:34] <sabor> 16MHz is much better, you get 62.5kHz overflow rate, so a simpler low pass is enough to filter out that frequency
[02:23:51] <dgriffi> an external low-pass circuit?
[02:24:38] <sabor> yes
[02:25:27] <sabor> you have s 62kHz square wave at the PB0 pin, it's a PWM, so after a low pass you get the signal you actually want to generate
[02:25:53] <sabor> just a RC low pass might be enough for now
[02:27:20] <dgriffi> hmm... that's essentially what I have in my hardware
[02:28:50] <dgriffi> sabor: do you think that the code I posted earlier can be reworked to actually work? I need the ability to do ``play(duration, freq1, freq2);``
[02:29:21] <dgriffi> or rather just play(freq); for the practice code
[02:29:28] <sabor> you could now try to integrate the sine into my code
[02:29:46] <Emil> sabor: explain your pwm setup
[02:30:33] <sabor> ofcourse it is possible to fix that other code...
[02:30:39] <Emil> Oeör do you count overflows manually?
[02:30:53] <sabor> it's just a bit strange, why doing the PWM by hand if you have hardware which can do that?
[02:31:01] <Emil> and flip bits every 71 overflow?
[02:31:21] <sabor> exactly
[02:31:25] <dgriffi> sabor: "...just a bit strange..." was that for me or Emil?
[02:32:05] <sabor> dgriffi: no, that's about the code you posted, or actually you copied from somewhere else...
[02:32:53] <dgriffi> sabor: that code was ripped from https://github.com/occamsshavingkit/port-o-rotary
[02:33:20] <sabor> Emil: this whole counter/count_max code is just to generate a suqare wave
[02:33:24] <dgriffi> sabor: and then I fumblingly tried to port it to the attiny85
[02:34:04] <sabor> dgriffi: yeah, that port-o-rotary is very good example for bad code ;)
[02:34:52] <dgriffi> I've been talking with the author. he did it as an attempt to clean up Sparkfun's original code
[02:34:59] <Emil> sabor: why not just change prescaler and OCCRX?
[02:35:03] <sabor> dgriffi: now that you have a working piece of code you can try to generate a sine wave instead of a square wave
[02:35:40] <dgriffi> the original code wouldn't cut off the ring when the hook went off. you had to wait for the ring cycle to complete
[02:35:51] <dgriffi> and THEN you could talk
[02:36:24] <dgriffi> hrmm.. maybe if I get this cleanly working, I can port back code into occamsshavingkit's repo
[02:36:24] <sabor> dgriffi: the ISR would then look like this: ISR(){ OCR0A = ocr0a_next; i = calc_next_sin_table_index(); ocr0a_next = sin_table[i]; }
[02:37:18] <Emil> sabor: because handling overflows at that speed is terribly inefficient
[02:37:45] <dgriffi> since it was just being used to make a dial tone, I guess it was thought okay
[02:38:19] <Emil> unless done in asm or withot register access
[02:38:29] <Emil> with ISR_NAKES enabled
[02:38:34] <sabor> Emil: but you get much less jitter that way
[02:39:43] <sabor> Emil: ofcourse it's not perfect for a square wave, but for a sine wave you have to do it that way
[02:40:22] <Emil> sabor: are you actually trying to do a "function generator" where you low pass filter and then pass that signal to an amp?
[02:41:07] <dgriffi> sabor: is ``i`` supposed to be initialized just before a sound is to be played?
[02:41:30] <Emil> Because with just directly changing the freency you can just filter the high frequencies also
[02:42:10] <Emil> The question is: are you trying to do a dac or are you trying to generate a frequency
[02:42:27] <dgriffi> me?
[02:42:34] <Emil> s/trying to/doing/
[02:42:45] <Emil> dgriffi: sabor
[02:45:57] <Emil> Bwcause in C
[02:50:05] <Emil> if you do ISR(TIMERX_OVF_vect){PORTX=next_bit[i];} where the timer is 8 bit prescaled by 1 you will: a) have a fuckton of jitter on your signal b) lose a fuckton of precision and c) consume around 20% of your cycles/s
[02:52:02] <Emil> if you do ISR(TIMERX_OVF_vect){OCRNX=next_value[i];} you will just consume 20% of your cycles/s
[02:52:36] <Emil> and assuming that counter is in fastpwm mode
[02:53:22] <Emil> You wilö have a function generator if filtered properly
[02:53:58] <Emil> if you do ISR(TIMERX_OVF_vect){OCRNX=next_value[i];} you will consume 20% of your cycles/s but will have a frequency generator if your timer is in ctc mode
[02:54:19] <Emil> s/value/frequency
[02:59:24] <dgriffi> sabor: what is calc_next_sin_table_index() supposed to do? wouldn't that just be i++?
[03:08:55] <dgriffi> sabor: you still here?
[03:14:12] <dgriffi> sabor: I don't follow your suggestion for making a sine wave.
[04:26:17] <dgriffi> is anyone still awake in here?
[04:40:46] <Jartza> still?
[04:40:49] <Jartza> it's only noon
[04:40:51] <Jartza> :)
[04:45:31] <dgriffi> I'm trying to get an attiny85 to emit sine waves
[04:45:50] <dgriffi> sabor was helping me but suddenly vanished
[04:50:25] <Jartza> sine wave for what?
[04:51:24] <dgriffi> I have this: http://pastebin.com/eVraZEDd that makes a 440hz square wave. I want it to make a sine wave.
[04:51:33] <Jartza> and how good the sine wave needs to be and what resolution?
[04:52:12] <dgriffi> 7 bits will be enough. eventually I'll be adding two sine waves together and 7-bit resolution will allow it all to fit in 8 bits
[04:53:23] <dgriffi> 8000hz sample rate should be enough
[04:53:42] <Jartza> umm
[04:54:12] <dgriffi> ?
[04:55:34] <Jartza> with resolution I meant frequency resolution
[04:56:32] <dgriffi> I don't understand the question. I'm working with a sine table of 256 entries with values from 0 to 127
[04:57:30] <Jartza> how are you trying to output the sine wave?
[04:57:47] <Jartza> as attiny does not output "analog waves" as such
[04:57:55] <Jartza> so, MCU cannot generate sine wave
[04:58:38] <Jartza> what you can do is to generate PWM which duty cycle and frequency you change and with RC filtering you can modify it to something resembling sine wave
[04:59:07] <Jartza> there was nice article about it, but it was for atmega
[04:59:14] <Jartza> should not be too hard to convert to attiny
[04:59:21] <Jartza> lemme check if I can find it
[04:59:37] <dgriffi> okay, I started with this: http://pastebin.com/UQMN79Za which was ripped from https://github.com/occamsshavingkit/port-o-rotary
[04:59:52] <Jartza> http://web.csulb.edu/~hill/ee470/Lab%202d%20-%20Sine_Wave_Generator.pdf
[04:59:53] <dgriffi> the original code is for an atmega328
[04:59:54] <Jartza> there it was
[05:00:56] <dgriffi> I'm trying to avoid arduino
[05:02:04] <Jartza> yea, but that's very simple to modify to non-arduino
[05:02:34] <Jartza> like setup() & loop() -> main()
[05:03:07] <Jartza> pinMode(outputPin, OUTPUT); -> DDRB |= (1 << PBxxx) etc
[05:03:11] <Jartza> not huge changes.
[05:09:20] <Jartza> anyway you want PWM where you adjust the frequency and duty cycle
[05:33:12] <dgriffi> Jartza: I'm tinkering with that code on an arduino, but I don't see how to change the frequence of the simulated sine wave
[05:35:12] <sabor> dgriffi: if calc_next_sin_table_index() just does i++ you get only one frequency, if it can do i+1 or i+2 depending on some global variable you can choose between 2 frequencies, etc.
[05:36:35] <dgriffi> sabor: is ``i`` a global?
[05:37:20] <sabor> good question
[05:37:36] <sabor> yeah, somehow yu have to save the state, but then it needs a better name
[05:38:30] <dgriffi> something like this seems like it would serve for calc_next...: tone_step = 2 * (freq * SINE_SAMPLES * (TICKS_PER_CYCLE << STEP_SHIFT)) / F_CPU;
[05:39:24] <sabor> hmm, looks very expensive
[05:39:44] <sabor> dgriffi: what else does your tiny have to do except making sine waves?
[05:40:21] <Levitator> Meep.
[05:40:33] <sabor> Mooh
[05:40:35] <dgriffi> sabor: monitor a keypad made up of a resistor ladder, playback tone sequences, save tone sequences as they're entered.
[05:41:44] <sabor> so not too much, then it doesn't matter if we burn sme cycles in the ISR...
[05:42:17] <sabor> in which frequency range are these tones?
[05:43:08] <dgriffi> about 600 to 2800
[05:43:18] <sabor> ok
[05:43:54] <dgriffi> scratch that... about 300 to 2800
[05:46:07] <dgriffi> another thought (sorry, wee hours here)
[05:46:23] <dgriffi> that expensive line doesn't need to go into the ISR function.
[05:46:24] <sabor> hmm, this is then between 208 and 22 samples fore one sine
[05:46:41] <sabor> aah, right
[05:47:10] <dgriffi> I have a play() function that sets the step, then turns on the timer, waits a prescribed period of time, then turns off the timer.
[05:47:54] <dgriffi> so the expensive line executes only once per sustained beep
[05:48:08] <sabor> yeah, that's good
[05:48:46] <dgriffi> okay, I think I might have enough to sleep on now. will you be here tomorrow?
[05:49:08] <sabor> yes, i'll be around
[05:51:09] <dgriffi> sabor: thanks for your help
[05:51:18] <dgriffi> and thanks in advance too