Modbus Coils in MOACON are stored in arrays of bytes (u8) while the use of them is at the bit level. This means that in order to test or set a single coil, some kind of bit masking has to be done. Anyone that has to deal with it knows that the procedure can be cumbersome and leading to almost unreadable code so I've created a couple of functions to treat the coils as individual items, abstracting them from the actual Modbus coils array. They may be useful for you too.
- Code: Select all
// Powers of 2 (used to mask individual bits in a 8 bit word)
u8 pwr2[] = { 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80 };
bool getCoil(u8 * coilsarray, short coilnbr) //Get one boolean value from coilsarray[index]
{
return ( (coilsarray[coilnbr / 8] & (u8)pwr2[coilnbr % 8]) == (u8)pwr2[coilnbr % 8] );
}
void setCoil (u8 * coilsarray, short coilnbr, bool value) //Set one boolean coil into coilsarray()
{
coilsarray[coilnbr/8] = (value ? coilsarray[coilnbr/8] | pwr2[coilnbr%8] : coilsarray[coilnbr/8] & ~pwr2[coilnbr%8]);
}
Note the definition of a powers of 2 array to have the 8 bit mask ready to use, instead of calculating them everytime and that the Modbus coil array is passed as a pointer.
Here is an example to use them in MOACON
- Code: Select all
#include "moacon500.h"
//Number of Modbus coils and registers to use. Change this number to reflect your needs
#define NBR_COILS 64 //Number of coils (bits)
#define NBR_REGS 16 //Number of registers (word)
//Create the static arrays for Modbus
static u8 MBCoils[NBR_COILS / 8 + 1]; //Modbus bytes hold 8 bits each, so the number of elements in this array is 1/8 of the coils defined
static u16 MBRegister[NBR_REGS]; //Modbus registers
// Powers of 2 (used to mask individual bits in a 8 bit word)
u8 pwr2[] = { 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80 };
bool getCoil(u8 * coilsarray, short coilnbr) //Get one boolean value from coilsarray[index]
{
return ( (coilsarray[coilnbr / 8] & (u8)pwr2[coilnbr % 8]) == (u8)pwr2[coilnbr % 8] );
}
void setCoil (u8 * coilsarray, short coilnbr, bool value) //Set one boolean coil into coilsarray()
{
coilsarray[coilnbr/8] = (value ? coilsarray[coilnbr/8] | pwr2[coilnbr%8] : coilsarray[coilnbr/8] & ~pwr2[coilnbr%8]);
}
void cmain(void)
{
int i;
//Open the CPU comm channel and start the Modbus RTU function
openCom(0, 37600, com8N1); //The CUPANEL comminucation must be set to the same speed
startModbusRtu(0,1,MBRegister,MBCoils); //Start the Modbus RTU engine. This runs in the background without any further programming
while(1)
{
//Write a few coils
setCoil(MBCoils,3, 1);
setCoil(MBCoils,6, 1);
setCoil(MBCoils,9, 1);
//Read back first 16 coils
for (i=0; i<=16; i++)
{
debugLocate(0,i); //Display in the first line
printf("Coil[%d] = %d\r\n",i, getCoil(MBCoils,i));
delay(1000);
}
}
}
TUTAN