Página 1 de 1

MODBUS ATMEGA168

MensagemEnviado: 19 Ago 2021 16:22
por longo.251272
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

Re: MODBUS ATMEGA168

MensagemEnviado: 19 Ago 2021 16:51
por edsont
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.

Re: MODBUS ATMEGA168

MensagemEnviado: 20 Ago 2021 09:06
por longo.251272
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.

Re: MODBUS ATMEGA168

MensagemEnviado: 23 Ago 2021 14:03
por longo.251272
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;
}