Notifications
Clear all

PCA 9685 to control servos

17 Posts
5 Users
0 Likes
4,401 Views
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

I am using the sketch that was on Dronebot Workshop to control 9 servos of which I am most grateful, 2 pairs servos will be linked so while one goes one way the other goes another, I wanted to change the input from Potentiometer to data inputs but my skills on sketches are very poor so I have gone for a Mega and use 9 Analog inputs I missed A4 and A5 as I think they are linked to SCL and SDA, and with a potential divider resistor network and SPDT and DPDT switches so input is about 2 volts so I get an angle of approx 60deg to operate points on a Model railway, I know there is a better way of doing this but I would get lost in the sketch, the only thing I would like to be able to do is slow down the servo movement but not sure if playing around with Min Pulse width and Max Pulse width would work, the original sketch with resistor network works really well..

 

Any help would be grateful, if I can get this part fixed I can move on to the main 4 way Crossing I have in Railway Forum.

Regards John


   
Quote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

Hi @john40131

for servos, the pulse width actually gives the angle position, so the MIN/MAX are about the angle limits.

To manage the movement speed what i usually see is a loop that gradually changes the value (either the angle position or the pulse width) in a timed manner.

Basically starting from something like this for a 60° to 120°:

for (int angle=60; angle<=120; angle++) {

  myservo.write(angle);

  delay(X);  // or delayMicroseconds(X) depending on requirements. find X by experimenting

}

Eric


   
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

@zeferby

This is the sketch which I have added inputs for extra servos but there isnt a way of adjusting speed, or is there..

Regards john

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
  PCA9685 PWM Servo Driver Example
  pca9685-servomotor-demo.ino
  Demonstrates use of 16 channel I2C PWM driver board with 4 servo motors
  Uses Adafruit PWM library
  Uses 4 potentiometers for input
 
  DroneBot Workshop 2018
*/
 
// Include Wire Library for I2C Communications
#include <Wire.h>
 
// Include Adafruit PWM Library
#include <Adafruit_PWMServoDriver.h>
 
#define MIN_PULSE_WIDTH       650
#define MAX_PULSE_WIDTH       2350
#define FREQUENCY             50
 
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
 
// Define Potentiometer Inputs
 
int controlA = A0;
int controlB = A1;
int controlC = A2;
int controlD = A3;
 
// Define Motor Outputs on PCA9685 board
 
int motorA = 0;
int motorB = 4;
int motorC = 8;
int motorD = 12;
 
void setup()
{
  pwm.begin();
  pwm.setPWMFreq(FREQUENCY);
}
 
 
void moveMotor(int controlIn, int motorOut)
{
  int pulse_wide, pulse_width, potVal;
  
  // Read values from potentiometer
  potVal = analogRead(controlIn);
  
  // Convert to pulse width
  pulse_wide = map(potVal, 0, 1023, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
  pulse_width = int(float(pulse_wide) / 1000000 * FREQUENCY * 4096);
  
  //Control Motor
  pwm.setPWM(motorOut, 0, pulse_width);
 
}
 
void loop() {
 
  //Control Motor A
  moveMotor(controlA, motorA);
  
  //Control Motor B
  moveMotor(controlB, motorB);
    
  //Control Motor C
  moveMotor(controlC, motorC);
  
  //Control Motor D
  moveMotor(controlD, motorD);
 
 
}

   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

@john40131

the only thing I would like to be able to do is slow down the servo movement

John, assuming your servos will control railroad turn points, or toggle "polarity" switches, I think you are hitting something like the "right tool for the job" problem : Bill's sample above was about manual control of servo position, while i think you're interested in 2 "fixed" positions AND the speed of movement between those.

Please tell me if my assumptions are wrong !

I think you would have an easier job starting with another library, freeing you from calculating pulse width etc... AND giving you access to movement speed.

One library I experimented with is ServoEasing , which gives you these features (and others you probably don't need) and it is compatible with the PCA9685 expander board. It provides functions like :

void easeTo(int aDegree, uint16_t aDegreesPerSecond);
void easeToD(int aDegree, uint16_t aMillisForMove);  
image

https://github.com/ArminJo/ServoEasing

 

Going back to your initial description :

control 9 servos

The PCA9685 is OK for this, only needing the I2C connection on the Arduino for all these servos.

 2 pairs servos will be linked so while one goes one way the other goes another

Item 1 : We'll have to remember that, it will imply some decisions in the design of the code.

By the way, do I understand it right as meaning 2x2 servos (the "2 pairs") + 5 "independant" servos = the 9 total ?

I wanted to change the input from Potentiometer to data inputs

Item 2 : Assuming we want to manage a "Left" and a "Right" position, each would be a servo angle, equivalent to a PWM pulse width.

Then all you need is a way to get a HIGH/LOW state with digitalRead on a pin linked to a switch or an Infrared sensor, etc... Any kind of input with 2 possible values will do.

Let's suppose you have a push button on a pin of the Arduino, somewhere in the loop() function you can do  :

int iLeftOrRight = digitalRead(thePushButtonArduinoPin);
if (iLeftOrRight==LOW) {
//do something for left position
}
else {
//do something for right position
}

 

The easiest way to manage the servos' positions is to store the 2 values (left/right) for each servo because they may not be identical for all servos.

Using angles, we can do something like this for example (of course, the left/right values have to be experimented on the physical setup) :

/*
!!! UN-Comment line 36 or 37 in ServoEasing.h to support PCA9685 expander !!!
This is the line with #define USE_PCA9685_SERVO_EXPANDER
Otherwise you will see errors like: "PCA9685_Expander:44:46: error: 'Wire' was not declared in this scope"
*/
#include "ServoEasing.h"

//Servos pins on the PCA9685
#define SERVO1_PIN 0
#define SERVO2_PIN 1
#define SERVO3_PIN 2
#define SERVO4_PIN 3
#define SERVO5_PIN 4
#define SERVO6_PIN 5
#define SERVO7_PIN 6
#define SERVO8_PIN 7
#define SERVO9_PIN 8

//Servos left and right positions
#define SERVO1_LEFT 58
#define SERVO1_RIGHT 124

#define SERVO2_LEFT 61
#define SERVO2_RIGHT 117

#define SERVO3_LEFT 60
#define SERVO3_RIGHT 120

#define SERVO4_LEFT 59
#define SERVO4_RIGHT 122

#define SERVO5_LEFT 57
#define SERVO5_RIGHT 121

#define SERVO6_LEFT 60
#define SERVO6_RIGHT 119

#define SERVO7_LEFT 59
#define SERVO7_RIGHT 123

#define SERVO8_LEFT 62
#define SERVO8_RIGHT 118

#define SERVO9_LEFT 70
#define SERVO9_RIGHT 125

ServoEasing myServo1;
ServoEasing myServo2;
ServoEasing myServo3;
ServoEasing myServo4;
ServoEasing myServo5;
ServoEasing myServo6;
ServoEasing myServo7;
ServoEasing myServo8;
ServoEasing myServo9;

//a digital pin on the Arduino for a switch/sensor, etc... commanding the servo pair 3+4
#define SWITCH_PIN_SERVOS_3_4 5

int lastSwitchPosition_Servos_3_4;

void setup() {
//...
myServo1.attach(SERVO1_PIN);
myServo2.attach(SERVO2_PIN);
myServo3.attach(SERVO3_PIN);
myServo4.attach(SERVO4_PIN);
myServo5.attach(SERVO5_PIN);
myServo6.attach(SERVO6_PIN);
myServo7.attach(SERVO7_PIN);
myServo8.attach(SERVO8_PIN);
myServo9.attach(SERVO9_PIN);
//...
//Initialize the servos 3+4 pair position to LEFT-RIGHT
lastSwitchPosition_Servos_3_4 = LOW;
myServo3.easeToD(SERVO3_LEFT, 1500); //mode servo 3 to LEFT position over 1.5 seconds
myServo4.easeToD(SERVO4_RIGHT, 1500); //mode servo 4 to RIGHT position over the same time of 1.5 seconds
//...
}//void setup()

void loop() {
//...
//some servos are moved for whatever reason...
myServo1.easeTo(SERVO1_LEFT, 30); //move servo 1 to LEFT position with 30 degrees per second speed
myServo2.easeToD(SERVO2_LEFT, 2000); //mode servo 2 to RIGHT position over 2 seconds
//...
//Did the switch change for the pair of servos 3+4 ?
int leftOrRight_Servos_3_4 = digitalRead(SWITCH_PIN_SERVOS_3_4);
if (leftOrRight_Servos_3_4 != lastSwitchPosition_Servos_3_4) {
//servos 3 and 4 are paired so they move in opposite directions
if (leftOrRight_Servos_3_4 == LOW) {
myServo3.easeToD(SERVO3_LEFT, 1500); //mode servo 3 to LEFT position over 1.5 seconds
myServo4.easeToD(SERVO4_RIGHT, 1500); //mode servo 4 to RIGHT position over the same time of 1.5 seconds
}
else {
myServo3.easeToD(SERVO3_RIGHT, 1500); //mode servo 3 to RIGHT position over 1.5 seconds
myServo4.easeToD(SERVO4_LEFT, 1500); //mode servo 4 to LEFT position over the same time of 1.5 seconds
}
//remember new position
lastSwitchPosition_Servos_3_4 = leftOrRight_Servos_3_4;
}//if (leftOrRight_Servos_3_4 != lastSwitchPosition_Servos_3_4)
//...
}//void loop()

 

Note : it would be more flexible to use global variables or constants of the array type if you're familiar with them :

https://www.arduino.cc/reference/en/language/variables/data-types/array/

/*
!!! UN-Comment line 36 or 37 in ServoEasing.h to support PCA9685 expander !!!
This is the line with #define USE_PCA9685_SERVO_EXPANDER
Otherwise you will see errors like: "PCA9685_Expander:44:46: error: 'Wire' was not declared in this scope"
*/
#include "ServoEasing.h"

ServoEasing myServos[9]; //9 servos
int servosPins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
int servosLeft[] = {58, 61, 60, 59, 57, 60, 59, 62, 70};
int servosRight[] = {124, 117, 120, 122, 121, 119, 123, 118, 125};

//remember the first element of an array is at index=0
//so we have myServos[0] to myServos[8]


//a digital pin on the Arduino for a switch/sensor, etc... commanding the servo pair at index 2 and 3
#define SWITCH_PIN_SERVOS_2_3 5

int lastSwitchPosition_Servos_2_3;


void setup() {
//...
for (int i = 0; i < 9; i++) {
myServos[i].attach(servosPins[i]);
}
//...
//Initialize the pair position for servos at index 2 and 3 to LEFT-RIGHT
lastSwitchPosition_Servos_2_3 = LOW;
myServos[2].easeToD(servosLeft[2], 1500); //mode servo 3 to LEFT position over 1.5 seconds
myServos[3].easeToD(servosRight[3], 1500); //mode servo 4 to RIGHT position over the same time of 1.5 seconds
//...
}//void setup()

void loop() {
//...
//some servos are moved for whatever reason...
myServos[0].easeTo(servosLeft[0], 30); //move servo 1 to LEFT position with 30 degrees per second speed
myServos[1].easeToD(servosLeft[1], 2000); //mode servo 2 to RIGHT position over 2 seconds
//...
//Did the switch change for the pair of servos at index 2 and 3 ?
int leftOrRight_Servos_2_3 = digitalRead(SWITCH_PIN_SERVOS_2_3);
if (leftOrRight_Servos_2_3 != lastSwitchPosition_Servos_2_3) {
//servos at index 2 and 3 are paired so they move in opposite directions
if (leftOrRight_Servos_2_3 == LOW) {
myServos[2].easeToD(servosLeft[2], 1500); //mode servo 3 to LEFT position over 1.5 seconds
myServos[3].easeToD(servosRight[3], 1500); //mode servo 3 to RIGHT position over the same time of 1.5 seconds
}
else {
myServos[2].easeToD(servosRight[2], 1500); //mode servo 3 to RIGHT position over 1.5 seconds
myServos[3].easeToD(servosLeft[3], 1500); //mode servo 3 to LEFT position over the same time of 1.5 seconds
}
//remember new position
lastSwitchPosition_Servos_2_3 = leftOrRight_Servos_2_3;
}//if (leftOrRight_Servos_2_3 != lastSwitchPosition_Servos_2_3)
//...
}//void loop()



Hoping this goes in the right direction for your needs...

 

Eric


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

...and of course I messed some Ctrl-C /Ctrl-V for the first 2 servos movement in the loop...

Eric


   
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

@zeferby

Hi Eric, Let me first thank you for the help you are giving me..

A bit of explanation so you know were i'm up to so far...

The sketch that I used from Bill does work, and being unable to work out how to use Data Pins and I had a spare Mega so can use the full 7 input Analog pins I need out of the 9 servo's, and you are correct 2 pairs of servos will work together on a Scissor crossing i.e there are 2 tracks with 4 sets of points and a Diamond crossing allowing a crossing in both directions I will probably use a DPDT switch so operates 2 servos independently but together if you get my meaning they will be the diagonal opposite servo's, this does require polarity switching depending which way you are going but that will be taken care of by the microswitches controlling 3 Mini relays.

The 5 points that are the other part of the equation will need to be triggered via the Servo board and the servo board will be operated via a MIMIC panel with 5 SPST switch so on the setup I have at the moment the switch will ground the analog input voltage, as you can see from the resistor divider I have a 4.7k and a 2.7k so I get 1.7 volts, I thought about using one common divider with all anolog pins working from the same supply but wasn't sure if you could do that.

Also I do somehow need an output from this Mega to operate the input and trigger the Crossover Mega board on the " track1Switch to track5Switch " there is probably a way of using the I2C bus to connect both together but that makes more complicated.

Sorry it gets more complicated.

Regarding the Servo angles they are not critical as the small arm on the servo has a piece of Piano wire bent and inserted in one of the holes this wire then goes through a 4mm hole in the servo mount and throught the base board which has a larger hole and the wire finishes up through a very small hole in the centre of the point actuator so as the arm moves from side to side the wire rocks in the opposite direction and moves the point and if it moves to much the wire will just flex so approx 60 deg, also by changing the hole in the servo arm can make more or less movement,  the servo arm can also operate microswitches which I can mount on the Servo mounts as required just 3D printed.

The small Vero board with heatsink on, is the 12volts input and 5 Volt supply from a 7805 for the PCA9685 and analog input voltage..

I will try you sketch tomorrow as I can easily build up another breadboard.

I will let you know how I get on.

Again many thanks for help.

Regards John

20191115 184328[1]

 

 

This post was modified 4 years ago by John40131

   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

@john40131

?This all seems to progress nicely.

Also I do somehow need an output from this Mega to operate the input and trigger the Crossover Mega board on the " track1Switch to track5Switch " there is probably a way of using the I2C bus to connect both together but that makes more complicated.

Actually if your 2 Megas have a common ground you may link digital pins from one (in OUPUT mode) going to digital pins of the other (INPUT or INPUT_PULLUP mode) ?

So if the MIMIC Mega only has to transmit some left/right or straight/turn infos to the destination Mega, you may perhaps use some of the numerous free digital pins on both Megas for that ?

Eric


   
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

@zeferby

Yes I did think about linking some

20191115 201710[1]

Output data pins of the MIMIC Mega to the Input pins of the crossover Mega but wasnt sure if you could do that and YES all the Arduino's have a common Ground and a 12 volt power source I also have a Nano which switches polarity of another Diamond crossing using 2 IR sensors, trigger on either and release when train has gone past second one and sets polarity for main line, its a similar sketch that you would use on a Road crossing using 2 servo's to operate the level crossing gates..


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

I found this : they advise on a 4K7 resistor on the line between an INPUT and an OUTPUT

https://forum.arduino.cc/index.php?topic=372148.0

 

Eric


   
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

@zeferby

Yeh thanks for that, just checked the sketches and not quite what I need the Line #define SWITCH_PIN_SERVOS_2_3  5, operates servo's 2 and 3 when pin 5 is low but they just go backwards and forwards, and I wouldnt have a clue how to modify this sketch to incorporate 9 servo's and switch say LOW to go Left and High to go Right or visa versa, so I think for the moment will keep with sketch I have that seems to work with Analogue inputs, but just got to workout were I can put a data pin command in Bill's sketch to give me a digital signal I can use on Crossover Mega.

Regards John


   
ReplyQuote
(@zeferby)
Member
Joined: 5 years ago
Posts: 355
 

@john40131

Oh it's just a sample, so you are supposed to mofify it according to your needs ? 

so if you want to switch servo at index X over a delay of myDelay milliseconds to the left on a LOW mySignal and to the right otherwise, it's just a matter of choosing servosLeft[X] rather than servosRight[X] for the corresponding value of the input :

if (mySignal == LOW) {
myServos[X].easeToD(servosLeft[X], myDelay); //mode servo X to LEFT position over myDelay milliseconds
}
else {
myServos[X].easeToD(servosRight[X], myDelay); //mode servo X to RIGHT position over myDelay milliseconds
  }

And the mySignal symbol i used above can come from reading whatever digital level you want, so you can have for example multiple inputs A, B, C from pins 6, 7, 8, respectively commanding servos at indices 1, pair(2+3 reversed) and pair(4+5 reversed).

Let's say you would want :

  • servo index 1 to go LEFT on pin A LOW
  • pair(2+3) to go RIGHT/LEFT on pin B LOW
  • and pair(4+5) to go LEFT/RIGHT on pin C LOW.

It would give something like this :

//somewhere at the beginning of the script
#define INPUT_PIN_A    6
#define INPUT_PIN_B    7
#define INPUT_PIN_C    8
...
...
//somewhere in loop() :
if (digitalRead(INPUT_PIN_A) == LOW) {
myServos[1].easeToD(servosLeft[1], 1000); //mode servo 1 to LEFT position over 1 second
}
else {
myServos[1].easeToD(servosRight[1], 1000); //mode servo 1 to RIGHT position over 1 second
  }

if (digitalRead(INPUT_PIN_B) == LOW) {   //RIGHT-LEFT pair
myServos[2].easeToD(servosRight[2], 1500); //mode servo 2 to RIGHT position over 1.5 second
myServos[3].easeToD(servosLeft[3], 1500); //mode servo 3 to LEFT position over 1.5 second }
else {
myServos[2].easeToD(servosLeft[2], 1500); //mode servo 2 to LEFT position over 1.5 second
myServos[3].easeToD(servosRight[3], 1500); //mode servo 3 to RIGHT position over 1.5 second
}

if (digitalRead(INPUT_PIN_C) == LOW) {   //LEFT-RIGHT pair
myServos[4].easeToD(servosLeft[4], 2000); //mode servo 4 to LEFT position over 2 seconds
 myServos[5].easeToD(servosRight[5], 2000); //mode servo 5 to RIGHT position over 2 second
}
else {
myServos[4].easeToD(servosRight[4], 2000); //mode servo 4 to RIGHT position over 2 seconds
 myServos[5].easeToD(servosLeft[5], 2000); //mode servo 5 to LEFT position over 2 second
  }

 

Eric


   
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

@zeferby

Thanks again for feedback, I got Bill's sketch up and running on Layout but I will try that addition imformation you have sent prob be Monday as its my Birthday Tomoz so i dont think i will be doing

20191116 173538[1]

much work on layout ..

I have 5 switches working and I need some extension Dupont leads for 3 servo's before I can try the 2 x 2 servos..

Regards John


   
ReplyQuote
 DAVO
(@davo)
Member
Joined: 3 years ago
Posts: 3
 

Hi 

I need advice. extruded and assembled the robot MK2 I used this example for control but I have a problem with the range of motion serv.zachadzaj too deep into the structure. if I understand this correctly, we can use "maps" to determine the range of motion of the servo. I think it's higher but for all servos at the same time. I would need to set each servo separately. can you help me?

vyskusal som toto ale nefunguje to

// Include Wire Library for I2C Communications
#include <Wire.h>

// Include Adafruit PWM Library
#include <Adafruit_PWMServoDriver.h>

#define MIN_PULSE_WIDTH 650
#define MAX_PULSE_WIDTH 2350
#define FREQUENCY 50

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

// Define Potentiometer Inputs

int controlA = A0;
int controlB = A1;
int controlC = A2;
int controlD = A3;

// Define Motor Outputs on PCA9685 board

int motorA = 0;
int motorB = 4;
int motorC = 8;
int motorD = 12;

void setup()
{
pwm.begin();
pwm.setPWMFreq(FREQUENCY);
}

void moveMotor(int controlIn, int motorOut)
{
int pulse_wide1, pulse_width1, potVal1;
int pulse_wide2, pulse_width2, potVal2;
int pulse_wide3, pulse_width3, potVal3;
int pulse_wide4, pulse_width4, potVal4;

// Read values from potentiometer
potVal1 = analogRead(controlA);
potVal2 = analogRead(controlB);
potVal3 = analogRead(controlC);
potVal1 = analogRead(controlD);

// Convert to pulse width
pulse_wide1 = map(potVal1, 0,1023, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
pulse_width1 = int(float(pulse_wide1) / 1000000 * FREQUENCY * 4096);

pulse_wide2 = map(potVal2, 0,1023, 700, 1000);
pulse_width2 = int(float(pulse_wide2) / 1000000 * FREQUENCY * 4096);

pulse_wide3 = map(potVal3, 0,1023, 800, 1100);
pulse_width3 = int(float(pulse_wide3) / 1000000 * FREQUENCY * 4096);

pulse_wide4 = map(potVal4, 0,1023, 1000, 1300);
pulse_width4 = int(float(pulse_wide4) / 1000000 * FREQUENCY * 4096);

//Control Motor
pwm.setPWM(motorOut, 0, pulse_width1);
pwm.setPWM(motorOut, 0, pulse_width2);
pwm.setPWM(motorOut, 0, pulse_width3);
pwm.setPWM(motorOut, 0, pulse_width4);

}

void loop() {

//Control Motor A
moveMotor(controlA, motorA);

//Control Motor B
moveMotor(controlB, motorB);

//Control Motor C
moveMotor(controlC, motorC);

//Control Motor D
moveMotor(controlD, motorD);

}

thank you david


   
ReplyQuote
(@dronebot-workshop)
Workshop Guru Admin
Joined: 5 years ago
Posts: 1081
 

@davo  Welcome to the forum David!

You'll notice that I edited your post to put your code in a code block, it makes it easier to read. You can do this by highlighting the code and then using the code button, the one that looks like "<>", in the editor.

I'm working on a set of instruction pages for using the forum, as I know it's different than many other forums and can be a bit confusing.

😎

Bill

"Never trust a computer you can’t throw out a window." — Steve Wozniak


   
ReplyQuote
codecage
(@codecage)
Member Admin
Joined: 5 years ago
Posts: 1037
 

@davo

Good morning David!  Well it is still morning here anyway, but probably approaching evening where you are if I've got my geography correctly set in my mind.

I used the Google translator for the first time myself to translate your line that reads "vyskusal som toto ale nefunguje to" into English.  The line in English reads "I tried this but it doesn't work."

I'll take a look at your code as I have worked a little bit with the PCA 9685.  It might take me a few days to setup my PCA again to refresh my memory as I am currently in the middle of another project, and I may have some questions for you as well.  Meanwhile maybe others will jumping in to help with your issue.

SteveG


   
ReplyQuote
Page 1 / 2