D/A chip for low frequency
Howdy guys, I am currently starting on the prop, I have held off way too long on this. I have been playing with the basic stamp for about 7 years and I need more power for what I am doing now.
What would you recomend for a Digital to Analog converter for low frequency range of 0.1 Hz to 12 Hz generation. I am currently working on a multichannel programable LFO and I want control over the PWM, phase and Amplitude·of the signal. Any sugetions? I have the Prop, regulators·and a 5Mhz crystal on order right now and just need a good choice for the Digital to analog. I'm also looking to do level detection so I will need an A/D also but thats not so critical at the moment.·
What would you recomend for a Digital to Analog converter for low frequency range of 0.1 Hz to 12 Hz generation. I am currently working on a multichannel programable LFO and I want control over the PWM, phase and Amplitude·of the signal. Any sugetions? I have the Prop, regulators·and a 5Mhz crystal on order right now and just need a good choice for the Digital to analog. I'm also looking to do level detection so I will need an A/D also but thats not so critical at the moment.·

Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Leon Heller
Amateur radio callsign: G1HSM
I also need it to be in DIP form. surface mount is a bit tough for my old hands.
on a side note is thier an I2C LCD avalible?
Post Edited (Pablo1234) : 5/15/2010 3:38:17 PM GMT
There are LCDs with serial interfaces, so there might I2C ones. I made my own serial LCD using an AVR, and I've often thought of making an I2C or SPI version.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Leon Heller
Amateur radio callsign: G1HSM
If one of the counters of a cog is initialized in DUTY mode, you only need to write the DAC value to the PHSx register.
So you can have 2 RC-DACs per cog.
The following code outputs a value at pin PA0 and increases it all 2 seconds.
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 DAC = 0 PUB Main | val dira[noparse][[/noparse]DAC] := 1 'Set up DAC ctra := %00110 << 26 + DAC 'counter A in DUTY mode val := 0 repeat 'loop frqa := val << 16 'set DAC (lower 16 bit of val) waitcnt(clkfreq*2 + cnt) 'wait 2 seconds val += 6000 'increase valueAndy
This is the DAC I'm looking at right now.
I don't want to do square wave outs and integrate them, I want control over the shape of the wave Tri, Saw, reverse saw and sine from .0 hz to 12 hz. I also need control over the amplitude and phase. doing this in anolog with a pulse output is how I am currently doing it with a basic stamp and its alot of extra circuitry, intigrator for square to·Tri or Saw·and high pass filter to readjust amplitude and set sine. Total pain in the but.
www.linear.com/pc/productDetail.jsp?navId=H0,C1,C1156,P2333
The buffered output will save you having to provide a buffer.
Linear is very liberal with free samples.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Leon Heller
Amateur radio callsign: G1HSM
With the Propeller there's much less external circuitry needed to get what you want. Here's a program I wrote to output low-frequency sine waves:
[b]CON[/b] [b]_clkmode[/b] = [b]xtal1[/b] + [b]pll16x[/b] [b]_xinfreq[/b] = 5_000_000 FREQ = 6111 'Frequency in millihertz. OUTPIN = 0 [b]PUB[/b] start | t, dt, phase, amplitude [b]ctra[/b] := %00110 << 26 | OUTPIN [b]dira[/b] := 1 << OUTPIN phase~ dt := clkfreq / 1000 t := [b]cnt[/b] + dt [b]repeat[/b] phase += FREQ << 15 / 3907 amplitude := sin(phase >> 10) << 15 + $8000_0000 [b]waitcnt[/b](t += dt) [b]frqa[/b] := amplitude [b]PUB[/b] sin(x) : value | t [b]if[/b] (x & $fff == $800) value := $ffff [b]else[/b] [b]if[/b] (x & $800) t := -x & $7ff [b]else[/b] t := x & $7ff value := [b]word[/b][noparse][[/noparse]*$e000][noparse][[/noparse]*t] [b]if[/b] (x & $1000) value := -valueIt uses a counter's DUTY mode output and the exact RC network that Andy showed above to filter it. Here's what the output looks like:
It's hardly what I'd call a "pain in the butt".
-Phil
Addendum: BTW, this is the raw output from the pin that the RC network is filtering:
'Notice the frequency and time scale? 12Hz is glacial by comparison.
Post Edited (Phil Pilgrim (PhiPi)) : 5/16/2010 9:17:19 PM GMT
I need 6 programable LFO's so the 8 channel will save me some pins
Here's some output that alternates between sine and sawtooth every cycle:
Andy's RC filter was a bit too aggressive for a sawtooth waveform, so I reduced the resistor to 6.8K to obtain this scope trace.
-Phil
I am getting sick as a dog but I think I can program from bed lol.
The main isue I had with integrating with an CR network on my stamp was that it would go from a tri wave at high freq to a saw at the lower frequencys. also the amplitude would change. I need to look more into how the Prop is programed and what its limitations are but I beleve I will be able to get closer to what I want with it x10. Some of the projects you guys have done are super impressive. I love the cnc router project.
I also have been reading the docs and I think I'm gona try the bst with PropBasic unless someone thinks it would be better for me to use Spin. I am very unfamiler with Spin, Multicore programing and the Propellor. I am very familer with PBasic, VB 6 and computer programing though.
Could someone start me off with PropBasic by rewriting this Spin Phil wrote the other day?
[b]CON [/b] [b]_clkmode[/b] = [b]xtal1[/b] + [b]pll16x[/b] [b]_xinfreq[/b] = 5_000_000 FREQ = 6111 'Frequency in millihertz. OUTPIN = 0 [b]PUB[/b] start | t, dt, phase, amplitude [b]ctra[/b] := %00110 << 26 | OUTPIN [b]dira[/b] := 1 << OUTPIN phase~ dt := clkfreq / 1000 t := [b]cnt[/b] + dt [b]repeat[/b] phase += FREQ << 15 / 3907 amplitude := sin(phase >> 10) << 15 + $8000_0000 [b]waitcnt[/b](t += dt) [b]frqa[/b] := amplitude [b]PUB[/b] sin(x) : value | t [b]if[/b] (x & $fff == $800) value := $ffff [b]else[/b] [b]if[/b] (x & $800) t := -x & $7ff [b]else[/b] t := x & $7ff value := [b]word[/b][noparse][[/noparse]­$e000][noparse][[/noparse]­t] [b]if[/b] (x & $1000) value := -valueok I wana try and break this down to see if I under stand it
this sets the·prop to the external crystal _xinfreq at 5,000,000 and xtal1 sets the proper internal RC network for the crystal and pll16x is the multiplier of _xinfreq x 16 = 80,000,000 hz
so ctra and ctrb will incrament every 12.5 microseconds with no modifiers.
the rest i get but I am a bianary person not boolian·so BITSHIFTING and·useing OR to add numbers kinda complicates it a bit for me. Not that I dont understand the·concept but i'm not understanding why you shift 0 (OUTPIN) to the 26th bit of ctra.
then phase an internal variable to the subroutine·is reset to 0 useing ~
dt is then set to··dt·:=·clkfreq·/·1000·= 80,000
then t is set to the current count + 80,000
so all that would be the initalization for the return loop that follows it. and the sin is a look up table in the rom to offset the amplitude to create a sin wave from a ramped signal.
I know I dont fully understand this yet but I want to.
' {$STAMP BS2p} ' {$PBASIC 2.5} Count_Base_0 CON 5000 Inc_Base CON 16 LFO1_Freq_T1 VAR Byte LFO2_Freq_T1 VAR Byte LFO3_Freq_T1 VAR Byte LFO4_Freq_T1 VAR Byte LFO1_Freq_T2 VAR Byte LFO2_Freq_T2 VAR Byte LFO3_Freq_T2 VAR Byte LFO4_Freq_T2 VAR Byte LFO_PWM VAR Byte LFO_Phase VAR Byte LFO1_Count VAR Word LFO2_Count VAR Word LFO3_Count VAR Word LFO4_Count VAR Word LFO1_State PIN 3 'Pulse out LFO2_State PIN 4 LFO3_State PIN 5 LFO4_State PIN 6 Config_Set PIN 12 Edit_P_Button PIN 13 DATA @0, 1 'LFO1 T1 Multiplier 1 to 16 DATA @1, 0 'Phase Incrament -16 to 16 DATA @2, 5 'T1 and T2 offset -11 - 11 DATA @16, 1 'LFO1 T1 Multiplier 1 to 16 DATA @17, 0 'Phase Incrament -16 to 16 DATA @18, 0 'T1 and T2 offset -11 - 11 DATA @32, 1 'LFO1 T1 Multiplier 1 to 16 DATA @33, 0 'Phase Incrament -16 to 16 DATA @34, 0 'T1 and T2 offset -11 - 11 DATA @48, 1 'LFO1 T1 Multiplier 1 to 16 DATA @49, 0 'Phase Incrament -16 to 16 DATA @50, 0 'T1 and T2 offset -11 - 11 Setup: READ 0, LFO1_Freq_T1 PUT 0, LFO1_Freq_T1 READ 1, LFO_Phase PUT 1, LFO_Phase READ 2, LFO_PWM PUT 2, LFO_PWM GET 0, LFO1_Freq_T1 GET 1, LFO_Phase GET 2, LFO_PWM LFO1_Count = (Count_Base_0 - (LFO_Phase * LFO1_Freq_T1)) LFO_PWM = (LFO_PWM * 2) * LFO1_Freq_T1 LFO1_Freq_T2 = LFO1_Freq_T1 * Inc_Base - LFO_PWM LFO1_Freq_T1 = LFO1_Freq_T1 * Inc_Base + LFO_PWM READ 16, LFO2_Freq_T1 PUT 16, LFO2_Freq_T1 READ 17, LFO_Phase PUT 17, LFO_Phase READ 18, LFO_PWM PUT 18, LFO_PWM GET 16, LFO2_Freq_T1 GET 17, LFO_Phase GET 18, LFO_PWM LFO2_Count = (Count_Base_0 - (LFO_Phase * LFO2_Freq_T1)) LFO_PWM = (LFO_PWM * 2) * LFO2_Freq_T1 LFO2_Freq_T2 = (LFO2_Freq_T1 * Inc_Base) + LFO_PWM LFO2_Freq_T1 = (LFO2_Freq_T1 * Inc_Base) - LFO_PWM READ 32, LFO3_Freq_T1 PUT 32, LFO3_Freq_T1 READ 33, LFO_Phase PUT 33, LFO_Phase READ 34, LFO_PWM PUT 34, LFO_PWM GET 32, LFO3_Freq_T1 GET 33, LFO_Phase GET 34, LFO_PWM LFO3_Count = (Count_Base_0 - (LFO_Phase * LFO3_Freq_T1)) LFO_PWM = (LFO_PWM * 2) * LFO3_Freq_T1 LFO3_Freq_T2 = (LFO3_Freq_T1 * Inc_Base) + LFO_PWM LFO3_Freq_T1 = (LFO3_Freq_T1 * Inc_Base) - LFO_PWM READ 48, LFO4_Freq_T1 PUT 48, LFO4_Freq_T1 READ 49, LFO_Phase PUT 49, LFO_Phase READ 50, LFO_PWM PUT 50, LFO_PWM GET 48, LFO4_Freq_T1 GET 49, LFO_Phase GET 50, LFO_PWM LFO4_Count = (Count_Base_0 - (LFO_Phase * LFO4_Freq_T1)) LFO_PWM = (LFO_PWM * 2) * LFO4_Freq_T1 LFO4_Freq_T2 = (LFO4_Freq_T1 * Inc_Base) + LFO_PWM LFO4_Freq_T1 = (LFO4_Freq_T1 * Inc_Base) - LFO_PWM Main: DO IF LFO1_State = 0 AND LFO1_Count = (Count_Base_0 + LFO1_Freq_T1) THEN LFO1_Count = Count_Base_0 HIGH LFO1_State ELSEIF LFO1_State = 1 AND LFO1_Count = (Count_Base_0 + LFO1_Freq_T2) THEN LFO1_Count = Count_Base_0 LOW LFO1_State ENDIF LFO1_Count = LFO1_Count + 1 IF LFO2_State = 0 AND LFO2_Count = (Count_Base_0 + LFO2_Freq_T1) THEN LFO2_Count = Count_Base_0 HIGH LFO2_State ELSEIF LFO2_State = 1 AND LFO2_Count = (Count_Base_0 + LFO2_Freq_T2) THEN LFO2_Count = Count_Base_0 LOW LFO2_State ENDIF LFO2_Count = LFO2_Count + 1 IF LFO3_State = 0 AND LFO3_Count = (Count_Base_0 + LFO3_Freq_T1) THEN LFO3_Count = Count_Base_0 HIGH LFO3_State ELSEIF LFO3_State = 1 AND LFO3_Count = (Count_Base_0 + LFO3_Freq_T2) THEN LFO3_Count = Count_Base_0 LOW LFO3_State ENDIF LFO3_Count = LFO3_Count + 1 IF LFO4_State = 0 AND LFO4_Count = (Count_Base_0 + LFO4_Freq_T1) THEN LFO4_Count = Count_Base_0 HIGH LFO4_State ELSEIF LFO4_State = 1 AND LFO4_Count = (Count_Base_0 + LFO4_Freq_T2) THEN LFO4_Count = Count_Base_0 LOW LFO4_State ENDIF LFO4_Count = LFO4_Count + 1 LOOP RETURNPost Edited (Pablo1234) : 5/20/2010 10:29:02 PM GMT
So how do I detect my on time and off time, not in the duty but the output. Say I want to have a triangle wave that ramps up·for 100mS and ramps down for 66mS. This would be on for·5/8ths and off for 3/8ths of 6Hz. I want to specify frequency and change·the duty of my output wave.
How do·I make an offset of my phase relationship between LFO 1·,2, 3, 4, 5, 6? and at what incrament would it be in. at 12Hz and 1 mS slice time·I am gessing 2.3 deg phase incraments, correct?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
A woman is the only thing I am afraid of that I know will not hurt me. - Abraham Lincoln