Fiddling with a now running code Serial.parseFloat is used.
It works perfectly until too many decimals are given. Sending 65.1111111 works fine but sending 65.11111111 gives me 0.00 reading it. Seven decimal ones works but eight decimal ones goes banana. I miss something.
The call is made at line 102. //line numbers don't copy?
For fun, take a look at the home mad "ParseLong" function.
#include<arduino.h>
//I2C for LCD
#include <AccelStepper.h>
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
hd44780_I2Cexp mylcd; // declare lcd object: auto locate & config exapander chip
AccelStepper myStepper (1, 6, 7);
// LCD geometry
#define LCD_COLS 16
#define LCD_ROWS 2
enum mode {Sides, Angle };
mode Mode; //Angle or Step mode
unsigned long nrOfFaces = 4;//Will be prompted in Setup
float stepAngle = 90.0;// will be set when angles selected
unsigned long nrOfStepsPerRev = 200L * 32L * 90L; // microstep 16
unsigned long currentStep;
unsigned long anglePos;
float accFloatAngle;//for display only
enum cmd {increase, decrease, Go, ChgMode, GoStep, nobutton};
void setup() {
char inChar;
Serial.begin(115200);
Serial.println("Rotation ");
pinMode(13, OUTPUT); digitalWrite(13, LOW);// Make board LED go off
myStepper.setMaxSpeed(4000);
myStepper.setAcceleration(30000);
#define digitalIncreaseButton 2
pinMode (digitalIncreaseButton, INPUT_PULLUP);
#define cuttingSpeed 100 // when cutting during rotation
#define movingSpeed 500 //when moving without cutting
int status;
status = mylcd.begin(LCD_COLS, LCD_ROWS);
if (status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// begin() failed so blink error code using the onboard LED if possible
hd44780::fatalError(status); // does not return
}
mylcd.clear();
mylcd.print("230228a Rotating");
mylcd.setCursor(0 , 1);
mylcd.print("Step Angle Chang");
Serial.println("230228a Rotating. S: Steps, A:Angle");
while (!Serial.available()) {}; //Wait for Serial input
inChar = Serial.read();//Read type of mode, Sides or Angle
if (inChar == 's')inChar = 'S';// DOESN*T work
if (inChar == 'S')//ORIGINAL S works
{
Serial.println("Step mode selected");
mylcd.clear();//command sent, here we go.
mylcd.setCursor(0 , 0);
mylcd.print("Step Mode ");
mylcd.setCursor(10 , 0);
Mode = Sides;
while (!Serial.available()) {}; //Wait for Serial input
nrOfFaces = ParseLong();
if (nrOfFaces > nrOfStepsPerRev)nrOfFaces = nrOfStepsPerRev;//Not above max
// nrOfFaces = Serial.parseInt();
Serial.print("Sides/Faces = "); Serial.println(nrOfFaces);
mylcd.print(nrOfFaces);//Nr of steps per rev on upper line
mylcd.setCursor(0 , 1);
mylcd.print("Step ");
mylcd.setCursor(5 , 1);
mylcd.print(nrOfFaces);
}
if (inChar == 'a')inChar = 'A';
if (inChar == 'A')
{
Serial.println("Angle mode selected");
mylcd.clear();//command sent, here we go.
mylcd.setCursor(0 , 0);
mylcd.print("Angle Mode ");
Mode = Angle;
while (!Serial.available()) {}; //Wait for Serial input
stepAngle = Serial.parseFloat();
if (stepAngle < 0) stepAngle = 0;
Serial.print("Angle step = "); Serial.println(stepAngle);
mylcd.setCursor(0 , 1);
mylcd.print("Angle ");
mylcd.setCursor(6 , 1);
mylcd.print(stepAngle);
}
myStepper.setCurrentPosition(0);//Accelstepper ready for a second turn around
anglePos = 0;
currentStep = 0;
Serial.println("S for stepping, both step/faces and angle");
// delay(5000);
}
enum cmd readButtons(void)
{
char cmd = 'q';
if (digitalRead(digitalIncreaseButton) == 0)
{
Serial.println("Button step received");
Serial.println();
delay(300); //debouncing
Serial.print("Recieved b cmd "); Serial.println(cmd);
return (GoStep);
}// increase);
if (Serial.available() > 0)
{
cmd = Serial.read();
}
if (cmd == 's' )
{
Serial.print("Recieved s cmd "); Serial.println(cmd);
return (GoStep);
}
if (cmd == 'S' ) {
Serial.print("Recieved S cmd "); Serial.println(cmd);
return (GoStep);
}
if (cmd == 'c' )
{
Serial.print("Recieved c cmd "); Serial.println(cmd);
return (ChgMode);
}
if (cmd == 'C' ) {
Serial.print("Recieved C cmd "); Serial.println(cmd);
return (ChgMode);
}
return (nobutton);
}
unsigned long ParseLong(void)
{
boolean goFlag = true;//read, decode and add digits
char tmpChar;
unsigned long longSum = 0;
while (!Serial.available()) {};
while ( Serial.available() && goFlag )
{
tmpChar = Serial.read();
if (isDigit(tmpChar)) // a numerical character recieved?
{
longSum *= 10l;// x 10
Serial.print( "Tmp char conversion "); Serial.println(tmpChar - '0');
longSum += tmpChar - '0';// + new digit
Serial.print( "longSum = "); Serial.println(longSum);
}
else
goFlag = false; //none digit entry
// Serial.print( "ParseLong = "); Serial.println(longSum);
}
return (longSum);
}
boolean guardCheck(void)
{
/* commented out until hardware is designed
if (!digitalRead(guard1) && !digitalRead(guard2))
return (true);//Unlocked, clear to go
else
return false;//Locked, don't go
*/
return (true);
}
void loop()
{
unsigned long lastMillis;
// unsigned long anglePos;
enum cmd lcmd;
// enum mode lmode;
// float accFloatAngle;//for display only
float tmpfloat;
char dummyChar;
lcmd = readButtons();// Read button inputs/ Serial, if any + - Go Chg mode
//while (Serial.available() > 0) dummyChar = Serial.read(); // Multiple cmd flushed.
if ( millis() - lastMillis > 200 )
{
lastMillis = millis();
if ( Mode == Sides ) //number of surnrOfFaces
{
switch (lcmd)
{
case increase:
{
nrOfFaces++;
break;
}
case decrease:
{
nrOfFaces--;
if (nrOfFaces < 2)
{
nrOfFaces = 1; //1 rotate one turn
// myStepper.setMaxSpeed(cuttingSpeed);
}
else
// myStepper.setMaxSpeed(movingSpeed);
break;
}
case ChgMode:
{
myStepper.setCurrentPosition(0);//Accelstepper ready for a second turn around
anglePos = 0;
currentStep = 0;
accFloatAngle = 0;
setup();// Ask for new mode
break;
}
case Go:
{
while (!guardCheck());;//DON*T GO IF LOCKS ARE ON
anglePos += nrOfStepsPerRev / nrOfFaces;
// myStepper.runToNewPosition();//Blocking until done
break;
}
case GoStep:
{
Serial.println("GoStep S received. ");
while (!guardCheck());;//DON*T GO IF LOCKS ARE ON
mylcd.setCursor(0 , 1);
mylcd.print(" ");
mylcd.setCursor(0 , 1);//Ready for start step
mylcd.print(currentStep);
mylcd.print(" > ");
Serial.print("From face "); Serial.print(currentStep);
Serial.print(" steps "); Serial.print( anglePos);
tmpfloat = (360.00 * currentStep) / nrOfFaces;
Serial.print(" angle = "); Serial.print( tmpfloat );
anglePos = (nrOfStepsPerRev * ++currentStep) / nrOfFaces;
currentStep %= nrOfFaces;
Serial.print(" To face "); Serial.print(currentStep);
Serial.print(" steps "); Serial.print( anglePos);
tmpfloat = 360.0 * float(currentStep) / float(nrOfFaces);
Serial.print(" angle = "); Serial.println( tmpfloat);
mylcd.print(currentStep);
lastMillis = millis();
myStepper.runToNewPosition(anglePos);//Blocking until done
Serial.print("Runtime "); Serial.println( millis() - lastMillis);
Serial.println("Ready."); Serial.println();
if (currentStep == 0)// Back on zero position, update AccelStepper position!!!
myStepper.setCurrentPosition(0);//Accelstepper ready for a second turn around
break;
}
default:
break;
}//end of switch
}//end of "if (lmode == Sides)"
else if ( Mode == Angle ) // Angle per step
{
switch (lcmd)
{
case increase:
{
anglePos = nrOfStepsPerRev * ++currentStep / nrOfFaces;
break;
}
case decrease:
{
anglePos = nrOfStepsPerRev * ++currentStep / nrOfFaces;
if (nrOfFaces < 1) nrOfFaces = 1; //1 rotate one turn
break;
}
case ChgMode:
{
myStepper.setCurrentPosition(0);//Accelstepper ready for a second turn around
anglePos = 0;
currentStep = 0;
accFloatAngle = 0;
setup();// Ask for new mode
break;
}
case GoStep:
{
while (!guardCheck());;//DON*T GO IF LOCKS ARE ON
if (accFloatAngle >= 360.0)accFloatAngle -= 360.0;
if (anglePos >= nrOfStepsPerRev)anglePos -= nrOfStepsPerRev;
Serial.print("From steps "); Serial.print( anglePos);
Serial.print(" angle "); Serial.print( accFloatAngle );
mylcd.setCursor(0 , 1);
mylcd.print(" ");
mylcd.setCursor(0 , 1);//Ready for start step
mylcd.print(accFloatAngle);//current F-angle
mylcd.print(" > ");
accFloatAngle += stepAngle; // Float angle to go to.
anglePos = accFloatAngle * nrOfStepsPerRev / 360.0 ; // Angle in steps
if (accFloatAngle >= 360.0)mylcd.print(accFloatAngle - 360.0);
else mylcd.print(accFloatAngle);
Serial.print(" To step ");
Serial.print( anglePos);
Serial.print(" angle "); Serial.println(accFloatAngle);
Serial.print("anglePos sent to accelstepper: "); Serial.println(anglePos);
lastMillis = millis();
myStepper.runToNewPosition(anglePos);//Blocking until done
Serial.print("Runtime "); Serial.println( millis() - lastMillis);
if (anglePos >= nrOfStepsPerRev )
{
myStepper.setCurrentPosition(anglePos - nrOfStepsPerRev);//Accelstepper ready for a second turn around
Serial.print("setCurrentPosition to "); Serial.println(anglePos - nrOfStepsPerRev);
}
anglePos = accFloatAngle * nrOfStepsPerRev / 360.0 ; // in steps
}
default:
break;
}
}
}
// if (guardCheck())
// {
// Serial.print("!");
//myStepper.run();
// }
}// End of loop
/*
moveTo KEYWORD2
move KEYWORD2
run KEYWORD2
runSpeed KEYWORD2
setMaxSpeed KEYWORD2
setAcceleration KEYWORD2
setSpeed KEYWORD2
speed KEYWORD2
distanceToGo KEYWORD2
targetPosition KEYWORD2z
currentPosition KEYWORD2
setCurrentPosition KEYWORD2
runToPosition KEYWORD2
runSpeedToPosition KEYWORD2
runToNewPosition KEYWORD2
stop KEYWORD2
disableOutputs KEYWORD2
enableOutputs KEYWORD2
setMinPulseWidth KEYWORD2
setEnablePin KEYWORD2
setPinsInverted KEYWORD2
maxSpeed KEYWORD2
enum flag {const1, const2, ..., constN};
By default, const1 is 0, const2 is 1 and so on. You can change default values of enum elements during declaration (if necessary).
// Changing default values of enum constants
enum suit {
club = 0,
diamonds = 10,
hearts = 20,
spades = 3,
};
*/