#include <Wire.h>
#define SSD1306_I2C_ADDR 0x3D
#define SSD1306_CMD_DISPLAY_OFF 0xAE
#define SSD1306_CMD_DISPLAY_ON 0xAF
#define SSD1306_CMD_SET_MEMORY_MODE 0x20
#define SSD1306_CMD_SET_COLUMN_RANGE 0x21
#define SSD1306_CMD_SET_PAGE_RANGE 0x22
#define SSD1306_CMD_SET_DISPLAY_START_LINE 0x40
#define SSD1306_CMD_SET_CONTRAST_CONTROL 0x81
#define SSD1306_CMD_SET_SEGMENT_REMAP 0xA1
#define SSD1306_CMD_SET_COM_SCAN_DIRECTION 0xC8
#define SSD1306_CMD_SET_DISPLAY_OFFSET 0xD3
#define SSD1306_CMD_SET_COM_PIN_CONFIG 0xDA
#define SSD1306_CMD_SET_CLOCK_DIVIDE_RATIO 0xD5
#define SSD1306_CMD_SET_PRECHARGE_PERIOD 0xD9
#define SSD1306_CMD_SET_VCOMH_DESELECT_LEVEL 0xDB
#define SSD1306_CMD_SET_CHARGE_PUMP 0x8D
#define SSD1306_DATA_START_PAGE 0xB0
#define SSD1306_DATA_START_COLUMN 0x00
uint8_t scrbuf[1024];
const uint8_t OLED_FONT[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, // sp
0x00, 0x00, 0x5F, 0x00, 0x00, // !
0x00, 0x03, 0x00, 0x03, 0x00, // "
0x14, 0x3E, 0x14, 0x3E, 0x14, // #
0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
0x43, 0x33, 0x08, 0x66, 0x61, // %
0x36, 0x49, 0x55, 0x22, 0x50, // &
0x00, 0x05, 0x03, 0x00, 0x00, // '
0x00, 0x1C, 0x22, 0x41, 0x00, // (
0x00, 0x41, 0x22, 0x1C, 0x00, // )
0x14, 0x08, 0x3E, 0x08, 0x14, // *
0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x50, 0x30, 0x00, 0x00, // ,
0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x60, 0x60, 0x00, 0x00, // .
0x20, 0x10, 0x08, 0x04, 0x02, // /
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x04, 0x02, 0x7F, 0x00, // 1
0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x22, 0x41, 0x49, 0x49, 0x36, // 3
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x3E, 0x49, 0x49, 0x49, 0x32, // 6
0x01, 0x01, 0x71, 0x09, 0x07, // 7
0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x26, 0x49, 0x49, 0x49, 0x3E, // 9
0x00, 0x36, 0x36, 0x00, 0x00, // :
0x00, 0x56, 0x36, 0x00, 0x00, // ;
0x08, 0x14, 0x22, 0x41, 0x00, // <
0x14, 0x14, 0x14, 0x14, 0x14, // =
0x00, 0x41, 0x22, 0x14, 0x08, // >
0x02, 0x01, 0x51, 0x09, 0x06, // ?
0x3E, 0x41, 0x59, 0x55, 0x5E, // @
0x7E, 0x09, 0x09, 0x09, 0x7E, // A
0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x7F, 0x41, 0x41, 0x41, 0x3E, // D
0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x7F, 0x09, 0x09, 0x09, 0x01, // F
0x3E, 0x41, 0x41, 0x49, 0x3A, // G
0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x30, 0x40, 0x40, 0x40, 0x3F, // J
0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
0x7F, 0x02, 0x04, 0x08, 0x7F, // N
0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
0x7F, 0x09, 0x09, 0x09, 0x76, // R
0x26, 0x49, 0x49, 0x49, 0x32, // S
0x01, 0x01, 0x7F, 0x01, 0x01, // T
0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x7F, 0x20, 0x10, 0x20, 0x7F, // W
0x41, 0x22, 0x1C, 0x22, 0x41, // X
0x07, 0x08, 0x70, 0x08, 0x07, // Y
0x61, 0x51, 0x49, 0x45, 0x43, // Z
0x00, 0x7F, 0x41, 0x00, 0x00, // [
0x02, 0x04, 0x08, 0x10, 0x20, // "/"
0x00, 0x00, 0x41, 0x7F, 0x00, // ]
0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x01, 0x02, 0x04, 0x00, // `
0x20, 0x54, 0x54, 0x54, 0x78, // a
0x7F, 0x44, 0x44, 0x44, 0x38, // b
0x38, 0x44, 0x44, 0x44, 0x44, // c
0x38, 0x44, 0x44, 0x44, 0x7F, // d
0x38, 0x54, 0x54, 0x54, 0x18, // e
0x04, 0x04, 0x7E, 0x05, 0x05, // f
0x08, 0x54, 0x54, 0x54, 0x3C, // g
0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x20, 0x40, 0x44, 0x3D, 0x00, // j
0x7F, 0x10, 0x28, 0x44, 0x00, // k
0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x7C, 0x04, 0x78, 0x04, 0x78, // m
0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x38, 0x44, 0x44, 0x44, 0x38, // o
0x7C, 0x14, 0x14, 0x14, 0x08, // p
0x08, 0x14, 0x14, 0x14, 0x7C, // q
0x00, 0x7C, 0x08, 0x04, 0x04, // r
0x48, 0x54, 0x54, 0x54, 0x20, // s
0x04, 0x04, 0x3F, 0x44, 0x44, // t
0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x44, 0x28, 0x10, 0x28, 0x44, // x
0x0C, 0x50, 0x50, 0x50, 0x3C, // y
0x44, 0x64, 0x54, 0x4C, 0x44, // z
0x00, 0x08, 0x36, 0x41, 0x41, // {
0x00, 0x00, 0x7F, 0x00, 0x00, // |
0x41, 0x41, 0x36, 0x08, 0x00, // }
0x02, 0x01, 0x02, 0x04, 0x02, // ~
};
#define GAIN 100
#define STEP 3
#define LOW_SOUND 100
#define MAX_SOUND 600
int strela=-45;
int hMeter = 65;
int vMeter = 85;
int rMeter = 80;
int ur,urr;
void sendCommand(uint8_t cmd) {
Wire.beginTransmission(SSD1306_I2C_ADDR);
Wire.write(0x00);
Wire.write(cmd);
Wire.endTransmission();
}
void sendData(uint8_t data) {
Wire.beginTransmission(SSD1306_I2C_ADDR);
Wire.write(0x40);
Wire.write(data);
Wire.endTransmission();
}
void initDisplay() {
sendCommand(SSD1306_CMD_DISPLAY_OFF);
sendCommand(SSD1306_CMD_SET_MEMORY_MODE);
sendCommand(0x00); // Horizontal addressing mode
sendCommand(SSD1306_CMD_SET_COLUMN_RANGE);
sendCommand(0x00); // Column start address
sendCommand(0x7F); // Column end address
sendCommand(SSD1306_CMD_SET_PAGE_RANGE);
sendCommand(0x00); // Page start address
sendCommand(0x07); // Page end address
sendCommand(SSD1306_CMD_SET_DISPLAY_START_LINE);
sendCommand(SSD1306_CMD_SET_CONTRAST_CONTROL);
sendCommand(0xCF); // Contrast value
sendCommand(SSD1306_CMD_SET_SEGMENT_REMAP);
sendCommand(SSD1306_CMD_SET_COM_SCAN_DIRECTION);
sendCommand(SSD1306_CMD_SET_DISPLAY_OFFSET);
sendCommand(0x00); // No offset
sendCommand(SSD1306_CMD_SET_COM_PIN_CONFIG);
sendCommand(0x12); // Sequential COM pin configuration
sendCommand(SSD1306_CMD_SET_CLOCK_DIVIDE_RATIO);
sendCommand(0x80); // Default oscillator frequency
sendCommand(SSD1306_CMD_SET_PRECHARGE_PERIOD);
sendCommand(0x22); // Phase 1 period of 15 DCLKs, Phase 2 period of 1 DCLK
sendCommand(SSD1306_CMD_SET_VCOMH_DESELECT_LEVEL);
sendCommand(0x20); // VCOMH deselect level
sendCommand(SSD1306_CMD_SET_CHARGE_PUMP);
sendCommand(0x14); // Enable charge pump
sendCommand(SSD1306_CMD_DISPLAY_ON);
}
void clearDisplay() {
for (uint8_t page = 0; page < 8; page++) {
sendCommand(SSD1306_DATA_START_PAGE + page);
sendCommand(SSD1306_DATA_START_COLUMN);
for (uint8_t column = 0; column < 128; column++) {
sendData(0x00);}}}
void setPixel(uint16_t x, uint16_t y){
int by, bi;
if ((x>=0) and (x<128) and (y>=0) and (y<64)){
by=((y/8)*128)+x;
bi=y % 8;
scrbuf[by]=scrbuf[by] | (1<<bi);}
Wire.beginTransmission(SSD1306_I2C_ADDR);
Wire.write(0xC0);
Wire.write(scrbuf[by]);
Wire.endTransmission();
}
void drawLine (uint8_t x1, uint8_t x2, uint8_t y1, uint8_t y2)
{
// determinant
int16_t D;
// deltas
int16_t delta_x, delta_y;
// steps
int16_t trace_x = 1, trace_y = 1;
// delta x
delta_x = x2 - x1;
// delta y
delta_y = y2 - y1;
// check if x2 > x1
if (delta_x < 0) {
// negate delta x
delta_x = -delta_x;
// negate step x
trace_x = -trace_x;
}
// check if y2 > y1
if (delta_y < 0) {
// negate detla y
delta_y = -delta_y;
// negate step y
trace_y = -trace_y;
}
// Bresenham condition for m < 1 (dy < dx)
if (delta_y < delta_x) {
// calculate determinant
D = (delta_y << 1) - delta_x;
// draw first pixel
setPixel (x1, y1);
// check if x1 equal x2
while (x1 != x2) {
// update x1
x1 += trace_x;
// check if determinant is positive
if (D >= 0) {
// update y1
y1 += trace_y;
// update determinant
D -= 2*delta_x;
}
// update deteminant
D += 2*delta_y;
// draw next pixel
setPixel (x1, y1);
}
// for m > 1 (dy > dx)
} else {
// calculate determinant
D = delta_y - (delta_x << 1);
// draw first pixel
setPixel (x1, y1);
// check if y2 equal y1
while (y1 != y2) {
// update y1
y1 += trace_y;
// check if determinant is positive
if (D <= 0) {
// update y1
x1 += trace_x;
// update determinant
D += 2*delta_y;
}
// update deteminant
D -= 2*delta_x;
// draw next pixel
setPixel (x1, y1);
}
}}
void drawHLine(int x, int y, int l){
int by, bi;
if ((x>=0) and (x<128) and (y>=0) and (y<64)){
for (int cx=0; cx<l; cx++){
by=((y/8)*128)+x;
bi=y % 8;
scrbuf[by+cx] |= (1<<bi);
Wire.beginTransmission(SSD1306_I2C_ADDR);
Wire.write(0xC0);
Wire.write(scrbuf[by+cx]);
Wire.endTransmission();
}}}
void OLED_printC(char ch) {
uint16_t offset = ch-32;
offset += offset << 2;
Wire.write(0x00);
for(uint8_t i=5; i; i--) Wire.write(pgm_read_byte(&OLED_FONT[offset++]));
}
void OLED_printS(const char* p) {
Wire.beginTransmission(SSD1306_I2C_ADDR);
Wire.write(0x40);
while(*p) OLED_printC(*p++);
Wire.endTransmission();
}
void OLED_num(byte num){
Wire.beginTransmission(SSD1306_I2C_ADDR);
Wire.write(0x40);
OLED_printC(num+48);
Wire.endTransmission();
}
void OLED_cursor(uint8_t xpos, uint8_t ypos) {
Wire.beginTransmission(SSD1306_I2C_ADDR);
Wire.write(0x00);
Wire.write(xpos & 0x0F);
Wire.write(0x10 | (xpos >> 4));
Wire.write(0xB0 | (ypos & 0x07));
Wire.endTransmission();
}
void setup() {
delay(100);
analogReference(INTERNAL); // если очень маленький уровень сигнала
pinMode(A0,INPUT);
Wire.begin();
Wire.setClock(800000);
initDisplay();
clearDisplay();
// OLED_num(5);
//OLED_cursor(10, 0);
//OLED_printS("RCL-R");OLED_printS("ADIO.");OLED_printS("RU");
}
void loop() {
int a1 = (hMeter + (sin(ur / 57.296) * rMeter)); // meter needle horizontal coordinate
int a2 = (vMeter - (cos(ur / 57.296) * rMeter)); // meter needle vertical coordinate
drawLine(12, 100, 10, 15);
delay(50);
//clearDisplay();
}