Send Integer to PC with usbMsgPtr

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
nictex

Send Integer to PC with usbMsgPtr

Post by nictex » Mon Apr 22, 2013 2:20 pm

Hey guys,

I want to make an ATMega8 USB device that reads a DS18B20 temperature sensor every few seconds and a corresponding PC program with which you can read the temperature from the atmega via v-usb.

The temperature is stored in a int variable.
I first did this:

Code: Select all

   int temp = 255;
   t_char[2] = {0};
   t_char[0] = (temp >> 8) & 0xff;
   t_char[1] = (temp) & 0xff;


and then in the usbFunctionSetup:

Code: Select all

   usbMsgPtr = t_char;
   return sizeof(t_char);


But when I try to read this out via a gcc console program:

Code: Select all

        
        nBytes = usb_control_msg(handle,
            USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
            USB_GET_TEMP, 0, 0, (char *)buffer, sizeof(buffer), 5000);
        printf("Bytecount: %d, Buffer: %s\n", nBytes, buffer);

        int temp = (buffer[0] << 8) | buffer[1];

        printf("Temperature: %i\n", temp);


Nothing happens, that means no temperature is displayed.

How can I fix this or is there something clearly wrong in my idea?

Thank you for your help, nictex

vouvoume

Re: Send Integer to PC with usbMsgPtr

Post by vouvoume » Tue Apr 23, 2013 12:04 am

Hi nictex

>Nothing happens, that means no temperature is displayed.

Does this mean, really nothing happens (printf does not output) or does it mean value "0" ist printed to the screen?

I could send you my (not completed yet) example code for an VUSB Oscilloscope sending 8-bit ADCs to the computer via ringbuffers?
Otherwise you can study a VUSB template like:
http://matrixstorm.com/avr/tinyusbboard/#examples ("VUSB skeleton/example with corresponding linux, windows (delphi) and platform independent GTK libusb program")

Best regards,

nictex

Re: Send Integer to PC with usbMsgPtr

Post by nictex » Tue Apr 23, 2013 6:42 pm

Hey vouvoume,

at first thank you for the fast response!
The problem is that sending normal characters works.
I want to build a temperature usb dongle that also toggles relays. And my program successfully sends the status of the relays to the PC program.

example:
pc:

Code: Select all

           
nBytes = usb_control_msg(handle,
                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
                USB_P1_STATUS, 0, 0, (char *)buffer, sizeof(buffer), 5000);
printf("Bytecount: %d, Buffer: %s\n", nBytes, buffer);


Code: Select all

status_p1_char = (char) 48+status_p1


Code: Select all

case USB_P1_STATUS: // send data to PC
   //*replyBuf = statusp1;
   usbMsgPtr = (int) status_p1_char;
   return sizeof(status_p1_char);


My program then successfully outputs: "Bytecount: 1, Buffer: 1 [or 0]" whereas with the code mentioned above outputs: "Bytecount: 2, Buffer: "
I also tried this here:

Code: Select all

   
usbMsgPtr = temp;
return sizeof(temp);         


and then the pc program outputs: "Bytecount: 2, Buffer: è(" when temp equals 255. I looked up the ascii table and the two characters equal 232 and 40, so 1110100000101000 in binary together - which doesnt equal to 255 (0b11111111).

So long,
nictex

vouvoume

Re: Send Integer to PC with usbMsgPtr

Post by vouvoume » Fri Apr 26, 2013 12:44 am

If you transmit strings via USB, please handle them properly. You have to ensure each string terminates with a NULL-char.
If your temp would be: temp="255\0" Then it should work. In this case Bytecount will be 4.

Best regards,

nictex

Re: Send Integer to PC with usbMsgPtr

Post by nictex » Fri Apr 26, 2013 11:52 am

hey vouvome

problem is i am not trying to transmit strings, but a 16bit integer via USB.

so long, nictex

vouvoume

Re: Send Integer to PC with usbMsgPtr

Post by vouvoume » Sat Apr 27, 2013 2:30 am

Hi.

Code: Select all

printf("Bytecount: %d, Buffer: %s\n", nBytes, buffer);


Then you should not do a %s, but a something like an %i instead?

nictex

Re: Send Integer to PC with usbMsgPtr

Post by nictex » Sat Apr 27, 2013 4:41 pm

Hey vouvoume,

did you understand what I was trying to do with the code in my first post?
Can I just point the usbMsgPtr to a 16bit variable instead of an array of 8bit variables??? (Char array) Because if you read through my first posted code segments you See that I bit shifted the integer into a char array of size 2 and then shifted it back in the PC program. So you think I just Have To do usbMsgPtr = temp; ?

so long, nictex

vouvoume

Re: Send Integer to PC with usbMsgPtr

Post by vouvoume » Sun Apr 28, 2013 4:06 pm

I am confused.

But for usbMsgPtr it is just imprtant to have at least 8 bytes accessable memory.
If it is memory of "type" int, char or void - not even the programming language really cares.

Important is just the memory (space).

For formated output (like printf) you need to tell the function how to "interpret" the memory. If the memory contains "data" of an integer you need to use %i instead %s.

Best regards,

nictex

Re: Send Integer to PC with usbMsgPtr

Post by nictex » Thu May 02, 2013 1:36 pm

I know haha :D

Okay, could you provide me with some functioning code?

I now did this:

Code: Select all

      case USB_GET_TEMP:
         {
            usbMsgPtr = temp;
            return sizeof(temp);
         }


But how do I get the value then in my PC program?
I am using this code http://codeandlife.com/2012/02/04/avr-attiny-usb-tutorial-part-4/
How do I get the 2 byte integer into the PC? It seems that you do not really understand my problem. Have you tried doing it?
I cannot just do this:

Code: Select all

       int16_t temp;
        nBytes = usb_control_msg(handle,
            USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
            USB_GET_TEMP, 0, 0, temp, sizeof(temp), 5000);
        printf("Bytecount: %d, Buffer: %i\n", nBytes, temp);


It just does not work.

So long, nictex

vouvoume

Re: Send Integer to PC with usbMsgPtr

Post by vouvoume » Fri May 03, 2013 12:52 pm

Hi.

Your AVR has an "other understanding" of integer, than your host.

One thing is the endianness (http://en.wikipedia.org/wiki/Endianness).
Your AVR is BIG endian - your PC little endian.
Also your AVR uses just 16bit (??) for int, while your PC uses 4 bytes.

As a convention data always is transmitted in little endian trough networks.
(Usually your PC has much more CPU power to transform it in its own format,
than little microcontrollers have.)

To simplify platform independent code see http://www.gnu.org/software/libc/manual ... Order.html .
(Use hton on the AVR side and ntoh on the PC side)

To avoid type misinterpretation on both sides use "#include <stdint.h>" and then the std-type uint32_t or int32_t.
(http://www.gnu.org/software/gnulib/manu ... 002eh.html AND
http://www.nongnu.org/avr-libc/user-man ... tdint.html)

Best regards

nictex

Re: Send Integer to PC with usbMsgPtr

Post by nictex » Mon May 06, 2013 9:30 am

Hey,

as far as I know both AVR-gcc and gcc on windows use little ebdian. Besides that I also bit shifted the numbers in another way so that it should resemble endianness conversion.

How do I really send an integer number now? The method i've put into my last post does not work!

so long, nictex

vouvoume

Re: Send Integer to PC with usbMsgPtr

Post by vouvoume » Mon May 06, 2013 2:25 pm

For example you could do this. Remember: "setupData" needs to be at least 8 bytes.
On the host side you again could decode the single bytes together to an int.

    usbMsgPtr = (usbMsgPtr_t)setupData;
    switch (rq->bRequest) {
    [...]
    case PSCMD_CALL_GETBUFFERSIZE: {
    setupData[0] = rq->bRequest;
    setupData[1] = PSCMD_RETN_OKAY;
    setupData[2] = (singlebuffersize)&0xff;
    setupData[3] = (singlebuffersize)>>8;
    cli();
    [...]

Best regards

nictex

Re: Send Integer to PC with usbMsgPtr

Post by nictex » Mon May 06, 2013 3:57 pm

But that was what I was doing at first.

In my very first post:

Code: Select all

  
int temp = 255;
t_char[2] = {0};
t_char[0] = (temp >> 8) & 0xff;
t_char[1] = (temp) & 0xff;
usbMsgPtr = t_char;
return sizeof(t_char);


Which does not work.

So long, nictex

vouvoume

Re: Send Integer to PC with usbMsgPtr

Post by vouvoume » Mon May 06, 2013 4:30 pm

Remember: "setupData" needs to be at least 8 bytes.


At host end of course you need to do:
    int result = ((int)buffer[3]<<8) | ((int)buffer[2]);
    printf("%i\n",result);

So long

nictex

Re: Send Integer to PC with usbMsgPtr

Post by nictex » Sat May 11, 2013 10:51 pm

Code: Select all

        int temp = (buffer[0] << 8) | buffer[1];

        printf("Temperature: %i\n", temp);


That was what I did too... I guess I will try it again.

Post Reply