diff --git a/README.md b/README.md index 53126e7..d62674e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The intention of this library is to make use of the NCD 2 channel relay controll ###Developer information NCD has been designing and manufacturing computer control products since 1995. We have specialized in hardware design and manufacturing of Relay controllers for 20 years. We pride ourselves as being the industry leader of computer control relay products. Our products are proven reliable and we are very excited to support Particle. For more information on NCD please visit www.controlanything.com -###Requirements +### Requirements - NCD 2 Channel Particle Core/Photon Compatible Relay board - Particle Core/Photon module - Knowledge base for developing and programming with Particle Core/Photon modules. @@ -39,7 +39,7 @@ NCD2Relay relayController; void setup() { Serial.begin(115200); - relayController.setAddress(0,0,0); + relayController.setInit(0,0,0); } void loop() { @@ -81,16 +81,27 @@ void loop() { } ``` -###Public accessible methods +### Public accessible methods ```cpp -void setAddress(int a0, int a1, int a2); +void setInit(int a0, int a1, int a2, byte direction = 0xFC, byte pullup = 0xFC); ``` >Must be called first before using the object. This method should also be called any time communication with ->the controller is lost or broken to recover communication This method accepts two int arguments. This ->tells the Library what address to direct commands to. a0 and a1 ints are representations of the two ->jumpers on the 4 channel relay controller which are labeled on the board A0, A1, and A2. If the jumper is ->installed then that int in this call should be set to 1. If it is not installed then the int should be set to -So if I have A0, A1, and A2 installed I would call ```relayController.setAddress(1, 1, 1).``` +>the controller is lost or broken to recover communication This method accepts three int arguments and optionally +>two byte arguments. int a0, int a1 and int a2 tell the Library what address to direct commands to. a0, a1 and a2 +>ints are representations of the three jumpers on the 2 channel relay controller which are labeled on the board A0, +>A1, and A2. If the jumper is installed then that int in this call should be set to 1. If it is not installed then +>the int should be set to 0. +> +>So if I have A0, A1, and A2 installed I would call ```relayController.setInit(1, 1, 1).``` +> +>The direction and pullup arguments are optional and default to Input on GP2 through GP7 (input 1 through 6) with +>pull-up resistors enabled. direction can be called without pullup and will enable all input pull-up resistors. +>pullup cannot be called without first calling direciton. direction and pullup are set bitwise with bit 2 representing +>input/output 1 and bit 7 representing input/output 6. +> +>If I wanted to switch Input 6 to an output I would call ```setInit(0,0,0,0x7C)``` +> +>If I wanted to turn off the pull-up resistor on Input 1 I would call ```setInit(0,0,0,0xFC,0xF8)``` ```cpp @@ -174,8 +185,18 @@ int readAllInputs(); >the bit in the byte is set to 1, if the input is open the bit in the byte is set to 0. 256 will be >returned if an error has occured(generally due to lack of communciation with controller). +```cpp +void setOutputHigh(int output); +``` +>This method accepts one int. Valid int arguments 1-6. A call to this method will set the open drain output +>to float. + +```cpp +void setOutputLow(int output); +``` +>This method accepts one int. Valid arguments 1-6. A call to this method will set the open drain output to ground. -###Public accessible variables +### Public accessible variables ```cpp bool initialized; ``` @@ -188,4 +209,4 @@ License ---- GNU -[sparkIncludeLibrary]:https://docs.particle.io/guide/getting-started/build/photon/ \ No newline at end of file +[sparkIncludeLibrary]:https://docs.particle.io/guide/getting-started/build/photon/ diff --git a/firmware/NCD2Relay.cpp b/firmware/NCD2Relay.cpp index e6e3148..b6d1560 100644 --- a/firmware/NCD2Relay.cpp +++ b/firmware/NCD2Relay.cpp @@ -9,7 +9,8 @@ NCD2Relay::NCD2Relay(){ } //Retry added -void NCD2Relay::setAddress(int a0, int a1, int a2){ +void NCD2Relay::setInit(int a0, int a1, int a2, byte direction, byte pullup){ + // Set address address = 0x20; if(a0 == 1){ address = address | 1; @@ -20,20 +21,27 @@ void NCD2Relay::setAddress(int a0, int a1, int a2){ if(a2 == 1){ address = address | 4; } + + // Set GPIO direction + byte directionMasked = (direction & 0xFC); // Mask out the relay control pins + // Set pull-up resistors + byte pullupMasked = (pullup & direction); // Only set pullup on/off for inout pins + //Start I2C port Wire.begin(); //Open connection to specified address retryAddress1: Wire.beginTransmission(address); - //Set all channels to outputs + //Set channels 0 and 1 to outputs Wire.write(0x00); - Wire.write(0xFC); + Wire.write(directionMasked); //Determine if device is present at that address byte status = Wire.endTransmission(); Wire.beginTransmission(address); + // turn off pull-up resistors Wire.write(0x06); - Wire.write(0xFC); + Wire.write(pullupMasked); status = Wire.endTransmission(); if(status != 0){ if(retrys < 3){ @@ -449,3 +457,109 @@ int NCD2Relay::readAllInputs(){ byte shifted = inverted >> 2; return shifted; } + +void NCD2Relay::setOutputHigh(int output){ + if(output > 6 || output < 1){ + return; + } + byte bankValue = bankOneStatus; + byte registerAddress = 0x0A; + switch(output){ + case 1: + bankValue = bankValue | 4; + break; + case 2: + bankValue = bankValue | 8; + break; + case 3: + bankValue = bankValue | 16; + break; + case 4: + bankValue = bankValue | 32; + break; + case 5: + bankValue = bankValue | 64; + break; + case 6: + bankValue = bankValue | 128; + break; + } + setOutputHighRetry: + Wire.beginTransmission(address); + Wire.write(registerAddress); + Wire.write(bankValue); + byte status = Wire.endTransmission(); + if(status != 0){ + if(retrys < 3){ + #ifdef LOGGING + Serial.println("Retry Turn On Output command"); + #endif + retrys++; + goto setOutputHighRetry; + }else{ + #ifdef LOGGING + Serial.println("Turn on Relay Failed"); + #endif + initialized = false; + retrys = 0; + } + }else{ + initialized = true; + retrys = 0; + readStatus(); + } + +} + +void NCD2Relay::setOutputLow(int output){ + if(output > 6 || output < 1){ + return; + } + byte bankValue = bankOneStatus; + byte registerAddress = 0x0A; + switch(output){ + case 1: + bankValue = bankValue & ~4; + break; + case 2: + bankValue = bankValue & ~8; + break; + case 3: + bankValue = bankValue & ~16; + break; + case 4: + bankValue = bankValue & ~32; + break; + case 5: + bankValue = bankValue & ~64; + break; + case 6: + bankValue = bankValue & ~128; + break; + } + setOutputLowRetry: + Wire.beginTransmission(address); + Wire.write(registerAddress); + Wire.write(bankValue); + byte status = Wire.endTransmission(); + if(status != 0){ + if(retrys < 3){ + #ifdef LOGGING + Serial.println("Retry Turn Off Output command"); + #endif + retrys++; + goto setOutputLowRetry; + }else{ + #ifdef LOGGING + Serial.println("Turn Off Relay Failed"); + #endif + initialized = false; + retrys = 0; + } + }else{ + initialized = true; + retrys = 0; + readStatus(); + } + +} diff --git a/firmware/NCD2Relay.h b/firmware/NCD2Relay.h index 6d51358..5a984f5 100644 --- a/firmware/NCD2Relay.h +++ b/firmware/NCD2Relay.h @@ -6,8 +6,11 @@ class NCD2Relay{ public: //Constructor NCD2Relay(void); - //Set Address. Indicate status of jumpers on board. Send 0 for not installed, send 1 for installed - void setAddress(int a0, int a1, int a2); + //Set Init. a0 through a1 Indicate status of jumpers on board. Send 0 for not installed, send 1 for installed. + // Optional: direction set GPIO pin as input or output bitwise, 1 input, 0 output + // Optional: pullup set GPIO internal pull-up resistors on or off bitwise, 1 on, 0 off. + // Default address: 000; direction: all inputs; pullup: all enabled. + void setInit(int a0, int a1, int a2, byte direction = 0xFC, byte pullup = 0xFC); //Turn on Relay void turnOnRelay(int relay); //Turn off Relay @@ -28,11 +31,17 @@ class NCD2Relay{ int readInputStatus(int input); //Read status of all inputs int readAllInputs(); + // Turn on output if enabled + void setOutputHigh(int output); + // Turn off output if enabled + void setOutputLow(int output); + // Set input pull-up resistors on or off + //void setPullUp(byte pullup); //User Accessible Variables //Whether or not the controller is ready to accept commands bool initialized; - + private: //internal use method for refreshing bank status variables void readStatus();