add artnet
This commit is contained in:
parent
bc9e06ba03
commit
c3a4b00682
3 changed files with 209 additions and 8 deletions
120
movinghead/artnetSend.py
Normal file
120
movinghead/artnetSend.py
Normal file
|
@ -0,0 +1,120 @@
|
|||
import socket
|
||||
import struct
|
||||
|
||||
import time
|
||||
import math
|
||||
|
||||
class ArtNet():
|
||||
packet_counter = 1
|
||||
dmxdata = [0, 0]
|
||||
|
||||
def __init__(self, artnet_net, artnet_subnet, artnet_universe, ip, port):
|
||||
self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.net = int(artnet_net)
|
||||
self.subnet = int(artnet_subnet)
|
||||
self.universe = int(artnet_universe)
|
||||
self.ip = ip
|
||||
self.port = int(port)
|
||||
print(self.port)
|
||||
#logger.debug("Init ArtNet Plugin done")
|
||||
|
||||
def run(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.close()
|
||||
|
||||
def __call__(self, var1=None, var2=None):
|
||||
if type(var1) == int and type(var2) == int:
|
||||
self.send_single_value(var1, var2)
|
||||
if type(var1) == int and type(var2) == list:
|
||||
self.send_frame_starting_at(var1, var2)
|
||||
if type(var1) == list and type(var2) == type(None):
|
||||
self.send_frame(var1)
|
||||
|
||||
def send_single_value(self, adr, value):
|
||||
if adr < 1 or adr > 512:
|
||||
#logger.error("DMX address %s invalid" % adr)
|
||||
return
|
||||
|
||||
while len(self.dmxdata) < adr:
|
||||
self.dmxdata.append(0)
|
||||
self.dmxdata[adr - 1] = value
|
||||
self.__ArtDMX_broadcast()
|
||||
|
||||
def send_frame_starting_at(self, adr, values):
|
||||
if adr < 1 or adr > (512 - len(values) + 1):
|
||||
#logger.error("DMX address %s with length %s invalid" %
|
||||
# (adr, len(values)))
|
||||
return
|
||||
|
||||
while len(self.dmxdata) < (adr + len(values) - 1):
|
||||
self.dmxdata.append(0)
|
||||
cnt = 0
|
||||
for value in values:
|
||||
self.dmxdata[adr - 1 + cnt] = value
|
||||
cnt += 1
|
||||
self.__ArtDMX_broadcast()
|
||||
|
||||
def send_frame(self, dmxframe):
|
||||
if len(dmxframe) < 2:
|
||||
#logger.error("Send at least 2 channels")
|
||||
return
|
||||
self.dmxdata = dmxframe
|
||||
self.__ArtDMX_broadcast()
|
||||
|
||||
def __ArtDMX_broadcast(self):
|
||||
# logger.info("Incomming DMX: %s"%self.dmxdata)
|
||||
# New Array
|
||||
data = []
|
||||
# Fix ID 7byte + 0x00
|
||||
data.append("Art-Net\x00")
|
||||
# OpCode = OpOutput / OpDmx -> 0x5000, Low Byte first
|
||||
data.append(struct.pack('<H', 0x5000))
|
||||
# ProtVerHi and ProtVerLo -> Protocol Version 14, High Byte first
|
||||
data.append(struct.pack('>H', 14))
|
||||
# Order 1 to 255
|
||||
data.append(struct.pack('B', self.packet_counter))
|
||||
self.packet_counter += 1
|
||||
if self.packet_counter > 255:
|
||||
self.packet_counter = 1
|
||||
# Physical Input Port
|
||||
data.append(struct.pack('B', 0))
|
||||
# Artnet source address
|
||||
data.append(
|
||||
struct.pack('<H', self.net << 8 | self.subnet << 4 | self.universe))
|
||||
# Length of DMX Data, High Byte First
|
||||
data.append(struct.pack('>H', len(self.dmxdata)))
|
||||
# DMX Data
|
||||
for d in self.dmxdata:
|
||||
data.append(struct.pack('B', d))
|
||||
# convert from list to string
|
||||
result = bytes()
|
||||
for token in data:
|
||||
try: # Handels all strings
|
||||
result = result + token.encode('utf-8', 'ignore')
|
||||
except: # Handels all bytes
|
||||
result = result + token
|
||||
|
||||
self.s.sendto(result, (self.ip, self.port))
|
||||
|
||||
def close(self):
|
||||
self.s.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
artnet_subnet = 0
|
||||
artnet_net = 0
|
||||
artnet_universe = 1
|
||||
ip = '195.160.169.161'
|
||||
port = 6454
|
||||
|
||||
sh = ArtNet(artnet_net, artnet_subnet, artnet_universe, ip, port)
|
||||
|
||||
value = 0
|
||||
while True:
|
||||
#sh.send_single_value(1,value)
|
||||
#sh.send_frame([128,0,128,0])
|
||||
sh.send_frame([128,int(128+math.sin(value/50.0*10)*120),128,int(128+math.cos(value/50.0*10)*120)])
|
||||
time.sleep(1.0/50)
|
||||
value +=1
|
|
@ -21,6 +21,7 @@ monitor_speed=115200
|
|||
|
||||
lib_deps =
|
||||
waspinator/AccelStepper@^1.64
|
||||
hideakitai/ArtNet@^0.8.0
|
||||
|
||||
build_flags =
|
||||
-D EN_PIN=D0
|
||||
|
|
|
@ -1,11 +1,22 @@
|
|||
#include <Arduino.h>
|
||||
|
||||
|
||||
#include <AccelStepper.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ArtnetWiFi.h>
|
||||
|
||||
|
||||
// https://learn.watterott.com/de/silentstepstick/pinconfig/tmc2130/
|
||||
|
||||
|
||||
const char* ssid = "wifi";
|
||||
const char* password = "password";
|
||||
|
||||
ArtnetWiFiReceiver artnet;
|
||||
|
||||
uint16_t universe1 = 1; // 0 - 32767
|
||||
uint8_t net = 0; // 0 - 127
|
||||
uint8_t subnet = 0; // 0 - 15
|
||||
uint8_t universe2 = 2; // 0 - 15
|
||||
|
||||
// Motor / Hardware Configuration
|
||||
int microsteppingPan = 4;
|
||||
|
@ -17,6 +28,8 @@ int microsteppingTilt = 4;
|
|||
long stepsPerRotationTilt=microsteppingTilt*42*400/12; //12z to 42z
|
||||
long homepos_tilt=0; //positive number=homed position is too far clockwise
|
||||
|
||||
double aimTilt=360; //in degrees
|
||||
double aimPan=360;
|
||||
|
||||
enum Mode{
|
||||
PROGRAM,
|
||||
|
@ -61,6 +74,7 @@ float mapfloat(float x, float in_min, float in_max, float out_min, float out_max
|
|||
void testMovementPan();
|
||||
void testMovementTilt();
|
||||
void testCircle();
|
||||
void movePosition();
|
||||
bool isEndstopPan();
|
||||
bool isEndstopTilt();
|
||||
|
||||
|
@ -105,9 +119,9 @@ void setStepperPreset(Stepperpreset preset,Stepper s)
|
|||
break;
|
||||
case NORMAL:
|
||||
pan_speed=stepsPerRotationPan*1/4;
|
||||
pan_accel=stepsPerRotationPan*1/2;
|
||||
pan_accel=stepsPerRotationPan*1;
|
||||
tilt_speed=stepsPerRotationTilt*1/4;
|
||||
tilt_accel=stepsPerRotationTilt*1/2;
|
||||
tilt_accel=stepsPerRotationTilt*2;
|
||||
break;
|
||||
case FAST:
|
||||
//abs. max. speed w/o load: stepsPerRotationPan*2/3 @19V
|
||||
|
@ -130,6 +144,61 @@ void setStepperPreset(Stepperpreset preset,Stepper s)
|
|||
}
|
||||
}
|
||||
|
||||
void initWiFi() {
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
Serial.print("Connecting to WiFi ..");
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print('.');
|
||||
delay(1000);
|
||||
}
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
|
||||
void initArtnet(){
|
||||
artnet.begin(); // waiting for Art-Net in default port
|
||||
|
||||
//artnet.subscribeArtDmxUniverse(universe15bit, [&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote) {
|
||||
// if Artnet packet comes to this universe(0-15), this function is called
|
||||
//});
|
||||
|
||||
// if Artnet packet comes to this universe, this function (lambda) is called
|
||||
artnet.subscribeArtDmxUniverse(universe1, [&](const uint8_t *data, uint16_t size, const ArtDmxMetadata &metadata, const ArtNetRemoteInfo &remote) {
|
||||
/*Serial.print("lambda : artnet data from ");
|
||||
Serial.print(remote.ip);
|
||||
Serial.print(":");
|
||||
Serial.print(remote.port);
|
||||
Serial.print(", universe = ");
|
||||
Serial.print(universe1);
|
||||
Serial.print(", size = ");
|
||||
Serial.print(size);
|
||||
Serial.print(") :");
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
Serial.print(data[i]);
|
||||
Serial.print(",");
|
||||
}
|
||||
Serial.println();*/
|
||||
|
||||
if (size>=4){
|
||||
aimPan=( (data[0]<<8) +data[1])/65535.0*720;
|
||||
aimTilt=( (data[2]<<8) +data[3])/65535.0*720;
|
||||
Serial.print("aimPan="); Serial.print(aimPan);
|
||||
Serial.print(" aimTilt="); Serial.print(aimTilt);
|
||||
Serial.println();
|
||||
}
|
||||
if (size>=5) {
|
||||
setOutput(data[4]>127);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
// you can also use pre-defined callbacks
|
||||
//artnet.subscribeArtDmxUniverse(net, subnet, universe, callback);
|
||||
//artnet.subscribeArtDmxUniverse(0, 0, 0, callbackArtnet);
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
|
@ -139,7 +208,11 @@ void setup() {
|
|||
setOutput(false);
|
||||
pinMode(EN_PIN,OUTPUT);
|
||||
setEnable(false);
|
||||
delay(500); //wait until terminal ready
|
||||
initWiFi(); //195.160.169.161
|
||||
|
||||
|
||||
initArtnet();
|
||||
|
||||
//stepperPan.moveTo(stepsPerRotationPan/2);
|
||||
|
||||
|
@ -160,6 +233,7 @@ void setup() {
|
|||
|
||||
void loop() {
|
||||
static unsigned long last_change;
|
||||
artnet.parse();
|
||||
|
||||
// ### Mode handling ###
|
||||
switch(mode){
|
||||
|
@ -179,7 +253,8 @@ void loop() {
|
|||
case RUN:
|
||||
//testMovementPan();
|
||||
//testMovementTilt();
|
||||
testCircle();
|
||||
//testCircle();
|
||||
movePosition();
|
||||
break;
|
||||
|
||||
case IDLE:
|
||||
|
@ -205,9 +280,9 @@ void loop() {
|
|||
|
||||
switch(mode){
|
||||
case PROGRAM:
|
||||
Serial.print("PAN Endstop="); Serial.print(digitalRead(ENDSTOP_PAN));
|
||||
/*Serial.print("PAN Endstop="); Serial.print(digitalRead(ENDSTOP_PAN));
|
||||
Serial.print(" TILT Endstop="); Serial.print(analogRead(ENDSTOP_TILT));
|
||||
Serial.println();
|
||||
Serial.println();*/
|
||||
break;
|
||||
|
||||
case HOME:
|
||||
|
@ -247,8 +322,8 @@ void setMode(Mode newmode) {
|
|||
break;
|
||||
|
||||
case RUN:
|
||||
setStepperPreset(FAST,PAN); //set Pan
|
||||
setStepperPreset(FAST,TILT); //set Tilt
|
||||
setStepperPreset(NORMAL,PAN); //set Pan
|
||||
setStepperPreset(NORMAL,TILT); //set Tilt
|
||||
setEnable(true);
|
||||
mode=newmode;
|
||||
Serial.println("Mode set to RUN");
|
||||
|
@ -382,6 +457,11 @@ void testMovementTilt()
|
|||
}
|
||||
}
|
||||
|
||||
void movePosition() {
|
||||
stepperPan.moveTo(aimPan/360.0*stepsPerRotationPan);
|
||||
stepperTilt.moveTo(aimTilt/360.0*stepsPerRotationTilt);
|
||||
}
|
||||
|
||||
|
||||
bool isEndstopPan()
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue