Posts tonen met het label PIC16F690. Alle posts tonen
Posts tonen met het label PIC16F690. Alle posts tonen

woensdag 13 december 2023

PICmicro PWM VCO

Many of the 8-bit PICmicro microcontrollers have a PWM built in, which usually is used to do D/A conversion by changing the pulse width and adding a low pass filter (see other posts on this blog). I was curious whether instead of doing this, it might be possible to use the actual PWM output as the waveform, turning this into a VCO.

I used the 16F690, mostly because I am familiar with it and because I have a number of them in a drawer. It has analog inputs that can be used to convert the input voltage, and a single PWM. To get the PWM frequencies in the audible range I changed the clock frequency of the microcontroller to 125 kHz. Fortunately this is easy. I then computed which notes it could play, from C1 to D#6 and determined the appropriate values. I decided that I'd accept an input voltage from 0V for C1 to 5.33V for D#6. Since the PICmicro can only accept voltages up to 5V this meant I had to have a voltage divider. I decided to use two OPAMP for this: one that allowed adding and subtracting -6V to 6V to the input voltage, and the other to divide the voltage and invert it back to the normal range. This worked fine.

For the PWM input I used a default of 5V which was fed through an attenuator, so if the cable is not plugged in it had a range from 0-5V, and if the cable was plugged in the incoming voltage could be attentuated. That was fed to the second analog channel. Since the PWM range changes with each note I had to build a clever piece of code that checked each bit of the incoming data and add various divisions of the maximum range.

Finally, since the output only moves between 0V and 5V, I added a transistor inverter with CV input, so I got a free VCA. The output of this I pushed through a high pass filter to remove the DC component and will be multiplying by two so I get 10 Vpp (I didn't make this currently, but it just means adding two 47k resistors to the OPAMP). I will add schematics later, but I wanted to at least publish the current source code.

I needed to use assembly because at 125 kHz the processor is quite slow, and I do need to do the A/D conversion and output fast enough to not have issues with latency between notes.



vrijdag 13 oktober 2023

PS/2 MIDI Eurorack module edition

 

I made a Eurorack version of the PS/2 MIDI project I did a while ago. It features a PS/2 input (which can accept USB keyboards that comply with the PS/2 protocol as well, which my most recent mechanical keyboard does), a MIDI output (now with 5 channels: 1 direct play, 3 recorded and 1 for drums), a 1v/oct output of the main notes and a gate belonging to that 1v/oct. There is also an LED that will show that the gate output works when there is no plug in the jack (this is done to prevent unnecessary energy use by the LED, given that my own power supplies can only supply 300 mA).

The source code is available, and I will try to keep it updated with future improvements. The source code can run both on a 20 MHz PIC16F690 or a 8 MHz one, depending on the presence of the MODULE definition.

F1-F4 can be used to record the different tracks. It can play 4 different drum sounds at the same time, each with a selection of 3 different drums for a total of 12 options. A future module will expose the recorded channels as 1v/oct as well.

Originally I used a Sallen-Key filter for the PWM, but it turned out this created some spiky behavior that especially my Chipz module didn't like on the input, so I switched it to a plain two pole low pass filter.

This is the first module for which I made by own panel out of aluminum, which was an exciting and slightly scary thing to do, involving sawing, drilling, dremeling, sanding and painting. The painting was the biggest struggle, as you can see the bottom part has a slightly different hue.

zondag 1 oktober 2023

PS/2 Keyboard Output (sending data to a keyboard)

As you have seen on this blog I have made multiple implementations that allow reading data from a PS/2 keyboard. However, in order to control the LED you have to also be able to write to the keyboard. This is far trickier than it seems, and the documentation on the Internet is limited. Basically the best document is only available using the wayback machine. There is also a working piece of code for the Arduino which isn't pretty and uses interrupts, which can be something people would shy away from (although I might try to implement a version with it).

The most important aspect is the timing schedule. There are many diagrams on the Internet, and most of them are wrong. This is the correct diagram, made by Craig Peacock and copied from the above linked website.


And here is a simplified C code implementation for PicMicro processors (suspendKeyboard() will take the clock line and move it to 0, resumeKeyboard() will release the clock line, keyboardClockHigh() waits for the clock line to go high, keyboardClockLow() waits for the clock line to go low, RB4 is considered to be the data line):

void sendKeyboard(unsigned char value, unsigned char parity) {
    suspendKeyboard();
    __delay_us(60);
    TRISBbits.TRISB4 = 0;
    PORTBbits.RB4 = 0;
    resumeKeyboard();
    keyboardClockHigh();
    for (int i = 0; i < 8; i++) {
        keyboardClockLow();
        if (value & 1) {
            PORTBbits.RB4 = 1;
        } else {
            PORTBbits.RB4 = 0;
        }
        value = value >> 1;
        keyboardClockHigh();
    }
    keyboardClockLow();
    if (parity) {
        PORTBbits.RB4 = 1;
    } else {
        PORTBbits.RB4 = 0;
    }
    keyboardClockHigh();
    keyboardClockLow();
    TRISBbits.TRISB4 = 1;
    while (PORTBbits.RB4) {};
    while (!PORTBbits.RB4) {};
    keyboardClockHigh();
    suspendKeyboard();
}

The full version of this code I will add later. Note that in order to actually change the LED on the keyboard, you need to send two bytes, as follows: first you need to send 0xED, then wait for the keyboard to respond with 0xFA, after which you send 0-7 based on which LED you wish to turn on. 

vrijdag 25 november 2022

Mosha Eurorack Modules #10: I/O Module (Head phone output and MIDI input)

 

The I/O Module is a 6 HP module that provides some input and output facilities. The black knob is a double potentiometer that controls the left and the right channels. If a cable is plugged into the gold jack it will be either the left channel or both channels, and a cable plugged into the purple jack will be the right channel. The output is a TRS jack with the black dial controlling the volume. It uses two NE5532 OPAMP, one for each channel. The input voltage is divided by 5 using a resistor network. Because a dual voltage system is used, there is no output capacitor to normal the voltage.

The bottom six jacks are all MIDI related. The MIDI input is fed to the board from the rear of the box using a special conversion circuit (shown below. The 10k resistor in this circuit is essential and occasionally missing in online versions of this circuit). The optocoupler prevents ground loops through the MIDI cable and is required by the MIDI protocol for receiving data. There are two headers on the module, one to provide power to this circuit and one to transfer the MIDI signal to the PIC16F690 that is used to convert the MIDI.

The PIC16F690 was chosen because it has an USART (for MIDI) an analog input and a PWM that can be used as an analog output, and it can be programmed by the PICkit 2. The MIDI outputs are, in order: CV out for MIDI notes played on channel 4. The gate signal of these MIDI notes. The clock signal of the MIDI, and three drums from channel 10. The source code for the MIDI is available here.

To ensure a quick response to frequency changes the PIC16F690 is running at 20Mhz, which also allows 10-bit accuracy. There's a two pole active filter to prevent the PWM signal from interfering with the output, and a small trim potentiometer that allows setting the output voltage from 1x to 2.1x (10k with 9.1k non-inverting OPAMP, which may not be enough).



maandag 9 april 2018

PS/2 keyboard to MIDI translation

In 2011 I made a PS/2 keyboard to MIDI converter. It came with a sample source code, but this source code had some issues as it was originally meant for a regular keyboard read, not one that is MIDI specific. So at the encouragement of Oscar I wrote a better version of the source code that has the following additional features:

  • It allows mapping of every key on the keyboard using two tables, one for the regular keys (BaseKeyboard) and one for the keys whose scan codes start with 0xE0 (SuperfluousKeyboard). Setting a key is as simple as giving it a note (1-127).
  • It removes the auto repeat that some keyboards have that could create notes with an annoying echo.
  • It allows assigning of MIDI CC messages. This is done by adding 128 to the channel you wish the CC message to be sent over. By default it will send key presses with 127 and releases with 0. This can be changed globally, but not per CC.
  • It has various fixes that make the code run smoother and be less error prone.
The source code is available here. Remember to keep the spacing intact, as otherwise the file may not compile. It is intended for a PIC16F690. The wiring is described at the top, and in the original article.

The biggest flaw so far is that upon startup it sends a few random MIDI sequences out, because the keyboard sends its start up sequence to the PICmicro. This can be avoided by mapping those specific keys to 0, or by adding a startup delay.

zaterdag 19 maart 2011

PS2 to MIDI converter


Recently I purchased an EMT-10E (Yamaha sound extender) which was meant for the Clavinova to increase the different sounds you could make. I bought it for the project I mentioned earlier on this blog, so I would have something to hook the toy piano with MIDI to once I was done. However, due to issues with the switches the toy piano still doesn't have MIDI, and I still wanted to play with the EMT-10E. So I decided to make a PS/2 keyboard to MIDI converter. Since a PS/2 keyboard already sends key press and release commands it would be just a matter of converting the protocol and assign a note value to each key.

As this didn't seem to difficult, I decided to give myself another requirement, which was that it had to look nice. As you can see on the picture, I think I succeeded. Initially I decided to use a wood box, but the PS/2 connector that I got from Jameco was too narrow for wood, so I needed something thinner, but still strong. After walking around in Lowes for a while I discovered that an light switch box with a blank plate would work very well. I also bought a 1/2" drill bit for the holes, and it turned out it was quite easy to put everything together.

I once made a servo controller for Brian Asman, and I already had converted that board for MIDI output. It turned out it had the right size for the box, and I therefore only had to add the PS/2 connector (I connected the data line to PORTB bit 4, and the clock line to PORTA bit 2. You also should connect +5V and ground. Wikipedia has a very clear diagram of the connector, but make sure you have the right mirror image (initially I connected it wrong, reversing the voltages. My keyboard was quite lenient, though). You'll know when you have the right connections if you see the keyboard's LED blink. To hook up the MIDI you need two 220 Ohm resistors for use in the data line and the +5V line. The data line should be hooked up to the TX pin of the PIC16F690 (you can also use a PIC16F688, if you want something smaller). The EMT-10E conveniently has a 9-12V output, which I use to power the box.

You can see and hear the box at work here:

The EMT-10E has a "split keyboard" mode and allows transposing up and down for several octaves, and it has a number of different instruments (no drums, unfortunately). The only problem remaining is that a PS/2 keyboard has auto-repeat on keys, which is undesirable if you want to play notes for a longer period of time (it also causes some notes to become "stuck", possibly because more press events are received than release events).

Here is the first version of the source code, which basically reads a key from the keyboard, converts it into a note value, and either plays it or stops playing it, depending on whether it is a key press or a key release.

If you're interested in this project you can always contact me and I can provide more details if needed.

zondag 28 november 2010

Attempt at creating my own simple MIDI controller


I started on a new project, converting a cheap toy piano into a MIDI keyboard. The toy piano has 23 keys, which it reads using a 4x6 grid of scanlines. The resistors are already in place, and fortunately there are places for me to solder my wires to. The PIC16F690 should have enough pins (I only need 10, it has 20), and I already have MIDI code for my Beethoven playing box, that I described earlier. Hooking up a MIDI output is very easy as well: just connect +5V to pin 4 of a 5-pin female DIN plug with a 220 Ohm resistor, and hook up the TX pin of the PIC16F690 to pin 5. The step I forgot before is that pin 2 definitely needs to be grounded, so don't forget that. You can of course also use sketch one or sketch two, or any of the others found on the Internet.

I used the Pic kit 2 to try different voltages, and the MIDI works with my CASIO keyboard even at 2.5V. Since the piano has a 3V battery, I was glad to see this. Using 3V of course makes it not entirely MIDI compliant, but I'm sure most pianos will behave just fine with it.

zondag 25 januari 2009

ZX-jen screen shot

Here is a screenshot from the "ZX-jen" project, or the Drake-TV mentioned earlier in this blog. The cursor is '>' and the screen continues at the top after it ends at the bottom, instead of scrolling. The square block is the cursor and indicates the current position. Before that is the executing of the program, which is:

10 print "Hello world!"
20 let a%=3

As you can see the result of the execution is:

pHello world!
l%

The "Hello world!" is the actual output, the "p" and "l" are debug indicators: they are the first letter of the command being executed, so "print" and "let". The % sign is the type of variable being read, in this case an integer, which indicates that the let statement was correctly interpreted. The only other command that is currently available is "goto". The "Esc" key can be used to interrupt a program. The next step will be to allow printing of a%, although for that to happen the assignment should actually store the value in memory. After this various simple operations, like + and - should be implemented. After this I will consider the "for" and "next" statements.

As you can see the system supports "run" and "list" commands, but also "new" to wipe the memory. The program is stored in an external 24LC512, so even if the power fails the program will be available. Program lines can be entered by just preceding something with a line number, and deleted by providing a line number with no data. Overwriting is possible too.

zondag 11 januari 2009

Current project: Drake-TV



My current project is Drake-TV, a new version of the Drake that is hooked up to a PS/2 keyboard and the television, and works on a 9V adapter. It contains the various circuits described on these pages: the power supply (using a 7805), the video output (this time using a 16F688 instead of the 16F628A), the main processor (the 16F690) and the "external" memory EEPROM (24LC512). The audio has not been connected yet, but will undoubtedly be connected in the future.