Hi everyone! I just found this forum, I've been using Teensy's and Arduino now for a few months and it's SO MUCH FUN! So thank you for creating them. I'm still very much learning, and the project I'm attempting is a bit in at the deep end... I'm creating a new instrument cluster for a car I'm building. It features two Teensy 3.2s and one Teensy 3.5 performing a number of functions such as running an 128x32 OLED display, 4 BKA30lF1 instrument stepper motors via a VID 6606 driver chip, CAN bus interface and running various dashboard led indicators.
I designed a number of PCBs to make up the unit and have had a set of prototypes made which I'm currently testing. Most things work really well which I'm super pleased about, but a couple of bits aren't quite how I want them so I'm currently working up a change list to develop Rev 2 of the boards.
Today's issue is with Teensystepper. I actually prototyped the board with Accelstepper and it works great. Since getting the PCBs I have plugged everything in and it still works great, currently controlling via 4 potentiometers until I have time to build a square wave simulator for RPM & wheel speed. Presently I have the steppers running from a Teensy 3.2, with the inputs for the steppers also being processed by this board to maintain as high response and I can. Teensy A then serial transmits data across to Teensy 3.2 B, which runs the OLED, CAN Bus and some other bits and pieces. It works pretty well but I'm finding that with 4 steppers running and the serial send, the performance of the steppers is getting degraded to the point where the RPM pointer probably isn't quite fast enough.
Enter Teensystepper. I have heard it is a little quicker than Accelstepper so I thought I'd give it a go as I only need a small amount of improvement from where I am now. I tried starting with a very simple example code to get one stepper running, and so far no response from the stepper at all. I know it works from Accelstepper so there must be something obvious that I've not considered - can anyone help me see what it is? Also if you have any great suggestions for improving the performance then I'd be all ears! Thank you!
Here is a video of it running (I have now fixed the OLED refresh rate!) https://www.instagram.com/p/B70bz6cFKO5/?utm_source=ig_web_copy_link
Old code (excuse the clunky code for the potentiometers to test, this will be replaced by some neater code to count pulses on two pins based on this: https://forum.pjrc.com/threads/48101-PMT-pulse-counting-using-Teensy-3-2 then I'll pull the fuel level and water temperature across serial from the other Teensy's CAN interface)
Code I'm trying to test (I tried LOW and HIGH pin polarity but no response to either):
I designed a number of PCBs to make up the unit and have had a set of prototypes made which I'm currently testing. Most things work really well which I'm super pleased about, but a couple of bits aren't quite how I want them so I'm currently working up a change list to develop Rev 2 of the boards.
Today's issue is with Teensystepper. I actually prototyped the board with Accelstepper and it works great. Since getting the PCBs I have plugged everything in and it still works great, currently controlling via 4 potentiometers until I have time to build a square wave simulator for RPM & wheel speed. Presently I have the steppers running from a Teensy 3.2, with the inputs for the steppers also being processed by this board to maintain as high response and I can. Teensy A then serial transmits data across to Teensy 3.2 B, which runs the OLED, CAN Bus and some other bits and pieces. It works pretty well but I'm finding that with 4 steppers running and the serial send, the performance of the steppers is getting degraded to the point where the RPM pointer probably isn't quite fast enough.
Enter Teensystepper. I have heard it is a little quicker than Accelstepper so I thought I'd give it a go as I only need a small amount of improvement from where I am now. I tried starting with a very simple example code to get one stepper running, and so far no response from the stepper at all. I know it works from Accelstepper so there must be something obvious that I've not considered - can anyone help me see what it is? Also if you have any great suggestions for improving the performance then I'd be all ears! Thank you!
Here is a video of it running (I have now fixed the OLED refresh rate!) https://www.instagram.com/p/B70bz6cFKO5/?utm_source=ig_web_copy_link
Old code (excuse the clunky code for the potentiometers to test, this will be replaced by some neater code to count pulses on two pins based on this: https://forum.pjrc.com/threads/48101-PMT-pulse-counting-using-Teensy-3-2 then I'll pull the fuel level and water temperature across serial from the other Teensy's CAN interface)
Code:
#include <AccelStepper.h>
// Define some steppers and the pins the will use
AccelStepper SPEED_STEPPER(AccelStepper::DRIVER, 5, 6); //Step, Direction
AccelStepper RPM_STEPPER(AccelStepper::DRIVER, 7, 8); //Step, Direction
AccelStepper CT_STEPPER(AccelStepper::DRIVER, 11, 12); //Step, Direction
AccelStepper FL_STEPPER(AccelStepper::DRIVER, 9, 10); //Step, Direction
const int RESET = 18; // pin for RESET
const int numReadings = 50;
//Speed
int SPEED_Pin = 23;
int SPEED_Val = 0;
int SPEED_STEPS;
int SPEED_readings[numReadings]; // the readings from the analog input
int SPEED_readIndex = 0; // the index of the current reading
int SPEED_total = 0; // the running total
int SPEED_average = 0; // the average
int SPEED_MPH = 0;
int SPEED_SEND;
//RPM
int RPM_Pin = 22;
int RPM_Val;
int RPM_STEPS;
int RPM_readings[numReadings]; // the readings from the analog input
int RPM_readIndex = 0; // the index of the current reading
int RPM_total = 0; // the running total
int RPM_average = 0; // the average
long RPM = 0;
int RPM_SEND;
//Coolant_T
int CT_Pin = 21;
int CT_Val;
int CT_STEPS;
int CT_readings[numReadings]; // the readings from the analog input
int CT_readIndex = 0; // the index of the current reading
int CT_total = 0; // the running total
int CT_average = 0; // the average
int COOLANT_TEMP = 0;
int CT_SEND;
//Fuel_L
int FL_Pin = 20;
int FL_Val;
int FL_STEPS;
int FL_readings[numReadings]; // the readings from the analog input
int FL_readIndex = 0; // the index of the current reading
int FL_total = 0; // the running total
int FL_average = 0; // the average
int FUEL_LEVEL = 0;
int FL_SEND;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 10; //the value is a number of milliseconds
void setup()
{
Serial.begin(9600);
Serial1.begin(250000);
pinMode(RESET, OUTPUT);
digitalWrite(RESET, LOW);
delay(1); // keep reset low min 1ms
digitalWrite(RESET, HIGH);
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
SPEED_readings[thisReading] = 0;
RPM_readings[thisReading] = 0;
CT_readings[thisReading] = 0;
FL_readings[thisReading] = 0;
}
SPEED_STEPPER.setMaxSpeed(10000.0);
SPEED_STEPPER.setAcceleration(250000.0);
RPM_STEPPER.setMaxSpeed(10000.0);
RPM_STEPPER.setAcceleration(250000.0);
CT_STEPPER.setMaxSpeed(10000.0);
CT_STEPPER.setAcceleration(250000.0);
FL_STEPPER.setMaxSpeed(10000.0);
FL_STEPPER.setAcceleration(250000.0);
//SPEED_STEPPER.runToNewPosition(-1000);
SPEED_STEPPER.runToNewPosition(3000);
SPEED_STEPPER.runToNewPosition(0);
//RPM_STEPPER.runToNewPosition(1000);
RPM_STEPPER.runToNewPosition(-3000);
RPM_STEPPER.runToNewPosition(0);
//CT_STEPPER.runToNewPosition(-500);
CT_STEPPER.runToNewPosition(2216);
CT_STEPPER.runToNewPosition(0);
//FL_STEPPER.runToNewPosition(500);
FL_STEPPER.runToNewPosition(-2216);
FL_STEPPER.runToNewPosition(0);
startMillis = millis(); //initial start time
}
void loop() {
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
//if (currentMillis - startMillis >= (period*2)) //test whether the period has elapsed
//{
//=====SPEED CALC=============
// subtract the last reading:
SPEED_total = SPEED_total - SPEED_readings[SPEED_readIndex];
// read from the sensor:
SPEED_Val = map(analogRead(SPEED_Pin), 0, 1023, 0, 3189); //scal val2 (kph) to stepper motor positions
SPEED_readings[SPEED_readIndex] = SPEED_Val;
SPEED_total = SPEED_total + SPEED_readings[SPEED_readIndex];
SPEED_readIndex = SPEED_readIndex + 1;
if (SPEED_readIndex >= numReadings) {
SPEED_readIndex = 0;
}
// calculate the average:
SPEED_STEPS = SPEED_total / numReadings; //10*(((total / numReadings)+5)/10);
SPEED_MPH = SPEED_STEPS / 15.945;
//=====RPM CALC=============
// subtract the last reading:
RPM_total = RPM_total - RPM_readings[RPM_readIndex];
// read from the sensor:
RPM_Val = map(analogRead(RPM_Pin), 0, 1023, 0, -2835); //scal val2 (kph) to stepper motor positions
RPM_readings[RPM_readIndex] = RPM_Val;
RPM_total = RPM_total + RPM_readings[RPM_readIndex];
RPM_readIndex = RPM_readIndex + 1;
if (RPM_readIndex >= numReadings) {
RPM_readIndex = 0;
}
// calculate the average:
RPM_STEPS = RPM_total / numReadings; //10*(((total / numReadings)+5)/10);
RPM = RPM_STEPS / 0.4252;
//=====CT CALC=============
// subtract the last reading:
CT_total = CT_total - CT_readings[CT_readIndex];
// read from the sensor:
CT_Val = map(analogRead(CT_Pin), 0, 1023, 2216, 0); //range of 80 starting at 40
CT_readings[CT_readIndex] = CT_Val;
CT_total = CT_total + CT_readings[CT_readIndex];
CT_readIndex = CT_readIndex + 1;
if (CT_readIndex >= numReadings) {
CT_readIndex = 0;
}
// calculate the average:
CT_STEPS = CT_total / numReadings; //10*(((total / numReadings)+5)/10);
COOLANT_TEMP = CT_STEPS / 2.77;
//=====FL CALC=============
// subtract the last reading:
FL_total = FL_total - FL_readings[FL_readIndex];
// read from the sensor:
FL_Val = map(analogRead(FL_Pin), 0, 1023, -2216, 0); //scal val2 (kph) to stepper motor positions
FL_readings[FL_readIndex] = FL_Val;
FL_total = FL_total + FL_readings[FL_readIndex];
FL_readIndex = FL_readIndex + 1;
if (FL_readIndex >= numReadings) {
FL_readIndex = 0;
}
// calculate the average:
FL_STEPS = FL_total / numReadings; //10*(((total / numReadings)+5)/10);
FUEL_LEVEL = FL_STEPS / 3.887193;
//}
//=============================
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
Serial1.print('<');
if (SPEED_MPH != SPEED_SEND) {
SPEED_SEND = SPEED_MPH;
Serial1.print('S');
Serial1.print(SPEED_SEND);
Serial1.print('S');
}
if (RPM != RPM_SEND) {
RPM_SEND = RPM;
Serial1.print('R');
Serial1.print(-RPM_SEND);
Serial1.print('R');
}
if (COOLANT_TEMP != CT_SEND) {
CT_SEND = COOLANT_TEMP;
Serial1.print('T');
Serial1.print(CT_SEND);
Serial1.print('T');
}
if (FUEL_LEVEL != FL_SEND) {
FL_SEND = FUEL_LEVEL;
Serial1.print('F');
Serial1.print(-FL_SEND);
Serial1.print('F');
}
Serial1.print('>');
}
//=============================
SPEED_STEPPER.moveTo(SPEED_STEPS);
RPM_STEPPER.moveTo(RPM_STEPS);
CT_STEPPER.moveTo(CT_STEPS);
FL_STEPPER.moveTo(FL_STEPS);
SPEED_STEPPER.run();
RPM_STEPPER.run();
CT_STEPPER.run();
FL_STEPPER.run();
}
Code I'm trying to test (I tried LOW and HIGH pin polarity but no response to either):
Code:
#include "TeensyStep.h"
Stepper motor_1(5, 6); //STEP pin = 2, DIR pin = 3
Stepper motor_2(7,8); //STEP pin = 9, DIR pin = 10
Stepper motor_3(9,10); //STEP pin = 14, DIR pin = 15
StepControl controller;
void setup()
{
// setup the motors
motor_1
.setMaxSpeed(50000) // steps/s
.setAcceleration(200000); // steps/s^2
motor_2
.setMaxSpeed(50000) // steps/s
.setAcceleration(200000); // steps/s^2
motor_3
//.setPullInSpeed(300) // steps/s currently deactivated...
.setMaxSpeed(10000) // steps/s
.setAcceleration(50000) // steps/s^2
.setStepPinPolarity(LOW); // driver expects active low pulses
}
void loop()
{
constexpr int spr = 16*200; // 3200 steps per revolution
// lets shake
for(int i = 0; i < 5; i++)
{
motor_1.setTargetRel(spr/4); // 1/4 revolution
controller.move(motor_1);
motor_1.setTargetRel(-spr/4);
controller.move(motor_1);
}
delay(500);
// move motor_1 to absolute position (10 revolutions from zero)
// move motor_2 half a revolution forward
// both motors will arrive their target positions at the same time
motor_1.setTargetAbs(10*spr);
motor_2.setTargetRel(spr/2);
controller.move(motor_1, motor_2);
// now move motor_2 together with motor_3
motor_2.setTargetRel(300);
motor_3.setTargetRel(-800);
controller.move(motor_2, motor_3);
// move all motors back to their start positions
motor_1.setTargetAbs(0);
motor_2.setTargetAbs(0);
motor_3.setTargetAbs(0);
controller.move(motor_1, motor_2, motor_3);
delay(1000);
}