Last active
April 10, 2017 21:07
-
-
Save sysrqbr/3a3811c11593c43b83c471d8d0383f23 to your computer and use it in GitHub Desktop.
Car-Project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ###### RC_Car_Project ######## | |
// Created by SysrqBR (Adail Junior) | |
// GitHub: https://github.com/sysrqbr | |
// | |
// Date : 21/02/2017 | |
// Last Modification : 24/02/2017 | |
// Version : 0.1.3 | |
// | |
// Thanks to GeekySingh at: http://www.instructables.com/member/GeekySingh/ | |
// for the Remote Controls code. | |
// | |
// Changelog Version 0.1.0 to 0.1.1 | |
// - Created controls for the Servo | |
// | |
// Changelog Version 0.1.1 to 0.1.2 | |
// - Add controls for the Brushmotor | |
// - Corrects 'parkinson' problem with the Servo | |
// | |
// Changelog Version 0.1.2 to 0.1.3 | |
// - Correct incorrect position and aceleration calculations problems | |
// - Changed all comments to english (grammar lovers could cry with some comments...) | |
// ####### Includes | |
#include <Servo.h> | |
// ####### Servo defines | |
#define STEERING_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt | |
#define STEERING_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead | |
#define NEUTRAL_STEERING 1480 // this is the duration in microseconds of neutral steering on an electric RC Car | |
#define SERVO 6 // Porta Digital 6 PWM | |
// ####### Brushmotor defines | |
#define THROTTLE_SIGNAL_IN 1 | |
#define THROTTLE_SIGNAL_IN_PIN 3 | |
#define NEUTRAL_THROTTLE 1480 | |
#define BRUSHDCFWD 11 // PWM Digital port Foward | |
#define BRUSHDCRWD 5// PWM Digital port reverse | |
// ####### Servo constants | |
const int steeringNeutral = NEUTRAL_STEERING; // Neutral value | |
const float steeringSinalMin = 996; // Steering Min RC value | |
const float steeringSinalMax = 1964; // Steering Max RC value | |
// ####### Servo global variables | |
volatile int nSteeringIn = NEUTRAL_STEERING; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile | |
volatile unsigned long ulStartPeriod = 0; // set in the interrupt | |
volatile boolean bNewSteeringSignal = false; // set in the interrupt and read in the loop | |
Servo servoMotor; // Create Servo | |
int steeringPos; // Servo position | |
int steeringPosLast = 90; // Changed last position | |
float steeringPosFloat; // Servo temp position | |
int steeringSinal; // RC steering signal | |
float razaoSteering = ( steeringSinalMax - steeringSinalMin ) / 180; // quantum to convert RC signal to a 0 - 180 value interval | |
// ####### Brushmotor constants | |
const int throttleNeutral = 1480; // Valor do centro | |
const float throttleSinalMin = 994; // Valor minimo do manche | |
const float throttleSinalMax = 1972; // Valor maximo do manche | |
// ####### Brushmotor global variables | |
volatile int nThrottleIn = NEUTRAL_THROTTLE; | |
volatile unsigned long ulThrottleStartPeriod = 0; | |
volatile boolean bNewThrottleSignal = false; | |
int throttleSpeed; // Brushmotor speed | |
int throttleSpeedTemp; // Brushmotor temporary speed value | |
float throttleSpeedTempFloat; // Brushmotor temporary float speed value | |
int throttleSinal; // RC throttle signal | |
float razaoThrottle = ( throttleSinalMax - throttleSinalMin ) / 255; // quantum to convert RC signal to a 0 - 255 value interval | |
// Setup block | |
// ################# | |
void setup () | |
{ | |
Serial.begin(9600); | |
// tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 2) changes from HIGH to LOW or LOW to HIGH | |
// catching these changes will allow us to calculate how long the input pulse is | |
attachInterrupt(STEERING_SIGNAL_IN,calcInputSteering,CHANGE); | |
attachInterrupt(THROTTLE_SIGNAL_IN,calcInputThrottle,CHANGE); | |
servoMotor.attach(SERVO); | |
servoMotor.write(90); // 90° motor initial position | |
pinMode(BRUSHDCFWD, OUTPUT); // Define pin to H-bridge circuit path to foward speed (Brushmotor) | |
pinMode(BRUSHDCRWD, OUTPUT); // Define pin to H-bridge circuit path to reverse speed (Brushmotor) | |
} // End Setup block | |
// ################################################## | |
void loop() | |
{ | |
// SERVO Controls | |
// ################# | |
if(bNewSteeringSignal) // if a new steering signal has been measured | |
{ | |
steeringSinal = nSteeringIn; | |
// set this back to false when we have finished with nSteeringIn, while true, calcInput will not update nSteeringIn | |
bNewSteeringSignal = false; | |
} | |
steeringPosFloat = ( steeringSinal - ( steeringSinalMin - 3 )) / razaoSteering; // Change to 0 to 180 range value | |
steeringPos = (int) steeringPosFloat; // Truncate float part | |
if ( steeringPos >= 89 and steeringPos <= 91 ) { // neutral area | |
steeringPos = 90; | |
if ( steeringPosLast != steeringPos ) { | |
servoMotor.write(steeringPos); // Rotates SERVO | |
} | |
steeringPosLast = steeringPos; | |
} | |
else { | |
if ( steeringPos >= 0 and steeringPos <= 180 ) { | |
servoMotor.write(steeringPos); // Rotates SERVO | |
steeringPosLast = steeringPos; | |
} | |
else if ( steeringPos > 180 ) { // Ensure valid interval | |
steeringPos = 180; | |
servoMotor.write(steeringPos); // Rotates SERVO | |
steeringPosLast = steeringPos; | |
} | |
else if (steeringPos < 0) { // Ensure valid interval | |
steeringPos = 0; | |
servoMotor.write(steeringPos); // Rotates SERVO | |
steeringPosLast = steeringPos; | |
} | |
} | |
servoMotor.write(steeringPos); // Rotates SERVO | |
// End SERVO Controls | |
// ############################################################### | |
// Brushmotor Controls | |
// ################# | |
// if a new throttle signal has been measured | |
if(bNewThrottleSignal) | |
{ | |
throttleSinal = nThrottleIn; // set this back to false when we have finished with nThrottleIn, while true, calcInput will not update nThrottleIn | |
bNewThrottleSignal = false; | |
} | |
Serial.print("razaoThrottle "); | |
Serial.println(razaoThrottle); | |
throttleSpeedTempFloat = ( throttleSinal - ( throttleSinalMin - 3 )) / razaoThrottle; // Convert to 0-255 range value | |
Serial.print("throttleSpeedTemp "); | |
Serial.println(throttleSpeedTemp); | |
throttleSpeedTemp = (int) throttleSpeedTempFloat; // Truncate float part | |
if ( throttleSpeedTemp >=126 and throttleSpeedTemp <=130 ){ // Stop Brushmotor movement | |
throttleSpeed = 0; | |
analogWrite(BRUSHDCFWD, throttleSpeed); // Brushmotor speed foward | |
analogWrite(BRUSHDCRWD, throttleSpeed); // Brushmotor speed reverse | |
} | |
else if ( throttleSpeedTemp < 126 ) { // reverse | |
if ( throttleSpeedTemp <= 1 ) { | |
throttleSpeed = 255; | |
} | |
else { | |
throttleSpeed = (int( ~( byte( throttleSpeedTemp + 127 ))))*2; | |
} | |
analogWrite(BRUSHDCFWD, 0); // Brushmotor speed foward | |
analogWrite(BRUSHDCRWD, throttleSpeed); // Brushmotor speed reverse | |
} | |
else if ( throttleSpeedTemp > 130) { // Foward | |
if ( throttleSpeedTemp >= 255 ) { | |
throttleSpeed = 255; | |
} | |
else { | |
throttleSpeed = ( throttleSpeedTemp - 128 )*2; | |
} | |
analogWrite(BRUSHDCRWD, 0); // reverse Brushmotor | |
analogWrite(BRUSHDCFWD, throttleSpeed); // foward Brushmotor | |
} | |
// End Brushmotor Controls | |
// ############################################################### | |
}// End loop | |
void calcInputSteering() | |
{ | |
// if the pin is high, its the start of an interrupt | |
if(digitalRead(STEERING_SIGNAL_IN_PIN) == HIGH) | |
{ | |
// get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its | |
// easy to understand and works very well | |
ulStartPeriod = micros(); | |
} | |
else | |
{ | |
// if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the | |
// start time ulStartPeriod from the current time returned by micros() | |
if(ulStartPeriod && (bNewSteeringSignal == false)) | |
{ | |
nSteeringIn = (int)(micros() - ulStartPeriod); | |
ulStartPeriod = 0; | |
// tell loop we have a new signal on the steering channel we will not update nSteeringIn until loop sets | |
// bNewSteeringSignal back to false | |
bNewSteeringSignal = true; | |
} | |
} | |
} // End calcInputSteering | |
void calcInputThrottle() | |
{ | |
// if the pin is high, its the start of an interrupt | |
if(digitalRead(THROTTLE_SIGNAL_IN_PIN) == HIGH) | |
{ | |
// get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its | |
// easy to understand and works very well | |
ulThrottleStartPeriod = micros(); | |
} | |
else | |
{ | |
// if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the | |
// start time ulStartPeriod from the current time returned by micros() | |
if(ulThrottleStartPeriod && (bNewThrottleSignal == false)) | |
{ | |
nThrottleIn = (int)(micros() - ulThrottleStartPeriod); | |
ulThrottleStartPeriod = 0; | |
// tell loop we have a new signal on the steering channel we will not update nSteeringIn until loop sets | |
// bNewSteeringSignal back to false | |
bNewThrottleSignal = true; | |
} | |
} | |
} // End calcInputThrottle |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment