I would like to know if it would be possible to test this code with a USB connection to my computer so that the raspberry pi pico w would be the master and my computer would be the slave.
I would also like to know if there are specific modbus libraries or if I really have to use the ones I created.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(pico_projects C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(PICO_BOARD pico_w)
pico_sdk_init()
add_executable(main
main.c
modbus.c
)
target_link_libraries(main PUBLIC
pico_stdlib
pico_cyw43_arch_none
hardware_uart
pico_multicore
)
pico_add_extra_outputs(main)
main.c :
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "modbus.h"
int main() {
stdio_init_all();
uart_config();
// Example usage of modbus_control_command function
modbus_control_command(1, 1, 255, 100);
// Example usage of modbus_read_status_1 function
modbus_read_status_1();
// Example usage of modbus_read_status_2 function
modbus_read_status_2();
return 0;
}
modbus.c:
#include "pico/stdlib.h"
#include "pico/printf.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "modbus.h"
#define UART_ID uart0
#define UART_TX_PIN 0
#define UART_RX_PIN 1
#define MODBUS_SLAVE_ADDRESS 0x4C
#define MODBUS_READ_HOLDING_REGISTERS 0x03
#define MODBUS_WRITE_MULTIPLE_REGISTERS 0x10
#define MODBUS_CONTROL_COMMAND_ADDRESS 41001
#define MODBUS_STATUS_1_ADDRESS 41101
#define MODBUS_STATUS_2_ADDRESS 41201
// UART initialization function
void uart_config() {
uart_init(UART_ID, 115200);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
uart_set_hw_flow(UART_ID, false, false);
uart_set_format(UART_ID, 8, 1, UART_PARITY_NONE);
}
// Function to calculate CRC16
uint16_t calculate_crc16(uint8_t *data, size_t length) {
uint16_t crc = 0xFFFF;
for (size_t i = 0; i < length; ++i) {
crc ^= data;
for (int j = 0; j < 8; ++j) {
if (crc & 0x0001) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
// Modbus function to handle control command
void modbus_control_command(uint8_t bus_mode, uint8_t direction, uint8_t speed, uint8_t current_limit) {
uint8_t command[] = {
MODBUS_SLAVE_ADDRESS,
MODBUS_WRITE_MULTIPLE_REGISTERS,
MODBUS_CONTROL_COMMAND_ADDRESS >> 8, MODBUS_CONTROL_COMMAND_ADDRESS & 0xFF,
0x00, 0x01, // Quantity (number of registers to write)
0x06, // Byte count
bus_mode, // Bus mode (example value)
direction, // Direction (example value)
speed, // Speed (example value)
current_limit, // Current limit (example value)
0x00, 0x00 // CRC (to be calculated)
};
size_t command_length = sizeof(command) - 2; // Excluding CRC
// Calculate CRC
uint16_t crc = calculate_crc16(command, command_length);
command[command_length++] = crc & 0xFF; // LSB
command[command_length++] = (crc >> 8) & 0xFF; // MSB
// Transmit command over UART
uart_write_blocking(UART_ID, command, command_length);
}
// Modbus function to read status 1
void modbus_read_status_1() {
uint8_t command[] = {
MODBUS_SLAVE_ADDRESS,
MODBUS_READ_HOLDING_REGISTERS,
MODBUS_STATUS_1_ADDRESS >> 8, MODBUS_STATUS_1_ADDRESS & 0xFF,
0x00, 0x06, // Quantity (number of registers to read)
0x00, 0x00 // CRC (to be calculated)
};
size_t command_length = sizeof(command) - 2; // Excluding CRC
// Calculate CRC
uint16_t crc = calculate_crc16(command, command_length);
command[command_length++] = crc & 0xFF; // LSB
command[command_length++] = (crc >> 8) & 0xFF; // MSB
// Transmit command over UART
uart_write_blocking(UART_ID, command, command_length);
}
// Modbus function to read status 2
void modbus_read_status_2() {
uint8_t command[] = {
MODBUS_SLAVE_ADDRESS,
MODBUS_READ_HOLDING_REGISTERS,
MODBUS_STATUS_2_ADDRESS >> 8, MODBUS_STATUS_2_ADDRESS & 0xFF,
0x00, 0x03, // Quantity (number of registers to read)
0x00, 0x00 // CRC (to be calculated)
};
size_t command_length = sizeof(command) - 2; // Excluding CRC
// Calculate CRC
uint16_t crc = calculate_crc16(command, command_length);
command[command_length++] = crc & 0xFF; // LSB
command[command_length++] = (crc >> 8) & 0xFF; // MSB
// Transmit command over UART
uart_write_blocking(UART_ID, command, command_length);
}
/*int main() {
stdio_init_all();
uart_config();
// Example usage of modbus_control_command function
modbus_control_command(1, 255, 100);
// Example usage of modbus_read_status_1 function
modbus_read_status_1();
// Example usage of modbus_read_status_2 function
modbus_read_status_2();
return 0;
}*/
modbus.h:
#ifndef MODBUS_H
#define MODBUS_H
#include <stdint.h>
#include <stddef.h>
// UART initialization function
void uart_config();
// Function to calculate CRC16
uint16_t calculate_crc16(uint8_t *data, size_t length);
// Modbus function to handle control command
void modbus_control_command(uint8_t bus_mode, uint8_t direction, uint8_t speed, uint8_t current_limit);
// Modbus function to read status 1
void modbus_read_status_1();
// Modbus function to read status 2
void modbus_read_status_2();
#endif // MODBUS_H
I would also like to know if there are specific modbus libraries or if I really have to use the ones I created.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
project(pico_projects C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(PICO_BOARD pico_w)
pico_sdk_init()
add_executable(main
main.c
modbus.c
)
target_link_libraries(main PUBLIC
pico_stdlib
pico_cyw43_arch_none
hardware_uart
pico_multicore
)
pico_add_extra_outputs(main)
main.c :
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "modbus.h"
int main() {
stdio_init_all();
uart_config();
// Example usage of modbus_control_command function
modbus_control_command(1, 1, 255, 100);
// Example usage of modbus_read_status_1 function
modbus_read_status_1();
// Example usage of modbus_read_status_2 function
modbus_read_status_2();
return 0;
}
modbus.c:
#include "pico/stdlib.h"
#include "pico/printf.h"
#include "hardware/uart.h"
#include "hardware/gpio.h"
#include "modbus.h"
#define UART_ID uart0
#define UART_TX_PIN 0
#define UART_RX_PIN 1
#define MODBUS_SLAVE_ADDRESS 0x4C
#define MODBUS_READ_HOLDING_REGISTERS 0x03
#define MODBUS_WRITE_MULTIPLE_REGISTERS 0x10
#define MODBUS_CONTROL_COMMAND_ADDRESS 41001
#define MODBUS_STATUS_1_ADDRESS 41101
#define MODBUS_STATUS_2_ADDRESS 41201
// UART initialization function
void uart_config() {
uart_init(UART_ID, 115200);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);
uart_set_hw_flow(UART_ID, false, false);
uart_set_format(UART_ID, 8, 1, UART_PARITY_NONE);
}
// Function to calculate CRC16
uint16_t calculate_crc16(uint8_t *data, size_t length) {
uint16_t crc = 0xFFFF;
for (size_t i = 0; i < length; ++i) {
crc ^= data;
for (int j = 0; j < 8; ++j) {
if (crc & 0x0001) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
// Modbus function to handle control command
void modbus_control_command(uint8_t bus_mode, uint8_t direction, uint8_t speed, uint8_t current_limit) {
uint8_t command[] = {
MODBUS_SLAVE_ADDRESS,
MODBUS_WRITE_MULTIPLE_REGISTERS,
MODBUS_CONTROL_COMMAND_ADDRESS >> 8, MODBUS_CONTROL_COMMAND_ADDRESS & 0xFF,
0x00, 0x01, // Quantity (number of registers to write)
0x06, // Byte count
bus_mode, // Bus mode (example value)
direction, // Direction (example value)
speed, // Speed (example value)
current_limit, // Current limit (example value)
0x00, 0x00 // CRC (to be calculated)
};
size_t command_length = sizeof(command) - 2; // Excluding CRC
// Calculate CRC
uint16_t crc = calculate_crc16(command, command_length);
command[command_length++] = crc & 0xFF; // LSB
command[command_length++] = (crc >> 8) & 0xFF; // MSB
// Transmit command over UART
uart_write_blocking(UART_ID, command, command_length);
}
// Modbus function to read status 1
void modbus_read_status_1() {
uint8_t command[] = {
MODBUS_SLAVE_ADDRESS,
MODBUS_READ_HOLDING_REGISTERS,
MODBUS_STATUS_1_ADDRESS >> 8, MODBUS_STATUS_1_ADDRESS & 0xFF,
0x00, 0x06, // Quantity (number of registers to read)
0x00, 0x00 // CRC (to be calculated)
};
size_t command_length = sizeof(command) - 2; // Excluding CRC
// Calculate CRC
uint16_t crc = calculate_crc16(command, command_length);
command[command_length++] = crc & 0xFF; // LSB
command[command_length++] = (crc >> 8) & 0xFF; // MSB
// Transmit command over UART
uart_write_blocking(UART_ID, command, command_length);
}
// Modbus function to read status 2
void modbus_read_status_2() {
uint8_t command[] = {
MODBUS_SLAVE_ADDRESS,
MODBUS_READ_HOLDING_REGISTERS,
MODBUS_STATUS_2_ADDRESS >> 8, MODBUS_STATUS_2_ADDRESS & 0xFF,
0x00, 0x03, // Quantity (number of registers to read)
0x00, 0x00 // CRC (to be calculated)
};
size_t command_length = sizeof(command) - 2; // Excluding CRC
// Calculate CRC
uint16_t crc = calculate_crc16(command, command_length);
command[command_length++] = crc & 0xFF; // LSB
command[command_length++] = (crc >> 8) & 0xFF; // MSB
// Transmit command over UART
uart_write_blocking(UART_ID, command, command_length);
}
/*int main() {
stdio_init_all();
uart_config();
// Example usage of modbus_control_command function
modbus_control_command(1, 255, 100);
// Example usage of modbus_read_status_1 function
modbus_read_status_1();
// Example usage of modbus_read_status_2 function
modbus_read_status_2();
return 0;
}*/
modbus.h:
#ifndef MODBUS_H
#define MODBUS_H
#include <stdint.h>
#include <stddef.h>
// UART initialization function
void uart_config();
// Function to calculate CRC16
uint16_t calculate_crc16(uint8_t *data, size_t length);
// Modbus function to handle control command
void modbus_control_command(uint8_t bus_mode, uint8_t direction, uint8_t speed, uint8_t current_limit);
// Modbus function to read status 1
void modbus_read_status_1();
// Modbus function to read status 2
void modbus_read_status_2();
#endif // MODBUS_H
Statistics: Posted by chico.lima — Tue Mar 12, 2024 4:44 pm