It is currently August 17th, 2019, 11:45 am

Syncing skins

Help with creating, editing & fixing problems with skins
Yincognito
Posts: 652
Joined: February 27th, 2015, 2:38 pm

Re: Syncing skins

Yincognito » March 11th, 2019, 2:00 pm

I understand - thanks for clearing this up as well.
User avatar
jsmorley
Developer
Posts: 19368
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Syncing skins

jsmorley » March 11th, 2019, 2:01 pm

I have long wished that there was an accurate, clock-based measurement in milliseconds in Rainmeter, but that can't be the Time measure. That is just entirely structured around seconds, and really can't be changed.

And even then, it still wouldn't be good for creating animations based on time at that level of granularity. The show-stopper is always going to be that Update is NOT clock-based.

Update becomes increasingly unreliable as a measure of clock time as the amount of work Rainmeter is doing on each update of ALL the skins you currently have running increases. If you have Update=16 in a skin, Rainmeter will "try" to update that skin once every 16 milliseconds. Depending on what else is in the "queue", it may or may not be able to do that at any given time. At that point, it not about the "clock", but more how fast your PC is, and what else Rainmeter is trying to do.
Yincognito
Posts: 652
Joined: February 27th, 2015, 2:38 pm

Re: Syncing skins

Yincognito » March 11th, 2019, 2:15 pm

jsmorley wrote:
March 11th, 2019, 2:01 pm
I have long wished that there was an accurate, clock-based measurement in milliseconds in Rainmeter, but that can't be the Time measure. That is just entirely structured around seconds, and really can't be changed.
Yeah, I tried to tackle this in my Rainmeter skin as well, where I measured the average CPU usage of Rainmeter over a minutes:seconds interval that's "resetting" once every hour, but when trying to make it time based I experienced the same occasional seconds skipping behavior as the OP. In the end, I gave up the idea of making it time based, as just made it update based using a formula like SecondsInUpdateInterval=(#UpdateInterval#/1000), where UpdateInterval is the actual value used by the Update option in the [Rainmeter] section. Of course, in my case, this was not critical, as all I needed was a very close approximation, but for a clock skin that's updating less than a second, it certainly is.

That being said, one second is already a tiny interval anyway, and we are not exactly NASA to care that much about very small time intervals, but yeah, in the case of animated skin showing the time this leads to an unwanted impact.
User avatar
jsmorley
Developer
Posts: 19368
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Syncing skins

jsmorley » March 11th, 2019, 2:17 pm

Yincognito wrote:
March 11th, 2019, 2:15 pm
Yeah, I tried to tackle this in my Rainmeter skin as well, where I measured the average CPU usage of Rainmeter over a minutes:seconds interval that's "resetting" once every hour, but when trying to make it time based I experienced the same occasional seconds skipping behavior as the OP. In the end, I gave up the idea of making it time based, as just made it update based using a formula like SecondsInUpdateInterval=(#UpdateInterval#/1000), where UpdateInterval is the actual value used by the Update option in the [Rainmeter] section. Of course, in my case, this was not critical, as all I needed was a very close approximation, but for a clock skin that's updating less than a second, it certainly is.

That being said, one second is already a tiny interval anyway, and we are not exactly NASA to care that much about very small time intervals, but yeah, in the case of animated skin showing the time this leads to an unwanted impact.
Yes. It does make something like a clock pendulum very difficult to animate. Any "jerkiness" would be very noticeable. That is too bad, but I don't think there is a good solution.

https://www.amazon.com/Felix-The-Cat-Motion-Clock/dp/B001G8PWV2
Yincognito
Posts: 652
Joined: February 27th, 2015, 2:38 pm

Re: Syncing skins

Yincognito » March 11th, 2019, 2:21 pm

jsmorley wrote:
March 11th, 2019, 2:17 pm
Yes. It does make something like a clock pendulum very difficult to animate, which is too bad, but I don't think there is a good solution.
In the end, it's not Rainmeter's fault, or even Windows' one. Even real clocks need to be readjusted once in a while, so...in a strictly abstract sense, this happens in every real world scenario, not just in Rainmeter. ;-)
User avatar
balala
Rainmeter Sage
Posts: 8532
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Syncing skins

balala » March 11th, 2019, 2:22 pm

qwerky wrote:
March 10th, 2019, 10:41 pm
Is there anything else that can be done, or is using a fast-updating pendulum just not going to work? :???:
I still think a sample code would be useful.
User avatar
jsmorley
Developer
Posts: 19368
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Syncing skins

jsmorley » March 11th, 2019, 3:00 pm

I think the closest you might get is to use an OnChangeAction on a Time measure that is getting the "seconds". Have that fire an ActionTimer measure that moves some meter(s) from point A to point B, using values to ensure that 1) It is always able to do so in less than one second, but as close to one second as possible, and 2) Use Clamp() as while you probably WANT execute the action more times than it takes to get from A to B, so it always "gets there", you don't want to set a value greater than B or less than A.

So this will not change something, presumably a position of some meter, based on where we are in the number of milliseconds that have elapsed between changes of the seconds, that is just not possible. It is based on some "distance of travel" that you define, smoothly moving that distance within (but likely not exactly) a second, and moving back in the other direction on the next change. The point is not to synchronize the intermediate positions with the clock, but simply to have the starting and ending positions synchronized the best we can, while moving "smoothly" in between them.

I don't think you are ever going to be able to get the movement to "end" at the precise moment that the second "ends". In fact, trying to get "too close" to that is likely to cause problems. I think you are going to have some "pause" at the start and end of the movements, as they are going to get there a bit "too soon", and this pause might vary a bit in length, but as long as the movement in between is smooth, that might not be too noticeable.

Take some chewing to get this more or less right... I don't think it can be perfect, as if you think about it, a pendulum is what drives the clock on a grandfather clock, and we are trying to have the clock drive the pendulum. A different animal...
User avatar
jsmorley
Developer
Posts: 19368
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Syncing skins

jsmorley » March 11th, 2019, 3:32 pm

Here is a skin that more or less uses this ActionTimer approach with the clock...

Code: Select all

[Rainmeter]
Update=50
DynamicWindowSize=1
AccurateText=1
SkinHeight=45
OnRefreshAction=[!SetVariable CurrentHours "[MeasureHours]"][!SetVariable CurrentMinutes "[MeasureMinutes]"][!SetVariable CurrentSeconds "[MeasureSeconds]"][!UpdateMeter *][!Redraw]

[Variables]
LinesColor=0,0,0,255
NumberColor=255,255,255,255
BackColor=19,43,77,255
CurrentHoursY=2
NewHoursY=-40
CurrentMinutesY=2
NewMinutesY=-40
CurrentSecondsY=2
NewSecondsY=-40
U=[!UpdateMeasureGroup Sliders][!UpdateMeterGroup Numbers][!Redraw]

[MeasureHours]
Measure=Time
Format=%I
OnChangeAction=[!CommandMeasure HoursSlide "Execute 1"]

[MeasureMinutes]
Measure=Time
Format=%M
OnChangeAction=[!CommandMeasure MinutesSlide "Execute 1"]

[MeasureSeconds]
Measure=Time
Format=%S
OnChangeAction=[!CommandMeasure SecondsSlide "Execute 1"]

[HoursSlide]
Measure=Plugin
Plugin=ActionTimer
Group=Sliders
IgnoreWarnings=1
ActionList1=SetThem | Wait 1 | Repeat SlideThem, 20, 21 | Wait 1| SwapThem
SetThem=[!SetVariable CurrentHoursY "2"][!SetVariable NewHoursY "-40"]#U#
SlideThem=[!SetVariable CurrentHoursY "(Clamp(#CurrentHoursY#+2,2,45))"][!SetVariable NewHoursY "(Clamp(#NewHoursY#+2,-40,2))"]#U#
SwapThem=[!SetVariable CurrentHoursY "2"][!SetVariable NewHoursY "-40][!SetVariable CurrentHours "[MeasureHours]"]#U#
DynamicVariables=1

[MinutesSlide]
Measure=Plugin
Plugin=ActionTimer
Group=Sliders
IgnoreWarnings=1
ActionList1=SetThem | Wait 1 | Repeat SlideThem, 20, 21 | Wait 1| SwapThem
SetThem=[!SetVariable CurrentMinutesY "2"][!SetVariable NewMinutesY "-40"]#U#
SlideThem=[!SetVariable CurrentMinutesY "(Clamp(#CurrentMinutesY#+2,2,45))"][!SetVariable NewMinutesY "(Clamp(#NewMinutesY#+2,-40,2))"]#U#
SwapThem=[!SetVariable CurrentMinutesY "2"][!SetVariable NewMinutesY "-40][!SetVariable CurrentMinutes "[MeasureMinutes]"]#U#
DynamicVariables=1

[SecondsSlide]
Measure=Plugin
Plugin=ActionTimer
Group=Sliders
IgnoreWarnings=1
ActionList1=SetThem | Wait 1 | Repeat SlideThem, 20, 21 | Wait 1| SwapThem
SetThem=[!SetVariable CurrentSecondsY "2"][!SetVariable NewSecondsY "-40"]#U#
SlideThem=[!SetVariable CurrentSecondsY "(Clamp(#CurrentSecondsY#+2,2,45))"][!SetVariable NewSecondsY "(Clamp(#NewSecondsY#+2,-40,2))"]#U#
SwapThem=[!SetVariable CurrentSecondsY "2"][!SetVariable NewSecondsY "-40][!SetVariable CurrentSeconds "[MeasureSeconds]"]#U#
DynamicVariables=1

[MeterNewHours]
Meter=String
Group=Numbers
MeasureName=MeasureHours
W=30
H=32
X=22
Y=#NewHoursY#
StringAlign=Center
FontFace=Fira Sans
FontSize=20
FontColor=#NumberColor#
SolidColor=#BackColor#
Padding=5,5,5,5
AntiAlias=1
UpdateDivider=-1
DynamicVariables=1

[MeterCurrentHours]
Meter=String
Group=Numbers
W=30
H=32
X=22
Y=#CurrentHoursY#
StringAlign=Center
FontFace=Fira Sans
FontSize=20
FontColor=#NumberColor#
SolidColor=#BackColor#
Padding=5,5,5,5
AntiAlias=1
Text=#CurrentHours#
UpdateDivider=-1
DynamicVariables=1

[MeterNewMinutes]
Meter=String
Group=Numbers
MeasureName=MeasureMinutes
W=30
X=64
Y=#NewMinutesY#
H=32
StringAlign=Center
FontFace=Fira Sans
FontSize=20
FontColor=#NumberColor#
SolidColor=#BackColor#
Padding=5,5,5,5
AntiAlias=1
UpdateDivider=-1
DynamicVariables=1

[MeterCurrentMinutes]
Meter=String
Group=Numbers
MeasureName=MeasureMinutes
W=30
X=64
Y=#CurrentMinutesY#
H=32
StringAlign=Center
FontFace=Fira Sans
FontSize=20
FontColor=#NumberColor#
SolidColor=#BackColor#
Padding=5,5,5,5
AntiAlias=1
Text=#CurrentMinutes#
UpdateDivider=-1
DynamicVariables=1

[MeterNewSeconds]
Meter=String
Group=Numbers
MeasureName=MeasureSeconds
W=30
X=106
Y=#NewSecondsY#
H=32
StringAlign=Center
FontFace=Fira Sans
FontSize=20
FontColor=#NumberColor#
SolidColor=#BackColor#
Padding=5,5,5,5
AntiAlias=1
UpdateDivider=-1
DynamicVariables=1

[MeterCurrentSeconds]
Meter=String
Group=Numbers
W=30
X=106
Y=#CurrentSecondsY#
H=32
StringAlign=Center
FontFace=Fira Sans
FontSize=20
FontColor=#NumberColor#
SolidColor=#BackColor#
Padding=5,5,5,5
AntiAlias=1
Text=#CurrentSeconds#
UpdateDivider=-1
DynamicVariables=1

[MeterTopLine]
Meter=Image
X=0
Y=0
H=2
W=128
SolidColor=#LinesColor#
UpdateDivider=-1
DynamicVariables=1

[MeterLeftLine]
Meter=Image
X=0
Y=0
H=43
W=2
SolidColor=#LinesColor#
UpdateDivider=-1
DynamicVariables=1

[MeterMidLine1]
Meter=Image
X=42
Y=2
W=2
H=41
SolidColor=#LinesColor#
UpdateDivider=-1
DynamicVariables=1

[MeterMidLine2]
Meter=Image
X=84
Y=2
W=2
H=41
SolidColor=#LinesColor#
UpdateDivider=-1
DynamicVariables=1

[MeterRightLine]
Meter=Image
X=126
Y=0
H=43
W=2
SolidColor=#LinesColor#
UpdateDivider=-1
DynamicVariables=1

[MeterBottomLine]
Meter=Image
X=0
Y=43
H=2
W=128
SolidColor=#LinesColor#
UpdateDivider=-1
DynamicVariables=1

GIF.gif
You do not have the required permissions to view the files attached to this post.
Yincognito
Posts: 652
Joined: February 27th, 2015, 2:38 pm

Re: Syncing skins

Yincognito » March 11th, 2019, 3:46 pm

jsmorley wrote:
March 11th, 2019, 3:00 pm
I think the closest you might get is to use an OnChangeAction on a Time measure that is getting the "seconds". Have that fire an ActionTimer measure that moves some meter(s) from point A to point B, using values to ensure that 1) It is always able to do so in less than one second, but as close to one second as possible, and 2) Use Clamp() as while you probably WANT execute the action more times than it takes to get from A to B, so it always "gets there", you don't want to set a value greater than B or less than A.

So this will not change something, presumably a position of some meter, based on where we are in the number of milliseconds that have elapsed between changes of the seconds, that is just not possible. It is based on some "distance of travel" that you define, smoothly moving that distance within (but likely not exactly) a second, and moving back in the other direction on the next change. The point is not to synchronize the intermediate positions with the clock, but simply to have the starting and ending positions synchronized the best we can, while moving "smoothly" in between them.

I don't think you are ever going to be able to get the movement to "end" at the precise moment that the second "ends". In fact, trying to get "too close" to that is likely to cause problems. I think you are going to have some "pause" at the start and end of the movements, as they are going to get there a bit "too soon", and this pause might vary a bit in length, but as long as the movement in between is smooth, that might not be too noticeable.

Take some chewing to get this more or less right... I don't think it can be perfect, as if you think about it, a pendulum is what drives the clock on a grandfather clock, and we are trying to have the clock drive the pendulum. A different animal...
Hehe, I was going to say the same thing, but then I saw a flaw in the approach and gave up. I was thinking of intentionally updating the seconds display in the skin on less than 1 second, say 800 or 900 milliseconds, and then when you discover there is a difference (of 1 second, since you can't measure less) between the measured seconds and the actual Time value, just "delay" the pendulum's movement for a little while. The problem with this is that although that 200 or 100 milliseconds of Rainmeter going faster than the actual time will be unnoticeable to the human eye, the 1 second "delay" will, and it will happen sooner or later. I thought about asking about an ActionTimer approach as well, but even though that's done independently of Rainmeter, it's still subject to occasional "out-of-sync" issues.

That being said, the sync moment could be "packed" in a way that's pleasing to the user, with the help of a flashing "Adjusting time..." once every N seconds interval. This, of course, won't attempt to be precise in between the N intervals, but simply attempt to make the adjusting moment more bearable to the user (than a visible second skipping would).
User avatar
qwerky
Posts: 181
Joined: April 10th, 2014, 12:31 am
Location: Canada

Re: Syncing skins

qwerky » March 11th, 2019, 8:15 pm

balala wrote:
March 11th, 2019, 2:22 pm
I still think a sample code would be useful.
Okay, here is some sample code (this is just my testing skin--not a finished product ;-) ):

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1

[Variables]
skinWidth=274
skinHeight=50
cornerRoundness=7

; pendulumHeight:  height of pendulum skin.
; pendulumBorder:  size of pendulum border.
pendulumHeight=50
pendulumBorder=2

pendulumLEDBorder=1
pendulumLEDSize=5
pendulumSpan=(#skinWidth#-#pendulumBorder#-((#pendulumLEDSize#+#pendulumLEDBorder#+2)*2))
pendulumLEDSpacing=(Trunc(#pendulumSpan#/9))
pendulumStartX=((#skinWidth#-(#pendulumLEDSpacing#*9))/2)

colorPendulumBackground=0,10,36,255
colorPendulumBorder=0,64,192,255
colorPendulumTitleBar=0,64,192,255
;colorLEDBorder=255,255,255,255
colorLEDBorder=0,10,36,255
colorLEDOff=0,10,36,255
colorLEDOn=255,063,063,255
All of the variables in the code below, which do not appear above, come from other includes; but you can make up your own values for colors, skin position, etc. Change update to 100 to see the pendulum swing at full speed.

Here are the meters:

Code: Select all

[mtrPendulumBackground]
Meter=Shape
Shape=Rectangle 0,0,#skinWidth#,#skinHeight#,#cornerRoundness# | StrokeWidth #pendulumBorder# | Stroke Color #colorPendulumBorder# | Fill Color #colorPendulumBackground#
AntiAlias=1
X=0
Y=0
W=#skinWidth#
H=#skinHeight#

;[mtrArc]
;Meter=Shape
;Shape=Arc 0,0,(#pendulumLEDSpacing#*9),0,41,10,*,1 | StrokeWidth 1 | Stroke Color #colorWhite#
;X=#pendulumStartX#
;Y=10
;DynamicVariables=1

[mtrLED1]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=#pendulumStartX#
Y=10
DynamicVariables=1

[mtrLED2]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=(#pendulumLEDSpacing#-6)r
Y=26
DynamicVariables=1

[mtrLED3]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=(#pendulumLEDSpacing#+0)r
Y=34
DynamicVariables=1

[mtrLED4]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=(#pendulumLEDSpacing#+3)r
Y=38
DynamicVariables=1

[mtrLED5]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=(#pendulumLEDSpacing#+3)r
Y=40
DynamicVariables=1

[mtrLED6]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=#pendulumLEDSpacing#r
Y=40
DynamicVariables=1

[mtrLED7]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=(#pendulumLEDSpacing#+3)r
Y=38
DynamicVariables=1

[mtrLED8]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=(#pendulumLEDSpacing#+3)r
Y=34
DynamicVariables=1

[mtrLED9]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=(#pendulumLEDSpacing#+0)r
Y=26
DynamicVariables=1

[mtrLED10]
Meter=Shape
Group=PendulumLED
Shape=Ellipse 0,0,#pendulumLEDSize# | StrokeWidth #pendulumLEDBorder# | Stroke Color #colorLEDBorder# | Extend PendulumFillColor
PendulumFillColor=Fill Color #colorLEDOn#
X=(#pendulumLEDSpacing#-6)r
Y=10
DynamicVariables=1
So there are ten "LED"s (circular ellipse-shape meters), arranged in an arc. There is a "mtrArc" meter which is commented out; if you enable it, you will get a 1-pixel arc, which I used to manually place the location of the LEDs. The LEDs themselves have a 1-pixel border for testing, but in the final version, that is turned off by setting #pendulumLEDBorder# to zero.

Finally, the measures, normally placed above the meters, but I saved them for last in this post:

Code: Select all

[msrPendulumWrap]
Measure=Calc
DynamicVariables=1
Formula=msrPendulumWrap+1
IfConditionMode=1
ifCondition=1
IfTrueAction=[!SetOptionGroup PendulumLED PendulumFillColor "Fill Color #*colorLEDOff*#"][!SetOption mtrLED[&msrPendulumWrap] PendulumFillColor "Fill Color #*colorLEDOn*#"]
IfAboveValue=9
IfAboveAction=[!SetOption msrPendulumWrap Formula "msrPendulumWrap-1"]
IfBelowValue=2
IfBelowAction=[!SetOption msrPendulumWrap Formula "msrPendulumWrap+1"]

;[msrPendulumArc1]
;Measure=Calc
;DynamicVariables=1
;Formula=msrPendulumArc+1
;IfConditionMode=1
;ifCondition=1
;IfTrueAction=[!SetVariable PendulumLEDNum "[msrPendulumArc]"]
;IfAboveValue=9
;IfAboveAction=[!SetOption msrPendulumArc Formula "msrPendulumArc-1"]
;IfBelowValue=2
;IfBelowAction=[!SetOption msrPendulumArc Formula "msrPendulumArc+1"]
;
;[msrPendulumArc2]
;Measure=Calc
;DynamicVariables=1
;Formula=Clamp(msrPendulumArc+2,2,21)
;IfConditionMode=1
;ifCondition=1
;IfTrueAction=[!SetVariable PendulumLEDNum "(Clamp(Trunc([msrPendulumArc]/2), 1, 10))"]
;IfAboveValue=20
;IfAboveAction=[!SetOption msrPendulumArc Formula "Clamp(msrPendulumArc-2,2,21)"]
;IfBelowValue=3
;IfBelowAction=[!SetOption msrPendulumArc Formula "Clamp(msrPendulumArc+2,2,21)"]
;
;[msrPendulumSwing]
;Measure=Calc
;DynamicVariables=1
;Formula=1
;IfConditionMode=1
;ifCondition=1
;IfTrueAction=[!SetOptionGroup PendulumLED PendulumFillColor "Fill Color #*colorLEDOff*#"][!SetOption mtrLED#PendulumLEDNum# PendulumFillColor "Fill Color #*colorLEDOn*#"]
msrPendulumWrap was the first attempt. It swings the pendulum back and forth, but since there are ten LEDs, that amounts to only nine steps, so if the steps were exactly 100ms apart, the pendulum would run fast by a tenth of a second, per second.

Next, there are are two versions of msrPendulumArc, which are to be used (one at a time) with msrPendulumSwing; so comment msrPendulumWrap, uncomment msrPendulumSwing, and then uncomment one (but not both) msrPendulumArc measure.

msrPendulumArc1 gives the same results as msrPendulumWrap above; it simply breaks the counter, and the LED colouring, into two separate measures. This is in preparation for the other msrPendulumArc measure.

msrPendulumArc2 is more interesting. What this does, is cause LED1 and LED10 (the ones at either end of the arc) to light for two updates, rather than one. This gives each swing, ten steps rather than nine, and therefore each swing (at 100ms updates) should take one second. But this also gives the pendulum the appearance of pausing at the top of each end of the arc, to simulate an actual physical pendulum. This measure achieves the final objective, except of course for the syncing issue. But when run with Update=1000, there is then no syncing issue, and the clock and pendulum run perfectly, except of course for the pendulum requiring ten seconds to complete one arc. :(
Last edited by qwerky on March 11th, 2019, 9:38 pm, edited 5 times in total.