x 過去ログを見よ!!
//秋月のOLEDとアイテンドウのOLEDのアドレスは3C
//ssd1306_level_meter_r1_2ch_C6_1
//ヘッダー
#include <Arduino.h>
#include <Wire.h>
//定義
#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
//パターンRAMの内容を液晶に転送
void level_meter(int L1, int L2) {
//ビットカウント
static int b_count = 0;
//8ドット分のデータ
static char dot_1ch[8];
static char dot_2ch[8];
//範囲の設定 (OLED内部のx,yカウンターを初期化してホームポジション0,0に)
setPageAddress(0, MAX_PAGE); // all pages
setColumnAddress(0, MAX_COL); // all columns
//yのループ
for (int y = 0; y < 64; y++) {
if (L1 >= y){dot_1ch[b_count] = 1;}else{dot_1ch[b_count] = 0;}
if (L2 >= y){dot_2ch[b_count] = 1;}else{dot_2ch[b_count] = 0;}
b_count++; //0から7までのカウンターに1を足しこむ
if (b_count > 7 ) { //8個たまると実行
//L1 L1 L1 vL1 L1 L1 L1 L1 L1
int a; //一時
//データの配列の定義
static uint8_t databytes[9] = {DATA_MODE, 0,0,0,0, 0,0,0,0};
static uint8_t databytes_null[9] = {DATA_MODE, 0,0,0,0, 0,0,0,0};
//空白1 8x2
write_s(databytes_null, 1+8);
write_s(databytes_null, 1+8);
//L1 L1 L1 L1 L1 L1 L1 L1 L1 L1
a = dot_1ch[7] << 7;
a = a | dot_1ch[6] << 6;
a = a | dot_1ch[5] << 5;
a = a | dot_1ch[4] << 4;
a = a | dot_1ch[3] << 3;
a = a | dot_1ch[2] << 2;
a = a | dot_1ch[1] << 1;
a = a | dot_1ch[0] ;
//8x4
databytes[1] = databytes[2] = databytes[3] = databytes[4] = a;
databytes[5] = databytes[6] = databytes[7] = databytes[8] = a;
write_s(databytes, 1+8);
write_s(databytes, 1+8);
write_s(databytes, 1+8);
write_s(databytes, 1+8);
//空白2 8x4
write_s(databytes_null, 1+8);
write_s(databytes_null, 1+8);
write_s(databytes_null, 1+8);
write_s(databytes_null, 1+8);
//L2 L2 L2 L2 L2 L2 L2 L2 L2
a = dot_2ch[7] << 7;
a = a | dot_2ch[6] << 6;
a = a | dot_2ch[5] << 5;
a = a | dot_2ch[4] << 4;
a = a | dot_2ch[3] << 3;
a = a | dot_2ch[2] << 2;
a = a | dot_2ch[1] << 1;
a = a | dot_2ch[0] ;
//8x4
databytes[1] = databytes[2] = databytes[3] = databytes[4] = a;
databytes[5] = databytes[6] = databytes[7] = databytes[8] = a;
write_s(databytes, 1+8);
write_s(databytes, 1+8);
write_s(databytes, 1+8);
write_s(databytes, 1+8);
//空白3 8x2
write_s(databytes_null, 1+8);
write_s(databytes_null, 1+8);
b_count = 0; //0から7までのカウンターをクリア
}//end if b_count
}//for y
//while(1){} //debug
}//Sound_Oscilloscope
//SSD1306の初期化
void display_begin(void) {
//I2Cの初期化
Wire.begin(); //NanoC6
delay(200);
//Wire.setClock(2000000); //速度の変更 (I2C高速化 2Mhz)
//Wire.setClock(1000000); //速度の変更 (I2C高速化 2Mhz)
//Wire.setClock(800000); //速度の変更 (I2C高速化 800khz)
Wire.setClock(400000); //速度の変更 (I2C高速化 400kMhz)
//Wire.setClock(200000); //速度の変更 (I2C高速化 200khz)
//Wire.setClock(100000); //速度の変更 (I2C高速化 100hz)
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(0, 1);
}//display_begin
//初期化
void setup() {
//SSD1306の初期化
display_begin();
}//setup
//メインループ
void loop() {
static int L1 = 0; //値
static int L2 = 0; //値
L1 = random(64); // ランダム
L2 = random(64); // 0から63
level_meter(L1, L2); //画面の再表示
//delay(1000); //1秒待つ debug
}//loop