Hello, I have a project I'm working on where I have a virtual representation of a 5-joint robotic arm in Unity, and it sends the angles of the joint (in float form) to serial in the format "[yaw],[shoulder],[elbow],[wrist],[hand]|" so a typical update might look like "90,75.43,0,54.2,180|". The Arduino then parses this data and, using Adafruit's 16-channel PWM output, drives the 5 servos to those positions.
I know Arduino is receiving the data just fine through some debugging, so the problem almost certainly isn't on Unity's end. However, I tried running it and manually sending an update (I used "90,90,90,0,90|", the arm's home position, as a test) through the serial monitor and told it to spit back what it received, and it only gave me "9". Here's my code you can look over...
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN 150 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 600 // this is the 'maximum' pulse length count (out of 4096)
float yaw, shoulder, elbow, wrist, hand;
// (7-digit float + 1 decimal + 1 endmark) * 5 servos = 45 char max
char data [45];
void receiveData () {
// reset data
for (int i = 0; i < 45; i++) {
data [i] = ' ';
}
//Serial.readBytesUntil ('|', data, 45);
Serial.readStringUntil('|').toCharArray(data, 45);
Serial.println(data); // when given the test "90,90,90,0,90|", this prints out "9" for some reason.
// parse data
char tmp [7];
int i;
int place;
// cycle through to get the individual angle values
for (i; data [i] != ','; i++) {
tmp [i - place] = data [i];
}
yaw = atof (tmp);
place = i;
for (i; data [i] != ','; i++) {
tmp [i - place] = data [i];
}
shoulder = atof (tmp);
place = i;
for (i; data [i] != ','; i++) {
tmp [i - place] = data [i];
}
elbow = atof (tmp);
place = i;
for (i; data [i] != ','; i++) {
tmp [i - place] = data [i];
}
wrist = atof (tmp);
place = i;
for (i; data [i] != '|'; i++) {
tmp [i - place] = data [i];
}
hand = atof (tmp);
}
void writeServos () {
//order is 0=yaw, 1=shoulder, 2=elbow, 3=wrist, 4=hand
pwm.setPWM (0, 0, map(yaw, 0, 180, SERVOMIN, SERVOMAX));
pwm.setPWM (1, 0, map(shoulder, 0, 180, SERVOMIN, SERVOMAX));
pwm.setPWM (2, 0, map(elbow, 0, 180, SERVOMIN, SERVOMAX));
pwm.setPWM (3, 0, map(wrist, 0, 180, SERVOMIN, SERVOMAX));
pwm.setPWM (4, 0, map(hand, 0, 180, SERVOMIN, SERVOMAX));
}
void setup () {
Serial.begin (9600);
pwm.begin();
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
}
void loop () {
if (Serial.available() > 0) {
receiveData ();
}
writeServos ();
//delay (10); // do I need this here? For stability and stuff?
}