2015年09月30日

GR-PEACHを使う(2): GR-PEACHのサンプルをmbedでコンパイル

昨日まででmbedのクラウド上でGP-PEACHのサンプルを作成するところまで実行しました。

それではまずワークスペース上でmain.cppをダブルクリックしてみます。
言い忘れていましたがmbed環境は通常C++です、ライブラリがC++前提となっており
とても短い記述で使えるようになっています。

クリックするとそのファイルが真ん中に表示されます。
GR_A_009.png


mbed環境ではLED1とかLED2などがすでにmbedのオンラインコンパイラ側(正確にいうとGR-PEACHのライブラリやヘッダなど)で定義されており、いちいち実際のポートの設定などを調べる必要がありません。まあ実際にどこがつくかなどはおいおい調べていきましょう。。

このmain.cppで重要ポイントは以下の2点でしょう。
DigitalOut myled(LED1);
 myled = 1;

まず、DigitalOutはmbedのライブラリでデジタルの出力用するためのクラスで、LED1をデジタル出力として定義します。
実際にはGPIOになります。このライブラリの良いところは、この定義をするだけで初期化をやってくれるところです。
C++のコンストラクタが動きますので、大変便利です(ただ、実行時間はかかりますけどね)。
でmyled=1でポートに1を出力しますし、myled=0で0を出力します。
こうしたライブラリが用意されているのがこのmbedの環境となります。

次にコンパイルしてみましょう。Compilerをクリックするとコンパイラを実行し、おわるとコンパイルした結果をバイナリファイルにしてこちらに送ってくれます。これをまずセーブしましょう。
GR_A_010.png

これでコンパイルが終わりました。


タグ:RZ/A1 Cortex-A9
posted by EWARMJP at 12:00| Comment(0) | TrackBack(0) | Renesas | このブログの読者になる | 更新情報をチェックする

2015年09月29日

GR-PEACHを使う(1): GR-PEACHとmbed

新しいボードを見つけました。

GR-PEACHという小さなボードです。小さいのですがなんとCPUコアにCortex-A9で400MHzで動作します。
また内蔵RAMに10MBとリッチなボードです。
GR_A_001.png

どこで売っているか?というと若松さんとかで販売しています。
値段も一万円を切っており、比較的入手しやすいです。

さて、このボードをの特徴はmbedに対応しているということです。
mbedとは?という方に簡単に説明すると、mbedとはARM社が提供しているオンライン上での開発環境です。
このため、通常の開発では自分のPCなどにコンパイラなどをインストールして、そのPC上のコンパイラで開発をすると思いますが、
オンライン上のコンパイラがありますので、ブラウザがあればソフトウェアの開発ができるというものです。

まずmbedの環境を見てみましょう. www.mbed.orgに行ってみましょう。
GR_A_002.png

ここでdeveloperサイトに行きます。開発環境を使うためにはsignupをしてください。

GR_A_003.png

signed upを済ませてログインしましょう。そして、上部のPlatformsという部分をクリックください。
GR_A_004.png

スクロールするとGR-PEACHがいます。
GR_A_005.png

GR-PEACHをクリックします。すると以下のようなページになります。
オンラインコンパイラを使うためには、ここで add to your mbed Compilerをクリックして登録しておく必要があります。
GR_A_006.png

これが終わったら、画面にはGR-PEACHが追加されたと表示されています。
GR_A_007.png
Compiler画面にします。そのために "Open mbed Compiler"をクリックします。


するといきなりLED点滅のプログラムを作りますとい状態になります。そこで”OK”します。
GR_A_008.png

今日はここまでにしておきます。。。続きはまた明日。。。





posted by EWARMJP at 12:00| Comment(0) | TrackBack(0) | Renesas | このブログの読者になる | 更新情報をチェックする

2015年09月28日

LPC11U14を使ってみる:まとめ

まだ、調整などは残っていますが、LPC11U14のこれまでのところをまとめておきます。

LPC11U14を使ってみる(1): ボードの素性と開発環境               
LPC11U14を使ってみる(2): EWARMで接続しようとしたらLPC-LINKは・・・    
LPC11U14を使ってみる(3):もとのコードが無い時のアタッチは?    
LPC11U14を使ってみる(4):サンプルを探します               
LPC11U14を使ってみる(5):サンプルのメイク             
LPC11U14を使ってみる(6):SPIを使うために1             
LPC11U14を使ってみる(7):SPIを使うために2               
LPC11U14を使ってみる(8):SPIを使うために3               
LPC11U14を使ってみる(9):SPIを使うために4               
LPC11U14を使ってみる(10):LPC11U14でSSELの制御は?           
LPC11U14を使ってみる(11):SPIでSSELの制御がほかのマイコンではLPC810  
LPC11U14を使ってみる(12):SPIでSSELの制御がほかのマイコンではSTM32F4  
LPC11U14を使ってみる(13):実際の波形を観測
LPC11U14を使ってみる(14):SPIのコードを書いたが動きがおかしい      
LPC11U14を使ってみる(15):SPIの動きを理解する               
LPC11U14を使ってみる(16):SPIの信号を観測してみる          
LPC11U14を使ってみる(17):ステップから一気に実行してみると結果が…   
LPC11U14を使ってみる(18):デバッガを使う時の注意            
LPC11U14を使ってみる(19):SSELを自分でコントロールする      
LPC11U14を使ってみる(20):温湿度・気圧センサモジュールBME280登場      
LPC11U14を使ってみる(21):GPIO制御のSSELを観測してみます          
LPC11U14を使ってみる(22):BME280登場を調べます               
LPC11U14を使ってみる(23):BME280の補正を調べます
LPC11U14を使ってみる(24):BME280の補正データの読み出し           
LPC11U14を使ってみる(25):BME280の補正関数の実装               
タグ:LPC11U14 EWARM
posted by EWARMJP at 12:00| Comment(0) | TrackBack(0) | まとめトップ | このブログの読者になる | 更新情報をチェックする

2015年09月27日

LPC11U14を使ってみる(25):BME280の補正関数の実装

昨日で補正データについては、取得できました。
それでは、補正関数を作成します。

前に見たように、BME280のマニュアルでは以下の3つのデータ型を使って補正関数を定義していました。
BME280_S32_t、BME280_U32_t、BME280_S64_t です。

このうち前の2つは32ビットの符号付きおよび符号なし整数ですので、Cortex-M0の場合にはsigned intとunsigned intにすれば良いです。
もし、移植性などを考慮するならばstdint.hで定義されているint32_tとuint32_tを使えばよいでしょう。

64ビットの整数はEWARMのマニュアルを確認してみます。signed long longで64ビットの符号付きという記述があります。
LPC11U14_P041.png

これで3つのデータ型は以下のように定義しました。
typedef  signed int  BME280_S32_t;
typedef  unsigned int  BME280_U32_t;
typedef signed long long BME280_S64_t;


あと、BME280からアルゴリズムをコピー&ペーストした時の -が?になることがありましたが、
それ以外はあまり問題もなく、コンパイルが出来るようになりました。

// Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
// t_fine carries fine temperature as global value
BME280_S32_t t_fine;
BME280_S32_t BME280_compensate_T_int32(BME280_S32_t adc_T)
{
  BME280_S32_t var1, var2, T;
  var1 = ((((adc_T>>3) - ((BME280_S32_t)dig_T1<<1))) * ((BME280_S32_t)dig_T2)) >> 11;
  var2 = (((((adc_T>>4) - ((BME280_S32_t)dig_T1)) * ((adc_T>>4) - ((BME280_S32_t)dig_T1))) >> 12) *((BME280_S32_t)dig_T3)) >> 14;
  t_fine = var1 + var2;
  T = (t_fine * 5 + 128) >> 8;
  return T;
}

// Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
// Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
BME280_U32_t BME280_compensate_P_int64(BME280_S32_t adc_P)
{
  BME280_S64_t var1, var2, p;
  var1 = ((BME280_S64_t)t_fine) - 128000;
  var2 = var1 * var1 * (BME280_S64_t)dig_P6;
  var2 = var2 + ((var1*(BME280_S64_t)dig_P5)<<17);
  var2 = var2 + (((BME280_S64_t)dig_P4)<<35);
  var1 = ((var1 * var1 * (BME280_S64_t)dig_P3)>>8) + ((var1 * (BME280_S64_t)dig_P2)<<12);
  var1 = (((((BME280_S64_t)1)<<47)+var1))*((BME280_S64_t)dig_P1)>>33;
  if (var1 == 0)
  {
    return 0; // avoid exception caused by division by zero
  }
  p = 1048576-adc_P;
  p = (((p<<31)-var2)*3125)/var1;
  var1 = (((BME280_S64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
  var2 = (((BME280_S64_t)dig_P8) * p) >> 19;
  p = ((p + var1 + var2) >> 8) + (((BME280_S64_t)dig_P7)<<4);
  return (BME280_U32_t)p;
}

// Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
// Output value of “47445” represents 47445/1024 = 46.333 %RH
BME280_U32_t bme280_compensate_H_int32(BME280_S32_t adc_H)
{
  BME280_S32_t v_x1_u32r;
  v_x1_u32r = (t_fine - ((BME280_S32_t)76800));
  v_x1_u32r = (((((adc_H << 14) - (((BME280_S32_t)dig_H4) << 20) - (((BME280_S32_t)dig_H5) * v_x1_u32r)) +
                 ((BME280_S32_t)16384)) >> 15) * (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * (((v_x1_u32r *
                                                                                                        ((BME280_S32_t)dig_H3)) >> 11) + ((BME280_S32_t)32768))) >> 10) + ((BME280_S32_t)2097152)) *
                                                   ((BME280_S32_t)dig_H2) + 8192) >> 14));
  v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((BME280_S32_t)dig_H1)) >> 4));
  v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
  v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
  return (BME280_U32_t)(v_x1_u32r>>12);
}    

実行結果がPRESSUREがおかしいです。。
AA:temp=41.880000
AA: hum=62.905273
AA: press=258239.620000

温度もすこし高いなぁ。。。 気圧がとんでもない値に。。。



タグ:LPC11U14 EWARM
posted by EWARMJP at 12:00| Comment(0) | TrackBack(0) | NXP | このブログの読者になる | 更新情報をチェックする

2015年09月26日

LPC11U14を使ってみる(24):BME280の補正データの読み出し

機能までの補正をコーディングしてみます。
まずは動くところの確認をしたいので、コードが汚いのはごめんなさい。


unsigned char BME280_basic_trans( unsigned char wdat) {
  unsigned char rdat;
 
   while ( (LPC_SSP->SR & 0x2) == 0 ); /*TNF 0: full,  1 not full */
  ////送信
  LPC_SSP ->DR = (wdat & 0xFF);// address ID
  ///受信
  while ( (LPC_SSP->SR  & 0x4) == 0 ); /* RNE 0:empty, RNE 1: not empty*/
  rdat = LPC_SSP->DR;
 
  return rdat;
}

volatile  unsigned short dig_T1;
volatile  signed   short dig_T2;
volatile  signed   short dig_T3;
volatile  unsigned short dig_P1;
volatile  signed   short dig_P2;
volatile  signed   short dig_P3;
volatile  signed   short dig_P4;
volatile  signed   short dig_P5;
volatile  signed   short dig_P6;
volatile  signed   short dig_P7;
volatile  signed   short dig_P8;
volatile  signed   short dig_P9;
volatile  unsigned char  dig_H1;
volatile  signed   short dig_H2;
volatile  unsigned char  dig_H3;
volatile  signed   short dig_H4;
volatile  signed   short dig_H5;
volatile  signed   char  dig_H6;

void BME280_print_calidata() {
  printf("dig_T1 = %d\n", dig_T1);
  printf("dig_T2 = %d\n", dig_T2);
  printf("dig_T3 = %d\n", dig_T3);
  printf("dig_P1 = %d\n", dig_P1);
  printf("dig_P2 = %d\n", dig_P2);
  printf("dig_P3 = %d\n", dig_P3);  
  printf("dig_P4 = %d\n", dig_P4); 
  printf("dig_P5 = %d\n", dig_P5);
  printf("dig_P6 = %d\n", dig_P6);
  printf("dig_P7 = %d\n", dig_P7);   
  printf("dig_P8 = %d\n", dig_P8);   
  printf("dig_P9 = %d\n", dig_P9);   
  printf("dig_H1 = %d\n", dig_H1);  
  printf("dig_H2 = %d\n", dig_H2);
  printf("dig_H3 = %d\n", dig_H3);   
  printf("dig_H4 = %d\n", dig_H4);  
  printf("dig_H5 = %d\n", dig_H5); 
  printf("dig_H6 = %d\n", dig_H6);   
}


void BME280_get_calidata( void ) {
  volatile unsigned char rd, wd;
  volatile int i;
   LPC_GPIO_PORT->CLR[0] = 0x4;
  
   // send address
   wd = 0x88  & 0xFF; // MSB=0 write 1:read
   rd=BME280_basic_trans(wd);
   //
   wd = 0x0; // dummy data;
   dig_T1 =BME280_basic_trans(wd); // 0x88
   //
   dig_T1 =(BME280_basic_trans(wd) << 8 ) | dig_T1; // 0x89
   //
   dig_T2=BME280_basic_trans(wd); // 0x8A
   //
   dig_T2=(BME280_basic_trans(wd) << 8 ) | dig_T2; // 0x8B
   //
   dig_T3=BME280_basic_trans(wd); // 0x8C
   //
   dig_T3=(BME280_basic_trans(wd)<<8 ) | dig_T3; // 0x8D
   //
   dig_P1=BME280_basic_trans(wd); // 0x8E
   //
   dig_P1=(BME280_basic_trans(wd)<<8) | dig_P1; // 0x8F
   //
   dig_P2=BME280_basic_trans(wd); // 0x90
   //
   dig_P2=(BME280_basic_trans(wd)<<8) | dig_P2; // 0x91
   //  
   dig_P3=BME280_basic_trans(wd); // 0x92
   //
   dig_P3=(BME280_basic_trans(wd)<<8)| dig_P3; // 0x93
   //  
   dig_P4=BME280_basic_trans(wd); // 0x94
   //
   dig_P4=(BME280_basic_trans(wd)<<8)| dig_P4; // 0x95
   //  
   dig_P5=BME280_basic_trans(wd); // 0x96
   //
   dig_P5=(BME280_basic_trans(wd)<<8) | dig_P5; // 0x97
   //  
   dig_P6=BME280_basic_trans(wd); // 0x98
   //
   dig_P6=(BME280_basic_trans(wd)<<8)| dig_P6; // 0x99
   //  
   dig_P7=BME280_basic_trans(wd); // 0x9A
   //
   dig_P7=(BME280_basic_trans(wd)| dig_P7); // 0x9B
   // 
   dig_P8=BME280_basic_trans(wd); // 0x9C
   //
   dig_P8=(BME280_basic_trans(wd)<<8)| dig_P8; // 0x9D
   //    
   dig_P9=BME280_basic_trans(wd); // 0x9E
   //
   dig_P9=(BME280_basic_trans(wd)<<8) | dig_P9; // 0x9F
   //    
   LPC_GPIO_PORT->SET[0] = 0x4;
   ///////////////////////////////////
   for (i=0;i<100;i++);
   ///////////////////////////////////
   LPC_GPIO_PORT->CLR[0] = 0x4;
  
   // send address
   wd = 0xA1  & 0xFF; // MSB=0 when write/ 1 read
   rd=BME280_basic_trans(wd);
   //
   wd = 0x0; // dummy data;
   dig_H1=BME280_basic_trans(wd); // 0xA1
  
   LPC_GPIO_PORT->SET[0] = 0x4;
  
   ///////////////////////////////////
   for (i=0;i<100;i++);
   ///////////////////////////////////
   LPC_GPIO_PORT->CLR[0] = 0x4;
  
   // send address
   wd = 0xE1  & 0xFF; // MSB=0 when write/ 1 read
   rd=BME280_basic_trans(wd);
   //
   wd = 0x0; // dummy data;
   dig_H2=BME280_basic_trans(wd); // 0xE1
   //
   dig_H2=(BME280_basic_trans(wd)<<8) | (dig_H2); // 0xE2
   //
   dig_H3=BME280_basic_trans(wd); // 0xE3
   //
   dig_H4=BME280_basic_trans(wd); // 0xE4
   //  
   rd=BME280_basic_trans(wd); // 0xE5
   dig_H4 = (dig_H4<<4) | (rd & 0xF) ;
   //       
   dig_H5=(BME280_basic_trans(wd)<<4)| (rd>>4); // 0xE6
   //  
   dig_H6=BME280_basic_trans(wd); // 0xE7
   //
   LPC_GPIO_PORT->SET[0] = 0x4;   
  
}

正直、細かいところがあっているかどうかは心配ですが、まずは実行してみます。
dig_T1 = 28547
dig_T2 = 26442
dig_T3 = 50
dig_P1 = 36285
dig_P2 = -10801
dig_P3 = 3024
dig_P4 = 5688
dig_P5 = 91
dig_P6 = -7
dig_P7 = 174
dig_P8 = -10230
dig_P9 = 4285
dig_H1 = 75
dig_H2 = 349
dig_H3 = 0
dig_H4 = 349
dig_H5 = 0
dig_H6 = 30

とりあえず何かデータは読み出せているようです。


と言いながら、一回失敗してから再度チェックしてこの結果となりました。





タグ:LPC11U14 EWARM
posted by EWARMJP at 12:00| Comment(0) | TrackBack(0) | NXP | このブログの読者になる | 更新情報をチェックする

2015年09月25日

LPC11U14を使ってみる(23):BME280の補正を調べます

それでは、BME280の補正を調べてみます。

まず変数は以下のビット幅が必要です。
  • 気圧と温度は20ビットなので、32ビットsigned整数
  • 湿度は16ビットなので、32ビットsigned整数

補正アルゴリズムはボッシュのマニュアルにあるので、見てみます。
この時に独自に定義されたデータ型があるので
  • BME280_S32_t 32ビットsigned整数
  • BME280_U32_t 32ビットunsigned 整数
  • BME280_S64_t 64ビットsigned整数

さてまずは温度補正は以下の関数で実行できます。正直t_fineがグローバルな理由が解っていませんが。
// Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
// t_fine carries fine temperature as global value
BME280_S32_t t_fine;
BME280_S32_t BME280_compensate_T_int32(BME280_S32_t adc_T)
{
  BME280_S32_t var1, var2, T;
  var1 = ((((adc_T>>3) – ((BME280_S32_t)dig_T1<<1))) * ((BME280_S32_t)dig_T2)) >> 11;
  var2 = (((((adc_T>>4) – ((BME280_S32_t)dig_T1)) * ((adc_T>>4) – ((BME280_S32_t)dig_T1))) >> 12) *
((BME280_S32_t)dig_T3)) >> 14;
  t_fine = var1 + var2;
  T = (t_fine * 5 + 128) >> 8;
  return T;
}


続いて気圧の補正になります。
// Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
// Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
BME280_U32_t BME280_compensate_P_int64(BME280_S32_t adc_P)
{
  BME280_S64_t var1, var2, p;
  var1 = ((BME280_S64_t)t_fine) – 128000;
  var2 = var1 * var1 * (BME280_S64_t)dig_P6;
  var2 = var2 + ((var1*(BME280_S64_t)dig_P5)<<17);
  var2 = var2 + (((BME280_S64_t)dig_P4)<<35);
  var1 = ((var1 * var1 * (BME280_S64_t)dig_P3)>>8) + ((var1 * (BME280_S64_t)dig_P2)<<12);
  var1 = (((((BME280_S64_t)1)<<47)+var1))*((BME280_S64_t)dig_P1)>>33;
  if (var1 == 0)
  {
    return 0; // avoid exception caused by division by zero
  }
  p = 1048576-adc_P;
  p = (((p<<31)-var2)*3125)/var1;
  var1 = (((BME280_S64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
  var2 = (((BME280_S64_t)dig_P8) * p) >> 19;
  p = ((p + var1 + var2) >> 8) + (((BME280_S64_t)dig_P7)<<4);
  return (BME280_U32_t)p;
}

最後に湿度補正になります。
// Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
// Output value of “47445” represents 47445/1024 = 46.333 %RH
BME280_U32_t bme280_compensate_H_int32(BME280_S32_t adc_H)
{
  BME280_S32_t v_x1_u32r;
  v_x1_u32r = (t_fine – ((BME280_S32_t)76800));
  v_x1_u32r = (((((adc_H << 14) – (((BME280_S32_t)dig_H4) << 20) – (((BME280_S32_t)dig_H5) * v_x1_u32r)) +
((BME280_S32_t)16384)) >> 15) * (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * (((v_x1_u32r *
((BME280_S32_t)dig_H3)) >> 11) + ((BME280_S32_t)32768))) >> 10) + ((BME280_S32_t)2097152)) *
((BME280_S32_t)dig_H2) + 8192) >> 14));
  v_x1_u32r = (v_x1_u32r – (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((BME280_S32_t)dig_H1)) >> 4));
  v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
  v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
  return (BME280_U32_t)(v_x1_u32r>>12);
}

結構複雑な式ですが、これがないと全然意味不明になると思われます。









タグ:NXP11U14 EWARM
posted by EWARMJP at 12:00| Comment(0) | TrackBack(0) | NXP | このブログの読者になる | 更新情報をチェックする