149 lines
3.2 KiB
Arduino
149 lines
3.2 KiB
Arduino
/* Packet Processing */
|
|
#define PACKET_START (0x55)
|
|
#define PACKET_END (0xaa)
|
|
|
|
#define PACKET_ID_INTERRUPT (0x00)
|
|
#define PACKET_ID_MAX (199)
|
|
#define PACKET_ID_ERROR (0xff)
|
|
|
|
static byte packet[5] = { PACKET_START, 0xff, 0xff, 0xff, PACKET_END };
|
|
|
|
enum pin_functions
|
|
{
|
|
BEACON_RED = 2,
|
|
BEACON_ORANGE,
|
|
BEACON_GREEN,
|
|
BEACON_BUZZER,
|
|
|
|
ACTUATOR_1, // 6
|
|
ACTUATOR_2,
|
|
CONVEYOR_EN,
|
|
CONVEYOR_PWM,
|
|
|
|
START_BUTTON, // 10
|
|
STOP_BUTTON,
|
|
PHOTOELECTRIC_SENSOR_1,
|
|
PHOTOELECTRIC_SENSOR_2,
|
|
|
|
LED // 14
|
|
};
|
|
|
|
#define SEND_PACKET(pin, value) \
|
|
do \
|
|
{ \
|
|
packet[2] = (pin); \
|
|
packet[3] = (value); \
|
|
Serial.write(packet, sizeof(packet)); \
|
|
} while (0)
|
|
|
|
/* Utility Functions */
|
|
#define INIT_OUTPUT_PAD(pad, val) \
|
|
pinMode((pad), OUTPUT); \
|
|
digitalWrite((pad), (val))
|
|
|
|
#define INIT_PWM_PAD(pad, val) \
|
|
pinMode((pad), OUTPUT); \
|
|
analogWrite((pad), (val))
|
|
|
|
#define CHECK(expr) \
|
|
if ((expr)) \
|
|
{ \
|
|
SEND_PACKET(0xff, 0xff); \
|
|
return; \
|
|
}
|
|
|
|
/* System Initialization */
|
|
void setup()
|
|
{
|
|
/* Initialize Outputs */
|
|
INIT_OUTPUT_PAD(BEACON_RED, HIGH);
|
|
INIT_OUTPUT_PAD(BEACON_ORANGE, HIGH);
|
|
INIT_OUTPUT_PAD(BEACON_GREEN, HIGH);
|
|
|
|
INIT_OUTPUT_PAD(BEACON_BUZZER, HIGH);
|
|
|
|
INIT_OUTPUT_PAD(ACTUATOR_1, HIGH);
|
|
INIT_OUTPUT_PAD(ACTUATOR_2, HIGH);
|
|
|
|
INIT_OUTPUT_PAD(CONVEYOR_EN, HIGH);
|
|
INIT_PWM_PAD(CONVEYOR_PWM, 0);
|
|
|
|
INIT_OUTPUT_PAD(LED, HIGH);
|
|
|
|
/* Initialize Inputs */
|
|
pinMode(START_BUTTON, INPUT_PULLUP);
|
|
pinMode(STOP_BUTTON, INPUT_PULLUP);
|
|
pinMode(PHOTOELECTRIC_SENSOR_1, INPUT_PULLUP);
|
|
pinMode(PHOTOELECTRIC_SENSOR_2, INPUT_PULLUP);
|
|
|
|
/* Prepare UART port - 115200 baud rate */
|
|
Serial.begin(115200);
|
|
while (!Serial)
|
|
;
|
|
}
|
|
|
|
/* Set to 0xff to report initial state */
|
|
static byte inputStatus[4] = { 0xff, 0xff, 0xff, 0xff };
|
|
|
|
static inline compareAndReport(byte pin)
|
|
{
|
|
static byte idx;
|
|
static byte value;
|
|
|
|
idx = pin - START_BUTTON;
|
|
value = digitalRead(pin);
|
|
if (inputStatus[idx] == value)
|
|
return;
|
|
|
|
inputStatus[idx] = value;
|
|
SEND_PACKET(pin, value);
|
|
}
|
|
|
|
static inline void polling(void)
|
|
{
|
|
packet[1] = PACKET_ID_INTERRUPT;
|
|
|
|
compareAndReport(START_BUTTON);
|
|
compareAndReport(STOP_BUTTON);
|
|
compareAndReport(PHOTOELECTRIC_SENSOR_1);
|
|
compareAndReport(PHOTOELECTRIC_SENSOR_2);
|
|
}
|
|
|
|
/* Actual Main loop */
|
|
void loop()
|
|
{
|
|
polling();
|
|
|
|
/* Packet Processing */
|
|
if (Serial.available() < 5)
|
|
return;
|
|
|
|
static byte packetId;
|
|
static byte pin;
|
|
static byte value;
|
|
|
|
packet[1] = PACKET_ID_ERROR;
|
|
|
|
CHECK(Serial.read() != PACKET_START);
|
|
|
|
packetId = Serial.read();
|
|
CHECK(packetId == 0 || packetId > PACKET_ID_MAX);
|
|
|
|
pin = Serial.read();
|
|
CHECK(pin < BEACON_RED || pin > LED);
|
|
|
|
value = Serial.read();
|
|
|
|
CHECK(Serial.read() != PACKET_END);
|
|
|
|
/* Run command */
|
|
packet[1] = packetId;
|
|
|
|
if (pin == CONVEYOR_PWM)
|
|
analogWrite(pin, value);
|
|
else
|
|
digitalWrite(pin, !!value);
|
|
|
|
SEND_PACKET(pin, value);
|
|
}
|