This website is still under construction.


Outside Fursuit

For this purpose, "Server" is Fursuit (Central Unit) and "Client" is device connecting to Fursuit.

Fursuit Specifications

Buttons

Axis

Packets

Communication Start

Communication Packet
C -> S login (request)
S -> C login (response)
Possible end of communication (Wrong Password)
S -> C getMainInfo (response)
getStatus (response)
From now, order may be different.
Not all packets may be send.
S -> C getLedInfo (response)
getWingsInfo (response)
getServoInfo (response)
getUserInputInfo (response)

After this start, any packets (in right direction) excluding login packets (both request + response).

Password

login (request)

ID 0x00
Direction Client -> Server
Size 4 bytes
Byte ID Data Type Name Value
0 uint / uint32 password 0 - 4,294,967,295

login (response)

ID 0x02
Direction Server -> Client
Size 1 byte
Byte ID Data Type Name Value
0 byte success 0 ~ success
>= 0 ~ fail

setPassword (request)

ID 0x03
Direction Client -> Server
Size 12 bytes
Byte ID Data Type Name Value
0 uint / uint32 master_password 0 - 4,294,967,295
4 uint / uint32 new_password 0 - 4,294,967,295
8 uint / uint32 ~new_password
Binary inverted new_password
0 - 4,294,967,295

setPassword (response)

ID 0x05
Direction Server -> Client
Size 1 byte
Byte ID Data Type Name Value
0 byte success 0 ~ success
>= 0 ~ fail

Info

getMainInfo (request)

ID 0x10
Direction Client -> Server
Size 0 bytes

getMainInfo (response)

ID 0x11
Direction Server -> Client
Size 34 bytes
Byte ID Data Type Name Value
0-15 char[16]
string
fursuit_name {fursuit_name}
16-31 char[16]
string
fursuit_owner {fursuit_owner}
32 byte battery_count {battery_count}
33 byte temp_sensor_count {temp_sensor_count}

getLedInfo (request)

ID 0x12
Direction Client -> Server
Size 0 bytes

getLedInfo (response)

ID 0x13
Direction Server -> Client
Size 1 byte + {led_count}
Byte ID Data Type Name Value
0 byte led_count {led_count}
{led_count} count
17 bytes per item
byte led_color_number {led_color_number}
(byte count)
0 = HIGH / LOW (1 byte)
1 = 1 color
3 = RGB color
char[16]
string
led_name {led_name}

getWingsInfo (request)

ID 0x14
Direction Client -> Server
Size 0 bytes

getWingsInfo (response)

ID 0x15
Direction Server -> Client
Size 1 byte + {wings_count}
Byte ID Data Type Name Value
0 byte wings_count {wings_count}
{wings_count} count
16 bytes per item
char[16]
string
wing_name {wing_name}

getServoInfo (request)

ID 0x16
Direction Client -> Server
Size 0 bytes

getServoInfo (response)

ID 0x17
Direction Server -> Client
Size 1 byte
+
{servo_count} * 16
Byte ID Data Type Name Value
0 byte servo_count {servo_count}
{servo_count} count
16 bytes per item
char[16]
string
servo_name {servo_name}

getUserInputInfo (request)

ID 0x18
Direction Client -> Server
Size 0 bytes

getUserInputInfo (response)

ID 0x19
Direction Server -> Client
Size 2 bytes
+
{user_buttons_count} * 16
+
{user_axis_count} * 16
Byte ID Data Type Name Value
0 byte user_buttons_count {user_buttons_count}
{user_buttons_count} count
16 bytes per item
char[16]
string
user_button_name {user_button_name}
1
+
{user_buttons_count} * 16
byte user_axis_count {user_axis_count}
{user_axis_count} count
16 bytes per item
char[16]
string
user_axis_name {user_axis_name}

Status

getStatus (request)

ID 0x20
Direction Client -> Server
Size 0 bytes

getStatus (response)

ID 0x21
Direction Server -> Client
Size 2 * {battery_count} bytes
+
2 * {temp_sensor_count} bytes
Byte ID Data Type Name Value
???
{battery_count} count
ushort / uint16
fixed point number (3 decimal)
Battery {battery_id} 0.000 - 65.535
???
{temp_sensor_count} count
ushort / uint16
fixed point number (3 decimal)
Temperature Sensor {temp_sensor_id} 0.000 - 65.535

Slots

saveToSlot

ID 0x30
Direction Client -> Server
Size 1 byte
Byte ID Data Type Name Value
0 byte slot 1 - 5

loadFromSlot

ID 0x31
Direction Client -> Server
Size 1 byte
Byte ID Data Type Name Value
0 byte slot 1 - 5

User Input

getUserInputButtons (request)

ID 0x40
Direction Client -> Server
Size 0 bytes

getUserInputButtons (response)

ID 0x41
Direction Server -> Client
Size {user_buttons_count} bytes
Byte ID Data Type Name Value
{user_buttons_count} count byte {user_button_name} 0 ~ LOW
>0 ~ HIGH

getUserInputAxis (request)

ID 0x42
Direction Client -> Server
Size 0 bytes

getUserInputAxis (response)

ID 0x43
Direction Server -> Client
Size {user_axis_count} bytes
Byte ID Data Type Name Value
{user_axis_count} count byte {user_axis_name} 0 - 255

Leds

setLedColor

ID 0x50
Direction Client -> Server
Size {led_count} count,
different byte number
Byte ID Data Type Name Value
??? byte {led_name} 0 / 255
0 - 255

getLedColor (request)

ID 0x51
{led_count} count,
different byte number
Direction Client -> Server
Size 0 bytes

getLedColor (response)

ID 0x52
Direction Server -> Client
Size {led_count} count,
different byte number
Byte ID Data Type Name Value
???
{led_count} count,
different byte number
byte {led_name} 0 / 255
0 - 255

Wings

setWings

ID 0x60
Direction Client -> Server
Size {wings_count} bytes
Byte ID Data Type Name Value
??? byte {wings_name} 0 - 100
byte wing_speed 0 - 25,500
(0 - 255) * 100

getWings (request)

ID 0x61
Direction Client -> Server
Size 0 bytes

getWings (response)

ID 0x62
Direction Server -> Client
Size {wings_count} bytes
Byte ID Data Type Name Value
??? byte {wings_name} 0 - 100
byte wing_speed 0 - 25,500
(0 - 255) * 100

Servo

setServoAngle

ID 0x70
Direction Client -> Server
Size {servo_count} bytes
Byte ID Data Type Name Value
??? byte {servo_name} 0 - 255

getServoAngle (request)

ID 0x71
Direction Client -> Server
Size 0 bytes

getServoAngle (response)

ID 0x72
Direction Server -> Client
Size {servo_count} bytes
Byte ID Data Type Name Value
??? byte {servo_name} 0 - 255

Inside Fursuit

In order to make everything smooth, I decided to use multiple microprocessors (Arduino Micro). Arduino has build-in Serial which we will use for communication (Serial.available() for available bytes).
Serial Port has different speed. Most common speed is 9,600 but for us, faster is better so we will use 115,200 which is fastest which Arduino supports.
#if defined(__AVR_ATmega32U4__) #define Communication Serial1 #define CommunicationEvent serialEvent1 #else #define Communication Serial #define CommunicationEvent serialEvent #endif
Because we want to use on-board Serial and it is different some boards, we will define "alias". Serial is on Arduino Uno (and derives), Serial1 is on Arduino Leonardo (and derives as Arduino Micro) because ATmega32U4 has Serial for USB communication.
void setup() { Communication.begin(115200); }
We also need to specify the speed of Serial Port. Thanks to our alias, Communication is Serial or Serial1 based on what we need.

The #define also defines CommunicationEvent which is name of function which is called when we receive data (byte) over Serial. It is called Serial Event but when you look at Arduino page, you can read that it does not work on Leonardo and Micro but it does not apply on serialEvent1().
You can check it yourself by code below. Connect pins RX (0) and TX (1) together and run code below. Then comment out the and try it again. First time it should work normally (as Serial.write()), second time it should not work.
void setup() { // put your setup code here, to run once: Serial.begin(9600); Serial1.begin(9600); } void serialEvent1() { Serial.write(Serial1.read());//COMMENT ME } void loop() { // put your main code here, to run repeatedly: Serial1.write('0'); delay(1000); }

The protocol itself is simple - just send raw data specified pin. Each unit has its own pin.

There is one exception - Servo and LED Control. It is because Arduino Micro has only one hardware Serial.