Hi. I have a small X27.168 stepper motor controlled with the SwitecX25.h library. I use it to control an RPM gauge from Euro Truck Simulator, using this function:
void function_rpm()
{
serial_byte = Serial.read();
rpm_pwm = map(serial_byte, 0, 250, 0, MAX_RPM);
rpm.setPosition(rpm_pwm);
rpm.update();
}
The problem is that although it is capable of moving at a very fast pace (it can go from 0 to 240 degrees in less than a second), because of the arduino refresh speed, it moves very slowly and kind of tripping. Adding a delay to that function messes with everything else. This is how it looks like:
In case you need it, this is the full code:
#include <LiquidCrystal_I2C.h>
#include <SwitecX25.h>
const int LEFT_INDICATOR = 32;
const int RIGHT_INDICATOR = 33;
const int PARKING_BREAK = A11;
const int FUEL_WARNING = A13;
const int LOW_BEAM = A12;
const int HIGH_BEAM = A10;
int serial_byte;
int fuel = 3;
int fuel_pwm;
int temp = 2;
int temp_pwm;
int speed_pwm;
int rpm_pwm;
int new_rpm;
int cruise_control;
int new_cruise_control;
String line1;
String line2;
String new_odometer;
bool enabled;
int MAX_SPEED = 720;
int MAX_RPM = 720;
#define STEPS (315*3)
SwitecX25 speedometer(STEPS,35,37,41,39);
SwitecX25 rpm(STEPS,34,36,40,38);
#define PACKET_SYNC 0xFF
#define PACKET_VER 2
LiquidCrystal_I2C lcd(0x27,20,4);
void setup()
{
Serial.begin(115200);
speedometer.zero();
rpm.zero();
lcd.init();
lcd.backlight();
lcd.print("Self Test");
// Initialise LEDs
pinMode(LEFT_INDICATOR, OUTPUT);
pinMode(RIGHT_INDICATOR, OUTPUT);
pinMode(PARKING_BREAK, OUTPUT);
pinMode(FUEL_WARNING, OUTPUT);
pinMode(LOW_BEAM, OUTPUT);
pinMode(HIGH_BEAM, OUTPUT);
pinMode(fuel, OUTPUT);
pinMode(temp, OUTPUT);
speedometer.setPosition(0);
rpm.setPosition(0);
digitalWrite(LEFT_INDICATOR, 0);
digitalWrite(RIGHT_INDICATOR, 0);
digitalWrite(PARKING_BREAK, 0);
digitalWrite(FUEL_WARNING, 0);
digitalWrite(LOW_BEAM, 0);
digitalWrite(HIGH_BEAM, 0);
analogWrite(fuel, 0);
analogWrite(temp, 0);
delay(500);
digitalWrite(LEFT_INDICATOR, 1);
digitalWrite(RIGHT_INDICATOR, 1);
digitalWrite(PARKING_BREAK, 1);
digitalWrite(FUEL_WARNING, 1);
digitalWrite(LOW_BEAM, 1);
digitalWrite(HIGH_BEAM, 1);
analogWrite(fuel, 224);
analogWrite(temp, 132);
delay(1000);
digitalWrite(LEFT_INDICATOR, 0);
digitalWrite(RIGHT_INDICATOR, 0);
digitalWrite(PARKING_BREAK, 0);
digitalWrite(FUEL_WARNING, 0);
digitalWrite(LOW_BEAM, 0);
digitalWrite(HIGH_BEAM, 0);
analogWrite(fuel, 0);
analogWrite(temp, 0);
lcd.clear();
lcd.print("Wait");
// Wait a second to ensure serial data isn't from re-programming
delay(1000);
lcd.clear();
lcd.print("Ready");
}
void function_speed()
{
serial_byte = Serial.read();
speed_pwm = map(serial_byte, 0, 120, 0, MAX_SPEED);
speedometer.setPosition(speed_pwm);
speedometer.update();
}
void function_rpm()
{
serial_byte = Serial.read();
rpm_pwm = map(serial_byte, 0, 250, 0, MAX_RPM);
rpm.setPosition(rpm_pwm);
rpm.update();
}
void skip_serial_byte()
{
(void)Serial.read();
}
void writeFuelValue(){
serial_byte = Serial.read();
fuel_pwm = map(serial_byte, 0, 100, 0, 224);
analogWrite(fuel, fuel_pwm);
}
void writeTempValue(){
serial_byte = Serial.read();
temp_pwm = map(serial_byte, 30, 120, 0, 132);
if(serial_byte < 30)
analogWrite(temp, 0);
else
analogWrite(temp, temp_pwm);
}
void digitalWriteFromBit(int port, int value, int shift)
{
digitalWrite(port, (value >> shift) & 0x01);
}
void loop()
{
if (Serial.available() < 16)
return;
serial_byte = Serial.read();
if (serial_byte != PACKET_SYNC)
return;
serial_byte = Serial.read();
if (serial_byte != PACKET_VER)
{
lcd.clear();
lcd.print("PROTOCOL VERSION ERROR");
return;
}
function_speed();
function_rpm();
skip_serial_byte(); // Brake air pressure
skip_serial_byte(); // Brake temperature
//skip_serial_byte(); // Fuel ratio
writeFuelValue();
skip_serial_byte(); // Oil pressure
skip_serial_byte(); // Oil temperature
//skip_serial_byte(); // Water temperature
writeTempValue();
skip_serial_byte(); // Battery voltage
new_cruise_control = Serial.read();
// Truck lights byte
serial_byte = Serial.read();
digitalWriteFromBit(LEFT_INDICATOR, serial_byte, 5);
digitalWriteFromBit(RIGHT_INDICATOR, serial_byte, 4);
if(enabled)
{
if(serial_byte >> 3 & 0x01) digitalWrite(LOW_BEAM, 1);
else digitalWrite(LOW_BEAM, 0);
if((serial_byte >> 3 & 0x01) && (serial_byte >> 2 & 0x01)){
digitalWrite(HIGH_BEAM, 1);
}
else digitalWrite(HIGH_BEAM, 0);
}
else
{
digitalWrite(LOW_BEAM, 0);
digitalWrite(HIGH_BEAM, 0);
}
// Warning lights bytes
serial_byte = Serial.read();
if(enabled)
{
if(serial_byte >> 7 & 0x01) digitalWrite(PARKING_BREAK, 1);
else digitalWrite(PARKING_BREAK, 0);
if(serial_byte >> 3 & 0x01) digitalWrite(FUEL_WARNING, 1);
else digitalWrite(FUEL_WARNING, 0);
}
else
{
digitalWrite(PARKING_BREAK, 0);
digitalWrite(FUEL_WARNING, 0);
}
// Enabled flags
serial_byte = Serial.read();
enabled = serial_byte >> 1 & 0x01;
// Text length
int text_len = Serial.read();
line2 = "ODO: ";
// Followed by text
if (0 < text_len && text_len < 127)
{
for (int i = 0; i < text_len; ++i)
{
while (Serial.available() == 0) // Wait for data if slow
{
delay(2);
}
serial_byte = Serial.read();
if (serial_byte < 0 && serial_byte > 127)
return;
line2.concat(char(serial_byte));
}
}
line2.concat(" KMS");
if((new_odometer != line2) || (new_cruise_control != cruise_control)){
new_odometer = line2;
cruise_control = new_cruise_control;
line1 = "CC: ";
line1 += cruise_control;
line1 += String(" KPH");
lcd.clear();
lcd.setCursor(0,0);
lcd.print(line1);
lcd.setCursor(0,1);
lcd.print(line2);
}
}