// Function prototypes for interface layer voidinterface_init(void); voidinterface_process_usb_data(void); // Process data received from USB virtual serial port voidinterface_send_response(uint8_t command_id, uint8_t status_code, uint8_t *data, uint8_t data_length);
// Define hardware pin configurations #define LED_PIN 0 // Example GPIO pin for LED #define RS485_TX_EN_PIN 1 // Example GPIO pin for RS-485 TX enable #define RS485_RX_EN_PIN 2 // Example GPIO pin for RS-485 RX enable (if separate enable pins are used)
// Define UART baudrate for Dynamixel communication #define DYNAMIXEL_BAUDRATE 1000000 // Example baudrate (1Mbps)
// Define servo IDs (you can configure this based on your setup) #define SERVO_ID_1 1 #define SERVO_ID_2 2 #define SERVO_ID_3 3
// Dummy GPIO and UART implementations for demonstration. // In a real project, you would use microcontroller-specific HAL libraries.
voidhal_gpio_init(void) { // Initialize GPIO peripheral // Configure LED_PIN as output // Configure RS485_TX_EN_PIN and RS485_RX_EN_PIN as output (if needed) // ... (Microcontroller specific GPIO initialization) // For demonstration, we'll just print a message. printf("HAL GPIO initialized\n"); }
voidhal_gpio_set_pin_output(uint8_t pin) { // Set GPIO pin as output // ... (Microcontroller specific GPIO configuration) printf("HAL GPIO pin %d set as output\n", pin); }
voidhal_gpio_set_pin_high(uint8_t pin) { // Set GPIO pin high // ... (Microcontroller specific GPIO output high) printf("HAL GPIO pin %d set high\n", pin); }
voidhal_gpio_set_pin_low(uint8_t pin) { // Set GPIO pin low // ... (Microcontroller specific GPIO output low) printf("HAL GPIO pin %d set low\n", pin); }
voidhal_uart_init(uint32_t baudrate) { // Initialize UART peripheral with given baudrate // Configure UART for 8N1, no flow control // ... (Microcontroller specific UART initialization) // For demonstration, use standard printf/scanf for UART simulation printf("HAL UART initialized at %lu bps\n", baudrate); }
voidhal_uart_send_byte(uint8_t data) { // Send a byte via UART // ... (Microcontroller specific UART send byte) putchar(data); // For demonstration, use putchar }
uint8_thal_uart_receive_byte(void) { // Receive a byte from UART (blocking) // ... (Microcontroller specific UART receive byte) return getchar(); // For demonstration, use getchar }
boolhal_uart_data_available(void) { // Check if data is available in UART receive buffer // ... (Microcontroller specific UART data available check) // For demonstration, always assume data is available (for simple testing) returntrue; }
voidhal_uart_enable_rs485_tx(void) { // Enable RS-485 transmit mode (e.g., using TX_EN pin) hal_gpio_set_pin_high(RS485_TX_EN_PIN); hal_gpio_set_pin_low(RS485_RX_EN_PIN); // Disable RX if separate enable pins are used printf("HAL UART RS485 TX enabled\n"); }
voidhal_uart_enable_rs485_rx(void) { // Enable RS-485 receive mode (e.g., using RX_EN pin) hal_gpio_set_pin_low(RS485_TX_EN_PIN); hal_gpio_set_pin_high(RS485_RX_EN_PIN); // Enable RX if separate enable pins are used printf("HAL UART RS485 RX enabled\n"); }
voidhal_timer_init(void) { // Initialize timer for delay functions // ... (Microcontroller specific timer initialization) printf("HAL Timer initialized\n"); }
voidhal_delay_ms(uint32_t ms) { // Delay for specified milliseconds // ... (Microcontroller specific delay implementation) // For demonstration, use a simple loop (not accurate for real-time systems) volatileuint32_t count; for (count = 0; count < ms * 10000; count++); // Adjust loop count for desired delay printf("HAL Delay %lu ms\n", ms); }
// Read ID, Length, Instruction, Parameters, Checksum if (hal_uart_data_available()) packet->id = hal_uart_receive_byte(); elsereturnfalse; if (hal_uart_data_available()) packet->length = hal_uart_receive_byte(); elsereturnfalse; if (hal_uart_data_available()) packet->instruction = hal_uart_receive_byte(); elsereturnfalse;
if (packet->length > 2) { for (int i = 0; i < packet->length - 2; i++) { if (hal_uart_data_available()) packet->parameters[i] = hal_uart_receive_byte(); elsereturnfalse; } }
if (hal_uart_data_available()) packet->checksum = hal_uart_receive_byte(); elsereturnfalse;
switch (command_id) { case CMD_SET_SERVO_POSITION: if (param_length == 3) { servo_id = parameters[0]; position = (parameters[2] << 8) | parameters[1]; // Position is 2 bytes result = dynamixel_set_goal_position(servo_id, position); } else { interface_send_response(command_id, STATUS_INVALID_PARAMETER, NULL, 0); return; } break;
case CMD_SET_SERVO_SPEED: if (param_length == 3) { servo_id = parameters[0]; speed = (parameters[2] << 8) | parameters[1]; // Speed is 2 bytes result = dynamixel_set_moving_speed(servo_id, speed); } else { interface_send_response(command_id, STATUS_INVALID_PARAMETER, NULL, 0); return; } break;
case CMD_GET_SERVO_POSITION: if (param_length == 1) { servo_id = parameters[0]; if (dynamixel_get_present_position(servo_id, &position)) { uint8_t data[2]; data[0] = position & 0xFF; data[1] = (position >> 8) & 0xFF; interface_send_response(command_id, STATUS_OK, data, 2); return; // Return here to avoid default error response } else { result = false; // Get position failed } } else { interface_send_response(command_id, STATUS_INVALID_PARAMETER, NULL, 0); return; } break;
case CMD_GET_SERVO_SPEED: if (param_length == 1) { servo_id = parameters[0]; if (dynamixel_get_present_speed(servo_id, &speed)) { uint8_t data[2]; data[0] = speed & 0xFF; data[1] = (speed >> 8) & 0xFF; interface_send_response(command_id, STATUS_OK, data, 2); return; // Return here to avoid default error response } else { result = false; // Get speed failed } } else { interface_send_response(command_id, STATUS_INVALID_PARAMETER, NULL, 0); return; } break;
case CMD_PING_SERVO: if (param_length == 1) { servo_id = parameters[0]; result = dynamixel_ping(servo_id); } else { interface_send_response(command_id, STATUS_INVALID_PARAMETER, NULL, 0); return; } break;
case CMD_RESET_SERVO: // Reset servo command handling (implementation depends on servo model and reset procedure) interface_send_response(command_id, STATUS_ERROR, NULL, 0); // Not implemented yet return;
voidinterface_init(void) { printf("Interface layer initialized\n"); hal_uart_init(DYNAMIXEL_BAUDRATE); // Initialize UART for Dynamixel communication hal_gpio_init(); // Initialize GPIOs hal_gpio_set_pin_high(LED_PIN); // Turn on LED to indicate power on
// Initialize RS-485 direction control (set to receive mode initially) hal_uart_enable_rs485_rx(); }
voidinterface_process_usb_data(void) { while (hal_uart_data_available()) { // Check for data from USB virtual serial port (using UART simulation for demo) uint8_t data = hal_uart_receive_byte(); // Simulate reading from USB usb_receive_buffer[usb_receive_index++] = data;
if (usb_receive_index >= USB_BUFFER_SIZE) { usb_receive_index = 0; // Buffer overflow protection (in real application, handle overflow properly) printf("USB receive buffer overflow!\n"); }
// Simple command parsing example: Command format: [Command ID][Parameter Length][Parameters...] if (usb_receive_index >= 2) { // Wait for at least command ID and length uint8_t command_id = usb_receive_buffer[0]; uint8_t param_length = usb_receive_buffer[1];
if (usb_receive_index >= 2 + param_length) { // Wait for all parameters app_process_command(command_id, &usb_receive_buffer[2], param_length); usb_receive_index = 0; // Reset buffer after processing command } } } }
// Set goal position for servo 1 position = 1023; // Example position printf("Setting servo %d goal position to %u...\n", SERVO_ID_1, position); if (dynamixel_set_goal_position(SERVO_ID_1, position)) { printf("Servo %d goal position set successfully!\n", SERVO_ID_1); } else { printf("Servo %d goal position set failed!\n", SERVO_ID_1); }
hal_delay_ms(500);
// Get present position of servo 1 printf("Getting servo %d present position...\n", SERVO_ID_1); if (dynamixel_get_present_position(SERVO_ID_1, &position)) { printf("Servo %d present position: %u\n", SERVO_ID_1, position); } else { printf("Servo %d get present position failed!\n", SERVO_ID_1); }
hal_delay_ms(500);
// Set moving speed for servo 1 speed = 500; // Example speed printf("Setting servo %d moving speed to %u...\n", SERVO_ID_1, speed); if (dynamixel_set_moving_speed(SERVO_ID_1, speed)) { printf("Servo %d moving speed set successfully!\n", SERVO_ID_1); } else { printf("Servo %d moving speed set failed!\n", SERVO_ID_1); }
hal_delay_ms(500);
// Get present speed of servo 1 printf("Getting servo %d present speed...\n", SERVO_ID_1); if (dynamixel_get_present_speed(SERVO_ID_1, &speed)) { printf("Servo %d present speed: %u\n", SERVO_ID_1, speed); } else { printf("Servo %d get present speed failed!\n", SERVO_ID_1); }
printf("--- Dynamixel Function Tests End ---\n"); }
通过不断地改进和完善,这个低成本的Dynamixel舵机电源转换接口将会成为一个可靠、高效、易用的产品,真正实现“抵制暴利”的目标。 Error executing command: Traceback (most recent call last): File “/home/tong/bin/desc_img3.py”, line 73, in for chunk in client.models.generate_content_stream( File “/home/tong/.local/lib/python3.10/site-packages/google/genai/models.py”, line 3722, in generate_content_stream for response_dict in self.api_client.request_streamed( File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 344, in request_streamed for chunk in session_response.segments(): File “/home/tong/.local/lib/python3.10/site-packages/google/genai/_api_client.py”, line 133, in segments yield json.loads(str(chunk, ‘utf-8’)) File “/usr/lib/python3.10/json/init.py”, line 346, in loads return _default_decoder.decode(s) File “/usr/lib/python3.10/json/decoder.py”, line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File “/usr/lib/python3.10/json/decoder.py”, line 353, in raw_decode obj, end = self.scan_once(s, idx) json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)