simple synth using resistor network for adc input; questions about resolution and cur

moorea21

Senior Member
I'm hoping to build a synthesiser of the most basic kind, using input to adc via any one of 60 resistors from a 5V source (1 under each 'key' of the keyboard), all of unique value, so that the input voltage varies between about 160mV to about 4.85V, using a 5V supply. So the lowest note would be 160mV; some code of the type 'if input = 160mV then output note x' would be added for each possible note. I left the 160mV margin at both ends to make the maths easier; I get 4 of my 256 value levels per note that way.

This sounds simple, but there must be some limitations somewhere to complicate this. For instance, is there a recommended input current range for adc on the 08m2? I know the maximum recommended is 20mA per channel. With 60 input voltage levels between my max and min, each input voltage would have a margin of error of +-1 gradation (19.5mV) before it gets close to being misread as the next value. Would this be enough to compensate for noise, temperature changes, etc, or am I asking for too much esolution from this chips adc inputs?

Thanks.
 

nick12ab

Senior Member
According to the PICAXE Manual, the maximum recommended input impedance of an ADC channel is 20k, so you should be fine as long as your resistor values satisfy that - the output impedance of each potential divider formed by the resistors when a switch is pressed is equivalent to all those on the high side (added up in series) in parallel with all those on the low side (added up in series). Microchip recommends an impedance of 3k but you should be fine if a small capacitor is used on the ADC input.

The effects of tolerances and temperature changes depend mostly on the tolerance of your resistors - check the datasheet for them. Let's say you use 1% resistors - would it be a problem if all the resistors on the high side were at 101% their value and all the resistors on the low side were at 99% of their value? Accuracy data of the ADC itself can be found in the datasheet for the microcontroller you're using.

Will it work if you hold down multiple keys simultaneously? Do you need to?
 

premelec

Senior Member
For full READADC accuracy source impedance should be 10K or less - input _current_ is very small. Stuff to consider is keyboard contact resistance and such. Lots of possible problems... good luck! Forgot to mention filtering as low pass as you can to exclude noise from READADC input - there are signals everywhere in our environment...
 
Last edited:

moorea21

Senior Member
Thanks nick12ab, I only need one note at a time, and a pwm 'buzzer' would be fine as output.

When you say 'a small capacitor' in the adc input, what sort of figures are you thinking of?
 

nick12ab

Senior Member
When you say 'a small capacitor' in the adc input, what sort of figures are you thinking of?
Microchip has recommended 10nF for the PICAXE-14M2 and 20M2, though this value isn't critical and only needs to be "around that".

Your application has a special requirement though, which is that the voltage (presumably) needs to fall quickly back down to zero when a key is released, or the sound of every key below the pressed one will be generated in turn when the pressed key is released, therefore a small capacitor should be used.

I'm guessing the ADC input would be floating if no key is pressed, because the resistors are in a ladder configuration, right? A large resistor (e.g. 100k but depends on your resistor values) which has negligible effect on the output of the switched-in potential divider should be placed in parallel with the capacitor. The discharge time of the capacitor is 5 * R * C (C is in Farads) so 0.05s for 10nF cap and 100k resistor. Also the ADC input will need to be debounced in software (e.g. only act on key presses where the same key is detected for two samples in a row).
 

AllyCat

Senior Member
Hi,

Yes, as premelec says, the source impedance should be less than 10k ohms, but that is achieved with a divider made from two 20k resistors in series (between supply and ground). The linearilty of the ADC is probably good enough (particularly if you use READADC10), but you may well need to use 1% accuracy/tolerance resistors.

But how are you planning to signal "no sound"? If for example it's to be "zero volts" then that also needs a < 10k source impedance (not just all switches open-circuit). If you use a pull-down resistor, then that will seriously affect the linearity of your divider chain calculations. So I suggest you sketch out how you plan to interface (a few of) the switches. This may also help to determine what size capacitor the input can tolerate; it will probably need a (worst) time constant of less than 1 ms to avoid the input level "sweeping" through a sequence on notes (or maskiing this effect in the sofware).

Cheers, Alan.
 

moorea21

Senior Member
Thanks both,
What I had envisaged at its simplest would be a single resistor and switch between supply rail and ADC. Imagine 60 of those, that's what I had in mind. maybe a voltage divider to hold the adc above earth would be good; whatever voltage that inputs could be marked in software as 'no output'. De-bounce sounds a good idea.
 

AllyCat

Senior Member
Hi,

If you use a 10k pulldown resistor permanently between the ADC input and ground, then I calculate that your switched pullup resistors will range from around 600k down to 150 ohms. That's good in that some (but not all) need be only "5%" tolerance, but you're going to need to make up some fairly "weird" values.

Another factor is that I presume the 60 switches are to represent 5 octaves, or a frequency ratio of 32 : 1 ? Note that the PWM frequency only has a (linear) setting range of one byte (256), so your highest frequency will be settable only to around 1/8 or +/- 6% (EDIT: Although the DIV4 .. prescalers may help get around this).

Cheers, Alan.
 

moorea21

Senior Member
If you use a 10k pulldown resistor permanently between the ADC input and ground, then I calculate that your switched pullup resistors will range from around 600k down to 150 ohms.
Yes, that was the sort of range I came up with, but i'm a bit concerned that the current passed to the adc via a 600k resistor will be way too small.

Another factor is that I presume the 60 switches are to represent 5 octaves, or a frequency ratio of 32 : 1 ? Note that the PWM frequency only has a (linear) setting range of one byte (256), so your highest frequency will be settable only to around 1/8 or +/- 6% (EDIT: Although the DIV4 .. prescalers may help get around this).

Yes, nearly 5 octaves. I may well have misunderstood, but I was under the impression that picaxes can 'beep' 128 different tones, which I (maybe wrongly) assumed to be semitones? I have to admit I havent considered the output in any depth; I thought maybe passing a voltage via DAC to a voltage to frequency chip, through an op amp to a speaker. But I'm not sure about resolution of that set up either. Was banking on the 'beeps' really...
Not heard of DIV4, etc before, sounds very sensible, does it work with 08m2s? the website doesnt say it doesnt...
 

moorea21

Senior Member
Of course the resistors on the adc input dont have to correspond directly to the required output frequency; they are just there to give each key a unique identity to trigger the appropriate output; I could use a linear scale input, for a logarithmic output.
With a 10k pull up resistor, if the resistor(s) 'above' it so to speak vairied from 0 to 10k, that would give 128 of the 256 adc levels to choose from. Not as great as the whole 256, but maybe enough to work with. I have a lot of resistors and trim pots, so I should be able to get something workable that way if necessary. At the end of the day, If I end up dividing the input duties to moer than one adc pin, or even using 2 picaxes, it's no big deal.
 

AllyCat

Senior Member
Hi,

600k + 10k is fine for the ADC because the source impedance (10k in parallel with 600k) is less than 10k. The point is that if you have a fixed lower (or upper) resistor value then to produce linear voltage changes the other resistor needs to be in an approximately logarithmic sequence (tip: the normal "E12" or "E24" series of resistors are basically in a logarithmic sequence). But if you want to use (and calibrate) 60 pots, then that's up to you. ;)

I've never used the SOUND command (partly) because AFAIK it's generated by software and "blocking", i.e. you must specify the duration and the PICaxe can't do anything else until the "beep" finishes (and I don't believe the numbers corrsepond directly to semitones). That's the reason for using the PWM command where the DIVn is explained (and yes the 08M2 has one normal PWM channel).

Another factor to consider is that 60 x "IF .. THENs" will take quite a time to execute and the alternatives such as SELECT .. CASE or LOOKDOWN, etc. are not much better (and maybe worse). If your input voltage range is genuinely linear, you might be able to scale and use ON...GOTO, or maybe use a "decoding tree": IF adcinput < halfway THEN : IF adcinput < quarterway : etc...

Finally, square waves (from PWM or SOUND) are not very "musical" so you might need to consider some (variable) low-pass filtering.

Cheers, Alan.
 

hippy

Technical Support
Staff member
With 60 input voltage levels between my max and min, each input voltage would have a margin of error of +-1 gradation (19.5mV) before it gets close to being misread as the next value. Would this be enough to compensate for noise, temperature changes, etc, or am I asking for too much esolution from this chips adc inputs?.
Having 60 resistors could be asking too much but it might work. There is a +/- 8 step tolerance using READADC10 which I think equates to about 0.5% tolerance for the resistors.

But you could also split the resistors into banks, use multiple ADC channels to read those.

An easier solution with a larger PICAXE would be to use an 8x8 keypad matrix. By using active low drive and sensing it's possible to scan a row at a time and check if any key is pressed so that should be quite speedy. That also overcomes the problem of pressing two keys, in fact opens the door to allowing multiple key detections for polyphonic sound.

I had a design for a MIDI keyboard which did exactly that, generated Note On and Note Off commands for any and all keys. I'll see if I can find it again.
 

premelec

Senior Member
If you want to stay resistors - though hippys' method is better - consider trimmer pots and in the good old days we filed notches in high quality [AB] carbon composition resistors to trim their values higher - and then coated the notch with laquer... :) Still that's a lot of resistors to modify...
 

moorea21

Senior Member
I found this yesterday:-
http://www.instructables.com/id/Tic-Tac-Tunes/?ALLSTEPS
A 'stylophone' based on a 08m, which seems to produce 36 semitones (or maybe just 18, judging by the sound file called 'chromatic.mp3'?), and uses a stripped 10k linear pot as a 'keyboard'. I was thinking of trying this, substituting a 1 turn 10k rotary pot, and marking (and measuring the resistance) at the points where the output transitions to the next note. 2 08m2's would give me 6 octaves, not that I need that many.
Hippy's midi keyboard sounds like a better idea musically; if you do manage to dig out the ircuit/code, I'd be very interested. Thanks.
And yes, its a lot of trim pots/filing. A bit boring no doubt...
I had overlooked the logarithmic nature of the input voltages. Not for the first time in a project like this... duh.
 

hippy

Technical Support
Staff member
Here's an 8x8 (64) keypad matrix scanner for a 20M2. Should also work for 20X2, X1 and X2 ...

Code:
#Picaxe 20M2
#Terminal 4800

; 8 x 8 keypad matrix scanner

; B.x are output low or input ( controlled by dirsB )
; C.x are inputs with pull-ups

pinsB = %00000000 ; B.x outputs low
dirsB = %00000000 ; B.x are inputs
dirsC = %00000000 ; C.x are inputs with pull-ups
Do
  ; Loop until key pressed - b0=0..63 
  Do
    b0 = $80
    Gosub ScanAll
  Loop until bit7 = 0
  SerTxd( "Pushed", 9, #b0 )
  ; Loop until key pressed is released - pinsC=$FF
  Do : Loop Until pinsC = $FF
  SerTxd( 9, "Released", CR, LF )   
Loop

ScanAll:
  ; Set B.x low in turn by using dirsB - 0 = input, 1 = output low
  dirsB = %00000001 : Gosub Scan : If bit7 = 0 Then ScanDone : b0 = b0 + 8
  dirsB = %00000010 : Gosub Scan : If bit7 = 0 Then ScanDone : b0 = b0 + 8
  dirsB = %00000100 : Gosub Scan : If bit7 = 0 Then ScanDone : b0 = b0 + 8
  dirsB = %00001000 : Gosub Scan : If bit7 = 0 Then ScanDone : b0 = b0 + 8
  dirsB = %00010000 : Gosub Scan : If bit7 = 0 Then ScanDone : b0 = b0 + 8
  dirsB = %00100000 : Gosub Scan : If bit7 = 0 Then ScanDone : b0 = b0 + 8
  dirsB = %01000000 : Gosub Scan : If bit7 = 0 Then ScanDone : b0 = b0 + 8
  dirsB = %10000000 : Gosub Scan
ScanDone:
  Return

Scan:
  ; If no key pressed pinsC will be $FF
  If pinsC = $FF Then
    Return
  End If
  ; Determine which pin pulled low; b1=0..7, b1=8 means none 
  LookDown 0, (pinC.0,pinC.1,pinC.2,pinC.3,pinC.4,pinC.5,pinC.6,pinC.7,0), b1
  ; If b1 <> 8 then we have a pin pulled low
  If bit11 = 0 Then
    ; Set which key pressed
    b0 = b0 & $78 | b1
  End If 
  Return
 

moorea21

Senior Member
Thanks Hippy, I like that better than my idea, much less hassle.
So when you say an 8 x 8 matrix, is that a matrix of 64 swiches connected from supply to inputs via a (? ohm) resistor? I can't tell how the matrix would connect to the picaxe either, is it 16 inputs?
Also, there are some statements there that read 'Gosub Scan'. I camn't see a sub called Scan. Is that something picaxe has already?
 
Last edited:

hippy

Technical Support
Staff member
The matrix is made from normally open switches connecting port B pins to port C pins. It is technically 8 output drives (B) and 8 input drives (C), but only one B line is driven low at a time, keeping the rest of B as inputs. No resistors other than the pull-ups on C inputs required ...

Code:
V+ ---.-.-- --.-
     .|.|.   .|.
     |_|_|   |_| 8 x 10K
      | |     |
C.0 --^-|-- --|---o----o---- --o      --o
        |     |    \    \       \        \ = N/O switch
        |     |     o    o       o        o
C.1 ----^-- --|---o-|--o-|-- --o |        |
              |    \|   \|      \|
              |     o    o       o
 :            :     :    :       :
              |     |    |       |
C.7 ----------^---o-|--o-|-- --o |
                   \|   \|      \|
                    o    o       o
                    |    |       |
B.0 ----------------'    |       |
B.1 ---------------------'       |
 :                               |
B.7 -----------------------------'
The "Scan" routine is towards the bottom of the program.
 

AndyGadget

Senior Member
I found this yesterday:-
http://www.instructables.com/id/Tic-Tac-Tunes/?ALLSTEPS
A 'stylophone' based on a 08m, which seems to produce 36 semitones (or maybe just 18, judging by the sound file called 'chromatic.mp3'?), and uses a stripped 10k linear pot as a 'keyboard'.
Hmmm . . . That looks familiar ;)

The challenge there was to get that running on an 08m, but with a 14m2 you can have a lot of fun with PWM by mixing channels (harmonic thirds etc) and adjusting the decay.
With 3 channels at an octave apart and long decay I got quite a decent 'church organ' effect. The 'Cosmotron' was another of those projects I was going to finish off one day, but that day hasn't come yet.
 

moorea21

Senior Member
Ah, you are that man!
I'd like to combine your stylo's output ( it it pwm?) with hippy's 8 x 8 matrix for input, if it's possible. Thats the rough plan, anyway, at this stage.
Trouble is I can't work out a way of increasing the output frequency range form the stylophone's 3 octaves ( is that all 36 chromatic tones within those 3 octaves btw?) up to the 4 1/2 to 5 octaves I was looking for.
Only thought at the minute is to use an analogue voltage multiplier switched on by an outputpin on the picaxe. Havent found a circuit that will do that yet, although this one (https://www.maximintegrated.com/en/app-notes/index.mvp/id/3327) at least takes its 'cue' from a voltage divider, so it could maybe be useful.

the other problem is that the lowest frequency I want would ideally be 196Hz (G) rather than the C (262?) that seems to be the lowest your stylophone will go.
 

AndyGadget

Senior Member
The original 'Stylophone' as published used the Tune command and so was limited in range. PWM gives you a lot more range as you have the pre-scaler options. Even more range is possible if you start playing around with the Picaxe clock frequency. It's a long time since I looked at that code and can't remember exactly what I was doing. I'm still at work, but I'll dig it out tonight and post it.
 

AndyGadget

Senior Member
There again - Just found a fairly complete version on my memory stick.
It uses 4 ADCs - One for the slider and then a rotary pot each for the octave, decay and for the effect (mix of channels). The PWM pin outputs were a simply fed to a small powered speaker via a resistor mixer. No comments, but variable names are pretty descriptive.
(PWM values against note frequency aren't bad at the top, but get pretty ropey at the low end.)

Code:
#picaxe 14m2
setfreq m4
'#terminal 4800
#terminal off
'#no_data
'#no_table

' Major  W W H W W W H
' Minor  W H W W H W W
   
data (0,252,238,212,189,178,158,141)
'        B   C   D   E   F   G   A  

data (126,118,105,94,88,79,70)
'      B   C   D  E  F  G  A  

data (62,59,52,46,44,39)
'      B  C  D  E  F  G 


symbol piezo1 	= c.2
symbol piezo2 	= b.4
symbol piezo3 	= b.2
symbol LED		= c.1
symbol adc_prb	= b.1
symbol adc_oct	= c.0
symbol adc_dky	= b.3
symbol adc_eff	= b.5
symbol sw1 		= pinc.3
symbol sw2 		= pinc.4

symbol WVal1 	= w13
symbol WVal2 	= w12
symbol WVal3 	= w11

symbol AVal 	= b1
symbol AvalX 	= b2
symbol dky		= b3
symbol Note1 	= b4
symbol Note2	= b5
symbol Note3	= b6
symbol Efct		= b7
symbol Oct		= b8
symbol ArpCnt 	= b9
symbol ArpNote 	= b10
symbol Mult		= b11
symbol tmp1		= b12
symbol dkyx 	= b13

'symbol dkyx		= b6
'symbol TDir		= b7
'symbol Tmp2		= b10
'symbol Cnt		= b13
'symbol note3x 	= b14
'symbol octx 	= b15
'symbol efctx	= b16

symbol sp = 32
symbol hi = 1
symbol lo = 0
symbol true = 255
symbol false = 0

'tdir = true
'dkyx = 20

do
	readadc adc_dky,dky	' Read decay pot - Min is no decay mode
	dky = dky / 16

	'if dky <> dkyx then	' Lookup for decay values
		'lookup dky,(128,47,59,70,80,89,97,104,110,115,119,122,124,125,126,127),dky				
		lookup dky,(128,17,27,37,47,59,70,80,89,97,104,110,115,119,122,124),dky				
	'	dkyx = dky
	'end if
	
	readadc adc_oct,oct	' Read octave pot
	oct = oct / 51
	
	'if oct<>octx then
		select oct
			case=0
				setfreq m1
				mult = 1
			case=1
				setfreq m2
				mult = 2
			case=2
				setfreq m4
				mult = 4
			case=3
				setfreq m8
				mult = 8
			case=4
				setfreq m16
				mult = 16
		end select			
		'octx = oct
	'end if
	
		
	readadc adc_prb,aval	' Get position of probe
	aval = 255 - aval + 10 / 22
	'aval = 255 - aval + 16 / 18
		
	if aval <> avalx and aval <=16 then
		avalx = aval
		gosub newnote
	end if
	
	if aval = 0 and dky = 128 then
		wval1 = 0
		wval2 = 0
		wval3 = 0
	end if
	
	tmp1 = tmp1 + 1 // mult
	
	if tmp1 = 0 then
		
	wval1 = wval1 * dky/128		
	wval2 = wval2 * dky/128		
	wval3 = wval3 * dky/128		
	pwmduty piezo1,wval1
	pwmduty piezo2,wval2
	pwmduty piezo3,wval3	
	toggle led

	end if

loop					


NewNote:
	
	read AVal,Note1


	if note1 <> 0 then
		readadc adc_eff,efct ' Note sound - 0 to 7
		efct = efct / 32
				
		select efct
		case 0 ' Unison

			note2 = note1
			note3 = note1

			wval1 = note1 * 2							
			wval2 = note1 * 2							
			wval3 = note1 * 2						

			pwmout pwmdiv16, piezo1,note1,wval1
			pwmout pwmdiv16, piezo2,note2,wval2
			pwmout pwmdiv16, piezo3,note3,wval3		
				
		case 1 ' Octave up & down

			note2 = note1 / 2
			note3 = note1 / 2
			wval1 = note1 * 2							
			wval2 = note2 * 2
			wval3 = note3 * 2
			
			pwmout pwmdiv16, piezo1,note1,wval1					
			pwmout pwmdiv16, piezo2,note2,wval2
			pwmout pwmdiv64, piezo3,note3,wval3

		case 2 '  2 octavesup & down
			
			note2 = note1 
			note3 = note1
			
			wval1 = note1 * 2							
			wval2 = note2 * 2
			wval3 = note3 * 2
			
			pwmout pwmdiv4, piezo1,note1,wval1					
			pwmout pwmdiv16, piezo2,note2,wval2
			pwmout pwmdiv64, piezo3,note3,wval3

		case 3 '  Minor 5th chord
			
			note2 = note1 * 5 / 6	' Min 3rd
			note3 = note1 * 2 / 3 	' Perf 5th
			
			wval1 = note1 * 2							
			wval2 = note2 * 2
			wval3 = note3 * 2
			
			pwmout pwmdiv16, piezo1,note1,wval1					
			pwmout pwmdiv16, piezo2,note2,wval2
			pwmout pwmdiv16, piezo3,note3,wval3
							
		case 4 '  Major 5th chord
			
			note2 = note1 * 4 / 5	' Maj 3rd
			note3 = note1 * 2 / 3 	' Perf 5th
			
			wval1 = note1 * 2							
			wval2 = note2 * 2
			wval3 = note3 * 2
			
			pwmout pwmdiv16, piezo1,note1,wval1					
			pwmout pwmdiv16, piezo2,note2,wval2
			pwmout pwmdiv16, piezo3,note3,wval3

		case 5 '  Power chord - Root and 5th
			
			note2 = note1 / 3
			note3 = note1 * 2 / 5
			wval1 = note1 * 2							
			wval2 = note2 * 2
			wval3 = note3 * 2
			
			pwmout pwmdiv16, piezo1,note1,wval1					
			pwmout pwmdiv16, piezo2,note2,wval2
			pwmout pwmdiv64, piezo3,note3,wval3



		case 6 ' 3 channels offset
		
			note2 = note1 * 238 / 240
			note3 = note1 * 244 / 240

			wval1 = note1 * 2							
			wval2 = note2 * 2							
			wval3 = note3 * 2							

			pwmout pwmdiv16, piezo1,note1,wval1
			pwmout pwmdiv16, piezo2,note2,wval2
			pwmout pwmdiv16, piezo3,note3,wval3

		case 7 '  Major 5th chord arpeggiated
			
			note2 = note1 * 4 / 5	' Maj 3rd
			note3 = note1 * 2 / 3 	' Perf 5th
			
			wval1 = note1 * 2							
			wval2 = note2 * 2
			wval3 = note3 * 2
			
			pwmout pwmdiv16, piezo1,note1,wval1					
			pwmout pwmdiv16, piezo2,note2,wval2
			pwmout pwmdiv16, piezo3,note3,wval3

		end select

	end if	
		
return


LedFlash:

	high led
	pause 50
	low led 

return
 

moorea21

Senior Member
Theres a lot going on in there!
My idea was to keep it really simple; no decay or mixing. It's going in a synth violin (so the only polyphony possible is on 2 adjacent strings,) so chords won't be possible either. The tones produced in your youtube video of the stylophone were exactly on pitch; I would expect it to be quite complicated to get that accuracy across the range using pwm.
I like the idea of altering the clock speed to extend the range, how fast can that be done on the fly? I imagine the transition would in no way be audible.
Does altering the clock speed make the note's frequencies no longer 'in tune'? Also, would your original stylophone play all notes over 3 octaves? Thanks.
 

AndyGadget

Senior Member
I'm absolutely no sort of a musician so quite happy to believe you about the tuning ;) As you've seen the TUNE command is of pre-defined length with an inbuilt pause after so could be a problem in your application. PWM would allow for continuous notes while a button is pressed. A factor which could affect the overall tuning is the clock frequency tolerance - I forget the figure but i seem to recall it can vary a few percent.
Changing the clock speed is instantaneous, but response time of scanning and TUNE duration etc would also alter accordingly.

I've attached spreadsheets I put together at the time of TUNE commands for the range of notes available. Of course, halving the clock speed would drop everything by an octave.
The other spreadsheet is PWM commands against ideal frequency. The thing missing here is the column of actual against the ideal note frequency. The notes will be closer to ideal at the higher frequencies as the resolution is better.

** Change the .ZIP extension to .XLS - The editor doesn't allow the Excel extension **

View attachment Freq-PWM.zip View attachment TuneData.zip
 

moorea21

Senior Member
Thanks, I hadn't twigged that the pause in 'tune' is permanent. Maybe pwm would be better, especially as you've done so much of the work already. Makes it feasible for me now!
I think what I need to do is write something that just outputs a 'scale' of pwm sounds, and check the frequencies. If the low ones sound wrong to a tin eared old git like me, I may see if there is another approach for the low ones...
May take some time, I've done very little picaxe coding, and found it a bit quirky when I did, but it'll get done.

Thanks for the help, much appreciated.
 

AndyGadget

Senior Member
Just glanced at that DATA statement and realised what I've told you is the wrong way around - The higher notes (lower PWM count) is where the PWM frequency will vary most from ideal.
Your program can be a lot simpler than mine if you're not using any decay. Mine loops around and changes the mark/space dynamically but you will just need a lookup for the PWMOUT value and then set PWMDUTY to a 50/50 mark/space, which will be 2 * the PWMOUT value. (PWMOUT period is in the range 0 - 255. PWMDUTY is 0 - 1023, so don't forget to use a word variable for this.)
 

moorea21

Senior Member
I've got as far as I can using pwm to get proper note frequecies out of a picaxe, I think. PWM can be tweaked a bit using DIV and setfreq, aiming to keep the 'period' number as high as possible but still under 255 (allows finer adjustments.)
The results arent that great; it's hard to measure the core frequencies that pwm outputs, but opening an mp3 of the attached code into 'intonia' (decent tuning/visualisation app aimed at violin players, etc) gives quite a wide variation in 'intervals'. It's audibly a bit wonky too, which is what really counts.

I may experiment more with 'tune', using very short 'lengths', and maybe a frequency doubler cicuit to extend the range (it seems setfreq doesnt work with 'tune'.) Tune notes are way better tuned than I can get with pwm. Oh well!
 

Attachments

moorea21

Senior Member
A question for AndyGadget:-

Your stylophone plays continuous notes very quickly for as long as the stylus contacts that part of the track that generates that particular pitch (https://www.youtube.com/watch?feature=player_embedded&v=U5Lovgc2FRQ, 1.08 mins.) I was hoping to set that to 'super fast' if thats possible, so it sounds more or less like a continuous note. I can't see how the very fast tempo is acheived in your software, can you enlighten me, if you get the time? Thanks.
 

AndyGadget

Senior Member
Ah, the bagpipe section ;)
The program plays everything as 1/8th notes and changes the note length by altering the tempo - Manual 2 page 251 gives the timing details.
The bit you mention is with a tempo of 1, which according to the manual equates to 1624 BPM (1/8th notes). Anyone into Speedcore?
 

moorea21

Senior Member
Hmmm....
Page 251 is TMR3SET, not even heard of that before, it says it's only for X2 chips, not m2. Does it do something in M2 chips too?
The manual says 812 bpm for '1'. If it was 1624, that would help.
For some reson I was using semibreves, not quavers. Duh.
Speedcore is great! But super fast notes that somehow get blended together (not sure how yet) are even better, potentially. Thanks for the pointers
 

AndyGadget

Senior Member
Hmmm....
Page 251 is TMR3SET, not even heard of that before, it says it's only for X2 chips, not m2. Does it do something in M2 chips too?
The manual says 812 bpm for '1'. If it was 1624, that would help.
For some reson I was using semibreves, not quavers. Duh.
Speedcore is great! But super fast notes that somehow get blended together (not sure how yet) are even better, potentially. Thanks for the pointers
Yep, I knew I should have given the manual version I was looking at - That was manual 7.9 accessed via the help system of editor 5.5.5.
It will be in manual 2 of the three; Just look for TUNE in the editor you're using.
 

moorea21

Senior Member
Thanks Andy.

I've had a more thorough look at what's needed to get a synth violin working, and I've decided a workable approach would be to use all the ADC's on a 20M2 , connected via a network of 9 switches and resistors of easily sourced values. This leaves C4 and C5 as pwm and hpwm respectively (can both be used simultaneously? They need to be, for 'double stops' where 2 strings are sounded at once.) I may have a use for C0, C6, and B7 as inputs.

Is it possible to use all 11 adc inputs on this chip (read sequentially, of course)?
Can hpwm do the same job as pwm? Can both be used simultaneously?
This is a longshot; can I use the serial input (pin 2) as another input? The idea would be to read its input with some code that basically says "if pin2 not equal 0000..., then 'consider it active."

The resistor values and their expected 'trigger points' are below:-

220k ADC<19
100k <60
22k <100
10k <135
8.2k <160
4.7k <200
2.2k <230
820r <240
220r <252

These values are cribbed from another instructable (http://www.instructables.com/id/StyloBuzz-Synthesizer/?ALLSTEPS), and I haven't tested them yet.
 
Top