GR KURUMI + LEDマトリクス (その2)

id:currygyu:20130528

前回↑が消化不良だったので、改良してみました。


修正点

トランジスタアレイを使ってLED用の電源を別に確保
・上記に関連して、電源を3.3Vから5Vに変更
(3.3Vで始めたらトランジスタアレイの電圧降下でLEDが点灯しなくなりました)
・74HC595(x2)でインタフェースをSPI化

はんだ付けを1箇所ずれたまま進めてしまい、半日悩んだりしましたが、どうにか完成しました。

次はフルカラーのLEDマトリクスをいじってみようかと思います。

SPI化したので、GR KURUMIのスケッチもシンプルになりました。

/*GR-KURUMI Sketch Template Version: V1.00*/
#include <RLduino78.h>
#include <spi.h>

byte leddat[8] = { 0x18, 0x24, 0x42, 0x81, 0x81, 0x42, 0x24, 0x18 };
void disp_update(unsigned long u32ms);

// the setup routine runs once when you press reset:
void setup() {

  // initialize the digital pin as an output.
  pinMode(9, OUTPUT);        // SS(STCP)
  digitalWrite(9, HIGH);

  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV128);
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);

  delay(50);
  
  attachCyclicHandler(1, disp_update, 1000);
}

// the loop routine runs over and over again forever:
void loop() {
  byte i=0;

  for(i=0; i<8; i++){
    SPI.transfer((byte)(0x01<<i));
    SPI.transfer(leddat[i]);
    digitalWrite(9, HIGH);
    digitalWrite(9, LOW);

    delay(1);
  }
}

void disp_update( unsigned long u32ms )
{
    int y, x;
    int num = 0;
    int alive = 0;
    byte work[8];
    
    for(y=0; y<8; y++){
        work[y] = leddat[y];
    }

    for(y=0; y<8; y++){
        for(x=0; x<8; x++){
            num = 0;
            
            /* count around */
            if( x != 0 ){
                if( ( ( leddat[y] >> ( 8-x ) ) & 0x01 ) != 0 ){
                    num ++;
                }
            }
            
            if( x != 7 ){
                if( ( ( leddat[y] >> ( 6-x ) ) & 0x01 ) != 0 ){
                    num ++;
                }                    
            }
            
            if( y != 0 ){
                if( ( ( leddat[y-1] >> ( 7-x ) ) & 0x01 ) != 0 ){
                     num ++;
                }
                if( x != 0 ){
                    if( ( ( leddat[y-1] >> ( 8-x ) ) & 0x01 ) != 0 ){
                        num ++;
                    }
                }
                if( x != 7 ){
                    if( ( ( leddat[y-1] >> ( 6-x ) ) & 0x01 ) != 0 ){
                        num ++;
                    }
                }
            }                    

            if( y != 7 ){
                if( ( ( leddat[y+1] >> ( 7-x ) ) & 0x01 ) != 0 ){
                    num ++;
                }
                if( x != 0 ){
                    if( ( ( leddat[y+1] >> ( 8-x ) ) & 0x01 ) != 0 ){
                        num ++;
                    }
                }
                if( x != 7 ){
                    if( ( ( leddat[y+1] >> ( 6-x ) ) & 0x01 ) != 0 ){
                        num ++;
                    }
                }
            }                    

            /* decide */
            if( ( ( leddat[y] >> ( 7-x ) ) & 0x01 ) == 0 ){
                if( num == 3 ){
                    work[y] |= ( 0x80 >> x );
                }
            }
            else{        
                if( ( num != 2 ) && ( num != 3 ) ){
                    work[y] &= ~( 0x80 >> x );
                }
            }
        }
    }

    for( y=0; y<8; y++ ){
        leddat[y] = work[y];
    }
}

表示内容は前回と同じライフゲームです。

1秒ごとにタイマで呼ばれるdisp_update関数の中で、表示内容を設定するleddat配列を書き換えています。その辺りをいじれば好きな表示内容に変更も可能かと。

※leddat配列は、ドットを8ビットで表現したものを1行目から順に8行分入れたたものです。

SPIで16ビット送信していますが、最初の8ビットは行指定、次の8ビットは点灯内容となっていて、送信後に74HC595にラッチの信号(KURUMIの9ピン)を入れて表示内容を反映させています。

よくあるやりかたなので、検索すればたくさんでてきます。僕もマネしました。

回路図

https://docs.google.com/file/d/0B9mpDLlbvvN8Wi04eVk1VGpBSkk/edit?usp=sharing

※7/5 配線ミス修正&PDFの窓を出すのやめました

PIC16F916 + 極小3桁LCD

aitendoの極小3桁LCD(3C8-DIP)の続きです。

GR KURUMIでうまくいかなかったのでPICでやってみました。今回使った、PIC16F916はLCDコントローラ機能を持っているので、つないでちょいちょいと設定すればうまくいくはず…だったのですが、LCD用の電圧を外から入れたりするので少し苦労しました。

とりあえず、うまくいったのでソースを貼っておきます。

#pragma config CPD = OFF, BOREN = OFF, IESO = OFF, DEBUG = OFF
#pragma config FOSC = INTOSCCLK, FCMEN = OFF, MCLRE = OFF
#pragma config WDTE = OFF, CP = OFF, PWRTE = OFF

#include "pic16f916.h"

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>

#define _XTAL_FREQ 8000000

unsigned char digit[10] =
{
    0x77, /* 0 */
    0x22, /* 1 */
    0x5b, /* 2 */
    0x6b, /* 3 */
    0x2e, /* 4 */
    0x6d, /* 5 */
    0x7d, /* 6 */
    0x23, /* 7 */
    0x7f, /* 8 */
    0x6f /* 9 */
};

void setnum( int num );
/*
 * 
 */
int main(int argc, char** argv) {
    int num = 0;

    OSCCON = 0b01110000;

    ANSEL = 0x00;

    LCDSE0 = 0x3f;
    LCDSE1 = 0x00;

    LCDPS = 0x88;
    LCDCON = 0x93;


    LCDDATA0 = 0x00;    /* COM0 */
    LCDDATA1 = 0x00;    /* COM0 */

    LCDDATA3 = 0x00;    /* COM1 */
    LCDDATA4 = 0x00;    /* COM1 */

    LCDDATA6 = 0x00;    /* COM2 */
    LCDDATA7 = 0x00;    /* COM2 */

    LCDDATA9 = 0x00;    /* COM3 */
    LCDDATA10 = 0x00;    /* COM3 */

    setnum( 123 );

    while( 1 );

    return (EXIT_SUCCESS);
}

void setnum( int num )
{
    unsigned char dat[3];

    dat[0] = digit[ num / 100 ];
    dat[1] = digit[ ( num /10 ) % 10 ];
    dat[2] = digit[ num % 10 ];

    LCDDATA0 = ( dat[0] & 0x03 ) |
                ( ( dat[1] & 0x03 ) << 2 ) |
                ( ( dat[2] & 0x03 ) << 4 );
    LCDDATA3 = ( ( dat[0] >> 2 ) & 0x03 ) |
                ( ( ( dat[1] >> 2 ) & 0x03 ) << 2 ) |
                ( ( ( dat[2] >> 2 ) & 0x03 ) << 4 );
    LCDDATA6 = ( ( dat[0] >> 4 ) & 0x03 ) |
                ( ( ( dat[1] >> 4 ) & 0x03 ) << 2 ) |
                ( ( ( dat[2] >> 4 ) & 0x03 ) << 4 );
    LCDDATA9 = ( ( dat[0] >> 6 ) & 0x03 ) |
                ( ( ( dat[1] >> 6 ) & 0x03 ) << 2 ) |
                ( ( ( dat[2] >> 6 ) & 0x03 ) << 4 );
}

(MPLAB X IDE + XC8)


追記:

回路図を書いてみました。(生まれて初めて)

GR KURUMI + 極小3桁LCD [失敗]

aitendoの極小3桁LCDをGR KURUMIから動かしたかったのですが、うまくいきませんでした。

PICでLCDコントローラの載ったものがあるようなので、そちらを試してみようと思います。

KURUMIがRL78/L13だったらなあ…笑

それにしてもオシロが欲しいです。安いの買ってしまおうかなあ…。

GR SAKURA + TS174

秋葉原のaitendoでTS174という型番の7セグLCDを買ってみました。データの無い部品なのですが、ネットの知恵をお借りしてGR SAKURAから操作できました。

といいましても、作業の99%は下記サイトの内容そのままです。

VikiWiki - TS119-5

こちらの中ほどのリンクから行けるサイトからダウンロードしたHT1621.cppとHT1621.hをWEBコンパイラにアップロードして、引用したサイトのスケッチを入れたところ、ほとんど変更なしで表示までいけました。

いじったのは以下の箇所です。

HT1621.h

#include コメントアウト

HT1621.cpp

#include を#include に変更

gr_sketch.cpp

#include を#include <../HT1621.h>に変更
※HT1621.hをProject_Rootに入れた場合

HT1621 htの引数はdata,wr,rd,csの順で、接続したピン番号を設定

ピン配置ですが、うちのTS174ではバックライトの電源が8ピン、GNDが9ピンでした。引用サイトで使用されているTS119-5とは逆のようです。

最初、一番下の横棒にあたるセグメントが全ての桁で点灯せずあせったのですが、裏面の検品用らしきシールをはがしてアルコールで拭いたところ、点灯するようになりました。

そういうこともあるんだなあと…。

GR KURUMI + LEDマトリクス

GR KURUMIからLEDマトリクスを操作してみました。


暗い行があったり、意図していないLEDが薄くついてしまったり、色々問題ありますね。少しずつ良くして行きたいと思います…。

スケッチは以下です。

/*GR-KURUMI Sketch Template Version: V1.00*/
#include <RLduino78.h>

#include <stdio.h>
#include <string.h>

#define PIN_A_1 2    /* pin9 */
#define PIN_A_2 7    /* pin14 */
#define PIN_A_3 10    /* pin8 */
#define PIN_A_4 5    /* pin12 */
#define PIN_A_5 17    /* pin1 */
#define PIN_A_6 11    /* pin7 */
#define PIN_A_7 16    /* pin2 */
#define PIN_A_8 13    /* pin5 */

#define PIN_K_1 6    /* pin13 */
#define PIN_K_2 15    /* pin3 */
#define PIN_K_3 14    /* pin4 */
#define PIN_K_4 3    /* pin10 */
#define PIN_K_5 12    /* pin6 */
#define PIN_K_6 4    /* pin11 */
#define PIN_K_7 8    /* pin15 */
#define PIN_K_8 9    /* pin16 */


// Pin 22,23,24 are assigned to RGB LEDs.
int led_red   = 22; // LOW active
int led_green = 23; // LOW active
int led_blue  = 24; // LOW active

unsigned char leddat[8];
int ledrow = 0;
void dynamic_led(unsigned long u32ms);
void disp_update(unsigned long u32ms);


// the setup routine runs once when you press reset:
void setup() {
  //setPowerManagementMode(PM_STOP_MODE, 0, 1023); //Set CPU STOP_MODE in delay()
  //setOperationClockMode(CLK_LOW_SPEED_MODE); //Set CPU clock from 32MHz to 32.768kHz

  memset( leddat, 0, sizeof(leddat) );
  
  leddat[0] = 0x18;
  leddat[1] = 0x24;
  leddat[2] = 0x42;
  leddat[3] = 0x81;
  leddat[4] = 0x81;
  leddat[5] = 0x42;
  leddat[6] = 0x24;
  leddat[7] = 0x18;

  // initialize the digital pin as an output.
  Serial.begin(9600);
  pinMode(led_red, OUTPUT);
  pinMode(led_green, OUTPUT);
  pinMode(led_blue, OUTPUT);
  pinMode(PIN_A_1, OUTPUT);
  pinMode(PIN_A_2, OUTPUT);
  pinMode(PIN_A_3, OUTPUT);
  pinMode(PIN_A_4, OUTPUT);
  pinMode(PIN_A_5, OUTPUT);
  pinMode(PIN_A_6, OUTPUT);
  pinMode(PIN_A_7, OUTPUT);
  pinMode(PIN_A_8, OUTPUT);
  pinMode(PIN_K_1, OUTPUT);
  pinMode(PIN_K_2, OUTPUT);
  pinMode(PIN_K_3, OUTPUT);
  pinMode(PIN_K_4, OUTPUT);
  pinMode(PIN_K_5, OUTPUT);
  pinMode(PIN_K_6, OUTPUT);
  pinMode(PIN_K_7, OUTPUT);
  pinMode(PIN_K_8, OUTPUT);

  attachCyclicHandler(0, dynamic_led, 1);
  attachCyclicHandler(1, disp_update, 1000);

  // turn the LEDs on, glow white.
  digitalWrite(led_red, LOW);
  digitalWrite(led_green, LOW);
  digitalWrite(led_blue, LOW);

}

// the loop routine runs over and over again forever:
void loop() {
}

// LED dynamic
void dynamic_led(unsigned long u32ms) {
    unsigned char dt = leddat[ledrow];

    /* LED */
    digitalWrite( PIN_A_1, ( ledrow == 0 ) ? HIGH : LOW );
    digitalWrite( PIN_A_2, ( ledrow == 1 ) ? HIGH : LOW );
    digitalWrite( PIN_A_3, ( ledrow == 2 ) ? HIGH : LOW );
    digitalWrite( PIN_A_4, ( ledrow == 3 ) ? HIGH : LOW );
    digitalWrite( PIN_A_5, ( ledrow == 4 ) ? HIGH : LOW );
    digitalWrite( PIN_A_6, ( ledrow == 5 ) ? HIGH : LOW );
    digitalWrite( PIN_A_7, ( ledrow == 6 ) ? HIGH : LOW );
    digitalWrite( PIN_A_8, ( ledrow == 7 ) ? HIGH : LOW );

    if( ( dt & 0x80 ) == 0 ){
        digitalWrite( PIN_K_1, HIGH );
    }
    else{
        digitalWrite( PIN_K_1, LOW );
    }

    if( ( dt & 0x40 ) == 0 ){
        digitalWrite( PIN_K_2, HIGH );
    }
    else{
        digitalWrite( PIN_K_2, LOW );
    }

    if( ( dt & 0x20 ) == 0 ){
        digitalWrite( PIN_K_3, HIGH );
    }
    else{
        digitalWrite( PIN_K_3, LOW );
    }

    if( ( dt & 0x10 ) == 0 ){
        digitalWrite( PIN_K_4, HIGH );
    }
    else{
        digitalWrite( PIN_K_4, LOW );
    }

    if( ( dt & 0x08 ) == 0 ){
        digitalWrite( PIN_K_5, HIGH );
    }
    else{
        digitalWrite( PIN_K_5, LOW );
    }

    if( ( dt & 0x04 ) == 0 ){
        digitalWrite( PIN_K_6, HIGH );
    }
    else{
        digitalWrite( PIN_K_6, LOW );
    }

    if( ( dt & 0x02 ) == 0 ){
        digitalWrite( PIN_K_7, HIGH );
    }
    else{
        digitalWrite( PIN_K_7, LOW );
    }

    if( ( dt & 0x01 ) == 0 ){
        digitalWrite( PIN_K_8, HIGH );
    }
    else{
        digitalWrite( PIN_K_8, LOW );
    }
    
    if( ledrow == 7 ){
        ledrow = 0;
    }
    else{
        ledrow ++;
    }
}

void disp_update( unsigned long u32ms )
{
    int y, x;
    int num = 0;
    int alive = 0;
    unsigned char work[8];
    
    for(y=0; y<8; y++){
        work[y] = leddat[y];
    }

    for(y=0; y<8; y++){
        for(x=0; x<8; x++){
            num = 0;
            
            /* count around */
            if( x != 0 ){
                if( ( ( leddat[y] >> ( 8-x ) ) & 0x01 ) != 0 ){
                    num ++;
                }
            }
            
            if( x != 7 ){
                if( ( ( leddat[y] >> ( 6-x ) ) & 0x01 ) != 0 ){
                    num ++;
                }                    
            }
            
            if( y != 0 ){
                if( ( ( leddat[y-1] >> ( 7-x ) ) & 0x01 ) != 0 ){
                     num ++;
                }
                if( x != 0 ){
                    if( ( ( leddat[y-1] >> ( 8-x ) ) & 0x01 ) != 0 ){
                        num ++;
                    }
                }
                if( x != 7 ){
                    if( ( ( leddat[y-1] >> ( 6-x ) ) & 0x01 ) != 0 ){
                        num ++;
                    }
                }
            }                    

            if( y != 7 ){
                if( ( ( leddat[y+1] >> ( 7-x ) ) & 0x01 ) != 0 ){
                    num ++;
                }
                if( x != 0 ){
                    if( ( ( leddat[y+1] >> ( 8-x ) ) & 0x01 ) != 0 ){
                        num ++;
                    }
                }
                if( x != 7 ){
                    if( ( ( leddat[y+1] >> ( 6-x ) ) & 0x01 ) != 0 ){
                        num ++;
                    }
                }
            }                    

            /* decide */
            if( ( ( leddat[y] >> ( 7-x ) ) & 0x01 ) == 0 ){
                if( num == 3 ){
                    work[y] |= ( 0x80 >> x );
                }
            }
            else{        
                if( ( num != 2 ) && ( num != 3 ) ){
                    work[y] &= ~( 0x80 >> x );
                }
            }
        }
    }

    for( y=0; y<8; y++ ){
        leddat[y] = work[y];
    }
}

一応、ライフゲームになってます。


参考:

LED > マトリックス - LEDドットマトリックス(1.26/8x8/green-yellow) - aitendo@shopping〜楽しい電子工作を提案する - aitendo@shopping

GR KURUMI買いました

GR KURUMIを買いました。

買った状態だとIOどころかプログラム書き込み用のピンすら立っておらず、はんだ付け必須という、小さいですがなかなか硬派?なマイコンボードであります。

まだ、全然使いこなせていないのですが、とりあえずtone関数を使ったサンプルがあったので、参考にして「KissからはじまるMiracle」の冒頭を演奏させてみました。(みらくるみ、なので)

スケッチは以下です。

/*GR-KURUMI Sketch Template Version: V1.00*/
#include <RLduino78.h>

// Pin 22,23,24 are assigned to RGB LEDs.
int led_red   = 22; // LOW active
int led_green = 23; // LOW active
int led_blue  = 24; // LOW active

#define TONE_C4    262
#define TONE_C4S   277
#define TONE_D4    294
#define TONE_D4S   311
#define TONE_E4    330
#define TONE_F4    349
#define TONE_F4S   370
#define TONE_G4    392
#define TONE_G4S   415
#define TONE_A4    440
#define TONE_A4S   466
#define TONE_B4    494

#define TONE_C5    523
#define TONE_C5S   554
#define TONE_D5    587
#define TONE_D5S   622
#define TONE_E5    659
#define TONE_F5    698
#define TONE_F5S   740
#define TONE_G5    784
#define TONE_G5S   831
#define TONE_A5    880
#define TONE_A5S   932
#define TONE_B5    988

#define TONE_C6    1047
#define TONE_C6S   1109
#define TONE_D6    1175
#define TONE_D6S   1245
#define TONE_E6    1319
#define TONE_F6    1397
#define TONE_F6S   1480
#define TONE_G6    1568
#define TONE_G6S   1661
#define TONE_A6    1780
#define TONE_A6S   1865
#define TONE_B6    1976


// the setup routine runs once when you press reset:
void setup() {
  //setPowerManagementMode(PM_STOP_MODE, 0, 1023); //Set CPU STOP_MODE in delay()
  //setOperationClockMode(CLK_LOW_SPEED_MODE); //Set CPU clock from 32MHz to 32.768kHz

  // initialize the digital pin as an output.
  pinMode(led_red, OUTPUT);
  pinMode(led_green, OUTPUT);
  pinMode(led_blue, OUTPUT);

  pinMode(5, OUTPUT);

  // turn the LEDs on, glow white.
  digitalWrite(led_red, LOW);
  digitalWrite(led_green, LOW);
  digitalWrite(led_blue, LOW);

  // play
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_F5S);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_F5S);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_A5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_F5S);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(375);    noTone(5);    delay(10);
  delay(577);

  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_F5S);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_F5S);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_B5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_A5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_B5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_A5);   delay(375);    noTone(5);    delay(10);
  delay(577);

  tone(5, TONE_B5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_B5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_E5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_E5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_D5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_D5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_B5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_B5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_G5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_E5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_E5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_D5);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_D5);   delay(182);    noTone(5);    delay(10);

  tone(5, TONE_E5);   delay(182);    noTone(5);    delay(10);
  delay(192);
  tone(5, TONE_E5);   delay(182);    noTone(5);    delay(10);
  delay(192);
  tone(5, TONE_F5S);   delay(182);    noTone(5);    delay(10);
  tone(5, TONE_F5S);   delay(182);    noTone(5);    delay(10);
  delay(192);

  tone(5, TONE_G5);   delay(375);    noTone(5);    delay(10);
  delay(577);
}

// the loop routine runs over and over again forever:
void loop() {
}

…ただの力技ですね。

単音なのが寂しいですが、DACつけたら和音鳴るような気もします。今後の課題ということで…。

部品は圧電サウンダのみです。IO5とGNDに圧電サウンダをつなげました。

参考:

KURUMIでキーボードピアノ(toneのお試し) - がじぇっとるねさす ゆーざー会 - Blog - がじぇっとるねさすゆーざー会 - Renesas Rulz - Japan

KURUMIスケッチリファレンス

圧電スピーカー(圧電サウンダ)(22mm)PKM22EPPH2001−B0: パーツ一般 秋月電子通商 電子部品 ネット通販

Raspberry PiとGR SAKURAでキャラクターLCD (2)

Raspberry Pi側からGR SAKURAに対して、自分のIPアドレスを文字列としてUARTに流すのですが、出荷時の設定だとUARTはシリアルターミナルのログイン用になっており、通信に使用できないとのことで、起動設定を変更しました。

変更内容は下記サイトの内容そのままです。

Raspberry Pi でシリアル通信 Chick Lab

書いてあるとおりに、以下の2ファイルを変更しました。

/boot/cmdline.txt
/etc/inittab

また、シリアル通信を一から書くと意外と面倒ですので、WiringPiというライブラリーを入れます。

公式サイト:Raspberry Pi | Wiring | Gordons Projects

インストールは上記のサイトの以下のページの通りにすすめます。

Raspberry Pi | Wiring | Download & Install | Gordons Projects

(うちは最初のgit-coreのインストールでエラーが出たので、updateとupgradeを行いましたが、けっこう時間がかかりました…)

WiringPiをインストールすると、serialXXXXという名前のついた関数を使って簡単にシリアル通信ができるようになります。

以下がRaspberry Pi側のプログラムです。

/* ipuart.c */

#include <stdio.h>
#include <string.h>

#include <unistd.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <wiringSerial.h>	/* WiringPi */


int main( int ac, char *av[] )
{
	int fd, sfd;
	struct ifreq ifr;
	char ipstr[256];

	/* get my IP addr */ 
	fd = socket(AF_INET, SOCK_DGRAM, 0);
	ifr.ifr_addr.sa_family = AF_INET;
	strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
	ioctl(fd, SIOCGIFADDR, &ifr );
	close(fd);

	memset( ipstr, '\0', sizeof(ipstr));
	strcpy(ipstr, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));

//	printf("%s\n", ipstr);

	/* UART */
	sfd = serialOpen( "/dev/ttyAMA0", 38400 );
	if( sfd == -1 ){
		printf( "serial cannot open.\n" );
		return 1;
	}


	serialPuts( sfd, ipstr );

	delay(1000);

	serialClose( sfd );

	return 0;
}

(前半でソケットを使ってマジメにIPアドレスを取得していますが、実はこの処理は不要なことが後で判明…)

ビルドすると実行ファイルができるので適当なディレクトリに置きます。うちは、/usr/local/binに置いてみました。

あとは、起動時に実行するようにしたいので、/etc/rc.localの末尾に実行ファイル名を書いておきます。以下は記述例です。

/usr/local/bin/ipuart

(上でIP取得が不要と書いた理由ですが、rc.localの中で自分のIPアドレスが$_IPという変数に記録されていますので、引数に指定した文字列をそのままUARTに流すようなプログラムを作れば$_IPを引数にするだけでよくなります。結果、自作プログラムの中でIPを取得する必要は無くなります…。)

これで、LCDIPアドレスが表示できるようになりました。

ただ、GR SAKURAを持ち出したり、20x4という大きめのLCDを使っていたりと、我ながらIP表示するだけのことにずいぶんおおげさになってしまったなあと思いまして、結局、今は3.3VでI2Cインタフェースの小さい16x2 LCDを直接Raspberry Piにつないでおります。まあ、勉強にはなりましたので後悔はしてません。多分…。



参考:
I2C低電圧キャラクタ液晶モジュール(16x2行) - SB1602B - ネット販売