So-net無料ブログ作成

Lazurite 920Jを立ち上げてみる 其の7 #LAZURITE920J #ラピスセミコンダクタ [Lazurite]

lazuriteImage_004.jpg

まず言って置きます。LazuriteのI2Cの標準の速度は400kHzだぁ。つまずく事間違いなし。勿論私もつまづいた!
※setupの中で100kHzに落としてねー!

さて今日のお題はArudinoとかGR-KURUMIとか用に作成したライブラリの移植の話。

LazuriteはC++をサポートしていないので、ライブラリは全てCソースで記述しなければならない。
この辺を参照して欲しい。
http://hamayan.blog.so-net.ne.jp/2016-10-17

つまりArduinoのライブラリを持って来てもコンパイルすら通らないので、地道にコツコツCソースへの置き換えが必要となる。きっとここでめげる人多数、、、

とは言え買っちゃったのでなんとか使いこなす必要性から、なんとかしてみたいと思う。

今回移植するライブラリはGR-KURUMI用に作成したOLED表示器のライブラリです。
※ArduinoのライブラリをGR-KURUMIに持ってきた場合、かなりの確率でそのまま動く。修正が必要となったとしても、それ程手間ではない。

以下にGR-KURUMI用のソースを掲載します。
US2066.cpp ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
/*********************************************************************************/
/* US2066を使用したOLED SO1602AWGBの初期化と表示                                 */
/*                                         designed by hamayan since 2015/04/21  */
/*********************************************************************************/
#include  <RLduino78.h>
#include  <iodefine.h>
#include  <iodefine_ext.h>
#include  <US2066.h>

extern "C" {
  #include  <mul_tsk.h>
}

#if !defined( _MULTITASK_H_ )
#define  dly_tsk(tim)  delay(tim)
#define  rot_rdq()
#define  loc_cpu()     interrupts()
#define  unl_cpu()     noInterrupts()
#endif /*_MULTITASK_H_ */

US2066::US2066()
{
}

/****************************************************************************/
/* I2C block Write                                                          */
/****************************************************************************/
int US2066::blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len)
{
  Wire.beginTransmission(addr);
  Wire.write(dat,len);
  return Wire.endTransmission();
}

/*************************************************************************/
/* write command         */
/*************************************************************************/
int US2066::writeCommand(unsigned char t_command)
{
  unsigned char cmd[2];

  cmd[0] = 0x00;
  cmd[1] = t_command;

  return blkWrite( i2cAddress, cmd, sizeof(cmd) );
}

/*************************************************************************/
/* write data                                                            */
/*************************************************************************/
int US2066::writeData(unsigned char t_data)
{
  unsigned char dat[2];

  dat[0] = 0x40;
  dat[1] = t_data;

  return blkWrite( i2cAddress, dat, sizeof(dat) );
}

/*************************************************************************/
/* US2066初期化                                                          */
/*************************************************************************/
void US2066::init( unsigned char adr )
{
  i2cAddress = adr;  /*I2C address set*/

  dly_tsk(100);
  writeCommand( 0x01 );  //clear display
  dly_tsk(20);
  writeCommand( 0x02 );  //return home
  dly_tsk(2);
  writeCommand( 0x0f );  //send display on command
  dly_tsk(2);
  writeCommand( 0x01 );  //clear display
  dly_tsk(20);
}

/*************************************************************************/
/* clear display                                                         */
/*************************************************************************/
void US2066::clear( void )
{
  dly_tsk(100);
  writeCommand( 0x01 );  //clear display
  dly_tsk(20);
}

/*************************************************************************/
/* display on/off                                                        */
/*************************************************************************/
void US2066::OnOff( unsigned char onoff )
{
  writeCommand( onoff | 0x08 );  //display on/off,cursor on/off,blink on/off
  dly_tsk(20);
}

/*************************************************************************/
/* locate                                                                */
/*************************************************************************/
void US2066::locate( int x, int y )
{
  int temp = x + (y * 20);

  if(temp >= 20) temp = (temp - 20) + 0x20;

  writeCommand( (unsigned char)temp | 0x80 );  //set ddram address
  dly_tsk(20);
}

/*************************************************************************/
/* set contrast         */
/*************************************************************************/
void US2066::contrast( unsigned char cnt )
{
  //コントラスト調整
  writeCommand( 0x2a );  //RE=1
  writeCommand( 0x79 );  //SD=1
  writeCommand( 0x81 );  //contrast set
  writeCommand( cnt );  //contrast max
  writeCommand( 0x78 );  //SD=0
  writeCommand( 0x28 );  //set character size is normal.
  dly_tsk(100);
}

/*************************************************************************/
/* write strings                                                         */
/*************************************************************************/
int US2066::writeString( const char *str )
{
  unsigned char dat[1 * SO2002A_COLUMN + 1];
  int len = strlen(str);

  dat[0] = 0x40;
  len = (len > sizeof(dat) - 1) ? sizeof(dat) - 1 : len;
  memcpy( &dat[1], str, len );

  return blkWrite( i2cAddress, dat, len + 1 );
}

/*************************************************************************/
/* write strings                                                         */
/*************************************************************************/
int US2066::writeString( const char *str, unsigned int len )
{
  unsigned char dat[1 * SO2002A_COLUMN + 1];

  dat[0] = 0x40;
  len = (len > sizeof(dat) - 1) ? sizeof(dat) - 1 : len;
  memcpy( &dat[1], str, len );

  return blkWrite( i2cAddress, dat, len + 1 );
}

/*************************************************************************/
/* write strings                                                         */
/*************************************************************************/
int US2066::writeString( String str )
{
  return writeString( (const char *)&str[0], str.length() );
}

/*********************************************************************************/
/* end of file                                                                   */
/*********************************************************************************/

US2066.h ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
/****************************************************************************/
/* ssd1305  header                                                          */
/*                         Copyright (C) 2014 hamayan All Rights Reserved.  */
/****************************************************************************/
#ifndef US2066_h
#define US2066_h

#include <wire.h>

extern "C" {
}

//#define  US2066_0_ADR         0x3C
#define  SO2002A_LINES        2
#define  SO2002A_COLUMN       16
#define  SO2002A_DISPLAY_ON   0x04
#define  SO2002A_DISPLAY_OFF  0x00
#define  SO2002A_CURSOR_ON    0x02
#define  SO2002A_CURSOR_OFF   0x00
#define  SO2002A_BLINK_ON     0x01
#define  SO2002A_BLINK_OFF    0x00

class US2066 {
private:
  unsigned char i2cAddress;

  int blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len);
  int writeCommand(unsigned char t_command);
  int writeData(unsigned char t_data);

public:
  US2066();
  void init( unsigned char adr );
  void clear( void );
  void OnOff( unsigned char onoff );
  void locate( int x, int y );
  void contrast( unsigned char cnt );
  int  writeString( const char *str );
  int  writeString( const char *str, unsigned int len );
  int  writeString( String str );
};

#endif  /*US2066_H*/
/****************************************************************************/
/*                         Copyright (C) 2014 hamayan All Rights Reserved.  */
/****************************************************************************/


さてこれを移植するのですが、まずC++の記述スタイルはCには適用できない事が多い!
例えば関数のオーバーライド
  int  writeString( const char *str );
  int  writeString( const char *str, unsigned int len );
  int  writeString( String str );

なんてもろにダメですね!

  Wire.endTransmission();

こう言った省略もダメです。
まぁ実際にコンパイル掛けてみると色々エラーや警告出ますんで、一つ一つ潰していくしかない。

クラスのメッソッドっぽく記述し直す必要があります。例えば
US2066 oled;
 oled.init( 10 );

みたいに書きたいとすれば、関数名のリストを作った構造体を用意して、それで呼び出す事になります。

結局以下の様になりました。
US2066.c ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
/*********************************************************************************/
/* US2066を使用したOLED SO1602AWGBの初期化と表示                                 */
/*                                         designed by hamayan since 2015/04/21  */
/*********************************************************************************/
#include  <US2066.h>

#if !defined( _MULTITASK_H_ )
#define  dly_tsk(tim)  delay(tim)
#define  rot_rdq()
#define  loc_cpu()     interrupts()
#define  unl_cpu()     noInterrupts()
#endif /*_MULTITASK_H_ */

static unsigned char i2cAddress;

static int blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len);
static int writeCommand(unsigned char t_command);
static int writeData(unsigned char t_data);

/****************************************************************************/
/* I2C block Write                                                          */
/****************************************************************************/
static int blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len)
{
  Wire.beginTransmission(addr);
  Wire.write(dat,len);
  return Wire.endTransmission( true );
}

/*************************************************************************/
/* write command         */
/*************************************************************************/
static int writeCommand(unsigned char t_command)
{
  unsigned char cmd[2];

  cmd[0] = 0x00;
  cmd[1] = t_command;

  return blkWrite( i2cAddress, cmd, sizeof(cmd) );
}

/*************************************************************************/
/* write data                                                            */
/*************************************************************************/
static int writeData(unsigned char t_data)
{
  unsigned char dat[2];

  dat[0] = 0x40;
  dat[1] = t_data;

  return blkWrite( i2cAddress, dat, sizeof(dat) );
}

/*************************************************************************/
/* US2066初期化                                                          */
/*************************************************************************/
static void init( unsigned char adr )
{
  i2cAddress = adr;  /*I2C address set*/

  dly_tsk(100);
  writeCommand( 0x01 );  //clear display
  dly_tsk(20);
  writeCommand( 0x02 );  //return home
  dly_tsk(2);
  writeCommand( 0x0f );  //send display on command
  dly_tsk(2);
  writeCommand( 0x01 );  //clear display
  dly_tsk(20);
}

/*************************************************************************/
/* clear display                                                         */
/*************************************************************************/
static void clear( void )
{
  dly_tsk(100);
  writeCommand( 0x01 );  //clear display
  dly_tsk(20);
}

/*************************************************************************/
/* display on/off                                                        */
/*************************************************************************/
static void OnOff( unsigned char onoff )
{
  writeCommand( onoff | (unsigned char)0x08 );  //display on/off,cursor on/off,blink on/off
  dly_tsk(20);
}

/*************************************************************************/
/* locate                                                                */
/*************************************************************************/
static void locate( int x, int y )
{
  int temp = x + (y * 20);

  if(temp >= 20) temp = (temp - 20) + 0x20;

  writeCommand( (unsigned char)temp | (unsigned char)0x80 );  //set ddram address
  dly_tsk(20);
}

/*************************************************************************/
/* set contrast         */
/*************************************************************************/
static void contrast( unsigned char cnt )
{
  //コントラスト調整
  writeCommand( 0x2a );  //RE=1
  writeCommand( 0x79 );  //SD=1
  writeCommand( 0x81 );  //contrast set
  writeCommand( cnt );  //contrast max
  writeCommand( 0x78 );  //SD=0
  writeCommand( 0x28 );  //set character size is normal.
  dly_tsk(100);
}

/*************************************************************************/
/* write strings                                                         */
/*************************************************************************/
static int writeString( const char *str )
{
  unsigned char dat[1 * SO2002A_COLUMN + 1];
  int len = strlen(str);

  dat[0] = 0x40;
  len = (len > sizeof(dat) - 1) ? sizeof(dat) - 1 : len;
  memcpy( &dat[1], str, len );

  return blkWrite( i2cAddress, dat, len + 1 );
}

/*************************************************************************/
/* メンバー関数のリスト                                                  */
/*************************************************************************/
const t_US2066_I2C oled =
{
  init,
  clear,
  OnOff,
  locate,
  contrast,
  writeString,
};

/*********************************************************************************/
/* end of file                                                                   */
/*********************************************************************************/

US2066.h ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
/****************************************************************************/
/* ssd1305  header                                                          */
/*                         Copyright (C) 2014 hamayan All Rights Reserved.  */
/****************************************************************************/
#ifndef US2066_h
#define US2066_h

#include <Wire.h>

//#define  US2066_0_ADR         0x3C
#define  SO2002A_LINES        2
#define  SO2002A_COLUMN       16
#define  SO2002A_DISPLAY_ON   0x04
#define  SO2002A_DISPLAY_OFF  0x00
#define  SO2002A_CURSOR_ON    0x02
#define  SO2002A_CURSOR_OFF   0x00
#define  SO2002A_BLINK_ON     0x01
#define  SO2002A_BLINK_OFF    0x00

#if 0
class US2066 {
private:
  unsigned char i2cAddress;

  int blkWrite(unsigned char addr, const unsigned char *dat, unsigned int len);
  int writeCommand(unsigned char t_command);
  int writeData(unsigned char t_data);

public:
  US2066();
  void init( unsigned char adr );
  void clear( void );
  void OnOff( unsigned char onoff );
  void locate( int x, int y );
  void contrast( unsigned char cnt );
  int  writeString( const char *str );
  int  writeString( const char *str, unsigned int len );
  int  writeString( String str );
};
#else
typedef struct
{
  void (*init)( unsigned char adr );
  void (*clear)( void );
  void (*OnOff)( unsigned char onoff );
  void (*locate)( int x, int y );
  void (*contrast)( unsigned char cnt );
  int  (*writeString)( const char *str );
} t_US2066_I2C;

extern const t_US2066_I2C oled;
#endif

#endif  /*US2066_H*/

/****************************************************************************/
/*                         Copyright (C) 2014 hamayan All Rights Reserved.  */
/****************************************************************************/

※関数のオーバーライドの代替関数はめんどうくさいので止めちゃいました!
※BME280の移植をしていて気付いたのですが、long long型が使えない、、、

上記ソースを、Lazurite IDEが入っているフォルダーの中のlibraries以下に、ソースと同じ名前にしたフォルダーを生成し、そこに収納します。
lazuriteImage_022.png

この状態でIDEを起動するとこのライブラリが左端のライブラリリストに表示されますので、チェックします。
※I2CなのでWireにもチェックを入れます。
lazuriteImage_023.png


で、冒頭の表示プログラムが以下になります。
blue_led.c ※<とか>などhtmlに変換した時に正しく変換されていない可能性が有るので、使わない事。
#include "blue_led_ide.h"		// Additional Header
#include  "mcu.h"

#define  BLUE_LED		26
#define  US2066_ADDRESS (0x3C << 0)

void setup(void)
{
  digitalWrite(BLUE_LED,HIGH);
  pinMode(BLUE_LED,OUTPUT);

  Wire.begin();
  I21MD=0;  /*100khz setup*/

  oled.init( US2066_ADDRESS );
  oled.contrast( 0xff );
  oled.clear();
  oled.OnOff( SO2002A_DISPLAY_ON | SO2002A_CURSOR_OFF | SO2002A_BLINK_OFF );
  oled.writeString( "Lazurite 920J" );
  oled.locate( 0, 1 );
  oled.writeString( "  with OLED" );
}

void loop(void)
{
  digitalWrite(BLUE_LED,HIGH);
  delay(1000);
  digitalWrite(BLUE_LED,LOW);
  delay(1000);
}

冒頭でmcu.hをインクルードしていますが、I2Cの速度を落とす為に必要です。
またsetupの先頭の
  Wire.begin();
  I21MD=0;  /*100khz setup*/

も必要です。

※まぁこれくらいのコード量なら移植はそれほどでもですが、もっと複雑なコードだと厳しいですね。BME280の移植はそれなりに手間でしたよ。

※IDEのライブラリにBME280は登録されていますが、、、SPIで動かした時のライブラリで、I2Cではありませんでしたorz。

※いや、最大の問題はこんなライブラリの移植ではなく、フォーラムのレスポンスの悪さだったりして。


nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。