A colegue has looked at my data and come up with an equation which only has a 5 RPM error.
its a second order polynomial
y = 0.000000002746 x^3 - 0.000025778517 x^2 + 0.614445568581 x + 46.160953172061
how can i use the equation in my code
Something like ?
void InverterOutput ()
{
// RPM
ch1= FS_SpeedMsg; // Spindle speed value fom incomming message
ch1=(0.000000002746*(FS_SpeedMsg)^3 - 0.000025778517*(FS_SpeedMsg)^2 + 0.614445568581* (FS_SpeedMsg) + 46.160953172061
}
The full working code without this equation as it is now
//============================================
// VFD_FO_Interface
// 30th January 2019
//
#include <SoftwareSerial.h>
#define rx 2
#define tx 3
#include <Wire.h>
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;
SoftwareSerial XSERIAL = SoftwareSerial(rx, tx, false);
const byte numChars = 10;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
char messageFromPC[numChars] = {0};
int SpindleSpd = 0;
int integerFromPC = 0;
float floatFromPC = 0.0;
boolean newData = false;
// Mechanical states //////////////////////////////////////////////////////////
const int SudsPump = 7;
const int SpinFWD = 5;
const int SpinREV = 6;
// Incoming messages /////////////////////////////////////////////////////////
const unsigned int MAX_INPUT = 10;
long int FS_SpeedMsg = 0; // spindle speed
int CmdSpindleCW = 0; // spindle CW direction
int CmdSpindleCCW = 0; // spindle CCW direction
int CmdCoolant = 0; // activate suds pump
int data = 0; // Spare data block
// Variables will change: ////////////////////////////////////////////////////
int SudsPumpState = LOW;
int SpinFWDState = LOW;
int SpinREVState = LOW;
int dummy;
bool Fwd_Rev;
float ch1;//spindle pwm
//int sensorValue = 100; // value read from the pot
int outputValue = 0; // value output to the PWM (analog out)
//============
void setup() {
Serial.begin(9600);
XSERIAL.begin(2400);
dac.begin(0x60);
// initialize digital output.
pinMode(SudsPump, OUTPUT);
pinMode(SpinFWD, OUTPUT);
pinMode(SpinREV, OUTPUT);
}
//============
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
showParsedData();
newData = false;
}
}
//============
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (XSERIAL.available() > 0 && newData == false) {
rc = XSERIAL.read();
//Serial.println(rc);
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//============
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,","); // get the first part - the string
strcpy(messageFromPC, strtokIndx); // copy it to messageFromPC
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
integerFromPC = atoi(strtokIndx); // convert this part to an integer
// strtokIndx = strtok(NULL, ",");
// floatFromPC = atof(strtokIndx); // convert this part to a float
}
//============
void showParsedData() {
SpindleSpd = atoi(messageFromPC);
FS_SpeedMsg = SpindleSpd;
Serial.print(SpindleSpd);
//Serial.print(messageFromPC);
Serial.print(", ");
Serial.println(integerFromPC);
Serial.println(ch1);
CmdSpindleCW = (bitRead (integerFromPC,0)); //Spindle CW Directrion
CmdSpindleCCW = (bitRead (integerFromPC,1));
CmdCoolant = (bitRead (integerFromPC,2));
if (FS_SpeedMsg == 0)
{
CmdSpindleCW = 0;
CmdSpindleCCW = 0;
}
InverterOutput (); // Send data to variable frequency drive
}
void InverterOutput ()
{
// RPM
ch1= FS_SpeedMsg; // Spindle speed value fom incomming message
dac.setVoltage((ch1 * 0.589), false); //17~4095 full range Generates 4.1 x ch to give 4095 max o/p
// Direction Relay Output Conditions
// 10 is minimum RPM - if a value less than 10 is sent the spindle will shut off
if (ch1 > 10) {
//Fwd_Rev = CmdSpindleCW; // direction value fom incomming RS485 message
SpinFWDState = CmdSpindleCW;
SpinREVState = CmdSpindleCCW;
//Serial.println (SpinFWDState);
//Serial.println (SpinREVState);
}
else {
SpinFWDState = 0;
SpinREVState = 0;
}
// Coolant Machine Commands
SudsPumpState = CmdCoolant;// value fom incomming message
if (SudsPumpState == 1) {
digitalWrite(SudsPump, HIGH); // turn the LED on (HIGH is the voltage level)
}
else {
//Energise the reset relay
digitalWrite(SudsPump, LOW); // turn the LED off by making the voltage LOW
// //delay by so many m/s then
// //deenergise reset relay
}
// Direction Relay Outputs
//
if (SpinFWDState == 1) {
//
digitalWrite(SpinFWD, HIGH); // turn the LED on (HIGH is the voltage level)
}
else {
digitalWrite(SpinFWD, LOW); // turn the LED off by making the voltage LOW
//
}
//
if (SpinREVState == 1) {
digitalWrite(SpinREV, HIGH); // turn the LED on (HIGH is the voltage level)
}
else {
digitalWrite(SpinREV, LOW); // turn the LED off by making the voltage LOW
//
}
}
Im thinking replace x in formula with FS_SpeedMsg
0.000000002746* (FS_SpeedMsg)^3 - 0.000025778517*(FS_SpeedMsg)^2 + 0.614445568581* (FS_SpeedMsg) + 46.160953172061
got lovely errors about double conversion to double etc.
any thoughts