51 const std::vector<daq::PWMActuatorCommand>&
commands);
63 Serial.println(
"Starting Actuator Testing with Ethernet...");
69 Serial.println(
"Initializing current sense pins...");
74 Serial.print(
"Current sense sensor ");
78 Serial.println(
") initialized");
84 esp_read_mac(
mac, ESP_MAC_ETH));
86 Serial.print(
"Generated unique MAC address: ");
87 for (
int i = 0; i < 6; i++) {
97 Serial.println(
"Initializing Ethernet...");
114 Serial.print(
"Ethernet initialized. IP: ");
116 Serial.print(
"Link Status: ");
117 if (
Ethernet.linkStatus() == LinkON) {
118 Serial.println(
"Connected");
119 }
else if (
Ethernet.linkStatus() == LinkOFF) {
120 Serial.println(
"Disconnected");
122 Serial.println(
"Unknown");
125 Serial.print(
"Listening for actuator commands on UDP port: ");
127 Serial.println(
"Setup complete!");
132 int packetSize =
udp.parsePacket();
133 if (packetSize > 0) {
140 daq::PacketHeader* header = (daq::PacketHeader*)
packetBuffer;
144 daq::PacketHeader parsedHeader;
145 std::vector<daq::ActuatorCommand>
commands;
149 Serial.print(
"Received actuator command packet with ");
151 Serial.println(
" commands");
156 "Error: Failed to parse actuator command packet");
158 }
else if (header->packet_type ==
161 daq::PacketHeader parsedHeader;
162 std::vector<daq::PWMActuatorCommand>
commands;
166 Serial.print(
"Received PWM actuator command packet with ");
168 Serial.println(
" commands");
173 "Error: Failed to parse PWM actuator command packet");
187 unsigned long currentTime =
millis();
195 Serial.println(
"Initializing actuators...");
202 Serial.print(
"Warning: Invalid actuator ID ");
210 Serial.print(
"Actuator ");
214 Serial.println(
") set to OFF");
217 Serial.println(
"All actuators initialized to OFF state");
233 if (cmd.actuator_id < 1 || cmd.actuator_id >
NUM_ACTUATORS) {
234 Serial.print(
"Warning: Invalid actuator ID: ");
235 Serial.println(cmd.actuator_id);
242 Serial.print(
"Warning: Failed to get pin for actuator ID: ");
243 Serial.println(cmd.actuator_id);
248 uint8_t new_state = (cmd.actuator_state != 0) ? 1 : 0;
258 Serial.print(
"Actuator ");
259 Serial.print(cmd.actuator_id);
260 Serial.println(
" PWM interrupted by digital command");
268 Serial.print(
"Actuator ");
269 Serial.print(cmd.actuator_id);
272 Serial.print(
") set to ");
273 Serial.println(new_state ?
"ON" :
"OFF");
275 Serial.print(
"Actuator ");
276 Serial.print(cmd.actuator_id);
277 Serial.println(
" already in requested state");
283 const std::vector<daq::PWMActuatorCommand>&
commands) {
286 if (cmd.actuator_id < 1 || cmd.actuator_id >
NUM_ACTUATORS) {
287 Serial.print(
"Warning: Invalid actuator ID for PWM: ");
288 Serial.println(cmd.actuator_id);
294 Serial.print(
"Warning: Failed to get pin for actuator ID: ");
295 Serial.println(cmd.actuator_id);
304 Serial.print(
"Error: Actuator ");
305 Serial.print(cmd.actuator_id);
306 Serial.println(
" cannot use PWM (Channel > 7)");
314 ledcSetup(channel, cmd.frequency, 14);
315 ledcAttachPin(pin, channel);
319 uint32_t max_duty = 16383;
320 uint32_t duty = (uint32_t)(cmd.duty_cycle * (
float)max_duty);
324 ledcWrite(channel, duty);
335 Serial.print(
"Actuator ");
336 Serial.print(cmd.actuator_id);
337 Serial.print(
" PWM started: Freq=");
338 Serial.print(cmd.frequency);
339 Serial.print(
"Hz, Duty=");
340 Serial.print(cmd.duty_cycle * 100.0f);
341 Serial.print(
"%, Duration=");
342 Serial.print(cmd.duration);
348 unsigned long current_time =
millis();
351 if (current_time -
pwm_states[i].start_time >=
364 Serial.print(
"Actuator ");
366 Serial.println(
" PWM finished");
377 for (uint8_t actuator_id = 1; actuator_id <=
NUM_SENSORS; actuator_id++) {
380 Serial.print(
"Warning: Invalid current sense actuator ID: ");
381 Serial.println(actuator_id);
390 float voltage = (
static_cast<float>(adcValue) / 4095.0f) * 3.3f;
394 uint32_t voltage_bits;
395 memcpy(&voltage_bits, &voltage,
sizeof(
float));
397 chunk.add_datapoint(actuator_id, voltage_bits);
401 if (!
chunk.empty()) {
411 std::vector<daq::SensorDataChunkCollection>
chunks;
418 if (packetSize == 0) {
419 Serial.println(
"Error: Failed to create sensor data packet");
428 Serial.print(
"Sent sensor data packet: ");
432 Serial.println(
" sensors");
void digitalWrite(int, int)
#define ADC_READ_INTERVAL_MS
static EthernetClass Ethernet
void readCurrentSensePins()
void initializeActuators()
unsigned long lastAdcReadTime
PWMState pwm_states[NUM_ACTUATORS]
IPAddress staticIP(192, 168, 2, 202)
void processActuatorCommand(const std::vector< daq::ActuatorCommand > &commands)
IPAddress dns(192, 168, 2, 1)
IPAddress subnet(255, 255, 255, 0)
IPAddress receiverIP(192, 168, 2, 20)
void processPWMActuatorCommand(const std::vector< daq::PWMActuatorCommand > &commands)
IPAddress gateway(0, 0, 0, 0)
void sendSensorDataPacket()
std::vector< daq::SensorDataChunkCollection > chunks
IPAddress dns(192, 168, 2, 1)
IPAddress subnet(255, 255, 255, 0)
IPAddress staticIP(192, 168, 2, BOARD_ID_DEFAULT)
static uint8_t actuator_states[NUM_ACTUATORS]
IPAddress gateway(0, 0, 0, 0)
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]
static osMessageQueueId_t commands
static BasicJsonType::size_type array_index(const string_t &s)
int getActuatorPin(uint8_t actuator_id)
constexpr int NUM_ACTUATORS
int getCurrentSensePin(uint8_t actuator_id)
constexpr Layout Actuator_Board
size_t create_sensor_data_packet(const std::vector< SensorDataChunkCollection > &chunks, const uint8_t num_sensors, uint32_t timestamp_ms, uint8_t *buffer, size_t buffer_size)
Creates a complete Sensor Data packet in the provided buffer.
bool parse_pwm_actuator_packet(const uint8_t *buffer, size_t buffer_size, PacketHeader &header_out, std::vector< PWMActuatorCommand > &commands_out)
Parses a PWM Actuator Command packet from buffer.
bool parse_actuator_command_packet(const uint8_t *buffer, size_t buffer_size, PacketHeader &header_out, std::vector< ActuatorCommand > &commands_out)
Parses an Actuator Command packet from buffer.
Represents a single data chunk with timestamp and sensor datapoints.