init main app code
This commit is contained in:
315
RpiLedBars/src/artnet/ArtnetnodeWifi.cpp
Normal file
315
RpiLedBars/src/artnet/ArtnetnodeWifi.cpp
Normal file
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
|
||||
Copyright (c) Charles Yarnold charlesyarnold@gmail.com 2015
|
||||
|
||||
Copyright (c) 2016-2020 Stephan Ruloff
|
||||
https://github.com/rstephan/ArtnetnodeWifi
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, under version 2 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include <ArtnetnodeWifi.h>
|
||||
|
||||
|
||||
const char ArtnetnodeWifi::artnetId[] = ARTNET_ID;
|
||||
|
||||
ArtnetnodeWifi::ArtnetnodeWifi()
|
||||
{
|
||||
// Initalise DMXOutput array
|
||||
for (int i = 0; i < DMX_MAX_OUTPUTS; i++) {
|
||||
DMXOutputs[i][0] = 0xFF;
|
||||
DMXOutputs[i][1] = 0xFF;
|
||||
DMXOutputs[i][2] = 0;
|
||||
}
|
||||
|
||||
// Start DMX tick clock
|
||||
msSinceDMXSend = 0;
|
||||
|
||||
// Init DMX buffers
|
||||
for (int i = 0; i < DMX_MAX_OUTPUTS; i++) {
|
||||
memset(DMXBuffer[i], 0, sizeof(DMXBuffer[i]));
|
||||
}
|
||||
|
||||
sequence = 1;
|
||||
physical = 0;
|
||||
outgoingUniverse = 0;
|
||||
dmxDataLength = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@retval 0 Ok
|
||||
*/
|
||||
uint8_t ArtnetnodeWifi::begin(String hostname)
|
||||
{
|
||||
byte mac[6];
|
||||
|
||||
Udp.begin(ARTNET_PORT);
|
||||
localIP = WiFi.localIP();
|
||||
localMask = WiFi.subnetMask();
|
||||
localBroadcast = IPAddress((uint32_t)localIP | ~(uint32_t)localMask);
|
||||
|
||||
WiFi.macAddress(mac);
|
||||
PollReplyPacket.setMac(mac);
|
||||
PollReplyPacket.setIP(localIP);
|
||||
PollReplyPacket.canDHCP(true);
|
||||
PollReplyPacket.isDHCP(true);
|
||||
|
||||
host = hostname;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::setShortName(const char name[])
|
||||
{
|
||||
PollReplyPacket.setShortName(name);
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::setLongName(const char name[])
|
||||
{
|
||||
PollReplyPacket.setLongName(name);
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::setName(const char name[])
|
||||
{
|
||||
PollReplyPacket.setShortName(name);
|
||||
PollReplyPacket.setLongName(name);
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::setNumPorts(uint8_t num)
|
||||
{
|
||||
PollReplyPacket.setNumPorts(num);
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::setStartingUniverse(uint16_t startingUniverse)
|
||||
{
|
||||
PollReplyPacket.setStartingUniverse(startingUniverse);
|
||||
}
|
||||
|
||||
uint16_t ArtnetnodeWifi::read()
|
||||
{
|
||||
uint8_t startcode;
|
||||
|
||||
packetSize = Udp.parsePacket();
|
||||
|
||||
if (packetSize <= ARTNET_MAX_BUFFER && packetSize > 0) {
|
||||
Udp.read(artnetPacket, ARTNET_MAX_BUFFER);
|
||||
|
||||
// Check that packetID is "Art-Net" else ignore
|
||||
if (memcmp(artnetPacket, artnetId, sizeof(artnetId)) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
opcode = artnetPacket[8] | artnetPacket[9] << 8;
|
||||
|
||||
switch (opcode) {
|
||||
case OpDmx:
|
||||
return handleDMX(0);
|
||||
case OpPoll:
|
||||
return handlePollRequest();
|
||||
case OpNzs:
|
||||
startcode = artnetPacket[13];
|
||||
if (startcode != 0 && startcode != DMX_RDM_STARTCODE) {
|
||||
return handleDMX(startcode);
|
||||
}
|
||||
}
|
||||
|
||||
return opcode;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t ArtnetnodeWifi::makePacket(void)
|
||||
{
|
||||
uint16_t len;
|
||||
uint16_t version;
|
||||
|
||||
memcpy(artnetPacket, artnetId, sizeof(artnetId));
|
||||
opcode = OpDmx;
|
||||
artnetPacket[8] = opcode;
|
||||
artnetPacket[9] = opcode >> 8;
|
||||
version = 14;
|
||||
artnetPacket[10] = version >> 8;
|
||||
artnetPacket[11] = version;
|
||||
artnetPacket[12] = sequence;
|
||||
sequence++;
|
||||
if (!sequence) {
|
||||
sequence = 1;
|
||||
}
|
||||
artnetPacket[13] = physical;
|
||||
artnetPacket[14] = outgoingUniverse;
|
||||
artnetPacket[15] = outgoingUniverse >> 8;
|
||||
len = dmxDataLength + (dmxDataLength % 2); // make an even number
|
||||
artnetPacket[16] = len >> 8;
|
||||
artnetPacket[17] = len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int ArtnetnodeWifi::write(void)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
len = makePacket();
|
||||
Udp.beginPacket(host.c_str(), ARTNET_PORT);
|
||||
Udp.write(artnetPacket, ARTNET_DMX_START_LOC + len);
|
||||
|
||||
return Udp.endPacket();
|
||||
}
|
||||
|
||||
int ArtnetnodeWifi::write(IPAddress ip)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
len = makePacket();
|
||||
Udp.beginPacket(ip, ARTNET_PORT);
|
||||
Udp.write(artnetPacket, ARTNET_DMX_START_LOC + len);
|
||||
|
||||
return Udp.endPacket();
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::setByte(uint16_t pos, uint8_t value)
|
||||
{
|
||||
if (pos > 512) {
|
||||
return;
|
||||
}
|
||||
artnetPacket[ARTNET_DMX_START_LOC + pos] = value;
|
||||
}
|
||||
|
||||
|
||||
bool ArtnetnodeWifi::isBroadcast()
|
||||
{
|
||||
if (Udp.remoteIP() == localBroadcast){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ArtnetnodeWifi::handleDMX(uint8_t nzs)
|
||||
{
|
||||
if (isBroadcast()) {
|
||||
return 0;
|
||||
} else {
|
||||
// Get universe
|
||||
uint16_t universe = artnetPacket[14] | artnetPacket[15] << 8;
|
||||
|
||||
// Get DMX frame length
|
||||
uint16_t dmxDataLength = artnetPacket[17] | artnetPacket[16] << 8;
|
||||
|
||||
// Sequence
|
||||
uint8_t sequence = artnetPacket[12];
|
||||
|
||||
if (artDmxCallback) {
|
||||
(*artDmxCallback)(universe, dmxDataLength, sequence, artnetPacket + ARTNET_DMX_START_LOC);
|
||||
}
|
||||
|
||||
for(int a = 0; a < DMX_MAX_OUTPUTS; a++){
|
||||
if(DMXOutputs[a][1] == universe){
|
||||
for (int i = 0 ; i < DMX_MAX_BUFFER ; i++){
|
||||
if(i < dmxDataLength){
|
||||
DMXBuffer[a][i] = artnetPacket[i+ARTNET_DMX_START_LOC];
|
||||
}
|
||||
else{
|
||||
DMXBuffer[a][i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nzs) {
|
||||
return OpNzs;
|
||||
} else {
|
||||
return OpDmx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ArtnetnodeWifi::handlePollRequest()
|
||||
{
|
||||
if (1 || isBroadcast()) {
|
||||
Udp.beginPacket(localBroadcast, ARTNET_PORT);
|
||||
Udp.write(PollReplyPacket.printPacket(), sizeof(PollReplyPacket.packet));
|
||||
Udp.endPacket();
|
||||
|
||||
return OpPoll;
|
||||
} else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::enableDMX()
|
||||
{
|
||||
DMXOutputStatus = true;
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::disableDMX()
|
||||
{
|
||||
DMXOutputStatus = false;
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::enableDMXOutput(uint8_t outputID)
|
||||
{
|
||||
DMXOutputs[outputID][2] = 1;
|
||||
|
||||
int numEnabled = 0;
|
||||
for(int i = 0; i < DMX_MAX_OUTPUTS; i++){
|
||||
if(DMXOutputs[i][2]==1){
|
||||
if(numEnabled<4){
|
||||
numEnabled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
PollReplyPacket.setNumPorts(numEnabled);
|
||||
PollReplyPacket.setOutputEnabled(outputID);
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::disableDMXOutput(uint8_t outputID)
|
||||
{
|
||||
DMXOutputs[outputID][2] = 0;
|
||||
|
||||
int numEnabled = 0;
|
||||
for(int i = 0; i < DMX_MAX_OUTPUTS; i++){
|
||||
if(DMXOutputs[i][2]==1){
|
||||
if(numEnabled<4){
|
||||
numEnabled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
PollReplyPacket.setNumPorts(numEnabled);
|
||||
PollReplyPacket.setOutputDisabled(outputID);
|
||||
}
|
||||
|
||||
uint8_t ArtnetnodeWifi::setDMXOutput(uint8_t outputID, uint8_t uartNum, uint16_t attachedUniverse)
|
||||
{
|
||||
// Validate input
|
||||
if(outputID < DMX_MAX_OUTPUTS && uartNum != 0xFF && attachedUniverse != 0xFF){
|
||||
DMXOutputs[outputID][0] = uartNum;
|
||||
DMXOutputs[outputID][1] = attachedUniverse;
|
||||
DMXOutputs[outputID][2] = 0;
|
||||
PollReplyPacket.setSwOut(outputID, attachedUniverse);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ArtnetnodeWifi::tickDMX(uint32_t time)
|
||||
{
|
||||
msSinceDMXSend += time;
|
||||
if(msSinceDMXSend > DMX_MS_BETWEEN_TICKS){
|
||||
sendDMX();
|
||||
msSinceDMXSend = 0;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user