Go Down

Topic: Control Digital Servo with Logitech Extreme 3D Joystick Mega2560 + USB Shield (Read 1 time) previous topic - next topic

mhzcode

Hi.
I want to control a Digital servo with Logitech Extreme 3D Joystick with Arduino Mega2560 and USB Host Shield (Keyes - funduino).
My problem is , i can read data from joystick with usb host shield , but i cant send command to digital servo.
I think it is pin-conflict problem , but i don't know how to solve it.
Servo is connected to pin 9.

Here is my code:

Code: [Select]

#include <usbhid.h>
#include <hiduniversal.h>
#include <usbhub.h>
#include <Wire.h>


#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>
#endif

#include "hidjoystickrptparser.h"
#include <Servo.h>
USB Usb;
USBHub Hub(&Usb);
HIDUniversal Hid(&Usb);
JoystickEvents JoyEvents;
JoystickReportParser Joy(&JoyEvents);

Servo myservo;






void setup() {
  myservo.attach(9);
        Serial.begin(9600);
#if !defined(__MIPSEL__)
        while (!Serial);
#endif
        Serial.println("Start");

        if (Usb.Init() == -1)
                Serial.println("OSC did not start.");

        delay(200);

        if (!Hid.SetReportParser(0, &Joy))
                ErrorMessage<uint8_t > (PSTR("SetReportParser"), 1);
}


void loop() {
       Usb.Task();
      uint16_t val = map(JoystickEvents::mostRecentEvent.x,0,1023,0,180);
      Serial.println(val);
      myservo.write(val);
      delay(100);
}





CPP File for hidjoystick report parser:

Code: [Select]




#include "hidjoystickrptparser.h"


GamePadEventData JoystickEvents::mostRecentEvent;
byte xPin = 2;
JoystickReportParser::JoystickReportParser(JoystickEvents *evt) :
  joyEvents(evt)
{}

void JoystickReportParser::Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
{
  bool match = true;

  // Checking if there are changes in report since the method was last called
  for (uint8_t i=0; i<RPT_GAMEPAD_LEN; i++) {
    if( buf[i] != oldPad[i] ) {
      match = false;
      break;
    }
  }
    // Calling Game Pad event handler
  if (!match && joyEvents) {
    joyEvents->OnGamePadChanged((const GamePadEventData*)buf);

    for (uint8_t i=0; i<RPT_GAMEPAD_LEN; i++) oldPad[i] = buf[i];
  }
}


void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt)
{
  mostRecentEvent = *evt;
  uint16_t myX = evt->x;

  uint16_t myY = evt->y;

  uint16_t myT = evt->twist;
 
  Serial.print("X: ");
  PrintHex<uint16_t>(evt->x, 0x80);
  Serial.print(" Y: ");
  PrintHex<uint16_t>(evt->y, 0x80);
  Serial.print(" Hat Switch: ");
  PrintHex<uint8_t>(evt->hat, 0x80);
  Serial.print(" Twist: ");
  PrintHex<uint8_t>(evt->twist, 0x80);
  Serial.print(" Slider: ");
  PrintHex<uint8_t>(evt->slider, 0x80);
  Serial.print(" Buttons A: ");
  PrintHex<uint8_t>(evt->buttons_a, 0x80);
  Serial.print(" Buttons B: ");
  PrintHex<uint8_t>(evt->buttons_b, 0x80);
  Serial.println("");
    if(myX > 512){//you can do whatever you want with the myX,myY,and myT.
    digitalWrite(xPin,HIGH);//You can also use the buttons and the Z-axis.
  }
  else{
    digitalWrite(xPin,LOW);
  }

}



Header file:

Code: [Select]


#if !defined(__HIDJOYSTICKRPTPARSER_H__)
#define __HIDJOYSTICKRPTPARSER_H__

#include <usbhid.h>

struct GamePadEventData
{
  union { //axes and hut switch
    uint32_t axes;
    struct {
      uint32_t x : 10;
      uint32_t y : 10;
      uint32_t hat : 4;
      uint32_t twist : 8;     
    };
  };
  uint8_t buttons_a;
  uint8_t slider;
  uint8_t buttons_b;
};

class JoystickEvents
{
public:
  virtual void OnGamePadChanged(const GamePadEventData *evt);
  static GamePadEventData mostRecentEvent;
};

#define RPT_GAMEPAD_LEN sizeof(GamePadEventData)/sizeof(uint8_t)

class JoystickReportParser : public HIDReportParser
{
  JoystickEvents    *joyEvents;

  uint8_t oldPad[RPT_GAMEPAD_LEN];

public:
  JoystickReportParser(JoystickEvents *evt);

  virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
};

#endif // __HIDJOYSTICKRPTPARSER_H__



Servo works when i disable all codes related to USB Host ...

Thanks.!

mhzcode

After some debugging , i realized that the problem occurs only when myservo.write(val); called.Arduino LED not blinking after call anymore , and needs to unplug cable and plug it again.(Reset button doesn't have effect)

Otherwise , all things working perfectly.
I don't know

vinceherman

How are you supplying power to the servo?
Can you draw a wiring diagram and post it here?

mhzcode

How are you supplying power to the servo?
Can you draw a wiring diagram and post it here?
Servo power is from arduino itself.
I also tried using a 5v 1.5A USB Adapter but same problem.
Do you think that this problem occurs because of not-seperated power?
if so , i will try that tomorrow.

vinceherman

Servo power is from arduino itself.
This is your problem.

This is more like what you want.

xl97

^ agreed.

A servo can pull anywhere from 1amp+ under load!..

this is WAAAAAY more than any single Arduino pin can supply.. or even the whole Arduino board itself!

You need to power the servo from a separate power supply.... (and make sure ALL GNDS are connected)..

Outside of the +9v battery in the wiring diagram above.. everything looks legit to me!



bobby696


Go Up