forked from JanekOstendorf/THOMAS
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRelayProtocol.cpp
195 lines (146 loc) · 3.37 KB
/
RelayProtocol.cpp
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
-- RelayProtocol-KLASSE :: IMPLEMENTIERUNG --
*/
/* INCLUDES */
// Klassenheader
#include "RelayProtocol.h"
using namespace THOMAS;
// Enthält Methoden für I/O
#include <cstdio>
// Utilities Klasse
#include <cstdlib>
// Enhält Methoden für Strings
#include <cstring>
// POSIX-Definition
#include <unistd.h>
// File-Control-Definitionen
#include <fcntl.h>
// Terminal-IO-Definitionen
#include <termios.h>
// IOStream Klasse
#include <iostream>
RelayProtocol::RelayProtocol()
{
// Anschlussoptionen Struktur
struct termios options;
// Anschlusshandle erstellen
_handle = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
// Anschluss-Flags leeren
fcntl(_handle, F_SETFL, 0);
// Aktuelle Anschluss-Optionen abrufen
tcgetattr(_handle, &options);
// Baundrate setzen (19200)
cfsetispeed(&options, B19200); // Input
cfsetospeed(&options, B19200); // Output
// Schnittstellen-Flags setzen
options.c_cflag &= ~PARENB; // kein Partybit
options.c_cflag &= ~CSTOPB; // 1 Stopbit
options.c_cflag &= ~CSIZE; // 8 Datenbits
options.c_cflag |= CS8;
options.c_cflag |= (CLOCAL | CREAD); // CD Signal ignorieren
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST; // "raw" Input
options.c_cc[VMIN] = 0; // Auf 0 Zeichen warten
options.c_cc[VTIME] = 10; // Timeout 10 Sekunden
// Einstellungen flushen
tcflush(_handle,TCIOFLUSH);
// Attribute setzen
tcsetattr(_handle, TCSAFLUSH, &options);
fcntl(_handle, F_SETFL, FNDELAY);
fcntl(_handle, F_SETFL, 0);
// Relay initialisieren
SendCommand(1, 1, 0);
// Status lesen
if(!ReceiveStatus())
std::cout << "Fehler beim Initialisieren des Relays" << std::endl;
}
void RelayProtocol::SendCommand(UBYTE command, UBYTE address, UBYTE data)
{
// Neues Buffer Array erstellen
UBYTE buff[4];
// Buffer füllen
buff[0] = command;
buff[1] = address;
buff[2] = data;
// Prüfsumme erstellen
buff[3] = buff[0] ^ buff[1] ^ buff[2];
// 50ms warten
usleep(50000);
// Daten absenden und ggf. Fehler ausgeben
if(!write(_handle, buff, 4))
std::cout << "Fehler beim Senden eines Statusbytes an das Relay!" << std::endl;
}
bool RelayProtocol::ReceiveStatus()
{
// Neues Buffer Array erstellen
UBYTE buff[4];
// Daten einlesen
read(_handle, buff, 4);
// Prüfsumme berechnen
int pruefsumme = buff[0] ^ buff[1] ^ buff[2];
// Stimmen die Prüfsummen überein?
if(pruefsumme != buff[3])
return false;
// Erfolg zurückgeben
return true;
}
void RelayProtocol::SetRelay(int port, bool status)
{
// Port Value
UBYTE val = -1;
// Enhält die Relay Daten
UBYTE rval;
// Status prüfen
switch (status)
{
// Relay ausschalten
case false:
{
// Port in Binary umwandeln
val = ~(1 << (port - 1));
// Bitweises UND
rval = rval & val;
break;
}
// Relay anschalten
case true:
{
// Port in Binary umwandeln
val = 1 << (port - 1);
// Bitweises ODER
rval = rval | val;
break;
}
}
// Status senden
SendCommand(3, 1, rval);
// Read-Buffer leeren
ReceiveStatus();
}
void RelayProtocol::SetAll(bool status)
{
// Port Value
UBYTE val = -1;
// Status prüfen
switch (status)
{
// Relay ausschalten
case false:
{
// Port in Binary umwandeln
val = 0;
break;
}
// Relay anschalten
case true:
{
// Port in Binary umwandeln
val = 255;
break;
}
}
// Status senden
SendCommand(3, 1, val);
// Read-Buffer leeren
ReceiveStatus();
}