
Este guia prático permitirá que você controle a velocidade de um motor através do inversor WEG CFW500 utilizando um ESP32 como mestre Modbus RTU.
1. Conexão Física (Hardware)
Para realizar a comunicação RS485, o ESP32 não possui essa interface nativamente, então é necessário um conversor.
Sugestão de Modelo de Conversor: Um modelo comum e acessível é o Módulo Conversor RS485 MAX485 TTL para RS485. Ele converte os sinais TTL (Transistor-Transistor Logic) do ESP32 para o padrão RS485.
Passo a Passo da Conexão:
- Desligue o Inversor e o ESP32: Antes de qualquer conexão, certifique-se de que o inversor CFW500 e o ESP32 estejam completamente desligados da energia para evitar danos.
- Conecte o Módulo MAX485 ao ESP32:
- VCC do MAX485 ao 3.3V do ESP32 (o ESP32 opera em 3.3V, certifique-se de que o MAX485 seja compatível com 3.3V ou use um regulador de tensão, embora a maioria dos MAX485 populares funcione bem com 3.3V).
- GND do MAX485 ao GND do ESP32.
- DI (Driver Input) do MAX485 ao TX2 do ESP32 (GPIO17).
- RO (Receiver Output) do MAX485 ao RX2 do ESP32 (GPIO16).
- DE (Driver Enable) do MAX485 a um GPIO livre do ESP32 (ex: GPIO4). Este pino controlará o modo de transmissão/recepção do MAX485.
- RE (Receiver Enable) do MAX485 ao GND do ESP32 (ou ao mesmo GPIO que o DE, mas para Modbus, geralmente o DE e RE são conectados juntos e controlados por um único pino do microcontrolador). Para simplificar, conecte DE e RE juntos a um pino do ESP32.

ESP32 conectado a um módulo MAX485
- Conecte o Módulo MAX485 ao Inversor CFW500:
- A do MAX485 ao terminal SA+ do CFW500.
- B do MAX485 ao terminal SB- do CFW500.
- GND do MAX485 ao terminal 0V ou GND do CFW500 (para ter uma referência de terra comum, embora a RS485 seja diferencial, uma conexão de terra comum pode ajudar a evitar ruídos em alguns casos).
Observação: O CFW500 possui terminais de comunicação RS485 (SA+, SB-). Consulte o manual do CFW500 para a localização exata desses terminais.
- Terminação da Rede (Opcional, mas Recomendado para Distâncias Maiores): Para evitar reflexões de sinal em longas distâncias ou em redes com vários dispositivos, é recomendado usar um resistor de terminação de 120 ohms entre A e B na última e/ou primeira ponta da rede Modbus. Para este projeto didático, pode não ser estritamente necessário se as distâncias forem curtas.
2. Parametrização do Inversor WEG CFW500
A parametrização do inversor é crucial para que ele “entenda” que será controlado via Modbus RTU. Você precisará acessar o painel do inversor ou usar o software WLP para configurá-lo.
Passo a Passo da Configuração:
- Acesse o Menu de Parâmetros: Ligue o CFW500 e navegue pelos menus para acessar os parâmetros de configuração.
- Configure os Parâmetros de Comunicação Serial:
- P200 – Endereço Modbus: Defina um endereço único para o inversor na rede Modbus (ex: 1). Este é o slaveId que você usará no código do ESP32.
- P202 – Baud Rate (Velocidade de Comunicação): Configure a velocidade de comunicação (ex: 9600 bps, 19200 bps, 38400 bps). Este valor deve ser o mesmo configurado no ESP32.
- P203 – Parity (Paridade):
- 0: Nenhuma (None)
- 1: Par (Even)
- 2: Ímpar (Odd)
- Recomendado: 0 (Nenhuma) para 8 bits de dados e 1 bit de parada.
- P204 – Stop Bits (Bits de Parada):
- 0: 1 bit
- 1: 2 bits
- Recomendado: 0 (1 bit).
- P205 – Tempo de Timeout (ms): Tempo máximo que o inversor espera por uma resposta após enviar um dado (pode manter o padrão).
- P206 – Tempo de Delay (ms): Tempo de atraso entre o envio de caracteres (pode manter o padrão).
- Configure os Parâmetros de Controle e Referência de Frequência:
- P220 – Origem do Comando RUN/STOP:
- 0: Bornes de Comando (entradas digitais)
- 1: IHM (painel do inversor)
- 2: Serial (Modbus/Fieldbus)
- Defina para 2 (Serial) para que o ESP32 possa enviar o comando RUN/STOP.
- P221 – Origem da Referência de Frequência:
- 0: Potenciômetro na IHM
- 1: Entrada Analógica (AI1)
- 2: Teclado IHM
- 3: Serial (Modbus/Fieldbus)
- Defina para 3 (Serial) para que o ESP32 possa enviar a referência de velocidade.
- P220 – Origem do Comando RUN/STOP:
Importante: Consulte o Manual de Programação do CFW500 para obter os números exatos dos parâmetros e seus valores permitidos. Os valores acima são exemplos comuns.
3. Desenvolvimento do Código no ESP32 (Arduino IDE)
Para simplificar a comunicação Modbus, utilizaremos a biblioteca ModbusMaster.
Instalação da Biblioteca:
- Abra a IDE do Arduino.
- Vá em Sketch > Incluir Biblioteca > Gerenciar Bibliotecas….
- Pesquise por “ModbusMaster” e instale a biblioteca de Doc Walker.
Código ESP32:
Este código demonstra como enviar o comando de RUN/STOP e a referência de frequência para o inversor, além de ler a frequência de saída e a corrente.
Código ESP32 para Controle CFW500 via Modbus RTU
Explicação do Código:
- #include <ModbusMaster.h> e #include <HardwareSerial.h>: Incluem as bibliotecas necessárias.
- MAX485_DE_RE_PIN: Define o pino do ESP32 conectado ao DE/RE do MAX485.
- HardwareSerial ModbusSerial(2);: Cria uma instância da classe HardwareSerial para usar a porta serial 2 do ESP32 (GPIO16/RX2, GPIO17/TX2) para a comunicação Modbus.
- ModbusMaster node;: Cria um objeto ModbusMaster.
- INVERTER_SLAVE_ID: O endereço Modbus do seu CFW500, configurado no parâmetro P200.
- Registradores Modbus: Constantes que definem os endereços dos registradores do CFW500 para controle (palavra de comando, referência de frequência) e leitura (frequência, corrente, tensão de saída). Esses valores são críticos e devem ser verificados no manual do CFW500.
- setup():
- Inicia o Serial para debug.
- Configura o pino MAX485_DE_RE_PIN como saída.
- Inicia ModbusSerial (Serial2) com o baud rate, configuração de bits e os pinos RX/TX. É fundamental que o baud rate aqui (9600) seja o mesmo configurado no inversor (P202).
- node.begin(): Associa o nó Modbus com o ID do escravo e a porta serial.
- node.preTransmission() e node.postTransmission(): Funções callback chamadas antes e depois de cada transmissão Modbus para controlar o pino DE/RE do MAX485 (habilitar/desabilitar o driver).
- loop(): Contém a lógica de exemplo para ligar/desligar o motor e variar a frequência. Ele também realiza leituras periódicas dos dados do inversor.
- writeControlWord(bool run): Envia o comando RUN (0x0001) ou STOP (0x0000) para o registrador 0x1000.
- writeFrequencyReference(float frequencyHz): Converte a frequência em Hz para o formato de 0.01 Hz (multiplica por 100) e envia para o registrador 0x1003.
- readInverterData(): Lê 3 registradores de entrada/holding contíguos a partir de 0x0004 (frequência, corrente, tensão) e exibe no Monitor Serial. Note que alguns valores (como frequência) precisam ser divididos por 100 para obter o valor real em Hz, e a tensão por 10 para o valor real em Volts, conforme a escala do inversor.
4. Procedimento de Testes
Após a conexão e o upload do código para o ESP32, é hora de testar a comunicação.
Passo a Passo dos Testes:
- Revisão Final:
- Verifique todas as conexões físicas novamente (ESP32, MAX485, CFW500).
- Confirme se a parametrização do CFW500 (P200 a P206, P220, P221) está correta e corresponde aos valores no código do ESP32.
- Certifique-se de que o motor está conectado corretamente ao inversor e em um ambiente seguro para testes.
- Upload do Código:
- Conecte o ESP32 ao seu computador via USB.
- Na IDE do Arduino, selecione a placa “ESP32 Dev Module” (ou similar) e a porta COM correta.
- Faça o upload do código.
- Monitoramento Serial:
- Após o upload, abra o Monitor Serial na IDE do Arduino (certifique-se de que o baud rate do Monitor Serial esteja em 115200).
- Você deverá ver as mensagens do ESP32 indicando o envio de comandos e a leitura de dados do inversor.
- Observação do Inversor:
- Observe o painel do CFW500. Se a comunicação estiver funcionando, você deverá ver:
- O status de RUN/STOP mudando.
- A frequência de saída variando de acordo com os valores enviados pelo ESP32.
- O LED de comunicação (geralmente Rx/Tx) no módulo MAX485 piscando, indicando tráfego de dados.
- O motor conectado ao inversor deverá ligar/desligar e ter sua velocidade alterada.
- Observe o painel do CFW500. Se a comunicação estiver funcionando, você deverá ver:
- Verificação de Dados:
- Compare os valores de frequência, corrente e tensão lidos pelo ESP32 (exibidos no Monitor Serial) com os valores mostrados no display do CFW500. Eles devem ser consistentes.
Solução de Problemas Comuns:
- “Erro ao enviar comando/ler dados”:
- Verifique o Endereço Modbus (P200 no CFW500 e INVERTER_SLAVE_ID no código): Devem ser idênticos.
- Verifique o Baud Rate (P202 no CFW500 e ModbusSerial.begin() no código): Devem ser idênticos.
- Verifique a Paridade e Stop Bits (P203/P204 no CFW500 e configuração SERIAL_8N1 no código): Devem ser compatíveis.
- Conexões RS485 (A e B): Verifique se A está conectado a A e B a B. Ocasionalmente, pode ser necessário inverter A e B se a comunicação não funcionar.
- Conexão DE/RE do MAX485: Garanta que o pino de controle esteja corretamente conectado e que as funções preTransmission e postTransmission estejam configuradas na biblioteca ModbusMaster.
- Terminação de Rede: Para distâncias maiores ou ambientes ruidosos, tente adicionar resistores de terminação de 120 ohms nas extremidades da linha RS485.
- Cabos: Use cabos de par trançado (como cabos de rede UTP/STP) para as conexões RS485, pois são menos suscetíveis a ruídos.
- Aterramento: Certifique-se de que os GNDs (0V) do ESP32/MAX485 e do CFW500 estejam conectados para uma referência de terra comum.
- Motor não Liga/Não Altera Velocidade:
- Verifique P220 (Origem Comando RUN/STOP) e P221 (Origem Referência Frequência): Devem estar configurados para “Serial” (2 e 3, respectivamente).
- Verifique os Registradores Modbus no Código: Confirme que CFW500_CONTROL_WORD_REG (0x1000) e CFW500_FREQ_REFERENCE_REG (0x1003) estão corretos conforme o manual do CFW500.
Este projeto oferece uma excelente oportunidade para os alunos entenderem a ponte entre a teoria de controle e a aplicação prática em sistemas industriais.
#include <ModbusMaster.h>
#include <HardwareSerial.h> // Para usar Serial2 no ESP32
// Definições dos pinos do ESP32 para o módulo MAX485
#define MAX485_DE_RE_PIN 4 // Pino GPIO para controle DE/RE do MAX485
// Cria uma instância da biblioteca ModbusMaster
// Usa HardwareSerial2 (GPIO16/RX2, GPIO17/TX2) para a comunicação RS485
HardwareSerial ModbusSerial(2);
ModbusMaster node;
// Endereço Modbus do inversor CFW500
const uint8_t INVERTER_SLAVE_ID = 1;
// Registradores Modbus do CFW500 (extraídos do manual)
// Registradores de escrita (Holding Registers)
const uint16_t CFW500_CONTROL_WORD_REG = 0x1000; // Comando RUN/STOP, Reset, etc.
const uint16_t CFW500_FREQ_REFERENCE_REG = 0x1003; // Referência de frequência (0.01 Hz)
// Registradores de leitura (Input Registers ou Holding Registers dependendo da função)
const uint16_t CFW500_OUTPUT_FREQ_REG = 0x0004; // Frequência de saída (0.01 Hz)
const uint16_t CFW500_OUTPUT_CURRENT_REG = 0x0005; // Corrente de saída (0.01 A)
const uint16_t CFW500_OUTPUT_VOLTAGE_REG = 0x0006; // Tensão de saída (0.1 V)
// Variáveis para controle da velocidade
float targetFrequencyHz = 0.0; // Frequência alvo em Hz (ex: 30.0 Hz)
bool motorRunning = false; // Estado do motor
void setup() {
// Inicializa a comunicação serial para debug (Monitor Serial)
Serial.begin(115200);
Serial.println("Iniciando comunicacao Modbus RS485 com CFW500...");
// Configura o pino DE/RE do MAX485 como saída
pinMode(MAX485_DE_RE_PIN, OUTPUT);
// Inicializa a comunicação serial para Modbus (Serial2)
ModbusSerial.begin(9600, SERIAL_8N1, 16, 17); // Baud Rate, Config (8 bits de dados, sem paridade, 1 stop bit), RX, TX
// Configura a instância do ModbusMaster
node.begin(INVERTER_SLAVE_ID, ModbusSerial);
node.preTransmission(preTransmission); // Função para habilitar transmissão
node.postTransmission(postTransmission); // Função para desabilitar transmissão
// Pequeno atraso para estabilização
delay(1000);
}
void loop() {
// Exemplo de controle:
// Alterna o estado do motor (liga/desliga) a cada 10 segundos
// Aumenta e diminui a frequência alvo a cada 5 segundos quando ligado
static unsigned long lastToggleTime = 0;
static unsigned long lastFreqChangeTime = 0;
static bool increasingFreq = true;
// Ligar/Desligar o motor a cada 10 segundos
if (millis() - lastToggleTime >= 10000) {
motorRunning = !motorRunning; // Inverte o estado
if (motorRunning) {
Serial.println("\nLigando o motor...");
writeControlWord(true); // Envia comando de LIGAR
targetFrequencyHz = 10.0; // Frequência inicial
writeFrequencyReference(targetFrequencyHz); // Envia referência de frequência
} else {
Serial.println("\nDesligando o motor...");
writeControlWord(false); // Envia comando de DESLIGAR
}
lastToggleTime = millis();
}
// Ajustar a frequência quando o motor estiver ligado
if (motorRunning && (millis() - lastFreqChangeTime >= 5000)) {
if (increasingFreq) {
targetFrequencyHz += 5.0;
if (targetFrequencyHz >= 50.0) {
targetFrequencyHz = 50.0;
increasingFreq = false;
}
} else {
targetFrequencyHz -= 5.0;
if (targetFrequencyHz <= 10.0) {
targetFrequencyHz = 10.0;
increasingFreq = true;
}
}
Serial.print("Definindo frequencia para: ");
Serial.print(targetFrequencyHz);
Serial.println(" Hz");
writeFrequencyReference(targetFrequencyHz);
lastFreqChangeTime = millis();
}
// Leitura periódica dos dados do inversor (a cada 2 segundos)
static unsigned long lastReadTime = 0;
if (millis() - lastReadTime >= 2000) {
readInverterData();
lastReadTime = millis();
}
delay(50); // Pequeno atraso no loop
}
// Funções de controle para o pino DE/RE do MAX485
void preTransmission() {
digitalWrite(MAX485_DE_RE_PIN, HIGH); // Habilita o driver (transmissão)
}
void postTransmission() {
digitalWrite(MAX485_DE_RE_PIN, LOW); // Desabilita o driver (recepção)
}
/**
* @brief Envia o comando RUN/STOP para o inversor.
* @param run true para ligar, false para desligar.
*/
void writeControlWord(bool run) {
uint16_t controlWord = 0;
if (run) {
controlWord = 0x0001; // Bit 0 = 1 (Run)
} else {
controlWord = 0x0000; // Bit 0 = 0 (Stop)
}
uint8_t result = node.writeSingleRegister(CFW500_CONTROL_WORD_REG, controlWord);
if (result == node.ku8MBSuccess) {
Serial.print("Comando de ");
Serial.print(run ? "LIGAR" : "DESLIGAR");
Serial.println(" enviado com sucesso.");
} else {
Serial.print("Erro ao enviar comando de ");
Serial.print(run ? "LIGAR" : "DESLIGAR");
Serial.print(". Codigo de erro: ");
Serial.println(result, HEX);
}
}
/**
* @brief Envia a referência de frequência para o inversor.
* @param frequencyHz Frequência em Hz.
*/
void writeFrequencyReference(float frequencyHz) {
// A referência de frequência é em 0.01 Hz (ex: 6000 para 60.00 Hz)
uint16_t freqValue = (uint16_t)(frequencyHz * 100);
uint8_t result = node.writeSingleRegister(CFW500_FREQ_REFERENCE_REG, freqValue);
if (result == node.ku8MBSuccess) {
Serial.print("Referencia de frequencia (");
Serial.print(frequencyHz);
Serial.println(" Hz) enviada com sucesso.");
} else {
Serial.print("Erro ao enviar referencia de frequencia. Codigo de erro: ");
Serial.println(result, HEX);
}
}
/**
* @brief Lê dados de status do inversor (frequência, corrente, tensão).
*/
void readInverterData() {
uint8_t result;
uint16_t data[3]; // Array para armazenar os dados lidos
// Lê 3 registradores a partir do 0x0004 (Frequencia, Corrente, Tensao)
result = node.readInputRegisters(CFW500_OUTPUT_FREQ_REG, 3); // Lê 3 registradores contíguos
if (result == node.ku8MBSuccess) {
float outputFreq = (float)node.getResponseBuffer(0) / 100.0; // Frequência (0.01 Hz)
float outputCurrent = (float)node.getResponseBuffer(1) / 100.0; // Corrente (0.01 A)
float outputVoltage = (float)node.getResponseBuffer(2) / 10.0; // Tensão (0.1 V)
Serial.println("\n--- Dados do Inversor ---");
Serial.print("Frequencia de Saida: ");
Serial.print(outputFreq);
Serial.println(" Hz");
Serial.print("Corrente de Saida: ");
Serial.print(outputCurrent);
Serial.println(" A");
Serial.print("Tensao de Saida: ");
Serial.print(outputVoltage);
Serial.println(" V");
Serial.println("------------------------");
} else {
Serial.print("Erro ao ler dados do inversor. Codigo de erro: ");
Serial.println(result, HEX);
}
}