app/README.md,tiny/README.md,ctrl/READM.md : Initial commit.
This commit is contained in:
parent
5008c67002
commit
e3a5a9a6fa
@ -2,19 +2,19 @@ This folder contains the _picadae_ control code.
|
||||
|
||||
The _picadae_ control program consists of three parts:
|
||||
|
||||
- _tiny_ : Keyboard solenoid driver
|
||||
- _ctrl_ : Keyboard central controller
|
||||
- _app_ : Monitor and command utility.
|
||||
- _tiny_ : [ATtiny85 solenoid driver firmware](tiny/README.md)
|
||||
|
||||
- _ctrl_ : [ATmega328 interface unit](ctrl/README.md)
|
||||
|
||||
- _app_ : [Python monitor and command utility](app/README.md)
|
||||
|
||||
# Architecture
|
||||
|
||||
The keyboard control hardware consists of 8 driver boards
|
||||
mounted above the solenoids on the keyboard assembly.
|
||||
Each driver board has 11 key driver circuits and can
|
||||
therefore control 11 piano keys. Each key driver
|
||||
circuit consists of an ATtiny85 microcontroller
|
||||
which controls a set of power transistors
|
||||
which in turn control the state of the solenoid.
|
||||
The keyboard control hardware consists of 8 driver boards mounted
|
||||
above the solenoids on the keyboard assembly. Each driver board has
|
||||
11 key driver circuits which control 11 piano keys. Each key driver
|
||||
circuit consists of an ATtiny85 microcontroller which controls a set
|
||||
of power transistors which in turn control the state of the solenoid.
|
||||
The solenoid can be in one of three states:
|
||||
|
||||
- off
|
||||
@ -25,56 +25,29 @@ The attack state is triggered by pulsing the
|
||||
the solenoid with a fast (250 microsecond to
|
||||
30 millisecond) 36 volt pulse. The duration
|
||||
of the pulse determines the attack dynamic.
|
||||
The hold state then holds the key down
|
||||
during the sustain portion of the note.
|
||||
Longer pulses produce louder notes.
|
||||
At the end of the attack state the solenoid
|
||||
transitions into a hold state. During
|
||||
this time the key is held down with just
|
||||
enough force to sustain the note.
|
||||
|
||||
All 88 ATtiny85 microncontrollers are attached
|
||||
to a single I2C bus which is shared with
|
||||
an Arduino Uno. The application computer
|
||||
communicate with the Uno via
|
||||
a serial connection. The Uno in turn
|
||||
translates messages between the
|
||||
ATtiny85 channel computers and the
|
||||
application computer.
|
||||
to a single I2C bus which is mastered by an ATmega328 MCU
|
||||
which acts as a serial to I2C translator for the host computer.
|
||||
|
||||
The host API is implemented as the Python class 'Picadae' in app/picadae_api.py.
|
||||
The control shell program app/picadae_shell.py shows an example
|
||||
usage of the API.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Keyboard central controller : Arduino Uno Serial Interface
|
||||
|
||||
Read a register value of `<count>` bytes from channel `<i2c-addr>`
|
||||
|
||||
'r' <i2c-addr> <register> <count>
|
||||
|
||||
Write a register value of `<count>` bytes from channel `<i2c-addr>`
|
||||
|
||||
'w' <i2c-addr> <register> <count> <value-0> <value-1> ... <value-n>
|
||||
|
||||
|
||||
# Keyboard solenoid driver : ATtiny85 Firmware
|
||||
|
||||
|
||||
PWM counter frequency and period.
|
||||
for each possible `div` setting
|
||||
with 16 Mhz system clock.
|
||||
|
||||
Value | Div | Frequency | Period
|
||||
------|------|-------------|-------
|
||||
1 | 1 | 16 M | 62.5 n
|
||||
2 | 2 | 8 M | 125 n
|
||||
3 | 4 | 4 M | 250 n
|
||||
4 | 8 | 2 M | 500 n
|
||||
5 | 16 | 1 M | 1 u
|
||||
6 | 32 | 500 K | 2 u
|
||||
7 | 64 | 250 K | 4 u
|
||||
8 | 128 | 125 K | 8 u
|
||||
9 | 256 | 62500 Hz | 16 u
|
||||
10 | 512 | 31250 Hz | 32 u
|
||||
11 | 1024 | 15625 Hz | 64 u
|
||||
12 | 2048 | 7812.5 Hz | 128 u
|
||||
13 | 4096 | 3906.25 Hz | 256 u
|
||||
14 | 8192 | 1953.125 Hz | 512 u
|
||||
15 |16384 | 976.6625 Hz | 1024 u
|
||||
|
||||
|
||||
# Monitor and command utility : Python Utility
|
||||
|
||||
|
||||
|
||||
|
1
control/app/README.md
Normal file
1
control/app/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Picadea control and monitor shell
|
23
control/ctrl/README.md
Normal file
23
control/ctrl/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# ATmega328 Interface Unit
|
||||
|
||||
This MCU acts as a serial to I2C translator for the host
|
||||
computer. The serial protocol implements two
|
||||
interfaces. One for read requests and another for write commands.
|
||||
|
||||
The data format of the write commands is given
|
||||
in the ATtiny85 I2C protocol document.
|
||||
|
||||
Read requests return blocks of memory begining with the address
|
||||
specified in the last 'Set read address' command.
|
||||
|
||||
## Read: Channel to Host
|
||||
|
||||
Read a `<count>` bytes from a channel beginning at offset = 'offset'
|
||||
|
||||
'r' <i2c-addr> <offset> <count>
|
||||
|
||||
## Write: Host to Channel
|
||||
|
||||
Write `<count>` bytes from from the host to a channel
|
||||
|
||||
'w' <i2c-addr> <register> <count> <value-0> <value-1> ... <value-n>
|
157
control/tiny/README.md
Normal file
157
control/tiny/README.md
Normal file
@ -0,0 +1,157 @@
|
||||
# ATtiny85 I2C protocol
|
||||
|
||||
|
||||
Arguments in curly braces are optional.
|
||||
|
||||
|
||||
Function | Opcode | Arguments
|
||||
-------------------------|--------|---------------------------
|
||||
Set hold PWM duty cycle | 0 | (duty) { (freq) { (div) }}
|
||||
|
||||
Arguments | Range | Default | Note
|
||||
----------|-------|---------|------------------------------------------------------
|
||||
(duty) | 0-255 | 127 | 0=0%, 255=100%
|
||||
(freq) | 0-255 | 255 | Sets PWM top value
|
||||
(div) | 1-15 | 5 | Set the PWM base clock frequency (See table below)
|
||||
|
||||
PWM frequency and period for each possible (div) setting.
|
||||
|
||||
Reg. | | Base |
|
||||
Value | Div | Frequency | Period
|
||||
------|------|-------------|-------
|
||||
1 | 1 | 16 M | 62.5 n
|
||||
2 | 2 | 8 M | 125 n
|
||||
3 | 4 | 4 M | 250 n
|
||||
4 | 8 | 2 M | 500 n
|
||||
5 | 16 | 1 M | 1 u
|
||||
6 | 32 | 500 K | 2 u
|
||||
7 | 64 | 250 K | 4 u
|
||||
8 | 128 | 125 K | 8 u
|
||||
9 | 256 | 62500 Hz | 16 u
|
||||
10 | 512 | 31250 Hz | 32 u
|
||||
11 | 1024 | 15625 Hz | 64 u
|
||||
12 | 2048 | 7812.5 Hz | 128 u
|
||||
13 | 4096 | 3906.25 Hz | 256 u
|
||||
14 | 8192 | 1953.125 Hz | 512 u
|
||||
15 |16384 | 976.6625 Hz | 1024 u
|
||||
|
||||
|
||||
Function | Opcode | Arguments
|
||||
-------------------------|--------|---------------------------
|
||||
Note on velocity | 1 | (vel)
|
||||
|
||||
Arguments | Range | Default | Note
|
||||
----------|-------|---------|------------------------------------------------------
|
||||
(vel) | 0-127 | n/a | Note on velocity.
|
||||
|
||||
Execute a note onset.
|
||||
The (vel) value is translated to an attack pulse duration
|
||||
by looking up the pulse tick count in the velocity table.
|
||||
|
||||
|
||||
Function | Opcode | Arguments
|
||||
-------------------------|--------|-------------------------------------------------
|
||||
Note on ticks | 2 | (pulse-ticks-high-byte) (pulse-ticks-low-byte)
|
||||
|
||||
Execute a note onset.
|
||||
The 16 bit attack duration in ticks is calculated from microseconds.
|
||||
|
||||
pulse-ticks = (usec / 1e6) * (16e6/256)
|
||||
|
||||
Where 16e6 is the system clock frequency and 256 is the timer0 clock divider.
|
||||
`TCCR0B:C02,C01,C00 = 100b (4)`
|
||||
|
||||
|
||||
ticks to micoseconds:
|
||||
|
||||
usecs = (pulse-ticks * 1e6)*(256/16e6)
|
||||
|
||||
|
||||
Function | Opcode | Arguments
|
||||
-------------------------|--------|---------------------------
|
||||
Note off | 3 | None
|
||||
|
||||
Turn off a sounding note by settting the hold-voltage to 0.
|
||||
|
||||
|
||||
Function | Opcode | Arguments
|
||||
-------------------------|--------|---------------------------
|
||||
Set read address | 4 | (src) {(addr)}
|
||||
|
||||
Set the source and address of the next I2C read request.
|
||||
|
||||
The read can come from one of three memory banks:
|
||||
Register File, MIDI velocity table or EEPROM.
|
||||
See the _Memory Location Id_ table below for the (src) id values.
|
||||
|
||||
|
||||
Arguments | Range | Default | Note
|
||||
------------|-------|---------|-------------------------------------------------------
|
||||
(src) | 0-2 | n/a | Memory location id. See _Memory Location Id_ table.
|
||||
(addr) | 0-255 | n/a | Offset from base address set by (src)
|
||||
|
||||
|
||||
Function | Opcode | Arguments
|
||||
-------------------------|--------|---------------------------
|
||||
Write memory | 5 |
|
||||
|
||||
|
||||
|
||||
Function | Opcode | Arguments
|
||||
-------------------------|--------|---------------------------
|
||||
Set hold delay | 6 | { high {low}}
|
||||
|
||||
Set the length of the delay, in ticks, between when the attack pulse ends and when the
|
||||
hold voltage is applied.
|
||||
The high and low byte values are calculated identically to the
|
||||
attack pulse duration values.
|
||||
|
||||
|
||||
Function | Opcode | Arguments
|
||||
-------------------------|--------|---------------------------
|
||||
Set flags variable | 7 | (flags)
|
||||
|
||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
|
||||
-----|-----|-----|-----|-----|-----|-----|-----
|
||||
n/a | n/a | n/a | n/a | n/a | n/a | n/a | HOA
|
||||
|
||||
_HOA_ : Set to apply the hold voltage at the beginning of the attack.
|
||||
|
||||
|
||||
Register file
|
||||
|
||||
Address | Label | Note
|
||||
--------|-----------------|------------------------------------------------------------------------------------------------
|
||||
0 | Reg_Rd_Addr | Next register file address to read.
|
||||
1 | Table_Rd_Addr | Next MIDI velocity address to read.
|
||||
2 | EEPROM_Rd_Addr | Next EEPROM address to read.
|
||||
3 | Read_Src_Addr | Source of the next I2C read request. See Memory Location Id table below.
|
||||
4 | Reg_Wr_Addr | Next register file address to write.
|
||||
5 | Table_Rd_Addr | Next MIDI velocity address to write.
|
||||
6 | EEPROM_Rd_Addr | Next EEPROM address to write.
|
||||
7 | Write_Dst_Addr | Destination of the next 'write operation'. See Memory Location id table below.
|
||||
8 | Tmr_High_Addr | Current attack pulse tick count high byte
|
||||
9 | Tmr_Low_Addr | Current attack pulse tick count low byte
|
||||
10 | Tmr_Div_Addr | Attack pulse counter frequency divider.
|
||||
11 | Pwm_Duty_Addr | Duty cycle of the hold PWM generator
|
||||
12 | Pwm_Freq_Addr | PWM counter max values. Determines the PWM frequency.
|
||||
13 | Pwm_Div_Addr | PWM clock divider
|
||||
14 | State_Addr | Current solenoied state.
|
||||
15 | Error_Addr | Error status
|
||||
16 | Max_Tmr_Hi_Addr | Max attack pulse high byte tick count.
|
||||
17 | Delay_High_Addr | Hold delay onset tick count high byte
|
||||
18 | Delay_Low_Addr | Hold delay onset tick count low byte
|
||||
19 | Flags_Addr | Binary variable field.
|
||||
|
||||
|
||||
Memory Location Id table.
|
||||
|
||||
Id | Memory | Note
|
||||
---|----------------|-------------------------------
|
||||
0 | Register file | See register table file
|
||||
1 | Velocity table | MIDI velocity to pulse ticks lookup table
|
||||
2 | EEPROM | EEPROM data memory
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user