Hello Everyone and sorry for my late reply but I had some very busy days at work.
@StefanL38:
Sorry for giving you the impression of being lazy, it is actually the contrary, I simply tried to keep my posts as short as possible as I thought not many people would be willing to read an amazingly long post.
Thank you very much for your answer, I'll try to be more specific here.
@pcbbc:
You are right, I have forgotten to add a line of code to update t = millis();
Here is the correct bit of code:
void readbutton(){
runactual = digitalRead(runpin);
if (runpin){
if ((millis()-t) > debounce_delay){
if (runactual == LOW && runbefore == HIGH){
runmode = !runmode;
Serial.println(runmode);
runbefore = runactual;
}
else if (runactual == HIGH && runbefore == LOW){
runbefore = runactual;
Serial.println(runmode);
}
t = millis();
}
}
}
Going back to the main topic...
The aim of the project is to create an experimental rolling shutter for a camera.
I've 3D printed the whole case and various "blades" for the shutter. 180°, 90°, etc...
The diameter is around 20cm and they are connected with a bolt to the shaft of the motor.
They need to rotated at various speed (which I modify with a rotary encoder).
I've set up a test which measure the time for 100 rotations:
digitalWrite(M0, LOW); digitalWrite(M1, HIGH); digitalWrite(M2, LOW); // Set 1/4 Steps
stepper.setMaxSpeed(steppermaxspeed);
stepper.setAcceleration(stepperacceleration);
stepper.setCurrentPosition(0);
steppertestbegin = millis();
stepper.moveTo(80000); // 800 (single rotation in 1/4 Steps) * 100 Rotations
stepper.runToPosition();
steppertestend = millis();
testresult = (float)(steppertestend-steppertestbegin)/1000;
Serial.println("Speed Test");
Serial.print("Stepper Speed: "); Serial.println(steppermaxspeed);
Serial.print("Stepper Acceleration: "); Serial.println(stepperacceleration);
Serial.print("Time to complete 10 rotations: "); Serial.println(testresult);
Serial.print("Average time to complete 1 rotation: "); Serial.println(testresult/100);
The result seems to be okay to me:
11:21:02.735 -> Speed Test
11:21:02.735 -> Stepper Speed: 4000
11:21:02.768 -> Stepper Acceleration: 8000
11:21:02.768 -> Time to complete 10 rotations: 20.97
11:21:02.835 -> Average time to complete 1 rotation: 0.21
If the speed is 4000 steps per second and it takes 800 steps to make a turn it should make 5 revolution per second: it reports 0.21 sec per rotation which, considering the acceleration, should be good.
Here is the complete code for the moment:
MAIN
// LIBRARIES
#include <AccelStepper.h>
// METHODS DECLARATIONS
void readbutton();
void encoder();
// Stepper Variables
#define dirPin 8
#define stepPin 9
#define motorInterfaceType 1
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);
int steppermaxspeed = 4000;
int stepperacceleration = 8000;
byte M0 = 12;
byte M1 = 11;
byte M2 = 10;
long stepperspeed = 200;
byte singlestep = 4;
// STEPPER TEST VARIABLES
uint32_t steppertestbegin;
uint32_t steppertestend;
float testresult;
// RUN VARIABLE
const int runpin = 7;
byte runactual;
byte runbefore;
static boolean runmode = false;
//DEBOUNCING VARIABLES
uint32_t now = 0;
long debounce_delay = 200;
// -----------------------------------------------------------------------------
// RE Variables
byte pinClk [] = { 2,4 };
byte pinData [] = { 3,5 };
#define N_ENC sizeof(pinData) // determine # of encoders
// allocate state variables for each encoder (i.e. N_ENC)
int encState [N_ENC] = {};
int encInp [N_ENC] = {};
long encPos [N_ENC] = {};
long prevencPos [N_ENC] = {};
int res;
// -----------------------------------------------------------------------------
// A vald CW or CCW move returns 1, invalid returns 0.
int8_t read_rotary (
int & store,
int & prevNextCode,
byte data,
byte clk )
{
static int8_t rot_enc_table[] = {
0,1,1,0, 1,0,0,1,
1,0,0,1, 0,1,1,0 };
prevNextCode <<= 2;
prevNextCode |= data << 1;
prevNextCode |= clk;
prevNextCode &= 0x0F;
// If valid then store as 16 bit data.
if (rot_enc_table [prevNextCode] ) {
store <<= 4;
store |= prevNextCode;
store &= 0xFF;
if (store == 0x2b) {
return -1;
}
if (store == 0x17) {
return 1;
}
}
return 0; // invalid input
}
// -----------------------------------------------------------------------------
void setup() {
// -----------------------------------------------------------------------------
// RE Setup
for(int i = 0; i < N_ENC; i++){
char info [100];
sprintf(info, "Clk Input number %d: %d",i, pinClk[i]);
Serial.println(info);
sprintf(info, "Data Input number %d: %d",i, pinData[i]);
Serial.println(info);
}
for (int i=0; i < N_ENC; i++){
pinMode (pinData[i], INPUT_PULLUP);
pinMode (pinClk[i], INPUT_PULLUP);
}
// -----------------------------------------------------------------------------
Serial.begin(9600);
digitalWrite(M0, LOW); digitalWrite(M1, HIGH); digitalWrite(M2, LOW); // Set 1/4 Steps
stepper.setMaxSpeed(steppermaxspeed);
stepper.setAcceleration(stepperacceleration);
stepper.setCurrentPosition(0);
steppertestbegin = millis();
stepper.moveTo(80000); // 800 (single rotation in 1/4 Steps) * 100 Rotations
stepper.runToPosition();
steppertestend = millis();
testresult = (float)(steppertestend-steppertestbegin)/1000;
Serial.println("Speed Test");
Serial.print("Stepper Speed: "); Serial.println(steppermaxspeed);
Serial.print("Stepper Acceleration: "); Serial.println(stepperacceleration);
Serial.print("Time to complete 10 rotations: "); Serial.println(testresult);
Serial.print("Average time to complete 1 rotation: "); Serial.println(testresult/100);
// RUN
pinMode(runpin, INPUT_PULLUP);
runbefore = digitalRead(runpin);
}
void loop() {
readbutton();
while(runmode == true){
for (int i = 0; i < N_ENC; i++) {
encoder (i);
}
readbutton();
if(runmode == false) break;
stepper.setSpeed(stepperspeed);
stepper.runSpeed();
}
for (int i = 0; i < N_ENC; i++) {
encoder (i);
}
}
TAB 1
// -----------------------------------------------------------------------------
void readbutton(){
runactual = digitalRead(runpin);
if (runpin){
if ((millis()-now) > debounce_delay){
if (runactual == LOW && runbefore == HIGH){
runmode = !runmode;
Serial.println(runmode);
runbefore = runactual;
}
else if (runactual == HIGH && runbefore == LOW){
runbefore = runactual;
Serial.println(runmode);
}
now = millis();
}
}
}
// -----------------------------------------------------------------------------
void encoder (int idx ) {
res = read_rotary (encState [idx], encInp [idx],
digitalRead (pinData [idx]),
digitalRead (pinClk [idx]) );
encPos [idx] += res;
// -----------------------------------------------------------------------------
// ENCODER 1
if (res == -1 && idx == 0) {
stepper.setCurrentPosition(0);
stepper.moveTo(-singlestep);
stepper.runToPosition();
}
if (res == 1 && idx == 0) {
stepper.setCurrentPosition(0);
stepper.moveTo(singlestep);
stepper.runToPosition();
}
// -----------------------------------------------------------------------------
// ENCODER 2
if (res == -1 && idx == 1) {
stepperspeed = stepperspeed -100;
Serial.println(stepperspeed);
}
if (res == 1 && idx == 1) {
stepperspeed = stepperspeed +100;
Serial.println(stepperspeed);
}
// -----------------------------------------------------------------------------
if (res) {
char s [80];
sprintf (s, " %d: %02X %2d", idx, encState [idx], encPos [idx]);
Serial.println (s);
}
}
// -----------------------------------------------------------------------------