![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | LinkBack | Thread Tools | Display Modes |
| | (permalink) |
| Hello, Here's what's been bothering me now for a week and perhaps someone could please help me out... I saw this Brain Machine circuit (Make magazine #10, article here: http://cachefly.oreilly.com/make/wp_brainmachine.pdf ) so I figured to build it. Since I'm a PIC and not an AVR guy I wanted to use what I have handy, a 16F88, thinking it's a fairly modern micro-controller. In their circuit they use two AVR's built in timers that link to two oscillators (PWM) to generate different frequencies. Great, sounds pretty easy if only most PICs had more than one PWM (yes, I know there are some with two but they are in large packaging, and besides not handy). My idea was, since there's only one PWM on most PICs to instead use two four bit sine wave ladders on port A or B or both, regardless (four bit sine wave example as seen here, towards bottom part of the page: http://homepage.ntlworld.com/moonsha...lectronics.htm ) Well, the problem is that I can generate one just fine and the output is pretty decent going through and RC filter, but how do I generate two sine-waves at the same time, having two different frequencies, let's say 205Hz and 215Hz? I have been trying all kinds of things with timers and interrupts, and to be honest I am no expert in writing for micro-controllers (presently using CCS C) so I'm stuck and hoping someone here could enlighten me? Thank you in advance. Last edited by 3dluvr; 6th January 2008 at 03:29 PM. | |
| |
| | (permalink) |
| Did you watch the video demonstrating this thing? Do you still want to build it?
__________________ --- The days of the digital watch are numbered. --- | |
| |
| | (permalink) |
| Actually I watched author's presentation from the Chaos Communications Camp 2007 where he discussed brain entrainment and his device, which is nothing new really. But that's all beside the point, any ideas on how to achieve the above? | |
| |
| | (permalink) |
| Can't you just add the two sine waves in software and output them to the one PWM channel? Mike. | |
| |
| | (permalink) |
| How would I do that? The sounds need to be so called binaural tones, where one is slightly higher in frequency than the other, ie. 200Hz and 211.4Hz and their difference causes the entrainment of the brain to 11.4Hz. My understanding is that they need to be outputted at the same time not one following the other, or the effect won't work... Plus, the tones need to go to different ears, one channel is one tone and the other channel is the other tone, left and right earphone. | |
| |
| | (permalink) |
| You could use two timers. One running at a (16 x 200Hz) rate and another at (16 x 211.4Hz) to trigger when to output a value from of your 4bit sine lookup table.
__________________ --- The days of the digital watch are numbered. --- | |
| |
| | (permalink) |
| But could the output be simultaneous and independent from each other? If I use the higher nibble of port B for left channel and lower nibble for the right channel? Could you please mock-up an example for me? In reality one channel/tone is always static and does not change, it's a fixed frequency of let's say 200Hz. The other channel would change depending on which brainwave range user wishes to entrain to (Delta, Theta, Alpha, Beta). Then there are the LEDs that would need to be pulsed at that entrain frequency (11.1Hz for example for Alpha as used in the Brain Machine) along with the tones being produced. Thanks. | |
| |
| | (permalink) | |||||
| Quote:
Quote:
Quote:
Quote:
Quote:
__________________ --- The days of the digital watch are numbered. --- Last edited by kchriste; 6th January 2008 at 11:04 PM. | ||||||
| |
| | (permalink) |
| Thank you again for the direction pointers, I think I understand now (sort of). I still have to figure out the interrupts and timers (noob) but using two different ports is not an issue since the chip will do nothing else but produce tones and flash LEDs. | |
| |
| | (permalink) |
| I didn't realise you needed the 2 signals to be separate. A possible solution would be to use a fixed interrupt of say 500uS and a 32 byte sine lookup table and simply step through the table each interrupt, then you will get a frequency of 1/(500*10-6*32) Hz = 62.5Hz. If we add 2 to our lookup table position then we will get a frequency of 2/(500*10-6*32) = 125Hz. If we want 211.4 Hz then we need to add 211.4*500*10-6*32 = 3.3824 which is not a very nice number. However, if we multiply 3.3824 by 256 we get 868 which is much nicer. If we add this number to a 16 bit variable and then shift the variable right 8 places, we can use the resultant value as our lookup value to get 211.4Hz. If we also want 200Hz then 200*500*10-6*32 = 3.2. 3.2*256=819 The actual frequencies due to rounding errors would be, 868/(500*10-6*32*256) = 211.9 819/(500*10-6*32*256) = 199.9 Our interrupt would look something like, (generic C) Code: void interrupt(){
position+=868;
PORTB=SineTab[(position>>8)&31];
position2+=819;
PORTA=SineTab[(position2>>8)&31];
}
or, if you want to use just port B,
void interrupt(){
position+=868;
Temp=SineTab[(position>>8)&31]<<4;
position2+=819;
PORTB=Temp|SineTab[(position2>>8)&31];
} Hope that makes sense. Mike. edit typo and changes nS to uS as pointed out by kcriste. Last edited by Pommie; 8th January 2008 at 05:25 AM. | |
| |
| | (permalink) |
| Thank you for the calculation, it seems better than mine... Here is what I've done so far (yesterday night). I used timer0 and timer2, did not want to mess with the 16bit values in timer1 yet so my freq2 adjustment is rather crude, steps of 4 or so Hz. Code: #include <16F88.h>
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,PUT,CCPB3
#use delay(clock=8000000)
int i, j;
CONST unsigned int SINE_WAVE[30] = {
0b00010000, 0b10010000, 0b01010000, 0b11010000, 0b00110000, 0b10110000,
0b01110000, 0b11110000, 0b01110000, 0b10110000, 0b00110000, 0b11010000,
0b01010000, 0b10010000, 0b00010000, 0b11100000, 0b01100000, 0b10100000,
0b00100000, 0b11000000, 0b01000000, 0b10000000, 0b00000000, 0b10000000,
0b01000000, 0b11000000, 0b00100000, 0b10100000, 0b01100000, 0b11100000};
#INT_RTCC
void main_wave() {
if (i++ == 29)
i = 0;
output_b(SINE_WAVE[i]);
}
#INT_TIMER2
void TIMER2_isr() {
if (j++ == 29)
j = 0;
output_a(SINE_WAVE[j]>>4);
}
void main(void) {
i = 0;
j = 0;
setup_adc_ports(NO_ANALOGS); // Turn off analogue inputs
setup_oscillator(OSC_8MHZ | OSC_INTRC); // Use internal 8MHz osc
set_timer0(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_1 | RTCC_8_BIT);
// about 258.7Hz
setup_timer_2( T2_DIV_BY_4, 65, 1 );
// 65 gives 250.8Hz
enable_interrupts(INT_TIMER0);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
while(TRUE)
{
delay_ms(1);
}
disable_interrupts(INT_RTCC);
} Also, where do I stick the LED pulsing now in, so they pulse at the binaural beat (the frequency difference)? Last edited by 3dluvr; 8th January 2008 at 01:04 AM. | |
| |
| | (permalink) |
| I don't understand your sine table. It seems to go 1, 9, 5, 13, 3, 11 .... which doesn't look very sinusoidal. A quick play with excel gives a 20 byte sign table as, 7,9,11,13,14,14,14,13,11,9,7,5,3,1,0,0,0,1,3,5,7,9 ,11,13,14,14,14,13,11,9 Where, 7 represents 0 0 represents -1 14 represents +1 As for the binaural beat, I would guess that the LED should be on if one wave form is the opposite sign to the other waveform, but I suspect this would be twice the frequency. Maybe when A>0 and B<0 then LEN is on will work. Mike. | |
| |
| | (permalink) |
| The sine table is for a 4-bit based resistor network: 1k, 2k, 3k9, 8k2 which seems to work pretty good here (at least according to my scope) Should I just tie the LEDs to the PWM instead of the one or the other timer, but then I'm afraid that pulsing would be off because the PWM and the timers would not be in the right sync? If base freq is ~258.7 and second freq ~250.8 the difference is 7.9Hz and that would be the proper pulsing for the LEDs, but does that mean that they need to be on the whole time of those 7.9Hz (126.58227ms) or half the time 3.95Hz (63.29113ms) ?! Thanks | |
| |
| | (permalink) | |
| Quote:
Am I to presume you are using timer1 which is 16-bit, but you said 500ns which is 0.5us, so at 8MHz that's 1/4 of the instruction cycle or T1_DIV_BY_4 ? | ||
| |
| | (permalink) | |
| You won't be able to implement an interrupt at a 500ns rate on a PIC running at 8Mhz which gives you a 500ns instruction cycle. So Pommie's DDS method, while very elegant, won't work for you. EDIT: OOpps. I see he really meant 500uS not 500ns!!!! So it will work at that rate: Quote:
__________________ --- The days of the digital watch are numbered. --- Last edited by kchriste; 8th January 2008 at 05:21 AM. | ||
| |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Title | Starter | Forum | Replies | Latest |
| circuit help: square and sin wave input = square wave output | spyghost | Electronic Projects Design/Ideas/Reviews | 2 | 28th April 2004 02:09 AM |
| Effects | stephenpic | Micro Controllers | 6 | 19th January 2004 12:57 PM |
| VERY low voltage on output pins, please help! | New2PIC | Micro Controllers | 1 | 18th January 2004 04:22 AM |
| How do I generate a potentiometer output? | klick | General Electronics Chat | 3 | 23rd November 2003 03:26 PM |
| square waves into sine waves... any ideas???? | bully_victim | Electronic Projects Design/Ideas/Reviews | 9 | 10th November 2003 05:46 PM |