LoginSignup
1
1

More than 5 years have passed since last update.

AtmelStudioでu8glibを使用した開発環境を作る

Last updated at Posted at 2018-10-14

はじめに

ArduinoにてOLED, LCDなどのグラフィックデバイスを使用する場合はu8glibを使用しています。

AtmelStudioとUSBtinyISPでAVR(AtMega, ATtiny)の開発環境を作る
にてAtmelSudioでの開発環境をととのえましたので、こちらの環境でもu8glibを使用できるようにしました。

image.png
AtmelStudioでの開発

用意するもの

AtmelStudio

AtmelStudioの開発環境はこちらを参照してください。
AtmelStudioとUSBtinyISPでAVR(AtMega, ATtiny)の開発環境を作る

u8glib

u8glib for avrのソースをダウンロードして適当な場所に展開しておきます。

u8glibをコンパイルする

運用はソースをプロジェクトにリンクする方法で行うつもりですので、コンパイルはソースエラーがないかチェックするために行います。

C Static Library Projectを作成します。
image.png

Solution Exprolerで右クリックしAdd->Existing Item...を選択
image.png

ソースを選択します
image.png
リンクで追加ではなく、Addで追加します。(ファイルがプロジェクトにコピーされます)

AVR/GNU C Compiler -> Symbolsに

F_CPU=16000000UL

を追加
image.png

CPUの動作周波数にあわせて適宜修正してください。

ビルドします。
image.png

u8g_dev_t u8g_dev_rot = { u8g_dev_rot_dummy_fn, NULL, NULL };

でWarningが出ますが無視してOKです。

u8glibを使用したプロジェクトの作成

GCC C++ Executable Projectで作成します。
image.png

Solution Exprolerで右クリックしAdd->Existing Item...を選択
image.png
先程コンパイルしたソースを追加します。

Arduino Unoからソースを移植します。

UNOのソース
///////////////////////////////////////////////////////////
// OLEDテスト

//
// 2018/10/13 First, Based on OFFICE_CLOCK_R2
//
////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// 1. ArduinoでOLED表示をする
// 2. プロジェクトをAtmelStudioに移植
///////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////
// OLED with u8glib
//
// 1  VCC
// 2  GND
// 3  SCL  -- Pin A5 -OLD common use
// 4  SDA  -- Pin A4 -OLD common use
///////////////////////////////////////////////////////////////////////
#include "U8glib.h"   // OLED disp library
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI



void setup() {

  pinMode(0, INPUT_PULLUP);    // BTN1
  pinMode(1, INPUT_PULLUP);    // BTN2
  pinMode(2, INPUT_PULLUP);    // BTN3
  pinMode(3, INPUT_PULLUP);    // BTN4

  // flip screen, if required
  // u8g.setRot180();
  u8g.setContrast(0);                  // 液晶のコントラスト設定 0:暗い, 255:明るい(あんまり変らない)

  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255, 255, 255);
  }

  // Font set
  u8g.setFont(u8g_font_10x20);

}

void loop()
{
  long i = 0;
  if (1) // Setting
  {
    i = (analogRead(A0) / 10) * 5;
    DispSetting(0, i );
  }
  else  // ON Camera
  {

  }
  delay( 50 );
}

////////////////////////////////////////////////////////
// 設定画面
void DispSetting(byte modeSts, int setting)
{
  u8g.firstPage();
  do {
    drawStartupTime();
    drawTextMsg();
    drawMaruShikauSankaku();
  } while ( u8g.nextPage() );
}
////////////////////////////////////////////////////////
// 撮影中画面
void DispOnCamera()
{
  u8g.firstPage();
  do {
  } while ( u8g.nextPage() );
}

/////////////////////////////////////////////////////////////////////////////////////////////
// 設定画面SubFunc
////////////////////////////////////////////////////////////////////////////////////////////
char textbuffer[20];
/////////////////////////////////////////////////////////
// Time from Start up
void drawStartupTime()
{
  GetTimeText(textbuffer, millis()/1000, 0 );  // hour無し
  u8g.drawStr(5, 30 , textbuffer);
}
/////////////////////////////////////////////////////////
// DispMessage
void drawTextMsg()
{
  u8g.drawStr(5, 62 , "**G8LIB**");
}
/////////////////////////////////////////////////////////
// 図形描画
void drawMaruShikauSankaku()
{
  u8g.drawCircle(72, 24, 5);
  u8g.drawCircle(85, 24, 5);
  u8g.drawCircle(98, 24, 5);
}



/////////////////////////////////////////////////////////
// 時間フォーマットを返す
void GetTimeText(char* text, int time_sec, int format)
{
  if ( format == 1 && (time_sec / 3600 != 0))
    sprintf(text, "%01d:%02d", time_sec / 3600, (time_sec % 3600)/60 );
  else
    sprintf(text, "%02d:%02d", time_sec / 60, time_sec % 60 );
}

}

/////////////////////////////////////////////////////////
// 描画範囲のフレームを描く debug用途
void drawFlameBox()
{
  u8g.drawFrame( 0, 1, 127, 63);
}
AtmelStudioのソース

#ifndef F_CPU
#define F_CPU   16000000UL      // 16MHz
#endif

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include "Timer.h"

///////////////////////////////////////////////////////////////////////
// OLED with u8glib
//
// 1  VCC
// 2  GND
// 3  SCL  -- Pin A5 -OLD common use
// 4  SDA  -- Pin A4 -OLD common use
///////////////////////////////////////////////////////////////////////
#include "..\..\u8glib/u8glib/u8g.h"   // OLED disp library
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI
u8g_t u8g;

Timer timer;

void DispSetting(unsigned char modeSts, int setting);
void DispOnCamera();
void drawStartupTime();
void drawTextMsg();
void drawMaruShikauSankaku();
void GetTimeText(char* text, int time_sec, int format);

void setup(void)
{
    DDRB |= (1<<PB0);   // PB0 (PIN8 in Arduino UNO) as outputs (LED)
    DDRD =  0x00;       // PORTD (Pin 2-5) Input
    PORTD = 0x0F;       // PORTD 0-3 PULL-UP

    timer.StartTimer(); // 起動時からの時間

    u8g_InitI2C( &u8g, &u8g_dev_ssd1306_128x64_2x_i2c, U8G_I2C_OPT_NONE );

    // flip screen, if required
    // u8g_SetRot180(&u8g)
    u8g_SetContrast(&u8g, 0);                  // 液晶のコントラスト設定 0:暗い, 255:明るい(あんまり変らない)

    // set SPI backup if required
    // u8g_SetHardwareBackup(&u8g, u8g_backup_avr_spi);
    // assign default color value
    if ( u8g_GetMode(&u8g) == U8G_MODE_R3G3B2 ) {
        u8g_SetColorIndex(&u8g, 255);     // white
    }
    else if ( u8g_GetMode(&u8g) == U8G_MODE_GRAY2BIT ) {
        u8g_SetColorIndex(&u8g,3);         // max intensity
    }
    else if ( u8g_GetMode(&u8g) == U8G_MODE_BW ) {
        u8g_SetColorIndex(&u8g,1);         // pixel on
    }
    else if ( u8g_GetMode(&u8g) == U8G_MODE_HICOLOR ) {
        u8g_SetHiColorByRGB(&u8g, 255, 255, 255);
    }

    // Font set
    u8g_SetFont(&u8g,u8g_font_10x20);

}

int main(void)
{
    // setup
    setup();

    /* Replace with your application code */
    while (1) 
    {
        DispSetting(0, 0 );
        _delay_ms(50);
    }
}

////////////////////////////////////////////////////////
// 設定画面
void DispSetting(unsigned char modeSts, int setting)
{
    u8g_FirstPage(&u8g);
    do {
        drawStartupTime();
        drawTextMsg();
        drawMaruShikauSankaku();
    } while ( u8g_NextPage(&u8g) );
}
////////////////////////////////////////////////////////
// 撮影中画面
void DispOnCamera()
{
    u8g_FirstPage(&u8g);
    do {
    } while ( u8g_NextPage(&u8g) );
}

/////////////////////////////////////////////////////////////////////////////////////////////
// 設定画面SubFunc
////////////////////////////////////////////////////////////////////////////////////////////
char textbuffer[20];
/////////////////////////////////////////////////////////
// Time from Start up
void drawStartupTime()
{
    GetTimeText(textbuffer, timer.GetTime()/ 1000, 0 );  // hour無し
    u8g_DrawStr(&u8g, 5, 30 , textbuffer);
}
/////////////////////////////////////////////////////////
// DispMessage
void drawTextMsg()
{
    u8g_DrawStr(&u8g, 5, 62 , "**G8LIB**");
}
/////////////////////////////////////////////////////////
// 図形描画
void drawMaruShikauSankaku()
{
    u8g_draw_circle(&u8g, 72, 24, 5, U8G_DRAW_ALL);
    u8g_draw_circle(&u8g, 85, 24, 5, U8G_DRAW_ALL);
    u8g_draw_circle(&u8g, 98, 24, 5, U8G_DRAW_ALL);
}


/////////////////////////////////////////////////////////
// 時間フォーマットを返す
void GetTimeText(char* text, int time_sec, int format)
{
    if ( format == 1 && (time_sec / 3600 != 0))
    sprintf(text, "%01d:%02d", time_sec / 3600, (time_sec % 3600)/60 );
    else
    sprintf(text, "%02d:%02d", time_sec / 60, time_sec % 60 );

}

AVRのライブラリはCのコードですので、Arduinoとは呼出方法が変更となりますが、単純に置き換えていけば良いのでそれほど手間ではありません。

書き込み

ビルドが通ったら書き込むだけです。

image.png
Arduinoでの開発

image.png
AtmelStudioでの開発

同じ表示となりました。

終りに。

グラフィックもAtmelStudioで開発したくなり試してみました。Arduinoと異り、AtmelStudioではPULL-UPの設定にするにも仕様書を観る必要がありました。Arduinoでは色々と隠蔽されており御気軽ではありますが、動作が不安定になった場合何が問題なのかが追求しにくくなります。
一方AtmelStudioではコンフィグレジスタ等まで気を使ってソースを記載することになるため、本質の勉強になります。

あとIntentが気持ちわるく無いし、Intellisenseはあるしで最高ですね。

2018-10-14 Ikeda

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1