├── License.html ├── README.txt ├── SerialRelay.h ├── examples ├── Blink │ └── Blink.ino ├── CycleRelays │ └── CycleRelays.ino └── SerialRelay_demo │ └── SerialRelay_demo.ino ├── keywords.txt └── library.properties /License.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GNU Lesser General Public License v3.0 - GNU Project - Free Software Foundation (FSF) 6 | 8 | 9 | 10 |

GNU LESSER GENERAL PUBLIC LICENSE

11 |

Version 3, 29 June 2007

12 | 13 |

Copyright © 2007 Free Software Foundation, Inc. 14 | <http://fsf.org/>

15 | Everyone is permitted to copy and distribute verbatim copies 16 | of this license document, but changing it is not allowed.

17 | 18 |

This version of the GNU Lesser General Public License incorporates 19 | the terms and conditions of version 3 of the GNU General Public 20 | License, supplemented by the additional permissions listed below.

21 | 22 |

0. Additional Definitions.

23 | 24 |

As used herein, “this License” refers to version 3 of the GNU Lesser 25 | General Public License, and the “GNU GPL” refers to version 3 of the GNU 26 | General Public License.

27 | 28 |

“The Library” refers to a covered work governed by this License, 29 | other than an Application or a Combined Work as defined below.

30 | 31 |

An “Application” is any work that makes use of an interface provided 32 | by the Library, but which is not otherwise based on the Library. 33 | Defining a subclass of a class defined by the Library is deemed a mode 34 | of using an interface provided by the Library.

35 | 36 |

A “Combined Work” is a work produced by combining or linking an 37 | Application with the Library. The particular version of the Library 38 | with which the Combined Work was made is also called the “Linked 39 | Version”.

40 | 41 |

The “Minimal Corresponding Source” for a Combined Work means the 42 | Corresponding Source for the Combined Work, excluding any source code 43 | for portions of the Combined Work that, considered in isolation, are 44 | based on the Application, and not on the Linked Version.

45 | 46 |

The “Corresponding Application Code” for a Combined Work means the 47 | object code and/or source code for the Application, including any data 48 | and utility programs needed for reproducing the Combined Work from the 49 | Application, but excluding the System Libraries of the Combined Work.

50 | 51 |

1. Exception to Section 3 of the GNU GPL.

52 | 53 |

You may convey a covered work under sections 3 and 4 of this License 54 | without being bound by section 3 of the GNU GPL.

55 | 56 |

2. Conveying Modified Versions.

57 | 58 |

If you modify a copy of the Library, and, in your modifications, a 59 | facility refers to a function or data to be supplied by an Application 60 | that uses the facility (other than as an argument passed when the 61 | facility is invoked), then you may convey a copy of the modified 62 | version:

63 | 64 | 73 | 74 |

3. Object Code Incorporating Material from Library Header Files.

75 | 76 |

The object code form of an Application may incorporate material from 77 | a header file that is part of the Library. You may convey such object 78 | code under terms of your choice, provided that, if the incorporated 79 | material is not limited to numerical parameters, data structure 80 | layouts and accessors, or small macros, inline functions and templates 81 | (ten or fewer lines in length), you do both of the following:

82 | 83 | 91 | 92 |

4. Combined Works.

93 | 94 |

You may convey a Combined Work under terms of your choice that, 95 | taken together, effectively do not restrict modification of the 96 | portions of the Library contained in the Combined Work and reverse 97 | engineering for debugging such modifications, if you also do each of 98 | the following:

99 | 100 | 144 | 145 |

5. Combined Libraries.

146 | 147 |

You may place library facilities that are a work based on the 148 | Library side by side in a single library together with other library 149 | facilities that are not Applications and are not covered by this 150 | License, and convey such a combined library under terms of your 151 | choice, if you do both of the following:

152 | 153 | 162 | 163 |

6. Revised Versions of the GNU Lesser General Public License.

164 | 165 |

The Free Software Foundation may publish revised and/or new versions 166 | of the GNU Lesser General Public License from time to time. Such new 167 | versions will be similar in spirit to the present version, but may 168 | differ in detail to address new problems or concerns.

169 | 170 |

Each version is given a distinguishing version number. If the 171 | Library as you received it specifies that a certain numbered version 172 | of the GNU Lesser General Public License “or any later version” 173 | applies to it, you have the option of following the terms and 174 | conditions either of that published version or of any later version 175 | published by the Free Software Foundation. If the Library as you 176 | received it does not specify a version number of the GNU Lesser 177 | General Public License, you may choose any version of the GNU Lesser 178 | General Public License ever published by the Free Software Foundation.

179 | 180 |

If the Library as you received it specifies that a proxy can decide 181 | whether future versions of the GNU Lesser General Public License shall 182 | apply, that proxy's public statement of acceptance of any version is 183 | permanent authorization for you to choose that version for the 184 | Library.

185 | 186 | 187 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoboCore/SerialRelay/37942ed11301b67dc8cea69afc93d6380e9399d4/README.txt -------------------------------------------------------------------------------- /SerialRelay.h: -------------------------------------------------------------------------------- 1 | #ifndef RC_SERIAL_RELAY_H 2 | #define RC_SERIAL_RELAY_H 3 | 4 | /* 5 | RoboCore Serial Relay Library 6 | (v1.0 - 20/05/2015) 7 | 8 | Serial Relay functions for Arduino 9 | (tested with Arduino 1.0.1) 10 | 11 | Copyright 2015 RoboCore (François) ( http://www.RoboCore.net ) 12 | 13 | ------------------------------------------------------------------------------ 14 | This program is free software: you can redistribute it and/or modify 15 | it under the terms of the GNU Lesser General Public License as published by 16 | the Free Software Foundation, either version 3 of the License, or 17 | (at your option) any later version. 18 | 19 | This program is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | GNU Lesser General Public License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public License 25 | along with this program. If not, see . 26 | ------------------------------------------------------------------------------ 27 | 28 | */ 29 | 30 | #include 31 | 32 | #define SERIAL_RELAY_MAX_MODULES 10 33 | 34 | #define SERIAL_RELAY_DELAY_DATA 5 // [µs] 35 | #define SERIAL_RELAY_DELAY_CLOCK_HIGH 5 // [µs] 36 | #define SERIAL_RELAY_DELAY_CLOCK_LOW 20 // [µs] 37 | #define SERIAL_RELAY_DELAY_LATCH 1100 // [µs] 38 | 39 | #define SERIAL_RELAY_OFF 0 40 | #define SERIAL_RELAY_ON 1 41 | #define SERIAL_RELAY_NONE 0xFF 42 | 43 | #define SERIAL_RELAY_DEBUG 44 | 45 | //#define ENABLE_INFINITE_STREAM 46 | 47 | class SerialRelay { 48 | public: 49 | // Constructor 50 | SerialRelay(int pinData, int pinClock, byte qty = 1){ 51 | _pinData = pinData; 52 | _pinClock = pinClock; 53 | pinMode(_pinData, OUTPUT); 54 | pinMode(_pinClock, OUTPUT); 55 | digitalWrite(_pinData, LOW); 56 | digitalWrite(_pinClock, LOW); 57 | 58 | _tosend = false; // default 59 | 60 | for(int i=0 ; i < SERIAL_RELAY_MAX_MODULES ; i++) 61 | _data[i] = 0; // default all LOW 62 | 63 | // check and set module qty 64 | _module_qty = qty; 65 | if(qty > SERIAL_RELAY_MAX_MODULES) 66 | _module_qty = SERIAL_RELAY_MAX_MODULES; 67 | #ifndef ENABLE_INFINITE_STREAM 68 | if(qty == 0) 69 | _module_qty = 1; 70 | #endif 71 | } 72 | 73 | // Get the state of the relay (1-based) 74 | byte GetState(byte relay, byte module = 1){ 75 | // check index 76 | if((relay > 8) || (module > SERIAL_RELAY_MAX_MODULES)) 77 | return SERIAL_RELAY_NONE; 78 | 79 | // check if whole mask 80 | if(relay == 0) 81 | return _data[module - 1]; 82 | 83 | byte mask = (1 << (relay - 1)); 84 | if(mask & _data[module - 1]) 85 | return SERIAL_RELAY_ON; 86 | else 87 | return SERIAL_RELAY_OFF; 88 | } 89 | 90 | #ifdef SERIAL_RELAY_DEBUG 91 | // Print all information 92 | void Info(HardwareSerial *stream, byte format = HEX){ 93 | stream->print("Qty:"); 94 | stream->println(_module_qty); 95 | for(int i=0 ; i < _module_qty ; i++){ 96 | stream->print('['); 97 | stream->print(i+1); 98 | stream->print("] - "); 99 | if(format == HEX) 100 | stream->print("0x"); 101 | else if(format == BIN) 102 | stream->print("0b"); 103 | else if(format == OCT) 104 | stream->print('0'); 105 | stream->println(_data[i], format); 106 | } 107 | } 108 | #endif 109 | 110 | // Set all relays at once on one module (1-based) 111 | // NOTE: set send to FALSE to manually write to the shift register 112 | boolean SetModule(byte mask, byte module = 1, boolean send = true){ 113 | // check index 114 | if(module > SERIAL_RELAY_MAX_MODULES) 115 | return false; 116 | 117 | _data[module - 1] = mask; 118 | _tosend = true; 119 | 120 | if(send) 121 | Send(); 122 | 123 | return true; 124 | } 125 | 126 | // Set the relay state on a module (2x 1-based) 127 | // NOTE: set send to FALSE to manually write to the shift register 128 | boolean SetRelay(byte relay, byte state, byte module = 1, boolean send = true){ 129 | // check index 130 | if((relay == 0) || (relay > 8) || (module > SERIAL_RELAY_MAX_MODULES)) 131 | return false; 132 | 133 | if(state == SERIAL_RELAY_ON){ 134 | byte mask = (1 << (relay - 1)); 135 | _data[module - 1] |= mask; 136 | } else { 137 | byte mask = ~(1 << (relay - 1)); 138 | _data[module - 1] &= mask; 139 | } 140 | _tosend = true; 141 | 142 | if(send) 143 | Send(); 144 | 145 | return true; 146 | } 147 | 148 | // Write changes 149 | void Write(void){ 150 | if(_tosend) 151 | Send(); 152 | } 153 | 154 | 155 | private: 156 | int _pinClock; 157 | int _pinData; 158 | byte _module_qty; 159 | byte _data[SERIAL_RELAY_MAX_MODULES]; 160 | boolean _tosend; // TRUE if data to send 161 | 162 | // Send the data 163 | void Send(void){ 164 | byte mask; 165 | boolean last_relay = false; 166 | byte module_number = _module_qty; // start from MAX because the do loop will set it to 0-base at the beginning 167 | do { 168 | // loop infinite stream or increment 169 | if(_module_qty != 0){ 170 | module_number--; 171 | 172 | // check for last relay 173 | if(module_number == 0) 174 | last_relay = true; 175 | } 176 | 177 | // send pulse 178 | mask = 0x80; // reset 179 | for(int i=1 ; i <= 8 ; i++){ 180 | // set Data line 181 | if(_data[module_number] & mask) 182 | digitalWrite(_pinData, HIGH); 183 | else 184 | digitalWrite(_pinData, LOW); 185 | 186 | delayMicroseconds(SERIAL_RELAY_DELAY_DATA); // delay between Data and Clock signals 187 | 188 | // set Clock line 189 | digitalWrite(_pinClock, HIGH); // rising edge 190 | if((i == 8) && last_relay) 191 | delayMicroseconds(SERIAL_RELAY_DELAY_LATCH); // latch 192 | else 193 | delayMicroseconds(SERIAL_RELAY_DELAY_CLOCK_HIGH); // shift 194 | digitalWrite(_pinClock, LOW); 195 | delayMicroseconds(SERIAL_RELAY_DELAY_CLOCK_LOW); // it is acceptable to have 5µs delay after the last bit has been sent 196 | 197 | mask >>= 1; // update mask 198 | } 199 | } while(module_number > 0); 200 | digitalWrite(_pinData, LOW); // reset to maintain LOW level when not in use 201 | 202 | _tosend = false; // reset 203 | } 204 | 205 | }; 206 | 207 | 208 | #endif // RC_SERIAL_RELAY_H 209 | 210 | 211 | 212 | 213 | -------------------------------------------------------------------------------- /examples/Blink/Blink.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | RoboCore - Serial Relay example 4 | (16/07/2015) 5 | 6 | Written by François (based on default Blink example). 7 | 8 | Example of how to use the Serial Relay library. 9 | The relay 1 of module 1 will turn on for one 10 | second, then off for one second, repeatedly. 11 | 12 | */ 13 | 14 | #include 15 | 16 | const byte NumModules = 1; 17 | SerialRelay relays(4,5,NumModules); // (data, clock, number of modules) 18 | 19 | // the setup routine runs once when you press reset: 20 | void setup() { 21 | // nothing to do here 22 | } 23 | 24 | // the loop routine runs over and over again forever: 25 | void loop() { 26 | relays.SetRelay(1, SERIAL_RELAY_ON, 1); // turn the relay ON 27 | delay(1000); // wait for a second 28 | relays.SetRelay(1, SERIAL_RELAY_OFF, 1); // turn the relay OFF 29 | delay(1000); // wait for a second 30 | } 31 | 32 | 33 | -------------------------------------------------------------------------------- /examples/CycleRelays/CycleRelays.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RoboCore - Serial Relay example 3 | (19/06/2015) 4 | 5 | Written by François. 6 | 7 | Example of how to use the Serial Relay library. 8 | The relays will be energized one by one and then 9 | de-energized one by one. 10 | 11 | */ 12 | 13 | #include 14 | 15 | const int NumModules = 2; // maximum of 10 16 | const int PauseTime = 1000; // [ms] 17 | 18 | SerialRelay relays(4,5,NumModules); // (data, clock, number of modules) 19 | 20 | // -------------------------------------------------------------- 21 | 22 | void setup(){ 23 | Serial.begin(19200); 24 | relays.Info(&Serial,BIN); 25 | Serial.println(); 26 | } 27 | 28 | // -------------------------------------------------------------- 29 | 30 | void loop(){ 31 | // turn on one by one starting from relay 1 & module 1 32 | for(int i=1 ; i <= NumModules ; i++){ 33 | for(int j=1 ; j <= 4 ; j++){ 34 | relays.SetRelay(j, SERIAL_RELAY_ON, i); 35 | delay(PauseTime); 36 | } 37 | } 38 | 39 | // turn off one by one starting from relay 1 & module 1 40 | for(int i=1 ; i <= NumModules ; i++){ 41 | for(int j=1 ; j <= 4 ; j++){ 42 | relays.SetRelay(j, SERIAL_RELAY_OFF, i); 43 | delay(PauseTime); 44 | } 45 | } 46 | } 47 | 48 | // -------------------------------------------------------------- 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/SerialRelay_demo/SerialRelay_demo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RoboCore - Serial Relay example 3 | (20/05/2015) 4 | 5 | Written by François. 6 | 7 | Example of how to use the Serial Relay library. 8 | Control the state of the relay on a module or 9 | the state of all the relays in one module. 10 | End all serial commands with the '#' character: 11 | - '+x' >> turn ON relay X on active module; 12 | - '-x' >> turn OFF relay X on active module; 13 | - 'my' >> select module Y; 14 | - 'My' >> " " 15 | - 'HH' >> set the state of all the relays 16 | on the active module. HH must be 17 | replaced by a valid hexadecimal 18 | value (00 to FF). 19 | ! acceptable values for X are 1 to 8 20 | ! acceptable values for Y are 1 to 9 21 | 22 | 23 | Note: this example requires the String Functions 24 | v1.5 library (available at 25 | https://github.com/RoboCore/String_Functions) 26 | 27 | */ 28 | 29 | //#include 30 | //void PCINT_Extension2(void){} 31 | 32 | #include 33 | #include "SerialRelay.h" 34 | 35 | 36 | SerialRelay relays(4,5,8); // (data, clock, number of modules) 37 | byte module = 1; 38 | 39 | #define BUFFER_SIZE 3 40 | char buffer[BUFFER_SIZE]; 41 | 42 | void setup(){ 43 | Serial.begin(19200); 44 | relays.SetModule(0x00,1,false); 45 | relays.SetModule(0x55,2); 46 | relays.Info(&Serial); 47 | } 48 | 49 | void loop(){ 50 | 51 | if(ReadFromSerial(&Serial, buffer, BUFFER_SIZE, '#')){ 52 | 53 | if((buffer[0] == 'm') || (buffer[0] == 'M')){ 54 | if((buffer[1] >= '1') && (buffer[1] <= '9')){ 55 | module = buffer[1] - '0'; 56 | Serial.print("Module "); 57 | Serial.println(module); 58 | } 59 | } 60 | 61 | if(buffer[0] == 'i') 62 | relays.Info(&Serial); 63 | 64 | 65 | if((buffer[0] == '+') || (buffer[0] == '-')){ 66 | if((buffer[1] >= '1') && (buffer[1] <= '8')){ 67 | byte state = SERIAL_RELAY_OFF; 68 | if(buffer[0] == '+'){ 69 | state = SERIAL_RELAY_ON; 70 | } 71 | byte relay = (buffer[1] - '0'); 72 | relays.SetRelay(relay, state, module); 73 | Serial.print("Set #"); 74 | Serial.print(relay); 75 | Serial.print(" - "); 76 | Serial.println(state); 77 | } 78 | } 79 | 80 | if(((buffer[0] >= '0') && (buffer[0] <= '9')) || ((buffer[0] >= 'A') && (buffer[0] <= 'F'))){ 81 | byte value = 0x00; 82 | if(buffer[0] <= '9') 83 | value = (buffer[0] - '0') * 16; 84 | else 85 | value = (buffer[0] - 'A' + 10) * 16; 86 | 87 | if(((buffer[1] >= '0') && (buffer[1] <= '9')) || ((buffer[1] >= 'A') && (buffer[1] <= 'F'))){ 88 | if(buffer[1] <= '9') 89 | value += (buffer[1] - '0'); 90 | else 91 | value += (buffer[1] - 'A' + 10); 92 | 93 | Serial.print("Value = "); 94 | Serial.println(value, HEX); 95 | relays.SetModule(value, module); 96 | } 97 | } 98 | } 99 | 100 | } 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | 2 | SerialRelay KEYWORD1 3 | 4 | GetState KEYWORD2 5 | Info KEYWORD2 6 | SetModule KEYWORD2 7 | SetRelay KEYWORD2 8 | Write KEYWORD2 9 | 10 | SERIAL_RELAY_ON LITERAL1 11 | SERIAL_RELAY_OFF LITERAL1 12 | 13 | 14 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=RoboCore - Serial Relay 2 | version=1.0.0 3 | author=RoboCore Tecnologia (suporte@robocore.net) 4 | maintainer=RoboCore Tecnologia (suporte@robocore.net) 5 | sentence=Library for the Serial Relay module (https://www.robocore.net/modules.php?name=GR_LojaVirtual&prod=663) 6 | paragraph=Control up to 40 relays with only two pins. 7 | category=Device Control 8 | url=https://github.com/RoboCore/SerialRelay 9 | architectures=* 10 | --------------------------------------------------------------------------------