Im using the stepperdriver library and its for a gauge for a flight sim. because of gears and stuff the airspeed it gets in doesnt correspond to the gauge. Im trying to multiply the airspeed by 3.3 however it only seems to multiply by 3. It also doesnt seem to change if i change the decimal point? any ideas?
{
airspeed = "";
airspeed += getChar();
airspeed += getChar();
airspeed += getChar();
a = airspeed.toFloat();
a2 = a * 3.3;
if (a2 != oldas)
{
b = oldas - a2;
stepper.rotate(b);
oldas = a2;
}
here is the entire code airspeed is a string that's converted to a float.
#include <Arduino.h>
// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step
#define MOTOR_STEPS 12.5
// Target RPM for cruise speed
#define RPM 100
// Acceleration and deceleration values are always in FULL steps / s^2
#define MOTOR_ACCEL 50
#define MOTOR_DECEL 50
// Microstepping mode. If you hardwired it to save pins, set to the same value here.
#define MICROSTEPS 16
#define DIR 2
#define STEP 3
#define ENABLE 13 // optional (just delete ENABLE from everywhere if not used)
#include "A4988.h"
#define MS1 10
#define MS2 11
#define MS3 12
A4988 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, MS1, MS2, MS3);
int CodeIn;// used on all serial reads
int KpinNo;
int Koutpin;
String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
String gearSimple;
float a = 0;
float a2;
String airspeed;
float oldas = 0;
int b;
void setup()
{
Kstringoldstate = "111111111111111111111111111111111111111111111111111111111111111111111";
for (int KoutPin = 8; KoutPin < 70; KoutPin++)// Get all the pins ready for simconnect codes and "Keys"(all inputs)
{
pinMode(KoutPin, INPUT);
digitalWrite(KoutPin, HIGH);
}
Serial.begin(115200);
stepper.begin(RPM, MICROSTEPS);
stepper.enable();
stepper.setSpeedProfile(stepper.LINEAR_SPEED, MOTOR_ACCEL, MOTOR_DECEL);
}
void loop() {
{INPUTS();} //Check the Simconnect and "keys" section for any input pins
{OTHER();}// Check for "Other" things to do. (Non extraction stuff)
if (Serial.available()) {
CodeIn = getChar();
if (CodeIn == '=') {EQUALS();} // The first identifier is "="
if (CodeIn == '<') {LESSTHAN();}// The first identifier is "<"
if (CodeIn == '?') {QUESTION();}// The first identifier is "?"
if (CodeIn == '/') {SLASH();}// The first identifier is "/" (Annunciators)
}
} // end of void loop (The main one)
char getChar()// Get a character from the serial buffer
{
while(Serial.available() == 0);// wait for data
return((char)Serial.read());// Thanks Doug
}// end of getchar void.
void OTHER(){
/* In here you would put code that uses other data that
cant be put into an "extraction void" that references something else.
Also in here you would put code to do something that was not
relying on a current extraction trigger.
Or ,, you could just put it all in the main "void loop" and not worry about this "other void" at all.
*/
}// end of "other" void
void EQUALS(){ // The first identifier was "="
CodeIn = getChar(); // Get the second identifier
switch(CodeIn) {// Now lets find what to do with it
case 'B':
//Do something
break;
//etc etc etc
}
}// end of equals loop
void LESSTHAN(){ // The first identifier was "<"
CodeIn = getChar(); // Get the second identifier
switch(CodeIn) {// Now lets find what to do with it
case 'P'://The second identifier was an "A"
{
airspeed = "";
airspeed += getChar();
airspeed += getChar();
airspeed += getChar();
a = airspeed.toFloat();
a2 = a * 3.9;
if (a2 != oldas)
{
b = oldas - a2;
stepper.rotate(b);
oldas = a2;
}
}
break;
case 'A'://The second identifier was an "A"
{
}
break;
case 'B':
//Do something
break;
//etc etc etc
}
}// end of lessthan void
void QUESTION(){ // The first identifier was "?"
CodeIn = getChar(); // Get the second identifier
switch(CodeIn) {// Now lets find what to do with it
case 'A'://The second identifier was an "A"
//Do something
break;
case 'B':
//Do something
break;
case 'Y': // found the second identifier (the "Gear simple")
break;
//etc etc etc
}
}// end of question void
void SLASH(){ // The first identifier was "/" (Annunciator)
//Do something (See the other voids for layout)
} // end of slash void
void INPUTS() // Simconnect codes and "Keys" section
{
Kstringnewstate = "";
for (int KpinNo = 8; KpinNo < 70; KpinNo++){ //set to the input pins. (pins 8 to 70 ,, change the 70 to 19 for Uno cards)
KpinStateSTR = String(digitalRead(KpinNo));
KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 8));// set to the first pin read (The 8)
if (KpinStateSTR != KoldpinStateSTR)// checks if it's different to the last reading of that pinNo
{
if (KpinNo != 13){ // avoid using pin 13 as an input unless you know the tricks.
if (KpinNo == 8 && KpinStateSTR == "0"){Serial.println ("C01");} //sets gear handle up
if (KpinNo == 9 && KpinStateSTR == "0"){Serial.println ("C02");} //sets gear handle down
if (KpinNo == 10 && KpinStateSTR == "0"){Serial.println ("C15");} //Decrements flap handle position
if (KpinNo == 11 && KpinStateSTR == "0"){Serial.println ("C14");} //Increments flap handle position
if (KpinNo == 12 && KpinStateSTR == "0"){Serial.println ("A02");} //Increments COM1sb by one MHz
if (KpinNo == 14 && KpinStateSTR == "0"){Serial.println ("A01");} //Decrements COM1sb by one MHz
if (KpinNo == 15 && KpinStateSTR == "0"){Serial.println ("A426543");} //Sets transponder code to 6543
// Add more here but remember to change the figure in the next line down. (the 15)
if (KpinNo > 15){ //Change pinNo number to same as the highest one used for simconnect codes.(the 15)
Serial.print ("D");
if (KpinNo < 10) Serial.print ("0");
Serial.print (KpinNo);
Serial.println (KpinStateSTR);
}//end of 'its pinNo is greater than 12'
}//end of 'its not pin 13'
}//end of 'its different'
Kstringnewstate += KpinStateSTR;
}//end of 'for' loop (read the pins)
Kstringoldstate = Kstringnewstate;
}//end of INPUTS void
You are using an awful amount of "String" instances in your code. "String" is known to cause problems due to memory fragmentation, so you should start by removing those from your code. Also, you are adding useless {} braces, eg:
{INPUTS();} //{ and } are useless here.
INPUTS(); //This is enough.
The only string that could be causing these problems is the airspeed string because it reads it in from the serial buffer then converts it to a float or int ( it would be like 220) .
georgegohl888:
The only string that could be causing these problems is the airspeed string because it reads it in from the serial buffer then converts it to a float or int ( it would be like 220) .
You are so wrong.. "INPUTS()" is merrily using instances of "String" in an unfortunate manner. Just get rid of the "String" class - even if it is not the cause of your apparent problem, it will become the cause of another.
EDIT: If you know for sure, that "airspeed" will always be 3 chars long, why not use this:
char airspeed[4];
for (byte i = 0; i < 3; i++) airspeed[i] = getChar();
airspeed[3] = 0; //NULL terminate
a = atof(airspeed); //Ascii TO Float
Im using example code and thats part of the example code and i've used it before and never encountered any problems... I dont fancy changing it if it works.
georgegohl888:
Im using example code and thats part of the example code and i've used it before and never encountered any problems... I dont fancy changing it if it works.
Your other "self" seems to want help in changing it.
Thanks for the help. Ive added your suggestions and taken out some of the braces but the original problem still stands. multiplying by 4 give a movement on the stepper that is too large but any value between 3.0 and 3.9 yields the same result? any ideas? thanks
#include <Arduino.h>
// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step
#define MOTOR_STEPS 12.5
// Target RPM for cruise speed
#define RPM 100
// Acceleration and deceleration values are always in FULL steps / s^2
#define MOTOR_ACCEL 50
#define MOTOR_DECEL 50
// Microstepping mode. If you hardwired it to save pins, set to the same value here.
#define MICROSTEPS 16
#define DIR 2
#define STEP 3
#define ENABLE 13 // optional (just delete ENABLE from everywhere if not used)
#include "A4988.h"
#define MS1 10
#define MS2 11
#define MS3 12
A4988 stepper(MOTOR_STEPS, DIR, STEP, ENABLE, MS1, MS2, MS3);
int CodeIn;// used on all serial reads
int KpinNo;
int Koutpin;
String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
float a = 0;
float a2;
//String airspeed;
float oldas = 0;
float b;
void setup()
{
Kstringoldstate = "111111111111111111111111111111111111111111111111111111111111111111111";
for (int KoutPin = 8; KoutPin < 70; KoutPin++)// Get all the pins ready for simconnect codes and "Keys"(all inputs)
{
pinMode(KoutPin, INPUT);
digitalWrite(KoutPin, HIGH);
}
Serial.begin(115200);
stepper.begin(RPM, MICROSTEPS);
stepper.enable();
stepper.setSpeedProfile(stepper.LINEAR_SPEED, MOTOR_ACCEL, MOTOR_DECEL);
}
void loop() {
INPUTS(); //Check the Simconnect and "keys" section for any input pins
OTHER();// Check for "Other" things to do. (Non extraction stuff)
if (Serial.available()) {
CodeIn = getChar();
if (CodeIn == '=') {EQUALS();} // The first identifier is "="
if (CodeIn == '<') {LESSTHAN();}// The first identifier is "<"
if (CodeIn == '?') {QUESTION();}// The first identifier is "?"
if (CodeIn == '/') {SLASH();}// The first identifier is "/" (Annunciators)
}
} // end of void loop (The main one)
char getChar()// Get a character from the serial buffer
{
while(Serial.available() == 0);// wait for data
return((char)Serial.read());// Thanks Doug
}// end of getchar void.
void OTHER(){
/* In here you would put code that uses other data that
cant be put into an "extraction void" that references something else.
Also in here you would put code to do something that was not
relying on a current extraction trigger.
Or ,, you could just put it all in the main "void loop" and not worry about this "other void" at all.
*/
}// end of "other" void
void EQUALS(){ // The first identifier was "="
CodeIn = getChar(); // Get the second identifier
switch(CodeIn) {// Now lets find what to do with it
case 'B':
//Do something
break;
//etc etc etc
}
}// end of equals loop
void LESSTHAN(){ // The first identifier was "<"
CodeIn = getChar(); // Get the second identifier
switch(CodeIn) {// Now lets find what to do with it
case 'P'://The second identifier was an "A"
{
char airspeed[4];
for (byte i = 0; i < 3; i++) airspeed[i] = getChar();
airspeed[3] = 0; //NULL terminate
a = atof(airspeed); //Ascii TO Float
a2 = a * 3.9;
if (a2 != oldas)
{
b = oldas - a2;
stepper.rotate(b);
oldas = a2;
}
}
break;
//etc etc etc
}
}// end of lessthan void
void QUESTION(){ // The first identifier was "?"
CodeIn = getChar(); // Get the second identifier
switch(CodeIn) {// Now lets find what to do with it
case 'A'://The second identifier was an "A"
break;
//etc etc etc
}
}// end of question void
void SLASH(){ // The first identifier was "/" (Annunciator)
//Do something (See the other voids for layout)
} // end of slash void
void INPUTS() // Simconnect codes and "Keys" section
{
Kstringnewstate = "";
for (int KpinNo = 8; KpinNo < 70; KpinNo++){ //set to the input pins. (pins 8 to 70 ,, change the 70 to 19 for Uno cards)
KpinStateSTR = String(digitalRead(KpinNo));
KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 8));// set to the first pin read (The 8)
if (KpinStateSTR != KoldpinStateSTR)// checks if it's different to the last reading of that pinNo
{
if (KpinNo != 13){ // avoid using pin 13 as an input unless you know the tricks.
if (KpinNo == 8 && KpinStateSTR == "0"){Serial.println ("C01");} //sets gear handle up
if (KpinNo == 9 && KpinStateSTR == "0"){Serial.println ("C02");} //sets gear handle down
if (KpinNo == 10 && KpinStateSTR == "0"){Serial.println ("C15");} //Decrements flap handle position
if (KpinNo == 11 && KpinStateSTR == "0"){Serial.println ("C14");} //Increments flap handle position
if (KpinNo == 12 && KpinStateSTR == "0"){Serial.println ("A02");} //Increments COM1sb by one MHz
if (KpinNo == 14 && KpinStateSTR == "0"){Serial.println ("A01");} //Decrements COM1sb by one MHz
if (KpinNo == 15 && KpinStateSTR == "0"){Serial.println ("A426543");} //Sets transponder code to 6543
// Add more here but remember to change the figure in the next line down. (the 15)
if (KpinNo > 15){ //Change pinNo number to same as the highest one used for simconnect codes.(the 15)
Serial.print ("D");
if (KpinNo < 10) Serial.print ("0");
Serial.print (KpinNo);
Serial.println (KpinStateSTR);
}//end of 'its pinNo is greater than 12'
}//end of 'its not pin 13'
}//end of 'its different'
Kstringnewstate += KpinStateSTR;
}//end of 'for' loop (read the pins)
Kstringoldstate = Kstringnewstate;
}//end of INPUTS void
If you want help with some coding you do not understand, please tell how we can guide you. If you want someone to fix your cut'n paste examples to do what you want, hire a programmer.
There is the base code that is used to interface with a program called link2fs. It can send airspeeds for example and split up to the different parts. Im trying to learn how to interface with the stepper using the stepperdriver library. The code i wrote sort of works as in the gauge rotates its just the calibration cant seem to work out. Thats where i need the help, Thank you
Try to print "airspeed" with serial and see what it gets, and get rid of all the "String" instances. When you are done and still have problems, post your updated code.
Converts a valid String to a float. The input String should start with a digit. If the String contains non-digit characters, the function will stop performing the conversion. For example, the Strings "123.45", "123", and "123fish" are converted to 123.45, 123.00, and 123.00 respectively. Note that "123.456" is approximated with 123.46. Note too that floats have only 6-7 decimal digits of precision and that longer Strings might be truncated.
This Arduino description of usage of String seems to be wrong , it contradicts itself.
Of course we all been told over and over that the issue is with using String, not the way Arduino code works.
I would make sure the characters you have collected are only numeric.
If you just print out the input airspeed and the intermediate variables a, a2, oldas and b immediately before the stepper.rotate you'll probably spot what's happening. Or post them here and maybe we will.
Your code is throwing away the fractional part of every step.
if (a2 != oldas)
{
b = oldas - a2; // If the result is below 1 this will truncate it to 0
stepper.rotate(b);
oldas = a2;
}
You should keep the fractional parts:
b = oldas - a2;
if (b != 0) // Any full steps to be done?
{
stepper.rotate(b);
oldas += b; // Keep track of the fractional part not included in this movement.
}