HS Expander prototype


Unleash the FM Beast that is your Electone HS organ with this device.

The Expander allows access to all 113 parameters of the FM synths inside the Yamaha Electone HS series of organs.
It is build on the Arduino Uno development board, using cheaply available parts, keeping a minimal user interface whilst expanding the organ's capabilities tremendously.
Check the info below for all the nitty-gritty details that went into the design and build of the Expander.

Design and construction video: coming soon!.

Demonstration and explanation video: watch it here.







The YM2414



Since information on this Yamaha sound IC is rather scarce I'm going to quickly go into it here.

The few bits and bobs of info I found I compiled into the image below.

Yep, it's not much. But luckily we're not trying to control the YM2414 IC's directly, so the organ will do the heavy lifting for us.

The YM2414 is a neat IC though, and has been used in some well know Yamaha synths such as the DX11 and the TX81z.
You no doubt have heard the infamous 'Lately Bass' in popular songs from the 80's and 90's.

Here's a bunch of specs:
- 4 operators,
- Ratio and Fixed frequency modes for the operators,
- 8 algorithms for the operators,
- 8 waveforms for the operators,
- 2 LFOs that each can do pitch and amplitude modulation,
- 4 waveforms for the LFOs: saw, square, triangle, S&H,
- 4 Envelope generators (one for each operator),
- 5-stage envelopes: Attack, Decay1, Decay Level, Decay2, Release.

These are the algorithms:


These are the waveforms:


These are the envelopes:





The Yamaha Sysex



I hope you are ready for a deep-dive, because Yamaha only supplied info on the most basic sysex commands.
The actual format and size of the data was never published to the public for some reason, even though Yamaha is
tooting the MIDI programming capabilities of their DX synths and organs in every user manual...

Oh well, plenty o' clever people to figure things out instead!
Thanks to some smart people in a now long-gone Yahoo group (thanks Yahoo) and thanks to Marcel Krol's preservation of the
documents and knowledge created by that group, we now know a little more about how it all works.
I've done futher research and experimentation, based on the information given to me by Marcel. Here's what I currently know.

The Electone HS has two main ways to update the voices in memory:
Sending parameter data, either individual or as sets:


All values are in HEX format, 0xF0 and 0xF7 are general Sysex start and end commands.

First up is the command message, to tell the organ what to do:
0x43 is the Yamaha manufacturer tag, 0x70 is Electone tag, the second 0x70 can also be 0x72 for the HS tag.
XX can be either 0x01 to receive data from the organ, or 0x02 to send data to the organ.
ID1 is which registration the parameter needs to be send to and can be the following:
- 0x00 for Lead,
- 0x08 for Upper Orchestra,
- 0x10 for Lower Orchestra,
- 0x18 for Upper Combi,
- 0x20 for Lower Combi,
- 0x28 for Bass (also pedals),
- 0x30 for Arpeggio,
- 0x38 for Percussive (not drums, that's just how the registration is named).
ID2 is always 0x00,
SPL is the lower adress byte i.e. the parameter number,
SPH is the higher adress byte and is never used,
DCL is the amount of parameter bytes that are send or received,
DCH is the same, but the high byte just like the adress byte. Rarely used unless you are sending more than 255 param bytes

The second message in the above image is the actual data message:
First we get the Yamaha and Electone tags,
Model can just be 0x72 for the HS series,
We then get a 0x0 followed by the actual parameter data,
And finally the checksum, which is all the data bytes added together and then AND-ed with 0x7F (or 01111111 in binary)
to remove bit 7 as per required in the Sysex format.


Sending bulk User Voice data, 77 bytes per voice:

Again: all values are in HEX format, 0xF0 and 0xF7 are general Sysex start and end commands.
Model can also by 0x72 for the general HS series, as far as I'm aware all HS models have 4 user voices but I could be wrong.
If you're not sure you can use the tags in the image :)





The Voice Data



As you noticed in the previous section: we are still missing whatever "data" is in above commands.
There are a few oddities about the data format actually send to or from the organ as well, so lets dive into it.

The full parameter map is way too big to post here, so I'll provide a download link to the Excel sheet.
The sheet can be downloaded here.
This sheet was originally made by Marcel, when making his web editor, and has been further expanded/adjusted upon by me.
There is also a very old document (1989!) that this information is based on. It isn't entirely correct but does list all possible parameters.
This document (PDF) can be downloaded here.

I've color coded and corrected the Excel sheet as much as I can, but some parts are still a little questionable and require further testing.
Light blue is general settings, yellow is operators (note they are arranged 4,2,3,1 !), orange is envelopes.
Finally green and dark blue are the two LFOs, which is the part that I'm still figuring out the most.
The LFOs should each be able to do both pitch-modulation as amplitude-modulation (at the same time), but the HS organ has things configured a little differently.
LFO2 seems to be only for Vibrato, but LFO1 can do pitch- and amplitude-modulation. Furthermore, for Lead sounds you have the option to blend from LFO1 to LFO2
by setting the LFO Lead Attack setting in byte 51.
It does seem there are more settings available for the LFOs that would allow you to do more, but I haven't made much progress in figuring that out as of writing this.

Some things like the Harmonic, Aftertouch and Portamento values don't seem to do much yet, although editing Portamento Time for the Lead Glide does seem to work.

If you've figured out some new information, I'd be happy to hear it!

But... there's something very important when sending/receiving voice data...:
The voice data is converted from 8-bits to either one- or two bytes with 7-bits of data:


I've been able to reduce this to just two lines of code, and an IF statement. Here's some psuedocode:

byte value = param_byte;

if(value > 0b00111111)
{
	byte data[2];
	data[0] = (value & 0b00111111) | 0b01000000;
	data[1] = ((value & 0b11000000) >> 2) | 0b01000000;
	
	send_data_array(data);
}
else
{
	send_data_normally(value);
}
		
Basically: if the byte value is higher than 63 than bit 6 and 7 are not 0, so we need to convert the data to two bytes.
If the value is lower than 63 we don't need to do anything special and can just send the data unchanged.

For the values higher than 63 I shift the two upper bits of the value to bits 4 and 5 and store then in the second byte.
The first byte gets the value sans the two upper bits by AND-ing the value.
I then OR both bytes to add the required two upper bits for the 01xxxxxx format required.




The Code



The code is currently still in the experimental/beta stage and subject to changes.
I also need to clean it up, put some things in separate files to make it more readable and make it easy for other people to re-use the code
for their projects. But I will already offer the code up for download.
The Arduino project file can be downloaded here.

Note that you'll need to install the LiquidCrystal I2C (by Frand de Brabander) and MIDI (by Francois Best) libraries. Both can be installed from within Arduino IDE 2.

The 'voice_params' array contains all data bytes for a single voice in RAM and is the data of the voice that is currently being edited.
Voice data is permanently stored in the EEPROM along with the voice name. The Arduino Uno only has 1kb of EEPROM
so there is only 12 voice slots available. This can be easily expanded on Arduino boards with a bigger EEPROM.

Then there are 4 arrays stored on flash memory (using PROGMEM) that make the code a lot simpler for writing and reading
the voice data, since multiple voice parameters are compressed into the same bytes (reducing the size to 77 bytes).
These arrays store the maximum values, voice_param array indexes, bitmasks and bitshift amounts for all parameters.

The function 'sendParam' is used to send a single byte to the HS organ. Note that one byte can contain multiple voice parameters.

The function 'sendVoice' does the same thing, but with all 77 (orchestra, combi) or 57 (other registrations) bytes of a voice.

The function 'menu_set' handles all LCD updates, of all the various menus in the Expander.





Schematics


Here's a quick 'n dirty schematic of the connections on the Arduino:




Copyright 2023 Evil Turtle Productions. All Rights Reserved.