Детская машинка из гироскутера с ppm управлением

Автор fedy, 13 Июль 2019 в 19:22

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

fedy

Все доброго дня.
Собираю детский багги. Привод задний - гироскутер.



Прошивку для родной платы гироскутера взял тут:
https://github.com/NiklasFauth/hoverboard-firmware-hack
Решил делать управление на arduino. Она же делает сигнал ppm.
Пример кода взял здесь:
https://www.rcgroups.com/forums/showthread.php?2037080-DIY-Arduino-joystick-to-PPM
Все отлично работает. Только максимальная скорость около 7км/ч.
Нужна помошь, можно ли в прошивке увеличить максимальную скорость при ppm управлении?

verial

Можно у меня 40 прет и это на 50% задушена.
выложите сюда полностью свою программу подскажу.
Каждый человек индивидум оставьте его в этом состоянии.

fedy

#2
#define NB_WAY 2 // number of ways
#define LOW_LENGTH 100 // How long last (in µs) a low between 2 pulses
#define MIN_PPM_PULSE 1300 // 1300 minimum pulse length in µs
#define PPM_PULSE_LENGTH 700 //700 how much more µs will last the max pulse length
#define PACKET_LENGTH 21000 //21000, How long (µs) last a full trame
// trame length is fixed ! Every trame will make PACKET_LENGTH µs !
// MUST NO BE MORE THAN 32ms !!! (timer's prescaler constraint)

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // зеленый!          set the LCD address to 0x20 for a 16 chars and 2 line display

#define PPM_OUTPUT 13 // OUTPUT PIN

int way_value[NB_WAY];
int way_pin[NB_WAY];
int way_min[NB_WAY];
int way_max[NB_WAY];

int i = 0;
int p = 0; // temp var for duty cycle calculation
int bal = 1390; // балансировка колес
int vol = 1400; // скорость
int torm = 0; // назад/тормоз
int last_i_timer = 0; // last way's value sent through PPM signal
unsigned long int trame_elapsed_time = 0;
bool output_state = LOW;


void setup() {
  Serial.begin(115200);
  Serial.println("ppm_motors");
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);

  // ppm output :
  pinMode(PPM_OUTPUT, OUTPUT);
  digitalWrite(PPM_OUTPUT, output_state);

  // inits arrays
  for (i = 0; i < NB_WAY; i++)
  {
    way_pin[i] = 14 + i;
    pinMode(way_pin[i], INPUT);
    way_value[i] = analogRead(way_pin[i]);
    way_min[i] = way_value[i];
    way_max[i] = way_value[i];
  }

  // init timer
  cli();          // desactivation interruptions
  TCCR1A = 0x00;  // set timer1 registers to 0
  TCCR1B = 0x00;
  TIMSK1 = 0x00;

  OCR1A = 65535;// set to the max
  // CTC mode:
  TCCR1B |= (1 << WGM12);
  // prescaler to 8, that allow (@16mhz) 32.8ms trame
  TCCR1B |= (0 << CS10);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (0 << CS12);
  // timer activation
  TIMSK1 |= (1 << OCIE1A);
  sei();
  lcd.init();     // initialize the lcd
  lcd.backlight();
  lcd.print("---ppm---");
  delay(1000);
  lcd.clear();
}

ISR(TIMER1_COMPA_vect)
{
  TIMSK1 &= (0 << OCIE1A);
  if (output_state)
  { // END OF A HIGH, we have to wait LOW_LENGTH ms before next pulse
    output_state = LOW;
    digitalWrite(PPM_OUTPUT, output_state);
    OCR1A = 2 * LOW_LENGTH; // set when next timer interruption will occur
    TIMSK1 |= (1 << OCIE1A);  // restart timer
    trame_elapsed_time += LOW_LENGTH;
  }
  else
  { // END of a LOW_LENGTH, new pulse !
    output_state = HIGH;
    digitalWrite(PPM_OUTPUT, output_state);
    if (last_i_timer >= NB_WAY) // last way, so wait until next packet
    {
      OCR1A = (2 * PACKET_LENGTH) - (trame_elapsed_time * 2);// set when next timer interruption will occur
      TIMSK1 |= (1 << OCIE1A); // restart timer
      last_i_timer = 0;
      trame_elapsed_time = 0;
    }
    else
    {
      OCR1A = 2 * way_value[last_i_timer];// set when next timer interruption will occur
      TIMSK1 |= (1 << OCIE1A); // restart timer
      last_i_timer ++;
      trame_elapsed_time += way_value[NB_WAY];
    }
  }
}


void loop() {
  v_lcd();

  bal = analogRead(A0);
  vol = analogRead(A1);
  torm = analogRead(A2);

  // баланс между колес
  way_value[0] = map(bal, 0, 1023, 1300, 1500); //  1395 +- 500

  // скорость
  way_value[1] = map(vol, 788, 120, 1395, 1950); // 800 мин и 2000 макс (1100 медленный назад)

  // на a1 менее 535 включается задний ход
  // 1385 стоп. 1950 полный ход

  // педаль тормоза
  if (torm < 800) {
    way_value[1] = map(torm, 800, 160, 1350, 1100);
  }

}


void v_lcd()
{
  lcd.setCursor(0, 0);  lcd.print(bal);  lcd.print(" ");
  lcd.setCursor(0, 1);  lcd.print(vol);  lcd.print(" ");
  lcd.setCursor(7, 0);  lcd.print(way_value[0]);  lcd.print(" ");
  lcd.setCursor(7, 1);  lcd.print(way_value[1]);   lcd.print(" ");
}



fedy

код формирования ppm не мой. взял по ссылке выше.
при way_value[1] = 1395, моторы не крутятся. стоим.
от 1395 до 1950, едем вперед, 1950 макс скорость, при выше 1950 моторы останавливаются.
от 1395 и ниже до 1100, задняя скорость, едем назад. 800 минимум, далее моторы останавливаются.

verial

Скетч битый не запускается
'NB_WAY' was not declared in this scope
поточнее выложите.
Каждый человек индивидум оставьте его в этом состоянии.

fedy

У меня все норм.
плата: arduino pro mini
Рабочий код взял здесь: https://www.rcgroups.com/forums/showthread.php?2037080-DIY-Arduino-joystick-to-PPM

вот копипаст:
#define NB_WAY 6 // number of ways
#define LOW_LENGTH 300 // How long last (in µs) a low between 2 pulses
#define MIN_PPM_PULSE 1300 // minimum pulse length in µs
#define PPM_PULSE_LENGTH 700 // how much more µs will last the max pulse length
#define PACKET_LENGTH 21000 // How long (µs) last a full trame

// trame length is fixed ! Every trame will make PACKET_LENGTH µs !
// MUST NO BE MORE THAN 32ms !!! (timer's prescaler constraint)

#define PPM_OUTPUT 13 // OUTPUT PIN

int way_value[NB_WAY];
int way_pin[NB_WAY];
int way_min[NB_WAY];
int way_max[NB_WAY];

int i = 0;
int p = 0; // temp var for duty cycle calculation
int last_i_timer = 0; // last way's value sent through PPM signal
unsigned long int trame_elapsed_time = 0;
bool output_state = LOW;

void setup() {
  // ppm output :
  pinMode(PPM_OUTPUT, OUTPUT);
  digitalWrite(PPM_OUTPUT, output_state);
 
  // inits arrays
  for(i=0;i<NB_WAY;i++)
  {
    way_pin[i] = 14 + i;
    pinMode(way_pin[i], INPUT);
    way_value[i] = analogRead(way_pin[i]);
    way_min[i] = way_value[i];
    way_max[i] = way_value[i];
  }

  // init timer
  cli();          // desactivation interruptions
  TCCR1A = 0x00;  // set timer1 registers to 0
  TCCR1B = 0x00;     
  TIMSK1 = 0x00;
   
  OCR1A = 65535;// set to the max
    // CTC mode:
  TCCR1B |= (1 << WGM12);
    // prescaler to 8, that allow (@16mhz) 32.8ms trame
  TCCR1B |= (0 << CS10);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (0 << CS12);
    // timer activation
  TIMSK1 |= (1 << OCIE1A);
  sei();
}

ISR(TIMER1_COMPA_vect)
{
  TIMSK1 &= (0 << OCIE1A);
  if(output_state)
  { // END OF A HIGH, we have to wait LOW_LENGTH ms before next pulse
    output_state = LOW;
    digitalWrite(PPM_OUTPUT, output_state);
    OCR1A = 2 * LOW_LENGTH; // set when next timer interruption will occur
    TIMSK1 |= (1 << OCIE1A);  // restart timer
    trame_elapsed_time += LOW_LENGTH;
  }
  else
  { // END of a LOW_LENGTH, new pulse !
    output_state = HIGH;
    digitalWrite(PPM_OUTPUT, output_state);
    if(last_i_timer >= NB_WAY) // last way, so wait until next packet
    {
      OCR1A = (2 * PACKET_LENGTH) - (trame_elapsed_time * 2);// set when next timer interruption will occur
      TIMSK1 |= (1 << OCIE1A); // restart timer
      last_i_timer = 0;
      trame_elapsed_time = 0;
    }
    else
    {
      OCR1A = 2 * way_value[last_i_timer];// set when next timer interruption will occur
      TIMSK1 |= (1 << OCIE1A); // restart timer
      last_i_timer ++;
      trame_elapsed_time += way_value[NB_WAY];
    }
  } 
}


void loop() {

  for(i=0;i<NB_WAY;i++)
  {
     // Read current value of way i :
     p = analogRead(way_pin[i]);
     
     // auto calibration...
     if(p > way_max[i]) way_max[i] = p;
     if(p < way_min[i]) way_min[i] = p;
     
     // Arduino map function sucks
      way_value[i] = MIN_PPM_PULSE + PPM_PULSE_LENGTH * (float)((float)(p - way_min[i]) / (float)(way_max[i] - way_min[i]));
  }
}


verial

возьмите прошивку от Виктора_7 там не надо ардуино там все на прямую сделано и идет она 25 км.час
Каждый человек индивидум оставьте его в этом состоянии.

fedy

чтобы не забыть:

Цитата: ЭФЭ от 15 Июль 2019 в 10:51
Исходники автор любезно предоставил в 24 -й странице "Трайк из колёс от гироскутера" в разделе Детский электротранспорт. https://electrotransport.ru/index.php?msg=1619095
С накатом и без тормоза https://electrotransport.ru/index.php?msg=1619835

fedy

Прошивку от Виктора скомпилил под ppm
ссылка на скачку  https://yadi.sk/d/FkHjPBggSV2OIw
Обороты выросли значительно. :)

Измерить обороты колеса не могу. Раньше пользовался таким приложением, которое считает обороты ротора rc вертолета по микрофону. Думаю, что так же можно померить обороты колеса по щелчку приклеенной бумажке(и).
Не моу найти, может кто знает? Подскажите пожалуйста!

fedy

нашел интересное приложение:
https://play.google.com/store/apps/details?id=lt.magneticcounter&hl=ru

приклеиваем магнитик к колесу и телефоном мерим его обороты :)

старая прошивка 10км/ч.
прошивка от Виктора, максимальные обороты колеса 425 об/мин. получается примерно скорость 20км/ч, т.е. в два раза быстрее.



fedy

Цитата: Александр91 от 20 Июль 2019 в 19:56
Всем привет! Помогите пожалуйста найти прошивку для гироскутера, управление чтоб было с джойстиком, при этом можно было использовать ардуино и настроить параметры под инвалидную коляску. С возможностью использовать дисплей по i2c шине. Буду очень благодарен. Не могу найти прошивку рабочую со скетчем =( Я в первые проект делаю.строго не судите. Плата стандартная джойстик ардуиновский.
как прошить плату гироскутера знаете?

verial

#11
Прошивка работающая по uart  не стабильна очень много глюков.

Добавлено 21 Июл 2019 в 10:10

Цитата: fedy от 16 Июль 2019 в 10:28
У меня все норм.
плата: arduino pro mini
Рабочий код взял здесь: https://www.rcgroups.com/forums/showthread.php?2037080-DIY-Arduino-joystick-to-PPM

вот копипаст:
#define NB_WAY 6 // number of ways
#define LOW_LENGTH 300 // How long last (in µs) a low between 2 pulses
#define MIN_PPM_PULSE 1300 // minimum pulse length in µs
#define PPM_PULSE_LENGTH 700 // how much more µs will last the max pulse length
#define PACKET_LENGTH 21000 // How long (µs) last a full trame

// trame length is fixed ! Every trame will make PACKET_LENGTH µs !
// MUST NO BE MORE THAN 32ms !!! (timer's prescaler constraint)

#define PPM_OUTPUT 13 // OUTPUT PIN

int way_value[NB_WAY];
int way_pin[NB_WAY];
int way_min[NB_WAY];
int way_max[NB_WAY];

int i = 0;
int p = 0; // temp var for duty cycle calculation
int last_i_timer = 0; // last way's value sent through PPM signal
unsigned long int trame_elapsed_time = 0;
bool output_state = LOW;

void setup() {
  // ppm output :
  pinMode(PPM_OUTPUT, OUTPUT);
  digitalWrite(PPM_OUTPUT, output_state);
 
  // inits arrays
  for(i=0;i<NB_WAY;i++)
  {
    way_pin[i] = 14 + i;
    pinMode(way_pin[i], INPUT);
    way_value[i] = analogRead(way_pin[i]);
    way_min[i] = way_value[i];
    way_max[i] = way_value[i];
  }

  // init timer
  cli();          // desactivation interruptions
  TCCR1A = 0x00;  // set timer1 registers to 0
  TCCR1B = 0x00;     
  TIMSK1 = 0x00;
   
  OCR1A = 65535;// set to the max
    // CTC mode:
  TCCR1B |= (1 << WGM12);
    // prescaler to 8, that allow (@16mhz) 32.8ms trame
  TCCR1B |= (0 << CS10);
  TCCR1B |= (1 << CS11);
  TCCR1B |= (0 << CS12);
    // timer activation
  TIMSK1 |= (1 << OCIE1A);
  sei();
}

ISR(TIMER1_COMPA_vect)
{
  TIMSK1 &= (0 << OCIE1A);
  if(output_state)
  { // END OF A HIGH, we have to wait LOW_LENGTH ms before next pulse
    output_state = LOW;
    digitalWrite(PPM_OUTPUT, output_state);
    OCR1A = 2 * LOW_LENGTH; // set when next timer interruption will occur
    TIMSK1 |= (1 << OCIE1A);  // restart timer
    trame_elapsed_time += LOW_LENGTH;
  }
  else
  { // END of a LOW_LENGTH, new pulse !
    output_state = HIGH;
    digitalWrite(PPM_OUTPUT, output_state);
    if(last_i_timer >= NB_WAY) // last way, so wait until next packet
    {
      OCR1A = (2 * PACKET_LENGTH) - (trame_elapsed_time * 2);// set when next timer interruption will occur
      TIMSK1 |= (1 << OCIE1A); // restart timer
      last_i_timer = 0;
      trame_elapsed_time = 0;
    }
    else
    {
      OCR1A = 2 * way_value[last_i_timer];// set when next timer interruption will occur
      TIMSK1 |= (1 << OCIE1A); // restart timer
      last_i_timer ++;
      trame_elapsed_time += way_value[NB_WAY];
    }
  } 
}


void loop() {

  for(i=0;i<NB_WAY;i++)
  {
     // Read current value of way i :
     p = analogRead(way_pin[i]);
     
     // auto calibration...
     if(p > way_max[i]) way_max[i] = p;
     if(p < way_min[i]) way_min[i] = p;
     
     // Arduino map function sucks
      way_value[i] = MIN_PPM_PULSE + PPM_PULSE_LENGTH * (float)((float)(p - way_min[i]) / (float)(way_max[i] - way_min[i]));
  }
}


Вы на свою ардуино ставили 3.3 преобразователь?
Каждый человек индивидум оставьте его в этом состоянии.

fedy


fedy

#13
Цитата: verial от 16 Июль 2019 в 16:36
возьмите прошивку от Виктора_7 там не надо ардуино там все на прямую сделано и идет она 25 км.час
идет да быстрее, но при резком нажатии на газ, сгорели транзисторы (

вывод такой, машинку надо делать меньше и легче. и самому не ездить (80кг). тогда возможно и поедет нормально.  :bw:
хотя мне кажется моторы гироскутера должны легко выдавать больше мощности. или я чтото делаю не так.
Народ! кто нибудь делал подобное? если у вас едет нормально, напишите плс сюда или в личку! обьясните мне, как? что бы ехало!

verial

#14
https://www.youtube.com/watch?v=GHcGzDb4cP4
трицикл с прошивкой от Виктора 7 на последней 4й скорости.
Каждый человек индивидум оставьте его в этом состоянии.

fedy

а что так воют моторы? это не правильно
такое у меня было когда перепутанны датчики холла. или перепутал обмотки (относительно датчиков)
я так делал на эл велосипеде. если не правильно подключить мотор. и получаем: сильный вой моторов на старте, плохую тягу на старте, но когда разгонишься, начинает ехать быстрее штатного и вой пропадает. но так ездить не возможно. вибразия и вой это не правильно

fedy

планирую поднять напряжение до 50 вольт (12s li-po). что должно повысить скорость при таком же токе.
на гироскутерной плате стоят кондеры на 63 вольта. норм.
можно поменять кондеры на 100в. и дать напрядение: две гироскутерных батареи включенне последовательно. т.е. 84 вольта )

verial

Каждый человек индивидум оставьте его в этом состоянии.