getting 10 bit analogue out of the unojoy [Solved]

Could somebody please guide me as to how to get a 10bit serialWrite, serialRead(or 16 bit[2 bytes] as this is what the specified HID report size is [ I know that 10 bit is the best an UNO can manage, 16 bit just lines the HID data up nicely]) currently this is working as an 8 bit Write/Read

HID joystick, (boring project for most, but it's what I'm making)

//Just included this bit to show what's going on
int main(void) {
	// Make sure our watchdog timer is disabled!
	wdt_reset(); 
	MCUSR &= ~(1 << WDRF); 
	wdt_disable();

	// Start up the USART for serial communications
	// 25 corresponds to 38400 baud - see datasheet for more values
	USART_Init(25);// 103 corresponds to 9600, 8 corresponds to 115200 baud, 3 for 250000
	
	// set the prescale for the USB for our 16 MHz clock
	CPU_PRESCALE(0);

	// Initialize our USB connection
	usb_init();
	while (!usb_configured()){
		LEDon(TXLED);
		_delay_ms(50);
		LEDoff(TXLED);
		_delay_ms(50);
}

// This is the bit I need help with
	dataForController_t dataToSend;
        // We get our data from the ATmega328p by writing which byte we
        //  want from the dataForController_t, and then wait for the
        //  ATmega328p to send that back to us.
        // The serialRead(number) function reads the serial port, and the
        //  number is a timeout (in ms) so if there's a transmission error,
        //  we don't stall forever.
		LEDon(TXLED);
		flushSerialRead();
		serialWrite(0);
		dataToSend.al0 = serialRead(25);
		serialWrite(1);
		dataToSend.al1 = serialRead(25);
		LEDoff(TXLED);
		sendPS3Data(dataToSend);

Is there a simple fix or would I have to change it considerably?

a) This doesn't appear to be on an Arduino.
b) WTH is a "10bit serialWrite, serialRead"
c) What device requires 10 data bits over async serial? I've never heard of this before.


Rob

This is part of the source code for compiling the HexFile (for the ATMega16u2) to make a UNO become a HID joystick.

I must have used the wrong language, at present the sketch on the Uno does a analogueRead and bit shifts to make the data 1 byte long , this is then put into a HID report format by the ATMega16u2, which I think is explained in this bit of code, I'm just trying to get a 10 bits into the HID input report

        // We (meaning the ATMega16u2) get our data from the ATmega328p by writing which byte we
        //  want from the dataForController_t, and then wait for the
        //  ATmega328p to send that back to us.
        // The serialRead(number) function reads the serial port, and the
        //  number is a timeout (in ms) so if there's a transmission error,
        //  we don't stall forever.

Like I said it's a joystick but it has 32 analogue pots (actually I'm aiming for 48 * 8 bit pots, 32 * 10 bit pots and 128 buttons, it's actually going to be used as a HID dj software controller) I just cut it down for clarity, If I see how you would do 2 I can do the rest.

I tried something like this (it didn't work)( but perhaps it wasn't exactly this so I may have to test it again) by looking at the megajoy project, which has 10 bit analogue output, it's a bit late to test now but is this the way to go?

// Get a 16 bit value off the serial port by doing two successive reads
//  Assumes that data is being transmitted high byte first
int16_t get16bitValue(int serialIndex){
        int16_t returnValue = 0;
        serialWrite(serialIndex);
        serialIndex++;
        returnValue = serialRead(25);
       
        serialWrite(serialIndex);
        serialIndex++;
        returnValue += serialRead(25) << 8;    
        return returnValue;
}

int main(void) {
        // Make sure our watchdog timer is disabled!
        wdt_reset();
        MCUSR &= ~(1 << WDRF);
        wdt_disable();

        // Start up the USART for serial communications
        // 25 corresponds to 38400 baud - see datasheet for more values
        USART_Init(25);// 103 corresponds to 9600, 8 corresponds to 115200 baud, 3 for 250000
       
        // set the prescale for the USB for our 16 MHz clock
        CPU_PRESCALE(0);

        // Initialize our USB connection
        usb_init();
        while (!usb_configured()){
                LEDon(TXLED);
                _delay_ms(50);
                LEDoff(TXLED);
                _delay_ms(50);
        } // wait

        // Wait an extra second for the PC's operating system to load drivers
        // and do whatever it does to actually be ready for input
        // This wait also gives the Arduino bootloader time to timeout,
        //  so the serial data you'll be properly aligned.
        _delay_ms(500);
        dataForController_t dataToSend;

        while (1) {
                // Delay so we're not going too fast
                _delay_ms(10);
               
        // We get our data from the ATmega328p by writing which byte we
        //  want from the dataForController_t, and then wait for the
        //  ATmega328p to send that back to us.
        // The serialRead(number) function reads the serial port, and the
        //  number is a timeout (in ms) so if there's a transmission error,
        //  we don't stall forever.
                LEDon(TXLED);
                flushSerialRead();
               
                int serialIndex = 0;
                             
                // Assuming that 16 bit data gets sent high byte first        
                dataToSend.al0 = get16bitValue(serialIndex);
                serialIndex += 2;
                dataToSend.al1 = get16bitValue(serialIndex);
               
                // Communication with the Arduino chip is over here
                LEDoff(TXLED);  
        // Finally, we send the data out via the USB port
		sendPS3Data(dataToSend);
        }
}
       serialWrite(serialIndex);
        serialIndex++;
        returnValue = serialRead(25);

Does serialRead() block waiting for a character or 25mS? We have no way on knowing because you haven't posted that function although the comments imply it does.

USART_Init(25);// 103 corresponds to 9600, 8 corresponds to 115200 baud, 3 for 250000

So what baud rate is 25?

What about the "Arduino" side of the code? What does that look like?

What is a "dataForController_t"?

"serialIndex" is incremented twice in get16bitValue() and then again in the main while() loop. That looks odd.

present the sketch on the Uno does a analogueRead and bit shifts to make the data 1 byte long

So why read two bytes.

Is there some reason you can't post all the code? There are too many unknowns to attempt a diagnosis IMO.


Rob

serialRead waits for a byte/character if it doesn't get one in 25 ms it times out and reports zero

25 corresponds to 38400 baud

The arduino side of the code is so simple it is laughable and not the issue but here it is but I've cut out the 128 buttons, 30 of the 32 * 10 bit analogues, all 48 * 8 bit analogues and I also cut muxing scheme, although Unojoy.h library (attached) might clear some things up

#include "UnoJoy.h"

void setup(){
  setupUnoJoy();
}

void loop(){
  // Always be getting fresh data
  dataForController_t controllerData = getControllerData();
  setControllerData(controllerData);
}

dataForController_t getControllerData(void){
  dataForController_t controllerData = getBlankDataForController();

void loop(void);
    controllerData.pl0 = analogRead(A3);
    controllerData.pl1 = analogRead(A4);

  // And return the data!
  return controllerData; 

}//It's that simple

Why read two bytes? 10 bit doesn't fit into 1 byte.

Now you mention (serialIndex) being ++'d in the method and the loop does sound odd, but that is a direct copy from the megajoy project which does have 10 bit analogue. But it was a guess of a copy paste job by me.

I couldn't post all the code because there's lots, And much code = TLDR
35KB of Arduino code (not complied just in text format with comments)
and 65KB in 4 source files to compile the HID firmware

I'll be honest it's been a nightmare as newb, because the unojoy project whilst easy once you get it, isn't best supported (the help desk is on tumblr), HID reports once you get it is pretty easy but getting a straight answer is pretty rare.

It's been a tough 2 months to get this far.

Although I am pleased that I got a 64 byte version (128 button + 48 * 8 bit analog) working perfectly, I'm wanting + 32 more 10 bit analog inputs as 8 bit isn't precise enough for some stuff.

4 56 am Time for sleep.

UnoJoy.h (17.9 KB)

Why read two bytes? 10 bit doesn't fit into 1 byte.

But you said the Arduino was shifting the data to 8 bits.

That code segment makes absolutely no sense, a declaration of loop() inside loop(), no setting up of the serial port or sending of any data to the 16u2 (unless that's buried inside one of the UnoJoy functions), returning a value from loop() which is not allowed and of no use anyway. How can that possibly be the code you are using? Does it compile for you?

I think you should break this down into it's component parts, for example we need to get bytes travelling from the Arduino to the u16, forget UnoJoy for the time being and just send bytes, we need to get bytes from the u16 to the PC, write a small program that JUST does that, etc etc. When the parts work add them together.

For example, on the Arduino something like

void setup(){
	Serial.begin(38400);
}

void loop(){
	int val1 = 1234;
	int val2 = 5678;
	
 	Serial.write(val1 >> 8);
 	Serial.write(val1 & 0xff);
 	Serial.write(val2 >> 8);
 	Serial.write(val2 & 0xff);

 	delay(20);

}

I can't really help with the u16 as I've not written code for that before, but a simple program that does the equivalent of the above Arduino code would test that you can talk correctly with the PC.

Get that working and the Arduino code working (maybe with a standard u16 in place so you can print the data and verify it), then you add the get16bitValue() function and you can test from Arduino right through to the PC. When that works add the UnoJoy stuff back in, and finally start adding arrays etc to handle all the 32/48/whatever input muxing.

One small thing at a time, at present there are too many things happening, all of which are untested.


Rob

2 years ago I looked at articles that showed the steps to do that and then I bought a Teensy++ 2.0 that lets me do HID on command. Arduino has the Leonardo that's got the same chip as the smaller Teensy 2.0 also capable of the same trick.
Teensy 2.0 costs $16 without pins and is small enough to fit inside a stick, .7" x 1.2".
http://www.pjrc.com/teensy/index.html

Self solved my original idea was correct but there may have been a typo.

Anyone else wanting 10 bit analogue from a unojoy ask here.

You know that to use your UNO in the regular way, you have to change it back? And isn't there a bit of soldering or de-soldering required?

But hey, you may like the V-USB site.

It's got the goods to do USB from stand-alone AVR chips, even ATtiny's. No U2 chip needed!

GoForSmoke:
You know that to use your UNO in the regular way, you have to change it back? And isn't there a bit of soldering or de-soldering required?
But hey, you may like the V-USB site.
http://www.obdev.at/products/vusb/index.html
It's got the goods to do USB from stand-alone AVR chips, even ATtiny's. No U2 chip needed!
http://www.obdev.at/products/vusb/projects.html

I'm using a R3 Uno so I don't have to solder to go into DFU mode, I just short two pins

I looked at V-USB 2 months ago but from what I remember it had limits on the number of analogue outputs,
I don't want to change brand now! I'm almost there,
My next battle is pc to device communication, joysticks with LED's seems like where I should be looking. (Time to get confused again.)

I don't know what you're on about with the analog outputs. USB is serial. It's all data. Put the value into 2 bytes and send it! What's the big deal?

Erk, wait, HID. Well, it's not a problem with the Teensy software!

Teensy 3.1 does look tempting, 16 bit ADC, HID/MIDI out of the box, more memory, more pins and cheaper than the uno, once I get this prototype made I think I'll sell uno based dj controllers (HIDjoystick) as V 1.X and I'll put some study in for V2 of a dj controller on the teensy,

The 3.1 is pretty much a small board Due isn't it?

The $16 Teensy 2.0 has 12 analog inputs, a bunch more pins and more than enough flash and RAM to make a super stick. HID is done through commands the Teensy software brings to the Arduino IDE. There are some different steps from UNO programming but they are well documented.

GoForSmoke:
The 3.1 is pretty much a small board Due isn't it?

More or less but the 3.1 has 16 bit ADC as where the Due has 12 bit. Time to up the game Arduino.

You're going to need shielded cables and a lot of care to get 12 bits and beyond with any accuracy.

I had a Microsoft product that was good once (they copied or co-opted someone else), a 3DPro stick.
It used optical encoding. That was back in the Red Baron era.

im newbie and no understand code good but i need 16 analog input my flight sim X
joystick and other analog potentiometer input, i read mega can add max 16 input ?
but how make ? how make description ? what program need and what hardware need ?
and can do ch340 chip board ? what different have mega 16U2 chip or ch340 chip whit USB-HID ?
i need only 16 analog input code, who can made to me ?
i try looking google many site but i no found any site were tell good how made hid analog input board.
can somebody help me.
i have uno,mega,nano board many at home (ch340 chip)
but how made usb-hid 16 analog input NO switch or buttons need.
i think save memory. and mobiflight software can use buttons and encoder board.
need me mega 16U2 chip board and how make description and how burn in board ????