STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/**
2 * Stacklight Driver — receives STACKLIGHT_COMMAND over Ethernet/UDP, drives
3 * stack segments (active-low). Board heartbeats + firmware hash match hotfire
4 * boards; Ethernet OTA on HOTFIRE_OTA_PORT.
5 */
6
7#include <Arduino.h>
8#include <Ethernet.h>
9#include <EthernetUdp.h>
10#include <SPI.h>
11#include <STAR_EthernetOTA.h>
12#include <daq-protocol.h>
13#include <esp_mac.h>
14
15#include <cstring>
16
17#include "firmware_hash.h"
18#include "hotfire_config.h"
19#include "stacklight_pins.h"
20
21using namespace stacklight_pins;
22
23#ifndef MAX_PACKET_SIZE
24#define MAX_PACKET_SIZE 512
25#endif
26
27#ifndef SENSOR_UDP_LISTEN_PORT
28#define SENSOR_UDP_LISTEN_PORT 5005
29#endif
30
31static uint8_t board_id = BOARD_ID;
32static byte mac[6];
33static IPAddress staticIP(192, 168, 2, BOARD_ID);
34static IPAddress gateway(0, 0, 0, 0);
35static IPAddress subnet(255, 255, 255, 0);
36static IPAddress dns(192, 168, 2, 1);
38static EthernetUDP udp;
40static unsigned long lastHeartbeatMillis = 0;
41static unsigned long last_server_heartbeat_ms = 0;
43
44static void applyStacklightOutputs(uint8_t red, uint8_t yellow, uint8_t green,
45 uint8_t buzzer) {
46 digitalWrite(PIN_RED, red ? LOW : HIGH);
47 digitalWrite(PIN_YELLOW, yellow ? LOW : HIGH);
48 digitalWrite(PIN_GREEN, green ? LOW : HIGH);
49 digitalWrite(PIN_BUZZ, buzzer ? LOW : HIGH);
50}
51
68
69static void sendBoardHeartbeat() {
70 daq::BoardHeartbeatPacket hb;
71 memcpy(hb.firmware_hash, FirmwareHash::get(), 32);
72 hb.board_id = board_id;
73 hb.engine_state = last_engine_state;
74 hb.board_state = daq::BoardState::ACTIVE;
75
78 sizeof(packetBuffer));
79 if (len == 0)
80 return;
81
82 udp.beginPacket(serverIP, HOTFIRE_SERVER_PORT);
83 udp.write(packetBuffer, len);
84 udp.endPacket();
85}
86
87void setup() {
88 Serial.begin(115200);
90 Serial.println("Stacklight Driver starting...");
91
92 board_id = static_cast<uint8_t>(BOARD_ID);
93 staticIP = IPAddress(192, 168, 2, board_id);
94 Serial.print("Board ID / IP: ");
95 Serial.print(static_cast<unsigned>(board_id));
96 Serial.print(" / 192.168.2.");
97 Serial.println(static_cast<unsigned>(board_id));
98
100
101 ESP_ERROR_CHECK(esp_read_mac(mac, ESP_MAC_ETH));
102 SPI.begin(ETH_SCLK, ETH_MISO, ETH_MOSI, ETH_CS);
104 Ethernet.init(ETH_CS);
109 Serial.print("UDP listen port ");
111 otaServer.begin();
112 Serial.print("OTA TCP port ");
113 Serial.println(HOTFIRE_OTA_PORT);
114 Serial.print("Ethernet IP: ");
115 Serial.println(Ethernet.localIP());
116 Serial.flush();
117}
118
119void loop() {
120 // Blocks only if a client connects; never returns on success.
121 otaServer.poll();
123
124 int packetSize = udp.parsePacket();
125 if (packetSize > 0) {
127 int bytesRead = udp.read(packetBuffer, sizeof(packetBuffer));
128 if (bytesRead > 0 &&
129 bytesRead >= static_cast<int>(sizeof(daq::PacketHeader))) {
130 daq::PacketHeader hdr;
131 memcpy(&hdr, packetBuffer, sizeof(hdr));
132 switch (hdr.packet_type) {
134 daq::PacketHeader dummy;
135 daq::ServerHeartbeatPacket sh;
137 packetBuffer, static_cast<size_t>(bytesRead), dummy,
138 sh)) {
140 last_engine_state = sh.engine_state;
141 }
142 break;
143 }
145 daq::PacketHeader dummy;
146 daq::StacklightCommandPacket cmd;
148 packetBuffer, static_cast<size_t>(bytesRead), dummy,
149 cmd)) {
150 applyStacklightOutputs(cmd.red, cmd.yellow, cmd.green,
151 cmd.buzzer);
152 }
153 break;
154 }
155 default:
156 break;
157 }
158 }
159 }
160
161 unsigned long now = millis();
165 }
166
168}
static SerialStub Serial
Definition Arduino.h:128
#define HIGH
Definition Arduino.h:19
void pinMode(int, int)
Definition Arduino.h:46
#define OUTPUT
Definition Arduino.h:22
unsigned long millis()
Definition Arduino.h:29
#define LOW
Definition Arduino.h:20
void digitalWrite(int, int)
Definition Arduino.h:48
#define ETHERNET_INIT_DELAY_MS
#define LOOP_DELAY_MS
#define ETHERNET_BEGIN_DELAY_MS
#define BOARD_HEARTBEAT_INTERVAL_MS
#define ETHERNET_SPI_DELAY_MS
static EthernetClass Ethernet
Definition Ethernet.h:116
#define MAX_PACKET_SIZE
Definition main.h:6
#define SENSOR_UDP_LISTEN_PORT
const int IPAddress
void delay(int ms)
The OTA listener.
static unsigned long lastHeartbeatMillis
Definition main.cpp:81
static unsigned long last_server_heartbeat_ms
Definition main.cpp:59
IPAddress dns(192, 168, 2, 1)
byte mac[6]
Definition main.cpp:31
IPAddress subnet(255, 255, 255, 0)
IPAddress staticIP(192, 168, 2, BOARD_ID_DEFAULT)
IPAddress serverIP(192, 168, 2, 20)
static uint8_t board_id
Definition main.cpp:30
EthernetUDP udp
Definition main.cpp:40
IPAddress gateway(0, 0, 0, 0)
StarOTA::Server otaServer(OTA_TCP_PORT)
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]
Definition main.cpp:15
static constexpr int ETH_CS
Ball Valve Hotfire — motorized ball valve prototype board.
Definition main.cpp:53
static constexpr int ETH_SCLK
Definition main.cpp:55
static constexpr int ETH_MISO
Definition main.cpp:56
static constexpr int ETH_MOSI
Definition main.cpp:54
static StarOTA::Server otaServer(HOTFIRE_OTA_PORT)
static void initOutputs()
Definition main.cpp:52
void setup()
Definition main.cpp:87
static IPAddress dns(192, 168, 2, 1)
static IPAddress subnet(255, 255, 255, 0)
static void applyStacklightOutputs(uint8_t red, uint8_t yellow, uint8_t green, uint8_t buzzer)
Definition main.cpp:44
static daq::EngineState last_engine_state
Definition main.cpp:42
static IPAddress staticIP(192, 168, 2, BOARD_ID)
static void sendBoardHeartbeat()
Definition main.cpp:69
static IPAddress gateway(0, 0, 0, 0)
static IPAddress serverIP(192, 168, 2, HOTFIRE_SERVER_IP_OCTET_4)
void loop()
Definition main.cpp:119
#define HOTFIRE_SERVER_PORT
#define HOTFIRE_SERVER_IP_OCTET_4
#define HOTFIRE_OTA_PORT
#define BOARD_ID
const uint8_t * get()
void printTestMessage()
Bench-test helper: prints STAR_OTA_TEST_MESSAGE on a timer as.
bool parse_server_heartbeat_packet(const uint8_t *buffer, size_t buffer_size, PacketHeader &header_out, ServerHeartbeatPacket &data_out)
Parses a Server Heartbeat packet from buffer.
EngineState
Defines the overall state of the engine system.
Definition DiabloEnums.h:48
size_t create_board_heartbeat_packet(const BoardHeartbeatPacket &data, uint32_t timestamp_ms, uint8_t *buffer, size_t buffer_size)
Creates a complete Board Heartbeat packet in the provided buffer.
bool parse_stacklight_command_packet(const uint8_t *buffer, size_t buffer_size, PacketHeader &header_out, StacklightCommandPacket &data_out)
Parses a Stacklight Command packet from buffer.
Stacklight Driver PCB — GPIO assignments.
constexpr int PIN_BUZZ
constexpr int PIN_EX2
constexpr int PIN_RED
constexpr int PIN_GREEN
constexpr int PIN_EX1
constexpr int PIN_YELLOW
constexpr int PIN_EX3