При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)
А что, "различные одновременные комбинации фигур" - это обязательно для данного проекта?
Научитесь, наконец, выделять главное и жертвовать второстепенным. Без такого умения у Вас ничего не получится.
Цитата:
И их тоже как то надо выбирать сообразно фигурам.
Да - для каждого проекта свои примитивы. Не нужно только пытаться создать единые примитивы универсальные для всех проектов одновременно. Ну не будут они все на одном экране. Сам формат 128х64 этого не позволяет.
Через Wire так и должно быть - Вы на каждый байт команды или данных организуете:
Старт - Байт признака команды/данные - Сам байт - Стоп (Избыточность около х3)
В эти дисплеи нужно слать ИНАЧЕ (если аппаратную прокрутку не используем-команды только для инициализации дисплея):
Старт - Байт признака команды - ВСЕ БАЙТЫ КОМАНД подряд - Стоп
Старт - Байт признака данные - ВСЕ БАЙТЫ ДАННЫХ ... ... ...
Стоп уже не нужен.
p.s. Сама Wire имеет буфер :-)
Попробовал вот так для основного блока (как мне кажется сообразно предлагаемой логике) - не работает.
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {
/////////////////////
oledCommand(0x21);//установка столбца
oledCommand(0);//Начальный столбец.
oledCommand(127);//Конечный столбец.
oledCommand(0x22);//установка страницы
oledCommand(0);//Начальная страница.
oledCommand(7);//Конечная страница.
//////////////////////
Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R/*&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)*/ ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
}
}
Wire.write(K); K = 0; // отправляем "число-столбик в экран"
}
Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {
/////////////////////
oledCommand(0x21);//установка столбца
oledCommand(0);//Начальный столбец.
oledCommand(127);//Конечный столбец.
oledCommand(0x22);//установка страницы
oledCommand(0);//Начальная страница.
oledCommand(7);//Конечная страница.
//////////////////////
Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные.
for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R/*&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)*/ ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
}
}
Wire.write(K); K = 0; // отправляем "число-столбик в экран"
}
Wire.endTransmission();//Завершаем передачу данных.
}
При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)
А что, "различные одновременные комбинации фигур" - это обязательно для данного проекта?
Научитесь, наконец, выделять главное и жертвовать второстепенным. Без такого умения у Вас ничего не получится.
Цитата:
И их тоже как то надо выбирать сообразно фигурам.
Да - для каждого проекта свои примитивы. Не нужно только пытаться создать единые примитивы универсальные для всех проектов одновременно. Ну не будут они все на одном экране. Сам формат 128х64 этого не позволяет.
А если много горизонтальных отрезков через пиксель?
если у вас вертикально-стролбцовая организация видиопамяти - то от горизонтальных примитивов вы много не выиграете.
Вообще, подобная оптимизация всегда процесс равновесный. Примитивы ускоряют вывод на экран (во всяком случае должны бы :)), но на выбор между примитивами и на вызов функций, передачу параметров - тоже тратится процессорное время, поэтому на некоторых текстурах примитивы могут давать выигрыш, а на других - почти не сказываться на скорости или даже замедлять процесс.
Буфер Wire по умолчанию 32 байта. После 32 посылок надо Wire.endtransmission(false) т.е. посылать буфер физически без посыла Stop.
#include <Wire.h>//Подключаю библиотеку протокола I2C.
int K = 0; // переменная хранения числа-столбца 8 пикселей
int st=0;
//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
Wire.write(comm);//Передаем команду.
Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
Wire.write(data);//Передаем данные.
Wire.endTransmission();//Завершаем передачу данных.
}
/////////////////////////////////////////////////////////////////////
void setup() {
///////////////////
pinMode(11, OUTPUT);
digitalWrite(11, HIGH);
delay(100);
///////////////////
Wire.begin();
//процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
oledCommand(0xAE);//выключение дисплея
oledCommand(0xD5);// Частота обновления экрана
oledCommand(0x80);
oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
oledCommand(0x0);
oledCommand(0x40);
oledCommand(0x8D);//включение емкостного умножителя
oledCommand(0x14);
oledCommand(0x20);//настройка адресации
oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
//Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
oledCommand(0xDA);
oledCommand(0x12);
oledCommand(0x81);//установка контрастности дисплея
oledCommand(0xCF);
oledCommand(0xD9);
oledCommand(0xF1);
oledCommand(0xDB); // установка Vcomh(влияет на яркость)
// oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
oledCommand(0x40);
oledCommand(0xA4);
oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
oledCommand(0xAF);//включение дисплея
Wire.setClock( 400000L );
}
void loop() {
int R = map(analogRead(A0), 0, 1020, 0, 63);// выставляем потенциометром координаты центра фигуры - двигаем её по экрану
krug_(63, 32, R); //круг в центре экрана переменного радиуса
delay(25);
}
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {
/////////////////////
oledCommand(0x21);//установка столбца
oledCommand(0);//Начальный столбец.
oledCommand(127);//Конечный столбец.
oledCommand(0x22);//установка страницы
oledCommand(0);//Начальная страница.
oledCommand(7);//Конечная страница.
//////////////////////
for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
if(st>15){st=0; Wire.endTransmission(); Wire.beginTransmission(0x3C);Wire.write(0x40);}st++;
int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
bool sbros=true;
///
if (sbros==true &&((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1) ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros=false;
}
///
if (sbros==true &&((x+10 - X) * (x+10 - X)) + ((y - Y) * (y - Y)) <= R * R&&((x+10 - X) * (x+10 - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1) ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros=false;
}
///
}
Wire.write(K); K = 0; // отправляем "число-столбик в экран"
}
Wire.endTransmission(); //Завершаем передачу данных.
}
Если не тяжело поправьте в скетче. Этот работает, но только при 16 числах-столбцах в одной передаче, иначе начинает картинка чудить. Смысл деяний моих в строках 82 и 105.
#include <Wire.h>//Подключаю библиотеку протокола I2C.
int K = 0; // переменная хранения числа-столбца 8 пикселей
//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
Wire.write(comm);//Передаем команду.
Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
Wire.write(data);//Передаем данные.
Wire.endTransmission();//Завершаем передачу данных.
}
/////////////////////////////////////////////////////////////////////
void setup() {
///////////////////
pinMode(11, OUTPUT);
digitalWrite(11, HIGH);
delay(100);
///////////////////
Wire.begin();
//процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
oledCommand(0xAE);//выключение дисплея
oledCommand(0xD5);// Частота обновления экрана
oledCommand(0x80);
oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
oledCommand(0x0);
oledCommand(0x40);
oledCommand(0x8D);//включение емкостного умножителя
oledCommand(0x14);
oledCommand(0x20);//настройка адресации
oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
//Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
oledCommand(0xDA);
oledCommand(0x12);
oledCommand(0x81);//установка контрастности дисплея
oledCommand(0xCF);
oledCommand(0xD9);
oledCommand(0xF1);
oledCommand(0xDB); // установка Vcomh(влияет на яркость)
// oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
oledCommand(0x40);
oledCommand(0xA4);
oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
oledCommand(0xAF);//включение дисплея
Wire.setClock( 400000L );
}
void loop() {
int R = map(analogRead(A0), 0, 1020, 0, 63);// выставляем потенциометром координаты центра фигуры - двигаем её по экрану
krug_(63, 32, R); //круг в центре экрана переменного радиуса
delay(25);
}
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {
/////////////////////
oledCommand(0x21);//установка столбца
oledCommand(0);//Начальный столбец.
oledCommand(127);//Конечный столбец.
oledCommand(0x22);//установка страницы
oledCommand(0);//Начальная страница.
oledCommand(7);//Конечная страница.
//////////////////////
for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1) ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
}
}
oledData(K); K = 0; // отправляем "число-столбик в экран"
}
}
Вот отрисовка окружности, если быстро-быстро крутить потенциометр, то видно чётко две окружности - новая и старая.
Из 216 поста скетч пожалуйста трансформируйте, кажется в моих ранних версиях надо обязательно добавлять про установку страниц и столбцов всего экрана, это строки 73-78 из 216 поста. Ну принцип вашей "вставки" я наверное пойму :-)
Полностью нет, но отрисовка пошла шустрее. Теперь потенциометр надо дёргать, чтоб увидеть "шар в шаре", а при спокойном вращении шар просто убывает-возрастает в размерах.
#include <Wire.h>//Подключаю библиотеку протокола I2C.
int K = 0; // переменная хранения числа-столбца 8 пикселей
int st = 0;//счётчик числа пересылаемых байт данных за 1 сеанс (16 байт)
//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
Wire.write(comm);//Передаем команду.
Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
Wire.write(data);//Передаем данные.
Wire.endTransmission();//Завершаем передачу данных.
}
/////////////////////////////////////////////////////////////////////
void setup() {
///////////////////
pinMode(11, OUTPUT);
digitalWrite(11, HIGH);
delay(100);
///////////////////
Wire.begin();
//процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
oledCommand(0xAE);//выключение дисплея
oledCommand(0xD5);// Частота обновления экрана
oledCommand(0x80);
oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
oledCommand(0x0);
oledCommand(0x40);
oledCommand(0x8D);//включение емкостного умножителя
oledCommand(0x14);
oledCommand(0x20);//настройка адресации
oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
//Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
oledCommand(0xDA);
oledCommand(0x12);
oledCommand(0x81);//установка контрастности дисплея
oledCommand(0xCF);
oledCommand(0xD9);
oledCommand(0xF1);
oledCommand(0xDB); // установка Vcomh(влияет на яркость)
// oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
oledCommand(0x40);
oledCommand(0xA4);
oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
oledCommand(0xAF);//включение дисплея
Wire.setClock( 400000L );
}
void loop() {
/////////////////////
oledCommand(0x21);//установка столбца
oledCommand(0);//Начальный столбец.
oledCommand(127);//Конечный столбец.
oledCommand(0x22);//установка страницы
oledCommand(0);//Начальная страница.
oledCommand(7);//Конечная страница.
//////////////////////
int R = map(analogRead(A0), 0, 1020, 0, 63);// выставляем потенциометром выбранный параметр в фигуре
for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
if (st > 15) {
st = 0;
Wire.endTransmission();
Wire.beginTransmission(0x3C);
Wire.write(0x40);
} st++;
int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
bool sbros = true;
///
if (sbros == true && figura_1(x, y,63,32, R) ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
if (sbros == true && figura_1(x, y,80,20, R/2) ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
if (sbros == true && figura_1(x, y,40,45, 2*R/3) ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
}
Wire.write(K); K = 0; // отправляем "число-столбик в экран"
}
Wire.endTransmission(); //Завершаем передачу данных.
delay(25);
}
////////////////////// функция отрисовки окружности или круга
bool figura_1(int x, int y, int X,int Y,int R) {
if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R && ((x - X) * (x - X)) + ((y - Y) * (y - Y)) >= ( R - 1) * (R - 1)) {
return true;
} else {
return false;
}
}
Вот вариант "архитектуры" скетча - можно задавать фигуры с разными аргументами для анимации. Пока только из фигур окружность и круг можно.
/////шкала индикатор уровня сигнала
#include <Wire.h>//Подключаю библиотеку протокола I2C.
int K = 0; // переменная хранения числа-столбца 8 пикселей
int st = 0;//счётчик числа пересылаемых байт данных за 1 сеанс (16 байт)
//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
Wire.write(comm);//Передаем команду.
Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
Wire.write(data);//Передаем данные.
Wire.endTransmission();//Завершаем передачу данных.
}
/////////////////////////////////////////////////////////////////////
void setup() {
///////////////////
pinMode(11, OUTPUT);
digitalWrite(11, HIGH);
delay(100);
///////////////////
Wire.begin();
//процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
oledCommand(0xAE);//выключение дисплея
oledCommand(0xD5);// Частота обновления экрана
oledCommand(0x80);
oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
oledCommand(0x0);
oledCommand(0x40);
oledCommand(0x8D);//включение емкостного умножителя
oledCommand(0x14);
oledCommand(0x20);//настройка адресации
oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
//Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
oledCommand(0xDA);
oledCommand(0x12);
oledCommand(0x81);//установка контрастности дисплея
oledCommand(0xCF);
oledCommand(0xD9);
oledCommand(0xF1);
oledCommand(0xDB); // установка Vcomh(влияет на яркость)
// oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
oledCommand(0x40);
oledCommand(0xA4);
oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
oledCommand(0xAF);//включение дисплея
Wire.setClock( 400000L );
}
void loop() {
/////////////////////
oledCommand(0x21);//установка столбца
oledCommand(0);//Начальный столбец.
oledCommand(127);//Конечный столбец.
oledCommand(0x22);//установка страницы
oledCommand(0);//Начальная страница.
oledCommand(7);//Конечная страница.
//////////////////////
int R = map(analogRead(A0), 0, 1020, 2, 125);// выставляем потенциометром выбранный параметр в фигуре
for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
if (st > 15) {
st = 0;
Wire.endTransmission();
Wire.beginTransmission(0x3C);
Wire.write(0x40);
} st++;
int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
bool sbros = true;
///
if (sbros == true && figura_2(x, y, R, 32, 1, 24, true) ) { // указатель-стрелка
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
if (sbros == true && figura_2(x, y, 40, 32, 35 , 10, false) ) { // шкала
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
if (sbros == true && figura_2(x, y, 100, 32, 20 , 10, false) ) { //шкала
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
if (sbros == true && figura_2(x, y, 63, 32, 63, 31, false) ) { // шкала
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
}
Wire.write(K); K = 0; // отправляем "число-столбик в экран"
}
Wire.endTransmission(); //Завершаем передачу данных.
delay(25);
}
////////////////////// функция отрисовки окружности или круга
bool figura_1(int x, int y, int X, int Y, int R, bool f) { //проверяет принадлежит ли пиксель с координатами x,y окружности/кругу (false/true)с координатами X,Y центра и радиуса R
if (f == false) {
if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R && ((x - X) * (x - X)) + ((y - Y) * (y - Y)) >= ( R - 1) * (R - 1)) {//окружность
return true;
} else {
return false;
}
}
else {
if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R ) {//круг
return true;
} else {
return false;
}
}
}
///////////////////////////////
////////////////////// функция отрисовки прямоугольника закрашенного или нет
bool figura_2(int x, int y, int X, int Y, int R1, int R2 , bool f) { //проверяет принадлежит ли пиксель с координатами x,y прямоугольнику незакрашенному/закрашенному (false/true)с координатами центра X,Y и длинами полусторон R1,R2.
if (f == false) {
if (((x <= X + R1 && x > X + R1 - 1 || x >= X - R1 && x < X - R1 + 1 ) && (y <= Y + R2 && y >= Y - R2)) || (x <= X + R1 && x >= X - R1 && (y <= Y + R2 && y > Y + R2 - 1 || y >= Y - R2 && y < Y - R2 + 1)) ) { //прямоугольник
return true;
} else {
return false;
}
}
else {
if (x <= X + R1 && x >= X - R1 && y <= Y + R2 && y >= Y - R2 ) { //прямоугольник закрашенный
return true;
} else {
return false;
}
}
}
///////////////////////////////
/////шкала индикатор уровня сигнала
#define SCL0PORT PORTC
#define SCL0PIN PORTC5
#define SDA0PORT PORTC
#define SDA0PIN PORTC4
#define SCL1PORT PORTB
#define SCL1PIN PORTB3
#define SDA1PORT PORTB
#define SDA1PIN PORTB4
#include <avr/pgmspace.h>
void __attribute__ ((noinline)) i2c_init(uint8_t device = 0) {
asm volatile(
"TST %8\n\t"
"BRNE i2c_init_1\n\t"
"CBI %0-1,%1\n\t"
"CBI %2-1,%3\n\t"
"CBI %2,%3\n\t"
"CBI %0,%1\n\t"
"RJMP i2c_init_2\n\t"
"i2c_init_1:\n\t"
"CBI %4-1,%5\n\t"
"CBI %6-1,%7\n\t"
"CBI %6,%7\n\t"
"CBI %4,%5\n\t"
"NOP\n\t"
"i2c_init_2:\n\t"
::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN),
"I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
"r" (device)
);
}
void __attribute__ ((noinline)) i2c_start(uint8_t device = 0) {
asm volatile(
"SBRS %4,0\n\t"
"SBI %0-1,%1\n\t"
"SBRC %4,0\n\t"
"SBI %2-1,%3\n\t"
::"I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
"r" (device)
);
}
void __attribute__ ((noinline)) i2c_write(uint8_t data, uint8_t device = 0) {
uint8_t b, i;
asm (
"LDI %10,8\n\t"
"i2c_write_1:"
"SBRS %8,0\n\t"
"SBI %0-1,%1\n\t"
"SBRC %8,0\n\t"
"SBI %4-1,%5\n\t"
"ROL %9\n\t"
"BRCS i2c_write_2\n\t"
"SBRS %8,0\n\t"
"SBI %2-1,%3\n\t"
"SBRC %8,0\n\t"
"SBI %6-1,%7\n\t"
"RJMP i2c_write_3\n"
"i2c_write_2:\n\t"
"SBRS %8,0\n\t"
"CBI %2-1,%3\n\t"
"SBRC %8,0\n\t"
"CBI %6-1,%7\n\t"
"NOP\n"
"i2c_write_3:\n\t"
"LDI %11,4\n"
"i2c_write_4:\n\t"
"DEC %11\n\t"
"BRNE i2c_write_4\n\t"
"SBRS %8,0\n\t"
"CBI %0-1,%1\n\t"
"SBRC %8,0\n\t"
"CBI %4-1,%5\n\t"
"LDI %11,2\n"
"i2c_write_5:\n\t"
"DEC %11\n\t"
"BRNE i2c_write_5\n\t"
"DEC %10\n\t"
"BRNE i2c_write_1\n\t"
"NOP\n\t"
"SBRS %8,0\n\t"
"SBI %0-1,%1\n\t"
"SBRC %8,0\n\t"
"SBI %4-1,%5\n\t"
"SBRS %8,0\n\t"
"CBI %2-1,%3\n\t"
"SBRC %8,0\n\t"
"CBI %6-1,%7\n\t"
"TST %8\n\t"
"BRNE i2c_write_6\n\t"
"NOP\n"
"i2c_write_7:\n\t"
"SBIC %2-2,%3\n\t"
"RJMP i2c_write_7\n\t"
"RJMP i2c_write_8\n"
"i2c_write_6:\n\t"
"SBIC %6-2,%7\n\t"
"RJMP i2c_write_6\n\t"
"NOP\n\t"
"NOP\n"
"i2c_write_8:\n\t"
"LDI %11,3\n\t"
"i2c_write_9:\n\t"
"DEC %11\n\t"
"BRNE i2c_write_9\n\t"
"SBRS %8,0\n\t"
"CBI %0-1,%1\n\t"
"SBRC %8,0\n\t"
"CBI %4-1,%5\n\t"
"LDI %11,3\n"
"i2c_write_10:\n\t"
"DEC %11\n\t"
"BRNE i2c_write_10\n\t"
"SBRS %8,0\n\t"
"SBI %0-1,%1\n\t"
"SBRC %8,0\n\t"
"SBI %4-1,%5\n\t"
"LDI %11,4\n"
"i2c_write_11:\n\t"
"DEC %11\n\t"
"BRNE i2c_write_11\n\t"
"NOP\n\t"
"NOP\n\t"
::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN),
"I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
"r" (device), "r" (data), "r" (b), "r" (i)
);
}
void __attribute__ ((noinline)) i2c_stop(uint8_t device = 0) {
uint8_t i;
asm volatile(
"SBRS %8,0\n\t"
"SBI %2-1,%3\n\t"
"SBRC %8,0\n\t"
"SBI %6-1,%7\n\t"
"LDI %9,6\n"
"i2c_stop_1:\n\t"
"DEC %9\n\t"
"BRNE i2c_stop_1\n\t"
"SBRS %8,0\n\t"
"CBI %0-1,%1\n\t"
"SBRC %8,0\n\t"
"CBI %4-1,%5\n\t"
"LDI %9,2\n\t"
"i2c_stop_2:\n\t"
"DEC %9\n\t"
"BRNE i2c_stop_2\n\t"
"SBRS %8,0\n\t"
"CBI %2-1,%3\n\t"
"SBRC %8,0\n\t"
"CBI %6-1,%7\n\t"
"LDI %9,3\n"
"i2c_stop_3:\n\t"
"DEC %9\n\t"
"BRNE i2c_stop_3\n\t"
::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN),
"I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
"r" (device), "r" (i)
);
}
#define addr 0x3C
static const uint8_t PROGMEM init_bytes[] = {addr << 1, 0x00, 0xAE, 0xD5, 0x80, 0xD3, 0x0, 0x40, 0x8D, 0x14, 0x20, 0x00, 0xA1, 0xC8, 0xDA, 0x12, 0x81, 0xCF, 0xD9, 0xF1, 0xDB, 0x40, 0xA4, 0xA6, 0xAF, 0x21, 0, 127, 0x22, 0, 7};
/////////////////////////////////////////////////////////
int K = 0; // переменная хранения числа-столбца 8 пикселей
/////////////////////////////////////////////////////////////////////
void setup() {
///////////////////
pinMode(11, OUTPUT);
digitalWrite(11, HIGH);
delay(100);
///////////////////
i2c_init();
i2c_start();
for (uint8_t i = 0; i < sizeof(init_bytes); i++) i2c_write(pgm_read_byte(init_bytes + i));
asm volatile ("nop\n\t""nop");
i2c_stop();
i2c_start();
i2c_write(addr << 1);
asm volatile ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop");
i2c_write(0x40);
asm volatile ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop");
}
void loop() {
int R = map(analogRead(A0), 0, 1020, 1, 126);// выставляем потенциометром выбранный параметр в фигуре
for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
bool sbros = true;
///
if (sbros == true && figura_2(x, y, R, 32, 1, 24, true) ) { // указатель-стрелка
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
if (sbros == true && figura_2(x, y, 40, 32, 35 , 10, false) ) { // шкала
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
if (sbros == true && figura_2(x, y, 100, 32, 20 , 10, false) ) { //шкала
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
if (sbros == true && figura_2(x, y, 63, 32, 63, 31, false) ) { // шкала
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
sbros = false;
}
///
}
i2c_write(K); K = 0; // отправляем "число-столбик в экран"
}
delay(25);
}
////////////////////// функция отрисовки окружности или круга
bool figura_1(int x, int y, int X, int Y, int R, bool f) {
if (f == false) {
if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R && ((x - X) * (x - X)) + ((y - Y) * (y - Y)) >= ( R - 1) * (R - 1)) {//окружность
return true;
} else {
return false;
}
}
else {
if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R ) {//круг
return true;
} else {
return false;
}
}
}
///////////////////////////////
////////////////////// функция отрисовки прямоугольника закрашенного или нет
bool figura_2(int x, int y, int X, int Y, int R1, int R2 , bool f) {
if (f == false) {
if (((x <= X + R1 && x > X + R1 - 1 || x >= X - R1 && x < X - R1 + 1 ) && (y <= Y + R2 && y >= Y - R2)) || (x <= X + R1 && x >= X - R1 && (y <= Y + R2 && y > Y + R2 - 1 || y >= Y - R2 && y < Y - R2 + 1)) ) { //прямоугольник
return true;
} else {
return false;
}
}
else {
if (x <= X + R1 && x >= X - R1 && y <= Y + R2 && y >= Y - R2 ) { //прямоугольник закрашенный
return true;
} else {
return false;
}
}
}
///////////////////////////////
Вот она, первая шкала. Всего четыре вызова одной функции с разными аргументами. Оба варианта скетча работают визуально одинаково, второй не использует динамическую память (пишет 0 процентов) и весит минимум. Фризы (слово новое узнал :-) на стрелке видны одинаково. В общем путь к про мини 168 и 17 экранчикам на ней - открыт :-)
Конечно постичь "формулу" контура прямоугольника без издевательств над дисплеем было невозможно.
/////шкала приёмника
#include <Wire.h>//Подключаю библиотеку протокола I2C.
int K = 0; // переменная хранения числа-столбца 8 пикселей
int st = 0;//счётчик числа пересылаемых байт данных за 1 сеанс (16 байт)
extern const unsigned char schkala_A[];
extern const unsigned char schkala_B[];
//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
Wire.write(comm);//Передаем команду.
Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
Wire.write(data);//Передаем данные.
Wire.endTransmission();//Завершаем передачу данных.
}
/////////////////////////////////////////////////////////////////////
void setup() {
///////////////////
pinMode(11, OUTPUT);
digitalWrite(11, HIGH);
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
delay(100);
///////////////////
Wire.begin();
//процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
oledCommand(0xAE);//выключение дисплея
oledCommand(0xD5);// Частота обновления экрана
oledCommand(0x80);
oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
oledCommand(0x0);
oledCommand(0x40);
oledCommand(0x8D);//включение емкостного умножителя
oledCommand(0x14);
oledCommand(0x20);//настройка адресации
oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
//Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
oledCommand(0xDA);
oledCommand(0x12);
oledCommand(0x81);//установка контрастности дисплея
oledCommand(0xCF);
oledCommand(0xD9);
oledCommand(0xF1);
oledCommand(0xDB); // установка Vcomh(влияет на яркость)
// oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
oledCommand(0x40);
oledCommand(0xA4);
oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
oledCommand(0xAF);//включение дисплея
Wire.setClock( 400000L );
}
void loop() {
/////////////////////
oledCommand(0x21);//установка столбца
oledCommand(0);//Начальный столбец.
oledCommand(127);//Конечный столбец.
oledCommand(0x22);//установка страницы
oledCommand(0);//Начальная страница.
oledCommand(7);//Конечная страница.
//////////////////////
int R = map(analogRead(A0), 0, 1023, 0, 265);// выставляем потенциометром выбранный параметр в фигуре
bool fl_;
if(R<133){digitalWrite(10, HIGH);digitalWrite(11, LOW);fl_=true;}else{digitalWrite(10, LOW);digitalWrite(11, HIGH);fl_=false;R=R-140;}//
for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
if(fl_==true){K=pgm_read_byte(&schkala_A[i]);}else{K=pgm_read_byte(&schkala_B[i]);}
if (st > 15) {
st = 0;
Wire.endTransmission();
Wire.beginTransmission(0x3C);
Wire.write(0x40);
} st++;
int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
if ( figura_2(x, y, R, 32, 2, 24, false) ) { // указатель-стрелка
int bi = y % 8;
K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
}
}
Wire.write(K); // отправляем "число-столбик в экран"
}
Wire.endTransmission(); //Завершаем передачу данных.
delay(25);
}
////////////////////// функция отрисовки прямоугольника закрашенного или нет
bool figura_2(int x, int y, int X, int Y, int R1, int R2 , bool f) { //проверяет принадлежит ли пиксель с координатами x,y прямоугольнику незакрашенному/закрашенному (false/true)с координатами центра X,Y и длинами полусторон R1,R2.
if (f == false) {
if (((x <= X + R1 && x > X + R1 - 1 || x >= X - R1 && x < X - R1 + 1 ) && (y <= Y + R2 && y >= Y - R2)) || (x <= X + R1 && x >= X - R1 && (y <= Y + R2 && y > Y + R2 - 1 || y >= Y - R2 && y < Y - R2 + 1)) ) { //прямоугольник
return true;
} else {
return false;
}
}
else {
if (x <= X + R1 && x >= X - R1 && y <= Y + R2 && y >= Y - R2 ) { //прямоугольник закрашенный
return true;
} else {
return false;
}
}
}
///////////////////////////////
Ну да, штучная кнопка с их профилем не вариант. На али китайцы не "проболтались"- я и близко похожего не нашёл. Просто синтез механики и экранов делает идею избыточно интересной.
Мне охота будильник механический нарисовать для своих часов (дисплей 128*64,но ST7565)
Нет смысла рисовать. Проще в поисковике вбить "иконки будильник". Выбрать например:
Используя paint.net затереть стрелки, уменьшить размер картинки до 64*64 пикселя. Затем с помощью image2LCD превратить картинку в массив чисел и вставить в скетч часов как просто фоновую картинку. Если это получится на ваших часах - расскажу дальше.
При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)
И их тоже как то надо выбирать сообразно фигурам.
с заметной глазу отрисовкой экрана
Через Wire так и должно быть - Вы на каждый байт команды или данных организуете:
Старт - Байт признака команды/данные - Сам байт - Стоп (Избыточность около х3)
В эти дисплеи нужно слать ИНАЧЕ (если аппаратную прокрутку не используем-команды только для инициализации дисплея):
Старт - Байт признака команды - ВСЕ БАЙТЫ КОМАНД подряд - Стоп
Старт - Байт признака данные - ВСЕ БАЙТЫ ДАННЫХ ... ... ...
Стоп уже не нужен.
p.s. Сама Wire имеет буфер :-)
При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)
И их тоже как то надо выбирать сообразно фигурам.
столбцовый примитив нужен всего один - это вертикальная линия с тремя параметрами - координаты х у точки начала и длина. ВСЕ
При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)
А что, "различные одновременные комбинации фигур" - это обязательно для данного проекта?
Научитесь, наконец, выделять главное и жертвовать второстепенным. Без такого умения у Вас ничего не получится.
И их тоже как то надо выбирать сообразно фигурам.
Да - для каждого проекта свои примитивы. Не нужно только пытаться создать единые примитивы универсальные для всех проектов одновременно. Ну не будут они все на одном экране. Сам формат 128х64 этого не позволяет.
с заметной глазу отрисовкой экрана
Через Wire так и должно быть - Вы на каждый байт команды или данных организуете:
Старт - Байт признака команды/данные - Сам байт - Стоп (Избыточность около х3)
В эти дисплеи нужно слать ИНАЧЕ (если аппаратную прокрутку не используем-команды только для инициализации дисплея):
Старт - Байт признака команды - ВСЕ БАЙТЫ КОМАНД подряд - Стоп
Старт - Байт признака данные - ВСЕ БАЙТЫ ДАННЫХ ... ... ...
Стоп уже не нужен.
p.s. Сама Wire имеет буфер :-)
Попробовал вот так для основного блока (как мне кажется сообразно предлагаемой логике) - не работает.
Пардон, набрехал в 15 строке надо другое число.
При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)
И их тоже как то надо выбирать сообразно фигурам.
столбцовый примитив нужен всего один - это вертикальная линия с тремя параметрами - координаты х у точки начала и длина. ВСЕ
А если много горизонтальных отрезков через пиксель?
При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)
А что, "различные одновременные комбинации фигур" - это обязательно для данного проекта?
Научитесь, наконец, выделять главное и жертвовать второстепенным. Без такого умения у Вас ничего не получится.
И их тоже как то надо выбирать сообразно фигурам.
Да - для каждого проекта свои примитивы. Не нужно только пытаться создать единые примитивы универсальные для всех проектов одновременно. Ну не будут они все на одном экране. Сам формат 128х64 этого не позволяет.
Стратегию я понял, но морально к ней не готов.
А если много горизонтальных отрезков через пиксель?
если у вас вертикально-стролбцовая организация видиопамяти - то от горизонтальных примитивов вы много не выиграете.
Вообще, подобная оптимизация всегда процесс равновесный. Примитивы ускоряют вывод на экран (во всяком случае должны бы :)), но на выбор между примитивами и на вызов функций, передачу параметров - тоже тратится процессорное время, поэтому на некоторых текстурах примитивы могут давать выигрыш, а на других - почти не сказываться на скорости или даже замедлять процесс.
не работает
Буфер Wire по умолчанию 32 байта.
После 32 посылок надо Wire.endtransmission(false)
т.е. посылать буфер физически без посыла Stop.
Если не тяжело поправьте в скетче. Этот работает, но только при 16 числах-столбцах в одной передаче, иначе начинает картинка чудить. Смысл деяний моих в строках 82 и 105.
lilik в 107 сообщении возьмите код.
Там без буфера-каждый байт улетает в железо на максимальной скорости для АВР.
:-)
Я вообще ничего в нём не понимаю, что брать, куда вставлять и т.д.
:-) :-) :-)
Какой ваш код работает, но с фризами? В 197 сообщении ?
Вот отрисовка окружности, если быстро-быстро крутить потенциометр, то видно чётко две окружности - новая и старая.
Это из 197. Оказывается в 107 версия на 1 МГц, но за то на два девайса на разных пинах !
А вот FULL SPEED:
Работает, но вместо 1 шара два.
Логику я вроде не менял и байты инициализации Ваши скопировал...
Из 216 поста скетч пожалуйста трансформируйте, кажется в моих ранних версиях надо обязательно добавлять про установку страниц и столбцов всего экрана, это строки 73-78 из 216 поста. Ну принцип вашей "вставки" я наверное пойму :-)
Вы байты из этих строк:
oledCommand(0x21);
//установка столбца
74
oledCommand(0);
//Начальный столбец.
75
oledCommand(127);
//Конечный столбец.
76
oledCommand(0x22);
//установка страницы
77
oledCommand(0);
//Начальная страница.
78
oledCommand(7);
//Конечная страница.
добавьте в массив инициализации ...
получим:
static
const
uint8_t PROGMEM init_bytes[]={addr<<1,0x00,0xAE,0xD5,0x80,0xD3,0x0,0x40,0x8D,0x14,0x20,0x00,0xA1,0xC8,0xDA,0x12,0x81,0xCF,0xD9,0xF1,0xDB,0x40,0x21,0,127,0x22,0,7,0xA4,0xA6,0xAF};
Попробую.
Спасибо, всё сработало!
Фризы пропали ?
Полностью нет, но отрисовка пошла шустрее. Теперь потенциометр надо дёргать, чтоб увидеть "шар в шаре", а при спокойном вращении шар просто убывает-возрастает в размерах.
Вот вариант "архитектуры" скетча - можно задавать фигуры с разными аргументами для анимации. Пока только из фигур окружность и круг можно.
Вот она, первая шкала. Всего четыре вызова одной функции с разными аргументами. Оба варианта скетча работают визуально одинаково, второй не использует динамическую память (пишет 0 процентов) и весит минимум. Фризы (слово новое узнал :-) на стрелке видны одинаково. В общем путь к про мини 168 и 17 экранчикам на ней - открыт :-)
Конечно постичь "формулу" контура прямоугольника без издевательств над дисплеем было невозможно.
Вот ещё пример "безбуферного функционального рисования". В принципе использовать можно, но с классической библиотекой будет проще.
Шкала с нониусом, по типу как у микрометра.
Индикатор включения-выключения-регулировки яркости лампочки с эффектом сияния, будет полезна поджигателям светодиодов в качестве тренажера.
:-)
Хорошо.
Есть ещё революционная идея с графической кнопкой-дисплеем, электронным калейдоскопом и т.д.
Я же говорю, множества Мандельброта!
Вот такая, с утра смотрел (не могу найти ссылку), 183 бакса. Грех не попробовать на экранчике 0,96.
Я же говорю, множества Мандельброта!
Да...аааа, хотел просто 3 зеркала на дисплей водрузить :-)
Только проводов многовато, как то надо схемно разрулить.
пока есть хоть какие идеи останавливаться нельзя
пока есть хоть какие идеи останавливаться нельзя
Да сама идея не нова, но просто купить совсем не просто. Нашёл 1 ссылку всего и без ценника.
https://www.e3-keys.com/index.html
Если бы китайцы подрезали платку до границ экранчика хоть бы в 3 линиях, а не 2 - "былоб красивше".
https://www.artlebedev.ru/optimus/mini-six/
Такая же штука. Думаю, что Лебедев притырил где-нить идейку и китайцы давно уже шмякают такие управляшки.
Ну да, штучная кнопка с их профилем не вариант. На али китайцы не "проболтались"- я и близко похожего не нашёл. Просто синтез механики и экранов делает идею избыточно интересной.
Микрое делает такое. Вроде как $99 за девкит просят.
Посмотрю, полажу по роликам на ютубе :-)
https://www.mikroe.com/oled-switch-click
Как изящно, прям до слёз. Почему цену сразу не пишут?, чтобы "синтементы" отбить.
Почему не пишут... $74.25 только сегодня.
В чипдипе - 14+ тыщ рэ.
:-))))
Разглядел!
А в какой программе вы рисуете?
Мне охота будильник механический нарисовать для своих часов (дисплей 128*64,но ST7565)
А в какой программе вы рисуете?
Мне охота будильник механический нарисовать для своих часов (дисплей 128*64,но ST7565)
Нет смысла рисовать. Проще в поисковике вбить "иконки будильник". Выбрать например:
Используя paint.net затереть стрелки, уменьшить размер картинки до 64*64 пикселя. Затем с помощью image2LCD превратить картинку в массив чисел и вставить в скетч часов как просто фоновую картинку. Если это получится на ваших часах - расскажу дальше.
ДА-ДА!Именно это я и хотел!
Попробовал загрузить ваши картинки , почему то бочка у меня боком лежит...
http://arduino.ru/sites/default/files/u61453/dscn1187.jpg