Closed Petorrrrr closed 2 years ago
Thanks for this. Question: what hardware do you use exactly in you ArtNet setup? (just out of curiosity)
If I'm going to implement ArtNet I'm more inclined to do it in a separate library and use that library in this project. do you have any docs that helped you understand the ArtNet protocol?
I'm using this very cheaply to build artnet node: https://github.com/mtongnz/ESP8266_ArtNetNode_v2 and the S1-DR DMX dimmer (2 channels) from aliexpress
Works really stable. I haven't developed it myself, just creative searching on the web and copy-pasting and adjusting along the way. Found it originally here: http://www.oscat.de/community/index.php?topic=880.0
I have been working with the code that @Petorrrrr has posted and integrated into this project code. I am not a full time progammer so improvements are probably possible.
I've created a variable as Petorrrr stated, created the DMXSend PRG and created a DMX task, running in freewheeling mode.
I wanted to use the FB_OUTPUT_DIMMER_MQTT functionblock. I copied it to a DMX specific one FB_OUTPUT_DIMMER_MQTT_DMX (this shouldn't be necessary, could be integrated in the normal one). In the new FB created these VARS:
DmxChannel :INT;
pDmxValues :POINTER TO oscat_network.NETWORK_BUFFER_SHORT;
InitDmxDone :BOOL;
OUT_Target :BYTE;
SoftDimToValue :BOOL;
SoftDimToQFalse :BOOL;
UpdateValueStep :BYTE := 4;
OUT_Internal_tmp :BYTE;
I added a method to intitialize the DMX variables:
METHOD InitDmx
VAR_INPUT
DmxChannel :INT;
pDmxValues :POINTER TO oscat_network.NETWORK_BUFFER_SHORT;
END_VAR
THIS^.DmxChannel := DmxChannel;
THIS^.pDmxValues := pDmxValues;
THIS^.InitDmxDone := TRUE;
In the PublishReceived method I changed:
THIS^.OUT_Internal:=STRING_TO_BYTE(Data.PayloadString^);
to
THIS^.OUT_Target:=STRING_TO_BYTE(Data.PayloadString^);
THIS^.SoftDimToValue:=TRUE;
Then inside the main functions I added this on the top of the code:
IF SoftDimToValue = TRUE THEN
IF OUT_Target > OUT_Internal THEN // we are moving up to OUT_Internal
IF OUT_Target - OUT_Internal > UpdateValueStep THEN
OUT_Internal := OUT_Internal + UpdateValueStep;
ELSE
OUT_Internal := OUT_Target;
END_IF
ELSIF OUT_Target < OUT_Internal THEN // we are moving down to OUT_Internal
IF OUT_Internal - OUT_Target > UpdateValueStep THEN
OUT_Internal := OUT_Internal - UpdateValueStep;
ELSE
OUT_Internal := OUT_Target;
IF SoftDimToQFalse THEN
Q := FALSE;
END_IF
END_IF
END_IF
END_IF
And changed the "ELSIF SINGLE THEN" to:
(* a single click reverses output Q *)
Q := NOT Q;
(* when dimmer is turned on we need to limit out to min and max limits *)
IF Q THEN
OUT_Target := LIMIT(MAX(OUT_Internal,1), OUT_Internal, MAX_ON);
OUT_Internal := 0;
SoftDimToValue := TRUE;
ELSE
IF OUT_Internal > 0 THEN
OUT_Target := 0;
OUT_Internal_tmp := OUT_Internal;
Q := TRUE; // back to true while soft dimming to 0
SoftDimToValue := TRUE;
SoftDimToQFalse := TRUE;
END_IF
END_IF;
(* set the appropriate direction of dimmer dir is reversed because next action will reverse again *)
dir := OUT_Internal > 127;
At the end I've added:
IF InitDmxDone THEN
IF Q THEN
IF pDmxValues^.BUFFER[DmxChannel-1] <> OUT_Internal THEN
pDmxValues^.BUFFER[DmxChannel-1] := OUT_Internal;
END_IF
ELSE
IF pDmxValues^.BUFFER[DmxChannel-1] <> 0 THEN
pDmxValues^.BUFFER[DmxChannel-1] := 0;
END_IF
END_IF
END_IF
IF SoftDimToValue AND OUT_Internal = OUT_Target THEN // If the same, softdim to value is done
SoftDimToValue := FALSE;
IF SoftDimToQFalse THEN
SoftDimToQFalse := FALSE;
OUT_Internal := OUT_Internal_tmp;
PreviousOUT:=OUT_Internal;
END_IF
END_IF
Works very nice (I think), when I click a pushbutton (single) the light fades out, when I click it again it fades in. When I set a value through MQTT the light fades to this value. This is currently running on my test setup. I'm planning to push to my production system later this week. Please let me know if you like it or if there is improvements.. (this was probably not the easiest way of posting this code... I cannot get used to these WAGO source files :-( )
Cool! Unfortunately, this didn't work out fully for me. I use a slightly different setup where I created additional Virtual dimmers for use with my OpenHAB instance with MQTT. Don't recall the exact reasons, but I think it was the easiest way for me with limited knowledge.
But you inspired me to add the fade functionality in the DMX_SEND program. So I added/changed this:
IF S_BUF1.BUFFER[i] <> OtherVariables.DMX.BUFFER[i-18] THEN
IF OtherVariables.DMX.BUFFER[i-18] > S_BUF1.BUFFER[i] THEN //dimming up
IF OtherVariables.DMX.BUFFER[i-18] - S_BUF1.BUFFER[i] > UpdateValueStep THEN
S_BUF1.BUFFER[i] := S_BUF1.BUFFER[i] + UpdateValueStep;
ELSE
S_BUF1.BUFFER[i] := OtherVariables.DMX.BUFFER[i-18];
END_IF
ELSIF OtherVariables.DMX.BUFFER[i-18] < S_BUF1.BUFFER[i] THEN // dimming down
IF S_BUF1.BUFFER[i] - OtherVariables.DMX.BUFFER[i-18] > UpdateValueStep THEN
S_BUF1.BUFFER[i] := S_BUF1.BUFFER[i] - UpdateValueStep;
ELSE
S_BUF1.BUFFER[i] := OtherVariables.DMX.BUFFER[i-18];
END_IF
END_IF
send := TRUE;
END_IF
@jaccospelt thanks for sharing, much appreciated! Could you perhaps share your project over here? I'm planning to add a dedicated page on it. For sure it will help other people as well.
@jaccospelt any chance you could share your project? I tried to reconstruct your work based on the code snippets above, but that did not work out completely. I am not totally sure how to incorporate this in the main program and also https://github.com/MichielVanwelsenaere/HomeAutomation.CoDeSys3/pull/75 seems to interfere. Once I have it up and running, I will document this feature in order to help others.
thank you for the feedback on sharing on this one. Closing this one due to inactivity and lack of time (& Artnet hardware) to implement this in the project decently. Don't let this hold you back to use this thread for more code sharing :)
Does anyone have some updates, or is willing to share their code?
As posted on Gitter, I managed to get the pfc200 to output ArtNet communication.
Included you find my project (I've anonimized the IP adresses used, but not my home setup). It's written in codesys 3.5 SP15 patch 3 homeAutomation export.zip
In essence, I've created another Global Variable List (OtherVariables) where I store the var DMX. In here I store the artnet characters to be send.
In the program DMX_SEND the first 18 characters get initialized (mandatory for ArtNet) and then it loops through the DMX variable to add the DMX values to the send buffer. If it detects a value has changed a flag "send" is set to true. If send is true, an ArtNet message is sent over UDP to the specified IP address. This program runs in Freewheeling mode (if you do it cyclic it doesn't always pick up all the changes if you change more than 5 channels through MQTT).
I'm sure that the code can be cleaned up. I've mostly copy-pasted it and adjusted it so that it's working (stable).
Also in here are some minor changes to some of the functions, if needed I can provide some more detail. Also I've done some visualization. Since this issue is focusses on the ArtNet part I won't describe this further.