さくらのジャンク箱ロゴ

Sakura87がほぼ月刊でお届けするPCや電子工作と写真の備忘録てきなブログ @なんと20周年

Raspberry Pi2で電光掲示板をつくる

この記事は8年ほど前に投稿されました。内容が古くなっている可能性がありますので更新日時にご注意ください。

IMG_7157_20151231

以前よりRaspberry Pi2にていろいろな種類の表示器を試してきました。
7セグLEDやキャラクタ液晶、グラフィック液晶にカラー液晶。
あとは普通のLEDも表示器といえば表示器ですね。

そんな中、今回は「ドットマトリクスLED」を使ってみたいと思います。
今回は直接制御するのではなく、シフトレジスタ3個とLEDユニットを2個使用して8×16の大きさで使います。

ドットマトリクスLEDとは

ドットマトリクスLEDとは、小さなLEDを二次元配列で敷き詰め、記号や文字、図画などを表示できるようにしたLEDユニットのことです。このLEDは内部で縦一列のカソードと、横一列のアノードが接続されており、これの接続を変更することによって光らせるLEDを変え、その行を高速で切り替えることによって文字等を表示することができるデバイスです。

原理としては、以前複数桁の7セグLEDを表示したときに使用したものと同じです。

7セグLEDや液晶との使い分け

似たようにたくさんのドットを集めて文字等を表示するデバイスに7セグLEDや各種液晶ディスプレイがありますが。これらの使い分けとしては…

  • 7セグLED
    基本的に数字のみだが制御が簡単。
    最近はあまり見かけないが16セグメントLEDを用いることで英字も表示可能。
    数字や簡単な英字のみをなるべく簡単な処理で、表示器から近~中距離で使用するのであればこのデバイスを用いる。既製品で存在する主なサイズは10cm前後のものが中心だが、中には大型のものもあるので範囲としては手のひら~庭程度の広さのものに適している。
  • キャラクタ液晶
    英数字とカタカナ、簡単な記号が表示できる。制御は比較的簡単。
    英文や数字がメインで7セグより情報量を増やしたい場合に有効。液晶なのでバックライトがなければ消費電力は少ない。
    あまり大型の製品は存在しないので、近距離で使用する場合で、簡単な英文まで表示したいのであればこちらを選択する。範囲としては既製品ではあまり大きなものが存在しないので手のひら~目の前程度の範囲に限られる。
  • グラフィック液晶
    液晶のドットマトリクスなので文字や図画も表示できるがフォントを持たないものが多いので表示したい文字のパターンを液晶に転送することになる。ゆえに制御が複雑になる。ただしPCで扱える視覚情報はほぼすべて表示できるのでその制御の煩雑さに応えるだけの利益があります。
    漢字や絵を表示したいのであればこれを使いましょう。
    製品の大きさはさまざまで、7セグLEDよりも小さいものから、100インチ程度のものまでさまざま。
    なので近~遠距離まで様々なところで利用できます。範囲としては手のひらから野球場くらいまでならいけます。※ただし、大きな液晶はたいていHDMIなどのPC入力が備わっていますし。RaspberryPiならそれを利用したほうがいいので、I/Oポートを用いて制御するのであれば~10インチくらいまで、手のひら~目の前程度になるでしょう。
  • ドットマトリクスLED
    基本的にはグラフィック液晶と同様ですが、ホビーユースとして入手できるものは一辺が3~4cmで8ドット程度のものが多く、ドットが荒いので近~中距離、目の前~広めの室内程度の範囲での使用が適しています。また、ある程度光量が確保できるので屋外での使用にも向いています。
    制御は制御装置が付いた完成品もありますが、基本的にLED単体の場合は自分で制御回路を作成する必要があります。8×8ドットのユニット1つ程度なら単純にIOに接続するだけでも使えますが…。

というわけで今回使うドットマトリクスLEDは屋外みたいな光量を必要とする場所で、比較的距離のある所で使用するのに適しています。もちろん室内でも使えますが。

必要なもの

今回はLEDユニットを直接制御するのではなく、シフトレジスタおよびトランジスタアレイを用いて制御したいと思います。ですので2個のドットマトリクスLEDを制御する場合には以下のものが必要になります。

  • 8×8ドットのドットマトリクスLED
    今回は秋月電子で買えるOSL641501-AGを使用。
    使用するドットマトリクスLEDは、8×8タイプのものでしたら基本的に同じように使えるはずですが。
    今回は窒化ガリウム系(多分)で、順方向電圧が3.3Vで扱いやすいこちらのタイプを選びました。
    昔ながらの緑色や赤色、黄色でも構いません。
  • NPN型(反転型)トランジスタアレイ(シンクドライバ) TD62083APG
    トランジスタを複数個1つのパッケージにしたもので、今回はカソード側を切り替えるために使用します。なお、上に示した型番のものは内部に入力抵抗が内蔵されているので、マイコン(今回はシフトレジスタ)→トランジスタアレイの接続に外部抵抗が必要なく、シンプルな回路が構成できます。
  • 適当な抵抗16本
    LEDの電流制限用の抵抗です。必要な明るさと、流す電圧によって適切なものを購入してください。
    今回は5V電源を使用するので手持ちの抵抗で20mAに近くなるように75Ωを使用しました。
    なお、75Ωだと若干オーバーするので80~100Ωの抵抗がいいと思われます。
  • シリアル→パラレルシフトレジスタ 74HC595
    今回はシフトレジスタを使用して3線で制御するのでシフトレジスタが1+桁数分必要になります。ここで製作する内容なら3個必要です。
    なお、シリアル→パラレル変換に使用できるシフトレジスタはいくつか種類がありますが、私はラッチつきの595を使用しました。これならSPIコマンドで制御を行う事が可能ですし、数珠繋ぎにして拡張することも可能ですので。専用ICを使ったり、列切り替えのICのみラッチなしにする手もありますが、部品の入手性や壊れた時の交換しやすさから考えると別にラッチがあっても構わないため、今回は74HC595を使用することにしました。
    メーカーについてですが、このICはどのメーカー製でも互換性があるので、好きなものを使用してください。通販を利用するのであれば、秋月にあるテキサスインスツルーメンツ製の安いものでいいてでしょう。

このほか、プリント基板やRaspberry Piとの接続に使う線材類が必要です。
今回はブレッドボードで軽くテストした後、ハードウェアを先に作りました。

ハードウェアの作成

IMG_7151_20151230

使用した主パーツ一覧。あとはこれに配線とコネクタ類。

ドットマトリクスLEDの内部構造

ドットマトリクスLEDの内部構造は、メーカーの仕様書によればこうなっています。

dmpat

(メーカー仕様書より引用)

上述のとおり縦の1列8個分のLEDのアノード、横1列8個分のカソードがひとまとめになっています。
例えばこの表で1番にGND、16番に3.3Vを接続してみると、以下のように右端の5番目のLEDが点灯します。

IMG_7148_20151230

これを利用して+側にしているIOポートにパターンデータを送信して、-側を順々に切り替えていくことで文字等を表示することが出来ます。(別にプラスとマイナスの制御は逆でも何の問題もないですが。)

トランジスタアレイの使い方

IMG_7164_20160102

ざっくり言うと、トランジスタを複数まとめた製品ですが。
例えばLEDやモーターを複数駆動させる場合に、足三本のトランジスタを使用していたら回路が複雑になってしまいます。そんな時にトランジスタをまとめた製品があれば便利ですね。それがこいつです。

トランジスタアレイは内包されるトランジスタの種類によって シンクドライバ や ソースドライバ と呼ばれることも有ります。また種類も様々で、本品のように、エミッタをまとめ逆起電力吸収用のダイオードや入力抵抗を内蔵したものもあれば、単純にトランジスタのみをまとめたもの。特定用途向けのトランジスタ構成にしたものと、様々な種類が有ります。

今回は-側の切り替えで制御を行うのでシンクドライバと呼ばれるNPN型のダーリントントランジスタアレイを使用します。型番はTD62083APGです。似たような型番で末尾が1~4まで有りますが、1~2は既に入手方法がなく(生産終了?)4は6~15Vの電圧で使用するものなので、Raspberry PiやArduinoで使用する場合は本品を使うことになります。(4を使っても問題は無いですが、抵抗が大きいため最大出力が得られない場合もあると思われます。今回はせいぜい200mA程度なので問題ないでしょうけど。)

メーカーサイトで公開されている仕様書によると、ピン配列は以下のとおりです。

tarray
(メーカー仕様書より引用)

切り欠きのある方から8ピン目までがそれぞれ入力と出力に対応しています。
9番ピンをGNDに接続、1~8番ピンをそれぞれマイコンのI/Oに接続します。
18~11番がそれぞれ向かい合う1~8番のピンに対応しており、ここにLEDのカソード側を接続します。
COMMON端子はモーター制御などで逆起電力を吸収するために使用しますので今回は未接続でも問題ありませんが、念のため電源に接続しておきます。

LEDの電流はアノードに接続された電源から、このトランジスタアレイの18~11番ピンを通り9番ピンのGNDに流れます。

回路

dmatrix

単純に仕様書通りにつないでいるだけです。

桁数を増やす場合は、一番右端の塊を複数作ることで実現しますが、1行のドットを全て点灯させた場合、3桁で480mAと、トランジスタアレイの許容電流ギリギリなので、3桁以上に桁数を増やす場合はトランジスタアレイを別のものにするか、輝度を下げたほうが良さそうです。4桁以上を使う場合は回路の中々の工夫が必要でしょう。もしくは、今回は行で切り替えていますが、列を切り替えることで、桁数が増えてもトランジスタアレイの数は1つで済むでしょう。(その分1サイクルあたりの切り替え回数が増え、ちらつきやすくなる場合があるので、それも考えると10桁は超えないほうがいいかもしれません。)その場合は今回とは逆の、ソースドライバを用いて制御するほうが良いかも知れません。

基板の作成

IMG_7152_20151230

今回使用した基板はSunhayatoのICB-504ですが、2桁だと半分で収まるので半分にしました。IMG_7153_20151230

部品の位置決めを行っています。
74HC595には最上位ビットを出力する機能がありますので、そこにもう一つの74HC595を接続して数珠つなぎにすることにより、8bit・16bitと拡張する機能があります。これを利用して今回はたった3本の制御線と電源線の計5本の線で制御してみたいと思います。
なお、回路図を見ればわかると思いますが、接続方法は列切り替え用のシフトレジスタをマスターとして接続しています。その後は1桁目・2桁目…という順に接続していきます。

IMG_7154_20151230

はんだづけした状態。LEDユニットは少し内側にしました。

IMG_7158_20151231

裏面はこんな感じです。見事なパスタが出来上がっていますね。
ちなみに途中でウレタン線が太くなっていますが。これは特に深い意味はなく、単に細い線の在庫が切れたためです。

IMG_7155_20151231

コンソールによるSPIにて\xff\xff\xffを送信し、全てのLEDを点灯させて動作確認を行いました。

この方法で行うと上下左右が反転してしまったので、本来下向きのところを上向きで使っています。
配線を入れ替えて修正してもいいのだけど。この方が制御がしやすいのでこのままでいきます。

制御

上下反転させるので下から上に表示していきます。
左右は物理的に反転しているので制御プログラム上では反転させる必要はありません。

今回は文字を表示させるプログラムを作ります。
文字の表示はフォントデータからいろいろやってもいいのですが、今回もBMPの文字一覧ファイルから読み込もうと思います。

プログラムに関しては基本的に前回グラフィック液晶で文字を表示したものを簡素化させた感じです。
なお、フォントデータファイルについては以下の通りに作成してください。

  • JISコードで全角文字が並んだ画像ファイル
  • 1文字あたりは8x8px以内
  • Windows形式のモノクロBMPファイル
    ペイントで「モノクロビットマップ」を選んで作成できる。
  • 画像ファイルの回転等は不要

今回は前回同様美咲フォントの画像版を使用。これをダウンロードしてモノクロBMPに変えるだけでOK。

コーディング

前回のコードをほぼそのまま、転送部分が変わっているだけなので詳細は省きます。

文字コードを変換して連結する部分はこんな感じです。

	// EUC-JPからJISコードを計算する。
	// 本来は0xA0を引くことで算出できるが。変数番号は0からスタートなので
	// 0xA1を引く。
	int jis_code[4] = {send_char[0]-0xA1,send_char[1]-0xA1,send_char[2]-0xA1,send_char[3]-0xA1};
	
	// 転送するパターンを作成する。
	// 1文字目のパターンを8bitシフトして転送後、2文字目をORでくっつける。
	int s=8;
	while(s--) pat[s] = (255-font_data[font_size[0]-(1+s+(jis_code[0]*8))][jis_code[1]])<<8;
	s=8;
	while(s--) pat[s] |= (255-font_data[font_size[0]-(1+s+(jis_code[2]*8))][jis_code[3]]);

文字コード変換は前回のまま、前回は原理を説明するために-1-0xA0にしていましたが、今回は不要なのでくっつけました。
そのあとは最初に1桁目を8bitシフトして転送。その後にOR演算で2桁目をくっつけています。
普通なら文字数に応じて変更できるコードを書くべきですが。今回は2文字固定なのでこういう方法をとりました。

全体のコードは以下の通りです。

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

#include <string.h>
#include <stdlib.h>


// 周波数用
#define kHz  * 1000
#define MHz  * 1000000

#define SegDel 0.001 //1行当たりの表示周期

static uint8_t SPIMode = 0,SPIbit=8; //SPIモード0 bit数8
static uint32_t SPISpeed =10 MHz;    // SPI転送速度設定

// SPIデバイス定義
// # ls -l /dev/spidev* で確認できる。
// Pi2の場合CE1に接続した場合は0.0
//          CE2に接続した場合は0.1 だった。
static char *SPIDevice = "/dev/spidev0.0";

int font_size[2] = {752,752};   // フォント画像サイズ 横x縦(正方形になるはずだが)
char font_path[]   = "/code/misaki_gothic.bmp"; //フォントファイルパス


int errRet;

int DataSend(int fd,unsigned int TrData){
	uint32_t ReData;         //受信用変数
	// 転送するデータの準備
	struct spi_ioc_transfer tr={
	.tx_buf       =(unsigned long)&TrData,
	.rx_buf       =(unsigned long)&ReData,
	.len          = 3,
	.delay_usecs  = 1,
	.speed_hz     = SPISpeed,
	.bits_per_word= SPIbit,
	};
	
	
	// 転送
	errRet =ioctl(fd,SPI_IOC_MESSAGE(1),&tr);
	if(errRet<1)printf("SPI 転送エラー(Data)\n");
	return errRet; // 受信データサイズを返す
}

int main(int argc,char *argv[]){
	
	// 転送データ作成用の変数
	unsigned int pat[8];

	// フォントサイズをpx単位からバイト単位に。
	// 白黒データなので+7でバイト単位に慣らして8で割るだけでOK。
	font_size[1] = (font_size[1]+7)/8;
	
	// データの読み込み関係。
	// 読み込むデータの形式はわかっているのでヘッダを捨ててデータを読み込むだけでOK
	// (((font_size[1]+3)/4)*4) ← BMPは1行4バイト単位で格納されているのでそれに合わせる
	unsigned char bmp_head[62],font_data[font_size[0]][(((font_size[1]+3)/4)*4)];
	FILE *bmp_read;
	bmp_read = fopen(font_path,"rb");

	fread(bmp_head,1,62,bmp_read);fread(font_data,1,font_size[0]*((((font_size[1]+3)/4)*4)*8),bmp_read);
	fclose(bmp_read);

	// ユーザー入力を受け付ける。
	// 文字コードをすべてEUC-JPで統一すること。
	printf("表示する文字を「全角2文字」で入力してください\n");
	char send_char[6];

	scanf("%[^\n]%*c",send_char);
	
	// EUC-JPからJISコードを計算する。
	// 本来は0xA0を引くことで算出できるが。変数番号は0からスタートなので
	// 0xA1を引く。
	int jis_code[4] = {send_char[0]-0xA1,send_char[1]-0xA1,send_char[2]-0xA1,send_char[3]-0xA1};
	
	// 転送するパターンを作成する。
	// 1文字目のパターンを8bitシフトして転送後、2文字目をORでくっつける。
	int s=8;
	while(s--) pat[s] = (255-font_data[font_size[0]-(1+s+(jis_code[0]*8))][jis_code[1]])<<8;
	s=8;
	while(s--) pat[s] |= (255-font_data[font_size[0]-(1+s+(jis_code[2]*8))][jis_code[3]]);



	// SPIデバイスの初期化
	int fd = open(SPIDevice,O_RDWR);if(fd<0) printf("SPI デバイス初期化エラー\n");
	errRet = ioctl(fd,SPI_IOC_WR_MODE,&SPIMode);if(errRet <0) printf("SPI Mode設定エラー\n");
	errRet =ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&SPIbit);if(errRet <0) printf("SPI bit/Word設定エラー\n");
	errRet =ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&SPISpeed);if(errRet <0) printf("SPI Speed設定エラー\n");

	// 文字コード転送
	int i;
	while(1){
		
		DataSend(fd,(1<<(23-(i%8)))+(pat[i%8]));
		usleep(1);
		i++;
		}
}

これをコンパイルします。(今回は特別なライブラリ指定は必要ないです。)

※文字コードはEUC-JPを指定すること。
コンパイル時の文字コード・ローケル・端末の文字コード。すべてEUC-JPで統一。
端末でログインする場合はコンパイル時と端末のコードでとりあえず使える。

IMG_7157_20151231

コンパイルしたものに「さく」を入力し表示させてみた状態

CXno742UoAEMJfZ

「賀正」を入力してみた。あまり複雑な文字は読みにくいですね。

終わりに

ドットマトリクスLEDの制御方法は以上です。

今回は簡単に制御するために8×16にしてみましたが、実用的なものを作るのであれば16×32は最低ほしいところですね。(このLED1つ320円するんで結構な金額になりますが…。)縦8pxだと英数字・記号やかな・カナは問題ないのでそれに絞った用途であれば8×32くらいでいいかもしれません。(もしくは文字を流すか…。)

ドットマトリクスLEDはきれいでなんかかっこいいので制御法を覚えておきたいアイテムですね!

更新履歴

令和元年7月6日(土) 美咲フォントのアドレスが変更されていたため修正。

総閲覧数:710 PV

“Raspberry Pi2で電光掲示板をつくる” への18件のフィードバック

  1. […] まず初めに決めたのは描画領域のサイズですね。英語ならば前回の8×16の電光掲示板でも十分実用的ですが。日本語を扱うのであれば縦幅8pxでは少々きつい。少し前のWEBサイトが10pxの小さな文字で作られていたことを考えると、最低10pxはほしい。 […]

  2. […] まず初めに決めたのは描画領域のサイズですね。英語ならば前回の8×16の電光掲示板でも十分実用的ですが。日本語を扱うのであれば縦幅8pxでは少々きつい。少し前のWEBサイトが10pxの小さな文字で作られていたことを考えると、最低10pxはほしい。 […]

  3. 匿名 より:

    たびたびすみません。ちょっとした質問です。
    私はラズベリーパイ3を使用しているのですが、本サイトで公開している内容は、パイ3でも可能かどうかご存じでしょうか?

    • Sakura87 より:

      コメントありがとうございます。

      こちらの記事はRaspberry Pi2にて作成しており、現状3は所持しておらず、確認は出来ませんが。Raspberry Pi製造元の財団が互換性を謳っておりますし、最新のラズビアンでは動作しておりますし。3でコンパイルすれば概ね動作するものと思われます。ただし、一部変更が必要な可能性はあります。特にSPIデバイスの指定は、Raspberry Piシリーズの中でもいくつかあるようで、実機での確認が必要と思われます。

      それでは。

  4. あらら より:

    たびたびすみません。いろいろアドバイス頂き、勉強になっています。
    ところで、入力を聞いてこなくて無反応は、私の勘違いでした。この件は無視して下さい。
    ところで、gdbでどこでエラーになっているのか確認してみました。
    89行目の転送データの作成で
    Segmentation fault
    のエラーが出ているようです。
    58行目のpat[8]をpat[9]に変えたりしたのですが、同様なエラーが出ます。。。

    • Sakura87 より:

      コメントありがとうございます。

      89行目でエラーが出るなら、おそらく文字コード変換に失敗しています。
      文字を入力する端末エミュレータというソフトの文字コードがEUC-JPに正しく設定されていない可能性があります。一度Raspberry Piのローケルの設定が正しく設定されレテいることを確認してみてください。

      • あらら より:

        アドバイスありがとうございます。
        いろいろ試行錯誤しながらですが、89行目でエラーが出る理由は、
        単純に半角英字を入力しているのが原因でした。
        大変ご迷惑お掛けしました。全角ひらがなにすることで、
        89行目のエラーは解消しました。
        ところが、gdbで1つ1つ処理を確認していくと、下記のように105行目から
        107行目の処理が繰り返され、「SPI 転送エラー(Data)」とメッセージが出ています。
        何が原因かアドバイス頂けないかと思い、コメントします。
        表示する文字を「全角2文字」で入力してください
        79 scanf(“%[^\n]%*c”,send_char);
        (gdb) next
        ああ
        84 int jis_code[4] = {send_char[0]-0xA1,send_char[1]-0xA1,send_char[2]-0xA1,send_char[3]-0xA1};
        (gdb) next
        88 int s=8;
        (gdb) next
        89 while(s–) {pat[s] = (255-font_data[font_size[0]-(1+s+(jis_code[0]*8))][jis_code[1]])<<8;}
        (gdb) next
        90 s=8;
        (gdb) next
        91 while(s–) {pat[s] |= (255-font_data[font_size[0]-(1+s+(jis_code[2]*8))][jis_code[3]]);}
        (gdb) next
        96 int fd = open(SPIDevice,O_RDWR);if(fd<0) printf("SPI デバイス初期化エラー\n");
        (gdb) next
        SPI デバイス初期化エラー
        97 errRet = ioctl(fd,SPI_IOC_WR_MODE,&SPIMode);if(errRet <0) printf("SPI Mode設定エラー\n");
        (gdb) next
        SPI Mode設定エラー
        98 errRet =ioctl(fd,SPI_IOC_WR_BITS_PER_WORD,&SPIbit);if(errRet <0) printf("SPI bit/Word設定エラー\n");
        (gdb) next
        SPI bit/Word設定エラー
        99 errRet =ioctl(fd,SPI_IOC_WR_MAX_SPEED_HZ,&SPISpeed);if(errRet <0) printf("SPI Speed設定エラー\n");
        (gdb) next
        SPI Speed設定エラー
        105 DataSend(fd,(1<<(23-(i%8)))+(pat[i%8]));
        (gdb) next
        SPI 転送エラー(Data)
        106 usleep(1);
        (gdb) next
        107 i++;
        (gdb) next
        105 DataSend(fd,(1<<(23-(i%8)))+(pat[i%8]));
        (gdb) next
        SPI 転送エラー(Data)
        106 usleep(1);
        (gdb) next
        107 i++;
        (gdb) next
        105 DataSend(fd,(1<<(23-(i%8)))+(pat[i%8]));

        • Sakura87 より:

          コメントありがとうございます。

          SPI転送エラーが出てしまう場合は、多くの場合プログラム側の問題と言うよりはハードウェア側の問題です。
          以下の事項を確認してみてください。

          ・ラズベリーパイのSPI通信が有効になっているかどうか
          →Raspberry Piの設定→インターフェイス→SPIが「有効」になっていればOK

          ・他にRaspberry PiのSPIを使う機器が接続されていないか
          →接続されていればいったん外してみる。

          ・SPI通信を占有するようなハードウェア・ソフトなどを使っていないか
          →液晶など。入れているなら最悪アンインストールが必要かも。

          ・他のSPI通信を使用するデバイスを接続しているなら、それがそのプログラムで
           正常に動作しているかを確認。
          →正常に動作しているならSPI通信機能自体は問題ないが、
           直上の項目である、SPIを占有するものに該当しないこと。

          ・*SPIDeviceの末尾の0を1に変えてみる。
          →ピンヘッダの位置もCE.1のヘッダに変更すること。

          ・ls -l /dev/spidev* コマンドを実行してSPIデバイスのファイルを確認する。
          →この中で数字の一番若いものに*SPIDeviceの内容を変更する。
          例:
          pi@raspberrypi:~ $ ls -l /dev/spidev*
          crw-rw—- 1 root spi 153, 0 7月 6 15:10 /dev/spidev0.0
          crw-rw—- 1 root spi 153, 1 7月 6 15:10 /dev/spidev0.1

          以上の例なら、実行後、一番最初の行の一番最後の「/dev/」から始まるところをコピーする。

          以上を試しても問題が解決しない場合は作成した電光掲示板の回路やRaspberry Piへの配線が間違っていないかどうかを確認してください。
          私のサイトに公開しているものを作ったのであれば、回路さえあっていれば問題なく使用できるはずです。
          他のサイトで公開されているものや既製品を使用した場合は、そのものに合わせてプログラムの改修が必要な場合があります。

          もし、上記の対策をすべて行っても、エラーが改善しない場合は。一度お近くの詳しい人に、作った回路が正しいかどうかを見てもらってください。

          なお、以上を行って無事転送できた場合に表示される文字がおかしい場合は以下の事が考えられます。

          ・真っ白のまま・点滅するのみで文字が出ない
          →配線の再確認を行います。
          →配線に問題がない場合は用意した画像ファイルが「モノクロビットマップ」であることを確認します。
          →モノクロビットマップで作成した画像は美咲ゴシックで70KBほどです。これ以上・以下の場合は別の形式になっています。

           参考:
            モノクロビットマップ 70.5KB←これが正解
            オリジナル画像 53.4KB ←失敗
            16色ビットマップ 276KB←これ以上のサイズは失敗

          ・ある程度規則正しい模様が出る・文字がずれているような感じ
          →これも画像が間違っているか、変換に失敗しておかしくなっている。

          ・「け」を打ったのに数字やカタカナ、前後の別の文字が表示される
          →作成した画像がおかしい場合があります。
           正常に変換できていれば、画像データのオリジナルは72,192バイトで、ヘッダーが62バイトなので
           合計72,254バイトあります。もしこれより多かったり少なかったりした場合は
           67・71行目の「62」を実際のファイルサイズから72,192を引いた数字にします。
           例えばファイルサイズが72,338バイトだった場合は、72,338-72,192=146なので146バイトに変更します。

          ということで以上確認してみてください。

          それでは。

          • 匿名 より:

            だいぶ間があきましたが、SPIのエラーは、ラズベリーパイのSPIの設定が無効になっていたので、有効に設定し直すことで解消できました。ありがとうございました。
            しかし残念なことに、まだ
            Segmentation fault
            が出てしまいます。。。
            コメントでのやりとりだけでは、そろそろ限界にきているのかなと思いますが、もし、思い当たるものがあればと思い、コメント致します。。
            P.S.今回のやりとりで、ラズベリーパイやLinuxについて勉強になりました。

          • Sakura87 より:

            コメントありがとうございます。

            以上の事を試してもエラーが出るのであれば、再度作成された画像と入力している文字の文字コードを確認してみてください。
            特にこのプログラムは画像のヘッダーサイズがおかしいと上記エラーが発生します。また、文字の入力をシェルからではなくEUC-JPでエンコードされたテキストファイルから入力するように変更するなど工夫をしてみてください。

            ここまで問題なければ、おそらく実物をみればどこがおかしいかすぐ分かるレベルのものかと思いますので、以上で治らなければ近くの詳しい人に聞いてみてください。

            それでは失礼いたします。

  5. あらら より:

    アドバイスありがとうございます。
    Linux、ラズベリーパイ初心者で、トライアンドエラーですが、
    コマンドで、以下のようになりました。

    ****************
    pi@raspberrypi:~ $ sudo -s
    root@raspberrypi:/home/pi# gcc denko1.c
    denko1.c: In function ‘main’:
    denko1.c:76:9: warning: unknown escape sequence: ‘\216’
    printf(“�\���镶���u�S�p2���v�œ��͂��Ă�������\n”);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    root@raspberrypi:/home/pi# ./a.out
    Segmentation fault
    ****************

    『Segmentation fault』と言うエラーが出ているのですが、どこが悪いのかお気付きの点がありましたらよろしくお願いします。。。

    • Sakura87 より:

      コメントありがとうございます。

      おそらく日本語を使っているところでエラーが出ているので、
      コメント以外の部分で日本語を使っているところをすべて半角の英数字に変えてみてください。

      もしくはこのあたりを参考にコンパイル設定を変えてみます。
      https://hake.hatenablog.com/entry/20120505/p1
      これはWindows用の説明になっていますが、test.cの後の-から最後までをdenko1.cの後に同じように入力してください。(スペースを忘れないように)

      おそらくどちらかの方法で実行できるようになると思います。
      もしこれでダメなら、もう一度見直してみて、それでもダメなら多分ラズベリーパイ本体の問題なので本体の設定をもう一度見直してみましょう。
      もし誰かにセットアップして貰ったのなら、その人にもう一度見て貰ってください。

      • あらら より:

        アドバイス頂いた内容をやってみたところ、日本語のエラーは解消できました。
        大変ありがとうございます。
        ただ、
        Segmentation fault
        と言うエラーだけがまだ解消できていない状況です。
        プログラムは、「全体のコードは以下の通りです。」と書かれているところの下の
        1から109行までのコードをコピーして実行してみたのですが、もしかして、他に
        追加するコードとかあるのかなと思い、質問しました。

        • Sakura87 より:

          コメントありがとうございます。

          失礼いたしました。
          上のコードをコピー・ペーストしたという事でしたら、このコードはEUC-JPという文字コードで
          動かすように出来ていますので、以下の処置で動くようになると思います。

          ・端末(プログラムを実行しようとしている画面)の文字コードをEUC-JPにする
          ※端末の文字コードの変更方法はラズベリーパイをセットアップした人に聞いてください。
           おそらく「RaspberryPiの設定」から変更できると思いますが。変更して他で問題が発生する
           事がありますので、もし誰か別の人に設定して貰ったなら、その人にやって貰ってくださいね。

          ・コードのファイルの文字コードをEUC-JPに変更する

          ・1つ前の返信で説明した、gccの後の命令の中の「CP932」を「EUC-JP」に変更する(2つ)

          これで実行すれば動くはずですが、動かない場合は以下の事を試してください。

          1.使用している感じが入った画像ファイルは正しい形式なのか
           ・説明にもある「美咲フォント」の画像版を使っています。
           ・白黒ビットマップファイルを作ってください。

          2.画像ファイルの設置場所は正しいか
           ・このプログラムをそのままコピーしたのなら「/code/misaki_gothic.bmp」
            というところにファイルを置いてある必要があります。この/からはじまる
            ものは、ラズベリーパイのドライブルートというところなので、もしかしたら
            アクセス権がないかも知れないから、31行目の最初の/の前に「.」を半角でを入れて、
            「./code/misaki_gothic.bmp」と書き換えて、プログラムファイルと同じ場所に「code」
            フォルダを作って、その中にフォントファイルを入れてください。

          3.余計な改行やおかしな文字がないかどうかもう一度見てみる。
           ・もしかしたらコピーする時に他の文字が入ってきて失敗しているかも知れません(インターネットのプログラムをコピーしたらよくあります)
           ・コードをダブルクリックするか1行目の右上に「<>」のようなマークがあるのでここをクリックすればきれいにコピーできるようになります。

          これでもダメなら、おそらくコメントで対応するのは難しいので、
          身近の詳しい人に聞いてみてください。

          それでは。

          • あらら より:

            アドバイスありがとうございます。
            初心者ですが、ネットで調べながらEUC-JPの設定変更をしたところ、
            Segmentation fault
            は解消できました。ありがとうございます。
            ただ、文字入力を聞いてくることもなく無反応で今止まっています。。。
            上記3のコピペする際、右上の<>をクリックして、コピペしてみたのですが、まだ無反応で、もう少し試行錯誤してみます。
            ありがとうございました。

          • Sakura87 より:

            コメントありがとうございます。

            解決できて何よりです。
            また何かありましたらお気軽にどうぞ!

            なお、入力を聞いてこなく無反応な件、もしかすると単純に日本語が出ていないだけの可能性がありますので、いったんそのまま打ち込んでみてください。もしくは他で入力してコピー・貼り付けを行うともしかすると表示されるかもしれません。

            それでは。

  6. あらら より:

    記事を見て8×8のドットマトリックスの電工掲示版を製作してみていますが、プログラムは何という開発環境を使いましたか?
    Geanyというものを使っていますが、うまくいかなくて。

    • Sakura87 より:

      コメントありがとうございます。

      こちらのプログラムはテキストエディタで作成してラズベリーパイ上のgccを用いてコンパイルしています。
      そのあたりの話は以下の記事にまとめてあるので参考にしていただければと思います。

      https://sakura87.net/archives/1555

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください