Seperate a value in arduino

Hello, I have some issues with programming a code for a 6dof car simulator. Ill explain it simple to keep the post short;
I have "DataValueL" and "DataValueR" - data from the game
"SensorL" and "SensorR" - the actual position of the motor.

all this values are scaled to 0-1024, and then compared to each other. The motor will rund backwards or forwards for the Sensor value to be equal to the Data value.

and then I have "gap" that i can use to slow the movement of the motor down when they move closer to the target value. The problem is that i need seperate "gap" values. I need "gap1" for the Left motor, and "gap2" for the Right motor. the code is complex with targetpos, actualpos and stuff. guess i need targetpos1 and 2 ect. But i cant get it to work. Will attach my code. 1DOF-6interface_working.ino (10.1 . KB)

Behandler: 1DOF-6interface_working.ino...

Please post it here instead

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

Using the same sensor value for both seems like a typo. You should just add your second "gap" as a parameter to this function rather than computing it within the function.

Also, you don't appear to be "slowing" down since you are not doing any PWM, just turning pins HIGH/LOW.

Thanks for reply!
I got 4 preset speeds with two relays instead of pwm. Im using VFD's, so 00 - 01 - 10 and 11 on my relays are 4 four different speeds on the motor :slight_smile: I should remove pwm from the code, but its difficult too remove it all from the code when its in some of the calculations. Yeah, the sensor is not a writing error, because I tried to use one arduino on one motor. Left and Right is the same motor. But if i get two gaps to work, i can use two motors on each arduino :slight_smile: any suggestions how to get gap in the function you mentioned?

This will give your separate ranges

/*
  Arduino code for dynamic playseat 2DOF
  Created 24 May 2011 by Jim Lindblom   SparkFun Electronics https://www.sparkfun.com/products/10182 "Example Code"
  Created 24 Apr 2012 by Jean David SEDRUE Version betatest26 - 24042012 http://www.gamoover.net/Forums/index.php?topic=25907
  Updated 20 May 2013 by RacingMat in english http://www.x-sim.de/forum/posting.php?mode=edit&f=37&t=943&p=8481  in french : http://www.gamoover.net/Forums/index.php?topic=27617
  Updated 30 April 2014 by RacingMat (bug for value below 16 corrected)
*/

#define BRAKEVCC 0
#define RV  2 //beware it's depending on your hardware wiring
#define FW  1 //beware it's depending on your hardware wiring
#define STOP 0
#define BRAKEGND 3

////////////////////////////////////////////////////////////////////////////////
#define pwmMax 255 // or less, if you want to lower the maximum motor's speed

// defining the range of potentiometer's rotation
const int potMini = 208;
const int potMaxi = 815;

////////////////////////////////////////////////////////////////////////////////
#define motLeft 0
#define motRight 1
#define potL A0
#define potR A1

////////////////////////////////////////////////////////////////////////////////
//  DECLARATIONS
////////////////////////////////////////////////////////////////////////////////
/*  VNH2SP30 pin definitions*/
int inApin[2] = {
  51, 52
};  // INA: Clockwise input
int inBpin[2] = {
  53, 54
}; // INB: Counter-clockwise input
int pwmpin[2] = {
  5, 6
}; // PWM input
int cspin[2] = {
  2, 3
}; // CS: Current sense ANALOG input
int enpin[2] = {
  0, 1
}; // EN: Status of switches output (Analog pin)
int statpin = 13;  //not explained by Sparkfun
/* init position value*/
int DataValueL = 512; //middle position 0-1024
int DataValueR = 512; //middle position 0-1024
int speedpin1 = 42;
int speedpin2 = 43;

const byte gapSteps = 5;
// max values for OFF, Speed 1, Speed 2, ...
const int gapRangeL[gapSteps] = { 50, 75, 150, 175, 200 };
const int gapRangeR[gapSteps] = { 50, 75, 150, 175, 200 };

////////////////////////////////////////////////////////////////////////////////
// INITIALIZATION
////////////////////////////////////////////////////////////////////////////////
void setup()
{
  pinMode(speedpin1, OUTPUT);
  pinMode(speedpin2, OUTPUT);
  // serial initialization
  Serial.begin(115200);

  // initialization of Arduino's pins
  pinMode(statpin, OUTPUT); //not explained by Sparkfun
  digitalWrite(statpin, LOW);

  for (int i = 0; i < 2; i++)
  {
    pinMode(inApin[i], OUTPUT);
    pinMode(inBpin[i], OUTPUT);
    pinMode(pwmpin[i], OUTPUT);
  }
  // Initialize braked for motor
  for (int i = 0; i < 2; i++)
  {
    digitalWrite(inApin[i], LOW);
    digitalWrite(inBpin[i], LOW);
    digitalWrite(speedpin1, LOW);
    digitalWrite(speedpin2, LOW);
  }
}
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Main Loop ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void loop()
{
  readSerialData();   // DataValueR & L contain the last order received (if there is no newer received, the last is kept)
  // the previous order will still be used by the PID regulation MotorMotion Function

  int sensorR = analogRead(potR);  // range 0-1023
  int sensorL = analogRead(potL);  // range 0-1023

  motorMotion(motRight, sensorR, DataValueR, gapRangeR);
  motorMotion(motLeft, sensorL, DataValueL, gapRangeL);
}
////////////////////////////////////////////////////////////////////////////////
// Procedure: wait for complete trame
////////////////////////////////////////////////////////////////////////////////
void readSerialData()
{
  byte Data[3] = {
    '0', '0', '0'
  };
  // keep this function short, because the loop has to be short to keep the control over the motors

  if (Serial.available() > 2) {
    //parse the buffer : test if the byte is the first of the order "R"
    Data[0] = Serial.read();
    if (Data[0] == 'L') {
      Data[1] = Serial.read();
      Data[2] = Serial.read();
      //  call the function that converts the hexa in decimal and that maps the range
      DataValueR = NormalizeData(Data);
    }
    if (Data[0] == 'R') {
      Data[1] = Serial.read();
      Data[2] = Serial.read();
      //  call the function that converts the hexa in decimal and maps the range
      DataValueL = NormalizeData(Data);
    }
  }
  if (Serial.available() > 16) Serial.flush();
}
////////////////////////////////////////////////////////
void motorMotion(int numMot, int actualPos, int targetPos, const int gapRange[gapSteps])
                 ////////////////////////////////////////////////////////
{
  int Tol = gapRange[0]; // no order to move will be sent to the motor if the target is close to the actual position
  // this prevents short jittering moves
  //could be a parameter read from a pot on an analogic pin
  // the highest value, the calmest the simulator would be (less moves)

  int pwm = 128;
  int brakingDistance = 0;

  // security concern : targetPos has to be within the mechanically authorized range
  targetPos = constrain(targetPos, potMini + brakingDistance, potMaxi - brakingDistance);

  int gap = abs(targetPos - actualPos);

  if (gap <= Tol) {
    Serial.print("Gap <= "); Serial.println(gapRange[0]);
    motorOff(numMot); //too near to move
  }
  else {
    // PID : calculates speed according to distance
    if (gap > gapRange[4]) {
      Serial.print("Gap > "); Serial.println(gapRange[4]);
      digitalWrite(speedpin1, LOW);
      digitalWrite(speedpin2, LOW);
    }
    else if (gap > gapRange[3]) {
      Serial.print("Gap > "); Serial.println(gapRange[3]);
      digitalWrite(speedpin1, LOW);
      digitalWrite(speedpin2, HIGH);
    }
    else if (gap > gapRange[2]) {
      Serial.print("Gap > "); Serial.println(gapRange[2]);
      digitalWrite(speedpin1, HIGH);
      digitalWrite(speedpin2, LOW);
    }
    else if (gap > gapRange[1]) {
      Serial.print("Gap > "); Serial.println(gapRange[1]);
      digitalWrite(speedpin1, HIGH);
      digitalWrite(speedpin2, HIGH);
    }

    // if motor is outside from the range, send motor back to the limit !
    // go forward (up)
    if ((actualPos < potMini) || (actualPos < targetPos)) {
      Serial.print("Go forward");
      motorGo(numMot, FW, pwm);
    }
    // go reverse (down)
    else if ((actualPos > potMaxi) || (actualPos > targetPos)) {
      Serial.print("Go reverse");
      motorGo(numMot, RV, pwm);
    }
  }
}



////////////////////////////////////////////////////////////////////////////////
void motorOff(int motor) { //Brake Ground : free wheel actually
  ////////////////////////////////////////////////////////////////////////////////
  digitalWrite(inApin[motor], LOW);
  digitalWrite(inBpin[motor], LOW);
  analogWrite(pwmpin[motor], 0);
}
////////////////////////////////////////////////////////////////////////////////
void motorOffBraked(int motor) { // "brake VCC" : short-circuit inducing electromagnetic brake
  ////////////////////////////////////////////////////////////////////////////////
  digitalWrite(inApin[motor], HIGH);
  digitalWrite(inBpin[motor], HIGH);
  analogWrite(pwmpin[motor], 0);
}

////////////////////////////////////////////////////////////////////////////////
void motorGo(uint8_t motor, uint8_t direct, uint8_t pwm)
////////////////////////////////////////////////////////////////////////////////
{
  if (motor <= 1)
  {
    if (direct <= 4)
    {
      // Set inA[motor]
      if (direct <= 1)
        digitalWrite(inApin[motor], HIGH);
      else
        digitalWrite(inApin[motor], LOW);

      // Set inB[motor]
      if ((direct == 0) || (direct == 2))
        digitalWrite(inBpin[motor], HIGH);
      else
        digitalWrite(inBpin[motor], LOW);

      analogWrite(pwmpin[motor], pwm);

    }
  }
}

////////////////////////////////////////////////////////////////////////////////
void motorDrive(uint8_t motor, uint8_t direct, uint8_t pwm)
////////////////////////////////////////////////////////////////////////////////
{
  // more readable function than Jim's (for educational purpose)
  // but 50 octets heavier ->  unused
  if (motor <= 1 && direct <= 4)
  {
    switch (direct) {
      case 0: //electromagnetic brake : brake VCC
        digitalWrite(inApin[motor], HIGH);
        digitalWrite(inBpin[motor], HIGH);
        break;
      case 3: //Brake Ground (free wheel)
        digitalWrite(inApin[motor], LOW);
        digitalWrite(inBpin[motor], LOW);
        break;
      case 1: // forward : beware it's depending on your hardware wiring
        digitalWrite(inApin[motor], HIGH);
        digitalWrite(inBpin[motor], LOW);
        break;
      case 2: // Reverse : beware it's depending on your hardware wiring
        digitalWrite(inApin[motor], LOW);
        digitalWrite(inBpin[motor], HIGH);
        break;
    }
    analogWrite(pwmpin[motor], pwm);
  }
}
////////////////////////////////////////////////////////////////////////////////
// testPot
////////////////////////////////////////////////////////////////////////////////
void testPot() {


}
////////////////////////////////////////////////////////////////////////////////
void testpulse() {
  int pw = 120;
  while (true) {

    motorGo(motLeft, FW, pw);
    delay(250);
    motorOff(motLeft);
    delay(250);
    motorGo(motLeft, RV, pw);
    delay(250);
    motorOff(motLeft);

    delay(500);

    motorGo(motRight, FW, pw);
    delay(250);
    motorOff(motRight);
    delay(250);
    motorGo(motRight, RV, pw);
    delay(250);
    motorOff(motRight);
    Serial.println("testpulse pwm:80");
    delay(500);

  }
}
////////////////////////////////////////////////////////////////////////////////
// Function: convert Hex to Dec
////////////////////////////////////////////////////////////////////////////////
int NormalizeData(byte x[3])
////////////////////////////////////////////////////////////////////////////////
{
  int result;

  if ((x[2] == 13) || (x[2] == 'R') || (x[2] == 'L')) //only a LSB and Carrier Return or 'L' or 'R' in case of value below 16 (ie one CHAR and not 2)
  {
    x[2] = x[1]; //move MSB to LSB
    x[1] = '0';   //clear MSB
  }
  for (int i = 1; i < 3; i++)
  {
    if (x[i] > 47 && x[i] < 58 ) { //for x0 to x9
      x[i] = x[i] - 48;
    }
    if (x[i] > 64 && x[i] < 71 ) { //for xA to xF
      x[i] = (x[i] - 65) + 10;
    }
  }
  // map the range from Xsim (0 <-> 255) to the mechanically authorized range (potMini <-> potMaxi)
  result = map((x[1] * 16 + x[2]), 0, 255, potMini, potMaxi);
  return result;
}

but your code still has lots of other issues. For example Serial.flush() isn't doing what you think.

Wow! Thank you so much!
I know. The code is a kind of standard default we can use for simulators, and then you need to change some things to make it work for your setup. In my case I use relays instead of PWM. Ive added speedpin outputs and write the gap section. Can i add Speedpin3 and Speedpin4 and write it like this now?;

if (gap > gapRangeL[4]) {
Serial.print("Gap > "); Serial.println(gapRange[4]);
digitalWrite(speedpin1, LOW);
digitalWrite(speedpin2, LOW);
if (gap > gapRangeR[4]) {
Serial.print("Gap > "); Serial.println(gapRange[4]);
digitalWrite(speedpin3, LOW);
digitalWrite(speedpin4, LOW);

Here is your code snippet Auto Formatted in the IDE to show the code blocks

if (gap > gapRangeL[4])
{
  Serial.print("Gap > ");
  Serial.println(gapRange[4]);
  digitalWrite(speedpin1, LOW);
  digitalWrite(speedpin2, LOW);
  if (gap > gapRangeR[4])
  {
    Serial.print("Gap > ");
    Serial.println(gapRange[4]);
    digitalWrite(speedpin3, LOW);
    digitalWrite(speedpin4, LOW);

Notice how much easier it is to see what is going on than your cramped, unformatted version

Thanks! will do that :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.