Skip to content

Commit caac7c0

Browse files
committed
Squashed/Edited commit of the following:
commit ba336aa Author: Bill C <[email protected]> Date: Wed Mar 5 20:36:21 2025 -0600 Add 30s retry to USBRelay Init for reliable boot-time USB detection Add 30s retry to USBRelay Init for reliable boot-time USB detection - Added delay to handle USB enumeration timing (~15-30s) - Ensures CH340 and ICStation relays initialize consistently commit 39902f9 Author: Bill C <[email protected]> Date: Sun Mar 2 20:46:19 2025 -0600 Revert "trying stuff until I get it" This reverts commit c6bd365. commit c6bd365 Author: Bill C <[email protected]> Date: Sun Mar 2 08:44:18 2025 -0600 trying stuff until I get it commit 0c0d46a Author: Bill Carriveau <[email protected]> Date: Sat Mar 1 09:27:26 2025 -0600 Update co-other.php Trying to keep things the way they were before. :) commit f53ad80 Author: Bill C <[email protected]> Date: Fri Feb 28 23:16:46 2025 -0600 Add CH340 UsbRelay Have compiling and verified working on pi
1 parent f4b497a commit caac7c0

File tree

3 files changed

+44
-88
lines changed

3 files changed

+44
-88
lines changed

src/channeloutput/USBRelay.cpp

Lines changed: 37 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,13 @@
1717
#include "../Warnings.h"
1818
#include "../log.h"
1919

20+
#include "Plugin.h"
2021
#include "USBRelay.h"
21-
#include "serialutil.h"
2222

23-
#include "Plugin.h"
2423
class USBRelayPlugin : public FPPPlugins::Plugin, public FPPPlugins::ChannelOutputPlugin {
2524
public:
2625
USBRelayPlugin() :
27-
FPPPlugins::Plugin("USBRelay") {
28-
}
26+
FPPPlugins::Plugin("USBRelay") {}
2927
virtual ChannelOutput* createChannelOutput(unsigned int startChannel, unsigned int channelCount) override {
3028
return new USBRelayOutput(startChannel, channelCount);
3129
}
@@ -39,19 +37,12 @@ FPPPlugins::Plugin* createPlugin() {
3937

4038
/////////////////////////////////////////////////////////////////////////////
4139

42-
/*
43-
*
44-
*/
45-
USBRelayOutput::USBRelayOutput(unsigned int startChannel,
46-
unsigned int channelCount) :
40+
USBRelayOutput::USBRelayOutput(unsigned int startChannel, unsigned int channelCount) :
4741
ChannelOutput(startChannel, channelCount), SerialChannelOutput(), m_subType(RELAY_DVC_UNKNOWN), m_relayCount(0) {
4842
LogDebug(VB_CHANNELOUT, "USBRelayOutput::USBRelayOutput(%u, %u)\n",
4943
startChannel, channelCount);
5044
}
5145

52-
/*
53-
*
54-
*/
5546
USBRelayOutput::~USBRelayOutput() {
5647
LogDebug(VB_CHANNELOUT, "USBRelayOutput::~USBRelayOutput()\n");
5748
}
@@ -60,9 +51,6 @@ void USBRelayOutput::GetRequiredChannelRanges(const std::function<void(int, int)
6051
addRange(m_startChannel, m_startChannel + m_relayCount - 1);
6152
}
6253

63-
/*
64-
*
65-
*/
6654
int USBRelayOutput::Init(Json::Value config) {
6755
LogDebug(VB_CHANNELOUT, "USBRelayOutput::Init(JSON)\n");
6856

@@ -72,13 +60,16 @@ int USBRelayOutput::Init(Json::Value config) {
7260
m_subType = RELAY_DVC_BIT;
7361
else if (subType == "ICStation")
7462
m_subType = RELAY_DVC_ICSTATION;
63+
else if (subType == "CH340")
64+
m_subType = RELAY_DVC_CH340;
7565

7666
m_relayCount = config["channelCount"].asInt();
7767

7868
if (m_subType == RELAY_DVC_UNKNOWN) {
79-
LogErr(VB_CHANNELOUT, "Invalid Config: invalid type\n");
69+
LogErr(VB_CHANNELOUT, "Invalid Config, missing device or invalid type\n");
8070
return 0;
8171
}
72+
8273
if (!setupSerialPort(config, 9600, "8N1")) {
8374
return 0;
8475
}
@@ -94,10 +85,9 @@ int USBRelayOutput::Init(Json::Value config) {
9485
usleep(500000);
9586

9687
bool foundICS = false;
97-
int res = 0;
98-
res = read(m_fd, &c_reply, 1);
88+
int res = read(m_fd, &c_reply, 1);
9989
if (res == 0) {
100-
LogWarn(VB_CHANNELOUT, "Did not receive a response byte from ICstation relay, unable to confirm number of relays. Using configuration value from UI\n");
90+
LogWarn(VB_CHANNELOUT, "Did not receive a response byte from ICstation relay\n");
10191
} else if (c_reply == 0xAB) {
10292
LogInfo(VB_CHANNELOUT, "Found a 4-channel ICStation relay module\n");
10393
m_relayCount = 4;
@@ -118,53 +108,56 @@ int USBRelayOutput::Init(Json::Value config) {
118108

119109
if (foundICS)
120110
write(m_fd, &c_open, 1);
111+
} else if (m_subType == RELAY_DVC_CH340) {
112+
LogInfo(VB_CHANNELOUT, "Initializing CH340 USB Relay with %d channels\n", m_relayCount);
121113
}
122114

123115
return ChannelOutput::Init(config);
124116
}
125117

126-
/*
127-
*
128-
*/
129118
int USBRelayOutput::Close(void) {
130119
LogDebug(VB_CHANNELOUT, "USBRelayOutput::Close()\n");
131120
closeSerialPort();
132121
return ChannelOutput::Close();
133122
}
134123

135-
/*
136-
*
137-
*/
138124
int USBRelayOutput::SendData(unsigned char* channelData) {
139125
LogExcess(VB_CHANNELOUT, "USBRelayOutput::RawSendData(%p)\n", channelData);
140126

141-
char out = 0x00;
142-
int shiftBits = 0;
143-
144-
for (int i = 0; i < m_relayCount; i++) {
145-
if ((i > 0) && ((i % 8) == 0)) {
146-
// Write out previous byte
147-
write(m_fd, &out, 1);
148-
out = 0x00;
149-
shiftBits = 0;
127+
if (m_subType == RELAY_DVC_CH340) {
128+
// CH340-specific logic: Send a 4-byte command for each relay to control its state
129+
unsigned char cmd[4] = { 0xA0, 0, 0, 0 }; // Initialize the command array: byte 0 is the start flag (0xA0)
130+
for (int i = 0; i < m_relayCount; i++) { // Loop over each relay channel (1 to m_relayCount)
131+
cmd[1] = i + 1; // Byte 1: Relay number (1-based: 1 to 8 for an 8-channel relay)
132+
cmd[2] = channelData[i] ? 1 : 0; // Byte 2: Relay state (1 for ON, 0 for OFF), based on channelData[i]
133+
cmd[3] = cmd[0] + cmd[1] + cmd[2]; // Byte 3: Checksum, sum of bytes 0, 1, and 2
134+
write(m_fd, cmd, 4); // Write the 4-byte command to the serial device (m_fd) to control the relay
135+
}
136+
} else {
137+
// Non-CH340 (Bit or ICStation) logic: Send data as a bitstream, 8 bits per byte
138+
char out = 0x00;
139+
int shiftBits = 0;
140+
141+
for (int i = 0; i < m_relayCount; i++) {
142+
if ((i > 0) && ((i % 8) == 0)) {
143+
write(m_fd, &out, 1);
144+
out = 0x00;
145+
shiftBits = 0;
146+
}
147+
148+
out |= (channelData[i] ? 1 : 0) << shiftBits;
149+
shiftBits++;
150150
}
151151

152-
out |= (channelData[i] ? 1 : 0) << shiftBits;
153-
shiftBits++;
152+
if (shiftBits)
153+
write(m_fd, &out, 1);
154154
}
155155

156-
// Write out any unwritten bits
157-
if (shiftBits)
158-
write(m_fd, &out, 1);
159-
160156
return m_relayCount;
161157
}
162158

163-
/*
164-
*
165-
*/
166159
void USBRelayOutput::DumpConfig(void) {
167160
LogDebug(VB_CHANNELOUT, "USBRelayOutput::DumpConfig()\n");
168161
dumpSerialConfig();
169162
ChannelOutput::DumpConfig();
170-
}
163+
}

src/channeloutput/USBRelay.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ class USBRelayOutput : public ChannelOutput, public SerialChannelOutput {
3434
enum RelayType {
3535
RELAY_DVC_UNKNOWN,
3636
RELAY_DVC_BIT,
37-
RELAY_DVC_ICSTATION
37+
RELAY_DVC_ICSTATION,
38+
RELAY_DVC_CH340
3839
};
3940

4041
RelayType m_subType;
4142
int m_relayCount;
42-
};
43+
};

0 commit comments

Comments
 (0)