Professional Documents
Culture Documents
Coaster Motor I2C 04-20-10
Coaster Motor I2C 04-20-10
motor_speed[motorIdx] = motorSpd;
// replace with lookup table here to allow for
non-linear motor response?
// for now, assume linear and equal side to side
int pwmValue = abs(motorSpd);
// disable first
analogWrite(motor_pins[motorIdx][0], 0);
if (motorSpd < 0)
{
digitalWrite(motor_pins[motorIdx][1], LOW);
digitalWrite(motor_pins[motorIdx][2], HIGH);
}
else
{
digitalWrite(motor_pins[motorIdx][1], HIGH);
digitalWrite(motor_pins[motorIdx][2], LOW);
}
// set analog output to start motor - done
analogWrite(motor_pins[motorIdx][0], pwmValue);
}
//
// set both motors to same speed in 1 call for
convinience
//
void setBothMotors(int motorSpd)
{
for(int i = 0; i < MOTOR_CNT; i++)
{
setMotorSpeed(i, motorSpd);
}
}
//
// I2C slave receive event handler
// registered in setup()
//
// byteCnt is the number of bytes received from
master
// first byte is mode, determines how many to follow
and what they mean
// mode 1 - set both motors to same speed. 2 bytes
(1 int) for speed follows
// mode 2 - set motors to individual speeds. 4 bytes
(2 int) for r, l speeds follows
void receiveEvent(int byteCnt) {
I2C_mode = Wire.receive();
// convert bytes to ints easily using defined
union
BYTE2INT received;
// int storage buffer
int intReceived[4] = {0, 0, 0, 0};
switch(I2C_mode)
{
// set both motors to same speed
// 2 bytes representing integer speed follow
case(SAME_SPEED):
received.asBytes[0] = Wire.receive();
received.asBytes[1] = Wire.receive();
setBothMotors(received.asInt);
changed = 1;
break;
//
// set motors to different speeds
// 4 bytes representing 2 integer speeds (right,
left) follow
case(UNIQUE_SPEED):
received.asBytes[0] = Wire.receive();
received.asBytes[1] = Wire.receive();
intReceived[0] = received.asInt;
received.asBytes[0] = Wire.receive();
received.asBytes[1] = Wire.receive();
intReceived[1] = received.asInt;
setBothMotors(received.asInt);
setMotorSpeed(R_MOTOR, intReceived[0]);
setMotorSpeed(L_MOTOR, intReceived[1]);
changed = 1;
break;
// next master request is for motor speeds
case(SPEED_REQUESTED):
changed = 1;
break;
// unknown message, just clear receive buffer
default:
for(int i = 0; i < byteCnt - 1; i++)
{
Wire.receive();
}
break;
}
}
//
// I2C slave request event handler
// registered in setup()
//
void requestEvent() {
byte msg4[4];
BYTE2INT toSend;
// info sent out depends on request mode set by
// last message received
switch(I2C_mode)
{
case SPEED_REQUESTED:
toSend.asInt = motor_speed[R_MOTOR];
msg4[0] = toSend.asBytes[0];
msg4[1] = toSend.asBytes[1];
toSend.asInt = motor_speed[L_MOTOR];
msg4[2] = toSend.asBytes[0];
msg4[3] = toSend.asBytes[1];
// begin and end transmission not required
// for slave response.
Wire.send(msg4, 4);
break;
default:
toSend.asInt = 32767;
msg4[0] = toSend.asBytes[0];
msg4[1] = toSend.asBytes[1];
msg4[2] = toSend.asBytes[0];
msg4[3] = toSend.asBytes[1];
// begin and end transmission not required
// for slave response.
Wire.send(msg4, 4);
break;
}
}