Hi all,
First of all, I am new to Arduino and also new to this forum, hopefully I post this question in the right place.
I have got a Duemilanoves (ATmega168) board and a USB Host Shield from Sparkfun http://www.sparkfun.com/commerce/produc … ts_id=9628. I used the libraries from http://www.circuitsathome.com/category/ … usb-shield and have changed the .h file according to the Sparkfun website. I tried the example sketch http://www.circuitsathome.com/mcu/progr … eripherals and it works fine. So I start to work on my project.
My project is to use the Arduino to talk to a power monitoring device called the “WattsUp Pro”.
https://www.wattsupmeters.com/secure/im … CORD_1.jpg
This device has a USB port and I can get information through my computer, by using pyserial with python. In general, you issue a command such as “#D,R,0;” to the device and it will feed back the measured data, eg. “#D,-,34, … ;”. I use USEB_View and get the device’s USB information as follow:
By using the USBView utility, we can get the USB connection tree of the end device.
Device Descriptor:
• bcdUSB: 0x0200
• bDeviceClass: 0x00
• bDeviceSubClass: 0x00
• bDeviceProtocol: 0x00
• bMaxPacketSize0: 0x08 (8)
• idVendor: 0x0403 (Future Technology Devices International Limited)
• idProduct: 0x6001
• bcdDevice: 0x0600
• iManufacturer: 0x01
• 0x0409: "FTDI"
• iProduct: 0x02
• 0x0409: "FT232R USB UART"
• 0x0409: "FT232R USB UART"
• iSerialNumber: 0x03
• 0x0409: "A7005chz"
• bNumConfigurations: 0x01
• ConnectionStatus: DeviceConnected
• Current Config Value: 0x01
• Device Bus Speed: Full
• Device Address: 0x01
• Open Pipes: 2
Endpoint Descriptor:
• bEndpointAddress: 0x81 IN
• Transfer Type: Bulk
• wMaxPacketSize: 0x0040 (64)
• bInterval: 0x00
Endpoint Descriptor:
• bEndpointAddress: 0x02 OUT
• Transfer Type: Bulk
• wMaxPacketSize: 0x0040 (64)
• bInterval: 0x00
Configuration Descriptor:
• wTotalLength: 0x0020
• bNumInterfaces: 0x01
• bConfigurationValue: 0x01
• iConfiguration: 0x00
• bmAttributes: 0xA0 (Bus Powered Remote Wakeup)
• MaxPower: 0x2D (90 Ma)
Interface Descriptor:
• bInterfaceNumber: 0x00
• bAlternateSetting: 0x00
• bNumEndpoints: 0x02
• bInterfaceClass: 0xFF
• bInterfaceSubClass: 0xFF
• bInterfaceProtocol: 0xFF
• iInterface: 0x02
• 0x0409: "FT232R USB UART"
• 0x0409: "FT232R USB UART"
Endpoint Descriptor:
• bEndpointAddress: 0x81 IN
• Transfer Type: Bulk (Attr 02)
• wMaxPacketSize: 0x0040 (64)
• bInterval: 0x00
Endpoint Descriptor:
• bEndpointAddress: 0x02 OUT
• Transfer Type: Bulk (Attr 02)
• wMaxPacketSize: 0x0040 (64)
• bInterval: 0x00
And I tried to write a program to ask the device for data and the code is as follow (I modified the ps3 interface code from circuit@home):
#include <Spi.h>
#include <Max3421e.h>
#include <Max3421e_constants.h>
#include <Usb.h>
#include <avr/pgmspace.h>
#define WATTSUP_CONFIGURATION 1
#define WATTSUP_ADDR 0x01
#define WATTSUP_VID 0x0403
#define WATTSUP_PID 0x6001
#define WATTSUP_NUM_EP 3
#define EP_MAXPKTSIZE 64
#define EP_BULK 0x02
#define EP_POLL 0x01
#define CONTROL_PIPE 0
#define INPUT_PIPE 1
#define OUTPUT_PIPE 2
#define DEV_DESCR_LEN 32
#define WATTSUP_CLEAR_COMMAND_LEN 7
#define WATTSUP_HEADER_COMMAND_LEN 7
#define statusDeviceConnected 0x01
#define statusUSBConfigured 0x02
#define statusWATTSUPConnected 0x04
#define statusReportReceived 0x08
char buf[64] = {0}; //Gemeral purpose buffer for USB data
static unsigned char wattsup_status;
prog_char clear_command[] PROGMEM = {0x23,0x52,0x2C,0x57,0x2C,0x30,0x3B};
prog_char header_command[] PROGMEM = {0x23,0x44,0x2C,0x52,0x2C,0x30,0x3B};
void setup();
void loop();
EP_RECORD ep_record[WATTSUP_NUM_EP];
MAX3421E Max;
USB Usb;
void setup(){
byte tmpdata = 0;
Serial.begin(115200);
Serial.println("Start");
Max.powerOn();
delay(200);
}
void loop(){
Max.Task();
Usb.Task();
if(Usb.getUsbTaskState() == USB_DETACHED_SUBSTATE_INITIALIZE){
Serial.println("USB_DETACHED_SUBSTATE_INITIALIZE");
wattsup_status = 0;
}
if(Usb.getUsbTaskState() == USB_STATE_CONFIGURING) {
Serial.println("START TO INIT");
WATTSUP_init();
if(wattsup_status & statusWATTSUPConnected){
Serial.println(wattsup_status & statusWATTSUPConnected, HEX);
Usb.setUsbTaskState(USB_STATE_RUNNING);
}
}
if(Usb.getUsbTaskState() == USB_STATE_RUNNING){
Serial.println("Polling");
WATTSUP_poll();
}
}
void WATTSUP_init(void){
Serial.println("INSIDE THE INIT LOOP");
byte rcode = 0;
byte i;
USB_DEVICE_DESCRIPTOR* device_descriptor;
wattsup_status = statusDeviceConnected;
ep_record[CONTROL_PIPE] = *(Usb.getDevTableEntry(0,0)); //copy Endpoint Zero
//make sure if the ep_record[Control Pipe] is good
ep_record[OUTPUT_PIPE].epAddr = 0x02;
ep_record[OUTPUT_PIPE].Attr = EP_BULK;
ep_record[OUTPUT_PIPE].MaxPktSize = EP_MAXPKTSIZE;
ep_record[OUTPUT_PIPE].Interval = EP_POLL;
ep_record[OUTPUT_PIPE].sndToggle = bmSNDTOG0;
ep_record[OUTPUT_PIPE].rcvToggle = bmRCVTOG0;
ep_record[INPUT_PIPE].epAddr = 0x81;
ep_record[INPUT_PIPE].Attr = EP_BULK;
ep_record[INPUT_PIPE].MaxPktSize = EP_MAXPKTSIZE;
ep_record[INPUT_PIPE].Interval = EP_POLL;
ep_record[INPUT_PIPE].sndToggle = bmSNDTOG0;
ep_record[INPUT_PIPE].rcvToggle = bmRCVTOG0;
Usb.setDevTableEntry(WATTSUP_ADDR, ep_record);
rcode = Usb.getDevDescr(WATTSUP_ADDR, ep_record[CONTROL_PIPE].epAddr, DEV_DESCR_LEN, (char *)&buf);
if(rcode){
Serial.println("Cannot get Descriptor");
return;
}
device_descriptor = (USB_DEVICE_DESCRIPTOR *) &buf;
if((device_descriptor->idVendor != WATTSUP_VID) || (device_descriptor->idProduct != WATTSUP_PID)){
Serial.println("The End Device Is Unknown.");
return;
}
Serial.println("Succeed");
rcode = Usb.setConf(WATTSUP_ADDR, ep_record[CONTROL_PIPE].epAddr, WATTSUP_CONFIGURATION );
if( rcode ) return;
wattsup_status |= statusUSBConfigured;
Serial.println("Configured");
WATTSUP_request();
Serial.println("Connected");
delay(200);
}
void WATTSUP_request(void){
byte rcode = 0;
byte i = 0;
char buf[64] = {0};
for (i=0; i<WATTSUP_CLEAR_COMMAND_LEN; i++) {
buf[i] = pgm_read_byte_near(clear_command+i);
}
rcode = Usb.outTransfer(WATTSUP_ADDR, ep_record[OUTPUT_PIPE].epAddr, WATTSUP_CLEAR_COMMAND_LEN, buf);
for( i = 0; i < WATTSUP_CLEAR_COMMAND_LEN; i++ ) {
Serial.print( buf[i]);
}
if(rcode){
Serial.println("Failed");
return;
}
Serial.println("Issued the clear command.");
delay(200);
for (i=0; i<WATTSUP_HEADER_COMMAND_LEN; i++) {
buf[i] = pgm_read_byte_near(header_command+i);
}
rcode = Usb.outTransfer(WATTSUP_ADDR, ep_record[OUTPUT_PIPE].epAddr, WATTSUP_HEADER_COMMAND_LEN, buf);
for( i = 0; i < WATTSUP_CLEAR_COMMAND_LEN; i++ ) {
Serial.print( buf[i]);
}
if(rcode){
Serial.println("Failed");
return;
}
Serial.println("Issued the header command.");
wattsup_status |= statusWATTSUPConnected;
delay(200);
return;
}
void WATTSUP_poll(void){
char buf[0x0040] = { 0 }; //keyboard buffer
byte i = 0;
byte rcode = 0;
rcode = Usb.inTransfer(WATTSUP_ADDR, ep_record[INPUT_PIPE].epAddr, 8, buf);
if(rcode){
Serial.println("Failed polling");
return;
}
for( i = 0; i < 0x0040; i++ ) {
Serial.print( buf[i]);
}
return;
}
Now, first of all, I dont know if I am doing the correct thing to start a bulk out transfer, furthermore, I dont know if I have the setting or procedure correct. The bottom line is, I cannot get any data from the device. Wondering if anyone has any idea what I have done wrong. Thanks so much.
-klo