MAL4X Научно-технический форум разработчиков симуляторов и автоматики


Симуляторы перегрузок. DIY электроника. ЭВМ. Компьютерные сети.
Up

Новейшая прошивка для Arduino.

Строим реалистичный симулятор перегрузок своими руками. Рекомендации. Советы.

Модераторы: Death_Morozz, null, Ale

Сообщение SimAl » 07 окт 2017, 14:01

Simctrl это тулза для настройки? Ну, видимо, разные. Скорее всего эта утилита отправляет всегда значения двумя цифрами - добавляет ноль впереди при необходимости, т.е. 01, 02 ... 0F, 10... FF. А симтулз первый, ничего не значащий ноль опускает: 0, 1 ... F,10...FF. По смыслу это одно и то же, но отсутствие нуля вводит ардуино в ступор.
Аватара пользователя
SimAl
SIMER
 
Сообщения: 379
Зарегистрирован: 22 ноя 2013, 20:03
Откуда: Кропивницкий
Благодарил (а): 58 раз.
Поблагодарили: 258 раз.
Баллы репутации: 128
ТехнарьТехнарь

Re: Новейшая прошивка для Arduino.

Сообщение lm890405 » 12 окт 2017, 19:51

DmRaF писал(а):А против писка моторов использую наушники

вот прошивка которая не пищит

Код: Выделить всё
/*   
 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 Mathieu RIVIER in english http://www.xsimulator.net/2dof-wiper-motor-playseat/ in french : http://www.gamoover.net/Forums/index.php?topic=27617
 Updated 30 April 2014 by RacingMat (bug for value below 16 corrected)
 Updated 1 June 2014 by RacingMat: implementation of Ultrasonic PWM (don't stack the motomonster! follow the new pinout!)
 results in video here : https://www.youtube.com/watch?v=FzhUga64fJs
 */

#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 than 255, if you want to lower the maximum motor's speed
#define pwmMini 150

// defining the range of potentiometer's rotation 0 <-> 1024
const int potMini=200;
const int potMaxi=800;

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

////////////////////////////////////////////////////////////////////////////////
//  DECLARATIONS
////////////////////////////////////////////////////////////////////////////////
/*  VNH2SP30 pin definitions
 // with 20kHz PWM pinout is changed, you CANNOT stack the motomonster anymore!
 Arduino /..Motomonster1
 ......GND <-> GND pin
 ........5V <-> 5V
 .....pin 4 <-> pin 4 inA motor1
 .....pin 5 <-> pin 9 inB motor2
 .....pin 6 <-> xxxx
 .....pin 7 <-> pin 7 inA motor2
 .....pin 8 <-> pin 8 inB motor1
 .....pin 9 <-> pin 5 pwm motor1
 .....pin 10 <-> pin 6 pwm motor2 */

int inApin[2] = {
  7, 4};  // INA: Clockwise input
int inBpin[2] = {
  8, 5}; // INB: Counter-clockwise input
int pwmpin[2] = {
  9, 10}; // PWM input
/* init position value at startup */
int DataValueL=512; //middle position 0-1024
int DataValueR=512; //middle position 0-1024

int sensorL,sensorR;   
////////////////////////////////////////////////////////////////////////////////
// INITIALIZATION
////////////////////////////////////////////////////////////////////////////////
void analogWriteSAH_Init( void )
{
  // Stop the timer while we muck with it

  TCCR1B = (0 << ICNC1) | (0 << ICES1) | (0 << WGM13) | (0 << WGM12) | (0 << CS12) | (0 << CS11) | (0 << CS10);

  // Set the timer to mode 14...
  //
  // Mode  WGM13  WGM12  WGM11  WGM10  Timer/Counter Mode of Operation  TOP   Update of OCR1x at TOV1  Flag Set on
  //              CTC1   PWM11  PWM10
  // ----  -----  -----  -----  -----  -------------------------------  ----  -----------------------  -----------
  // 14    1      1      1      0      Fast PWM                         ICR1  BOTTOM                   TOP

  // Set output on Channel A and B to...
  //
  // COM1z1  COM1z0  Description
  // ------  ------  -----------------------------------------------------------
  // 1       0       Clear OC1A/OC1B on Compare Match (Set output to low level).

  TCCR1A =
    (1 << COM1A1) | (0 << COM1A0) |   // COM1A1, COM1A0 = 1, 0
  (1 << COM1B1) | (0 << COM1B0) |
    (1 << WGM11) | (0 << WGM10);      // WGM11, WGM10 = 1, 0

    // Set TOP to...
  //
  // fclk_I/O = 16000000
  // N        = 1
  // TOP      = 799
  //
  // fOCnxPWM = fclk_I/O / (N * (1 + TOP))
  // fOCnxPWM = 16000000 / (1 * (1 + 799))
  // fOCnxPWM = 16000000 / 800
  // fOCnxPWM = 20000

    ICR1 = 799;

  // Ensure the first slope is complete

  TCNT1 = 0;

  // Ensure Channel A and B start at zero / off

  OCR1A = 0;
  OCR1B = 0;

  // We don't need no stinkin interrupts

  TIMSK1 = (0 << ICIE1) | (0 << OCIE1B) | (0 << OCIE1A) | (0 << TOIE1);

  // Ensure the Channel A and B pins are configured for output
  DDRB |= (1 << DDB1);
  DDRB |= (1 << DDB2);

  // Start the timer...
  //
  // CS12  CS11  CS10  Description
  // ----  ----  ----  ------------------------
  // 0     0     1     clkI/O/1 (No prescaling)

  TCCR1B =
    (0 << ICNC1) | (0 << ICES1) |
    (1 << WGM13) | (1 << WGM12) |              // WGM13, WGM12 = 1, 1
  (0 << CS12) | (0 << CS11) | (1 << CS10);
}

void analogWriteUltrasonic255( uint8_t motor, uint16_t value )

  //  My variable value varies from 0 to 255
  //  but awaited range in OCR1A is from 0 to 799 and nothing else!
  switch (motor) {
  case 0:
    OCR1A=constrain(map(value, 0, 255, 0, 799), 0, 799); //D9
    break;
  case 1:
    OCR1B=constrain(map(value, 0, 255, 0, 799), 0, 799); //D10
    break;
  }
}


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void setup()
{
  analogWriteSAH_Init();
  // serial initialization
  Serial.begin(115200);

  // initialization of Arduino's pins

  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);
  }

}
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Main Loop ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

void loop()
{
  while (1==1) // to get the fastest loop possible
{

  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

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

  motorMotion(motRight,sensorR,DataValueR);
  motorMotion(motLeft,sensorL,DataValueL);
}}
////////////////////////////////////////////////////////////////////////////////
// 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)
////////////////////////////////////////////////////////
{
  int Tol=20; // 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 gap;
  int pwm;
  int brakingDistance=30;

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

  gap=abs(targetPos-actualPos); // 0 <-> 1024

  if (gap<= Tol) {
        analogWriteUltrasonic255(numMot,0); //too near to move : stop -> pwm=0   
  }
  else {
    // PID : P only as it calculates speed according to distance
    // smooth growing of speed
    //pwm=pwmMini+((255-pwmMini)/(100-Tol))*(gap-Tol);
        pwm=195;
        if (gap>50)   pwm=215;
        if (gap>75)   pwm=235;   
        if (gap>100)  pwm=255;
    pwm=map(pwm, 0, 255, 0, pwmMax);  //adjust the value according to pwmMax for global sensitivity !

    // if motor is outside from the range, send motor back to the limit !
    // go forward (up)
    if ((actualPos<potMini) || (actualPos<targetPos))
    {   
      digitalWrite(inApin[numMot], HIGH);
      digitalWrite(inBpin[numMot], LOW);
    }
    // go reverse (down)   
    if ((actualPos>potMaxi) || (actualPos>targetPos))
    {   
      digitalWrite(inApin[numMot], LOW);
      digitalWrite(inBpin[numMot], HIGH);
    }
    analogWriteUltrasonic255(numMot,pwm);
  }
}

////////////////////////////////////////////////////////////////////////////////
// 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 xA to xF
      x[i]=x[i]-48;
    }                       
    if (  x[i]>64 && x[i]<71 ){//for x0 to x9
      x[i]=x[i]-55;               
    }
  }
  // map the range from game telemetry which is sent between (0 <-> 255) to the mechanically authorized range (potMini <-> potMaxi) (0<->1024)
  result=map((x[1]*16+x[2]),0,255,potMini,potMaxi);
  return result;
}



lm890405
Новичок
 
Сообщения: 21
Зарегистрирован: 03 сен 2017, 23:20
Благодарил (а): 3 раз.
Поблагодарили: 2 раз.
Баллы репутации: 0

Re: Новейшая прошивка для Arduino.

Сообщение SimAl » 12 окт 2017, 20:26

lm890405 писал(а):вот прошивка которая не пищит
Да, тут не нулевой таймер используется, а первый. Он позволяет задать произвольную частоту, соответственно можно избавиться от писка. Но на Ардуино с такой прошивкой монстр не станет бутербродом - потребуются либо хардварные модификации, либо соединять соплями.
Аватара пользователя
SimAl
SIMER
 
Сообщения: 379
Зарегистрирован: 22 ноя 2013, 20:03
Откуда: Кропивницкий
Благодарил (а): 58 раз.
Поблагодарили: 258 раз.
Баллы репутации: 128
ТехнарьТехнарь

Re: Новейшая прошивка для Arduino.

Сообщение Spirit » 14 окт 2017, 00:59

Возможно этот глюк поправили в Simtools 2, если проверишь - отпишись пожалуйста.
Чтобы избавиться от писка надо установить частоты повыше, SMC3 может помочь.
Аватара пользователя
Spirit
SIMER
 
Сообщения: 300
Зарегистрирован: 18 ноя 2014, 14:40
Откуда: Киев
Благодарил (а): 85 раз.
Поблагодарили: 95 раз.
Баллы репутации: 58
Технарь

Re: Новейшая прошивка для Arduino.

Сообщение deadlymanager » 30 июн 2019, 11:45

Извиняюсь за глупый вопрос, можно ли подключить к ардуино с вашей прошивкой 86HSE8N BC38 Closed loop stepper motor, шаговик с энкодером.
Я тупой...., я очень тупой.
Аватара пользователя
deadlymanager
Новичок
 
Сообщения: 18
Зарегистрирован: 30 июн 2019, 10:04
Откуда: Красноярск, Россия
Благодарил (а): 3 раз.
Поблагодарили: 12 раз.
Баллы репутации: 15
Новичок

Re: Новейшая прошивка для Arduino.

Сообщение Ale » 30 июн 2019, 12:08

deadlymanager писал(а):Извиняюсь за глупый вопрос, можно ли подключить к ардуино с вашей прошивкой 86HSE8N BC38 Closed loop stepper motor, шаговик с энкодером.

Вопрос интересный. Насколько я понял, это фактически готовый серво на базе шаговика и энкодера. По управлению он все равно - шаговик, т.к. управляется по входам DIR и PULSE.

Другое дело, что петля регулирования у него встроенная, а прошивка имеет свою "программную" петлю регулирования с обязательным наличием датчика положения. Можно, конечно, и к этому мотору прикрутить снаружи потенциометр и концевики, и использовать его как простой шаговик, но это, как-то, "масло масленое" будет.
Аватара пользователя
Ale
Разработчик
 
Сообщения: 1477
Зарегистрирован: 01 фев 2011, 20:48
Откуда: Дубна
Благодарил (а): 570 раз.
Поблагодарили: 595 раз.
Баллы репутации: 277
ТехнарьТехнарьТехнарь

Re: Новейшая прошивка для Arduino.

Сообщение deadlymanager » 30 июн 2019, 16:17

Ale Жду драйвера к ним, буду смотреть может они по ШИМ работать могут. Заработает поделюсь. Во всяком случае спасибо. Тут вопрос в цене. 8 Н/м момент нужен, сервопривод с такими параметрами ну дофига стоит + драйвер, в моем варианте выходит раза в три дешевле. И грузоподъемность около 200 кг.
Вложения
Render 4.png
Вот такая конструкция
Render 4.png (1.13 МБ) Просмотров: 11643
Я тупой...., я очень тупой.
Аватара пользователя
deadlymanager
Новичок
 
Сообщения: 18
Зарегистрирован: 30 июн 2019, 10:04
Откуда: Красноярск, Россия
Благодарил (а): 3 раз.
Поблагодарили: 12 раз.
Баллы репутации: 15
Новичок

Re: Новейшая прошивка для Arduino.

Сообщение deadlymanager » 11 июл 2019, 08:27

Подключил к ардуинно мега 2560. Отрабатывает на ура. Мож кому понадобится. Вот такой код. Изменений не много, за основу взял код от Ale.
Код: Выделить всё
#include <AccelStepper.h>
#define MOTOR1_DIR_PIN  3
#define MOTOR1_STEP_PIN 2
#define MOTOR1_ENABLE_PIN 4
#define MOTOR1_SPR 400  // Кол-во шагов на 1 оборот вала двигателя
int DataValueR=0; //middle position 0-255
int DataValueL=0;

AccelStepper stpMotor1(AccelStepper::DRIVER, MOTOR1_STEP_PIN, MOTOR1_DIR_PIN);
void setup()
{     
  Serial.begin(57600);
  phInit();
  }
 
void phInit()
{
    pinMode(MOTOR1_DIR_PIN, OUTPUT);
    pinMode(MOTOR1_STEP_PIN, OUTPUT);
    stpMotor1.setAcceleration(10000);
    stpMotor1.setMaxSpeed(100000);
    stpMotor1.setCurrentPosition(DataValueR);
   

    return;
}

////////////////////////////////////////////////////////////////////////////////
// Procedure: wait for complete trame
////////////////////////////////////////////////////////////////////////////////
void readSerialData()
{
  char 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]=='R'){
      Data[1]=Serial.read();
      Data[2]=Serial.read();
      //  call the function that converts the hexa in decimal and maps the range
      DataValueR=hex_to_uchar(Data);
      }
       if (Data[0]=='L'){
      Data[1]=Serial.read();
      Data[2]=Serial.read();
      //  call the function that converts the hexa in decimal and maps the range
      DataValueL=hex_to_uchar(Data);
    }
  }
  if (Serial.available()>16)  Serial.flush();
}

////////////////////////////////////////////////////////////////////////////////
// Function: convert Hex to Dec
////////////////////////////////////////////////////////////////////////////////
unsigned char hex_to_uchar(char x[3])
{
register unsigned char uc1,uc2;
    uc1=(x[1] - '0');
    if (uc1>9) uc1-=7;
    uc2=(x[2] - '0');
    if (uc2>9) uc2-=7;
    return ((uc1<<4) | uc2 );               
}

static char tab[] = "0123456789ABCDEF";
char *byte_to_hex(byte b)
{
  char ss[3];
 
  ss[0]= tab[b>>4];
  ss[1]= tab[b & 0x0F];
  ss[2]= 0;
  return ss;
}


void loop() {
 readSerialData();
 stpMotor1.moveTo(DataValueR*20);
stpMotor1.run();
}

Пока кручу один двигатель. SimTools отрабатывает на 5 баллов. Двигатели имеют замкнутую петлю. То есть двигатель в принципе шаги не пропускает, комплектный драйвер имеет выходы для считывания данных в контроллер с энкодера. Я его не задействовал вообще. Хотя можно. В программе stpMotor1.moveTo(DataValueR*20); 20 - это коэффициент редуктора.
Я тупой...., я очень тупой.
Аватара пользователя
deadlymanager
Новичок
 
Сообщения: 18
Зарегистрирован: 30 июн 2019, 10:04
Откуда: Красноярск, Россия
Благодарил (а): 3 раз.
Поблагодарили: 12 раз.
Баллы репутации: 15
Новичок

Re: Новейшая прошивка для Arduino.

Сообщение deadlymanager » 12 июл 2019, 14:59

Еще вопрос. Скажите люди знающие, где можно найти норм описание SimTools. Я уже башку сломал как ее настроить. Нормальной инструкции видимо в природе нет. Ну или объясните мне тупому, как 6 осей прописать и куда?
Я тупой...., я очень тупой.
Аватара пользователя
deadlymanager
Новичок
 
Сообщения: 18
Зарегистрирован: 30 июн 2019, 10:04
Откуда: Красноярск, Россия
Благодарил (а): 3 раз.
Поблагодарили: 12 раз.
Баллы репутации: 15
Новичок

Re: Новейшая прошивка для Arduino.

Сообщение green » 16 июл 2019, 10:36

Задачка еще та. Мне его сделать было проще, чем настраивать. Ищи похожий по кинематике и смотри, как у них, но лучше сразу системно разобраться в принципах. Чтоб абы-как дергался-не вопрос, а вот чтоб похоже на реал стало(особенно, под чьи-то субьективные требования) - там повозится прийдется. ЗЫ. Юзер мануал в пдф на английском, качать, переводить. Там по осям достаточно https://simtools.us/wp-content/uploads/ ... l-v2.4.pdf
Аватара пользователя
green
Зашел на огонёк
 
Сообщения: 9
Зарегистрирован: 06 июл 2019, 01:11
Откуда: Одесса
Благодарил (а): 3 раз.
Поблагодарили: 2 раз.
Баллы репутации: 0

Re: Новейшая прошивка для Arduino.

Сообщение Death_Morozz » 16 июл 2019, 19:24

deadlymanager писал(а):Еще вопрос. Скажите люди знающие, где можно найти норм описание SimTools. Я уже башку сломал как ее настроить. Нормальной инструкции видимо в природе нет.

Ну на форуме же есть документация на русском!
Хочешь сделать хорошо - сделай это сам.
Изображение
Аватара пользователя
Death_Morozz
Фраерок
 
Сообщения: 2839
Зарегистрирован: 11 янв 2007, 23:35
Откуда: Ростов-на-Дону
Благодарил (а): 822 раз.
Поблагодарили: 312 раз.
Баллы репутации: 200
ТехнарьТехнарьТехнарь

Re: Новейшая прошивка для Arduino.

Сообщение deadlymanager » 17 июл 2019, 07:14

Death_Morozz писал(а):
deadlymanager писал(а):Еще вопрос. Скажите люди знающие, где можно найти норм описание SimTools. Я уже башку сломал как ее настроить. Нормальной инструкции видимо в природе нет.

Ну на форуме же есть документация на русском!

Я прочитал этот краткий мануальчик, всё что там написано я уже опытным путем изучил. А вот English вариант - вот то что надо. Спасибо.
Я тупой...., я очень тупой.
Аватара пользователя
deadlymanager
Новичок
 
Сообщения: 18
Зарегистрирован: 30 июн 2019, 10:04
Откуда: Красноярск, Россия
Благодарил (а): 3 раз.
Поблагодарили: 12 раз.
Баллы репутации: 15
Новичок

Re: Новейшая прошивка для Arduino.

Сообщение deadlymanager » 20 авг 2019, 14:21

Как картинку вставить в текст, забыл что-то. Хотел показать процесс
Я тупой...., я очень тупой.
Аватара пользователя
deadlymanager
Новичок
 
Сообщения: 18
Зарегистрирован: 30 июн 2019, 10:04
Откуда: Красноярск, Россия
Благодарил (а): 3 раз.
Поблагодарили: 12 раз.
Баллы репутации: 15
Новичок

Re: Новейшая прошивка для Arduino.

Сообщение deadlymanager » 20 авг 2019, 16:10

[img]http://127.0.0.1/Users/PaulKhalter/Desktop/photo_2019-08-20_17-53-05.jpg[/img]
Я тупой...., я очень тупой.
Аватара пользователя
deadlymanager
Новичок
 
Сообщения: 18
Зарегистрирован: 30 июн 2019, 10:04
Откуда: Красноярск, Россия
Благодарил (а): 3 раз.
Поблагодарили: 12 раз.
Баллы репутации: 15
Новичок

Re: Новейшая прошивка для Arduino.

Сообщение deadlymanager » 25 авг 2019, 08:49

Вот так идет процесс. Запрограммировал обратную кинематику. Теперь в зависимости от данных, получаемых из SimTools, редуктора шести моторов поворачиваются на рассчитанный угол. Скорость обработки одного цикла расчета 3 миллисекунды на все 6 моторов. Ход плеча 110 градусов. Arduino Mega это реально МЕГА!!!
Вложения
photo_2019-08-25_12-43-17.png
Вот как то так
photo_2019-08-25_12-43-17.png (1.44 МБ) Просмотров: 11339
Я тупой...., я очень тупой.
Аватара пользователя
deadlymanager
Новичок
 
Сообщения: 18
Зарегистрирован: 30 июн 2019, 10:04
Откуда: Красноярск, Россия
Благодарил (а): 3 раз.
Поблагодарили: 12 раз.
Баллы репутации: 15
Новичок

Пред.След.

Вернуться в X-SIMULATOR и RU-SIMULATOR & SimTools

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19

cron
x

#{title}

#{text}