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

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.

Man the configuration in platformio didn’t work:

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

The J1 jumper makes no difference because i have always worked with it open (3.3V).

The configuration you posted didn’t work for me:

[env:micro]
platform = atmelavr
board = micro
framework = arduino
lib_archive = no

I tested the code in Sloeber and it worked swiftly! Pratical and efficient IDE, thank you for the indication.
As for the Platformio i have not found a solution yet.
But i’m happy to have found the Sloeber, a nice plugin in a great IDE that is Eclipse.

1 Like

Sorry to hear that. As I said earlier, it worked just fine with the code you provided with my board once I figured out why it wasn’t letting me upload to it without errors.

From your comments about the jumper, does that mean your Micro is a 3.3v one, rather than a 5v one (like mine is), meaning it’s running at 8Mhz, not 16Mhz? If so, this line would probably be needed in the platformio.ini (or perhaps using the sparkfun_promicro8 board setting instead?)

board_build.f_cpu = 8000000L

Regardless, good to hear you have a working environment now. :slight_smile:

I uninstalled the Mouse.h in library manager and after i build the project, platformio automatically downloaded the library in libdeps folder.
But even so, the mouse doesn’t respond to the analog stick after i upload the code to the micro board!
Whyyyyyyyyyyyyyyyyyyyy???

screen

Did you see my earlier reply about the clock speed, since you said you’re using a 3.3v board, not a 5v one, hence it should be running at a different clock speed than the micro (the genuine Micro never had a 3.3v version AFAIK, only the sparkfun pro micro came in both variants).

Mas i used the board_build.f_cpu = 8000000L and i almost lose my board! The Device Manager doesn’t recognize my board anymore, it only shows “Unknown Device”, i cannot upload my code, the COM Port didn’t exist! So i searched the internet for a solution and the forums only says that i need to buy a AVRISP MkII programmer to send the bootloader to the board via ICSP to make it work again!
But I found a solution myself, I reset the board and ran the upload command, and when platformio waited for the upload port I reset the board again and miraculously the upload worked!
Man, I almost got screwed over this option.

PS: In Arduino IDE and in the Sloeber IDE this project works very well!

Ok, so that sounds like the clock fuse is set for 16Mhz… are you sure it is a 3.3v Micro? You don’t need a AVRISP MkII programmer… you just need a ISP programmer, which you can use another Arduino to emulate. And once I got over the initial problems of board not wanting to upload with any IDE (PlatformIO or Arduino IDE) it worked just fine for me… so it still seems like something is different with your configuration.

Try a simple test to see if the clock speed of the CPU is the same as what the program expects… blink test with 1000ms delay… does it blink on/off with 1 second delay between state changes, or is it slower?

#include <Arduino.h>
void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN,LOW);
  }

void loop()
{
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  delay(1000);
}

Yeah, i know i can use any ICSP programmer, but i only have one for PIC microcontrolers and one TTL to USB device. Thank God i could fix without the need to buy one for Arduino boards.
The micro does not have a built in LED, but i can control the RX and TX Leds:

#include <Arduino.h>

int RXLED = 17;  // The RX LED has a defined Arduino pin
// The TX LED was not so lucky, we'll need to use pre-defined
// macros (TXLED1, TXLED0) to control that.
// (We could use the same macros for the RX LED too -- RXLED1,
//  and RXLED0.)

void setup()
{
  pinMode(RXLED, OUTPUT);  // Set RX LED as an output
  // TX LED is set as an output behind the scenes

  //Serial.begin(9600); //This pipes to the serial monitor
  Serial1.begin(9600); //This is the UART, pipes to sensors attached to board
}

void loop()
{
  //Serial.println("Hello world");  // Print "Hello World" to the Serial Monitor
  //Serial1.println("Hello!");  // Print "Hello!" over hardware UART

  digitalWrite(RXLED, LOW);   // set the RX LED ON
  delay(10);              

  digitalWrite(RXLED, HIGH);    // set the RX LED OFF
  delay(1000);              
}

The RX LED blinks every exact 1 second!

My board comes with the J1 jumper opened, so the board is regulating the 5V from the USB to 3.3V? I’m thinking to short the Jumper.

That’s what I would have thought…

So, the other thing to double check as a final sanity check would be the crystal - does it have 16.000Mhz *(or similar) stamped on it?

Since you’re getting 1 sec on, 1 second off… all should be good there - that board_build.f_cpu = 8000000L is definitely not needed at all!!

And if the code is working fine with the Arduino IDE / Eclipse /w Sloeber, then it shouldn’t be the hardware at fault… but it shouldn’t hurt to change the jumper if you have a soldering iron handy… easily enough to remove the solder blob if it doesn’t give you any joy. However, I don’t think it will make matters worse, as going by this schematic, it should bypass the 3v3 regulator, and supply the ~4.7-5.0 coming from your USB directly to VCC, which means the VCC voltage will be what the ATmega32U4 actually wants.

The interesting thing is when measuring the VCC and the RAW pins they are providing 4.7V! Same on the digital ports (when they are configured as Outputs)! And the J1 is open!

The crystal on my board has 16.000 MHz stamped on it. I think the board is working with 5V/16MHz although the J1 is open, hahaha.

Raw should always be whatever comes from the USB (if powered over USB)… but yeah, Vcc being the same suggests chip is getting 5v, not 3.3v… but you can run this sketch to make sure… it’s not very accurate as the internal 1v1 bandgap value would need to be measured as IIRC it can vary 0.1v +/- from part to part … but it is plenty good enough for this job… 4.90v at the USB port is measured as 4.98v by my board.

#include <Arduino.h>

long readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
  #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
     ADMUX = _BV(MUX5) | _BV(MUX0) ;
  #else
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #endif  
 
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA,ADSC)); // measuring
 
  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
  uint8_t high = ADCH; // unlocks both
 
  long result = (high<<8) | low;
 
  result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts
}

void setup()
{
  Serial.begin(9600);
  while (!Serial){
    ;
  }
  delay(500);
  Serial.println("Ready!");
}

void loop()
{
  long vcc = readVcc();
  Serial.println("Vcc is = " + String(vcc*0.001));
  delay(1000);
}