MODBUS ATMEGA168

Software e Hardware para ATMEL

Moderadores: guest2003, 51, brasilma

MODBUS ATMEGA168

Mensagempor longo.251272 » 19 Ago 2021 16:22

Boa tarde pessoal,

Estou estudando qual a melhor forma de fazer uma comunicação modbus rtu com o ATMega168.
Pesquisando encontrei o biblioteca, https://github.com/nucleron/freemodbus-v1.5.0/tree/master/demo/AVR

Fiz alguns ajustes para conseguir compilar no AVR Studio 7.0 porém não estou me achando onde coloco os dados de envio ou como leio os dados recebidos.
No exemplo ele fica em um loop, segue abaixo

Código: Selecionar todos
main( void )
{
    const UCHAR     ucSlaveID[] = { 0xAA, 0xBB, 0xCC };
    eMBErrorCode    eStatus;

    eStatus = eMBInit( MB_RTU, 0x05, 0, 9600, MB_PAR_NONE );   //Changed address to 0x05 from 0x0A

    eStatus = eMBSetSlaveID( 0x34, TRUE, ucSlaveID, 3 );
    sei(  );

    /* Enable the Modbus Protocol Stack. */
    eStatus = eMBEnable(  );

    for( ;; )
    {
        ( void )eMBPoll(  );

        /* Here we simply count the number of poll cycles. */
        usRegInputBuf[0]++;
    }
}


A aplicação é implementar um escravo que vai fornecer dados do endereço, recebido pelo mestre, da memória externa I2C.

Ainda não implementei nada fisicamente, só manipulando bibliotecas.

Se alguém puder me orientar agradeço,
Ricardo
longo.251272
Byte
 
Mensagens: 283
Registrado em: 08 Nov 2011 11:58
Localização: São Paulo - SP

Re: MODBUS ATMEGA168

Mensagempor edsont » 19 Ago 2021 16:51

Nesse exemplo o MCU é escravo. Os dados estão nos endereços usRegInputBuf[0], usRegInputBuf[1], usRegInputBuf[2] e usRegInputBuf[3].
O primeriro endereço é acessado via modbus como endereço 1000 (ou 1001 se for base 1) e este contém um valor que é incrementado no loop. Os demais endereços estão com zero, a não ser que você atribua algum valor.
É isso que está escrito no Readme.txt.
Avatar do usuário
edsont
Word
 
Mensagens: 539
Registrado em: 22 Mai 2007 17:19
Localização: Araraquara-SP Brasil - Terra - Sistema Solar - Via Láctea

Re: MODBUS ATMEGA168

Mensagempor longo.251272 » 20 Ago 2021 09:06

Bom dia,

Pelo que entendi no usRegInputBuf ficam os dados que o mestre vai receber, mas onde estão os dados que o mestre envia ? Para o escravo determinar qual dado enviar para o mestre.
Não estou familiarizado com esse nível de linguagem utilizado nessa biblioteca.
longo.251272
Byte
 
Mensagens: 283
Registrado em: 08 Nov 2011 11:58
Localização: São Paulo - SP

Re: MODBUS ATMEGA168

Mensagempor longo.251272 » 23 Ago 2021 14:03

Bem pesquisando descobri que tem no exemplo não está implementado a função eMBRegHoldingCB onde trata o envio/leitura de dados.
Ainda não testei fisicamente, quando tiver mais dados eu posto aqui.

Obrigado

Código: Selecionar todos
/*
 * FreeModbus Libary: AVR Demo Application
 * Copyright (C) 2006 Christian Walter <wolti@sil.at>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * File: $Id: demo.c,v 1.7 2006/06/15 15:38:02 wolti Exp $
 */

/* ----------------------- AVR includes -------------------------------------*/
#include <avr/io.h>
#include <avr/interrupt.h>

/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"

/* ----------------------- Defines ------------------------------------------*/
#define REG_INPUT_START      1000
#define REG_INPUT_NREGS      4

#define REG_HOLDING_START   2000
#define REG_HOLDING_NREGS   4

/* ----------------------- Static variables ---------------------------------*/
static USHORT   usRegInputStart = REG_INPUT_START;
static USHORT   usRegInputBuf[REG_INPUT_NREGS];

static USHORT   usRegHoldingStart = REG_HOLDING_START;
static USHORT   usRegHoldingBuf[REG_HOLDING_NREGS];

/* ----------------------- Start implementation -----------------------------*/
int
main( void )
{
    const UCHAR     ucSlaveID[] = { 0xAA, 0xBB, 0xCC };
    eMBErrorCode    eStatus;

    eStatus = eMBInit( MB_RTU, 0x05, 0, 9600, MB_PAR_NONE );   //Changed address to 0x05 from 0x0A

    eStatus = eMBSetSlaveID( 0x34, TRUE, ucSlaveID, 3 );
    sei(  );

    /* Enable the Modbus Protocol Stack. */
    eStatus = eMBEnable(  );

    for( ;; )
    {
        ( void )eMBPoll(  );

        /* Here we simply count the number of poll cycles. */
        usRegInputBuf[0]++;
    }
}

eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;

    if( ( usAddress >= REG_INPUT_START )
        && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegInputStart );
        while( usNRegs > 0 )
        {
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ =
                ( unsigned char )( usRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}

eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,
                 eMBRegisterMode eMode )
{
    //return MB_ENOREG;
    eMBErrorCode eStatus = MB_ENOERR;
    int iRegIndex;
 
    if((usAddress >= REG_HOLDING_START) && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
    {
        iRegIndex = (int)(usAddress - usRegHoldingStart);
        switch(eMode)
        {
        /* Pass current register values to the protocol stack. */
        case MB_REG_READ:
            while(usNRegs > 0)
            {
                *pucRegBuffer++ = (unsigned char)(usRegHoldingBuf[iRegIndex] >> 8);
                *pucRegBuffer++ = (unsigned char)(usRegHoldingBuf[iRegIndex] & 0xFF);
                iRegIndex++;
                usNRegs--;
            }
            break;
 
            /* Update current register values with new values from the
             * protocol stack. */
        case MB_REG_WRITE:
            while(usNRegs > 0)
            {
                usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
                usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
                iRegIndex++;
                usNRegs--;
            }
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }
    return eStatus;   
//    return MB_ENOREG;
}


eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
               eMBRegisterMode eMode )
{
    return MB_ENOREG;
}

eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
    return MB_ENOREG;
}
longo.251272
Byte
 
Mensagens: 283
Registrado em: 08 Nov 2011 11:58
Localização: São Paulo - SP


Voltar para AVR

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 2 visitantes

x