VCI-100 unofficial firmware 1.3.1 available

Home :: DJ TechTools' VCI-100 FAQ :: VCI-100 unofficial firmware 1.3.1 availableReply
VCI-100 unofficial firmware 1.3.1 available
Posted on: 16.08.2010 by Verla Jurgensmeyer
UPDATE: Version 1.3.3 released, later in this thread!

== Intro ==

Hi everybody,

I recently purchased a VCI-100 SE. After reading a lot of different reviews about different USB DJ controller it seemed like the right choice. With all those good feedbacks and reviews I read, I was very surprised to receive a device with which you can't do serious beat matching. It's only after searching this community that I found all the complaints about this particular problem and the workarounds.

But there's one really good thing about the VCI-100 it's the fact that you can reprogram it. I'm quite into hardware hacking in general, so I downloaded the 1.3 firmware, fired up my favorite disassembler, and wasted some time on it in order to fix it

I'm very happy to present an unofficial 1.3.1 version of the firmware that has a 4x better precision for pitch faders than previous firmwares, look at the attached picture to see what that means!

== New features ==

  • Improved pitch faders resolution (512 steps instead of 128)

== Howto ==

To upgrade your firmware you need to follow the 1.3 upgrade instructions, but with the proper firmware file.

This new firmware sends the old messages as well as the new ones, so it's compatible with the DJranking s Traktor settings out of the box, but if you want the extra bits of precision you need to remap your Tempo settings (someone please make an import file for Traktor?)

- Deck A/C Tempo = CH02.PitchBend
- Deck B/D Tempo = CH03.PitchBend
- Deck A/C Tempo Reset = CH02.Note.C0
- Deck B/D Tempo Reset = CH02.Note.C#0

== Technical Details ==

All the analog faders & knobs on the VCI-100 are read using the main MCU (h8/300) built-in AD converters. Those converters have a precision of 10 bits. The previous firmwares converted those signals to 7 bits so it can fit in a regular Control Change MIDI message. In my 1.3.1 firmware, the pitch faders are converted to 9 bits then sent as a Pitch Bend MIDI message which has a 14 bits precision.

Why using 9 bits instead of 10 bits ? I worry that if the analog value is just between two digital values, it may oscillate between the two (due to noise) and so MIDI messages may be sent even when the pitch fader didn't move. The extra bit is required to avoid this kind of situation.

In theory it's possible to use 14 bits of precision for the pitch faders using a small hardware mod involving an external AD. Is it worth it? I dont know!

For interested people I've attached a couple of screenshots from the reverse-engineering process showing the same piece of code before and after all the guesswork and analysis

== Closing words ==

While I tested it, this release is a beta version so I'm waiting for your feedback. I've taken great care of polishing all the details, and you don't risk anything as you can always downgrade to 1.3 or 1.2 afterwards.

Have fun!

DaveX
Adolf Hit
17.08.2010
Ill be testing this as soon as im not bed ridden!
Verla Jurgensmeyer
18.08.2010
Still looking for testers, here's 1.3.2 with new improvements! I believe it's time to put my VCI back in its case to finally enjoy it, it
Hipolito Scionti
17.08.2010
Ean and DJTT need to get on this.. this is serious breaking news!!! Surely this will make the vci se/arcade edition an extremely serious competitor to any controller now.

I still haven't got my FW kit yet but when i do i will check this out.

But i'd like to see DJTT get behind this asap.

So, does this mean the jogs will be more responsive for scratching??? that's pretty key for a lot of people eh...

Stirling work!
Doug Bieling
17.08.2010
ooowh need to get my vci tempo slider fixed for this?

Anyone used it yet?
Tyrone Baghdadi
17.08.2010
Holy Sh
Verla Jurgensmeyer
17.08.2010
Originally Posted by MaxOne
I dont know what the hell you guys are talking about but i love the cut of your jib...

if you can make the vci 100 jogs and pitch more accurate then i'll nominate you for a nobel peace prize...
Done!

4x pitch resolution
4x jog resolution

I'll release a new firmware soon after more testing. I'm REALLY looking for someone with a programmer to do some testing!

For the technical infos related to the jogs:

The jog info is sent as relative value since last jog message. That's why it doesn't make sense to talk about 7-bit or 14-bit jog MIDI signal: as long as you send your signals fast enough, 7-bit MIDI messages are enough even if the absolute resolution of the jog is much more precise.

Actually the jog wheel implementation on the VCI-100 is not done using an AD converter, but the jog wheel sends pulses to the microcontroller at high speed. One pulse = one step. I've no idea how many steps there are for a full rotation of the jog wheel, but much more than 128 that's for sure.

I was able to improve the jog resolution by a factor of 2 because internally the resolution is divided by 2 (that's not for debouncing), so I just disabled it. Over this I gained a factor of 2 again by triggering the edge-detection interrupt on both edges instead of just rising edge (the signal seems well suited to do that).
Hipolito Scionti
17.08.2010
I dont know what the hell you guys are talking about but i love the cut of your jib...

if you can make the vci 100 jogs and pitch more accurate then i'll nominate you for a nobel peace prize...
Verla Jurgensmeyer
17.08.2010
Hey Fatlimey, thanks for your reply.

This post will get technical, warning!

Thanks a lot for the tip, but actually this is exactly what I'm doing, I simplified my explaination for the sake of readability I'm waiting for a difference of at least 2 integer values (in comparison to previously stored value) before sending the fader data to have this hysteresis. The least significant bit is then truncated (technically it's still a bit of precision, but you can't use it for fine tuning so it doesn't sound like worth keeping) and then the value used as an index in a response-mapping table which is linear except for the center value which is very wide, so that you're in the center even if you're not exactly at the center (as each pot has a slightly different response, original firmware does this too).

What's interesting is that original firmware does this response-mapping conversion using an 8bit AD value (already debounced) as index, to convert the data to 7 bits. So values between 0 and 127 are stored in this 256-entries table, there are really 128 steps. In my case, I can't afford to "lose a bit" in this conversion table. That's why there are not exactly 512 steps in 1.3.1 but around 490-500 or so (as the center value eats up more than one field). I then shift the value to the left to make it 14 bits. That way even if more bits of precision are added, there's no need to change the mapping.

Add to this a Note ON and Note OFF message when you enter / leave the center position, and that's about all the processing that's done...

Regarding LEDs, do you have a mapping of LED MIDI messages the unit can receive? Or at least one of the message? I didn't fully trace the MIDI events in that direction, except for a couple of SysEx calls (one sending back the unit description, the other sending back all the current unit configuration).

I'll reply to your PM.

Cheers

Originally Posted by Fatlimey
Some improvements you might like to make. Truncating an ADC value to remove LSB noise doesn't unfortunately work for all values in the number line, only most of them. Take for instance the 10-bit value:

010011111?

where "?" is the noisy bit. The ADC value is wobbling between two digital values:

0100111111 and 0101000000

Truncating to 7 bits will still send a noisy value to the result because the chain of 1-bits causes the noise to "rise up" through the value and appear in the truncated end result.

The trick to "debouncing" ADC reads is to keep a copy of the previous ADC value at full resolution and only pass on the new ADC value to the truncation code if the full-res value has changed by, say, plus or minus two bits. This adds a bit of hysteresis into the system that will remove noise but still allow actual movement to be recorded quickly. Here's some code:

Code:
        // Make sure any change in the value is due to
        // user action and not sampling noise. We do this by making sure the
        // value has changed by a minimum amount before we say it has
        // changed - essentially adding a small amount of Hysteresis into
        // the system. This part happens at full resolution.
        for (uint8_t i=0; i<4; ++i) {
            // Read the ADC value once and record it for use everywhere else.
            int16_t value = adc_read(i);
            // NOTE: Need a signed 16-bit value for the difference
            int16_t difference = value - g_analog_prev[i];
            // If the difference is less than three bits either way we
            // assume the difference was noise and the ADC was not changed.
            if (abs(difference) < 8) {
                // do not send the noisy new value, use the old reliable one.
                adc_value[i] = g_analog_prev[i];
            } else {
                adc_value[i] = value;
            }
        }

        // Next, loop over these fresh ADC values to see if, after
        // truncation, they have changed and a MIDI event needs
        // to be generated.
        for (uint8_t i=0; i<4; ++i) {

            // Lose the bottom three bits of each 10-bit ADC value,
            // converting it to a 7-bit CC value.
            uint8_t value = (uint8_t)(adc_value[i] >> 3);
            uint8_t prev_value = (uint8_t)(g_analog_prev[i] >> 3);

            // Compare the CC value to the previous one sent. If there has
            // been a change, generate a new MIDI Control Change event
            // sending the new value.
            if (value != prev_value) {
                // Generate the default CC event.
                midi_stream_cc(16 + i, value);
                ....

                // Record the new ADC value, at full resolution, for the next
                // time through.
                g_analog_prev[i] = adc_value[i];
           }
           ....
        }
Do this and your faders return rock solid results. This code comes from a Midifighter update I'm working on.

Looks like you'll have to find a few unused words of RAM to use for the previous values. Also, if you have any clue why the lights flicker when the unit recieves MIDI input I'd love to try and fix that. My guess is there's no latch on the LED values and the flickering is the LED bits rippling through the serial input. No good way to fix that unfortunately.

Keep up the good work! Should you feel the desire to share your discoveries as an open source Creative Commons project, I'd love to help you out. Check your PM!
robert chanda
17.08.2010
DaveX, blinkin' marvellous work. *applause*

Some improvements you might like to make. Truncating an ADC value to remove LSB noise doesn't unfortunately work for all values in the number line, only most of them. Take for instance the 10-bit value:

010011111?

where "?" is the noisy bit. The ADC value is wobbling between two digital values:

0100111111 and 0101000000

Truncating to 7 bits will still send a noisy value to the result because the chain of 1-bits causes the noise to "rise up" through the value and appear in the truncated end result.

The trick to "debouncing" ADC reads is to keep a copy of the previous ADC value at full resolution and only pass on the new ADC value to the truncation code if the full-res value has changed by, say, plus or minus two bits. This adds a bit of hysteresis into the system that will remove noise but still allow actual movement to be recorded quickly. Here's some code:

Code:
        // Make sure any change in the value is due to
        // user action and not sampling noise. We do this by making sure the
        // value has changed by a minimum amount before we say it has
        // changed - essentially adding a small amount of Hysteresis into
        // the system. This part happens at full resolution.
        for (uint8_t i=0; i<4; ++i) {
            // Read the ADC value once and record it for use everywhere else.
            int16_t value = adc_read(i);
            // NOTE: Need a signed 16-bit value for the difference
            int16_t difference = value - g_analog_prev[i];
            // If the difference is less than three bits either way we
            // assume the difference was noise and the ADC was not changed.
            if (abs(difference) < 8) {
                // do not send the noisy new value, use the old reliable one.
                adc_value[i] = g_analog_prev[i];
            } else {
                adc_value[i] = value;
            }
        }

        // Next, loop over these fresh ADC values to see if, after
        // truncation, they have changed and a MIDI event needs
        // to be generated.
        for (uint8_t i=0; i<4; ++i) {

            // Lose the bottom three bits of each 10-bit ADC value,
            // converting it to a 7-bit CC value.
            uint8_t value = (uint8_t)(adc_value[i] >> 3);
            uint8_t prev_value = (uint8_t)(g_analog_prev[i] >> 3);

            // Compare the CC value to the previous one sent. If there has
            // been a change, generate a new MIDI Control Change event
            // sending the new value.
            if (value != prev_value) {
                // Generate the default CC event.
                midi_stream_cc(16 + i, value);
                ....

                // Record the new ADC value, at full resolution, for the next
                // time through.
                g_analog_prev[i] = adc_value[i];
           }
           ....
        }
Do this and your faders return rock solid results. This code comes from a Midifighter update I'm working on.

Looks like you'll have to find a few unused words of RAM to use for the previous values. Also, if you have any clue why the lights flicker when the unit recieves MIDI input I'd love to try and fix that. My guess is there's no latch on the LED values and the flickering is the LED bits rippling through the serial input. No good way to fix that unfortunately.

Keep up the good work! Should you feel the desire to share your discoveries as an open source Creative Commons project, I'd love to help you out. Check your PM!
Jolyn Brunello
16.08.2010
nice work dave.thanx for sharing.i've never flashed but will give it a try when i get back thursday
Reece Murray
16.08.2010
Holy God, DaveX - can you do this with the jog wheels as well?
Adolf Hit
16.08.2010
I'm forwarding this to Ean now - I'm sure he will be in contact shortly.

Very nice work!
Hipolito Scionti
16.08.2010
I haven't got my firmware upgrade kit yet but this looks interesting i must say...
Verla Jurgensmeyer
16.08.2010
I updated the post with small details, you don't risk anything upgrading as you can always downgrade to 1.2 or 1.3. But I also hope one of the admins checks it out!
Merlyn Komula
15.08.2010
I might check this out! Would be nice if any of the admins check this out and let us know if its safe!

SS
Ji Pursel
15.08.2010
Originally Posted by photojojo
Curious to see if anyone tries this firmware.
you go first

ill have to check back later and decide if i want to dig out my usb-serial cable
Leeanna Ayla
15.08.2010
Curious to see if anyone tries this firmware.

<< Back to DJ TechTools' VCI-100 FAQReply

Copyright 2012-2023
DJRANKINGS.ORG n.g.o.
Chuo-ku, Osaka, Japan

Created by Ajaxel CMS

Terms & Privacy