roboforum.ru

Технический форум по робототехнике.

Arduino Nano + джойстик PS2 = не печатает в UART

Arduino Nano + джойстик PS2 = не печатает в UART

dccharacter » 21 янв 2011, 16:40

Ребята, помогайте.

Есть Ардуино Нано (купленное у Семенова Михаила, первая, судя по всему, версия). Есть джойстик для PS2, судя по всему неофициальный, на морде название 32BIT.

Есть библиотека и скетч-пример: http://www.billporter.info/playstation-2-controller-arduino-library-v1-0/

Проблема - в терминале Arduino IDE печатает лишь часть информации, часть теряется или превращается в мусор.

Подробности:
1. От скорости USART не зависит - менял в диапазоне от 9600 до 57600
2. Те сообщения, которые выводятся модулем-библиотекой печатаются нормально, в частности если включить дебаг-режим, то все команды/ответы от джойстика выводятся на терминал.
3. Заголовочные строки из библиотеки тоже выводятся нормально, например Serial.println("Reading controller type"); печатаются ОК. Однако большинство команд печати работают в библиотеке все-таки с небольшими строками длиной в два-три байта.
4. Сообщения, которые выводятся кодом, расположенном в файле скетча, могут выводится частично (начало строки, середина строки, конец строки - в зависимости от положения инструкции в файле) или полностью (например, выводятся только две из 4-х строк, команды на вывод идут одна за одной).
5. Поведение воспроизводится, т.е. не по рандому там что-то пропало, что-то напечаталось, а одинаковая картина после перезагрузки/перезаливке скетча.
6. Насколько я могу судить, прерывания в скетче не используются.
7. Теряются, например, строки, которые находятся вне инструкций взаимодействия с контроллером в теле config-a борды.

Итак, вопрос - что происходит? :-)

Re: Arduino Nano + джойстик PS2 = не печатает в UART

=DeaD= » 21 янв 2011, 16:44

Если у Семёнова, то там скорее всего наша ORduino Nano.
А где сам скетч на котором такие косяки?

Re: Arduino Nano + джойстик PS2 = не печатает в UART

dccharacter » 21 янв 2011, 16:59

Там же в БЫБЛИОТЕКЕ: http://www.billporter.info/playstation- ... rary-v1-0/

Код: Выделить всёРазвернуть
#include <PS2X_lib.h>  //for v1.6

PS2X ps2x; // create PS2 Controller Class

//right now, the library does NOT support hot pluggable controllers, meaning
//you must always either restart your Arduino after you conect the controller,
//or call config_gamepad(pins) again after connecting the controller.
int error = 0;
byte type = 0;
byte vibrate = 0;

void setup(){
Serial.begin(57600);

//CHANGES for v1.6 HERE!!! **************PAY ATTENTION*************
 
error = ps2x.config_gamepad(13,11,10,12, true, true);   //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?) check for error

if(error == 0){
   Serial.println("Found Controller, configured successful");
   Serial.println("Try out all the buttons, X will vibrate the controller, faster as you press harder;");
  Serial.println("holding L1 or R1 will print out the analog stick values.");
  Serial.println("Go to www.billporter.info for updates and to report bugs.");
}
   
  else if(error == 1)
   Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
   
  else if(error == 2)
   Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
   
  else if(error == 3)
   Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
   
   //Serial.print(ps2x.Analog(1), HEX);
   
   type = ps2x.readType();
     switch(type) {
       case 0:
        Serial.println("Unknown Controller type");
       break;
       case 1:
        Serial.println("DualShock Controller Found");
       break;
       case 2:
         Serial.println("GuitarHero Controller Found");
       break;
     }
 
}

void loop(){
   /* You must Read Gamepad to get new values
   Read GamePad and set vibration values
   ps2x.read_gamepad(small motor on/off, larger motor strenght from 0-255)
   if you don't enable the rumble, use ps2x.read_gamepad(); with no values
   
   you should call this at least once a second
   */
   
   
   
if(error == 1) //skip loop if no controller found
  return;
 
if(type == 2){ //Guitar Hero Controller
   
   ps2x.read_gamepad();          //read controller
   
   if(ps2x.ButtonPressed(GREEN_FRET))
     Serial.println("Green Fret Pressed");
   if(ps2x.ButtonPressed(RED_FRET))
     Serial.println("Red Fret Pressed");
   if(ps2x.ButtonPressed(YELLOW_FRET))
     Serial.println("Yellow Fret Pressed");
   if(ps2x.ButtonPressed(BLUE_FRET))
     Serial.println("Blue Fret Pressed");
   if(ps2x.ButtonPressed(ORANGE_FRET))
     Serial.println("Orange Fret Pressed");
     

    if(ps2x.ButtonPressed(STAR_POWER))
     Serial.println("Star Power Command");
   
    if(ps2x.Button(UP_STRUM))          //will be TRUE as long as button is pressed
     Serial.println("Up Strum");
    if(ps2x.Button(DOWN_STRUM))
     Serial.println("DOWN Strum");
 

    if(ps2x.Button(PSB_START))                   //will be TRUE as long as button is pressed
         Serial.println("Start is being held");
    if(ps2x.Button(PSB_SELECT))
         Serial.println("Select is being held");

   
    if(ps2x.Button(ORANGE_FRET)) // print stick value IF TRUE
    {
        Serial.print("Wammy Bar Position:");
        Serial.println(ps2x.Analog(WHAMMY_BAR), DEC);
    }
}

else { //DualShock Controller
 
    ps2x.read_gamepad(false, vibrate);          //read controller and set large motor to spin at 'vibrate' speed
   
    if(ps2x.Button(PSB_START))                   //will be TRUE as long as button is pressed
         Serial.println("Start is being held");
    if(ps2x.Button(PSB_SELECT))
         Serial.println("Select is being held");
         
         
     if(ps2x.Button(PSB_PAD_UP)) {         //will be TRUE as long as button is pressed
       Serial.print("Up held this hard: ");
       Serial.println(ps2x.Analog(PSAB_PAD_UP), DEC);
      }
      if(ps2x.Button(PSB_PAD_RIGHT)){
       Serial.print("Right held this hard: ");
        Serial.println(ps2x.Analog(PSAB_PAD_RIGHT), DEC);
      }
      if(ps2x.Button(PSB_PAD_LEFT)){
       Serial.print("LEFT held this hard: ");
        Serial.println(ps2x.Analog(PSAB_PAD_LEFT), DEC);
      }
      if(ps2x.Button(PSB_PAD_DOWN)){
       Serial.print("DOWN held this hard: ");
     Serial.println(ps2x.Analog(PSAB_PAD_DOWN), DEC);
      }   
 
   
      vibrate = ps2x.Analog(PSAB_BLUE);        //this will set the large motor vibrate speed based on
                                              //how hard you press the blue (X) button   
   
    if (ps2x.NewButtonState())               //will be TRUE if any button changes state (on to off, or off to on)
    {
     
       
         
        if(ps2x.Button(PSB_L3))
         Serial.println("L3 pressed");
        if(ps2x.Button(PSB_R3))
         Serial.println("R3 pressed");
        if(ps2x.Button(PSB_L2))
         Serial.println("L2 pressed");
        if(ps2x.Button(PSB_R2))
         Serial.println("R2 pressed");
        if(ps2x.Button(PSB_GREEN))
         Serial.println("Triangle pressed");
         
    }   
         
   
    if(ps2x.ButtonPressed(PSB_RED))             //will be TRUE if button was JUST pressed
         Serial.println("Circle just pressed");
         
    if(ps2x.ButtonReleased(PSB_PINK))             //will be TRUE if button was JUST released
         Serial.println("Square just released");     
   
    if(ps2x.NewButtonState(PSB_BLUE))            //will be TRUE if button was JUST pressed OR released
         Serial.println("X just changed");   
   
   
    if(ps2x.Button(PSB_L1) || ps2x.Button(PSB_R1)) // print stick values if either is TRUE
    {
        Serial.print("Stick Values:");
        Serial.print(ps2x.Analog(PSS_LY), DEC); //Left stick, Y axis. Other options: LX, RY, RX 
        Serial.print(",");
        Serial.print(ps2x.Analog(PSS_LX), DEC);
        Serial.print(",");
        Serial.print(ps2x.Analog(PSS_RY), DEC);
        Serial.print(",");
        Serial.println(ps2x.Analog(PSS_RX), DEC);
    }
   
   
}


delay(50);
     
}


Добавлено спустя 4 минуты 28 секунд:
Хм....

* Если у вас ORduin Nano на ATMega88PA с частотой 14.7456МГц, тогда выберите "OR-duino (Nano) w/ ATmega88 @ 14.7456MHz";
* Если у вас ORduin Nano на ATMega168(V) с частотой 16МГц, тогда выберите "Arduino Diecimila, Duemilanove, or Nano w/ ATmega168";

А я ничего такого не делал. Я даже не знал, что у меня ОР-дуино. Ну, Анатолий. Ну погоди.

Так, а есть этот ТКСТ для 22 ИДЕ???

Re: Arduino Nano + джойстик PS2 = не печатает в UART

=DeaD= » 21 янв 2011, 16:59

Какой МК стоит на ORduino и какой кварц?
какие строки теряются, например, и что выдаёт при этом терминал?

Re: Arduino Nano + джойстик PS2 = не печатает в UART

dccharacter » 21 янв 2011, 17:19

Если правильно помню, то ATMega168(V)
Строки теряются я не понимаю по какому принципу

Например, код
Код: Выделить всёРазвернуть
type = readType();
Serial.println(type, HEX);
Serial.println(type, HEX);
Serial.println(type, HEX);
Serial.println(type, HEX);
Serial.println(type, HEX);
Serial.println("DualShock controller found");


Выведет
Код: Выделить всёРазвернуть
2
2
2
2


А код
Код: Выделить всёРазвернуть
Serial.println(type, HEX);
Serial.println(type, HEX);
Serial.println(type, HEX);
Serial.println(type, HEX);
Serial.println(type, HEX);
Serial.println("as123df");
Serial.println("DualShock controller found");


выведет
Код: Выделить всёРазвернуть
2
2
2
2
as123df
DualSho

Re: Arduino Nano + джойстик PS2 = не печатает в UART

=DeaD= » 21 янв 2011, 17:21

Сдаётся мне библиотека через буфер работает и он переполняется.
Скорость 115200 пробовали?

Re: Arduino Nano + джойстик PS2 = не печатает в UART

dccharacter » 21 янв 2011, 17:28

=DeaD= писал(а):Сдаётся мне библиотека через буфер работает и он переполняется.
Скорость 115200 пробовали?

Неа, не догадался. Уменьшал только.

Да, там есть буфер для значений состояний кнопок. Буфер - член класса PS2X. Но странно - если переполняется буфер для хранения состояний джойстика, то при чем тут ЮАРТ? Ресета платы не происходит, через какое-то время она, судя по всему оклимовывается и продолжает работать...

Потом, я специально делал много коротких строк подряд и одну длинную потом - длинную то теряет совсем, то режет до 8-ми, что ли символов. Иногда режет строку, что похоже на цензуру:
Код: Выделить всёРазвернуть
2
2
king thing doesn't wo
*^

Re: Arduino Nano + джойстик PS2 = не печатает в UART

blindman » 21 янв 2011, 17:30

Да, оченно похоже на переполнение буфера. Тем более что после рестарта картина всегда одинаковая. Но насколько я знаю, ардуиновские либы работают синхронно, без использования буфера

Re: Arduino Nano + джойстик PS2 = не печатает в UART

=DeaD= » 21 янв 2011, 17:41

По ходу я понял в чем дело.
Arduino IDE хранит все строки по умолчанию в RAM, а в МК ATMega168 её не так много. Видимо все не влезает и строки изначально битые.

Добавлено спустя 3 минуты 50 секунд:
Видимо только или строки урезать или во FLASH их выносить. Авторы Arduino IDE конечно могли бы и сами по умолчанию во флеш писать строки вида Serial.println("Hello, this is a very long debug message!"); :)

Re: Arduino Nano + джойстик PS2 = не печатает в UART

dccharacter » 21 янв 2011, 17:47

Хм, тогда бы все зависело от объема отладочной информации, а я такой зависимости не заметил.

А как в таких случаях производить отладку?

Добавлено спустя 3 минуты 21 секунду:
=DeaD= писал(а):Видимо только или строки урезать или во FLASH их выносить. Авторы Arduino IDE конечно могли бы и сами по умолчанию во флеш писать строки вида Serial.println("Hello, this is a very long debug message!"); :)

Как, простите, это сделать?
Объявить константы и их сливать в терминал??

Re: Arduino Nano + джойстик PS2 = не печатает в UART

avr123.nm.ru » 21 янв 2011, 17:57

dccharacter писал(а):Есть Ардуино Нано купленное у Семенова Михаила,
У Семенова Михаила были Arduino nano с кварцем 16 Мгц как родные кварцы ардуин. А значит UART может давать допустимые ошибки битрейта только на низких скоростях передачи.

Ошибку битрейта и ее допустимость можно посмотреть в мастете кода CVAVR - http://proavr.narod.ru/z5.htm

Из-за ошибки в битрейте у вас по ходу передачи теряется синхронизация.
Последний раз редактировалось avr123.nm.ru 21 янв 2011, 18:02, всего редактировалось 2 раз(а).

Re: Arduino Nano + джойстик PS2 = не печатает в UART

=DeaD= » 21 янв 2011, 18:00

dccharacter писал(а):Как, простите, это сделать?
Объявить константы и их сливать в терминал??

Вот тут есть адский пример :)
http://www.arduino.cc/en/Reference/PROGMEM
только его упрощать надо.

Добавлено спустя 14 секунд:
avr123.nm.ru писал(а):Из-за ошибки в битрейте у вас по ходу передачи теряется синхронизация.

Хм, а может и это :)

Re: Arduino Nano + джойстик PS2 = не печатает в UART

Myp » 21 янв 2011, 18:01

пользуйся поиском по форуму и не пользуйся стандартным терминалом ардуины :)
у меня тот же самый косяк был.

в обычный виндовый терминал ордуино с радостью сливает строки из 66 групп 2х значных чисел с разделителем и заголовком
тоесть в сумме 200 с лишним символов в строке по дёсятку строк в секунду.

ардуиновский терминал тормозит и пропускает
любой другой работает идеально

Re: Arduino Nano + джойстик PS2 = не печатает в UART

avr123.nm.ru » 21 янв 2011, 18:28

Мастер CVAVR показывает что при кварце 16 Мгц допустимы все стандартные битрейты UART до 56000 и отклонение не превышает 0.8 % а вот 57600 и выше уже не допустимо использовать.
Вложения
16_mhz_uart_til_56000.png

Re: Arduino Nano + джойстик PS2 = не печатает в UART

Dmitri Vladimirovich » 21 янв 2011, 21:51

Myp +1


Советую Terminal by Br@Y

Для меня самый оптимальный вариант. Еще лучше подобрать себе такую терминалку, чтобы она автоматически байты в порт отправляла, без нажатия Энтер


Rambler\'s Top100 Mail.ru counter