-
Notifications
You must be signed in to change notification settings - Fork 1
/
Qwiic_Relay_Firmware.ino
133 lines (102 loc) · 3.64 KB
/
Qwiic_Relay_Firmware.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/******************************************************************************
Qwiic Relay Firmware
Kevin Kuwata @ SparkX
March 21, 2018
https://github.com/sparkfunX/Qwiic_Relay
Arduino 1.8.5
This is the firmware on the Qwiic Relay. The default I2C Address is
0x18;
******************************************************************************/
#include <TinyWire.h> //https://github.com/lucullusTheOnly/TinyWire
#include <EEPROM.h>
#define RELAY_PIN 4
#define SETTING_LOCATION_ADDRESS 1
volatile byte qwiicRelayAddress = 0x18; //default
const byte relayAddressPin = 3;
#define COMMAND_RELAY_OFF 0x00
#define COMMAND_RELAY_ON 0x01
#define COMMAND_CHANGE_ADDRESS 0x03
#define COMMAND_FIRMWARE_VERSION 0x04
#define COMMAND_STATUS 0x05
#define COMMAND_HAS_BEEN_CHECKED 0x99
const byte firmwareVersionMajor = 1;
const byte firmwareVersionMinor = 1;
volatile byte command = COMMAND_HAS_BEEN_CHECKED;
volatile byte address = COMMAND_HAS_BEEN_CHECKED;
void setup() {
pinMode(relayAddressPin, INPUT);
digitalWrite(relayAddressPin, HIGH); //internal pull up
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
if(digitalRead(relayAddressPin) == 0){
qwiicRelayAddress = 0x19;
}
else{
//Read EEPROM, is it empty (0xFF)? or does it have a value?
qwiicRelayAddress = EEPROM.read(SETTING_LOCATION_ADDRESS);
if (qwiicRelayAddress == 0xFF) {
//EEPROM has never been written before, use the default address 0x18.
qwiicRelayAddress = 0x18; //default
}
}
TinyWire.begin(qwiicRelayAddress);
TinyWire.onReceive(receiveEvent); // register event
TinyWire.onRequest(onI2CRequest);
}
void loop() {
}
/*========================================================*/
// ISR
/*========================================================*/
// When the master initiates a command and data to slave
// ie) the master says 0x01, then sends a 1, means command: 0x01 then the slave listens for the next thing, which is the relay state 1
void receiveEvent(int bytesReceived) {
byte count = 0;
while (TinyWire.available() > 0) {
if (count == 0) {
command = TinyWire.read();
if (command == COMMAND_RELAY_ON) {
digitalWrite(RELAY_PIN, HIGH);
command = COMMAND_HAS_BEEN_CHECKED;
}
else if (command == COMMAND_RELAY_OFF) {
digitalWrite(RELAY_PIN, LOW);
command = COMMAND_HAS_BEEN_CHECKED;
}
}
else if (count == 1) {
if (command == COMMAND_CHANGE_ADDRESS) {
byte address = TinyWire.read();
if (address > 0x07 && address < 0x78) {
//valid address, update and save to EEPROM
qwiicRelayAddress = address;
EEPROM.write(SETTING_LOCATION_ADDRESS, qwiicRelayAddress);
TinyWire.begin(qwiicRelayAddress);
}
}
}
else {
TinyWire.read(); //read the data coming in but ignore it.
}
count++;
}
}// end of receive ISR
//When the master requests data from the slave, this
// ISR is triggered.
void onI2CRequest() {
//not sure if this will work because the master sends 0x04, then the salve enters the RX event isr
// then goes to main, sets the flag. then if that happens slower than versionFlag we have a race condition.
if (command == COMMAND_FIRMWARE_VERSION) {
//TinyWire.send(firmwareVersion);// tiny wire can't send multiple bytes.
TinyWire.send(firmwareVersionMajor);
TinyWire.send(firmwareVersionMinor);
command = COMMAND_HAS_BEEN_CHECKED;
}
else if (command == COMMAND_STATUS) {
if (digitalRead(RELAY_PIN) == HIGH)
TinyWire.send(COMMAND_RELAY_ON);
else
TinyWire.send(COMMAND_RELAY_OFF);
command = COMMAND_HAS_BEEN_CHECKED;
}
}