x 過去ログをみよ
目的
グラフ表示
メインの処理
//↓開始 グラフのメイン処理 x=0...127 , y=0...64
if (y == y_[x]) {
Dot(x, y, 1); //白のドットを打つ
} else {
Dot(x, y, 0); //黒のドットを打つ
}//end if
//↑終了
結果
プログラム
//秋月のOLEDとアイテンドウのOLEDのアドレスは3C
//SSD1306_no_vram_graph1_UNO_1
//インクルド
#include <Arduino.h>
#include <Wire.h>
//定義(SSD1306)
#define MAX_PAGE (7)
#define MAX_COL (127)
#define COMMAND_MODE 0x80 // continuation bit is set!
#define DATA_MODE 0x40
#define SET_COLUMN_ADDRESS 0x21 // takes two bytes, start address and end address of display data RAM
#define SET_PAGE_ADDRESS 0x22 // takes two bytes, start address and end address of display data RAM
#define SET_MEMORY_ADDRESSING_MODE 0x20 // takes one byte as given above
#define HORIZONTAL_ADDRESSING_MODE 0x00
#define SET_SEGMENT_REMAP_0 0xA0 // column address 0 is mapped to SEG0 (Reset)
#define SET_SEGMENT_REMAP_127 0xA1 // column address 127 is mapped to SEG0
#define SET_COMMON_REMAP_0 0xC0 // row address 0 is mapped to COM0 (Reset)
#define SET_COMMON_REMAP_63 0xC8 // row address 63 is mapped to COM0
//I2Cに配列を転送する
void write_s(uint8_t *str1, uint8_t len1) {
Wire.beginTransmission( 0x3c );
for (int ii = 0; ii < len1; ii++) {
//一文字出力
Wire.write(*str1 ++);
}//for
Wire.endTransmission();
}//write_s
//セットページアドレス
void setPageAddress(uint8_t start, uint8_t end)
{
uint8_t databytes[6] = {COMMAND_MODE, SET_PAGE_ADDRESS, COMMAND_MODE, start, COMMAND_MODE, end};
write_s(databytes, 6);
}//setPageAddress
//セットカラムアクセス
void setColumnAddress(uint8_t start, uint8_t end)
{
uint8_t databytes[6] = {COMMAND_MODE, SET_COLUMN_ADDRESS, COMMAND_MODE, start, COMMAND_MODE, end};
write_s(databytes, 6);
}//setColumnAddress
//セットメモリーアドレシングモード
void setMemoryAddressingMode()
{
uint8_t databytes[4] = {COMMAND_MODE, SET_MEMORY_ADDRESSING_MODE, COMMAND_MODE, HORIZONTAL_ADDRESSING_MODE};
write_s(databytes, 4);
}//setMemoryAddressingMode
//セットディスプレー Flip
void setDisplayFlip(int left, int down)
{
if ( left == 0) {
// column address 0 is mapped to SEG0 (Reset)
//_sendCommand(SET_SEGMENT_REMAP_0);
uint8_t databytes[2] = {COMMAND_MODE, SET_SEGMENT_REMAP_0};
write_s(databytes, 2);
} else {
// column address 127 is mapped to SEG0
//_sendCommand(SET_SEGMENT_REMAP_127);
uint8_t databytes[2] = {COMMAND_MODE, SET_SEGMENT_REMAP_127};
write_s(databytes, 2);
}//end if
if ( down == 0) {
// Reset mode
//_sendCommand(SET_COMMON_REMAP_0);
uint8_t databytes[2] = {COMMAND_MODE, SET_COMMON_REMAP_0};
write_s(databytes, 2);
} else {
// Flip Up/Down (Need to rewrite display before H effect shows)
//_sendCommand(SET_COMMON_REMAP_63);
uint8_t databytes[2] = {COMMAND_MODE, SET_COMMON_REMAP_63};
write_s(databytes, 2);
}//end if
}//setDisplayFlip
//8バイト分まとめて出力
void put8byte(uint8_t qq) {
//データの配列の定義
static uint8_t databytes[9] = {DATA_MODE, 0, 0, 0, 0, 0, 0, 0, 0};
static char byte_count = 1;
databytes[byte_count++] = qq;
if ( byte_count > 8 ) { //8バイト分、貯まったら
write_s(databytes, 9);
byte_count = 1;
} // endif
} //put8byte
//ドットを打つ
void Dot(int x, int y, uint8_t c) {
static uint8_t qq = 0; //一時
qq = qq | ( c << (y & 0x07));
if ( (y & 0x07) == 7 ) { //1バイト分、貯まったら
put8byte(qq); qq = 0; //SSD1306に出力
}//end if
}//DOt
//キャラクターRAMの内容
char y_[] = {
//1 2 3 4 5 6 7 8
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , //1
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //2
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //3
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //4
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //5
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //6
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //7
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //8
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //9
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //A
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //B
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //C
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //D
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //E
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , //F
56 , 57 , 58 ,59 ,60 ,61 ,62 ,63 //G
};
//再表示
void display(void) {
char y; char x; char y1; char y2;
//範囲の設定 (OLED内部のx,yカウンターを初期化してホームポジション0,0に)
setPageAddress(0, MAX_PAGE); // all pages
setColumnAddress(0, MAX_COL); // all columns
for (int ii = 0; ii < 8192; ii++) {
//SSD1306のバッファーの配置順のxとyを求める
//y = ((ii & 0b0001110000000000 ) >> 7) + (ii & 0b0111);
y2 = (char)(ii & 0b0111);
if ( y2 == 0 ) {
y1 = (char)(ii >> 7) & 0b00111000;
//x = (ii & 0b0000001111111000) >> 3;
x = (char)(ii >> 3) & 0b1111111;
}//endif y2
y = y1 | y2;
//↓開始 グラフのメイン処理 x=0...127 , y=0...64
if (y == y_[x]) {
Dot(x, y, 1); //白のドットを打つ
} else {
Dot(x, y, 0); //黒のドットを打つ
}//end if
//↑終了
}//for ii
}//display
//SSD1306の初期化
void display_begin(void) {
//I2Cの初期化
Wire.begin(); //M5Stamp S3
delay(200);
//Wire.setClock(2000000); //速度の変更 (I2C高速化 2Mhz) 493ms
//Wire.setClock(1000000); //速度の変更 (I2C高速化 1Mhz) 125ms
Wire.setClock(800000); //速度の変更 (I2C高速化 800khz) 125ms
//Wire.setClock(400000); //速度の変更 (I2C高速化 400khz) 137ms
//Wire.setClock(200000); //速度の変更 (I2C高速化 200khz) 166ms
//Wire.setClock(100000); //速度の変更 (I2C高速化 100khz) 226ms
delay(200);
//SSD1306の初期化スペル(魔法)
//0x80,0x8D,0x80,0x14,0x80,0xAF
write_s( (uint8_t*) "\200\215\200\024\200\257", 6);
delay(100);
//セットメモリーアドレシングモード (画面の終端に来たら画面の先頭に)
setMemoryAddressingMode();
//セットディスプレー Flip (画面の向きを変える)
setDisplayFlip(1, 0);
}//display_begin
//初期化
void setup() {
//SSD1306の初期化
display_begin();
}//setup
//メインループ
void loop() {
y_[0]=1; //debug
display(); //再表示
delay(500); //0.5秒待つ
//while(1){} //debug
y_[0]=32; //debug
display(); //再表示
delay(500); //0.5秒待つ
}//loop