1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  3. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  4. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

Tutorial SMC3 Arduino 3DOF Motor Driver and Windows Utilities

Discussion in 'SimTools compatible interfaces' started by RufusDufus, Dec 1, 2013.

  1. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    21,094
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    148,246Coins
    Ratings:
    +10,892 / 54 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
    SMC3 can do 3 motors but does not treat all 3 exactly the same way, so using an additional Arduino, given how relatively cheap they are, can be advantageous.
  2. Nick Clements

    Nick Clements Member

    Joined:
    Jan 7, 2019
    Messages:
    41
    Balance:
    77Coins
    Ratings:
    +4 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, SCN5, Arduino, Motion platform
    once I have added the second Uno3 card I guess I just change the config file to match the new card com port. But what is the correct setting for the serial port setup in sim tools or flyptmover ?
  3. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    21,094
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    148,246Coins
    Ratings:
    +10,892 / 54 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
    In SimTools you set it up as a separate controller in Interface Settings, specifying the correct port and axis designation.
  4. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    21,094
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    148,246Coins
    Ratings:
    +10,892 / 54 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
    In SimTools you set it up as a separate controller in Interface Settings, specifying the correct port and axis designation.
  5. Nick Clements

    Nick Clements Member

    Joined:
    Jan 7, 2019
    Messages:
    41
    Balance:
    77Coins
    Ratings:
    +4 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, SCN5, Arduino, Motion platform
    After purchasing a new IBT and the decision to use a second arduino all is now working perfectly. Many thanks for the help.
    One more question. In SimTools and flypt what do I put as the axis assignment under the serial interface settings. Is it just [C<Axis3>] on the second arduino for the 3 rd motor (traction loss)
  6. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    21,094
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    148,246Coins
    Ratings:
    +10,892 / 54 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
    For SimTools it should be [C<Axis3a>]
  7. Nick Clements

    Nick Clements Member

    Joined:
    Jan 7, 2019
    Messages:
    41
    Balance:
    77Coins
    Ratings:
    +4 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, SCN5, Arduino, Motion platform
    Thankyou . All working fine now. I did however have to change from [C<Axis3a>] to [A<Axis3a>] . As this third axis was on second arduino .

    Before I dive into properly setting up, as I’m only using for MS2020 flight sim what are the best axis assignments to use. For Yaw should I use Yaw velocity?

    Also after using the tuner in sim tools 3 both for ground and then air, how do I tone down the ground movements as it’s way to strong.? Do I use the sliders, and tone down by moving slider up and adding to the limits?
  8. Nick Clements

    Nick Clements Member

    Joined:
    Jan 7, 2019
    Messages:
    41
    Balance:
    77Coins
    Ratings:
    +4 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, SCN5, Arduino, Motion platform
    Anyone got a successful flight sim setup in sim tools 3 I could copy and use as a good starting point.
  9. grooste_lwd

    grooste_lwd Active Member

    Joined:
    Nov 20, 2015
    Messages:
    123
    Location:
    Nederland => Friesland => Leeuwarden
    Balance:
    123Coins
    Ratings:
    +91 / 0 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino
    I use 2 h-brige parallel on one 24v motor. 1 h-brige overheat and stops. Going error like status in a short time. 2x ibt parrallel did the fix. If using big 24 high amp (250watt wheelchair motor) they are stil in my opinion fast. Need more reduced gears.
    • Like Like x 1
  10. Sebastian2

    Sebastian2 Member Gold Contributor

    Joined:
    Dec 17, 2023
    Messages:
    82
    Balance:
    296Coins
    Ratings:
    +48 / 1 / -0
    I'm using SMC3 for my rig and I want to try pot scaling.

    Can anyone give me a recommendation on the specs for a pot that is suited for this job? I have no idea what maximum resistance value I should choose.
  11. Sebastian2

    Sebastian2 Member Gold Contributor

    Joined:
    Dec 17, 2023
    Messages:
    82
    Balance:
    296Coins
    Ratings:
    +48 / 1 / -0
    Update: I tried a 1 kOhm and a 47 kOhm pot and both worked fine.

    I suggest updating the first post in this thread with info on what pot to use. That way more people will find it.

    ---

    Another question:

    SMC3 and Simtools can easily be set to a different serial data transfer rate. However, anything else than the default data rate breaks SMC3utils. Is there any way to get around that?

    It would be really nice to be able to set the bits per second in the SMC3utils.ini file.
  12. Gefahren

    Gefahren Member

    Joined:
    Mar 9, 2024
    Messages:
    55
    Occupation:
    Electronics Engineer
    Location:
    Central Mississippi, USA
    Balance:
    395Coins
    Ratings:
    +66 / 0 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino, Motion platform
    Can someone tell me if the SMC3v1.0.zip file in the first post of this thread the latest one that everyone is using?

    The reason I am asking is because I went looking in the code when questioning the results of my settings. Down in the code for the PID calculations I noticed that they were wrong, and worse yet they were different for each of the motors. I even redownloaded that file to make sure it wasn't something I'd done.

    If someone could please confirm that the file in the first post of this thread is the one I'm supposed to be using, then I'll elaborate on my findings. If that's not the one I'm supposed to be using, then please point me in the right direction.
  13. noorbeast

    noorbeast VR Tassie Devil Staff Member Moderator Race Director

    Joined:
    Jul 13, 2014
    Messages:
    21,094
    Occupation:
    Innovative tech specialist for NGOs
    Location:
    St Helens, Tasmania, Australia
    Balance:
    148,246Coins
    Ratings:
    +10,892 / 54 / -2
    My Motion Simulator:
    3DOF, DC motor, JRK
  14. Gefahren

    Gefahren Member

    Joined:
    Mar 9, 2024
    Messages:
    55
    Occupation:
    Electronics Engineer
    Location:
    Central Mississippi, USA
    Balance:
    395Coins
    Ratings:
    +66 / 0 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino, Motion platform
    Ok, that is the file I downloaded.
    I'll give a more detailed explanation after work today, but to summarize what I found is that taking the same input values (Kp, Ki, Kd, Ks, CurrentPosistion, TargetPosistion) each of the three PID functions (CalcMotor1PID, CalcMotor2PID, CalcMotor3PID) will give a different answer. Also, the Integral and Derivative terms are not calculated properly because the Cumulative Error and Last Position values are re-initialized to zero every time the functions are called.
    • Like Like x 1
  15. Gefahren

    Gefahren Member

    Joined:
    Mar 9, 2024
    Messages:
    55
    Occupation:
    Electronics Engineer
    Location:
    Central Mississippi, USA
    Balance:
    395Coins
    Ratings:
    +66 / 0 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino, Motion platform
    I'll try to walk through the code to explain the errors I see with it.
    The CalcMotor1PID function starts at line 1402 in the code if anyone wants to follow along. I'll put the code in red and my comments in black.

    int CalcMotor1PID(int TargetPosition, int CurrentPosition)

    This is the function call, we pass it current and desired positions

    {
    static int Error=0;
    static long pTerm_x100=0;
    static long dTerm_x100=0;
    static long iTerm_x100=0;
    static int CumError=0;
    static int LastPosition=0;
    static int DeltaPosition=0;
    static int KdFilterCount=0;

    Here the variables are initialized to a zero value. CumError, LastPosition, KdFilterCount should not be here. They need to persist through each run of this function instead of being set to zero every time.

    Error = TargetPosition - CurrentPosition;
    if (abs(Error)<=DeadZone1)
    {
    CumError = 0;
    }
    else
    {
    CumError += Error;
    CumError = constrain(CumError,-1024,1024);
    }

    This calculates our Error term and if it is less than our deadzone setting we set CumError to a zero again. If Error is greater than our deadzone we add Error to CumError, then constrain CumError to not be ouside of the -1024 to 1024 range. Problem is that we always initialize CumError to zero when we call this function, it should be something that gets bigger the longer it takes us to get to the TargetPosition.

    pTerm_x100 = Kp1_x100 * (long)Error; // Error can only be between +/-1023 and Kp1_100 is constrained to 0-1000 so can work with type long
    iTerm_x100 = (Ki1_x100 * (long)CumError); // was >>6

    Now it calculates the pTerm from the Error and Kp setting. This appears right. Next it calculates the iTerm from the CumError and Ki setting. This also appears right, except that the CumError will always be zero or equal to Error. This essentially makes any Ki value you set just an additional Kp value.

    KdFilterCount++;
    if (KdFilterCount >= Ks1) // Apply a level of filtering to Kd parameter to help reduce motor noise
    {
    DeltaPosition = (CurrentPosition - LastPosition);
    LastPosition = CurrentPosition;
    dTerm_x100 = (Kd1_x100 * (long)DeltaPosition); // was <<5
    KdFilterCount=0;
    }
    This increments the KdFilterCount which was initialized to a zero. So, it makes KdFilterCount = 1 every time this is run through. Next it checks to see if KdFilterCount is Greater than or equal to the Ks value. Since KdFilterCount will always equal 1 at this point, then any Ks value besides 1 will make it skip calculating the dTerm. Ks is supposed to make it skip calculating the dTerm a set number of times equal to the Ks value.

    When it does go into calculating it the first thing is it calculates the DeltaPosition by taking the LastPosition from the CurrentPosition. Problem here is LastPosition is always set to zero at the beginning of this function. So, the dTerm it calculates is based on how far the axis is from its minimum, not how far it is from where it was last time this function ran.


    return constrain((pTerm_x100 + iTerm_x100 - dTerm_x100) >> PowerScale ,-255,255); // the /128 (PowerScale) is an approximation to bring x100 terms back to units. Accurate/consistent enough for this function.
    }

    This is the last part of the function where it calculates the return value. This looks correct.

    The CalcMotor2PID function has all the same problems but it has two extra lines added between the error calculation and the pTerm calculation.

    CumError = constrain(CumError,-1024,1024); // Maybe Try 512 as the limits??????
    }

    -->>DeltaPosition = (CurrentPosition - LastPosition);
    -->>LastPosition = CurrentPosition;


    pTerm_x100 = Kp2_x100 * (long)Error; // Error can only be between +/-1023 and Kp1_100 is constrained to 0-1000 so can work with type long

    Those two lines (with the arrows pointing to them) set the DeltaPosition to the CurrentPosition since the LastPosition is alway zero at this point. Then sets the LastPosition to equal the CurrentPosition. This isn't anymore of a problem than with the Motor1 calculations except when it gets to calculating the dTerm it has those same to lines in it which means now DeltaPosition is set to zero since the LastPosition is equal to CurrentPosition and we subtract it from CurrentPosition. So, in this case the dTerm will always be zero.

    When we get to CalcMotor3PID is has all the same problems as CalcMotor2PID. However, it also adds a right bitshift to the calculated iTerm. This effectively divides the iTerm by 64 so it has a smaller effect on the final value. The dTerm calculation has an added left bitshift which is effectively a multiply by 32. However, since the dTerm is always zero then this doesn't matter.

    For an example of how this effects the return values from these functions I ran through each using the same values:
    Current Position = 500
    Target Position = 550
    Kp = 200
    Ki = 50
    Kd = 10
    Ks = 1

    With those values the return from the three functions were as follows:
    CalcMotor1PID return = 58
    CalcMotor2PID return = 97
    CalcMotor3PID return = 78

    What I am surprised at is that no one else noticed this.
  16. Sebastian2

    Sebastian2 Member Gold Contributor

    Joined:
    Dec 17, 2023
    Messages:
    82
    Balance:
    296Coins
    Ratings:
    +48 / 1 / -0
    Because PID is hard ;)

    Interesting work you have done there!

    I found some aspects of how the PIDs behaved odd, but they worked well enough for me to not digg into it.

    Could you provide updated code with fixed PID implementation? I'm willing to check it out.
  17. dryas123

    dryas123 New Member

    Joined:
    Jan 19, 2023
    Messages:
    16
    Balance:
    - 138Coins
    Ratings:
    +12 / 0 / -0
    My Motion Simulator:
    2DOF
    Hey,

    This would explain why the speed of my motors was always the same as it makes no difference how far target and current position is away from each other (it makes a difference, but not from a logical standpoint). It ended that I've written my own implementation of PID and an SMC3 like firmware.

    ...but you are right, it's strange no one recognized this over the last... 10 years or so. I'll probably will have a look at the code this evening too.

    Best,

    Ben
  18. Gefahren

    Gefahren Member

    Joined:
    Mar 9, 2024
    Messages:
    55
    Occupation:
    Electronics Engineer
    Location:
    Central Mississippi, USA
    Balance:
    395Coins
    Ratings:
    +66 / 0 / -0
    My Motion Simulator:
    3DOF, DC motor, Arduino, Motion platform
    I looked in some of the other versions of SMC3 that people have written where they added things like soft start and such. In those I noticed that they had rewritten and corrected the problems in the PID section at least. Nobody apparently mentioned it everybody else.

    As it is, the SMC3 file from this thread still is a Proportional controller which will still work depending on your setup.

    Sebastian2 I have rewritten the code to fix the behavior, but it wouldn't be right to post it in this thread. Also, with the other versions out there that have already fixed this problem it would be better to point people to one of those versions that is actively being supported.
    • Like Like x 1
  19. Attyla.pl

    Attyla.pl Active Member

    Joined:
    Oct 1, 2023
    Messages:
    163
    Location:
    Polska
    Balance:
    660Coins
    Ratings:
    +46 / 0 / -0
    My Motion Simulator:
    2DOF, Arduino
    Gefahren i have a request if you could explain in a few words for those not very tech savvy what are the potential problems for those using SMC3 file from this thread e.g.:
    In your opinion is it possible to build a 6DOF rotary based on 3 Arduino ?


    And of course I have a request to make available your corrected SMC code, I think that since for so many years no one has had any requests from the author of the original code then and this time rather everyone will be grateful for the correction. All in all, we all build and use our own motion sim at our own risk.
  20. ordanssela

    ordanssela New Member

    Joined:
    Jul 17, 2023
    Messages:
    4
    Balance:
    - 58Coins
    Ratings:
    +0 / 0 / -0
    My Motion Simulator:
    2DOF, 3DOF, DC motor, SimforceGT, Motion platform
    (I'm from Brazil and I'm using Google translate) I want to use hall sensors on my platform, I wanted to use the (p3022-v1-cw360) but it is a little expensive for me to import, I tried to use the (AS5600) but it did not generate an analog signal, I don't know why, I want to do the try with (MT6701). But I don't know if it will work, could someone tell me the model of the chip used in (P3022)?