Problem uploading sketch.  

Page 5 / 6
  RSS

dorsay
(@dorsay)
Trusted Member
Joined: 2 months ago
Posts: 67
2020-02-16 11:22 pm  

@john40131

Posted by: @john40131

the type I am using are DC90 which only have a turning circle of 180 deg, I have an Arduino Mega and a PCA9685 to give me 16 channels

Thanks John, I'm doing something very similar.  I'm using SG90 and a PCA9685. 

Posted by: @john40131

many thanks to @zeferby who has helped me on my Model railway travels

And I have many thanks to @zeferby who has helped me also.

The sketch you're using is almost the same as the one I was using except I was using toggle switches.  I said was, until @zeferby created a much better sketch with slow movement.  Many thanks Eric. 

But I still can't stop a servo, usually on the 1st pin of the PCA9685, from going mental - sometimes - when I power up.  And when they're supposed to be stationary, they sometimes shake slightly, not the thing you want when your train is running through the point!

David


ReplyQuote
John40131
(@john40131)
Trusted Member
Joined: 10 months ago
Posts: 77
2020-02-17 11:44 am  

@dorsay

Sorry cant help with servo problem ... yeh I think mine are SG90 not DC90 ... the small blue ones.

I have also a big thanks to Eric has he helped on a Block signal sketch going to test today ... and my 4 Way crossing polarity and point switching sketch this was over 1000 lines ... and it does work but just finishing wiring to Mimic panel also got a lot of 3D printing to do ... its going to be a busy week...

John

DSC 0009

 


ReplyQuote
John40131
(@john40131)
Trusted Member
Joined: 10 months ago
Posts: 77
2020-02-17 12:02 pm  
Posted by: @dorsay

The sketch you're using is almost the same as the one I was using except I was using toggle switches.  I said was, until @zeferby created a much better sketch with slow movement.  Many thanks Eric. 

I am the same but I am using 16 toggle switches of which 5 are for a 4 Way Crossing polarity Mega which as well as giving control 10 DPDT relays for FROG switching it also controls 5 Relays for 5 " Y " point polarity (which I may not need ) also the 10 polarity outputs I have linked to an LED Mimic Vero board so I can see whats going on this then goes to another Relay board with 5 Relays to switch the second Mega that has the PCA9685 connect to ... this PCA9685 also has 2 switches for a Scissor crossing  4 SG90 servo's 3 of these servos also have microswiches to change polarity and Lock one direction if one is already switched ... the furthe 7 switch other SG90 servos for points on another board which will prob need Microswitches or Arduino for polarity and blocking ... JMRi is another option for the future..

John


ReplyQuote
ZeFerby
(@zeferby)
Reputable Member
Joined: 6 months ago
Posts: 348
2020-02-17 1:26 pm  
Posted by: @dorsay

But I still can't stop a servo, usually on the 1st pin of the PCA9685, from going mental - sometimes - when I power up

About this point I'm wondering if a solution like this could help : have a relay that only delivers power to the servos side after the MCU has initialized and the PCA9685 has stable PWM values setup on all relevant channels

Posted by: @dorsay

And when they're supposed to be stationary, they sometimes shake slightly, not the thing you want when your train is running through the point!

Isn't that where the "flexible" approach is supposed to help ? (servos with stable positions slightly over the position needed to establish the direction, the excess movement absorbed by the flexible transmission)

Sorry, I have no model railroad to test...

 

Also : are you sure your GND is ok and shared by MCU, PCA, servos ?

Eric


ReplyQuote
dorsay
(@dorsay)
Trusted Member
Joined: 2 months ago
Posts: 67
2020-02-18 4:50 am  

@john40131

You're a brave man, John. ? 

David


ReplyQuote
dorsay
(@dorsay)
Trusted Member
Joined: 2 months ago
Posts: 67
2020-02-18 5:03 am  

@zeferby

Posted by: @zeferby

have a relay that only delivers power to the servos side after the MCU has initialized and the PCA9685 has stable PWM values setup on all relevant channels

That's a thought but do you mean 1 relay for all servos or 1 relay per servo?

Posted by: @zeferby

Isn't that where the "flexible" approach is supposed to help ? (servos with stable positions slightly over the position needed to establish the direction, the excess movement absorbed by the flexible transmission)

The flexible piano wire allows the user to not have to position the servo so exactly that it stops at the absolute correct position.  The shaking that I'm getting is enough to transmit movement through the piano wire to the turnout.

Update: tried again today with a new servo in the set of 5 (only need 4 toggles as 2 servos are controlled by 1 toggle).  I was beginning to think the problem was being caused by my sketch as the servos seemed to be ok using yours.  But then, when testing all toggles and I switched the 4th and last toggle, the 2 servos controlled by that toggle went crazy.  Then tested all toggles and all servos went crazy!

I'm no electronics person - you could say that electronics is one of my least favourite things but I need them in my hobby  -  but is it possible that the problems I'm experiencing could be caused by questionable connections?  I'm relying on pins and jumper wires through a breadboard.  I'm sure things would be better if I soldered everything but I'm hesitant to go to all that effort and still have the problem?

David


ReplyQuote
dorsay
(@dorsay)
Trusted Member
Joined: 2 months ago
Posts: 67
2020-02-18 5:06 am  

@zeferby

Posted by: @zeferby

are you sure your GND is ok and shared by MCU, PCA, servos ?

GND is definitely shared but the connection may be suss as I said in my previous post.

David


ReplyQuote
ZeFerby
(@zeferby)
Reputable Member
Joined: 6 months ago
Posts: 348
2020-02-18 7:30 am  

@dorsay

Hum, I'm wondering how the "servos side" of your PCA9685 is powered ?

Maybe your power supply doesn't have enough juice for all servos ?

Maybe you share a single power supply with both the Arduino and the servos ? Then adding some decoupling capacitors could help because the servos will create some nasty feedback.

Also make sure NOT to power servos from the Arduino itself !

 

I think we may be hitting multiple (unrelated ?) problems at the same time...now it's time to think !

Can you post your current sketch and some kind of rough schematic of your setup ?

Eric


ReplyQuote
John40131
(@john40131)
Trusted Member
Joined: 10 months ago
Posts: 77
2020-02-18 9:48 am  
Posted by: @dorsay

Update: tried again today with a new servo in the set of 5 (only need 4 toggles as 2 servos are controlled by 1 toggle).  I was beginning to think the problem was being caused by my sketch as the servos seemed to be ok using yours.  But then, when testing all toggles and I switched the 4th and last toggle, the 2 servos controlled by that toggle went crazy.  Then tested all toggles and all servos went crazy!

I had a problem with a previous sketch when I used a voltage divider and inputs to A0 to A5 and when I switched 2 servo's at once went a bit crazy, I found it was the 5volt power source using a LM7805 5volt regulator the voltage was falling so I built a 3 amp 5 volt regulator using an LM7805 but feeding output to a 2N3055 transistor , you have to put a small voltage divider to ground pin on LM7805 so output is just above 5 volts feeding to base of 2N3055 so emitter output is 5 volts and collector is voltage input in my case 12 volts and a few stabalising capacitors, and that solved my problem, or use a dedicated 5 volt source, as for me my main power source is a 12 volt 10amp switch mode PSU ...

John

DSC 0010

 


ReplyQuote
dorsay
(@dorsay)
Trusted Member
Joined: 2 months ago
Posts: 67
2020-02-20 12:05 pm  

@zeferby

Posted by: @zeferby

Maybe your power supply doesn't have enough juice for all servos ?

Maybe you share a single power supply with both the Arduino and the servos ? Then adding some decoupling capacitors could help because the servos will create some nasty feedback.

Also make sure NOT to power servos from the Arduino itself !

The Arduino is powered by either the USB or a separate power supply.  I've tried 12v and 5v.  The PCA9685 is powered by it's own 5v supply.

Posted by: @zeferby

Can you post your current sketch and some kind of rough schematic of your setup ?

The sketch in use is the one you wrote.  Can you remember it or would you like me to post it?  A rough schematic will be just that, rough!  Still working on it.

David


ReplyQuote
dorsay
(@dorsay)
Trusted Member
Joined: 2 months ago
Posts: 67
2020-02-20 12:07 pm  

@john40131

Posted by: @john40131

I found it was the 5volt power source using a LM7805 5volt regulator the voltage was falling so I built a 3 amp 5 volt regulator using an LM7805 but feeding output to a 2N3055 transistor , you have to put a small voltage divider to ground pin on LM7805 so output is just above 5 volts feeding to base of 2N3055 so emitter output is 5 volts and collector is voltage input in my case 12 volts and a few stabalising capacitors, and that solved my problem, or use a dedicated 5 volt source, as for me my main power source is a 12 volt 10amp switch mode PSU ...

That's impressive John, but more than my very limited capabilities.  It looks like electronics is a hobby for you.  For me, not so.

David


ReplyQuote
John40131
(@john40131)
Trusted Member
Joined: 10 months ago
Posts: 77
2020-02-20 12:55 pm  

Hi david.

Regarding SG90 servo's I just been testing my point motors and was finding 2 didnt work thought was it wiring was it my program but I tested on bench, found it was the motors that had died also noticed last thing another motor chattering a bit so will keep my eye on it so I think its the crappy SG90 servos, I just ordered another 12 off ebay ... or is it being caused by the speed the servo moves ... so would be interseted to see what your sketch is showing to slow movement down ... also a good idea to get a servo tester .... im getting very close to powering up just need to test the 5 "Y" point motors thats on a different Mega and also need to re-upload sketch from last time Eric and I were trying to find a problem ... one strange problem I did find was, was using outputs to power an LED and for some strange reason these output voltages were dropping on just these pins even when I changed to other data pins was same so maybe something on program ... Eric did modify so will try ... but I put these outputs into a Cmos chip a CD4069 Hex invertor which does'nt put a load on input and that worked, this was to work my Mimic panel LED's ..

John


ReplyQuote
dorsay
(@dorsay)
Trusted Member
Joined: 2 months ago
Posts: 67
2020-02-21 5:21 am  

@john40131

Posted by: @john40131

so would be interseted to see what your sketch is showing to slow movement down

John here's the sketch that I was planning on using with a PCA9685.  This was written by Eric (@zeferby).

<pre>
<font color="#5e6d03">#include</font> <font color="#434f54">&lt;</font><font color="#d35400">Wire</font><font color="#434f54">.</font><font color="#000000">h</font><font color="#434f54">&gt;</font>
<font color="#5e6d03">#include</font> <font color="#434f54">&lt;</font><b><font color="#d35400">Adafruit_PWMServoDriver</font></b><font color="#434f54">.</font><font color="#000000">h</font><font color="#434f54">&gt;</font>
<b><font color="#d35400">Adafruit_PWMServoDriver</font></b> <font color="#000000">pwm</font> <font color="#434f54">=</font> <b><font color="#d35400">Adafruit_PWMServoDriver</font></b><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>

<font color="#5e6d03">#define</font> <font color="#000000">NB_OF_SERVOS</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#000000">4</font>

<font color="#434f54">// Let's have arrays so we can adjust the nb. of servos</font>
<font color="#00979c">int</font> <font color="#000000">switchPins</font><font color="#000000">[</font><font color="#000000">NB_OF_SERVOS</font><font color="#000000">]</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">=</font> <font color="#000000">{</font> <font color="#000000">2</font><font color="#434f54">,</font> <font color="#000000">3</font><font color="#434f54">,</font> <font color="#000000">4</font><font color="#434f54">,</font> <font color="#000000">5</font><font color="#434f54">,</font> &nbsp;<font color="#000000">}</font><font color="#000000">;</font>
<font color="#00979c">int</font> <font color="#000000">switchStates</font><font color="#000000">[</font><font color="#000000">NB_OF_SERVOS</font><font color="#000000">]</font> &nbsp;&nbsp;&nbsp;<font color="#434f54">=</font> <font color="#000000">{</font> <font color="#00979c">LOW</font><font color="#434f54">,</font> <font color="#00979c">LOW</font><font color="#434f54">,</font> <font color="#00979c">LOW</font><font color="#434f54">,</font> <font color="#00979c">LOW</font><font color="#434f54">,</font> &nbsp;<font color="#000000">}</font><font color="#000000">;</font>
<font color="#00979c">int</font> <font color="#000000">leftPWM</font><font color="#000000">[</font><font color="#000000">NB_OF_SERVOS</font><font color="#000000">]</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">=</font> <font color="#000000">{</font> <font color="#000000">370</font><font color="#434f54">,</font> <font color="#000000">370</font><font color="#434f54">,</font> <font color="#000000">370</font><font color="#434f54">,</font> <font color="#000000">370</font><font color="#434f54">,</font> &nbsp;<font color="#000000">}</font><font color="#000000">;</font> &nbsp;<font color="#434f54">//adjust limits per servo as required</font>
<font color="#00979c">int</font> <font color="#000000">rightPWM</font><font color="#000000">[</font><font color="#000000">NB_OF_SERVOS</font><font color="#000000">]</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">=</font> <font color="#000000">{</font> <font color="#000000">290</font><font color="#434f54">,</font> <font color="#000000">290</font><font color="#434f54">,</font> <font color="#000000">290</font><font color="#434f54">,</font> <font color="#000000">290</font><font color="#434f54">,</font> &nbsp;<font color="#000000">}</font><font color="#000000">;</font> &nbsp;<font color="#434f54">//adjust limits per servo as required</font>
<font color="#00979c">bool</font> <font color="#000000">bRightIsMinPWM</font><font color="#000000">[</font><font color="#000000">NB_OF_SERVOS</font><font color="#000000">]</font><font color="#000000">;</font> &nbsp;<font color="#434f54">//Manage servo orientation (rightPWM &lt; leftPWM or leftPWM &gt; rightPWM)</font>

<font color="#434f54">//variabes for timed movement</font>
<font color="#00979c">int</font> <font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">NB_OF_SERVOS</font><font color="#000000">]</font><font color="#000000">;</font>
<font color="#00979c">int</font> <font color="#000000">targetPWM</font><font color="#000000">[</font><font color="#000000">NB_OF_SERVOS</font><font color="#000000">]</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#00979c">long</font> <font color="#000000">prevMillis</font><font color="#000000">[</font><font color="#000000">NB_OF_SERVOS</font><font color="#000000">]</font> <font color="#434f54">=</font> <font color="#000000">{</font> <font color="#000000">0UL</font><font color="#434f54">,</font> <font color="#000000">0UL</font><font color="#434f54">,</font> <font color="#000000">0UL</font><font color="#434f54">,</font> <font color="#000000">0UL</font><font color="#434f54">,</font> <font color="#000000">}</font><font color="#000000">;</font> <font color="#434f54">//</font>

<font color="#434f54">//-------------------------------------------------</font>
<font color="#434f54">//adjust these constants to tune the movement speed (for all servos)</font>
<font color="#5e6d03">#define</font> <font color="#000000">MILLIS_PER_STEP</font> &nbsp;&nbsp;&nbsp;&nbsp;<font color="#000000">15UL</font> &nbsp;<font color="#434f54">// PWM/servo "step" every 15ms</font>
<font color="#5e6d03">#define</font> <font color="#000000">PWM_STEP_INCREMENT</font> &nbsp;<font color="#000000">2</font> &nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">// PWM value gets +/-2 for each "step"</font>
<font color="#434f54">//-------------------------------------------------</font>
<font color="#434f54">//adjust this constant to tune the overall speed of the sketch</font>
<font color="#5e6d03">#define</font> <font color="#000000">MAIN_LOOP_DELAY_uS</font> &nbsp;<font color="#000000">15UL</font> &nbsp;<font color="#434f54">//microseconds delay at the end of the main loop()</font>
<font color="#434f54">//-------------------------------------------------</font>

<font color="#434f54">//For real operation, comment the following define</font>
<font color="#434f54">//#define TEST_TUNE</font>

<font color="#434f54">//Test/tune utility variables</font>
<font color="#5e6d03">#ifdef</font> <font color="#000000">TEST_TUNE</font>
<font color="#5e6d03">#define</font> <font color="#000000">MILLIS_TEST_TUNE</font> &nbsp;&nbsp;&nbsp;&nbsp;<font color="#000000">10000UL</font> <font color="#434f54">//test/tune duration for direction reversing : 10 seconds</font>
<font color="#00979c">unsigned</font> <font color="#00979c">long</font> <font color="#000000">testMillis</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#000000">;</font>
<font color="#00979c">int</font> <font color="#000000">iTestLowHigh</font> &nbsp;<font color="#434f54">=</font> <font color="#00979c">HIGH</font><font color="#000000">;</font>
<font color="#5e6d03">#endif</font> &nbsp;<font color="#434f54">//TEST_TUNE</font>

<font color="#00979c">void</font> <font color="#5e6d03">setup</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#000000">{</font>
&nbsp;<b><font color="#d35400">Serial</font></b><font color="#434f54">.</font><font color="#d35400">begin</font><font color="#000000">(</font><font color="#000000">9600</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<b><font color="#d35400">Serial</font></b><font color="#434f54">.</font><font color="#d35400">println</font><font color="#000000">(</font><font color="#005c5f">"PCA9685_Turnouts_Timed - timed movement tests..."</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#000000">pwm</font><font color="#434f54">.</font><font color="#d35400">begin</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#000000">pwm</font><font color="#434f54">.</font><font color="#d35400">setPWMFreq</font><font color="#000000">(</font><font color="#000000">60</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#d35400">delay</font><font color="#000000">(</font><font color="#000000">30</font><font color="#000000">)</font><font color="#000000">;</font>

&nbsp;<font color="#5e6d03">for</font> <font color="#000000">(</font><font color="#00979c">int</font> <font color="#000000">iServo</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#000000">;</font> <font color="#000000">iServo</font> <font color="#434f54">&lt;</font> <font color="#000000">NB_OF_SERVOS</font><font color="#000000">;</font> <font color="#000000">iServo</font><font color="#434f54">++</font><font color="#000000">)</font>
&nbsp;<font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">bRightIsMinPWM</font><font color="#000000">[</font><font color="#000000">iServo</font><font color="#000000">]</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">rightPWM</font><font color="#000000">[</font><font color="#000000">iServo</font><font color="#000000">]</font> <font color="#434f54">&lt;</font> <font color="#000000">leftPWM</font><font color="#000000">[</font><font color="#000000">iServo</font><font color="#000000">]</font><font color="#000000">)</font><font color="#000000">;</font>

&nbsp;&nbsp;&nbsp;<font color="#d35400">pinMode</font><font color="#000000">(</font><font color="#000000">switchPins</font><font color="#000000">[</font><font color="#000000">iServo</font><font color="#000000">]</font><font color="#434f54">,</font> <font color="#00979c">INPUT_PULLUP</font><font color="#000000">)</font><font color="#000000">;</font>

&nbsp;&nbsp;&nbsp;<font color="#000000">pwm</font><font color="#434f54">.</font><font color="#d35400">setPWM</font><font color="#000000">(</font><font color="#000000">iServo</font><font color="#434f54">,</font> <font color="#000000">0</font><font color="#434f54">,</font> <font color="#000000">rightPWM</font><font color="#000000">[</font><font color="#000000">iServo</font><font color="#000000">]</font><font color="#000000">)</font><font color="#000000">;</font> &nbsp;&nbsp;<font color="#434f54">//swing servo right - Note : this initialization may be "brutal"...</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServo</font><font color="#000000">]</font> <font color="#434f54">=</font> <font color="#000000">rightPWM</font><font color="#000000">[</font><font color="#000000">iServo</font><font color="#000000">]</font><font color="#000000">;</font> &nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">//remember current position</font>
&nbsp;<font color="#000000">}</font>

<font color="#000000">}</font><font color="#434f54">//void setup()</font>

<font color="#00979c">void</font> <font color="#5e6d03">loop</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#000000">{</font>

<font color="#5e6d03">#ifdef</font> <font color="#000000">TEST_TUNE</font>
&nbsp;<font color="#434f54">//test/tune mode</font>

&nbsp;<font color="#5e6d03">if</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#d35400">millis</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#434f54">-</font> <font color="#000000">testMillis</font><font color="#000000">)</font> <font color="#434f54">&gt;=</font> <font color="#000000">MILLIS_TEST_TUNE</font><font color="#000000">)</font>
&nbsp;<font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">iTestLowHigh</font> <font color="#434f54">=</font> <font color="#434f54">!</font><font color="#000000">iTestLowHigh</font><font color="#000000">;</font> &nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">//reverse direction</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">testMillis</font> <font color="#434f54">=</font> <font color="#d35400">millis</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#000000">}</font>

&nbsp;<font color="#5e6d03">for</font> <font color="#000000">(</font><font color="#00979c">int</font> <font color="#000000">iServo</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#000000">;</font> <font color="#000000">iServo</font> <font color="#434f54">&lt;</font> <font color="#000000">NB_OF_SERVOS</font><font color="#000000">;</font> <font color="#000000">iServo</font><font color="#434f54">++</font><font color="#000000">)</font>
&nbsp;<font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">checkMoveServo</font><font color="#000000">(</font><font color="#000000">iServo</font><font color="#434f54">,</font> <font color="#000000">iTestLowHigh</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#000000">}</font>

<font color="#5e6d03">#else</font> <font color="#434f54">//TEST_TUNE</font>
&nbsp;<font color="#434f54">//real operations</font>
&nbsp;<font color="#00979c">int</font> <font color="#000000">newSwitchState</font><font color="#000000">;</font>

&nbsp;<font color="#5e6d03">for</font> <font color="#000000">(</font><font color="#00979c">int</font> <font color="#000000">iServo</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#000000">;</font> <font color="#000000">iServo</font> <font color="#434f54">&lt;</font> <font color="#000000">NB_OF_SERVOS</font><font color="#000000">;</font> <font color="#000000">iServo</font><font color="#434f54">++</font><font color="#000000">)</font>
&nbsp;<font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">newSwitchState</font> <font color="#434f54">=</font> <font color="#d35400">digitalRead</font><font color="#000000">(</font><font color="#000000">switchPins</font><font color="#000000">[</font><font color="#000000">iServo</font><font color="#000000">]</font><font color="#000000">)</font><font color="#000000">;</font> &nbsp;&nbsp;&nbsp;<font color="#434f54">//&lt;&lt;== may need debouncing ???</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">checkMoveServo</font><font color="#000000">(</font><font color="#000000">iServo</font><font color="#434f54">,</font> <font color="#000000">newSwitchState</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#000000">}</font>

<font color="#5e6d03">#endif</font> &nbsp;<font color="#434f54">//TEST_TUNE</font>

&nbsp;<font color="#d35400">delayMicroseconds</font><font color="#000000">(</font><font color="#000000">MAIN_LOOP_DELAY_uS</font><font color="#000000">)</font><font color="#000000">;</font>

<font color="#000000">}</font><font color="#434f54">//void loop()</font>

<font color="#00979c">void</font> <font color="#000000">checkMoveServo</font><font color="#000000">(</font><font color="#00979c">uint8_t</font> <font color="#000000">iServoNumber</font><font color="#434f54">,</font> <font color="#00979c">int</font> <font color="#000000">iNewSwitchState</font><font color="#000000">)</font> <font color="#000000">{</font>
&nbsp;<font color="#00979c">unsigned</font> <font color="#00979c">long</font> <font color="#000000">currMillis</font> <font color="#434f54">=</font> <font color="#d35400">millis</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#00979c">bool</font> <font color="#000000">bNotAtTarget</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">!=</font> <font color="#000000">targetPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">)</font><font color="#000000">;</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">//target not reached ?</font>
&nbsp;<font color="#00979c">bool</font> <font color="#000000">bTimerElapsed</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">currMillis</font> <font color="#434f54">-</font> <font color="#000000">prevMillis</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">&gt;=</font> <font color="#000000">MILLIS_PER_STEP</font><font color="#000000">)</font><font color="#000000">;</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">//step delay elapsed ?</font>
&nbsp;<font color="#00979c">bool</font> <font color="#000000">bBeginMove</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">iNewSwitchState</font> <font color="#434f54">!=</font> <font color="#000000">switchStates</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">)</font><font color="#000000">;</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">//switch toggled ?</font>

&nbsp;<font color="#00979c">bool</font> <font color="#000000">bMoveStep</font> <font color="#434f54">=</font> <font color="#000000">bBeginMove</font> <font color="#434f54">||</font> <font color="#000000">(</font><font color="#000000">bNotAtTarget</font> <font color="#434f54">&amp;&amp;</font> <font color="#000000">bTimerElapsed</font><font color="#000000">)</font><font color="#000000">;</font> &nbsp;&nbsp;<font color="#434f54">//must move : first or next step</font>

&nbsp;<font color="#5e6d03">if</font> <font color="#000000">(</font><font color="#434f54">!</font><font color="#000000">bMoveStep</font><font color="#000000">)</font> <font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#5e6d03">return</font><font color="#000000">;</font> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#434f54">//nothing to do, bye bye</font>
&nbsp;<font color="#000000">}</font>

&nbsp;<font color="#434f54">//From here on, we take a step, let's remember the time...</font>
&nbsp;<font color="#000000">prevMillis</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">=</font> <font color="#000000">currMillis</font><font color="#000000">;</font>

&nbsp;<font color="#434f54">//if the switch has been toggled, we need to BEGIN new movement (even if we were already moving</font>
&nbsp;<font color="#434f54">//in the opposite direction) : we set the target and remember the switch state</font>
&nbsp;<font color="#5e6d03">if</font> <font color="#000000">(</font><font color="#000000">bBeginMove</font><font color="#000000">)</font>
&nbsp;<font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">targetPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">iNewSwitchState</font> <font color="#434f54">==</font> <font color="#00979c">HIGH</font><font color="#000000">)</font> <font color="#434f54">?</font> <font color="#000000">leftPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">:</font> <font color="#000000">rightPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">;</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">switchStates</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">=</font> <font color="#000000">iNewSwitchState</font><font color="#000000">;</font>
&nbsp;<font color="#000000">}</font>

&nbsp;<font color="#434f54">//Calculate PWM for this step increment</font>
&nbsp;<font color="#5e6d03">if</font> <font color="#000000">(</font><font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">&gt;</font> <font color="#000000">targetPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">)</font> <font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">-=</font> <font color="#000000">PWM_STEP_INCREMENT</font><font color="#000000">;</font>
&nbsp;<font color="#000000">}</font>
&nbsp;<font color="#5e6d03">else</font> <font color="#5e6d03">if</font> <font color="#000000">(</font><font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">&lt;</font> <font color="#000000">targetPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">)</font> <font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font> <font color="#434f54">+=</font> <font color="#000000">PWM_STEP_INCREMENT</font><font color="#000000">;</font>
&nbsp;<font color="#000000">}</font>

&nbsp;<font color="#434f54">//avoid going over limits (if the increment is &gt;1)</font>
&nbsp;<font color="#434f54">//using &nbsp;</font><u><font color="#434f54">https://www.arduino.cc/reference/en/language/functions/math/constrain/</font></u><font color="#434f54"></font>
&nbsp;<font color="#5e6d03">if</font> <font color="#000000">(</font><font color="#000000">bRightIsMinPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">)</font> <font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#d35400">constrain</font><font color="#000000">(</font><font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#434f54">,</font> <font color="#000000">rightPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#434f54">,</font> <font color="#000000">leftPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#000000">}</font>
&nbsp;<font color="#5e6d03">else</font> <font color="#000000">{</font>
&nbsp;&nbsp;&nbsp;<font color="#d35400">constrain</font><font color="#000000">(</font><font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#434f54">,</font> <font color="#000000">leftPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#434f54">,</font> <font color="#000000">rightPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">)</font><font color="#000000">;</font>
&nbsp;<font color="#000000">}</font>

&nbsp;<font color="#434f54">//Finally apply this step</font>
&nbsp;<font color="#000000">pwm</font><font color="#434f54">.</font><font color="#d35400">setPWM</font><font color="#000000">(</font><font color="#000000">iServoNumber</font><font color="#434f54">,</font> <font color="#000000">0</font><font color="#434f54">,</font> <font color="#000000">currentPWM</font><font color="#000000">[</font><font color="#000000">iServoNumber</font><font color="#000000">]</font><font color="#000000">)</font><font color="#000000">;</font>

<font color="#000000">}</font><font color="#434f54">//void checkMoveServo(uint8_t iServoNumber, int iNewSwitchState)</font>

</pre>

David


ReplyQuote
dorsay
(@dorsay)
Trusted Member
Joined: 2 months ago
Posts: 67
2020-02-21 5:23 am  

@john40131

Sorry, posted it incorrectly.

 

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define NB_OF_SERVOS        4

// Let's have arrays so we can adjust the nb. of servos
int switchPins[NB_OF_SERVOS]      = { 2, 3, 4, 5,  };
int switchStates[NB_OF_SERVOS]    = { LOW, LOW, LOW, LOW,  };
int leftPWM[NB_OF_SERVOS]         = { 370, 370, 370, 370,  };  //adjust limits per servo as required
int rightPWM[NB_OF_SERVOS]        = { 290, 290, 290, 290,  };  //adjust limits per servo as required
bool bRightIsMinPWM[NB_OF_SERVOS];  //Manage servo orientation (rightPWM < leftPWM or leftPWM > rightPWM)

//variabes for timed movement
int currentPWM[NB_OF_SERVOS];
int targetPWM[NB_OF_SERVOS];
unsigned long prevMillis[NB_OF_SERVOS] = { 0UL, 0UL, 0UL, 0UL, }; //

//-------------------------------------------------
//adjust these constants to tune the movement speed (for all servos)
#define MILLIS_PER_STEP     15UL  // PWM/servo "step" every 15ms
#define PWM_STEP_INCREMENT  2     // PWM value gets +/-2 for each "step"
//-------------------------------------------------
//adjust this constant to tune the overall speed of the sketch
#define MAIN_LOOP_DELAY_uS  15UL  //microseconds delay at the end of the main loop()
//-------------------------------------------------


//For real operation, comment the following define
//#define TEST_TUNE

//Test/tune utility variables
#ifdef TEST_TUNE
#define MILLIS_TEST_TUNE     10000UL //test/tune duration for direction reversing : 10 seconds
unsigned long testMillis = 0;
int iTestLowHigh  = HIGH;
#endif  //TEST_TUNE


void setup() {
  Serial.begin(9600);
  Serial.println("PCA9685_Turnouts_Timed - timed movement tests...");
  pwm.begin();
  pwm.setPWMFreq(60);
  delay(30);

  for (int iServo = 0; iServo < NB_OF_SERVOS; iServo++)
  {
    bRightIsMinPWM[iServo] = (rightPWM[iServo] < leftPWM[iServo]);

    pinMode(switchPins[iServo], INPUT_PULLUP);

    pwm.setPWM(iServo, 0, rightPWM[iServo]);   //swing servo right - Note : this initialization may be "brutal"...
    currentPWM[iServo] = rightPWM[iServo];     //remember current position
  }

}//void setup()


void loop() {

#ifdef TEST_TUNE
  //test/tune mode

  if ((millis() - testMillis) >= MILLIS_TEST_TUNE)
  {
    iTestLowHigh = !iTestLowHigh;     //reverse direction
    testMillis = millis();
  }

  for (int iServo = 0; iServo < NB_OF_SERVOS; iServo++)
  {
    checkMoveServo(iServo, iTestLowHigh);
  }

#else //TEST_TUNE
  //real operations
  int newSwitchState;

  for (int iServo = 0; iServo < NB_OF_SERVOS; iServo++)
  {
    newSwitchState = digitalRead(switchPins[iServo]);    //<<== may need debouncing ???
    checkMoveServo(iServo, newSwitchState);
  }

#endif  //TEST_TUNE

  delayMicroseconds(MAIN_LOOP_DELAY_uS);

}//void loop()


void checkMoveServo(uint8_t iServoNumber, int iNewSwitchState) {
  unsigned long currMillis = millis();
  bool bNotAtTarget = (currentPWM[iServoNumber] != targetPWM[iServoNumber]);              //target not reached ?
  bool bTimerElapsed = (currMillis - prevMillis[iServoNumber] >= MILLIS_PER_STEP);        //step delay elapsed ?
  bool bBeginMove = (iNewSwitchState != switchStates[iServoNumber]);                      //switch toggled ?

  bool bMoveStep = bBeginMove || (bNotAtTarget && bTimerElapsed);   //must move : first or next step

  if (!bMoveStep) {
    return;         //nothing to do, bye bye
  }

  //From here on, we take a step, let's remember the time...
  prevMillis[iServoNumber] = currMillis;

  //if the switch has been toggled, we need to BEGIN new movement (even if we were already moving
  //in the opposite direction) : we set the target and remember the switch state
  if (bBeginMove)
  {
    targetPWM[iServoNumber] = (iNewSwitchState == HIGH) ? leftPWM[iServoNumber] : rightPWM[iServoNumber];
    switchStates[iServoNumber] = iNewSwitchState;
  }

  //Calculate PWM for this step increment
  if (currentPWM[iServoNumber] > targetPWM[iServoNumber]) {
    currentPWM[iServoNumber] -= PWM_STEP_INCREMENT;
  }
  else if (currentPWM[iServoNumber] < targetPWM[iServoNumber]) {
    currentPWM[iServoNumber] += PWM_STEP_INCREMENT;
  }

  //avoid going over limits (if the increment is >1)
  //using   https://www.arduino.cc/reference/en/language/functions/math/constrain/ 
  if (bRightIsMinPWM[iServoNumber]) {
    constrain(currentPWM[iServoNumber], rightPWM[iServoNumber], leftPWM[iServoNumber]);
  }
  else {
    constrain(currentPWM[iServoNumber], leftPWM[iServoNumber], rightPWM[iServoNumber]);
  }

  //Finally apply this step
  pwm.setPWM(iServoNumber, 0, currentPWM[iServoNumber]);

}//void checkMoveServo(uint8_t iServoNumber, int iNewSwitchState)

David


ReplyQuote
ZeFerby
(@zeferby)
Reputable Member
Joined: 6 months ago
Posts: 348
2020-02-21 12:19 pm  
Posted by: @dorsay

tried again today with a new servo in the set of 5 (only need 4 toggles as 2 servos are controlled by 1 toggle).  I was beginning to think the problem was being caused by my sketch as the servos seemed to be ok using yours.  But then, when testing all toggles and I switched the 4th and last toggle, the 2 servos controlled by that toggle went crazy.  Then tested all toggles and all servos went crazy!

Going back to this, I'm wondering if you plugged 2 servos into a single output port of the PCA9685.

If s,o I would not be surprised if the PCA had issues with this, and I would advise keeping 1 servo per output port of the PCA which means, if you want a single switch to command these 2 servos, that you'll just need to duplicate the switch pin number : if servos 4 and 5 among a series of 1 to 5 are to be controlled by a single switch then you can do this to use a common switch pin :

#define NB_OF_SERVOS        5

// Let's have arrays so we can adjust the nb. of servos
int switchPins[NB_OF_SERVOS]      = { 2, 3, 4, 5, 5 };
int switchStates[NB_OF_SERVOS]    = { LOW, LOW, LOW, LOW, LOW };
int leftPWM[NB_OF_SERVOS]         = { 370, 370, 370, 370, 370 };  //adjust limits per servo as required
int rightPWM[NB_OF_SERVOS]        = { 290, 290, 290, 290, 290 };  //adjust limits per servo as required

 

Eric


ReplyQuote
Page 5 / 6

Please Login or Register