I’m using a joystick and Pro Micro to emulate the mouse, I use exactly the same code on both platforms, it compiles perfectly, with no errors, however it only works if I pass the code via Arduino IDE.
I downloaded the latest version of VS Code with PlatformIO, i also downloaded the library Mouse.h from PlatformIO Library Manager, and even so, after i upload the code to my Micro Pro the mouse does not respond to the joystick!
But the same code works when i upload via Arduino IDE!
Here is the code:
/* HID Joystick Mouse Example
by: Jim Lindblom
license: MIT License - Feel free to use this code for any purpose.
No restrictions. Just keep this license if you go on to use this
code in your future endeavors! Reuse and share.
This is very simplistic code that allows you to turn the
SparkFun Thumb Joystick (http://www.sparkfun.com/products/9032)
into an HID Mouse. The select button on the joystick is set up
as the mouse left click.
int horzPin = A0; // Analog output of horizontal joystick pin
int vertPin = A1; // Analog output of vertical joystick pin
int selPin = 9; // select button pin of joystick
int vertZero, horzZero; // Stores the initial value of each axis, usually around 512
int vertValue, horzValue; // Stores current analog output of each axis
const int sensitivity = 200; // Higher sensitivity value = slower mouse, should be <= about 500
int mouseClickFlag = 0;
pinMode(horzPin, INPUT); // Set both analog pins as inputs
pinMode(selPin, INPUT); // set button select pin as input
digitalWrite(selPin, HIGH); // Pull button select pin high
delay(1000); // short delay to let outputs settle
vertZero = analogRead(vertPin); // get the initial values
horzZero = analogRead(horzPin); // Joystick should be in neutral position when reading these
vertValue = analogRead(vertPin) - vertZero; // read vertical offset
horzValue = analogRead(horzPin) - horzZero; // read horizontal offset
if (vertValue != 0)
Mouse.move(0, vertValue/sensitivity, 0); // move mouse on y axis
if (horzValue != 0)
Mouse.move((horzValue/sensitivity) *-1, 0, 0); // move mouse on x axis
if ((digitalRead(selPin) == 0) && (!mouseClickFlag)) // if the joystick button is pressed
mouseClickFlag = 1;
Mouse.press(MOUSE_LEFT); // click the left button down
else if ((digitalRead(selPin))&&(mouseClickFlag)) // if the joystick button is not pressed
mouseClickFlag = 0;
Mouse.release(MOUSE_LEFT); // release the left button
Your problem is not unique. There are several documented examples of code that executes perfectly on AVR processors when compiled with the Arduino IDE and its toolchain, but fail when compiled with ATMEL Studio or Atom/VSCode + PlatformIO. Here is an excellent example that was researched and solved by a very smart person digging into the guts of the WiFi101 library when compiled for an AVR Mega in ATMEL Studio. I found this because I had the exact same problem with WiFi101 code that worked in Arduino IDE or Eclipse+Sloeber, but hung in a loop when compiled in PlatformIO or ATMEL Studio.
There is clearly something deeply wrong here and the fact that ATMEL Studio has the same problem as PlatformIO is the hint. I suspect that PlatformIO is using the ATMEL AVR core (framework) instead of the “official Arduino core” and that’s the root of all the unreliable object code. My guess is that the ATMEL AVR 8-bit code just isn’t as well exercised or debugged as the Arduino core because most of the chip’s users are hobbyists who run the plain Arduino IDE, core, and toolchain. It’s made worse because most new development is targeted to ESP32 and ARM based microprocessors so the poor old 8-bit AVR is being ignored going forward.
So, reluctantly, I’ve given-up on any Arduino IDE alternative that doesn’t use the “official Arduino core”. It isn’t worth the risk that your code will compile fine but not run correctly. It’s too bad because I really like Atom and VSCode and PlatformIO.
I would have thought if anything it was it was a slight variation in the exactly compiler or build flags used, or the fact that it doesn’t use the arduino preprocessor/‘builder’ AFAIK, so the code the compiler sees isn’t ordered exactly the same as it would be with the Arduino IDE. Assuming, of course, exactly the same code and library versions, etc. As the OP posted on the WiFi101 issue - a seemingly unrelated change fixed the issue… both when he made the change, and both in the update to the library…
Just a thought… I noticed in your output it mentions each flag in a new line… i.e. the comment you have in your platformio.ini file… so something isn’t quite right there. Also, the output is slightly different around there… as it doesn’t mention the manually specified programmer… but that could be because you’re using the dev version of platformio, and I’m still on stable.
pfeerick@ASUS-H55D-ubuntu:~/Documents/PlatformIO/Projects/joystick$ pio run -t program
Processing micro (framework: arduino; platform: atmelavr; board: micro)
Verbose mode can be enabled via `-v, --verbose` option
PLATFORM: Atmel AVR > Arduino Micro
HARDWARE: ATMEGA32U4 16MHz 2.50KB RAM (28KB Flash)
Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF MODES: FINDER(chain) COMPATIBILITY(soft)
Collected 6 compatible libraries
|-- <Mouse> 1.0.1
| |-- <HID> 1.0
Checking size .pioenvs/micro/firmware.elf
Memory Usage -> http://bit.ly/pio-memory-usage
DATA: [= ] 8.2% (used 211 bytes from 2560 bytes)
PROGRAM: [== ] 19.9% (used 5716 bytes from 28672 bytes)
Configuring upload protocol...
CURRENT: upload_protocol = avr109
Looking for upload port...
Use manually specified: stk500v2
avrdude: ser_open(): can't open device "usb": No such file or directory
avrdude done. Thank you.
*** [program] Error 1
=========================================== [ERROR] Took 1.28 seconds ===========================================
This is the platformio.ini I’m using… note the flags on each line mode needs them to be indented…
Just curious, have you tried Eclipse with the “Sloeber” plugin? Eclipse is a bit old-school compared to VSCode and Atom but it has all the important features: code completion, syntax highlighting, error highlighting, Arduino library manager, and git/github integration. I’ll bet your code executes fine when compiled in that environment. It’s my current IDE of choice because of its 100% runtime compatibility with the Arduino IDE and toolchain.
I programmed for Arduino in Eclipse once, but never used this Sloeber Plugin, i will as soon as i get another ATMEGA32u4 because mine has fried after some testing opening momentary serial ports to upload the code.
Hey @Beto… my Arduino Pro Micro (chinesy clone) has arrived, and after having some issues with it on Linux due to it being a 5v clone without the J1 jumper soldered :-/ … and very recent versions of ModemManager interfering with uploads to devices like Arduino Micros … I got it working just fine with your sample code unchanged, and the following platformio.ini (as I didn’t need to use my USBAsp to program it… although I did until I figured out WTH was going on with it on linux.) Arduino enumerates as a USB mouse, and the joystick moves the cursor around the screen and button left clicks on both Linux and Windows.
Thanks for the reply!
Your board is exactly the same as mine, so i think the key to solve this big problem is the line:
In the platformio.ini.
I’ll order another board in AliExpress to test with this configuration.
I see that Tennsy 2.0 also uses ATMEGA32u4 and is easier to program as it has a button to do so, i will get one Teensy 2.0 too.
Please let me know how you go with the Teensy 2… I have a Teensy 3.5 & 3.6 and love them… so I might end up doing the same also.
I’m actually wondering how you got the code to compile without the lib_deps line in the first place… did you install the library manually or into global storage, instead of letting platformio manage it?
All right, as soon as i get the Teensy 2.0 i will post some tests here.
I used the Platformio Library Manager to install the mouse and keyboard libraries, when i Ctrl+click in the include mouse.h the Platformio opens the mouse.h code, so the pio sees the library, i wonder if the line in the platformio.ini will work.
I found the solution to my AVR + WiFi101 library problem here.
IMO, PlatformIO should change the default for this lib_archive setting from ‘yes’ to ‘no’. WiFi101 is a very commonly used library in the Arduino AVR space. The Arduino WiFi shield and the Adafruit WiFi boards are all based on this chip and library that uses “weak” bindings at link time. Surely it can’t be the only Arduino library that does this? The worst part is that the library compiles with the lib_archive set to ‘yes’ or ‘no’, but it hangs in a loop when attempting to connect to the AP unless you override lib_archive to ‘no’. This is a serious failure to deliver seamless portability from the Arduino IDE to PlatformIO. I struggled with this problem for months - giving up on PIO several times. Please seriously consider making PlatformIO fully Arduino IDE and toolchain compatible even at the cost of some inefficiency.
That assumes that someone on the PIO team reviews every Arduino library to see if it’s using the ‘weak’ attribute and then sets lib_archive appropriately on a per-library basis. If there is a run-time way for PIO to detect a library’s use of the ‘weak’ feature, I guess that would be fine. However, I suspect the only universally safe answer is to make the default be ‘lib_archive = no’ for all Arduino libraries. The link step may take a bit longer but that’s a small price to pay versus the extreme pain (and negative opinions of PIO) caused by generating code that compiles and links but then doesn’t run correctly.
Agreed… I don’t know the time implications… so can’t comment there, but if we’re talking about milliseconds or a second in regards to the entire build, in the grand scheme of things, it’s nothing. But yes, either way, Arduino compatibility is of importance, so defaults need to be for that wherever possible.