Jump to content

DCS-BIOS Libreria 0.2.1 arduino help


Adrian_gc

Recommended Posts

Hey guys, I'm trying to compile a simple sketch using the new expalmes od arduino library 0.2.1 on DCS-BIOS.... any reference line containing a servo and not get it to work. I copied the example and the failure of compilation that gives me to see if you can help me:

 

 

Code: Example for flaps posotion indicator gauge:

 

#define DCSBIOS_IRQ_SERIAL

 

#include "DcsBios.h"

#include <Servo.h>

 

DcsBios::ServoOutput flapPos(0x10a0, 5, 544, 2400);

 

/* paste code snippets from the reference documentation here */

 

void setup() {

DcsBios::setup();

}

 

void loop() {

DcsBios::loop();

}

 

 

 

Compilation fail:

 

Arduino:1.6.7 (Windows 10), Placa:"Arduino/Genuino Uno"

 

aa:14: error: 'ServoOutput' in namespace 'DcsBios' does not name a type

 

DcsBios::ServoOutput flapPos(0x10a0, 5, 544, 2400);

 

^

 

exit status 1

'ServoOutput' in namespace 'DcsBios' does not name a type

 

 

 

Any Idea. Thanks so much !!!!

Link to comment
Share on other sites

You have to #include the Servo library before you include DCS-BIOS.

The following should work (it compiles, I have not verified it on actual hardware):

#define DCSBIOS_IRQ_SERIAL

#include <Servo.h>
#include "DcsBios.h"

DcsBios::ServoOutput flapPos(0x10a0, 5, 544, 2400);

/* paste code snippets from the reference documentation here */

void setup() {
DcsBios::setup();
}

void loop() {
DcsBios::loop();
}

 

Background: The ServoOutput class depends on the default Servo library, which ties up some of the hardware timers on the microcontroller when it is included in a sketch. If DCS-BIOS would include the Servo library for you, it would force you to give up those resources even if you are not using a ServoOutput anywhere.

 

The "fix" for this problem is to have the user explicitly include the Servo library and have the DCS-BIOS library only define the ServoOutput class if the default Servo library has already been included. To make that work, the Servo library has to be included before the DCS-BIOS library.

 

A less confusing solution (and what I plan to do in the long term) would be to move the ServoOutput class to a separate Arduino library. The same would apply to other possible additions, such as support for I2C I/O port expander chips.


Edited by [FSF]Ian
Link to comment
Share on other sites

From me

 

A less confusing solution (and what I plan to do in the long term) would be to move the ServoOutput class to a separate Arduino library. The same would apply to other possible additions, such as support for I2C I/O port expander chips.

 

You never fail to amaze me Joe, you spend a lot of time sorting out this. Can you not use what you are doing here towards your Uni degree/PHD/Doctor

 

I respect the time you spend here bro. :thumbup:

Windows 7 64 Home Premium, i5 3570K (3.4 @ 4.4GHz), Asus P8Z77-V LX, 16GB dual channel 1600 ram, EVGA Nvidia GTX980ti, 240 GB OCZ SSD, 3 TB Raptor, Thrustmaster Warthog Hotas and Throttle, Saitek Pro Combat Rudder pedals.

Link to comment
Share on other sites

  • 1 month later...
  • 1 year later...

hello my frindes,plz hellp me.I'm trying to compile a simple sketch using the stepper motor for altimeter pointer with arduino library 0.2.1 on DCS-BIOS..... I copied the example and the failure of compilation that gives me to see if you can help me:

 

this error after compile>>>>>>>>>>>>>>>>

 

Stepper_revolation:11: error: 'DcsBios' does not name a type

 

DcsBios::ProtocolParser parser;

 

^

 

C:\Users\dear ali\Documents\Arduino\my sketch\Stepper_revolation\Stepper_revolation.ino: In function 'void loop()':

 

Stepper_revolation:51: error: 'parser' was not declared in this scope

 

parser.processChar(Serial.read());

 

^

 

Stepper_revolation:53: error: 'DcsBios' has not been declared

 

DcsBios::PollingInput::pollInputs();

 

^

 

exit status 1

'DcsBios' does not name a type

 

 

 

this code is:>>>>>>>>>>>>

// include AccelStepper library

#include <AccelStepper.h>

 

// include DcsBios library

#include <DcsBios.h>

#include <Servo.h>

 

// DcsBios-related declarations

DcsBios::ProtocolParser parser;

 

#define STEPS_PER_REVOLUTION 240

#define ZERO_OFFSET 0

 

AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

int currentStepperPosition = 0; // current stepper position (in steps, from 0 to STEPS_PER_REVOLUTION-1)

signed long lastAccelStepperPosition;

 

void setup()

{

Serial.begin(250000);

 

pinMode (12,INPUT); // LOW when in zero position, HIGH otherwise

 

 

// set up stepper motor for zeroing

stepper.setMaxSpeed(1000);

stepper.setSpeed(500);

// run clockwise until we detect the zero position

while (digitalRead (12)==1) {

stepper.runSpeed();

}

 

// add zero offset

stepper.runToNewPosition(stepper.currentPosition() + ZERO_OFFSET);

 

// tell the AccelStepper library that we are at position zero

stepper.setCurrentPosition(0);

lastAccelStepperPosition = 0;

// set stepper acceleration in steps per second per second

// (default is zero)

stepper.setAcceleration(1000);

 

}

 

void loop()

{

// handle DcsBios communication

while (Serial.available()) {

parser.processChar(Serial.read());

}

DcsBios::PollingInput::pollInputs();

 

// move stepper motor

stepper.run();

}

 

void onDcsBiosWrite(unsigned int address, unsigned int value) {

if (address == 0x107e) {

digitalWrite (13,1);

unsigned int alt100ftValue = (value & 0xffff) >> 0;

 

// convert data from DCS to a target position expressed as a number of steps

int targetPosition = map(alt100ftValue, 0, 65535, 0, STEPS_PER_REVOLUTION-1);

 

// adjust currentStepperPosition to include the distance our stepper motor

// was moved since we last updated it

int movementSinceLastUpdate = stepper.currentPosition() - lastAccelStepperPosition;

currentStepperPosition += movementSinceLastUpdate;

lastAccelStepperPosition = stepper.currentPosition();

 

if (currentStepperPosition < 0) currentStepperPosition += STEPS_PER_REVOLUTION;

if (currentStepperPosition > STEPS_PER_REVOLUTION) currentStepperPosition -= STEPS_PER_REVOLUTION;

 

int delta = targetPosition - currentStepperPosition;

 

// if we would move more than 180 degree counterclockwise, move clockwise instead

if (delta < -(STEPS_PER_REVOLUTION/2)) delta += STEPS_PER_REVOLUTION;

// if we would move more than 180 degree clockwise, move counterclockwise instead

if (delta > (STEPS_PER_REVOLUTION/2)) delta -= STEPS_PER_REVOLUTION;

 

// tell AccelStepper to move relative to the current position

stepper.move(delta);

}

}

Link to comment
Share on other sites

Sorry

I took the sketch created by Warhog and Ian but arduino continues to make me mistake you can tell me where I am wrong?

#define DCSBIOS_IRQ_SERIAL

#include <AccelStepper.h>
#include "DcsBios.h"

struct StepperConfig {
 unsigned int maxSteps;
 unsigned int acceleration;
 unsigned int maxSpeed;
};


class Vid60Stepper : public DcsBios::Int16Buffer {
 private:
   AccelStepper& stepper;
   StepperConfig& stepperConfig;
   inline bool zeroDetected() { return digitalRead(irDetectorPin) == 1; }
   unsigned int (*map_function)(unsigned int);
   unsigned char initState;
   long currentStepperPosition;
   long lastAccelStepperPosition;
   unsigned char irDetectorPin;
   long zeroOffset;
   bool movingForward;
   bool lastZeroDetectState;

   long normalizeStepperPosition(long pos) {
     if (pos < 0) return pos + stepperConfig.maxSteps;
     if (pos >= stepperConfig.maxSteps) return pos - stepperConfig.maxSteps;
     return pos;
   }

   void updateCurrentStepperPosition() {
     // adjust currentStepperPosition to include the distance our stepper motor
     // was moved since we last updated it
     long movementSinceLastUpdate = stepper.currentPosition() - lastAccelStepperPosition;
     currentStepperPosition = normalizeStepperPosition(currentStepperPosition + movementSinceLastUpdate);
     lastAccelStepperPosition = stepper.currentPosition();
   }
 public:
   Vid60Stepper(unsigned int address, 
   AccelStepper& stepper, 
   StepperConfig& stepperConfig, 
   unsigned char irDetectorPin, 
   long zeroOffset, unsigned int (*map_function)(unsigned int)): Int16Buffer(address), 
   stepper(stepper), 
   stepperConfig(stepperConfig), 
   irDetectorPin(irDetectorPin), 
   zeroOffset(zeroOffset), 
   map_function(map_function), 
   initState(0), 
   currentStepperPosition(0), 
   lastAccelStepperPosition(0) 
   {
   }

   virtual void loop() {
     if (initState == 0) { // not initialized yet
       pinMode(irDetectorPin, INPUT);
       stepper.setMaxSpeed(stepperConfig.maxSpeed);
       stepper.setSpeed(1000);
       
       initState = 1;
     }
     if (initState == 1) {
       // move off zero if already there so we always get movement on reset
       // (to verify that the stepper is working)
       if (zeroDetected()) {
         stepper.runSpeed();
       } else {
           initState = 2;
       }
     }
     if (initState == 2) { // zeroing
       if (!zeroDetected()) {
         stepper.runSpeed();
       } else {
           stepper.setAcceleration(stepperConfig.acceleration);
           stepper.runToNewPosition(stepper.currentPosition() + zeroOffset);
           // tell the AccelStepper library that we are at position zero
           stepper.setCurrentPosition(0);
           lastAccelStepperPosition = 0;
           // set stepper acceleration in steps per second per second
           // (default is zero)
           stepper.setAcceleration(stepperConfig.acceleration);
           
           lastZeroDetectState = true;
           initState = 3;
       }
     }
     if (initState == 3) { // running normally
       
       // recalibrate when passing through zero position
       bool currentZeroDetectState = zeroDetected();
       if (!lastZeroDetectState && currentZeroDetectState && movingForward) {
         // we have moved from left to right into the 'zero detect window'
         // and are now at position 0
         lastAccelStepperPosition = stepper.currentPosition();
         currentStepperPosition = normalizeStepperPosition(zeroOffset);
       } else if (lastZeroDetectState && !currentZeroDetectState && !movingForward) {
         // we have moved from right to left out of the 'zero detect window'
         // and are now at position (maxSteps-1)
         lastAccelStepperPosition = stepper.currentPosition();
         currentStepperPosition = normalizeStepperPosition(stepperConfig.maxSteps + zeroOffset);
       }
       lastZeroDetectState = currentZeroDetectState;
       
       
       if (hasUpdatedData()) {
           // convert data from DCS to a target position expressed as a number of steps
           long targetPosition = (long)map_function(getData());

           updateCurrentStepperPosition();
           
           long delta = targetPosition - currentStepperPosition;
           
           // if we would move more than 180 degree counterclockwise, move clockwise instead
           if (delta < -((long)(stepperConfig.maxSteps/2))) delta += stepperConfig.maxSteps;
           // if we would move more than 180 degree clockwise, move counterclockwise instead
           if (delta > (stepperConfig.maxSteps/2)) delta -= (long)stepperConfig.maxSteps;

           movingForward = (delta >= 0);
           
           // tell AccelStepper to move relative to the current position
           stepper.move(delta);
           
       }
       stepper.run();
     }
   }
};

/* modify below this line */

/* define stepper parameters
  multiple Vid60Stepper instances can share the same StepperConfig object */
struct StepperConfig stepperConfig = 
 {
 400,  // maxSteps
 2200, // maxSpeed
 1000 // acceleration
 };


// define AccelStepper instance
AccelStepper stepper(AccelStepper::DRIVER, 9, 8);
// define Vid60Stepper class that uses the AccelStepper instance defined in the line above
//           v-- arbitrary name
Vid60Stepper alt100ftPointer(0x107e,          // address of stepper data
                            stepper,         // name of AccelStepper instance
                            stepperConfig,   // StepperConfig struct instance
                            11,              // IR Detector Pin (must be HIGH in zero position)
                            0,               // zero offset
                            [](unsigned int newValue) -> unsigned int {
 /* this function needs to map newValue to the correct number of steps */
 return map(newValue, 0, 65535, 0, stepperConfig.maxSteps-1);
                                                          });


void setup() {
 DcsBios::setup();
 pinMode(13, OUTPUT);
}

void loop() {
 PORTB |= (1<<5);
 PORTB &= ~(1<<5);
 DcsBios::loop();
}

 

 

 

error:

Altimeter.ino.ino:154:68: error: type '__lambda0' with no linkage used to declare function 'unsigned int __lambda0::operator()(unsigned int) const' with linkage [-fpermissive]

type '__lambda0' with no linkage used to declare function 'unsigned int __lambda0::operator()(unsigned int) const' with linkage [-fpermissive]

 

 

 

Arduino version :0.2.11


Edited by albateo
Link to comment
Share on other sites

before the load was working well using the adrian script

//Script by Adrian_gc
//https://forums.eagle.ru/showthread.php?t=145193

Code:
// include AccelStepper library
#include <AccelStepper.h>

// include DcsBios library
#include <DcsBios.h>
#include <Servo.h>

// DcsBios-related declarations
DcsBios:rotocolParser parser;

#define STEPS_PER_REVOLUTION 240
#define ZERO_OFFSET 0

AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
int currentStepperPosition = 0; // current stepper position (in steps, from 0 to STEPS_PER_REVOLUTION-1)
signed long lastAccelStepperPosition;

void setup()
{ 
Serial.begin(250000);

pinMode (12,INPUT); // LOW when in zero position, HIGH otherwise


// set up stepper motor for zeroing
stepper.setMaxSpeed(1000);
stepper.setSpeed(500);
// run clockwise until we detect the zero position
while (digitalRead (12)==1) {
stepper.runSpeed(); 
}

// add zero offset
stepper.runToNewPosition(stepper.currentPosition() + ZERO_OFFSET);

// tell the AccelStepper library that we are at position zero
stepper.setCurrentPosition(0);
lastAccelStepperPosition = 0;
// set stepper acceleration in steps per second per second
// (default is zero)
stepper.setAcceleration(1000);

}

void loop()
{
// handle DcsBios communication
while (Serial.available()) {
parser.processChar(Serial.read());
}
DcsBios:ollingInput::pollInputs();

// move stepper motor
stepper.run();
}

void onDcsBiosWrite(unsigned int address, unsigned int value) {
if (address == 0x107e) {
digitalWrite (13,1);
unsigned int alt100ftValue = (value & 0xffff) >> 0;

// convert data from DCS to a target position expressed as a number of steps
int targetPosition = map(alt100ftValue, 0, 65535, 0, STEPS_PER_REVOLUTION-1);

// adjust currentStepperPosition to include the distance our stepper motor
// was moved since we last updated it
int movementSinceLastUpdate = stepper.currentPosition() - lastAccelStepperPosition;
currentStepperPosition += movementSinceLastUpdate;
lastAccelStepperPosition = stepper.currentPosition();

if (currentStepperPosition < 0) currentStepperPosition += STEPS_PER_REVOLUTION;
if (currentStepperPosition > STEPS_PER_REVOLUTION) currentStepperPosition -= STEPS_PER_REVOLUTION;

int delta = targetPosition - currentStepperPosition;

// if we would move more than 180 degree counterclockwise, move clockwise instead
if (delta < -(STEPS_PER_REVOLUTION/2)) delta += STEPS_PER_REVOLUTION;
// if we would move more than 180 degree clockwise, move counterclockwise instead
if (delta > (STEPS_PER_REVOLUTION/2)) delta -= STEPS_PER_REVOLUTION;

// tell AccelStepper to move relative to the current position
stepper.move(delta);
}
}

I bought 10 NEMA engines that worked fine with that type of script

now I have to throw them into the rubbish ??

 

Arduino version:0.2.0


Edited by albateo
Link to comment
Share on other sites

Sorry

I took the sketch created by Warhog and Ian but arduino continues to make me mistake you can tell me where I am wrong?

 

error:

Altimeter.ino.ino:154:68: error: type '__lambda0' with no linkage used to declare function 'unsigned int __lambda0::operator()(unsigned int) const' with linkage [-fpermissive]

type '__lambda0' with no linkage used to declare function 'unsigned int __lambda0::operator()(unsigned int) const' with linkage [-fpermissive]

 

Arduino version :0.2.11

 

 

before the load was working well using the adrian script

 

I bought 10 NEMA engines that worked fine with that type of script

now I have to throw them into the rubbish ??

 

Arduino version:0.2.0

 

No need to throw anything out just yet.

 

I am not sure if I read this correct? You say Adrian's code was woking on dcs-bios-arduino-library v0.2.0 but Warhog/Ian's code is not working on dcs-bios-arduino-library v0.2.11?

 

I tried to compile Warhog/Ian's code using Arduino library 0.2.10 and get no errors at all.

 

@Holycat(IIAF) I am a little reluctant to downgrade dcs-bios-arduino-library to v0.2.0 just to try and compile since its from March of last year. Have you tried to convert into a later version of dcs-bios-arduino-library?

 

Cheers

 

Hans


Edited by Hansolo
Link to comment
Share on other sites

thanks a thousand problem solved

Arduino IDE old version

Sorry yet I made a mistake, I was a puppet

Now I need to understand what it takes to eliminate the search for "0"

 

My "0" is mechanical...

I do not need part of the sketch,can you help me?

 

Thanks again

 

Teo


Edited by albateo
Link to comment
Share on other sites

  • 2 weeks later...

hello Guys.

I can connected a stepper motor to DCS via a A3967 chip and arduino UNO, however, this is very funny but I have a proplem, when incressing altitude and needle reached to 12 o'clock , the stepper rotate cunter clockwise and intercept actual altitude in other side, this proplem occur in any rotation, which in desent or assent.

 

I apologise for my bad english.

 

 

 

MOV 001

 

 

this code whih used for altitude ((((A-10)))))

 

 

#define DCSBIOS_IRQ_SERIAL

#include <math.h>

 

#include <LiquidCrystal.h>

#include <Servo.h> //This library needs to go before DcsBios.h for the servos to work

#include <DcsBios.h>

#include <AccelStepper.h>

float b,d,f;

float c;

int e,a;

LiquidCrystal lcd(2,3,4,5,6,7);

void onAlt10000ftCntChange(unsigned int newValue) {

 

a=((newValue+353.53)/6603.6);

lcd.setCursor(0, 1);

lcd.print(a);

a=a*10000;

lcd.setCursor(0,1);

lcd.print(a);

 

}

DcsBios::IntegerBuffer alt10000ftCntBuffer(0x1080, 0xffff, 0, onAlt10000ftCntChange);

 

void onAlt1000ftCntChange(unsigned int newValue) {

 

b=((newValue+353.53)/6603.6);

 

 

if(9>b>8){

b=floor(b);

}

 

lcd.setCursor(6,1);

lcd.print(b);

b=b*1000;

//lcd.setCursor(6,1);

//lcd.print(b);

 

 

lcd.setCursor(0,0);

lcd.print("ALT");

}

DcsBios::IntegerBuffer alt1000ftCntBuffer(0x1082, 0xffff, 0, onAlt1000ftCntChange);

 

void onAlt100ftCntChange(unsigned int newValue) {

//lcd.setCursor(0, 1);

c=((newValue+353.53)/6603.6);

lcd.setCursor(11,1);

lcd.print©;

 

c=c*100;

e=a+b+c;

lcd.setCursor(3,0);

e=floor(e);

lcd.print(e);

 

}

DcsBios::IntegerBuffer alt100ftCntBuffer(0x1084, 0xffff, 0, onAlt100ftCntChange);

 

void onAlt100ftChange(unsigned int newValue) {

lcd.setCursor(12, 1);

d=((newValue+353.53)/6603.6);

 

//lcd.print(d);

 

}

DcsBios::IntegerBuffer alt100ftBuffer(0x107e, 0xffff, 0, onAlt100ftChange);

 

 

DcsBios::ProtocolParser parser;

 

struct StepperConfig {

unsigned int maxSteps;

unsigned int acceleration;

unsigned int maxSpeed;

};

 

class Vid29Stepper : public DcsBios::Int16Buffer {

private:

AccelStepper& stepper;

StepperConfig& stepperConfig;

unsigned int (*map_function)(unsigned int);

unsigned char initState;

public:

Vid29Stepper(unsigned int address, AccelStepper& stepper, StepperConfig& stepperConfig, unsigned int (*map_function)(unsigned int))

: Int16Buffer(address), stepper(stepper), stepperConfig(stepperConfig), map_function(map_function), initState(0) {

}

 

virtual void loop() {

if (initState == 0) { // not initialized yet

stepper.setMaxSpeed(stepperConfig.maxSpeed);

stepper.setAcceleration(stepperConfig.acceleration);

stepper.moveTo(-((long)stepperConfig.maxSteps));

initState = 1;

}

if (initState == 1) { // zeroing

stepper.run();

if (stepper.currentPosition() <= -((long)stepperConfig.maxSteps)) {

stepper.setCurrentPosition(0);

initState = 2;

stepper.moveTo(stepperConfig.maxSteps/2);

}

}

if (initState == 2) { // running normally

if (hasUpdatedData()) {

unsigned int newPosition = map_function(getData());

newPosition = constrain(newPosition, 0, stepperConfig.maxSteps);

stepper.moveTo(newPosition);

}

stepper.run();

}

}

};

 

struct StepperConfig stepperConfig = {

1600, // maxSteps

1000, // maxSpeed

1000 // acceleration

};

 

 

// define AccelStepper instance

AccelStepper stepper(AccelStepper::DRIVER, 8, 9);

// define Vid29Stepper class that uses the AccelStepper instance defined in the line above

// +-- arbitrary name

// | +-- Address of stepper data (from control reference)

// | | +-- name of AccelStepper instance

// v v v v-- StepperConfig struct instance

Vid29Stepper RFAN(0x107e, stepper, stepperConfig, [](unsigned int newValue) -> unsigned int {

/* this function needs to map newValue to the correct number of steps */

return map(newValue, 0, 65535, 0, stepperConfig.maxSteps);

});

 

void setup() {

DcsBios::setup();

 

pinMode (12,INPUT); // LOW when in zero position, HIGH otherwise

 

 

 

// set up stepper motor for zeroing

//stepper.setMaxSpeed(1000);

//stepper.setSpeed(500);

// run clockwise until we detect the zero position

//while (digitalRead (12)==1) {

//stepper.runSpeed();

//}

}

void loop() {

DcsBios::loop();

 

}

 

 

 

 

no body help me........


Edited by Holycat(IIAF)
Link to comment
Share on other sites

Holycat(IIAF) does you stepper motor have a mechanical stop? If it has a mechanic stop then it I don't think it will work with the altimeter. Do you have a datasheet for the stepper motor?

 

Also when you include code try and use the wrap code function. The the code will stand out and you don't get smileys in the code.

 

Cheers

Hans

1916709537_Wrapcode.png.852700b50e2bc93d7bc3fc6b1f68960f.png

Link to comment
Share on other sites

Holycat(IIAF) does you stepper motor have a mechanical stop? If it has a mechanic stop then it I don't think it will work with the altimeter. Do you have a datasheet for the stepper motor?

 

Also when you include code try and use the wrap code function. The the code will stand out and you don't get smileys in the code.

 

Cheers

Hans

 

hi,before connected, I removed hard interlock pin and this stepper free rotate 360 degree.

 

and about smileys .... befor copy this code from Arduino IDE, this Emoticons not existed.and my compiler ,compile this code without any error. thx


Edited by Holycat(IIAF)
Link to comment
Share on other sites

hi,before connected, I removed hard interlock pin and this stepper free rotate 360 degree.

 

You know that, but the code doesn't. It still assumes it is controlling a Vid29 motor, which does have the hard stop.

 

You have to use the code for the Vid60 motor, as that has been written for continuous rotation steppers.

Link to comment
Share on other sites

Ian;3283093']You know that, but the code doesn't. It still assumes it is controlling a Vid29 motor, which does have the hard stop.

 

You have to use the code for the Vid60 motor, as that has been written for continuous rotation steppers.

 

thx my friend. I try with VID60. :thumbup::thumbup::thumbup:

Link to comment
Share on other sites

  • 2 weeks later...
Ian;3283093']You know that, but the code doesn't. It still assumes it is controlling a Vid29 motor, which does have the hard stop.

 

You have to use the code for the Vid60 motor, as that has been written for continuous rotation steppers.

 

THX my frinde, this worked prefectly...

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...