It’s been a slow day so I’ve been playing with the code I sent you yesterday. Here’s a modified version.
#define STOP 0
#define CCW 1
#define CW 2
#define N_MOTORS 2
// there are the values sent by the PC
#define MOTOR_A_STOP '1'
#define MOTOR_A_CW '2'
#define MOTOR_A_CCW '3'
#define MOTOR_B_STOP '4'
#define MOTOR_B_CW '5'
#define MOTOR_B_CCW '6'
char *action_strings [] = {"STOP", "CCW", "CW"};
char *command_strings [] = {
"MOTOR_A_STOP", "MOTOR_A_CW", "MOTOR_A_CCW", "MOTOR_B_STOP", "MOTOR_B_CW", "MOTOR_B_CCW"};
void ControlMotor (byte motor, byte action);
struct motor {
long count;
byte pin1;
byte pin2;
byte action;
} ;
struct motor motors[2];
void scanCounters (void) {
// this gets called every 100mS
// it decrements the motor's counter and if it reaches -1 it will call
// ControlMotor with the motor's number and action (which at present is fixed at STOP)
for (int i = 0; i < N_MOTORS; i++) {
if (motors[i].count != -1) {
motors[i].count--;
if (motors[i].count == -1)
// when counter times out we call
// ControlMotor() with whatever action
// is in the motor's struct
ControlMotor (i, motors[i].action);
}
}
}
void ControlMotor (byte motor, byte action) {
if (motor < 2 && action <= CW) {
Serial.print ("Motor :");
Serial.print (motor, HEX);
Serial.print (" Action:");
Serial.println (action_strings [action]);
}
switch (motor) {
case 0:
switch (action) {
case STOP:
digitalWrite (motors[0].pin1, LOW);
digitalWrite (motors[0].pin2, LOW);
break;
case CW:
digitalWrite (motors[0].pin2, LOW);
digitalWrite (motors[0].pin1, HIGH);
break;
case CCW:
digitalWrite (motors[0].pin1, LOW); // note we turn OFF before ON
digitalWrite (motors[0].pin2, HIGH);
break;
default:
digitalWrite (motors[0].pin1, LOW); // stop motor if bad value
digitalWrite (motors[0].pin2, LOW);
}
break;
case 1:
switch (action) {
case STOP:
digitalWrite (motors[1].pin1, LOW);
digitalWrite (motors[1].pin2, LOW);
break;
case CW:
digitalWrite (motors[1].pin2, LOW);
digitalWrite (motors[1].pin1, HIGH);
break;
case CCW:
digitalWrite (motors[1].pin1, LOW);
digitalWrite (motors[1].pin2, HIGH);
break;
default:
digitalWrite (motors[1].pin1, LOW);
digitalWrite (motors[1].pin2, LOW); }
break;
}
}
void setup () {
// map logical motor pins to physical pins
motors[0].pin1 = 14; // use your pin numbers here
motors[0].pin2 = 15;
motors[1].pin1 = 16;
motors[1].pin2 = 17;
Serial.begin (115200);
Serial.println ("\n\nEnter numbers 1-6");
// init counters and IO pins
for (int i = 0; i < N_MOTORS; i++) {
motors[i].count = -1;
motors[i].action = STOP;
pinMode(motors[i].pin1, OUTPUT);
pinMode(motors[i].pin2, OUTPUT);
digitalWrite(motors[i].pin1, LOW);
digitalWrite(motors[i].pin2, LOW);
}
}
void loop () {
if ((millis() % 100) == 0) scanCounters(); // scan counters 10x a second (100mS)
// potentially will skip a beat every now and then
delay (1); // so we don't do scanCounters() multiple times within the same mS
if (Serial.available () > 0) {
byte command = Serial.read ();
if (command >= MOTOR_A_STOP && command <= MOTOR_B_CCW) {
Serial.print ("\nCommand=");
Serial.println (command_strings[command - '1']);
}
switch (command) {
case MOTOR_A_STOP:
motors[0].count = -1;
ControlMotor (0, STOP);
break;
case MOTOR_A_CW:
motors[0].count = 200; // 200 * 100mS = 20 secs
ControlMotor (0, CW);
break;
case MOTOR_A_CCW:
motors[0].count = 200;
ControlMotor (0, CCW);
break;
case MOTOR_B_STOP:
motors[1].count = -1;
ControlMotor (1, STOP);
break;
case MOTOR_B_CW:
motors[1].count = 100;
ControlMotor (1, CW);
break;
case MOTOR_B_CCW:
motors[1].count = 100;
ControlMotor (1, CCW);
break;
default:
ControlMotor (0, STOP);
ControlMotor (1, STOP);
Serial.println ("Bad command from PC");
}
}
}
I’ve tested it on my clone with four LEDs and it works as follows.
Enter number from 1-6 to stop motors A and B or turn them CW or CCW.
MOTOR_A_STOP ‘1’
MOTOR_A_CW ‘2’
MOTOR_A_CCW ‘3’
MOTOR_B_STOP ‘4’
MOTOR_B_CW ‘5’
MOTOR_B_CCW ‘6’
I’ve set the times for A at 20s and B at 10s.
Once started a motor will run for it’s alloted time then turn off.
So if you say press 2 (A turn CW) follwed immediately by 6 (B turn CCW) 10 seconds later you will see a message saying that B has stopped and after a further 10 seconds another message saying that A has stopped.
This isn’t all you wanted I think but it must be getting close enough for you to play with and is better than looking at a blank screen.
Rob