jpliew / Multi-Reader-Wiegand-Protocol-Library-for-Arduino

Multi Reader Wiegand Protocol Library for Arduino
20 stars 4 forks source link

D2 or TX occupied by Wiegand Multi ? #2

Closed StephaneCYB closed 3 years ago

StephaneCYB commented 3 years ago

Hi,

I use the WiegandMulti.h to read the codes from a Wiegand keyboard with NFC reader. This works perfect to the serial monitor. I connected the Wiegand D0 & D1 to pin D5 &D6 of a nano. Now I like to make the nano also a modbus RTU slave, to make the codes available for a modbus master. I use always the older version SimpleModbusSlave, because this library is easy to use. SimpleModbusSlave is using RX,TX and D2 of the nano for serial communication to RS485.

Is the WiegandMulti library, using D2 and/or the communication lines of the nano when there is no output to the serial monitor ?

Here the sketch that I use

#include <WiegandMulti.h>
#include <SimpleModbusSlave.h>

WIEGANDMULTI wg;
void Reader1D0Interrupt(void)
{
    wg.ReadD0();
}
void Reader1D1Interrupt(void)
{
    wg.ReadD1();
}
int CODE_A = 0;    // low code
int CODE_B = 0;    // high code
int CODE_C = 0;    // 1111 , if keyboard used  // 2222 , if digi key used
int Teller = 0;
unsigned long CODE_W4 = 0;
unsigned long CODE = 0;
unsigned long SECTEL1 = 0;
String inString = "";    // string to hold input

// for MODBUS
// Using the enum instruction allows for an easy method for adding and 
// removing registers. Doing it this way saves you #defining the size 
// of your slaves register array each time you want to add more registers
// and at a glimpse informs you of your slaves register layout.

//////////////// registers of your slave ///////////////////
enum 
{     
    // just add or remove registers and your good to go...
    // The first register starts at address 0
    ModCode_A,
    ModCode_B,
    ModCode_C,

    HOLDING_REGS_SIZE // leave this one
    // total number of registers for function 3 and 16 share the same register array
    // i.e. the same address space
};

unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array
////////////////////////////////////////////////////////////

void setup() {
    //Serial.begin(9600);  
    wg.begin(5,6,Reader1D0Interrupt,Reader1D1Interrupt);

    // for MODBUS
    /* parameters(HardwareSerial* SerialPort,
        long baudrate, 
        unsigned char byteFormat,
        unsigned char ID, 
        unsigned char transmit enable pin,   (normaal 2, maar gezien gebruikt door WIEGAND, 4 ) 
        unsigned int holding registers size,
        unsigned int* holding register array)
    */

    /* Valid modbus byte formats are:
        SERIAL_8N2: 1 start bit, 8 data bits, 2 stop bits
        SERIAL_8E1: 1 start bit, 8 data bits, 1 Even parity bit, 1 stop bit
        SERIAL_8O1: 1 start bit, 8 data bits, 1 Odd parity bit, 1 stop bit

        You can obviously use SERIAL_8N1 but this does not adhere to the
        Modbus specifications. That said, I have tested the SERIAL_8N1 option 
        on various commercial masters and slaves that were suppose to adhere
        to this specification and was always able to communicate... Go figure.

        These byte formats are already defined in the Arduino global name space. 
    */

    modbus_configure(&Serial, 9600, SERIAL_8N1, 4, 2, HOLDING_REGS_SIZE, holdingRegs);
}

void loop() {
    // detect overtime
    SECTEL1 = SECTEL1 + 1;
    if (SECTEL1 > 1200000)
    {
        CODE_A = 0;
        CODE_B = 0;
        CODE_C = 0;
        inString = "";
        Teller = 0;
        SECTEL1 = 0;
    }
    if(wg.available())
    {
        if (wg.getWiegandType() == 4)
        {
            digitalWrite(LED_BUILTIN, HIGH); 
            if (wg.getCode() == 13)
            {
                CODE_W4 = inString.toInt(); 
                Teller = 0;
                CODE_B = CODE_W4 / 10000 ;
                CODE_A = CODE_W4 - (CODE_B * 10000);  
                CODE_C = 1111;
                SECTEL1 = 0;             
                //                      Serial.println((String)",  CODE_W4 = " + CODE_W4); 

            }
            else
            {
                Teller = Teller + 1;
                SECTEL1 = 0;
                if (Teller < 9)
                {
                    inString = inString + String(wg.getCode());
                    //                         Serial.println(inString);
                }                        
            }

        }
        if (wg.getWiegandType() == 26)
        {
            digitalWrite(LED_BUILTIN, LOW); 
            CODE_B = wg.getCode() / 10000 ;

            CODE_A = wg.getCode() - (CODE_B * 10000);
            CODE_C = 2222;
            SECTEL1 = 0;
        }       

        //                   Serial.println((String)",  CODE_A = " + CODE_A);                    
        //                   Serial.println((String)",  CODE_B = " + CODE_B);

        // MODBUS 

        holdingRegs[ModCode_A] = CODE_A;
        holdingRegs[ModCode_B] = CODE_B;
        holdingRegs[ModCode_C] = CODE_C;                   
        modbus_update(); 

    }
}
jpliew commented 3 years ago

This library does not use Serial or any other IO pin other than the pair declared with wg.begin

StephaneCYB commented 3 years ago

Thanks for your reply. I noticed that the PinChangeInterrupt is not compatible with SoftSerial. So I think that it is impossible to use the serial port, with the WiegandMulti. Do you think this is correct, or do you have any examples using TX & RX ?

jpliew commented 3 years ago

I am a bit confused, I didn't see anywhere in your code SoftSerial is being used.

SoftSerial has lots of issues, you should avoid using it for multiple hardware that uses interrupts.

From your sketch, it looks like you are using hardware serial, with hardware serial it should work. Only thing that you can't just print things to the "Arduino Serial Monitor" that will be conflicting with MODBUS.

Nano is cheap, why not use two nano boards, one for Wiegand and one for MODBUS, then the two can communicate using I2C ?

StephaneCYB commented 3 years ago

I think I tested now all libraries Modbus and Wiegand. Separately this libraries are working perfect, but modbus is not functional, when a wiegand library is implemented. I suppose that both libraries are using the same interrupt, or something else commonly. Using 2 nano boards, using I2C looks a solution, but I don't have the place to mount the 2 units in the box of a light switch. (including light switch). Because Serial.println instruction seems to work, I think to use this to send the codes to our PLC.