Инвалидная коляска и гироскутер с дисплеем и джойстиком.

Автор Александр91, 22 Июль 2019 в 12:03

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

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

Александр91

Всем привет!
Появился проект "Инвалидная коляска и гироскутер с джойстиком"
На порту сейчас имею прошитую уже плату от темы  https://electrotransport.ru/index.php?topic=59293.new#new
Есть дисплей 128х64 oled i2c.
Джойстик для проектов Ардуино.
Плата Arduino Uno.
Залил скетч на uno, подключил к плате и у меня автоматически запустились двигатели на гироскутере. Используя 13 пин на Uno, зеленый провод от гироскутера и землю. Подключил джойстик из темы, на A0, A1. Джойстик не реагировал совсем. Питание правда для теста использовал от пк на ардуино.
Что я делаю не так? =( Помогите ребят. смотрел много тем на данную тематику. Не чего не мог найти нормально =(

verial

#1

а dc/dc преобразователь с 5 вольт в 3 вольта поставили на uart дело в том что rx tx на stm32 3.3 вольта а арда дает все 5 вольт?
Каждый человек индивидум оставьте его в этом состоянии.

Александр91

Цитата: verial от 22 Июль 2019 в 12:21
а dc/dc преобразователь с 5 вольт в 3 вольта поставили на uart дело в том что rx tx на stm32 3.3 вольта а арда дает все 5 вольт?
Да, я подключал пока от пк. Там 5 вольт.можно же использовать 3.3 вольта от разъема для прошивки. но куда его на ардуино подключать? в какой пин?

verial

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

Александр91


verial

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

Александр91

Цитата: verial от 22 Июль 2019 в 12:35
вы ее конфигурировали под uart или взяли так по умолчанию?
и скиньте сюда ваш скетч.
по умолчанию
#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(" ");
}


verial

там в конфиге есть строчка : //#define CONTROL_SERIAL_USART2       // left sensor board cable, disable if ADC or PPM is used! там надо убрать // что бы работал uart/
Каждый человек индивидум оставьте его в этом состоянии.

Александр91

Цитата: verial от 22 Июль 2019 в 12:40
там в конфиге есть строчка : //#define CONTROL_SERIAL_USART2       // left sensor board cable, disable if ADC or PPM is used! там надо убрать // что бы работал uart/
Можешь пожалуйста скинуть готовую прошивку. Буду очень признателен.

verial

#9
дело в том что у них щаз программа работает с тремя видами управления нунчаки, ppm и аналог.
они щаз переделывают uart в другой протокол и я тоже завис с ихнем управлением.
Каждый человек индивидум оставьте его в этом состоянии.

Александр91

#10
Цитата: verial от 22 Июль 2019 в 12:46
дело в том что у них щаз программа работает с тремя видами управления нунчаки, ppm и аналог.
они щаз переделывают uarn в другой протокол и я тоже завис с ихнем управлением.
А есть прошивка где будет просто работать джойстик без ардуино с выполнением поворотов, назад и вперед?  мне надо с ppm

verial

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

Александр91

Цитата: verial от 22 Июль 2019 в 13:01
Есть, работает только от ppm вам подойдет?
да=) и схему подключения и скетч, если у вас свой.

ЭФЭ


verial

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

verial

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

ЭФЭ


fedy

#17
Цитата: Александр91 от 22 Июль 2019 в 12:36
по умолчанию
#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(" ");
}



если использовать данный скетч. он под ppm
то и прошивку в гироскутер надо делать под ppm
вот:

// ############################### INPUT ###############################

// ###### CONTROL VIA UART (serial) ######
//#define CONTROL_SERIAL_USART2       // left sensor board cable, disable if ADC or PPM is used!
//#define CONTROL_BAUD       19200    // control via usart from eg an Arduino or raspberry
// for Arduino, use void loop(void){ Serial.write((uint8_t *) &steer, sizeof(steer)); Serial.write((uint8_t *) &speed, sizeof(speed));delay(20); }

// ###### CONTROL VIA RC REMOTE ######
// left sensor board cable. Channel 1: steering, Channel 2: speed.
#define CONTROL_PPM                 // use PPM-Sum as input. disable CONTROL_SERIAL_USART2!
#define PPM_NUM_CHANNELS 2          // total number of PPM channels to receive, even if they are not used.

// ###### CONTROL VIA TWO POTENTIOMETERS ######
// ADC-calibration to cover the full poti-range: connect potis to left sensor board cable (0 to 3.3V) (do NOT use the red 15V wire in the cable!). see <How to calibrate>. turn the potis to minimum position, write value 1 to ADC1_MIN and value 2 to ADC2_MIN. turn to maximum position and repeat it for ADC?_MAX. make, flash and test it.
//#define CONTROL_ADC                 // use ADC as input. disable CONTROL_SERIAL_USART2!
//#define ADC1_MIN 0                // min ADC1-value while poti at minimum-position (0 - 4095)
//#define ADC1_MAX 4095               // max ADC1-value while poti at maximum-position (0 - 4095)
//#define ADC2_MIN 0                // min ADC2-value while poti at minimum-position (0 - 4095)
//#define ADC2_MAX 4095               // max ADC2-value while poti at maximum-position (0 - 4095)

// ###### CONTROL VIA NINTENDO NUNCHUCK ######
// left sensor board cable. keep cable short, use shielded cable, use ferrits, stabalize voltage in nunchuck, use the right one of the 2 types of nunchucks, add i2c pullups. use original nunchuck. most clones does not work very well.
//#define CONTROL_NUNCHUCK            // use nunchuck as input. disable DEBUG_SERIAL_USART3!


(вчера дал не тот пример, поправил)