Hello! I'm trying to control two servos acting as a turret. My program reads values off of an SD card (from an SD card module I built) and then writes the values to the servo. Weirdly, the servos do not write the correct values and freak out. I've written a sister program that doesn't use an SD card and it works fine. Here is the code:
#include <Servo.h>
#include <SD.h>
Servo servoOne; //x-axis
Servo servoTwo; //y-axis
const int SDpin = 10; //do not change!
const int laserPin = 4, servoOnePin = 2, servoTwoPin = 3;
int num, servo = 0, spd = 1000;
char array[5];
char posFile[10] = "fOut.txt";
void setup() {
servoOne.attach(servoOnePin);
servoTwo.attach(servoTwoPin);
pinMode(SDpin, OUTPUT);
pinMode(laserPin, OUTPUT);
Serial.begin(9600);
Serial.print("Initializing SD card...");
if (!SD.begin(SDpin)) {
Serial.println("Card failed, or not present");
return;
}
Serial.println("card initialized.");
servoOne.writeMicroseconds(1500);
servoTwo.writeMicroseconds(1500);
delay(500);
File dataFile = SD.open(posFile, FILE_READ);
if (dataFile) { //only starts if file exists
digitalWrite(laserPin, HIGH);
while (dataFile.available()) { //ends when file is over
readPosition();
Serial.println("Number:");
Serial.println(num);
if (servo == 0) {
servo = 1;
servoOne.writeMicroseconds(num);
}
else {
servo = 0;
servoTwo.writeMicroseconds(num);
Serial.println("Got here.");
}
Serial.println("Servo one:");
Serial.println(16.67*servoOne.read());
Serial.println("Servo two:");
Serial.println(16.67*servoTwo.read());
delay(spd);
}
digitalWrite(laserPin, LOW);
dataFile.close();
}
else { //error if no file
Serial.println("File not found.");
}
}
void loop() {
}
void readPosition() {
File dataFile = SD.open(posFile, FILE_READ);
Serial.println("Array values:");
for (int i = 0; i < 5; i++) { //adds the numbers into an array
array[i] = dataFile.read();
Serial.println(array[i]);
}
char *trunc = strtok(array, "\n\r\t"); //gets rid of extraneous characters
num = atoi(trunc); //converts the string into an int
if (num == 0) num = 1500; //resets the servo when the end of file returns 0
}
The Serial.println()'s are for debugging and give messages like:
Array values:
1
2
7
5
Number:
1275
Servo one:
1166.90
Servo two:
1533.64
Array values:
1
3
0
0
Number:
1300
Got here.
Servo one:
-666.80
Servo two:
1216.91
Array values:
1
2
7
5
Number:
1275
Servo one:
1166.90
Servo two:
1216.91
Array values:
1
3
0
4
Number:
1304
Got here.
Servo one:
-666.80
Servo two:
1216.91
As you can see, the servoOne position is negative, even though the number input makes sense. The positions of the servos do not match the input positions. Also, servoOne goes bonkers when servoTwo is supposed to move!
My thinking is, after much debugging and failing to spot the problem: the SD interface is messing with the servo pins in a way I don't understand. Any other suggestions? Thank you very much!
EDIT: Hello fellow searchers! I found the problem. The char array was too small. I wanted to read in 5 values but I set the array to only be size 5! Char arrays need to have an extra character at the end: \0. That's to show the end of the array. If you overwrite that or one of the characters is erased, then bad things happen. So make your array sizes larger than you think!