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!
Subscribe to:
Posts (Atom)