AlanChatham / UnoJoy

UnoJoy! allows you to easily turn an Arduino Uno (or Mega or Leonardo) into a PS3-compatible USB game controller
GNU General Public License v3.0
482 stars 130 forks source link

Strange axis jumping #62

Open Godehardt2003 opened 6 months ago

Godehardt2003 commented 6 months ago

Hello, first of all, thanks for this great tool Alan, there is nothing equal out there.

Now to my strange problem, I hope I did everything correct. In my short Video you can simply see the jumping axes: https://youtube.com/shorts/iRZpt27eo_4?feature=shared (bad cutted, in the end is an extreme jump, first completely to the right, then left, then back to center. Tried now to build it back to the most easy state to reproduce it.

setupMegaJoy(); in setup and so on...

void loop() {
  megaJoyControllerData_t controller = getBlankDataForMegaController();
  int test = analogRead(A0);
  controller.analogAxisArray[2] = test;
  controller.analogAxisArray[3] = test;
  controller.analogAxisArray[4] = test;

  setControllerData(controller);
}

I'm currently sitting in a train, thats why I don't have a potentiometer or something else. Did now the following: plugged 3.3V into A0 and removed it. Repeated that until the error occured. These are the results: https://youtube.com/shorts/82W1IY1axrM?feature=shared (X-Rotation jumping)

As you can see, single axes are jumping back and forward even if test should have the exact same value to all axes. I'm pretty sure that these jumps are the exact same ones that occure in the first video. I'm also pretty sure that these jumps are not from the analog input source. Hope this experiment proved that a bit. Used an original Arduino Mega made in Italy. Reproducable on every computer and also on Elegoo Arduinos. Tested values 10 bit, 0 - 1024 (and 16 bit Arduino int)

Godehardt2003 commented 6 months ago

Tried it now also with 9600 and 250000 baud rates. Of course with adjusted hex files which directly worked. Sadly still the same problem. It seems to be fixed at 8 bit with a max value of 254. That shouldn't be like that... I would really need the 10 bit. I'm trying to make a better recording of the error tomorrow.

I also moved my axes to X,Y and Z. Still a problem there.

Godehardt2003 commented 6 months ago

https://github.com/AlanChatham/UnoJoy/assets/78535292/de2c45bb-6075-4424-bddf-575abb9a346c

AlanChatham commented 6 months ago

This is going to be one of the dumber and more frustrating things you've heard in a while, but I was able to reproduce this a little bit I think, with the weird shaky single axes, and it went away when I connected things to A1 instead of A0.

I have some vague guesses as to what's going on on my setup, related to the AVR ADC being kind wonky sometimes - like, reading on A0, GND gets me an analogRead(A0) of 15, 3v3 in the 900s, and then 1023 on 5v, whereas analogRead(A1) gives a proper 0 for GND, 600-ish and stable for 3v3, and 1023 for 5v.

What I noticed is that it would get unstable for me when I picked up the board - the capacitance of my hand apparently was enough to mess with the A0 read, but things seem to be stable on A1? Which leads me to think it's basically ghosts/the onboard ADC just not being warmed up enough when reading from A0 (IIRC the ADC reads all the pins sequentially on any given ADC pin read).

If changing analog read ports doesn't help, can you share a quick circuit diagram of what you're plugging into the analog port? I think there may be some things on the electronics side that can help getting a better read?

In terms of axis resolution, I did figure out today (after 10 years lol) that you can see the raw axis data if you go into the joystick calibration wizard - it would be helpful to see the numbers if you can get things to be all wonky again; this is what I was getting on my end from plugging 3.3V into A0, which matched what I was getting from doing Serial.println(test) while in Arduino mode. MegaJoyCalibrationScreen

Godehardt2003 commented 6 months ago

Okay, interesting. I'll try it with the raw data and windows calibration tomorrow. My setup is pretty simple image I'm 99% sure that it is not a hardware/analog port problem. All axes are set by the value of variable "test" (which is the value of A0). So, if the problem would be A0 all axes should "jump". But they don't.

Meanwhile I found a solution named HoodLoader2. This one works without any "jumping". On the other side its a way more complicated even if it has some advantages to flash a new bootloader. Every program needs a way more code for a simple joystick application. So not really 100% what I'm looking for.

As I said I'll try the raw data output tomorrow. I'll need to reflash the old bootloader now....

Thanks for your fast answer.

AlanChatham commented 6 months ago

One thing that could be happening is that, if the signal on the ADC is jumping around a lot, especially since the loop is so simple, it might be updating the internal buffer on the main chip that gets set when sendControllerData(yourData) in the middle of when the communications chip is reading it. I.e., when the communications chip is asking for the X1 axis, it's getting ADC data read at T=0, but by the time the communications chip asks for the X2 axis, it's getting sent back ADC data read at T=1?

One thing to try would be to add a super long delay in your loop(), like delay(1000), and then see what's happening. If the axes are still bouncing around faster than once per second, then that would indicate some kind of data corruption in the communication between the main and communication chips. It sounds like you've poked around in the ATmega8u2 code, but just to clarify for anyone, the overall data flow is:

Arduino main chip runs your code, where you're setting up and setting virtual controller data, then using sendDataToController(yourData) This fills a buffer on the Arduino main chip, in UnoJoy.h (or megajoy.h, or whatever) The main chip has an interrupt handler on the serial port, that when it gets a byte, it sends out the corresponding byte of the buffer over the serial port

On the ATmega8u2 USB communications chip, it's both: -Every 10 milliseconds, send serial data to the main chip, which is just the numbers 1 through however many bytes of data is needed for all the controller data, then an interrupt on the serial port reads the data that comes back from the main chip, and stores it in an internal buffer on the 8u2

So, if there was instability in the main chip -> communications chip communication, then with delay(1000), we'd still see constant fluctuations, as every 10ms when the 8u2 polls the main chip, it's getting data that hasn't changed on the main chip's internal controller data buffer. If that communication were stable, though, we might occasionally see a bit of a blip if the loop() code happened to run right in time when the 8u2 was mid-read, but that data should then hold for the full second until the loop() runs again.

I tried this on my end, and got stable reads in the unstable test condition, so it's definitely wonky ADC reads on my end, but let me know what you get - it's also possible that I'm not recreating your exact issue....

Godehardt2003 commented 6 months ago

So, took me a while now. With a delay of 1000 ms I still have fluctuations. For my feeling a bit less, but they are still there. If I'm in calibration I don't get any fluctuations. Maybe because of a delay on windows side, the displayed number has a pretty low refresh rate, I'm assuming that the fluctuation is simply too fast.

I'm wondering why you are not getting this issue. Are you moving the potentiometer fast enough? I tested it now on an original Arduino mega made in Italy and three Elegoo Arduino megas with 16u2 com chips. Also tested on three different computers. Everywhere the same issue.

And yeah, as I said the issue disappears when using values from 0 to 255. All in all it sounds to me like there is something wrong with any buffer.