Difference between revisions of "Fire Pong/Interfaces/Puffer Control"

From Nottinghack Wiki
Jump to navigation Jump to search
 
(3 intermediate revisions by one other user not shown)
Line 1: Line 1:
 +
NOTE: since this document was prepared, there may have been alterations to the data structure / list of message types.  The canonical source of information is now the [https://github.com/matthewg42/fire_pong/blob/master/src/arduino/lib/fire_pong/FpEvent.h source for the FpEvent class] [[User:Mousetad|Mouse]] ([[User talk:Mousetad|talk]]) 09:00, 4 September 2016 (UTC)
 +
 +
 
=== Purpose ===
 
=== Purpose ===
  
Line 4: Line 7:
  
  
=== Requirements ===
+
=== Overview ===
  
 
* All puffers on a serial bus, each with ID mask (see below)
 
* All puffers on a serial bus, each with ID mask (see below)
* Serial bus params TBD, but probably slowish with error correction if possible because interference from sparkers:
+
* One "master" on the bus - it is the only thing which writes to the bus
** RS232 because Mouse has a bunch of MAX3232 converters
+
* Up to 32 "clients" on the bus, each with a unique address which is an integer which is 2**n, where 1 <= n <= 32
** parity & ECC
+
* Master writes packets which each represent an Event, which may be of many types, e.g. "puff", "halt", "display"
* Only control box writes to bus
+
* Clients elect to process one or more event types
* Puffer events are sent in real time
+
* Serial bus params TBD, but probably slowish with as much error correction as possible because of interference from sparkers
** Addressed by puffer ID
+
* Only well-formed event packets are processed by clients to prevent accidental firings due to corrupted packets
** With duration argument
+
* Packets are processed immediately by clients
** Multiple IDs in a single request?
+
* Non-well formed packets silently dropped
 +
** Packets start with a two-byte "magic" code
 +
** Packets ends with one-byte CRC8 of the rest of the packet (excluding magic)
 +
** Packets have different types and can have different payloads (e.g. the "puff" type has a duration as a payload, whereas a "display" type has a string payload)
 +
* Client addresses are 2**n values - there may be 32 clients on the bus at a time
 +
* Multiple clients can be addressed in a single packet
  
=== IDs ===
+
=== Packet Structure ===
  
* Each puffer has an '''ID mask''', which is:
+
==== Magic ====
** a 32-bit unsigned integer (uint32_t from stdint.h)
+
 
** little endian  
+
* Is used by clients to spot the beginning of a packet
** mask with a single bit set, i.e. 0x00000001,  0x00000002, 0x00000004, 0x00000008, ..., 0x80000000
+
* Is two little-endian uint8_t bytes, which equate to "fP"
* Requests include an '''ID set''', which is:
+
 
** a 32-bit unsigned integer (uint32_t from stdint.h)
+
==== Client IDs ====
** little endian
+
 
** mask with one or more bits set e.g. 0x00003001, corresponding to ID masks 0x00000001, 0x00001000, and 0x00002000,  
+
* Little endian uint32_t
 +
* Each client's has a mask with a single bit set, i.e. 0x00000001,  0x00000002, 0x00000004, 0x00000008, ..., 0x80000000
 +
* In a packet, the client ID is an '''ID set''', which is one or more masks logically OR'd together set e.g. 0x00003001, corresponds to ID masks 0x00000001, 0x00001000, and 0x00002000,  
 +
* "Broadcast" packets may be constructed by setting the ID to 0xffffffff
 +
 
 +
==== Event Types ====
 +
 
 +
* Enumerated event type (see below for details):
 +
** 0: HALT (safely stop processing events and wait for a reset)
 +
** 1: RESET (start processing events again)
 +
** 2: SPARK only
 +
** 3: SOLENOID only
 +
** 4: PUFF (begin sequence)
 +
** 5: DISPLAY (a string / data)
 +
* Little endian uint8_t
 +
 
 +
==== Payload Length ====
 +
 
 +
* Little endian uint8_t number of bytes in payload data - may be 0, and will depend on event type
 +
 
 +
==== Payload Data ====
 +
 
 +
* Array of little endian uint8_t's of length "payload length" (may be 0)
 +
* Actual meaning of data is defined by the event type
 +
 
 +
==== Checksum ====
 +
 
 +
* Little endian uint8_t CRC8 checksum of the rest of the packet (excluding magic)
 +
* CRC polynomial X^8 + X^5 + X^4 + X^0
 +
* Implementation from [https://github.com/develersrl/bertos/blob/master/bertos/algo/crc8.c here]
  
 
=== Event Types ===
 
=== Event Types ===
* Enumerated event type:
 
** 0: STOP (requires manual reset)
 
** 1: Spark/ignite only
 
** 2: Puff sequence
 
** other: undefined (do nothing)
 
* 8-bit unsigned integer (uint8_t from stdint.h)
 
* little endian
 
  
=== Durations ===
+
==== HALT events ====
 +
 
 +
The HALT event tells a client to immediately stop what it is doing, leaving itself in a safe state (i.e. close solenoid valves and shut off sparkers). A halted client will not process any events except RESET.  All safety critical clients (i.e. puffers) must handle the HALT event.
 +
 
 +
Halt events are always sent many times over several hundred milliseconds to prevent packet corruption.  They will likely be broadcast to all clients on the bus.
 +
 
 +
===== Payload =====
 +
 
 +
* There is no payload for the HALT event, i.e.
 +
* Payload Length = 0
 +
* Payload Data = []
  
* A time in milliseconds for a puffer solenoid valve to be open for
+
==== RESET events ====
* Typically 100 or 150 for small puffers
 
* Between 100 and 2000ms for large puffers (?)
 
* 16-bit unsigned integer (uint16_t from stdint.h)
 
* little endian
 
  
=== Checksum ===
+
Clients which are in a HALTed state may be reset to processing events normally by sending them a RESET packet
  
Because of the sparkers, we're operating in a noisy environment, so we need error detection so that we don't end up running too many sparkers at once (and causing too much current draw).
+
===== Payload =====
  
* A checksum value is a 8-bit unsigned integer which is set the the CRC8 checksum of the other seven bytes of data in order, as calculated by the CRC polynomial X^8 + X^5 + X^4 + X^0.
+
* There is no payload for the RESET event, i.e.
* Implementation from [https://github.com/develersrl/bertos/blob/master/bertos/algo/crc8.c here]
+
* Payload Length = 0
 +
* Payload Data = []
 +
 
 +
==== SPARK event ====
 +
 
 +
This event instructs a client to enable a sparker for a specified duration.
 +
 
 +
===== Payload =====
 +
 
 +
* The payload is to be interpreted as a duration for a spark in milliseconds
 +
* Payload Length = 2
 +
* Payload Data = duration in milliseconds (cast to a uint16_t)
 +
 
 +
==== SOLENOID event ====
 +
 
 +
This event instructs a client to enable a solenoid (i.e. gas valve) for a specified duration.
 +
 
 +
===== Payload =====
 +
 
 +
* The payload is to be interpreted as a duration for the solenoid valve to be open in milliseconds
 +
* Payload Length = 2
 +
* Payload Data = duration in milliseconds (cast to a uint16_t)
 +
 
 +
==== PUFF event ====
 +
 
 +
This event instructs the client to begin a puff sequence.
 +
 
 +
===== Payload =====
 +
 
 +
* The payload is to be interpreted as a duration for the main puff in milliseconds (typically ~100)
 +
* Payload Length = 2
 +
* Payload Data = duration in milliseconds (cast to a uint16_t)
 +
 
 +
==== DISPLAY event ====
 +
 
 +
This event instructs the client to display text. This event type is designed for use with the game display board client only.
 +
 
 +
===== Payload =====
  
=== Events ===
+
* The payload is a variable length string of characters
* Events are sent in real time and processed immediately by all puffer controllers on the bus
+
* Payload Length = 1 .. MAX_PAYLOAD_SIZE
* An event consists of an '''ID set''', and '''Event Type''', a '''Duration''' and a check byte
+
* Payload Data = A string to be displayed
* No acknowledgement is required - this is a broadcast only protocol
 
  
 
==== Example C code ====
 
==== Example C code ====
Line 60: Line 132:
 
     #include <stdint.h>
 
     #include <stdint.h>
 
      
 
      
     typedef struct PufferEvent {
+
     typedef struct FPEvent {
 
         uint32_t id_set;
 
         uint32_t id_set;
         uint8_t type;
+
         uint8_t type;
         uint16_t duration;
+
         uint8_t payload_length;
 +
        uint8_t payload[MAX_PAYLOAD_SIZE];
 
         uint8_t checksum;
 
         uint8_t checksum;
 
     } t_PufferEvent;
 
     } t_PufferEvent;

Latest revision as of 11:51, 5 February 2019

NOTE: since this document was prepared, there may have been alterations to the data structure / list of message types. The canonical source of information is now the source for the FpEvent class Mouse (talk) 09:00, 4 September 2016 (UTC)


Purpose

This interface defines how the main game control unit signals other parts of the system to set off the various puffers in the system.


Overview

  • All puffers on a serial bus, each with ID mask (see below)
  • One "master" on the bus - it is the only thing which writes to the bus
  • Up to 32 "clients" on the bus, each with a unique address which is an integer which is 2**n, where 1 <= n <= 32
  • Master writes packets which each represent an Event, which may be of many types, e.g. "puff", "halt", "display"
  • Clients elect to process one or more event types
  • Serial bus params TBD, but probably slowish with as much error correction as possible because of interference from sparkers
  • Only well-formed event packets are processed by clients to prevent accidental firings due to corrupted packets
  • Packets are processed immediately by clients
  • Non-well formed packets silently dropped
    • Packets start with a two-byte "magic" code
    • Packets ends with one-byte CRC8 of the rest of the packet (excluding magic)
    • Packets have different types and can have different payloads (e.g. the "puff" type has a duration as a payload, whereas a "display" type has a string payload)
  • Client addresses are 2**n values - there may be 32 clients on the bus at a time
  • Multiple clients can be addressed in a single packet

Packet Structure

Magic

  • Is used by clients to spot the beginning of a packet
  • Is two little-endian uint8_t bytes, which equate to "fP"

Client IDs

  • Little endian uint32_t
  • Each client's has a mask with a single bit set, i.e. 0x00000001, 0x00000002, 0x00000004, 0x00000008, ..., 0x80000000
  • In a packet, the client ID is an ID set, which is one or more masks logically OR'd together set e.g. 0x00003001, corresponds to ID masks 0x00000001, 0x00001000, and 0x00002000,
  • "Broadcast" packets may be constructed by setting the ID to 0xffffffff

Event Types

  • Enumerated event type (see below for details):
    • 0: HALT (safely stop processing events and wait for a reset)
    • 1: RESET (start processing events again)
    • 2: SPARK only
    • 3: SOLENOID only
    • 4: PUFF (begin sequence)
    • 5: DISPLAY (a string / data)
  • Little endian uint8_t

Payload Length

  • Little endian uint8_t number of bytes in payload data - may be 0, and will depend on event type

Payload Data

  • Array of little endian uint8_t's of length "payload length" (may be 0)
  • Actual meaning of data is defined by the event type

Checksum

  • Little endian uint8_t CRC8 checksum of the rest of the packet (excluding magic)
  • CRC polynomial X^8 + X^5 + X^4 + X^0
  • Implementation from here

Event Types

HALT events

The HALT event tells a client to immediately stop what it is doing, leaving itself in a safe state (i.e. close solenoid valves and shut off sparkers). A halted client will not process any events except RESET. All safety critical clients (i.e. puffers) must handle the HALT event.

Halt events are always sent many times over several hundred milliseconds to prevent packet corruption. They will likely be broadcast to all clients on the bus.

Payload
  • There is no payload for the HALT event, i.e.
  • Payload Length = 0
  • Payload Data = []

RESET events

Clients which are in a HALTed state may be reset to processing events normally by sending them a RESET packet

Payload
  • There is no payload for the RESET event, i.e.
  • Payload Length = 0
  • Payload Data = []

SPARK event

This event instructs a client to enable a sparker for a specified duration.

Payload
  • The payload is to be interpreted as a duration for a spark in milliseconds
  • Payload Length = 2
  • Payload Data = duration in milliseconds (cast to a uint16_t)

SOLENOID event

This event instructs a client to enable a solenoid (i.e. gas valve) for a specified duration.

Payload
  • The payload is to be interpreted as a duration for the solenoid valve to be open in milliseconds
  • Payload Length = 2
  • Payload Data = duration in milliseconds (cast to a uint16_t)

PUFF event

This event instructs the client to begin a puff sequence.

Payload
  • The payload is to be interpreted as a duration for the main puff in milliseconds (typically ~100)
  • Payload Length = 2
  • Payload Data = duration in milliseconds (cast to a uint16_t)

DISPLAY event

This event instructs the client to display text. This event type is designed for use with the game display board client only.

Payload
  • The payload is a variable length string of characters
  • Payload Length = 1 .. MAX_PAYLOAD_SIZE
  • Payload Data = A string to be displayed

Example C code

   #include <stdint.h>
   
   typedef struct FPEvent {
       uint32_t id_set;
       uint8_t type;
       uint8_t payload_length;
       uint8_t payload[MAX_PAYLOAD_SIZE];
       uint8_t checksum;
   } t_PufferEvent;