-
Notifications
You must be signed in to change notification settings - Fork 8
Controller board
The self-o-mat kits provided by x-tech UG include a controller board.
The Arduino-based board
- connects the arcade button and the LED ring (with 16 LEDs as default; other number of LEDs can be used and configured in the web-app) to a Raspberry Pi single board computer and
- can be used to power the screen and the Raspberry Pi and connects the on/off switch.
The communication interface between the Arduino and the Raspberry Pi is a serial interface, see details below.
The original board is based on an ATmega328 MCU based Arduino Nano.
Here it the pinout used by the firmware:
Pin | Alias | Function | Input/Output | Connection |
---|---|---|---|---|
2 | PIN_BUTTON |
Trigger Button | Input | Connect trigger button with a pull-up resistor |
3 | PIN_SWITCH |
ON/OFF Switch | Input | Connect ON/OFF switch with a pull-up or pull-down resistor. Pin is active low: connection to GND will switch on, connection to 5V will switch off. If not needed, connect to GND for always enabled. |
4 | PIN_LED |
NeoPixel data pin | Output | To NeoPixel data input |
7 | PIN_FLASH_CAM_TRIGGER |
Camera flash trigger | Input | Flash trigger from camera (probably only for older revisions) |
8 | PIN_ON |
POWER | Output | Can be used to control PC/screen power. Connect PC/screen via relay or leave open if unused |
9 | PIN_LED_OFF |
NeoPixel dummy data pin? | not configured | Set as NeoPixel pin in OffState
|
11 | PIN_FLASH_ON |
Flash enable signal | Output | GPIO pin to switch on Flash on custom PCB (probably only for older revisions), initialized to LOW
|
19 | PIN_LEVEL_SHIFTER_OE |
Output | ||
20 | PIN_STATUS |
Output |
In custom setups it is required to connect at least PIN_BUTTON
and PIN_SWITCH
and also recommended (due to user experience) to also connect PIN_LED
. All other pins are optional in such a setup.
The pin definitions can be found in globals.h.
Please take care when changing these as there may be dependencies on PCBs/hard-wiring!
Please also note that the Fritzing schematic shows resistors with a value of 220 Ohms (red-red-brown color coding). Please choose a higher value for those pull-up/down resistors (around 10kOhms should be ok).
The serial interface uses a baudrate of 38400.
The communication between the Arduino and the Raspberry Pi is encoded with Consistent Overhead Byte Stuffing (COBS). The null/zero byte (0x00
) cannot be used as delimiter because of issues with the boot loader. This is why the space character (0x20
) has been chosen. For packet decoding and encoding the PacketSerial Arduino library is used. The implementation uses Arduino's default Serial
stream. All Arduino boards have at least one serial port. On Uno, Nano, Mini, and Mega, pins 0 and 1 are used for communication with the computer (in this case the Raspberry Pi SBC).
Basically each sent packet starts with a command byte (see the list below) and optionally some data bytes. The receiver reads the first byte and then decides how many data bytes are needed as an argument (for many commands no data is needed). Then it checks if enough data is present and reads the data.
For example the "accept agreement" command simply consists of the command 'a' followed by a space character ' '.
List of commands, command arguments and expected responses:
- identification: send 'i' (encodes as "\2i "), expect 'b' as response
- heartbeat: send '.'
- enable/disable watchdog: send '!' and one argument byte (enable/disable)
- signal picture taken: send 'k'
- trigger flash: '#'
- signal update mode: 'f', expect 'F' as immediate response and finally 'a'
- signal print in progress: 'p'; may receive 'c' when button has been pressed to cancel print
- signal agreement is shown: 'a' (no command arguments), expect 'A' as immediate response and finally 'a'
- enable/disable stress test: send 'S'/'s' (not supported by firmware, is it?)
- signal remote trigger: 't', do not expect any response
- query settings from board: send '?', expect settings as response (prefixed with '$') or "E1"/"E2"/"E3" on error
- write settings to board: send '$' followed by settings sequence, expect 'k' as response
- move LED ring light offset to the right: send '>', expect current settings as response (prefixed with '$')
- move LED ring light offset to the left: send '<', expect current settings as response (prefixed with '$')
Settings relevant for using the controller board (i.e. hardware related settings, see list below) are stored in and read from the Arduino's EEPROM using Arduino's EEPROM Library.
The "write settings" command consists of a '$' byte and is followed by sizeof(settings)
bytes of data. The settings data type is a struct which holds all settings of the self-o-mat controller board. The last two bytes of the struct are used as CRC16 checksum ("false CCITT") - and calculated using Frank Bösing's FastCRC library. Finally a space character ' ' needs to be sent in order to finalize the packet.
#pragma pack(push, 1)
struct settings {
uint8_t ledTypeIndex;
uint8_t ledCount;
uint8_t ledOffset;
uint16_t countDownMillis;
uint32_t flashDurationMicros;
uint8_t flashMode;
uint8_t maxLedBrightness;
uint16_t crcChecksum;
} __attribute__((packed)) settings;
#pragma pack(pop)
Two instances of type settings
are declared and initialized inside of Arduino/SelfomatController/globals.cpp:
struct settings settings = {0};
struct settings default_settings = {
.ledTypeIndex = 0, // RGB
.ledCount = 16, // Default for our box
.ledOffset = 0, // We can't know this
.countDownMillis = 3000, // Seems reasonable
.flashDurationMicros = 10000,
.flashMode = 0,
.maxLedBrightness = 255,
.crcChecksum = 0
};
The firmware is located in ./Arduino.
The firmware basically implements a finite state machine. It reacts on different inputs (button press, ON/OFF switch level, the camera's flash trigger, inputs via the serial interface) and controls different outputs (mainly the LED ring light, an optional PCB flash, replies via the serial interface).
(Note: The state diagram is WIP; it is documented as PlantUML diagram and will be part of the repository.)
In order to build the Arduino sketch, an installation of the Arduino IDE is required.
Building the Arduino sketch yields the following error message:
globals.h:4:10: fatal error: Adafruit_NeoPixel.h: No such file or directory
#include <Adafruit_NeoPixel.h>
^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
exit status 1
Adafruit_NeoPixel.h: No such file or directory
You forgot to add the Adafruit NeoPixel library. Select Tools > Manage Libraries... from the menu. Search for "Adafruit NeoPixel", select the correct library and click the Install button.
Building the Arduino sketch yields the following error message:
BusyState.cpp:4:10: fatal error: PinChangeInterrupt.h: No such file or directory
#include "PinChangeInterrupt.h"
^~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
exit status 1
PinChangeInterrupt.h: No such file or directory
You forgot to add the PinChangeInterrupt library by NicoHood. Select Tools > Manage Libraries... from the menu. Search for "PinChangeInterrupt", select the correct library and click the Install button. (See also: https://github.com/NicoHood/PinChangeInterrupt)