Luckily, there is a nice function built into the standard library for the Arduino called ASCII to Integer. atoi() is a nice function that will convert any single number from it's ASCII input to its equivalent integer value. The first step in doing this, since we want to pass values with more than one character (i.e. 1023) we need to create a character array with five places. The first four places will contain the four digits we want to convert and the last one will be set to null. This will always guarantee there will be a blank value at the end to signify the end of an integer. There are several ways to go about converting these values. Here is the approach I used.
The first thing I looked at was how the values were handled at each input. It was determined that at the end of each value (i.e. 15), a carriage return was inserted at the end of each line. This value has an ASCII code as well and we do not want to convert it to an integer (it doesn't have an integer value). Therefore a while loop was generated that would look for any new lines or carriage returns and check all values after. These ASCII characters are "13" and "10" (this can be looked up here). Whenever a "13" or "10" is NOT received, then the ASCII values that follow will be read and stored in the character array generated earlier. We will not touch the 5th place in the array as it will stay null. If a "13" or "10" IS received, then the first value of the array will be set to null, "\0." This will ensure there is no value stored to that variable and the motors will not move.
This sort of worked the first time around, however it turns out that whenever no value is sent to the Arduino's serial port, the ASCII value is "-1." This was corrected by adding an if statement looking to make sure the read value was not "-1." Since the value "0" tended to produce errors (not completely sure why), I set an "old" variable that moved the older value to it before converting the new value just read. If the new value was a zero, the old value was used instead.
The final code used for the motor driver (which works with the XBee modules connected or just using the computer's serial monitor to pass values via USB cable):
#define switchPin 2 // switch input
#define motor1Pin 3 // Motor 1 leg 1 (pin 2, 1A)
#define motor2Pin 4 // Motor 1 leg 2 (pin 7, 2A)
#define motor3Pin 6 // Motor 2 leg 1
#define motor4Pin 7 // Motor 2 leg 2
#define enable1Pin 9 // Motor1 enable pin
#define enable2Pin 10 // Motor2 enable pin
#define ledPin 13 // Reset LED
#define slack 50 // Slack in joystick
int Y_axis_initial = 0; // Defines starting position of Y axis
char stickRead[5]; // Defines character size of 4 for reading serial input, 5th is null
int stickY; // Stick value
void setup()
{
Serial.begin(9600); //Turn on the Serial Port at 9600 bps
// Sets scaling factors and reads initial value at program start
int x; // Sets storage variable for Serial.read()
int i = 0; // Defines a counter for while loop
Serial.flush();
while(((x = Serial.read()) != 13) && ( x != 10 ));
while( Y_axis_initial == 0 )
{
while(((x = Serial.read()) != 13) && ( x != 10 ))
{
if( x != -1)
{
stickRead[i++] = x;
}
stickRead[i] = '\0';
}
Y_axis_initial = atoi(stickRead);
}
// set the switches as an input:
pinMode(switchPin, INPUT);
// set all the other pins you're using as outputs:
pinMode(motor1Pin, OUTPUT);
pinMode(motor2Pin, OUTPUT);
pinMode(motor3Pin, OUTPUT);
pinMode(motor4Pin, OUTPUT);
pinMode(enable1Pin, OUTPUT);
pinMode(enable2Pin, OUTPUT);
pinMode(ledPin, OUTPUT);
// blink the LED 3 times. This should happen only once.
// if you see the LED blink three times, it means that the module
// reset itself,. probably because the motor caused a brownout
// or a short.
blink(ledPin, 3, 100);
}
void loop()
{
// Reads position of A0 and A1 (X and Y axis)
int x; // Sets storage variable for Serial.read()
int i = 0; // Defines a counter for while loop
while( ( ( x = Serial.read() ) != 13 ) && ( x != 10 ) )
{
if( x != -1 )
{
stickRead[i++] = x;
}
}
stickRead[i]='\0';
int oldstick = stickY;
stickY = atoi(stickRead);
if( stickY == 0 )
{
stickY = oldstick;
}
int minus_Y = abs(stickY-510)/2;
int plus_Y = abs(stickY-513)/2;
// Reads the position of Y axis and determines direction and speed
if (stickY < Y_axis_initial-slack)
{
analogWrite(enable2Pin, minus_Y);
digitalWrite(motor3Pin, HIGH); // set leg 1 of the Motor2 high
digitalWrite(motor4Pin, LOW); // set leg 2 of the Motor2 low
analogWrite(enable1Pin, minus_Y);
digitalWrite(motor1Pin, HIGH); // set leg 1 of the Motor1 high
digitalWrite(motor2Pin, LOW); // set leg 2 of the Motor1 low
}
if (abs(stickY - Y_axis_initial) < slack) // Sets deadspace on stick
{
digitalWrite(enable2Pin, LOW);
digitalWrite(enable1Pin, LOW);
}
if (stickY > Y_axis_initial+slack)
{
analogWrite(enable2Pin, plus_Y);
digitalWrite(motor3Pin, LOW); // set leg 1 of the Motor2 low
digitalWrite(motor4Pin, HIGH); // set leg 2 of the Motor2 low
analogWrite(enable1Pin, plus_Y);
digitalWrite(motor1Pin, LOW); // set leg 1 of the Motor1 low
digitalWrite(motor2Pin, HIGH); // set leg 2 of the Motor1 high
}
}
//blinks an LED
void blink(int whatPin, int howManyTimes, int milliSecs)
{
int i = 0;
for ( i = 0; i < howManyTimes; i++)
{
digitalWrite(whatPin, HIGH);
delay(milliSecs/2);
digitalWrite(whatPin, LOW);
delay(milliSecs/2);
}
}
After study a couple of of the blog posts on your website now, and I really like your manner of blogging. I bookmarked it to my bookmark website checklist and will be checking again soon. Pls check out my web site as properly and let me know what you think. play casino
ReplyDelete