Precompile Arduino code for Raspberry Pi

I have a robot with several Arduinos controlled by a Raspberry Pi. Compiling the arduino code takes a while on the Pi. Is there a way to compile the code on my computer and transfer the compiled machine code to the pi over ssh, then have the pi upload that code to an arduino?

Very interesting task :slight_smile: Have ever used Python? I can explain you how to do it. It’s very easy with PlatformIO.

I have used python minimally. I much prefer node.js. I would love for you to explain it to me. Thanks! :smiley:

I’ll prepare something for you tomorrow. My time is 1 a.m. :sleeping:

What? I didn’t think programmers slept. Thanks for your help!

1 Like

I see that you use PlatformIO from the CLI. It significantly simplifies your task. I thought that you use PlatformIO IDE.

  1. Process environment (build) via platformio run
  2. Take a look at .pioenvs cache directory. It contains firmware.hex per each environment.
  3. Initialize new helper project on Raspberry Pi. For example, mkdir /tmp/piotmp; platformio init -d /tmp/piotmp.
  4. Copy/replace local files from the project to Raspberry Pi. platformio.ini -> /tmp/piotmp/platformio.ini and .pioenvs/*/firmware.hex-> /tmp/piotmp/.pioenvs/*/firmware.hex.
  5. Run on Raspberry PI platformio run -d /tmp/piotmp --disable-auto-clean -t nobuild -t upload. This command will upload firmware to the all nodes without rebuilding using existing cached firmware.hex.

You can write for these steps single script and run it. For the 4 step I recommend to use rsync.

In any case, this is just a hint. There are a few other ways how to do it. I recommend to start from this approach because you will understand how does it work. Later, I’ll explain how to make it using extra_script.

Thanks for your answer. Very informative. I am using flightplan.js to get my code onto the pi (which uses rsync).

I moved this topic to FAQ category. Please provide here your solution it will be useful for other users. Thanks.

As requested, my flightplan.js:

var plan = require('flightplan');

var arduinos = {
	wheels: { port: 'ttyWHEELS' },
	eyes:   { port: 'ttyEYES' },
	uno:    { port: 'ttyUNO' },
};

var name = '';
var arduino = {};

plan.target('pi', {
	host: '192.168.0.102',
	username: 'pi',
	agent: process.env.SSH_AUTH_SOCK

});

plan.target('odroid', {
	host: '192.168.0.103',
	username: 'odroid',
	agent: process.env.SSH_AUTH_SOCK
});

function transfer(local){
	local.log('Copying files to Pi');


	// Git's files

	var files1 = local.exec('git ls-files && git ls-files -o --exclude-standard', {silent: true}).stdout.trim().split('\n');;
	var deleted = local.exec('git ls-files -d', {silent: true}).stdout;


	// Remove deleted files from list

	if(deleted){
		deleted = deleted.trim().split('\n');

		files1 = files1.filter((item) => {
			return deleted.indexOf(item) < 0;
		});
	}


	// Remove ingored files from list

	files1 = files1.filter((item) => {
		return item.indexOf('images') === -1;
	});


	// Precompiled arduino code

	var files2 = local.find('arduino/.pioenvs/*/firmware.hex', {silent: true}).stdout.trim().split('\n');

	var filesToCopy = files1.concat(files2);

	// console.log(filesToCopy);
	local.transfer(filesToCopy, '~/eurobot2016/');
}

plan.local('py', (local) => {
	transfer(local);
});

plan.local(Object.keys(arduinos), (local) => {
	name = plan.runtime.task;
	arduino = arduinos[name] || 'lcd';


	local.log('Compiling Arduino code for ' + name);
	local.exec('pio run -d ./arduino/ -e ' + name);

	transfer(local);
});

plan.remote(Object.keys(arduinos), (remote) => {
	var params = [
		'--disable-auto-clean',
		'-t uploadlazy',
		'-d ~/eurobot2016/arduino/',
		'-e', name,
		'--upload-port', '/dev/' + arduino.port
	];

	remote.log('Uploading to ' + name);
	remote.exec('pio run ' + params.join(' '), {silent: true});
});

Edit 1: upadted above code.

@ivankravets Has this functionality changed? When I try to use uploadlazy now, I get

pio run --disable-auto-clean -t uploadlazy -d /home/marcel/code/marlin -e megaatmega2560
[Sun Jun 17 11:43:26 2018] Processing megaatmega2560 (platform: atmelavr; board: megaatmega2560; framework: arduino)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
PLATFORM: Atmel AVR > Arduino Mega or Mega 2560 ATmega2560 (Mega 2560)
SYSTEM: ATMEGA2560 16MHz 8KB RAM (248KB Flash)
Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF MODES: FINDER(chain) COMPATIBILITY(soft)
Collected 24 compatible libraries
Scanning dependencies...
No dependencies
*** Do not know how to make File target `uploadlazy' (/home/marcel/code/marlin/uploadlazy).  Stop.

A few years ago it was changed to nobuild. See updated post above.

Working now. Thanks.