Hi Folks,
I'm working on a project, where I have (among other thing) a RC remote control coming in, an Accellerometer and a SaberTooth motor driver module.
The Arduino used is a Leonardo. In a nutshell, the goal is to send a command with the remote control, and based on the value recorded by the accelerometer, give a command to both motor.
My problem is that in order to "extract" the RC command, I use an interrupt: I capture the time value went to '1' then when it became a '0'. I the calculate the time in-between ....
For the SaberTooth, I use "SimplifiedSerial" mode.
Now if the RC portion is enabled only, it works fine, but as soon as I enable the serial communication with the SaberTooth, the value received by the RC is somehow erratic. My guess is that the serial comm to the SaberTooth, is interfering my the interrupt for the RC.
I have tried to enable/disable the serial comm to the SaberTooth, in order to limit the interference, with no luck.
Right now, I use pin for the Serial Comm to the SaberTooth, but I could re-design my PCB to use Pin 1 (original Tx) but I'm not even sure if it would improve anything.
I originally was planning on using the RC mode on the SaberTooth, but it wasn't impressive ! My PCB being made, that's why I'm trying to use Pin 11 for serial comm.
/*
* Revision notes
* Includes ADXL345 logic
* includes Servo out (1 channel)
* Includes temperature sensor
* EEPROM Mapping
* 0 = Offset
* 1 = Polarity
*/
#include <EEPROM.h>
#include <Wire.h>
#include <ADXL345.h>
#include <LiquidCrystal_I2C.h>
#include <NewPing.h>
#include <SimpleTimer.h>
#include <SoftwareSerial.h>
#include <SabertoothSimplified.h>
SoftwareSerial SWSerial(NOT_A_PIN, 5); // RX on no pin (unused), TX on pin 11 (to S1).
SabertoothSimplified ST(SWSerial); // Use SWSerial as the serial port.
int TRIGGER_PIN = 13;
int ECHO_PIN = 12;
int MAX_DISTANCE = 200;
int Angle = 0;
int ValLH = 0;
int ValRH = 0;
String Line1 ="";
String Line2 ="";
String Line3 ="";
String Line4 ="";
int Temperature = 0;
int Distance = 0;
int TimeInCh1 = 0;
int TimeOutCh1 = 0;
int ValueCh1 = 0;
int Buffer = 0;
int MinSpeed = 1500;
int MaxSpeed = 1500;
int AbsoluteAngle = 0;
int MotorLeftCorrection = 0;
int MotorRightCorrection = 0;
int Correction = 0;
int Offset = 3;
byte ReadValue = 0;
byte Polarity = 0;
ADXL345 adxl; //variable adxl is an instance of the ADXL345 library
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
SimpleTimer timer;
void setup()
{
//Serial.begin(9600);
//Serial.println("Initializing Serial comm....");
Manipulate2Read();
pinMode(7, INPUT); //Remote Control Input
pinMode(8, INPUT); //Decrease Offset
pinMode(9, INPUT); //Write Offset to EEPROM
pinMode(10, INPUT); //Increase Offset
pinMode(11, INPUT); //Read Offset from EEPROM
attachInterrupt(digitalPinToInterrupt(7), CalculateRemoteCommand, CHANGE);
//SWSerial.begin(9600);
adxl.powerOn();
lcd.begin(20,4); // initialize the lcd for 16 chars 2 lines, turn on backlight
lcd.backlight(); // turn backlight on
timer.setInterval(333, Display);
timer.setInterval(250, ReadDistance);
}
//********************************************
void loop(){
timer.run();
int x,y,z;
adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z
Line1 = "Cmd= ";
Line1 = Line1 + ValueCh1;
Line1 = Line1 + " Offset:";
Line1 = Line1 + Offset;
Angle = map(x,-480,128,-90,90);
Angle = Angle + Offset;
Line2 = "Angle= ";
Line2 = Line2 + Angle;
Line2 = Line2 + " Temp: ";
Line2 = Line2 +Temperature;
ValLH = map(MotorLeftCorrection, -100, 100, -127, 127);
ValRH = map(MotorRightCorrection, -100, 100, -127, 127);
if(ValLH < -127)
{
ValLH = -127;
}
if(ValLH > 127)
{
ValLH = 127;
}
if(ValRH < -127)
{
ValRH = -127;
}
if(ValRH > 127)
{
ValRH = 127;
}
SWSerial.begin(9600);
ST.motor(1, ValLH);
ST.motor(2, ValRH);
SWSerial.end();
Temperature = map(analogRead(0),0,204,0,100);
Line3 = "LH :";
Line3 = Line3 + ValLH;
Line3 = Line3 + " RH :";
Line3 = Line3 + ValRH;
Line4 = "Dist to wall: ";
Line4 = Line4 + Distance;
Line4 = Line4 + " cm";
if (digitalRead(8)==1)
{
Offset = Offset+1;
ManipulateOffset2Save();
while(digitalRead(8)==1)
{
}
}
if (digitalRead(10)==1)
{
Offset = Offset-1;
ManipulateOffset2Save();
while(digitalRead(10)==1)
{
}
}
CalculateMotor();
if(digitalRead(9)==1)
{
ManipulateOffset2Save();
while(digitalRead(9)==1)
{
//wait
}
}
if(digitalRead(11)==1)
{
Offset = EEPROM.read(0);
while(digitalRead(11)==1)
{
//wait
}
}
}
//********************************************
void ReadDistance()
{
unsigned int uS = sonar.ping();
pinMode(ECHO_PIN,OUTPUT);
digitalWrite(ECHO_PIN,LOW);
pinMode(ECHO_PIN,INPUT);
Distance = uS / US_ROUNDTRIP_CM;
}
//********************************************
void Display()
{
lcd.clear();
lcd.setCursor(0,0); //Start on line 0
lcd.print(Line1);
lcd.setCursor(0,1); //Start on line 1
lcd.print(Line2);
lcd.setCursor(0,2); //Start on line 2
lcd.print(Line3);
lcd.setCursor(0,3); //Start on line 3
lcd.print(Line4);
}
//********************************************
void CalculateRemoteCommand()
{
if(digitalRead(7)==1)
{
TimeInCh1 = micros();
}
if(digitalRead(7)==0)
{
TimeOutCh1 = micros();
Buffer = TimeOutCh1 - TimeInCh1;
}
/*if(Buffer>900)
{
if(Buffer<1450)
{
ValueCh1 = map(Buffer,1025,1450, 100, 0);
}
}
if(Buffer>1550)
{
if(Buffer<1975)
{
ValueCh1 = map(Buffer,1450,1975, 0, -100);
}
}
if(Buffer>1449)
{
if(Buffer<1551)
{
ValueCh1 = 0;
}
}
//ValueCh1 = 25;*/
ValueCh1 = Buffer;
}
//********************************************
void CalculateMotor()
{
if (Angle <0)
{
AbsoluteAngle = Angle*-1;
}
else
{
AbsoluteAngle = Angle;
}
Correction = ((AbsoluteAngle * AbsoluteAngle));
if(ValueCh1==0)
{
Correction = Correction *1.5; //Set the gain of correction
}
if (Correction >=81)
{
Correction = 81;
}
if (Angle>0)
{
MotorLeftCorrection = ValueCh1-(Correction/2);
MotorRightCorrection = ValueCh1+(Correction/2);
}
if (Angle<0)
{
MotorLeftCorrection = ValueCh1+(Correction/2);
MotorRightCorrection = ValueCh1-(Correction/2);
}
}
//********************************************
void ManipulateOffset2Save()
{
if(Offset>0)
{
EEPROM.write(0,Offset);
EEPROM.write(1,1);
}
if(Offset <0)
{
EEPROM.write(0,!Offset);
EEPROM.write(1,0);
}
}
void Manipulate2Read()
{
//Serial.println("Entering Read routine....");
ReadValue = EEPROM.read(0);
Polarity = EEPROM.read(1);
if(Polarity ==1)
{
Offset = ReadValue;
}
if(Polarity ==0)
{
Offset = !ReadValue;
}
//Serial.print("Offset Value is:");
//Serial.println(Offset);
}
Please note that this is "Work in Progress", so some comments are not accurate/pertaining, and some "deadcode" is still present !