勤務校のマイコン実習をPIC + MPLAB から AVR + Arduino IDE に転換する作業を実施しているが,少々困ったことが起きた。

このマイコン実習で初めてC,C++プログラミングに取り組む生徒さんが多く,C言語について基本的なことをしっかりやらなければならない。

「C言語プログラムは起動すると,まず,main関数が実行される…」と教えたいのだが,Arduinoのスケッチ(プログラム)にはmain関数は無く…それができない。Arduinoではmain関数は裏に隠れていて,その働きはsetup関数とloop関数で実装されている。

…と,いうことで Arduino IDE で setup,loopを使わないでmain関数から実行する方法がないか試してみた。

ダメ元でArduino IDE の裏に隠れているmain.cppを参考にしてmain関数を書いてコンパイルしたらエラーにならずArduino UNOに書き込んで正しく動いた! Arduino IDE 1.6系でもOK。

arduino_main

main関数のある標準的C言語プログラムで導入して,適当な時期でsetup(),loop()形式のプログラムに移行しようと思う。

注意

  1. スケッチの名前を main で保存すると,main.cppと競合するらしくコンパイルエラーが出る。
  2. 上の例ではシリアル通信ができない。
    シリアル通信を行う場合は,無限ループのところにシリアル通信のイベントを見てハンドラを呼ぶ行を置く。
      if (serialEventRun) serialEventRun();

参照した main.cpp

/*
  main.cpp - Main loop for Arduino sketches
  Copyright (c) 2005-2013 Arduino Team.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include <Arduino.h>

//Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (*func)()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

int main(void)
{
	init();

	initVariant();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}

Follow me!