#include "NCE_Bus_Probe.h"NCE_Bus_Probe bus(5);//need the client code to handle the clock - void NCE_Message(uint8_t loc, uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t e, uint8_t f, uint8_t g, uint8_t h) { Serial.print("\nNCE Message "); if ((loc >=0xc1)||(loc<= 0xC4)){ Serial.print(char(a)); Serial.print(char(b)); Serial.print(char(c)); Serial.print(char(d)); Serial.print(char(e)); Serial.print(char(f)); Serial.print(char(g)); Serial.print(char(h));} else { Serial.print(loc,HEX); Serial.print(" "); Serial.print(a,HEX); } Serial.print("\n"); }void setup(){ Serial.begin(115200); Serial.println("\n-NCE Twin Probe-"); bus.begin( ); //need to set up the link between library and code for client to handle clock bus.setMessHandler(&NCE_Message);}void loop() { bus.wait_for_myaddress(); #if TRACE Serial.print("\nmyaddress "); #endif bus.I_am_here( ); // bus.byte_to_NCE(0x7D); // bus.byte_to_NCE(0x7F); //while(1); } ---------------------------//NCE_Bus_Probe.cpp Implementation File#include "NCE_Bus_Probe.h"SoftwareSerial RS485(12,11); //Rx TxNCE_Bus_Probe :: NCE_Bus_Probe ( uint8_t my_address) {_my_address = 0x80+my_address; }; void NCE_Bus_Probe::begin ( ){ RS485.begin(9600); //The following two lines are necessary for a RS485 board with a separate Tx enable pin pinMode(RS485_Tx_En, OUTPUT); digitalWrite(RS485_Tx_En, LOW); //receiver int count = 0; while (!RS485.available( )) {if (count<50) //do not saturate screen with dots. {Serial.print("."); count++;}} Serial.println("\nRS485 Available"); while (get_NCE_Byte( ) != 0x80){ }; //synchronise with broadcast address //Serial.print(" Here "); wait_for_myaddress( ); Serial.print("\nMy Address on reset "); Send2Bytes485(0x7E,0x7F); Serial.print("Send 7E-7F "); uint8_t rxByte = get_NCE_Byte( ); if (rxByte == 0xD2) {SendByteRS485('a'); //dumb terminal Serial.print(" Response 'a' == Dumb terminal. ");} else _handleBCmess(rxByte); }//NCE does not use straight ASCII code - this routine adjustsuint8_t NCE_Bus_Probe::_NCE_ASCII(uint8_t rr){ if (rr & 0x20) return (rr & 0x3F); else return (rr & 0x7F);}uint8_t NCE_Bus_Probe:: _handleBCmess(uint8_t rxByte){ if ((rxByte >= 0xC0)&& (rxByte <= 0xC7)) _bufflen=9; else if ((rxByte ==0xCE)||(rxByte==0xCF)) _bufflen= 1; else _bufflen = 2;#if TRACE Serial.print("Mess "); Serial.print(rxByte,HEX); //verifies have first byte of message Serial.print(" len= "); Serial.print(_bufflen); Serial.print(" "); #endif _BusBuffer[0] = rxByte; _BusPtr = 1; while(_BusPtr < _bufflen){ if (_bufflen == 9 ){ rxByte = get_NCE_Byte(); _BusBuffer[_BusPtr++] = _NCE_ASCII(rxByte); } else _BusBuffer[_BusPtr++] = get_NCE_Byte(); //load buffer } _handle_message(_bufflen); do { rxByte = get_NCE_Byte( ); } while ((rxByte & 0xf0)!= 0x80); //loop until a ping is received return rxByte; } void NCE_Bus_Probe::_handle_message(uint8_t len) { #if TRACE Serial.print("\nMessage "); for (int i= 0; i <len ; i++) {Serial.print(_BusBuffer[i],HEX); Serial.print(" ");} if (len==9) //only do ASCII for (int i= 0; i <len ; i++) {Serial.print(char(_BusBuffer[i])); Serial.print(" ");} //while(1); //freeze display to have a look #endif //This will be part of the Broadcast State and part of ItsMe state. if (MessHandlerFn) //if client has not set up link this code is skipped MessHandlerFn(_BusBuffer[0],_BusBuffer[1],_BusBuffer[2],_BusBuffer[3],_BusBuffer[4],_BusBuffer[5],_BusBuffer[6], _BusBuffer[7], _BusBuffer[8]); } uint8_t NCE_Bus_Probe ::_handleBC(){ #if TRACE Serial.print("HandleBC "); #endif uint8_t rxByte; do {rxByte = get_NCE_Byte(); if ((rxByte & 0xF0) != 0x80) rxByte = _handleBCmess(rxByte); //its not a ping } while ((rxByte & 0x80) != 0x80); return rxByte; //should return ping after bc ping }/*void NCE_Bus_Probe ::wait_for_myaddress(){ uint8_t rxByte; do { rxByte = get_NCE_Byte( ); if (rxByte == 0x80) { _handleBC(); } } while (rxByte != _my_address); // rxByte = get_NCE_Byte( ); // if ((rxByte & 0xF0)!= 0x80) _handleBCmess(rxByte); }*/ void NCE_Bus_Probe ::wait_for_myaddress(){ uint8_t rxByte; rxByte = get_NCE_Byte( ); // Serial.print(rxByte); if ((rxByte & 0xF0)!= 0x80) rxByte = _handleBCmess(rxByte); while (rxByte != _my_address) { //Serial.print('.'); if (rxByte == 0x80) _handleBC(); rxByte = get_NCE_Byte( ); } //Serial.print(" Found "); } uint8_t NCE_Bus_Probe::get_NCE_Byte( ) { uint8_t rxByte; while (!RS485.available( )); rxByte = RS485.read(); #if TRACE if (rxByte == 0x80) Serial.println(); //sync to broadcast if (rxByte < 16) Serial.print('0'); Serial.print(rxByte,HEX); //if (rxByte == 0x80) { // Serial.print(" BC"); // } Serial.print(' '); #endif return rxByte; }//--------------------------------------------------------------//Need to implement the method that will point the library routine to the required client operation//Client will call this as part of initialisationvoid NCE_Bus_Probe::setMessHandler(MessHandler clientPtr) { MessHandlerFn = clientPtr; } //-----------------------------------------------------------//Write to the RS485 Bus//digital writes required if using RS485 device with separate Tx enable.//It appears a delay of 200 microseconds is required. 100 will not workvoid NCE_Bus_Probe::SendByteRS485(uint8_t mess){ //digitalWrite(RS485_Tx_En,HIGH); delayMicroseconds(200); RS485.write(mess);// digitalWrite(RS485_Tx_En,LOW);}void NCE_Bus_Probe::Send2Bytes485(uint8_t m1,uint8_t m2) { //digitalWrite(RS485_Tx_En,HIGH); delayMicroseconds(200); RS485.write(m1); RS485.write(m2); // digitalWrite(RS485_Tx_En,LOW);}void NCE_Bus_Probe::I_am_here(){ Send2Bytes485(0x7D,0x7F); #if TRACE Serial.print(" Send 7D,7F "); #endif}void NCE_Bus_Probe::byte_to_NCE(uint8_t cmd){ SendByteRS485(cmd); #if TRACE Serial.print(" Send "); Serial.print(cmd,HEX); #endif }//--------------------------------- --------------------------------------------//NCE_Bus_Probe.h Header File#ifndef NCE_BUS_PROBE_H#define NCE_BUS_PROBE_H#include "Arduino.h"#define TRACE 1#include <SoftwareSerial.h> //Included SoftwareSerial Libraryenum NCE_STATE {START,BROADCAST,ITS_ME,OTHER};//in order to create a link between the library and the client code need to define a typetypedef void (*MessHandler)(uint8_t loc, uint8_t a, uint8_t b,uint8_t c,uint8_t d,uint8_t e, uint8_t f, uint8_t g, uint8_t h); #define RS485_Tx_En 13 //use inbuilt LED#define TX digitalWrite(RS485_Tx_En, HIGH)#define RX digitalWrite(RS485_Tx_En, LOW)class NCE_Bus_Probe { public: NCE_Bus_Probe (uint8_t my_address ); void begin( ); uint8_t get_NCE_Byte( ); void wait_for_myaddress(); //To transfer the clock result from the library to the client need a public routine that client can call to setup link void setMessHandler(MessHandler funcPtr); void Send2Bytes485(uint8_t m1,uint8_t m2); void SendByteRS485(uint8_t mess); void I_am_here(); void byte_to_NCE(uint8_t cmd); private: uint8_t _my_address; uint8_t _BusBuffer[10]; uint8_t _BusPtr; uint8_t _BusSize; uint8_t _bufflen; uint8_t _handleBC(); void _handle_message( ); void _build_message( ); uint8_t _handleBCmess(uint8_t rxByte); void _handle_message(uint8_t len); uint8_t _NCE_ASCII(uint8_t rr);//Need the private links that will do the actual transfers MessHandler MessHandlerFn; };#endif--------------------------------------------------------------------Trace of Bus activity13:55:54.950 -> -NCE Twin Probe-
13:55:54.950 -> ..................................
13:55:54.950 -> RS485 Available
13:55:54.950 -> 86 87 88 89 8A
13:55:54.997 -> 80 82 83 84 85
13:55:54.997 -> My Address on reset Send 7E-7F D2 Response 'a' == Dumb terminal. 86 87 88 89 8A
13:55:54.997 -> 80 HandleBC 82 83 84 85
13:55:55.044 -> myaddress Send 7D,7F C0 Mess C0 len= 9 E0 CE C3 C5 E0 E0 E0 E0
13:55:55.044 -> Message C0 20 4E 43 45 20 20 20 20 ⸮ N C E
13:55:55.044 -> NCE Message NCE
13:55:55.044 -> 86 87 88 89 8A
13:55:55.044 -> 80 HandleBC 82 83 84 85
13:55:55.091 -> myaddress Send 7D,7F C2 Mess C2 len= 9 E0 C4 C3 C3 E0 D4 D7 C9
13:55:55.091 -> Message C2 20 44 43 43 20 54 57 49 ⸮ D C C T W I
13:55:55.091 -> NCE Message DCC TWI
13:55:55.091 -> 86 87 88 89 8A
13:55:55.091 -> 80 HandleBC 82 83 84 85
13:55:55.138 -> myaddress Send 7D,7F C3 Mess C3 len= 9 CE E0 D6 F1 EE F1 F2 E0
13:55:55.138 -> Message C3 4E 20 56 31 2E 31 32 20 ⸮ N V 1 . 1 2
13:55:55.138 -> NCE Message N V1.12
13:55:55.138 -> 86 87 88 89 8A
13:55:55.185 -> 80 HandleBC 82 83 84 85
13:55:55.185 -> myaddress Send 7D,7F C1 Mess C1 len= 9 E0 E0 E0 E0 E0 E0 E0 E0
13:55:55.185 -> Message C1 20 20 20 20 20 20 20 20 ⸮
13:55:55.185 -> NCE Message
13:55:55.185 -> 86 87 88 89 8A
13:55:55.232 -> 80 HandleBC 82 83 84 85
13:55:55.232 -> myaddress Send 7D,7F CE Mess CE len= 1
13:55:55.232 -> Message CE
13:55:55.232 -> NCE Message
13:55:55.232 -> CE 86 87 88 89 8A
13:55:55.232 -> 80 HandleBC 82 83 84 85
13:55:55.278 -> myaddress Send 7D,7F C0 Mess C0 len= 9 CC CF C3 FA E0 F0 F0 F0
13:55:55.278 -> Message C0 4C 4F 43 3A 20 30 30 30 ⸮ L O C : 0 0 0
13:55:55.278 -> NCE Message LOC: 000
13:55:55.278 -> 86 87 88 89 8A
13:55:55.278 -> 80 HandleBC 82 83 84 85
13:55:55.325 -> myaddress Send 7D,7F C2 Mess C2 len= 9 C6 D7 C4 FA E0 F0 F0 F0
13:55:55.325 -> Message C2 46 57 44 3A 20 30 30 30 ⸮ F W D : 0 0 0
13:55:55.325 -> NCE Message FWD: 000
13:55:55.325 -> 86 87 88 89 8A
13:55:55.372 -> 80 HandleBC 82 83 84 85
13:55:55.372 -> myaddress Send 7D,7F C3 Mess C3 len= 9 E0 ED ED ED ED ED ED ED
13:55:55.372 -> Message C3 20 2D 2D 2D 2D 2D 2D 2D ⸮ - - - - - - -
13:55:55.372 -> NCE Message -------
13:55:55.372 -> 86 87 88 89 8A
13:55:55.419 -> 80 HandleBC 82 83 84 85
13:55:55.419 -> myaddress Send 7D,7F 86 87 88 89 8A
13:55:55.419 -> 80 HandleBC 82 83 84 85
13:55:55.466 -> myaddress Send 7D,7F 86 87 88 89 8A
13:55:55.466 -> 80 HandleBC 82 83 84 85
13:55:55.513 -> myaddress Send 7D,7F 86 87 88 89 8A
13:55:55.513 -> 80 HandleBC 82 83 84 85
13:55:55.513 -> myaddress Send 7D,7F 86 87 88 89 8A
13:55:55.560 -> 80 HandleBC 82 83 84 85
13:55:55.560 -> myaddress Send 7D,7F 86 87 88 89 8A
13:55:55.606 -> 80 HandleBC 82 83 84 85
-----------------------------------------
13:55:57.232 -> 80 HandleBC 82 83 84 85
13:55:57.232 -> myaddress Send 7D,7F 86 87 88 89 8A
13:55:57.232 -> 80 HandleBC D4 Mess D4 len= 2 0A
13:55:57.278 -> Message D4 A
13:55:57.278 -> NCE Message
13:55:57.278 -> -------
13:55:57.278 -> 82 83 84 85
13:55:57.278 -> myaddress Send 7D,7F 86 87 88 89 8A
13:55:57.278 -> 80 HandleBC 82 83 84 85
-----------------------------------------