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 |
65 |
a) under this License, provided that you make a good faith effort to
66 | ensure that, in the event an Application does not supply the
67 | function or data, the facility still operates, and performs
68 | whatever part of its purpose remains meaningful, or
69 |
70 |
b) under the GNU GPL, with none of the additional permissions of
71 | this License applicable to that copy.
72 |
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 |
84 |
a) Give prominent notice with each copy of the object code that the
85 | Library is used in it and that the Library and its use are
86 | covered by this License.
87 |
88 |
b) Accompany the object code with a copy of the GNU GPL and this license
89 | document.
90 |
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 |
101 |
a) Give prominent notice with each copy of the Combined Work that
102 | the Library is used in it and that the Library and its use are
103 | covered by this License.
104 |
105 |
b) Accompany the Combined Work with a copy of the GNU GPL and this license
106 | document.
107 |
108 |
c) For a Combined Work that displays copyright notices during
109 | execution, include the copyright notice for the Library among
110 | these notices, as well as a reference directing the user to the
111 | copies of the GNU GPL and this license document.
112 |
113 |
d) Do one of the following:
114 |
115 |
116 |
0) Convey the Minimal Corresponding Source under the terms of this
117 | License, and the Corresponding Application Code in a form
118 | suitable for, and under terms that permit, the user to
119 | recombine or relink the Application with a modified version of
120 | the Linked Version to produce a modified Combined Work, in the
121 | manner specified by section 6 of the GNU GPL for conveying
122 | Corresponding Source.
123 |
124 |
1) Use a suitable shared library mechanism for linking with the
125 | Library. A suitable mechanism is one that (a) uses at run time
126 | a copy of the Library already present on the user's computer
127 | system, and (b) will operate properly with a modified version
128 | of the Library that is interface-compatible with the Linked
129 | Version.
130 |
131 |
132 |
e) Provide Installation Information, but only if you would otherwise
133 | be required to provide such information under section 6 of the
134 | GNU GPL, and only to the extent that such information is
135 | necessary to install and execute a modified version of the
136 | Combined Work produced by recombining or relinking the
137 | Application with a modified version of the Linked Version. (If
138 | you use option 4d0, the Installation Information must accompany
139 | the Minimal Corresponding Source and Corresponding Application
140 | Code. If you use option 4d1, you must provide the Installation
141 | Information in the manner specified by section 6 of the GNU GPL
142 | for conveying Corresponding Source.)
143 |
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 |
154 |
a) Accompany the combined library with a copy of the same work based
155 | on the Library, uncombined with any other library facilities,
156 | conveyed under the terms of this License.
157 |
158 |
b) Give prominent notice with the combined library that part of it
159 | is a work based on the Library, and explaining where to find the
160 | accompanying uncombined form of the same work.
161 |
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 |
--------------------------------------------------------------------------------