var SPI = require('spi');
var spi = new SPI.Spi('/dev/spidev0.0', {
'mode': SPI.MODE['MODE_1'], // clock idle low, clock phase active to idle.
'chipSelect': SPI.CS['none'], // 'none', 'high' - defaults to low
'maxSpeed': 8000000
}, function(s){s.open();});
var rxbuf = new Buffer([ 0x00 ]);
var state = 0;
function writeToSpi(){
var txbuf = new Buffer([ state ]);
spi.transfer(txbuf, rxbuf, function(device, buf) {
console.log("Wrote " + state + " to SPI");
console.log("Received " + buf[0] + " from slave");
});
state++;
setTimeout(writeToSpi, 100);
}
writeToSpi();
Sunday, December 20, 2015
SPI gotchas
I am working on SPI communication between the Raspberry PI and a PIC32MX microcontroller for use in the Xonik M8 polysynth.
SPI is a very easy protocol once you get the hang of it, but it has a few gotchas:
CPOL - clock polarity
This defines when the clock is "idle" and when it is "active". The clock stays in idle mode whenever data is not transferred and goes active once per bit that should be transferred. The two possible states are:
CPOL=0 - clock is idle low, e.g. it is 0 when it is not running
CPOL=1 - clock is idle high, e.g. it is 1 when it is not running
CPHA - clock phase
This defines when new data should be read from and written to the bus. The two modes are "Idle to Active" and "Active to Idle". When the mode is "Idle to Active", data is READ (captured) when the clock changes from idle to active. Data must be WRITTEN to the bus when the clock changes from active to idle.
It is important to remember that CPHA is in relation to CPOL. Idle to Active does NOT always mean when the clock changes from 0 to 1 - if CPOL is 1, Idle to Active happens when the clock changes from 1 to 0.
The two possible states are:
CPHA=0 - Idle to Active, data is read when the clock changes from idle to active
CPHA=1 - Active to Idle, data is read when the clock changes from active to idle
This may sound a bit complex, but unless you are writing your own SPI slave/master code on a device without hardware support, all is taken care of for you. You just have to select the same config on the master and the slave.
The four common modes are:
0 - CPOL=0, CPHA=0 - clock is idle low, data is read on the rising edge
1 - CPOL=0, CPHA=1 - clock is idle low, data is read on the falling edge
2 - CPOL=1, CPHA=0 - clock is idle high, data is read on the falling edge
3 - CPOL=1, CHPA=1 - clock is idle low, data is read on the rising edge
If any data exists in the output buffer, it will be sent when the clock ticks once. Similarly, any data on the wire will be put into the input buffer when the clock ticks once. In other words, anything found in the output buffer on the master AND slave will be put on the wire once the clock starts running.
But what does this really mean?
First of all it means that in order to receive bits, the master has to pulse the clock the same number of times as the number of bits it wants to receive.
To do this, many SPI libraries including those on the Raspberry PI and the Microchip microcontrollers require you to actually send a byte. The byte may be zero as we are often only interested in the received data (this, of course, means that the transfer is only half duplex), but it can also be data usefull to the slave such as the next command/address to retrieve.
Secondly, to retrieve data from a slave you first need to transfer a command from the slave to the master. This could be a memory address, an action or similar, telling the slave to fill its output buffer. After the initial command/once the output buffer has been filled, you have to send a second byte to run the clock in order to transfer the data from the slave to the master. As mentioned above, this byte could either be bogus data or a new command, it all depends on how the slave is implemented. (As a side note, it is not strictly necessary to send a command before receiving data. For example, a ADC SPI slave could continously put its latest sampled value into its output buffer, which the master will read whenever it needs a new value from the ADC).
More info about the SPI bus can be found on wikipedia.
SPI is a very easy protocol once you get the hang of it, but it has a few gotchas:
1) Setup - SPI mode
There are two important parameters that control transmission. It is not essential to understand exactly what they do, but it IS important that they are set up the same way on the master and the slave. The parameters are:CPOL - clock polarity
This defines when the clock is "idle" and when it is "active". The clock stays in idle mode whenever data is not transferred and goes active once per bit that should be transferred. The two possible states are:
CPOL=0 - clock is idle low, e.g. it is 0 when it is not running
CPOL=1 - clock is idle high, e.g. it is 1 when it is not running
CPHA - clock phase
This defines when new data should be read from and written to the bus. The two modes are "Idle to Active" and "Active to Idle". When the mode is "Idle to Active", data is READ (captured) when the clock changes from idle to active. Data must be WRITTEN to the bus when the clock changes from active to idle.
It is important to remember that CPHA is in relation to CPOL. Idle to Active does NOT always mean when the clock changes from 0 to 1 - if CPOL is 1, Idle to Active happens when the clock changes from 1 to 0.
The two possible states are:
CPHA=0 - Idle to Active, data is read when the clock changes from idle to active
CPHA=1 - Active to Idle, data is read when the clock changes from active to idle
This may sound a bit complex, but unless you are writing your own SPI slave/master code on a device without hardware support, all is taken care of for you. You just have to select the same config on the master and the slave.
The four common modes are:
0 - CPOL=0, CPHA=0 - clock is idle low, data is read on the rising edge
1 - CPOL=0, CPHA=1 - clock is idle low, data is read on the falling edge
2 - CPOL=1, CPHA=0 - clock is idle high, data is read on the falling edge
3 - CPOL=1, CHPA=1 - clock is idle low, data is read on the rising edge
2) Data transfer
Data transfer is full duplex, meaning that data is sent and received at the same time. One bit of data is transfered every clock cycle - in both directions.If any data exists in the output buffer, it will be sent when the clock ticks once. Similarly, any data on the wire will be put into the input buffer when the clock ticks once. In other words, anything found in the output buffer on the master AND slave will be put on the wire once the clock starts running.
But what does this really mean?
First of all it means that in order to receive bits, the master has to pulse the clock the same number of times as the number of bits it wants to receive.
To do this, many SPI libraries including those on the Raspberry PI and the Microchip microcontrollers require you to actually send a byte. The byte may be zero as we are often only interested in the received data (this, of course, means that the transfer is only half duplex), but it can also be data usefull to the slave such as the next command/address to retrieve.
Secondly, to retrieve data from a slave you first need to transfer a command from the slave to the master. This could be a memory address, an action or similar, telling the slave to fill its output buffer. After the initial command/once the output buffer has been filled, you have to send a second byte to run the clock in order to transfer the data from the slave to the master. As mentioned above, this byte could either be bogus data or a new command, it all depends on how the slave is implemented. (As a side note, it is not strictly necessary to send a command before receiving data. For example, a ADC SPI slave could continously put its latest sampled value into its output buffer, which the master will read whenever it needs a new value from the ADC).
More info about the SPI bus can be found on wikipedia.
SPI and the Microchip PIC using Mikroelektronika's MikroC
There is another gotcha in the naming of SPI states in MikroC. For the 8 bit microcontrollers, CPHA modes are "high to low" and "low to high". These are NOT describing 0 and 1. Instead they are the same as "Active to Idle" and "Idle to Active".Sunday, November 29, 2015
Etching trials
Today I finally had time to do some photoresist developing and etching to try to figure out a sweet spot before doing all the vocoder cards.
I got some AA16 cards from C.I.F at Farnell and got to work.
After reading a lot about various methods, I landed on using Sodium Metasilicate as the developer. Incidently, I had some laying around. More specifically, I had a 25g sample of the Mega Electronics universal developer, but after reading the datasheet I figured it is what I wanted.
For etching I used "Etching power for PCBs" from Scan Kemi that I bought last time I did any cards. It seems it is mostly sodium peroxidisulfate (sodium persulfate).
I tried various exposure times as well as developer strengths and development time. Three of them failed and three were closer to success
The failed ones:
1) 2 minutes of exposure, developed in a 13g/2.5dl solution. This was not long enough, the developer had a hard time doing much at all.
2) 3 minutes of exposure, developed in a 25g/2.5dl solution. I left the card in the developer for three minutes. When etching, the resist floated away.
3) 4 minutes of exposure, developed in a 13g/2.5dl solution. Some of the traces were too thin and broke.
The better ones:
4) 3.5 minutes of exposure, developed in a 13g/2.5dl solution for 5 minutes. When etching some of the tracks got too thin and some were not etched enough
5) 3 minutes of exposure, developed in a 13g/2.5dl solution. The development time was a bit on the short side so some resist still stuck and was etched away later. The result was probably the best one of all the trials.
6) 3 minutes of exposure, developed in a 25g/3.5dl solution for 1m 30sec. The solution was a bit warm as the additional water was hot when added. This turned out almost as well as the previous one but with slightly thinner traces and one short circuit.
My conclusion is that 3 minutes of exposure seems perfect, and that I should probably retry the 13g/2.5dl developer solution but leave the cards in a little longer.
The etching times was around 10 minutes, depending on the heat of the water. I did the etching in a small plastic box in a bath of hot water which started out at 44 degrees celcius. The recommended temperature is 50 degrees.
I got some AA16 cards from C.I.F at Farnell and got to work.
After reading a lot about various methods, I landed on using Sodium Metasilicate as the developer. Incidently, I had some laying around. More specifically, I had a 25g sample of the Mega Electronics universal developer, but after reading the datasheet I figured it is what I wanted.
For etching I used "Etching power for PCBs" from Scan Kemi that I bought last time I did any cards. It seems it is mostly sodium peroxidisulfate (sodium persulfate).
I tried various exposure times as well as developer strengths and development time. Three of them failed and three were closer to success
The failed ones:
1) 2 minutes of exposure, developed in a 13g/2.5dl solution. This was not long enough, the developer had a hard time doing much at all.
2) 3 minutes of exposure, developed in a 25g/2.5dl solution. I left the card in the developer for three minutes. When etching, the resist floated away.
3) 4 minutes of exposure, developed in a 13g/2.5dl solution. Some of the traces were too thin and broke.
The better ones:
4) 3.5 minutes of exposure, developed in a 13g/2.5dl solution for 5 minutes. When etching some of the tracks got too thin and some were not etched enough
5) 3 minutes of exposure, developed in a 13g/2.5dl solution. The development time was a bit on the short side so some resist still stuck and was etched away later. The result was probably the best one of all the trials.
6) 3 minutes of exposure, developed in a 25g/3.5dl solution for 1m 30sec. The solution was a bit warm as the additional water was hot when added. This turned out almost as well as the previous one but with slightly thinner traces and one short circuit.
My conclusion is that 3 minutes of exposure seems perfect, and that I should probably retry the 13g/2.5dl developer solution but leave the cards in a little longer.
The etching times was around 10 minutes, depending on the heat of the water. I did the etching in a small plastic box in a bath of hot water which started out at 44 degrees celcius. The recommended temperature is 50 degrees.
Friday, November 20, 2015
Japanese transistors
I found this info in a forum, it clears up some of the confusion:
"Well,,, in Japan, "2SK30A" is a most common and very popular.
for low-frequency use, especially audio-use.
Its current part-number is 2SK30ATM. perfect substitute of "2SK30A"
TOSHIBA only carried out the minor change.
http://www.sm.rim.or.jp/~konton/Museum-7.htm
The minor change of "30A"was carried out in this way.
You'll notice the versions since 1970s.
Tons of data lists of Japanese transistor/FET also containing old things.
http://lobs.hp.infoseek.co.jp/data/data.html
The upper is bipolars, lower is FETs.
=====
2SK is J-FET or MOS-FET.
the digits following "2SK"shows original part-number for every manufucture.
=====
Japanese(or OEM) Bipolar-transisiter...
2SA PNP generally high-freq use, low-freq OK
2SB PNP low-freq
2SC NPN generally high-freq use, low-freq OK
2SD NPN low-freq
2SJ P-channel FETs (both JFETs and MOSFETs)
2SK N-channel FETs (both JFETs and MOSFETs)
=====
In the case of TOSHIBA,
The alphabet added to the end expresses an Idss ranking.
You can specify it certainly.
See PDF of 2SK30ATM...
R: 0.30-0.75,
O: 0.60-1.40,
Y: 1.20-3.00,
GR: 2.60-6.50 [mA]
Found here
"Well,,, in Japan, "2SK30A" is a most common and very popular.
for low-frequency use, especially audio-use.
Its current part-number is 2SK30ATM. perfect substitute of "2SK30A"
TOSHIBA only carried out the minor change.
http://www.sm.rim.or.jp/~konton/Museum-7.htm
The minor change of "30A"was carried out in this way.
You'll notice the versions since 1970s.
Tons of data lists of Japanese transistor/FET also containing old things.
http://lobs.hp.infoseek.co.jp/data/data.html
The upper is bipolars, lower is FETs.
=====
2SK is J-FET or MOS-FET.
the digits following "2SK"shows original part-number for every manufucture.
=====
Japanese(or OEM) Bipolar-transisiter...
2SA PNP generally high-freq use, low-freq OK
2SB PNP low-freq
2SC NPN generally high-freq use, low-freq OK
2SD NPN low-freq
2SJ P-channel FETs (both JFETs and MOSFETs)
2SK N-channel FETs (both JFETs and MOSFETs)
=====
In the case of TOSHIBA,
The alphabet added to the end expresses an Idss ranking.
You can specify it certainly.
See PDF of 2SK30ATM...
R: 0.30-0.75,
O: 0.60-1.40,
Y: 1.20-3.00,
GR: 2.60-6.50 [mA]
Found here
Thursday, November 19, 2015
Presensitized copper clad boards, where to find
What to search for to find photo sensitive copper clad boards for PCB production:
Ebay Presensitized copper/pcb/fr4
Mouser: Presensitized
Farnell: Presensitized
http://no.farnell.com/prototyping-boards
RS components: Photoresist
http://no.rs-online.com/web/c/pcb-prototyping/printed-circuit-boards-pcb/photoresist-boards/
Ebay Presensitized copper/pcb/fr4
Mouser: Presensitized
Farnell: Presensitized
http://no.farnell.com/prototyping-boards
RS components: Photoresist
http://no.rs-online.com/web/c/pcb-prototyping/printed-circuit-boards-pcb/photoresist-boards/
Monday, November 16, 2015
Dry film photo resist
I tried a new technique for making circuit boards yesterday - dry film photo resist.
I already own a (huge) UV-light box that I haven't used for a number of years. My previous UV experiments have all been under a large bulb, so I didn't what to expect.
The way the film works is this:
It has three layers. A bottom plastic layer that must be peeled away (this is on the inside of the curl when the plastic comes on a roll), a middle layer that will form the resist, and a top plastic layer that is peeled away once the film has been exposed.
The film is negative, meaning that any parts not covered by something when it is exposed to light will be "cured" and turn into resist. The remaining parts that were covered during exposure can be washed away during developing.
A friend of mine had already printed some templates on transparent plastic. Though they are meant for positive resist, they work well for the experiment. I put two copies of the same print on top of each other to better block the light.
Start off by sanding the copper clad board with a very fine sanding paper or a scotchbrite sponge to make stuff stick a bit better. Clean off with some alcohol or acetone or something similar to remove any grease.
To remove the bottom plastic, I used a trick I found here - put a bit of sticky tape on each side and rapidly rip the sides apart (it is important to do this quickly). I turned down the lights in the room while doing this, remember, you're working with photo sensitive film.
Then cover the copper side of the board with the film, protective plastic up.Try not to touch the film with your fingers to prevent greasing it up.
The film must be fastened to the board using an iron at a very low temperature (or the plastic will melt and warp) or idealy a laminator. I tried an iron with ok but not extremely great results.
Once the film sticks, put the transparent foil face down on the UV light box, put the board on top and something heavy like an old mathematics book on top of that to keep everything nice and flat.
I tried various exposure times from 2 to 6 minutes. 2 minutes turned out best, the others had cases of light leakage - ragged edges, thinner lines than on the foil etc. My UV light box has 10 powerful tubes and is very powerful so times will be different with other equipment.
After exposure I put the cards into what I think is a 1:100 mix of sodium carbonate and water (but I got it in the same package as the dry film from a vendor in china, so I'm not really sure). The development time was three minutes. After two minutes I started brushing the non-exposed parts with a coarse paint brush to rub off the film.
I haven't tried etching the boards yet so I don't know how well the film sticks. It looks and feels very sturdy though.
I already own a (huge) UV-light box that I haven't used for a number of years. My previous UV experiments have all been under a large bulb, so I didn't what to expect.
The way the film works is this:
It has three layers. A bottom plastic layer that must be peeled away (this is on the inside of the curl when the plastic comes on a roll), a middle layer that will form the resist, and a top plastic layer that is peeled away once the film has been exposed.
The film is negative, meaning that any parts not covered by something when it is exposed to light will be "cured" and turn into resist. The remaining parts that were covered during exposure can be washed away during developing.
A friend of mine had already printed some templates on transparent plastic. Though they are meant for positive resist, they work well for the experiment. I put two copies of the same print on top of each other to better block the light.
Start off by sanding the copper clad board with a very fine sanding paper or a scotchbrite sponge to make stuff stick a bit better. Clean off with some alcohol or acetone or something similar to remove any grease.
To remove the bottom plastic, I used a trick I found here - put a bit of sticky tape on each side and rapidly rip the sides apart (it is important to do this quickly). I turned down the lights in the room while doing this, remember, you're working with photo sensitive film.
Then cover the copper side of the board with the film, protective plastic up.Try not to touch the film with your fingers to prevent greasing it up.
The film must be fastened to the board using an iron at a very low temperature (or the plastic will melt and warp) or idealy a laminator. I tried an iron with ok but not extremely great results.
Once the film sticks, put the transparent foil face down on the UV light box, put the board on top and something heavy like an old mathematics book on top of that to keep everything nice and flat.
I tried various exposure times from 2 to 6 minutes. 2 minutes turned out best, the others had cases of light leakage - ragged edges, thinner lines than on the foil etc. My UV light box has 10 powerful tubes and is very powerful so times will be different with other equipment.
After exposure I put the cards into what I think is a 1:100 mix of sodium carbonate and water (but I got it in the same package as the dry film from a vendor in china, so I'm not really sure). The development time was three minutes. After two minutes I started brushing the non-exposed parts with a coarse paint brush to rub off the film.
I haven't tried etching the boards yet so I don't know how well the film sticks. It looks and feels very sturdy though.
Exposed for 4 minutes |
Thursday, September 10, 2015
Shift register led drivers
I've tried to do a little survey of viable solutions for the led dial. Preferably I'd like to not have any resistors or transistors on the lines connected to the LEDs as it s easier to solder one IC than several small smd parts, even if the cost would be quite a bit less with more parts.
The need for transistors is removed in two ways:
On the positive side of the diodes it is possible to use a line driver such as the uln2803 transistor array. This does however make a "local" solution where both positive and negative sides of the LED are controlled by a single shift register (see post earlier) impractical, but a single driver may power a whole bunch of diodes on several dials. The number of lines running between the dials will increase somewhat though.
On the negative side of the diode the transistor may be omitted if one uses an open drain led driver/shift register.
The resistors are still needed with the open drain version, but switching to a "constant current" led driver lets you control the current using a single, shared resistor that sets up a reference current.
I've done a little list of available 12bit and 16bit LED drivers. It is by no means exhaustive, but probably covers most of the common ones.
Open drain LED drivers
(low side, meaning they should be connected to the LEDs negative pole to sink current)
(low side, meaning they should be connected to the LEDs negative pole to sink current)
12 stage:
TLC6C5912
Hef4894b
Npic6c4894
Constant current
12 channel:
Max6979
Bd18377
16 channel:
Max6969
Max6971, high voltage
A6282
A6276 (obsolete)
Stp16c596
Dm133
Tlc59281x
Tlc59025
Cat4016
Tlc5927
Pca9952
Pca9955
24 channel:
Stp24dp05
So far the cheaper solution seems to be:
Tlc59281 - 16bit, 0.987€@100
These are normal shift registers often used for LED scanning in the DIY world. They are neither open drain nor constant current and just mentioned here to remember them:
74hc4094 (can this drive a led from its outputs? Some people seem to do it, letting it sink current without transistors).
74hc164
74hc595 in combination with the uln2803 (row scanner)
Monday, September 7, 2015
Prophet VS Keyboard controller PCBs v1.2 ordered
A batch of boards with the bugs from v1.1 fixed was just ordered from dirtypcbs. Fingers crossed they work this time!
Sunday, September 6, 2015
Pogo pins
Spring loaded pins, also known as pogo pins, spring loaded test pins etc, are a neat tool to keep pins pressed against a test point or interconnect point. I intend to use five of them for In Circuit Programming, removing the need for permanent ICP pins in my circuits.
While searching the web for such pins I realized brand name ones are insanely expensive. Ebay to the rescue! As often is, china products are available to fulfill your needs. I found that the most common ones are named P75-something. But what does this something after P75 mean?
I found this image, showing all variants. I went for the P75-B1 which has a very sharp tip perfect for holes in the PCB.
While searching the web for such pins I realized brand name ones are insanely expensive. Ebay to the rescue! As often is, china products are available to fulfill your needs. I found that the most common ones are named P75-something. But what does this something after P75 mean?
I found this image, showing all variants. I went for the P75-B1 which has a very sharp tip perfect for holes in the PCB.
Nailed it!
Finally got a stable, velocity sensitive version of the Prophet VS keyboard scanner working.
One last bug, double triggering of some notes took a long time an thorough research to figure out. I chose to quadruple the core speed from 16 to 64 MHz as some of the sends seemed to get delayed, possibly by the interrupt routines.
However, this sees to have triggered bouncing in the top switch readings. As a key start switch always leads to a note on event (through timeouts), this would lead to notes that never got turned off. Why? Because off is only sent when the start switch opens, and this has happened long before the timeout if the key isn't really pressed.
The solution is to check if the start switch is still on before sending a timeout (or possibly resetting hasSentNoteOn on start key opening).
The reason velocity didn't work straight away wasn't that hard to find. I have always only measured the most significant bits of the data transmission to be able to use two probes for kybd and kyint. When timing out, the velocity had all the 6 msbits set to 0 so I assumed velocity should be 0. Not so. 0 is always read as "no more data" by the main mcu, so the minimum velocity has to be 1!
One last bug, double triggering of some notes took a long time an thorough research to figure out. I chose to quadruple the core speed from 16 to 64 MHz as some of the sends seemed to get delayed, possibly by the interrupt routines.
However, this sees to have triggered bouncing in the top switch readings. As a key start switch always leads to a note on event (through timeouts), this would lead to notes that never got turned off. Why? Because off is only sent when the start switch opens, and this has happened long before the timeout if the key isn't really pressed.
The solution is to check if the start switch is still on before sending a timeout (or possibly resetting hasSentNoteOn on start key opening).
The reason velocity didn't work straight away wasn't that hard to find. I have always only measured the most significant bits of the data transmission to be able to use two probes for kybd and kyint. When timing out, the velocity had all the 6 msbits set to 0 so I assumed velocity should be 0. Not so. 0 is always read as "no more data" by the main mcu, so the minimum velocity has to be 1!
More Prophet VS Hardware issues.The
The VS I have been working on must have been used as a training kit for monkeys learning electronics. There are so many weird errors and botched jobs inside. After finishing the keyboard scanner, 8 keys (g#2 to d#2) still didn't work so I disassembled the keybed, initially leaving the pcb in place, to figure what was going on.
From the schematics it is clear that all these are connected to row 20 in the cable (I knew from earlier that it was the start key switch that was the problem, not the end).
I started by measuring between the diode kathode and pin 20 and got nothing. But the same was true for the working lines! Turns out there is an inaccuracy in the VS service manual - the diodes are before the key switches, not after, so it is the columns that are common to the diodes, not the rows.
Even if I tried pressing a key, my multimeter's connection checker didn't beep. I gave up and unscrewed the pcbs to get a closer look. It quickly became apparent where the error was. I also figured out why the connection checker didn't work: the switch pads have a tiny resistance. Also, I could see that both the top and bottom switches are in fact in the same place. Assumingly, the outer ring that makes the connection is pressed down slightly slanted, connecting two of the poles before the other two.
Scraping away a bit of solder mask from the broken trace enabled me to solder a new wire to bypass the fault. It worked straight away.
After (of course, after...) assembling the keyboard I heard and felt a clicking from one of the keys. I opened it up again and discovered a bent spring. How it is possible to bend this is beyond me, it was really hard bending it back. It only strengthens my monkey theory. Anyway, the synth is now fully operational and will be returned to a happy owner.
From the schematics it is clear that all these are connected to row 20 in the cable (I knew from earlier that it was the start key switch that was the problem, not the end).
I started by measuring between the diode kathode and pin 20 and got nothing. But the same was true for the working lines! Turns out there is an inaccuracy in the VS service manual - the diodes are before the key switches, not after, so it is the columns that are common to the diodes, not the rows.
Even if I tried pressing a key, my multimeter's connection checker didn't beep. I gave up and unscrewed the pcbs to get a closer look. It quickly became apparent where the error was. I also figured out why the connection checker didn't work: the switch pads have a tiny resistance. Also, I could see that both the top and bottom switches are in fact in the same place. Assumingly, the outer ring that makes the connection is pressed down slightly slanted, connecting two of the poles before the other two.
What happened here?! |
Scraping away a bit of solder mask from the broken trace enabled me to solder a new wire to bypass the fault. It worked straight away.
The bent spring in the middle black key |
The bent spring |
Tuesday, August 18, 2015
MPG-200 cards received
I got the MPG-200 PCBs from dirtyPCBs yesterday. They look very good. My little trick of panelizing four on a 10 x 8 cm card was accepted by the maker and it turned out like it should, which means I'll probably get 40 MPGs from this order. Next time I will put the holes closer to make the cards easier to break apart though, and maybe have fewer of them. These cards are still very well connected...
Thursday, August 13, 2015
Pic 18f gotchas: interrupts on portb change
I have constructed the 68b01 clone to use interrupts to detect when the main controller has read the output data. To do this I detect when pin 7 on portb changes. Changes on pin 4-7 on portb can generate an interrupt, PBIF whenever the input changes.
GIE = 1; // global interrupts enable
PBIE = 1; // portb change interrupt enable
IOCB7 = 1; // only pin 7 should trigger interrupt
IOCB6 = 0;
IOCB5 = 0;
IOCB4 = 0;
PBIF = 0; // reset any portb interrupt
While I got the interrupt working, clearing it would not work properly, the interrupt just refired instantly.
A little googling found me application note AN566 from microchip which solved the mystery: after the interrupt has been triggered, portb must be read to reset the mismatch state.
It may be possible to read the values into any variable, I haven't tried this yet. The solution used in the AN is a single assembly statement that reads portb onto itself:
MOVF PORTB, 1
After this, everything works as expected.
NB: the pic18F's (some of them at least) have one or more external interrups, on portb 0-3 on the 18F46k80 for example. It is better to use these if you only need to check that an interrupt has occurred. The external interrups are edge triggered, so they will only trigger on EITHER the rising OR the falling edge. Portb change interrups trigger on both.
Monday, August 3, 2015
Led indicator ring driver
I intend to have rings of LEDs around the potentiometers on my synth to show the current value of the parameter, and have been thinking about ways of doing it. One can take the normal approach and do a full matrix that runs through all the pots and have a single controlling circuit, but that requires a lot of data lines running across the PCB. Another option is to use a 16bit shift register per dial and connect each led to a pin, which reduces the number of lines necessary to six - two power lines, serial in-out and clock, latch.
I have been considering having even more LEDs per dial. For 32 LEDs this last method requires either two 16bit or one 32bit shift register, and things start being costly and take up a lot of board space.
Thus, a combination may be a good solution. If one uses a 12bit shift register, one can control 6 rows x 6 columns for a total of 36 diodes, while still only using 6 transmission lines (16 diodes may be controlled by a 4x4 matrix, requiring an 8 bit register only). It means you have to do row scanning instead of just updating the shift registers whenever the dials change, so there are pros and cons of each method. The scanning requires more (but cheaper) components - transistors and resistors. It also requires a more complex controlling algorithm which takes up time in the microcontroller, and ultimately the number of controllable LEDs and the refresh ratio is limited by the time it takes to fill the shift registers.
A possible circuit may look like this:
The shift register must be able to sink around 20mA per pin which means a normal CMOS chip won't do. A constant current sink led driver will be a good option, it may even do away with the resistors in the schematic.
I've found 16bit led driver shift registers at prices of just above $1in quantities of 50, for example the STP16CPC26 at mouser.com.
PS: a 32 LED dial may be controlled from a 12 bit shift register using 8 bits for rows and only 4 for columns. This reduces the necessary transistors from 6 to 4.
I have been considering having even more LEDs per dial. For 32 LEDs this last method requires either two 16bit or one 32bit shift register, and things start being costly and take up a lot of board space.
Thus, a combination may be a good solution. If one uses a 12bit shift register, one can control 6 rows x 6 columns for a total of 36 diodes, while still only using 6 transmission lines (16 diodes may be controlled by a 4x4 matrix, requiring an 8 bit register only). It means you have to do row scanning instead of just updating the shift registers whenever the dials change, so there are pros and cons of each method. The scanning requires more (but cheaper) components - transistors and resistors. It also requires a more complex controlling algorithm which takes up time in the microcontroller, and ultimately the number of controllable LEDs and the refresh ratio is limited by the time it takes to fill the shift registers.
A possible circuit may look like this:
The shift register must be able to sink around 20mA per pin which means a normal CMOS chip won't do. A constant current sink led driver will be a good option, it may even do away with the resistors in the schematic.
I've found 16bit led driver shift registers at prices of just above $1in quantities of 50, for example the STP16CPC26 at mouser.com.
PS: a 32 LED dial may be controlled from a 12 bit shift register using 8 bits for rows and only 4 for columns. This reduces the necessary transistors from 6 to 4.
68b01 boards arrived
The 68b01 clone is close to completion. The v1.1 boards arrived while I was away - they actually arrived before the 1.0 boards as I got bumped to a faster production board by oshpark.
Oh, and I just realised that the VDDCORE line of the PIC18F46K80 must have a 10uF ceramic cap to ground (an electrolytic one has been used in the photo above as I thought it could be the source of some of my problems - turned out I had a spelling error in my code. I meant to write ANCON1 and wrote ADCON1. Since both exist the compiler didn't give me any errors).
The reason I did a revision so soon was that I discovered that in order to use interrupts for the kybd line, it had to be part of portb. Unfortunately, while rushing to fix this before going on holidays, I forgot to read the data sheet properly. I have used porta for top switch scanning, but on this particular mcu (the pic18f46k80), only 7 of the 8 pins on porta are available. Worse, the remaining pin is used as a power output pin, which led to some surprises when connecting it to ground. I cannot easily change the chip either, as it is the only 44qfp chip to accept 5v power and have 5v data lines.
In addition to this I somehow forgot to move the pgc and pgd lines. They are now connected to some of the bottom switch data lines instead, which is of course no good.
On top of this, when I sat down to solder everything, I could not find the proper pin strips and had to make a Frankenstein solution out of sockets and male header pins, and didn't solder some of the pins properly. As a result I spent a lot of time trying to figure out why things didn't work properly.
A lot of rookie mistakes, but I guess that's to be expected when the time available to development are the minutes in between diaper changes, bottle feeding and singing lullabies ;-)
Oh, and I just realised that the VDDCORE line of the PIC18F46K80 must have a 10uF ceramic cap to ground (an electrolytic one has been used in the photo above as I thought it could be the source of some of my problems - turned out I had a spelling error in my code. I meant to write ANCON1 and wrote ADCON1. Since both exist the compiler didn't give me any errors).
I may finally get to try the chip tonight - fingers crossed!
Saturday, July 25, 2015
MPG-200 PCBs ordered from DirtyPCBs
I ordered what is hopefully the final version of the MPG-200 cards from DirtyPCBs last night. If all things go to plan I will get approximately 40 boards somewhere next month. Exciting!
Tuesday, July 21, 2015
WebMIDI and the MPG-200
A couple of days ago I put the final touches on a settings editor that can generate sysex for changing the MPG-200 internal settings like CC mappings and midi channel etc.
I wrote everything using javascript and HTML, and initially made it generate a sysex file that you could download and send using your favourite tool.
As an experiment, I thought I'd make it possible to send the data directly to the device using the newly available WebMIDI standard. I had a few issues but now it seems to work nicely.
I have been using Google Chrome to do the development, and there are a few things to be aware of:
1) In WebMIDI you have to ask the user for access to sysex messages. In Chrome, this cannot be done if the javascript file is accessed as a local file or from a local html file (file://...). Neither can it be accessed through an insecure connection (I assume this means you have to use HTTPS).
To get around this, I installed a tiny webserver (The TinyWeb actually) locally and ran the code through it. Works like a charm.
2) You have to send the complete sysex message in one go - it must start with F0 and end with F7. You cannot send the messages in blocks so the message has to be calculated up front.
3) Running status is not allowed, as with the sysex message each message has to be self contained and complete.
The sysex editor and my WebMIDI code is found on the Xonik webside, but as I said, you cannot use the WebMIDI part directly as it is not served over HTTPS.
I wrote everything using javascript and HTML, and initially made it generate a sysex file that you could download and send using your favourite tool.
As an experiment, I thought I'd make it possible to send the data directly to the device using the newly available WebMIDI standard. I had a few issues but now it seems to work nicely.
I have been using Google Chrome to do the development, and there are a few things to be aware of:
1) In WebMIDI you have to ask the user for access to sysex messages. In Chrome, this cannot be done if the javascript file is accessed as a local file or from a local html file (file://...). Neither can it be accessed through an insecure connection (I assume this means you have to use HTTPS).
To get around this, I installed a tiny webserver (The TinyWeb actually) locally and ran the code through it. Works like a charm.
2) You have to send the complete sysex message in one go - it must start with F0 and end with F7. You cannot send the messages in blocks so the message has to be calculated up front.
3) Running status is not allowed, as with the sysex message each message has to be self contained and complete.
The sysex editor and my WebMIDI code is found on the Xonik webside, but as I said, you cannot use the WebMIDI part directly as it is not served over HTTPS.
MPG-200 final hw version finished
Just finished what I hope will be the final version of the MPG-200 hardware, correcting the small mistakes with the previous verson. Will probably order a batch from dirtypcbs soon.
Friday, July 10, 2015
Decoding the 68b01 keyboard scanner
Returning to the Prophet VS service manual, I noticed that the output bus from the keyboard scanner runs through a set of latches. This means that bus communication is one way only. In addition to the bus, the only pins connecting the scanner to the main MCU are the KYBD and KYINT lines. Thus, the communication protocol should be fairly simple.
I connected logic probes to various parts of the 68B01 and its surrounding components. First to the CD4022 octal counter to see how the keyboard lines are scanned. Then to the rows to see which ones are connected to the first and second set of keys. I registered the data on the output bus while pressing keys to understand the protocol. I also checked the KYBD and KYINT lines while monitoring the data bus to see how the MCUs interacted.
The velocity was a bit trickier to get right. I needed to know the interval between hitting the first key and the second key, and at the same time registering the data bus output. I only have 8 probes on my logic decoder, but luckily, the velocity is 7 bit only, and by ignoring the least significant bit I could still get quite accurate velocity measurements.
What I found was that certain number of rounds of scanning the keys in between first and second keys made contact corresponded to a certain velocity. In other words, there is no 'free running' counter used for calculating velocity, one only needs to know how many times the keys have been scanned. This makes sense, as the only legal intervals corresponds to the times the keys are scanned.
I got a nice surprise when I made a plot of the velocity versus the scan cycle count. It turns out the velocity is a faux exponential curve, much like the way an analog audio-scale potentiometer works. For the first quarter of the measured cycles the velocity follows a steep line. For the other three quarters it follows a much flatter line. This, of course, makes calculating the velocity much easier (without the use of a lookup table. In that case any curve would be equally simple).
(Disclaimer: The lines measured are not perfectly flat even if I try correcting for a +/- 1 error. This means that there is actually some kind of timer involved that is not connected directly to the keyscanner cycles. However, when recreating the program it will be sufficient to count cycles as long as cycle lengths are constant)
Here are some details about the scanner:
The keys are scanned column-by-column. The first column is turned on for about 70uS, the rest for 52uS. The total period (time between successive scans of the same column) is 432uS, giving a scan frequency of about 2.3kHz.
The columns are scanned by clocking a CD4022 octal counter. Each clock pulse is approximately 2.5uS wide. The carry out from the CD4022 alternates between 0 and 1 every four clock pulses.
Data transfer works like this:
When the scanner has something to send, it lowers the KYINT line. At the same time, it puts the data on the output bus. Approximately 10uS later, the main MCU lowers the KYBD line. This turns on the 74HC367 transparent latches and puts the data on the databus, and at the same time signals to the scanner that it is reading data. KYBD stays low for about 0.25uS. The scanner waits an additional 10uS and then puts the next data byte on the output bus. The main MCU seems to read the data bus until it gets a 0 (0 on the bus is not a valid note on or velocity).
The data format is equally simple:
Note on is sent as two bytes: Note and Velocity
Note off is sent as a single byte: Note.
Both note and velocity are seven bit values. To differenciate between Note on and off, the MSB is always 1 for note on and 0 for note off. MSB is always 0 for velocities.
The lowest key on the keyboard, C0, is sent as x0100100 (x being 1 or 0 depending on note on/off), so the note value to send is simply 36 + key number.
Velocities:
Time t from key is pressed until it reaches bottom is x * 432uS + 571uS, where x is the number of times the first switch is scanned before it reaches bottom.
An approximation to the velocity transfer curve is as follows (not rounded):
[0, 1]: y = 127
[2,19]: y = 124 + (1867uS - t) / 80
[20,69]: y = 38 + (8779uS - t) / 570
[70, ->: y = 0
If more than 70 scan cycles are reached without the key hitting the bottom, a note on with velocity 0 is sent (and a note off is sent when the key is released later).
where
x = number of key scan cycles
y = velocity sent to master
This will of course not be an easily calculateable curve, so one is better off using a lookup table.
Important I/O pins:
Pins 13-20 corresponds to row 0-7 of the key press start switches
Pins 37-30 corresponds to row 0-7 of the key at bottom switches (NB: reverse order!)
Pins 22-29 are the output data bus pins
Pin 8 is clocking the CD4022 column selector
Pin 9 reads the carry bit from the CD4022
Pin 12 is the KYINT bit that must be set low before data transfer
Pin 39 is the KYBD bit that can be used to detect that the master reads the data.
I connected logic probes to various parts of the 68B01 and its surrounding components. First to the CD4022 octal counter to see how the keyboard lines are scanned. Then to the rows to see which ones are connected to the first and second set of keys. I registered the data on the output bus while pressing keys to understand the protocol. I also checked the KYBD and KYINT lines while monitoring the data bus to see how the MCUs interacted.
The velocity was a bit trickier to get right. I needed to know the interval between hitting the first key and the second key, and at the same time registering the data bus output. I only have 8 probes on my logic decoder, but luckily, the velocity is 7 bit only, and by ignoring the least significant bit I could still get quite accurate velocity measurements.
What I found was that certain number of rounds of scanning the keys in between first and second keys made contact corresponded to a certain velocity. In other words, there is no 'free running' counter used for calculating velocity, one only needs to know how many times the keys have been scanned. This makes sense, as the only legal intervals corresponds to the times the keys are scanned.
I got a nice surprise when I made a plot of the velocity versus the scan cycle count. It turns out the velocity is a faux exponential curve, much like the way an analog audio-scale potentiometer works. For the first quarter of the measured cycles the velocity follows a steep line. For the other three quarters it follows a much flatter line. This, of course, makes calculating the velocity much easier (without the use of a lookup table. In that case any curve would be equally simple).
Plot of cycles vs velocity |
(Disclaimer: The lines measured are not perfectly flat even if I try correcting for a +/- 1 error. This means that there is actually some kind of timer involved that is not connected directly to the keyscanner cycles. However, when recreating the program it will be sufficient to count cycles as long as cycle lengths are constant)
Here are some details about the scanner:
The keys are scanned column-by-column. The first column is turned on for about 70uS, the rest for 52uS. The total period (time between successive scans of the same column) is 432uS, giving a scan frequency of about 2.3kHz.
The three first columns and their scan pulses |
Data transfer works like this:
When the scanner has something to send, it lowers the KYINT line. At the same time, it puts the data on the output bus. Approximately 10uS later, the main MCU lowers the KYBD line. This turns on the 74HC367 transparent latches and puts the data on the databus, and at the same time signals to the scanner that it is reading data. KYBD stays low for about 0.25uS. The scanner waits an additional 10uS and then puts the next data byte on the output bus. The main MCU seems to read the data bus until it gets a 0 (0 on the bus is not a valid note on or velocity).
The data format is equally simple:
Note on is sent as two bytes: Note and Velocity
Note off is sent as a single byte: Note.
Both note and velocity are seven bit values. To differenciate between Note on and off, the MSB is always 1 for note on and 0 for note off. MSB is always 0 for velocities.
The lowest key on the keyboard, C0, is sent as x0100100 (x being 1 or 0 depending on note on/off), so the note value to send is simply 36 + key number.
Velocities:
Time t from key is pressed until it reaches bottom is x * 432uS + 571uS, where x is the number of times the first switch is scanned before it reaches bottom.
An approximation to the velocity transfer curve is as follows (not rounded):
[0, 1]: y = 127
[2,19]: y = 124 + (1867uS - t) / 80
[20,69]: y = 38 + (8779uS - t) / 570
[70, ->: y = 0
If more than 70 scan cycles are reached without the key hitting the bottom, a note on with velocity 0 is sent (and a note off is sent when the key is released later).
where
x = number of key scan cycles
y = velocity sent to master
This will of course not be an easily calculateable curve, so one is better off using a lookup table.
Important I/O pins:
Pins 13-20 corresponds to row 0-7 of the key press start switches
Pins 37-30 corresponds to row 0-7 of the key at bottom switches (NB: reverse order!)
Pins 22-29 are the output data bus pins
Pin 8 is clocking the CD4022 column selector
Pin 9 reads the carry bit from the CD4022
Pin 12 is the KYINT bit that must be set low before data transfer
Pin 39 is the KYBD bit that can be used to detect that the master reads the data.
Please don't butcher your synths!
A friend of mine recently brought me a Prophet VS he bought some time ago. The synth had some serious issues - while it worked perfectly over MIDI, 24 of the keys on the keyboard did not work as they should. 16 of the keys did not work at all, while 8 worked but always triggered the notes at maximum velocity. He considered selling the synth, but I was intrigued by the problem and asked him to wait for a while so I could look into the problem.
After consulting the service manual, I quickly realised that the keys in question were connected to three row-input lines of the keyboard scanning circuit. This got my hopes up, as it could simply be a matter of a few corroded or short circuited data lines.
I opened up the synth and within seconds came to the conclusion that it had to be something way more serious. Someone had, quite visibly, tried to fix this synth before. Aside from the fact that most of the screws holding the lid were missing, there were a few modifications, repair jobs and even a custom replacement for one of the CEM5580 sample and hold chips. Not a problem in itself, but surely a sign that this synth was in need of some love and care.
The biggest shock came when looking at the keyboard scanner chip. This chip, a Sequential Circuits 68B01, is a rebranded (or cloned) motorola 6801 microcontroller. Take a look at the pictures below:
Someone has cut deep grooves into the packaging and soldered new pins to the exposed internal connectors! I can only guess why - perhaps they cut the legs to get the chip loose from a PCB instead of trying to desolder it, or maybe one or more of the legs broke and they had to dig into the chip to reattach it. Whatever the reason, the person doing this must either have been well informed and highly competent, extremely brave or just desperate. The 68b01 is a very rare chip, and replacing it with a off-the-shelf 6801 will not work as it contains custom firmware. I guess if I owned this synth and the chip died, I could have tried something similar, after all you have little to lose if it does not work in the first place.
The chip even had a small wire connecting the first and second key switches for one of the rows. Now, the first switch detects when the key leaves the top position and the second when it reaches the bottom. The time between is used to calculate velocity. When they are connected, the effect will be that the synth thinks the key instantly hits the bottom position. This explains why 8 of the keys only played at maximum volume.
I tried resoldering the pins and even removing the wire, but this did not help. The chip is defective.
Luckily it seemed that the only defective parts are the row inputs. The chip still sends keypresses for most of the keys, which means it would be possible to decode the protocol. This lead to the only sane conclusion - I had to create a custom drop-in replacement. Challenge accepted!
After consulting the service manual, I quickly realised that the keys in question were connected to three row-input lines of the keyboard scanning circuit. This got my hopes up, as it could simply be a matter of a few corroded or short circuited data lines.
I opened up the synth and within seconds came to the conclusion that it had to be something way more serious. Someone had, quite visibly, tried to fix this synth before. Aside from the fact that most of the screws holding the lid were missing, there were a few modifications, repair jobs and even a custom replacement for one of the CEM5580 sample and hold chips. Not a problem in itself, but surely a sign that this synth was in need of some love and care.
This is probably a factory fix but still looks funny |
This could also be a factory fix, but the left resistors look horrible |
Someone has smudged the print on this SaH chip. Maybe we could do a finger print analysis? |
One of the CEM5510s has been replaced with a cool looking mod. |
The biggest shock came when looking at the keyboard scanner chip. This chip, a Sequential Circuits 68B01, is a rebranded (or cloned) motorola 6801 microcontroller. Take a look at the pictures below:
Someone has cut deep grooves into the packaging and soldered new pins to the exposed internal connectors! I can only guess why - perhaps they cut the legs to get the chip loose from a PCB instead of trying to desolder it, or maybe one or more of the legs broke and they had to dig into the chip to reattach it. Whatever the reason, the person doing this must either have been well informed and highly competent, extremely brave or just desperate. The 68b01 is a very rare chip, and replacing it with a off-the-shelf 6801 will not work as it contains custom firmware. I guess if I owned this synth and the chip died, I could have tried something similar, after all you have little to lose if it does not work in the first place.
The chip even had a small wire connecting the first and second key switches for one of the rows. Now, the first switch detects when the key leaves the top position and the second when it reaches the bottom. The time between is used to calculate velocity. When they are connected, the effect will be that the synth thinks the key instantly hits the bottom position. This explains why 8 of the keys only played at maximum volume.
I tried resoldering the pins and even removing the wire, but this did not help. The chip is defective.
Luckily it seemed that the only defective parts are the row inputs. The chip still sends keypresses for most of the keys, which means it would be possible to decode the protocol. This lead to the only sane conclusion - I had to create a custom drop-in replacement. Challenge accepted!
Tuesday, June 16, 2015
Exponential curve using lookup table
It has been a while since my last update. My daughter arrived on Norway's national day, the 17th of May. It's so incredibly nice and I am the proudest dad ever! It does take the focus away from other things though :-)
Just before she arrived, I bought a book from 1980, musical applications of microprocessors. It may sound outdated but in fact is a treasure - it explains lots about sound theory, filters, DAC and ADC etc.
Today I am reading about generating waveforms digitally. Since the book is from 1980, the available computers were incredibly slow, worse than many of today's microcontrollers. This is a plus, since it means it explains a lot of neat tricks to make things run faster.
For example, it shows how to generate a sine wave using a small lookup table and doing linear interpolation between the points (p. 388). If certain criteria are met, the task only requires two subtractions, an addition and one multiplication.
In the OMM, I intend to do linear to exponential conversion using a lookup table. With 16bit values this would require 128kB for a full table. This can be reduced dramatically if I accept a little inaccuracy and use the same interpolation. As long as the result is not used for controlling the frequency of a vco, it should not be much of a problem
Saving space would also allow me to implement for example both 50dB and 70dB curves etc.
Just before she arrived, I bought a book from 1980, musical applications of microprocessors. It may sound outdated but in fact is a treasure - it explains lots about sound theory, filters, DAC and ADC etc.
Today I am reading about generating waveforms digitally. Since the book is from 1980, the available computers were incredibly slow, worse than many of today's microcontrollers. This is a plus, since it means it explains a lot of neat tricks to make things run faster.
For example, it shows how to generate a sine wave using a small lookup table and doing linear interpolation between the points (p. 388). If certain criteria are met, the task only requires two subtractions, an addition and one multiplication.
In the OMM, I intend to do linear to exponential conversion using a lookup table. With 16bit values this would require 128kB for a full table. This can be reduced dramatically if I accept a little inaccuracy and use the same interpolation. As long as the result is not used for controlling the frequency of a vco, it should not be much of a problem
Saving space would also allow me to implement for example both 50dB and 70dB curves etc.
Monday, May 25, 2015
Free the PG-200!
Around three years ago, in april 2012, I decoded the PG-200 protocol. Using a Saleae logic probe I took a closer look at what happened while using the PG-200, and built a device that converts MIDI CC messages into PG-200 commands. This device, the MPG-200, also receives and transmits MIDI note messages, making it possible to completely control the JX-3P using MIDI.
To my knowledge, at the time I started the project only two other devices existed that could do this - the KiwiTechnics JX-3P upgrade and Patch Editor and the Organix Midi upgrade kit. These both require extensive modification of the JX-3P. Later, Mode machines made a PG-200 clone called the DT-200. I have yet to see the PG-200 protocol fully documented anywhere, but I may have missed something as I have not searched the web lately.
As a tiny gift to the synth community in honor of my daughter's birth, I now release all the information I have gathered. This document is based on the data found in the JX-3P/PG-200 service manual as well as a lot of work done by myself. Feel free to use it in any way you see fit, but I would be really happy if you acknowledged my contribution.
The complete protocol description can be found at http://www.xonik.no/mpg-200/pg-200/pg-200.html
Friday, May 15, 2015
Mmmmyeah... just one more bug.
I found the bug today. It wasn't the software - it is hardware related.
I have connected pin 2 of the midi connector to the PIC's MCLR. For some reason, when several midi messages arrive rapidly, the processor reboots. I assume it's induced noise on the line as I don't think the little phatty outputs anything on pin 2 (and it doesn't happen when just one or two messages arrive).
Fortunately, I foresaw that it could be a problem and added a solder blob jumper. After removing this the mpg-200 works as it should (but it cannot be programmed of course).
I have added a temporary normal jumper, so now things work again. I can just remove this jumper before shipping.
Btw: the midi connector didn't fit so i had to remove some of the copper and drill a new hole for the shield connector. Rookie mistake...
I have connected pin 2 of the midi connector to the PIC's MCLR. For some reason, when several midi messages arrive rapidly, the processor reboots. I assume it's induced noise on the line as I don't think the little phatty outputs anything on pin 2 (and it doesn't happen when just one or two messages arrive).
Fortunately, I foresaw that it could be a problem and added a solder blob jumper. After removing this the mpg-200 works as it should (but it cannot be programmed of course).
I have added a temporary normal jumper, so now things work again. I can just remove this jumper before shipping.
Btw: the midi connector didn't fit so i had to remove some of the copper and drill a new hole for the shield connector. Rookie mistake...
Thursday, May 14, 2015
Mpg-200 hardware verified
After some initial trouble - the pic18f25k50 has analog inputs on all ports that has to be turned off - I got the mpg-200 up and running. Receiving and transmitting midi works, but something is wrong with the software. Even so, it's great that the hardware is working as it should. The same hw will be used for other projects too.
Saturday, May 9, 2015
MPG-200 programming through midi cable
I soldered together the first MPG-200 today. I've made a few mistakes - my midi connector does not perfectly fit the board, and the electrolytic caps and transistors would have liked a little more space, but nothing serious.
I have yet to try it out as the mpg-200 firmware has to be adapted to the PIC18F25K50, but I got the programmer working. I've chosen to run the programmer pins, five in total, through the midi connector. The wiring is as follows:
Pin 1: 5V
Pin 2: MCLR
Pin 3: PGClock
Pin 4: PGData
Shield: GND
Now, I do not usually want the shield to be connected to GND, so I've added a jumper that must be removed after programming. Pins 1,2 and 3 are not normally used by midi so those are hardwired, but I've added solder-blob jumpers that can be removed should you use any equipment that use these lines for something else.
Pin 4 is normally midi in, but as long as I have not added the input optoisolator it can be used by the programmer as well.
I have yet to try it out as the mpg-200 firmware has to be adapted to the PIC18F25K50, but I got the programmer working. I've chosen to run the programmer pins, five in total, through the midi connector. The wiring is as follows:
Pin 1: 5V
Pin 2: MCLR
Pin 3: PGClock
Pin 4: PGData
Shield: GND
Now, I do not usually want the shield to be connected to GND, so I've added a jumper that must be removed after programming. Pins 1,2 and 3 are not normally used by midi so those are hardwired, but I've added solder-blob jumpers that can be removed should you use any equipment that use these lines for something else.
Pin 4 is normally midi in, but as long as I have not added the input optoisolator it can be used by the programmer as well.
The Mikroelektronika mikroProg connected to the MPG-200 through a custom cable |
Saturday, May 2, 2015
Time to update my knowledge, paper style
I ordered the "Circuit Designer's Companion" yesterday. Hopefully it will answer all my questions ;-) Bwack suggested it after I pondered him with questions about ground/earth connections etc.
From the list of "others who bought this also bought" I recon it will suit me very well - the main suggestions seemed to be "Practical electronics for inventors" which I bought in Singapore in 2007 and "The art of electronics" that I bought a couple of years ago on Ebay (hot tip: you can get an "asian only" copy from India at half price if you're lucky).
From the list of "others who bought this also bought" I recon it will suit me very well - the main suggestions seemed to be "Practical electronics for inventors" which I bought in Singapore in 2007 and "The art of electronics" that I bought a couple of years ago on Ebay (hot tip: you can get an "asian only" copy from India at half price if you're lucky).
DAC board soldered too
I finished something else yesterday - the DAC board prototype. My first real 0.5mm pitch soldering job. I think it turned out alright, I did as bwack suggested and tilted the card under the microscope. It looks good to me.
I can't test it with the sample and hold circuit just yet as I have no angled connectors for some reason. I may try just the DAC tomorrow though.
The DAC is an AD5547 dual output parallell input 16 bit device. There are two reasons I selected this. First of all, I selected the parallell version as I thought maybe I could load it faster than if I went for the SPI version. Second, I was not sure if I could load 32 sample and holds fast enough with only one DAC, this allows me to load two at the time before clocking the result into the sample and hold. The dual version costs significantly more than a single one though, so hopefully I'll get away with one channel. The sample and hold card lets me select which channel I want to use for output 17-32, so I can test both single and dual channel versions.
I can't test it with the sample and hold circuit just yet as I have no angled connectors for some reason. I may try just the DAC tomorrow though.
The DAC is an AD5547 dual output parallell input 16 bit device. There are two reasons I selected this. First of all, I selected the parallell version as I thought maybe I could load it faster than if I went for the SPI version. Second, I was not sure if I could load 32 sample and holds fast enough with only one DAC, this allows me to load two at the time before clocking the result into the sample and hold. The dual version costs significantly more than a single one though, so hopefully I'll get away with one channel. The sample and hold card lets me select which channel I want to use for output 17-32, so I can test both single and dual channel versions.
The DAC chip with its tiny legs. My index finger for measure. |
Through the microscope. Before cleaning away the flux obviously |
I had to add this as well, I am really impressed with the quality of the OSH park silk screen! Look at those sharp lines (this is at 80x magnification I think) |
The DAC and sample and hold together but not connected. The large white header is for analog power, digital power comes thru the 36 pin connector to the left. |
PSU finished!
Tonight I finished something for a change. The dual transformer, triple voltage PSU is safely enclosed in a box, transforming away. The output voltages are only as good as my cheap multimeter of course, but I had no problem dialing in +/- 15V and 5 or 9V. For the moment I've set the output of the "digital" PSU at 9V as this is what the EasyPIC Fusion 7 wants.
the digital and analog PSU's grounds meet at a star grounding point. This point is in turn connected to the "chassis ground"/earth via a 100nF/50V capacitor as suggested by bwack. In addition, I have exposed earth on top of the PSU to be able to clip on my ESD wrist band.
the digital and analog PSU's grounds meet at a star grounding point. This point is in turn connected to the "chassis ground"/earth via a 100nF/50V capacitor as suggested by bwack. In addition, I have exposed earth on top of the PSU to be able to clip on my ESD wrist band.
The DGND and AGND meet at a star point which is also connected to Earth via a 100nF cap (inside the shrink tube) |
Earth is also connected to a point outside the box where I can attach my ESD wrist band |
The box |
Subscribe to:
Posts (Atom)