USB Host...

Hello,

I have a question.
I bought a USB Host Shield because I want to control a relay card.
But how do I have to do that?
I have to send a few things but I don’t have any idea how to do that.
The documentation of this relay card (in English of course) is at: http://data.ljpc.nl/K8090_ProtocolManual.pdf

I hope you guys can help me.

Lars

K8090_ProtocolManual.pdf (164 KB)

It seems a rather complex way to control relays, the arduino is much more suited to controlling them directly. The problem with the USB shield is that most of the time you have to understand and write the software required and this is no easy task.

In your case you have to get the USB host to talk to a serial port. There might be examples of this already, I don't know.

When you do then that document tells you what package of bytes to send to it. So for example to turn on a relay (say relays 1, 2 and 8) the bits in the byte have to be set like this 1000 0011 which is hex 0x83. Then over the serial port you send the following bytes:- 0x04, 0x11, 0x83, 0x00, 0x00, 0x99, 0x0f where the 0x99 is the check sum as described in page 2

Okay, thanks. That is understandable :) But how do I send that to the shield?

In your case you have to get the USB host to talk to a serial port. There might be examples of this already, I don't know.

Try looking for examples on your USB shield that deal with serial communications.

This is the shield that I have: http://www.sparkfun.com/products/9947 And this is the code:

include "Spi.h"

include "Max3421e.h"

include "Usb.h"

include "Max_LCD.h"

/* Mail Notifier data taken from configuration descriptor */

define RELAY_ADDR 1

define RELAY_EP 1

define RELAY_IF 0

define EP_MAXPKTSIZE 8

define EP_POLL 0x0a

EP_RECORD ep_record[ 1 ]; //endpoint record structure for the Mail Notifier

MAX3421E Max; USB Usb; Max_LCD LCD;

void setup() { Serial.begin( 9600 ); Serial.println("Start"); Max.powerOn(); delay( 200 ); }

void loop() { Max.Task(); Usb.Task(); if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING ) { //wait for addressing state RELAY_init(); Usb.setUsbTaskState( USB_STATE_RUNNING ); } if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) { //poll the Mail Notifier RELAY_poll(); } } void RELAY_init( void ) { byte rcode = 0; //return code /* Initialize data structures / ep_record[ 0 ] = *( Usb.getDevTableEntry( 0,0 )); //copy endpoint 0 parameters ep_record[ 1 ].MaxPktSize = EP_MAXPKTSIZE; ep_record[ 1 ].Interval = EP_POLL; ep_record[ 1 ].sndToggle = bmSNDTOG0; ep_record[ 1 ].rcvToggle = bmRCVTOG0; Usb.setDevTableEntry( 1, ep_record ); //plug MailNotifier.endpoint parameters to devtable / Configure device / rcode = Usb.setConf( RELAY_ADDR, 0, 0x1F ); // byte addr, byte ep, byte conf_value, unsigned int nak_limit if( rcode ) { **Serial.print("Error attempting to configure keyboard. Return code :"); **Serial.println( rcode, HEX ); while(1); //stop } / Set boot protocol / rcode = Usb.setProto( RELAY_ADDR, 0, 0, 0 ); // byte addr, byte ep, byte interface, byte protocol, unsigned int nak_limit if( rcode ) { **Serial.print("Error attempting to configure boot protocol. Return code :"); **Serial.println( rcode, HEX ); while( 1 ); //stop } delay(2000); **Serial.println("Relay card initialized"); } / Poll Mail Notifier and update intensity colour / void RELAY_poll( void ) { char msg1[] = { 0x04, 0x11, 0x83, 0x00, 0x00, 0x99, 0x0f };//Relais 1 aan byte rcode = 0; //return code // byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char dataptr, unsigned int nak_limit rcode = Usb.setReport( RELAY_ADDR,0x00,0x08,RELAY_IF,0x02,0x00, msg1 ); delay(1500); }

But this code isn't working. Do I have to place some wires?

But this code isn't working.

Wrong. It is working. It may not be doing what you want. It may not be doing what you expect. But, it is working hard.

If you explained what you see that it is doing, and how that differs from what you expect/want it to do, perhaps we could offer more than insincere sympathy.

Well, I tried the code but it hangs when it reaches:

Max.powerOn();

It simply doesn't do anything after that and I really don't know why.

It simply doesn’t do anything after that and I really don’t know why.

In the code you posted, there is no Serial.print() after that call, so I don’t see how you know that that is the problem.

  Max.Task();
  Usb.Task();
  if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING ) {  //wait for addressing state
    RELAY_init();
    Usb.setUsbTaskState( USB_STATE_RUNNING );
  }
  if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) {  //poll the Mail Notifier
    RELAY_poll();
  }

It could be that Max.Task() isn’t doing what you expect. It could be that Usb.Task() does not cause Usb.getUsbTaskState() to return either of the values you are checking for.

There is only one thing plugged into the USB socket on the USB Host shield. Presumably, that is the thing that Usb.Task() is trying to talk to.

What is the MAX3421E class? What is the instance of the class supposed to be doing?

Okay it works now. Well it runs at least a little bit. This is what I get now:

Start Error attempting to configure boot protocol. Return code :5

This is my code now:

/* MAX3421E USB Host controller keyboard communication */

include "spi.h"

include "max3421e.h"

include "usb.h"

/* keyboard data taken from configuration descriptor */

define KBD_ADDR 1

define KBD_EP 1

define EP_MAXPKTSIZE 8

define EP_POLL 0x0a

/**/ EP_RECORD ep_record[ 2 ]; //endpoint record structure for the keyboard

void setup(); void loop();

MAX3421E Max; USB Usb;

void setup() { Serial.begin( 9600 ); Serial.println("Start"); Max.powerOn(); delay( 200 ); }

void loop() { Max.Task(); Usb.Task(); if( Usb.getUsbTaskState() == USB_STATE_CONFIGURING ) { //wait for addressing state kbd_init(); Usb.setUsbTaskState( USB_STATE_RUNNING ); } if( Usb.getUsbTaskState() == USB_STATE_RUNNING ) { //poll the keyboard kbd_poll(); } } /* Initialize keyboard / void kbd_init( void ) { byte rcode = 0; //return code // / Initialize data structures / ep_record[ 0 ] = *( Usb.getDevTableEntry( 0,0 )); //copy endpoint 0 parameters ep_record[ 1 ].MaxPktSize = EP_MAXPKTSIZE; ep_record[ 1 ].Interval = EP_POLL; ep_record[ 1 ].sndToggle = bmSNDTOG0; ep_record[ 1 ].rcvToggle = bmRCVTOG0; Usb.setDevTableEntry( 1, ep_record ); //plug kbd.endpoint parameters to devtable / Configure device / rcode = Usb.setConf( KBD_ADDR, 0, 1 ); if( rcode ) { **Serial.print("Error attempting to configure keyboard. Return code :"); **Serial.println( rcode, HEX ); while(1); //stop } / Set boot protocol / rcode = Usb.setProto( KBD_ADDR, 0, 0, 0 ); if( rcode ) { **Serial.print("Error attempting to configure boot protocol. Return code :"); **Serial.println( rcode, HEX ); while( 1 ); //stop } } / Poll keyboard and print result / void kbd_poll( void ) { char msg1[] = { 0x00, 0x04, 0x11, 0x83, 0x00, 0x00, 0x99, 0x0f };//Relais 1 aan byte rcode = 0; //return code // byte addr, byte ep, unsigned int nbytes, byte interface, byte report_type, byte report_id, char dataptr, unsigned int nak_limit rcode = Usb.setReport( KBD_ADDR,0x00,0x08,0x01,0x02,0x00, msg1 ); delay(1500); }

How do I solve this problem?

I bought a USB Host Shield because I want to control a relay card.

/* MAX3421E USB Host controller keyboard communication */

That tree you are barking up isn't even in the right forest.

PaulS:

I bought a USB Host Shield because I want to control a relay card.

/* MAX3421E USB Host controller keyboard communication */

That tree you are barking up isn't even in the right forest.

So? What do you mean? I know that it is possible because my relay card is controlled by USB.

I know that it is possible because my relay card is controlled by USB.

But your relay card is not a keyboard, or a mouse, or a thumb drive, or any of a number of other things for which USB drivers are required. You need to create a USB driver specifically for the device that you are trying to talk to.

And how do I have to do that? :)

And how do I have to do that?

See Grumpy_Mike’s first paragraph in reply #1.

Hmm okay. But this isn't a keyboard? And it's the same code. http://www.circuitsathome.com/mcu/driving-the-cheeky-mail-notifier-from-arduino

I know, I'm very cocky

But this isn't a keyboard? And it's the same code.

Yes but he is using the bit of the keyboard code that turns LEDs on and off, to turn his LEDs on and off. You want to access a pseudo serial port, that is a totally different thing to do.

Quite honestly if you ate having to ask then I don't think you are up to doing it. You might find an example of someone ho has done it but it will be much easier getting a proper relay board.