Sounds good! The more feedback the better.
[Release] HubDuino v1.1.3 - Hubitat to Arduino / ESP8266 / ESP32 / ThingShield Integration (ST_Anything)
Dan, Initial findings:
Single servo works smoothly. I especially like the immediate response to a change of mind. My version had to complete the previous command before moving on to the next. This is much better. The only issue I see for a single servo is the timing is not accurate if the endpoint angles are anything other than 0 and 180. I have not looked at the code yet, but I think it might need a scaling factor that changes with the servo endpoints.
Three servos operating simultaneously leads to choppy motion when the duration is equal for all servos. If the servo duration is different between servos the choppy behavior degrades further into erratic sawing motion. The end position is usually correct, but I sometimes see small errors there as well. These issues are less noticeable at duration < 2000. At 10,000 it is very pronounced.
Hmmm... I think the way it is coded is that the "rate" is fixed regardless of the min and max endpoint angles defined in the sketch. The "rate" is in units of ms/degree, not ms/%level. The %level will scale differently based on the min and max endpoint angles in the sketch, but the rate of change will still be constant, I think. Remember, the 'duration' field is really the rate in terms of milliseconds per 180 degrees.
I noticed that a little here as well, although I am testing with a single servo on an ESP8266. Because the updates to servo position are now non-blocking, it is possible that other ST_Anything activities will prevent the servo moves from being completely smooth. Please let me know if you think of any ways to improve this.
Thanks for the quick test results!
Then the text for preferences in the device driver needs to change. It currently says:
Default Rate (Duration)
Time in milliseconds to transition from 0% to 100% (0 = full speed)
Perhaps the following would be more accurate?
Default Rate (Duration)
Time in milliseconds to transition from 0 degrees to 180 degrees (0 = full speed)
An alternative is to change the calculation to make it actually be the time to go from 0% to 100%. I think I prefer this second approach as more intuitive. When a servo is incorporated into a device, rate of change per degree is not what a user can perceive. They will perceive the amount of time it takes for blinds, or register etc to move from fully closed to fully open or vice versa. This is under the assumption that the sketch parameters are calibrated so that the device is closed at 0% and open at 100%.
Done! Thanks for the feedback!
I really don't think it is worth the effort to scale the rate as a function of min-max endpoint angles. It is essentially a speed factor. With a little tweaking (or math) end-users should be able to dial in their settings. That said, if everyone feels strongly that it should scale, we can make that happen. Just not tonight...
So, I hooked up a seconds servo and set them both to use a rate of 10,000ms/180deg. I think started them moving at the same time and they were pretty smooth. They are the only two devices defined in my sketch.
I am curious - what microcontroller are you using? And what other ST_Anything devices do you have attached? If you're collecting and transmitting a bunch of temperature sensors, for example, processing the network traffic for those will cause the servos to hesitate during their moves.
The rate thing is not a big deal, especially tonight! The purist in me wants to change it, but it is not a must do item..
I'm running a Mega with an Ethernet shield and 3 of the cheapest analog servos I've ever seen (Arduino beginner kit servos). I fly RC planes and have found digital servos to be a better choice than analog. I ordered digital servos for the HVAC damper installation and can try them when they show up in a couple weeks. I also need to check if I am getting voltage sags when 3 servos are operating simultaneously. The combined current draw of multiple servos was not on my radar until now, as I have been planning for one servo at a time running.
My test rig does not have other devices running besides the 3 servos. (My in use Hubduino is a completely different set of hardware running 14 devices and 6 device types) For the test rig I am simultaneously sending move commands to the 3 servo child devices via a virtual switch and Rule Machine.
I will record a servo video and reply with a link. I suspect going from 3 servos to the 14 that I need for the zone control project will not give acceptable results. More to ponder on solutions as I study the code. I am wondering if your current architecture would support sequential moves. I suppose structuring them sequentially on the hub end of things would be a possible solution.
I can set up a second test rig with an ESP8266 tomorrow to see if the processing speed makes a difference vs Mega.
I have two "Tower Pro SG90" servos hooked up to a NodeMCU ESP8266. WHen I run them both at the same time, I hear the telltale sound of USB disconnecting and reconnecting. If you're running these directly off of the Arduino MEGA's 5vdc pin, I believe you will experience issues. You'll need to power the servos directly from a 5vdc power supply. Just be sure to tie the ground from the power supply to the Arduino Gnd to establish a common voltage reference. If you're powering the Arduino via USB (i.e. your PC), do not connect the external 5vdc power supply's +5v to the Arduino's +5v. Only the grounds should be tied together.
This is a decent wiring diagram for using an external PS for the servos. In this drawing, it is assumed the Arduino is being powered via USB, or its barrel ps connector.
My servo power supply is separate from the Mega power supply, and they share a common ground as you suggest. The power issue I suspected stems from using a 700 mA supply for the servos.
I just monitored servo supply voltage with a DVM and saw voltage bouncing all over the place between 5.1 V and 2.4 V. That's obviously a huge problem to be corrected tomorrow.
I am not liking the implications for my 14 servo zone controller. I don't really want to set up with a 10-15 amp power supply for possible simultaneous moves on all the servos. I need to think about the high level control logic that will use temperature inputs to set damper positions. Simultaneous moves on many servos will need to be avoided to keep power supply needs in check.
I'm anxious to see if @kilowatts can run 3 blinds simultaneously without upgrading his power supply.
Edit: I switched to a 3 amp supply for the servos and got much better results. The sawing motion is gone, but there are still minor stutters when moving 3 servos. DVM monitoring shows improvements with voltage starting at 4.95 V and sags to 4.31 volts. I might check with a scope tomorrow as it is likely lower that the 4.31 volts I can read with a DVM. I think this sag is probably enough to cause the stutter that remains.
These 3 servos are low power analog micro servos. My planned damper servos are standard size high torque digital units that will draw a lot more current.
small issue here. A temperature tile on the dashboard from a child temperature device shows the temp just fine. The degree icon to the right is replaced by null just about every other refresh. In the device settings for that child I have tried seting the Temperature Unit conversion to all the settings and the same thing happens. I believe I have the up to date drivers, only a couple of weeks old.
Funny you mention that... I was just looking into that. The fix is easy. My question to you is, should the units that are displayed be "°F" and "°C" or "F" and "C" ?
UPDATE: I updated the Child Temperature driver in my GitHub repository. I went with "°F" and "°C". You can change your copy of the driver as you see fit.
I think it would look more finished as °F" and "°C But if one is easier than the other I can live with either.
Dan, Is the device handler preference text the only change in the release vs what I was testing last night?
Yes, the text and I believe I changed the default values for some of the user preferences as well.
I also updated the Child Temperature driver this morning to include the units. This helps with display on the Dashboard.
Quick question...what are the suggested max and min values you can enter for servoRate? And is smaller faster or larger faster? I would think if it is ms/degree smaller would be faster, correct?
Also, I just tried to convert one of mine and it did not respect the "startingAngle" I entered in the constructor. I entered 0 and it used 90. I tried 1 and it also used 90. Doesn't seem I'm doing this right.
Did the parent device update too?
When it powered on, did it move to 90 and then immediately to 0?
That is an interesting problem to try to solve, as the sketch has no idea where the servo is when turned on. In order for the servo to move to your initial position, at the rate specified in the constructor, it needed a starting point. So i used 90 degrees as it was in the center of the range. It will immediately move to that position at full speed and then start the more gradual move to the desired initial position.
I’m not sold on that design. I could modify it to behave like it used to where it just snaps to the user defined initial position and then honors all other moves at the specified rate.
I’m open to ideas about this initial startup behavior.
Thoughts from the community?
0 to 30000ms/180 degrees, if I recall correctly. 0 behaves the same way the EX_Servo class used to behave.
My mistake...I didn't realize that a whole bunch of other libraries had updated too. I only moved over the servo .cpp and .h files at first. Now that I moved them all it's working much better. On power-on it moves to 90 and then back to the setting in the sketch.
Now i have to play around when it's sunny and see if my motion sensors still trip when I move them with the slower rate. That will save me all this trouble I'm going through with PB for all my motion rules whenever I move my blinds. If you saw all the rules I had for it, you'd laugh I'm sure.
Thinking about it from the perspective of avoiding potential damage on startup, the safest position to snap to is the middle of the travel range. Most any well setup physical system will include the middle of the servo range in it's normal travel limits, so snapping to that position is unlikely to jam the servo when it is moving quickly. If a user chooses to then have it move to a starting position beyond hardware range of motion at a high rate of speed, that is on them. I like it as is currently set up.