Please add a public SSH key to your
profile to be able to clone the repository via the SSH protocol.
Pre-render was disabled for this project as it contains too many files. Please click on the files to view them.
arm.ino
#include <Servo.h>
#include <Wire.h>
const int SERVO_PINS[] = { 3, 5, 6, 9 };
const int BUF_SIZE = 200;
const int SLAVE_ADDRESS = 0x05;
int curr_pos[] = { 150, 80, 50, 90 };
int limits[][2] = {
{ 0, 180 },
// Base
{ 0, 180},
{ 0, 180 }, // 125: Horizontal
{ 0, 180 }
};
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo* servos[] = { &servo1, &servo2, &servo3, &servo4 };
const int NOF_AXES = sizeof(servos)/sizeof(servos[0]);
int index = 0;
char buffer[BUF_SIZE];
enum State
{
STATE_OK = 0,
STATE_UNKNOWN_COMMAND,
STATE_WRONG_BYTECOUNT,
STATE_INVALID_AXIS
};
int i2c_state = STATE_OK;
void receiveData(int byteCount)
{
int c = Wire.read();
switch (c)
{
case 0:
// Read status
if (byteCount != 1)
{
while (--byteCount)
Wire.read();
i2c_state = STATE_WRONG_BYTECOUNT;
}
break;
case 1:
{
// Move to position
if (byteCount != 3)
{
while (--byteCount)
Wire.read();
return;
}
const int axis = Wire.read();
if (axis >= NOF_AXES)
{
i2c_state = STATE_INVALID_AXIS;
return;
}
int value = Wire.read();
if (value < limits[axis][0])
{
value = limits[axis][0];
}
if (value > limits[axis][1])
{
value = limits[axis][1];
}
curr_pos[axis] = value;
i2c_state = STATE_OK;
}
break;
default:
while (--byteCount)
Wire.read();
i2c_state = STATE_UNKNOWN_COMMAND;
break;
}
}
void sendData()
{
Wire.write(i2c_state);
}
void setup()
{
for (size_t i = 0; i < sizeof(servos)/sizeof(servos[0]); ++i)
{
pinMode(SERVO_PINS[i], OUTPUT);
servos[i]->write(curr_pos[i]);
servos[i]->attach(SERVO_PINS[i]);
}
Serial.begin(57600);
Wire.begin(SLAVE_ADDRESS);
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
}
int get_int(const char* buffer, int len)
{
char intbuf[BUF_SIZE];
memcpy(intbuf, buffer, max(BUF_SIZE-1, len));
intbuf[len] = 0;
return atoi(intbuf);
}
int get_int(const char* buffer, int len, int& next)
{
int index = 0;
while (buffer[index] && isspace(buffer[index]) && len)
{
++index;
--len;
}
while (buffer[index] && !isspace(buffer[index]) && len)
{
++index;
--len;
}
char intbuf[BUF_SIZE];
memcpy(intbuf, buffer, index);
intbuf[index] = 0;
next = index+1;
return atoi(intbuf);
}
void process(const char* buffer)
{
switch (buffer[0])
{
// G: Go to absolute position
case 'G':
case 'g':
{
int index;
const int axis = get_int(buffer+1, BUF_SIZE-1, index);
int value = get_int(buffer+index, BUF_SIZE-1, index);
Serial.print(axis);
Serial.print(": ");
Serial.println(value);
switch (axis)
{
case 0:
case 1:
case 2:
case 3:
if (value < limits[axis][0])
{
Serial.print("Hit lower limit ");
Serial.println(limits[axis][0]);
value = limits[axis][0];
}
if (value > limits[axis][1])
{
Serial.print("Hit upper limit ");
Serial.println(limits[axis][1]);
value = limits[axis][1];
}
servos[axis]->write(value);
curr_pos[axis] = value;
break;
default:
Serial.println("ERROR: Invalid parameters to 'G'");
break;
}
}
break;
default:
Serial.println("ERROR: Unknown command");
break;
}
}
void loop()
{
if (Serial.available())
{
// Command from PC
char c = Serial.read();
if ((c == '\r') || (c == '\n'))
{
buffer[index] = 0;
index = 0;
process(buffer);
}
else
{
if (index >= BUF_SIZE)
{
Serial.println("Error: Line too long");
index = 0;
return;
}
buffer[index++] = c;
}
}
else
{
delay(10);
}
for (size_t i = 0; i < sizeof(servos)/sizeof(servos[0]); ++i)
{
Serial.print(i);
Serial.print(": ");
Serial.println(curr_pos[i]);
servos[i]->write(curr_pos[i]);
}
}