Quantcast
Channel: Raspberry Pi Forums
Viewing all articles
Browse latest Browse all 5014

SDK • Test Raspberry pi pico w C code for comunication modbus with Driver

$
0
0
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

Statistics: Posted by chico.lima — Tue Mar 12, 2024 4:44 pm



Viewing all articles
Browse latest Browse all 5014

Trending Articles