The code compile in Arduino IDE and PlatformIO, but only works if using Arduino IDE

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
   date: 1/12/2012
   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.
 */

#include <Arduino.h>
#include <Mouse.h>
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;

void setup()
{
  pinMode(horzPin, INPUT);  // Set both analog pins as inputs
  pinMode(vertPin, INPUT);
  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
}

void loop()
{
  vertValue = analogRead(vertPin) - vertZero;  // read vertical offset
  horzValue = analogRead(horzPin) - horzZero;  // read horizontal offset
//delay(3000);

  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
  }
}

I am the only one that has tried to use Mouse.h in PlatformIO in VSCode???

Do you use the same Mouse library in both IDEs?

I compared the Mouse.h from .platformio/lib with the Mouse.h from program files\Arduino\libraries
I compared the Mouse.cpp from .platformio/lib with the Mouse.cpp from program files\Arduino\libraries

And they have exactly the same code!
All the files starts as this:

/*
  Mouse.h

  Copyright (c) 2015, Arduino LLC
  Original code (pre-library): Copyright (c) 2011, Peter Barrett

So, i think the problem is not the libraries, i also compared the library HID from both platforms and they are exactly the same too!

I tried to use AVRISP mkII programmer, platformio.ini:

[env:micro]
platform = atmelavr
board = micro
framework = arduino
upload_protocol = stk500v2
; each flag in a new line
upload_flags =
-Pusb

but i get this error on upload:

avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: ser_send(): write error: sorry no info avail
avrdude: stk500_send(): failed to send command to serial port

Do you use pio run -t program?

Thanks for the reply ivankravets, i used the command run -t program and i get and error:

Processing micro (platform: atmelavr; board: micro; framework: arduino)

Verbose mode can be enabled via -v, --verbose option
CONFIGURATION: Redirecting...
PLATFORM: Atmel AVR 1.13.0 > Arduino Micro
HARDWARE: ATMEGA32U4 16MHz, 2.50KB RAM, 28KB Flash
PACKAGES: toolchain-atmelavr 1.50400.0 (5.4.0), framework-arduinoavr 3.10623.190424 (1.6.23), tool-avrdude 1.60300.190424 (6.3.0)
LDF: Library Dependency Finder → Library Dependency Finder (LDF) — PlatformIO latest documentation
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 8 compatible libraries
Scanning dependencies…
Dependency Graph
|-- 1.0.1
| |-- 1.0
Checking size .pio\build\micro\firmware.elf
Memory Usage → Redirecting...
DATA: [= ] 8.2% (used 211 bytes from 2560 bytes)
PROGRAM: [== ] 19.9% (used 5716 bytes from 28672 bytes)
Configuring upload protocol…
AVAILABLE: avr109
CURRENT: upload_protocol = avr109
Looking for upload port…
Programming .pio\build\micro\firmware.hex
avrdude: ser_open(): can’t open device “unknown”: O sistema nÒo pode encontrar o arquivo especificado.

avrdude done. Thank you.

scons: *** [program] Error 1
======================================================================================= [ERROR] Took 1.48 seconds =======================================================================================

When i use stk500v2 with the command run -t program i get this error:

Processing micro (platform: atmelavr; board: micro; framework: arduino)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/micro.html
PLATFORM: Atmel AVR 1.13.0 > Arduino Micro
HARDWARE: ATMEGA32U4 16MHz, 2.50KB RAM, 28KB Flash
PACKAGES: toolchain-atmelavr 1.50400.0 (5.4.0), framework-arduinoavr 3.10623.190424 (1.6.23), tool-avrdude 1.60300.190424 (6.3.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 8 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Mouse> 1.0.1
|   |-- <HID> 1.0
Compiling .pio\build\micro\src\main.cpp.o
Compiling .pio\build\micro\lib488\HID\HID.cpp.o
Compiling .pio\build\micro\lib787\Mouse_ID890\Mouse.cpp.o
Archiving .pio\build\micro\libFrameworkArduinoVariant.a
Compiling .pio\build\micro\FrameworkArduino\CDC.cpp.o
Indexing .pio\build\micro\libFrameworkArduinoVariant.a
Archiving .pio\build\micro\lib488\libHID.a
Archiving .pio\build\micro\lib787\libMouse_ID890.a
Compiling .pio\build\micro\FrameworkArduino\HardwareSerial.cpp.o
Indexing .pio\build\micro\lib787\libMouse_ID890.a
Indexing .pio\build\micro\lib488\libHID.a
Compiling .pio\build\micro\FrameworkArduino\HardwareSerial0.cpp.o
Compiling .pio\build\micro\FrameworkArduino\HardwareSerial1.cpp.o
Compiling .pio\build\micro\FrameworkArduino\HardwareSerial2.cpp.o
Compiling .pio\build\micro\FrameworkArduino\HardwareSerial3.cpp.o
Compiling .pio\build\micro\FrameworkArduino\IPAddress.cpp.o
Compiling .pio\build\micro\FrameworkArduino\PluggableUSB.cpp.o
Compiling .pio\build\micro\FrameworkArduino\Print.cpp.o
Compiling .pio\build\micro\FrameworkArduino\Stream.cpp.o
Compiling .pio\build\micro\FrameworkArduino\Tone.cpp.o
Compiling .pio\build\micro\FrameworkArduino\USBCore.cpp.o
Compiling .pio\build\micro\FrameworkArduino\WInterrupts.c.o
Compiling .pio\build\micro\FrameworkArduino\WMath.cpp.o
Compiling .pio\build\micro\FrameworkArduino\WString.cpp.o
Compiling .pio\build\micro\FrameworkArduino\abi.cpp.o
Compiling .pio\build\micro\FrameworkArduino\hooks.c.o
Compiling .pio\build\micro\FrameworkArduino\main.cpp.o
Compiling .pio\build\micro\FrameworkArduino\new.cpp.o
Compiling .pio\build\micro\FrameworkArduino\wiring.c.o
Compiling .pio\build\micro\FrameworkArduino\wiring_analog.c.o
Compiling .pio\build\micro\FrameworkArduino\wiring_digital.c.o
Compiling .pio\build\micro\FrameworkArduino\wiring_pulse.S.o
Compiling .pio\build\micro\FrameworkArduino\wiring_pulse.c.o
Compiling .pio\build\micro\FrameworkArduino\wiring_shift.c.o
Archiving .pio\build\micro\libFrameworkArduino.a
Indexing .pio\build\micro\libFrameworkArduino.a
Linking .pio\build\micro\firmware.elf
Checking size .pio\build\micro\firmware.elf
Building .pio\build\micro\firmware.hex
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...
AVAILABLE: stk500v2
each flag in a new line
CURRENT: upload_protocol = stk500v2
each flag in a new line
Looking for upload port...
Programming .pio\build\micro\firmware.hex

avrdude done.  Thank you.

scons: *** [program] Error 1
======================================================================================= [ERROR] Took 6.63 seconds =======================================================================================

C:\Users\Beto\Documents\PlatformIO\Projects\KeyboardMouseControl>C:\Users\Beto\.platformio\penv\Scripts\platformio.exe run -t program
Processing micro (platform: atmelavr; board: micro; framework: arduino)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/micro.html
PLATFORM: Atmel AVR 1.13.0 > Arduino Micro
HARDWARE: ATMEGA32U4 16MHz, 2.50KB RAM, 28KB Flash
PACKAGES: toolchain-atmelavr 1.50400.0 (5.4.0), framework-arduinoavr 3.10623.190424 (1.6.23), tool-avrdude 1.60300.190424 (6.3.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 8 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Mouse> 1.0.1
|   |-- <HID> 1.0
Checking size .pio\build\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...
AVAILABLE: stk500v2
each flag in a new line
CURRENT: upload_protocol = stk500v2
Looking for upload port...
Programming .pio\build\micro\firmware.hex

avrdude done.  Thank you.

scons: *** [program] Error 1
======================================================================================= [ERROR] Took 1.56 seconds =======================================================================================

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
CONFIGURATION: https://docs.platformio.org/page/boards/atmelavr/micro.html
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
Scanning dependencies...
Dependency Graph
|-- <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...
AVAILABLE: avr109
CURRENT: upload_protocol = avr109
Looking for upload port...
Use manually specified: stk500v2
Programming .pioenvs/micro/firmware.hex
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…

; PlatformIO Project Configuration File
; 
; 890 = Mouse (https://www.arduino.cc/reference/en/language/functions/usb/mouse/)

[env:micro]
platform = atmelavr
board = micro
framework = arduino
lib_deps = 890
upload_port = stk500v2
upload_flags =
  -Pusb

One thing I find very peculiar is that the file size of both the Arduino IDE compiled version of that code, and the PlatformIO version is exactly the same (5716 flash, 211 ram), but it doesn’t work. :man_shrugging:

Sketch uses 5716 bytes (19%) of program storage space. Maximum is 28672 bytes.
Global variables use 211 bytes (8%) of dynamic memory, leaving 2349 bytes for local variables. Maximum is 2560 bytes

Only problem is I don’t have an Arduino Micro… I did have a Leonardo which has the same chip, but it died a sudden death a couple years back for no good reason.

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.

1 Like

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.

1 Like

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.

[env:micro]
platform = atmelavr
board = micro
framework = arduino
lib_deps = 
  Mouse

image

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:

lib_deps =
Mouse

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.

1 Like

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. :wink:

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. :grinning:
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.

Give it a try… maybe something wasn’t being compiled properly? Otherwise, I’d remove it from global library storage, and see if you have any luck then.

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.

1 Like

Since it can be configured on a per library basis, perhaps all that is needed is for that library to have that set?

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.

1 Like

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.