I know the MobaTools / MoTo Stepper library is s dynamic, so changes can be made on the fly, which is very cool, but in my scenario, I need to "queue up" instructions, so that multiple movement commands appear as one long movement.
For example, if I moved a clock hand from 6pm to 11pm and then sent another command to move the hand from 11pm to 9pm. My code would:
Pause between the commands, which I don't want (If I wait too long, between issuing commands)
OR
if I issued the second command, before the 1st command finished, it would cut short the first command. So the hand might move from 6 - 10pm and then start moving backwards, without reaching 11pm
Also, in an ideal world, it would be great if the RampLen (deceleration part) would only happen when the hand finishes moving.
For example, if the first command was to move the hand from 1 to 5 and the 2nd command was to move from 5 to 8. It would be great, if I could have the option to accelerate the hand when it starts moving (from 1) and then decelerate at 8, maintaining it's speed through the 5 O'clock position)
I am using the I2C bus to send messages to multiple (20+) slave devices at the same time, so will need to give this some serious thought. Currently, I wait X (currently 8) seconds before sending the next lot of commands. However, off the top of my head, these ideas may work:
Time the movements for each command and adjust the value of X to get the wait as close to zero as possible. - Simple to implement but does not address the 'middle' ramplen issue.
I presume it's not possible to use a command that allows me to set different ramplen values in one command. For example. Ramplen 300, 0 (short ramp to start and no ramp to stop) or RampLen 0,300 (no ramp to start and short deceleration)
Thanks again, for the prompt responses and excellent suggestions. I'll keep thinking!
Been trying without success to get this (capturing when all clock hands have finished moving, following an I2C command to move them) . Here's where I'm at:
Slave/ Clock I2C addresses start from 0 - 23 (24 clocks in total)
The Master NodeMCU does not have an I2C address
Each I2C address/device has two motors (dual shafted stepper BKA30d-R5) and I have created two objects MOT_0 and MOT_1 for each motor (on the slave code)
I need to add some Master I2C code, so that I can tell when all of the 'clock hands' have finished moving using the .moving() command, so I can send the next queued I2C command without too much of a delay between commands.
If I send the commands too early, the hands go out of sync. If I send them too late, then there is an unnecessary pause between movements.
This is the closest I got as far as writing code but verify is throwing up lots of errors (see below) Any advice or an easier approach to doing this would be much appreciated, as I'm really stuck!
Thanks so much
TK
#include <Wire.h>
#include <MobaTools.h>
#define NUM_ADDRESSES 24 // Number of I2C addresses (48 motors / 2 motors per address)
// Define I2C pins for NodeMCU
#define SDA_PIN D2
#define SCL_PIN D1
// Create motor objects for two motors per address
MoToStepper motorA[NUM_ADDRESSES];
MoToStepper motorB[NUM_ADDRESSES];
void setup() {
Serial.begin(9600); // Initialize serial communication for debugging
Wire.begin(SDA_PIN, SCL_PIN); // Initialize I2C communication with specified pins
// Initialize all motors
for (int address = 0; address < NUM_ADDRESSES; address++) {
motorA[address].attach(address, 0); // Initialize motor 0 (MOT_0) at address 'address'
motorB[address].attach(address, 1); // Initialize motor 1 (MOT_1) at address 'address'
}
Serial.println("Motors initialized.");
}
void loop() {
// Check if all motors have stopped moving
if (allMotorsStopped()) {
Serial.println("All motors have stopped moving.");
delay(1000); // Temporary / example delay
}
}
}
bool allMotorsStopped() {
for (int address = 0; address < NUM_ADDRESSES; address++) {
if (motorA[address].moving() || motorB[address].moving()) {
return false; // If any motor 0 or 1 at this address is moving, return false
}
}
return true; // All motors have stopped moving
}
Unfortunately, I don't think this is going to work for me. The reason is that in order for the slave to talk to the master we need to use this command Wire.onRequest(requestEvent);
as this is the only command that passes 'data' from the Slave device to the Master device. Remember I need a 0 (motors not moving) or 1 motors moving from each slave clock. However, as the slave clocks also receive data from the master clocks they need to use this command Wire.onReceive(receiveEvent);
Sadly, for reasons I do not understand, using the wire.onrequest command, stops the wire.onreceive from working properly.
Shame as I was so close .. Oh well, back to the drawing board!