SPI Ethernet Modbus

General discussion on mikroC PRO for 8051.
Post Reply
Author
Message
xhaner
Posts: 3
Joined: 03 Mar 2016 22:32

SPI Ethernet Modbus

#1 Post by xhaner » 17 Sep 2019 09:03

Hello,

I would like to join SPI Ethernet example with the code given below.
Can you help me convert arduino code to mikroC for 8051.
I would like to run arduino library for modbus on 8051.

// Mudbus.h file

#ifndef Mudbus_h
#define Mudbus_h

#define MB_N_R 125 //Max 16 bit registers for Modbus is 125
#define MB_N_C 128 //Max coils for Modbus is 2000 - dont need that many so here is a multiple of 8
#define MB_PORT 502

enum MB_FC {
MB_FC_NONE = 0,
MB_FC_READ_COILS = 1,
MB_FC_READ_REGISTERS = 3,
MB_FC_WRITE_COIL = 5,
MB_FC_WRITE_REGISTER = 6,
//Function codes 15 & 16 by Martin Pettersson http://siamect.com
MB_FC_WRITE_MULTIPLE_COILS = 15,
MB_FC_WRITE_MULTIPLE_REGISTERS = 16
};

class Mudbus
{
public:
Mudbus();
void Run();
int R[MB_N_R];
bool C[MB_N_C];
bool Active;
unsigned long PreviousActivityTime;
int Runs, Reads, Writes;
private:
uint8_t ByteArray[260];
MB_FC FC;
void SetFC(int fc);
};

#endif

/* Speculations on Modbus message structure:
**********************************************
**********Master(PC) request frames***********
00 ID high 0
01 ID low 1
02 Protocol high 0
03 Protocol low 0
04 Message length high 0
05 Message length low 6 (6 bytes after this)
06 Slave number 1
07 Function code
08 Start address high maybe 0
09 Start address low maybe 0
10 Length high maybe 125 or Data high if write
11 Length low maybe 125 or Data low if write
**********************************************
**********Slave(Arduino) response frames******
00 ID high echo / 0
01 ID low echo / slave ID 1
02 Protocol high echo
03 Protocol low echo
04 Message length high echo
05 Message length low num bytes after this
06 Slave number echo
07 Function code echo
08 Start address high num bytes of data
09 Data high
10 Data low
**********************************************
*/

// Mudbus.cpp file

#include "Mudbus.h"

EthernetServer MbServer(MB_PORT);

Mudbus::Mudbus()
{
}

void Mudbus::Run()
{
Runs = 1 + Runs * (Runs < 999);

//****************** Read from socket ****************
// For Arduino 0022
// Client client = MbServer.available();
// For Arduino 1.0
EthernetClient client = MbServer.available();
if(client.available())
{
Reads = 1 + Reads * (Reads < 999);
int i = 0;
while(client.available())
{
ByteArray = client.read();
i++;
}
SetFC(ByteArray[7]); //Byte 7 of request is FC
if(!Active)
{
Active = true;
PreviousActivityTime = millis();
}
}
if(millis() > (PreviousActivityTime + 60000))
{
if(Active)
{
Active = false;
}
}

int Start, WordDataLength, ByteDataLength, CoilDataLength, MessageLength;

//****************** Read Coils **********************
if(FC == MB_FC_READ_COILS)
{
Start = word(ByteArray[8],ByteArray[9]);
CoilDataLength = word(ByteArray[10],ByteArray[11]);
ByteDataLength = CoilDataLength / 8;
if(ByteDataLength * 8 < CoilDataLength) ByteDataLength++;
CoilDataLength = ByteDataLength * 8;
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data).
for(int i = 0; i < ByteDataLength ; i++)
{
for(int j = 0; j < 8; j++)
{
bitWrite(ByteArray[9 + i], j, C[Start + i * 8 + j]);
}
}
MessageLength = ByteDataLength + 9;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}

//****************** Read Registers ******************
if(FC == MB_FC_READ_REGISTERS)
{
Start = word(ByteArray[8],ByteArray[9]);
WordDataLength = word(ByteArray[10],ByteArray[11]);
ByteDataLength = WordDataLength * 2;
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
ByteArray[8] = ByteDataLength; //Number of bytes after this one (or number of bytes of data).
for(int i = 0; i < WordDataLength; i++)
{
ByteArray[ 9 + i * 2] = highByte(R[Start + i]);
ByteArray[10 + i * 2] = lowByte(R[Start + i]);
}
MessageLength = ByteDataLength + 9;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}

//****************** Write Coil **********************
if(FC == MB_FC_WRITE_COIL)
{
Start = word(ByteArray[8],ByteArray[9]);
C[Start] = word(ByteArray[10],ByteArray[11]) > 0;
ByteArray[5] = 2; //Number of bytes after this one.
MessageLength = 8;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}

//****************** Write Register ******************
if(FC == MB_FC_WRITE_REGISTER)
{
Start = word(ByteArray[8],ByteArray[9]);
R[Start] = word(ByteArray[10],ByteArray[11]);
ByteArray[5] = 6; //Number of bytes after this one.
MessageLength = 12;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}


//****************** Write Multiple Coils **********************
//Function codes 15 & 16 by Martin Pettersson http://siamect.com
if(FC == MB_FC_WRITE_MULTIPLE_COILS)
{
Start = word(ByteArray[8],ByteArray[9]);
CoilDataLength = word(ByteArray[10],ByteArray[11]);
ByteDataLength = CoilDataLength / 8;
if(ByteDataLength * 8 < CoilDataLength) ByteDataLength++;
CoilDataLength = ByteDataLength * 8;
ByteArray[5] = ByteDataLength + 5; //Number of bytes after this one.
for(int i = 0; i < ByteDataLength ; i++)
{
for(int j = 0; j < 8; j++)
{
C[Start + i * 8 + j] = bitRead( ByteArray[13 + i], j);
}
}
MessageLength = 12;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}


//****************** Write Multiple Registers ******************
//Function codes 15 & 16 by Martin Pettersson http://siamect.com
if(FC == MB_FC_WRITE_MULTIPLE_REGISTERS)
{
Start = word(ByteArray[8],ByteArray[9]);
WordDataLength = word(ByteArray[10],ByteArray[11]);
ByteDataLength = WordDataLength * 2;
ByteArray[5] = ByteDataLength + 3; //Number of bytes after this one.
for(int i = 0; i < WordDataLength; i++)
{
R[Start + i] = word(ByteArray[ 13 + i * 2],ByteArray[14 + i * 2]);
}
MessageLength = 12;
client.write(ByteArray, MessageLength);
Writes = 1 + Writes * (Writes < 999);
FC = MB_FC_NONE;
}
}


void Mudbus::SetFC(int fc)
{
if(fc == 1) FC = MB_FC_READ_COILS;
if(fc == 3) FC = MB_FC_READ_REGISTERS;
if(fc == 5) FC = MB_FC_WRITE_COIL;
if(fc == 6) FC = MB_FC_WRITE_REGISTER;
if(fc == 15) FC = MB_FC_WRITE_MULTIPLE_COILS;
if(fc == 16) FC = MB_FC_WRITE_MULTIPLE_REGISTERS;
}

User avatar
jovana.medakovic
mikroElektronika team
Posts: 986
Joined: 18 Dec 2018 10:36

Re: SPI Ethernet Modbus

#2 Post by jovana.medakovic » 18 Sep 2019 15:07

Hello,

Unfortunately, converting code for mikroC compiler is out of the scope of mikroE technical support.
I'm afraid we are unable to provide assistance in this case.
Maybe some of the other users can help you.

Kind regards,
Jovana

Post Reply

Return to “mikroC PRO for 8051 General”