#include <Servo.h>
Servo esc1;
Servo esc2;
Servo esc3;
Servo esc4;
#define SRC_NEUTRAL 1504
#define SRC_MAX 2004
#define SRC_MIN 988
#define TRC_NEUTRAL 1504
#define TRC_MAX 1992
#define TRC_MIN 1004
#define SRC_INTERVAL 50
#define TRC_INTERVAL 30
uint16_t unSteeringMin = SRC_MIN;
uint16_t unSteeringMax = SRC_MAX;
uint16_t unSteeringCenter = SRC_NEUTRAL;
uint16_t unThrottleMin = TRC_MIN;
uint16_t unThrottleMax = TRC_MAX;
uint16_t unThrottleCenter = TRC_NEUTRAL;
#define pos_min 39
#define pos_max 140
#define PPM_SPEED_1 5
#define PPM_SPEED_2 6
#define PPM_SPEED_3 9
#define PPM_SPEED_4 10
#define THROTTLE_IN_PIN 2
#define STEERING_IN_PIN 3
#define THROTTLE_FLAG 1
#define STEERING_FLAG 2
volatile uint8_t bUpdateFlagsShared;
volatile uint16_t unThrottleInShared;
volatile uint16_t unSteeringInShared;
uint32_t ulThrottleStart;
uint32_t ulSteeringStart;
uint8_t gThrottle = 0;
uint8_t gGear = 1;
uint8_t gOldGear = 1;
#define DIRECTION_STOP 0
#define DIRECTION_FORWARD 1
#define DIRECTION_REVERSE 2
#define DIRECTION_ROTATE_RIGHT 3
#define DIRECTION_ROTATE_LEFT 4
uint8_t gThrottleDirection = DIRECTION_STOP;
uint8_t gDirection = DIRECTION_STOP;
uint8_t gOldDirection = DIRECTION_STOP;
unsigned long pulse_time ;
void setup() {
Serial.begin(9600);
attachInterrupt(0, calcThrottle, CHANGE);
attachInterrupt(1, calcSteering, CHANGE);
esc1.attach(PPM_SPEED_1);
esc2.attach(PPM_SPEED_2);
esc3.attach(PPM_SPEED_3);
esc4.attach(PPM_SPEED_4);
pulse_time = millis();
arm();
}
void arm()
{
Serial.println("Arming start");
for(int i = 0; i < 50; i++)
{
esc1.write(140);
esc2.write(140);
esc3.write(140);
esc4.write(140);
delay(1);
esc1.write(39);
esc2.write(39);
esc3.write(39);
esc4.write(39);
delay(20);
}
Serial.println("Arming done");
}
void loop() {
static uint16_t unThrottleIn;
static uint16_t unSteeringIn;
static uint8_t bUpdateFlags;
Serial.print("Throttle: ");
Serial.println(unThrottleInShared);
Serial.print("Steering: ");
Serial.println(unSteeringInShared);
if(bUpdateFlagsShared)
{
noInterrupts();
pulse_time = millis();
bUpdateFlags = bUpdateFlagsShared;
if(bUpdateFlags & THROTTLE_FLAG)
{
unThrottleIn = unThrottleInShared;
}
if(bUpdateFlags & STEERING_FLAG)
{
unSteeringIn = unSteeringInShared;
}
interrupts();
}
if(bUpdateFlags & THROTTLE_FLAG)
{
unThrottleIn = constrain(unThrottleIn, unThrottleMin, unThrottleMax);
if(unThrottleIn > (unThrottleCenter + TRC_INTERVAL))
{
gThrottle = map(unThrottleIn,(unThrottleCenter + TRC_INTERVAL),unThrottleMax,pos_min,pos_max);
gThrottleDirection = DIRECTION_FORWARD;
}
else if (unThrottleIn < (unThrottleCenter - TRC_INTERVAL))
{
gThrottle = map(unThrottleIn,unThrottleMin,(unThrottleCenter-TRC_INTERVAL),pos_max,pos_min);
gThrottleDirection = DIRECTION_REVERSE;
}
else
{
gThrottleDirection = DIRECTION_STOP;
gThrottle=0;
}
}
uint8_t throttleSlow = gThrottle;
if(bUpdateFlags & STEERING_FLAG)
{
gDirection = gThrottleDirection;
unSteeringIn = constrain(unSteeringIn, unSteeringMin, unSteeringMax);
if(unSteeringIn > (unSteeringCenter + SRC_INTERVAL))
{
gDirection = DIRECTION_ROTATE_RIGHT;
throttleSlow = map(unSteeringIn, unSteeringCenter, unSteeringMax, gThrottle, gThrottle*0.8);
}
else if(unSteeringIn<(unSteeringCenter - SRC_INTERVAL))
{
gDirection = DIRECTION_ROTATE_LEFT;
throttleSlow = map(unSteeringIn, unSteeringMin, unSteeringCenter, gThrottle*0.8, gThrottle);
}
}
if (gThrottleDirection == DIRECTION_FORWARD)
{
if (gDirection == DIRECTION_ROTATE_RIGHT)
{
esc1.write(39);
esc2.write(39);
esc3.write(gThrottle);
esc4.write(throttleSlow);
}
else if (gDirection == DIRECTION_ROTATE_LEFT)
{
esc1.write(39);
esc2.write(39);
esc3.write(throttleSlow);
esc4.write(gThrottle);
}
else
{
esc1.write(39);
esc2.write(39);
esc3.write(gThrottle);
esc4.write(gThrottle);
}
}
else if (gThrottleDirection == DIRECTION_REVERSE)
{
if (gDirection == DIRECTION_ROTATE_RIGHT)
{
esc1.write(throttleSlow);
esc2.write(gThrottle);
esc3.write(39);
esc4.write(39);
}
else if (gDirection == DIRECTION_ROTATE_LEFT)
{
esc1.write(gThrottle);
esc2.write(throttleSlow);
esc3.write(39);
esc4.write(39);
}
else
{
esc1.write(gThrottle);
esc2.write(gThrottle);
esc3.write(39);
esc4.write(39);
}
}
else {
esc1.write(39);
esc2.write(39);
esc3.write(39);
esc4.write(39);
}
bUpdateFlags = 0;
}
void calcThrottle()
{
if(digitalRead(THROTTLE_IN_PIN) == HIGH)
{
ulThrottleStart = micros();
}
else
{
unThrottleInShared = (uint16_t)(micros() - ulThrottleStart);
bUpdateFlagsShared |= THROTTLE_FLAG;
}
}
void calcSteering()
{
if(digitalRead(STEERING_IN_PIN) == HIGH)
{
ulSteeringStart = micros();
}
else
{
unSteeringInShared = (uint16_t)(micros() - ulSteeringStart);
bUpdateFlagsShared |= STEERING_FLAG;
}
}