Ви не увійшли.
Боюсь вас огорчить, но по моему мнению за такое никто не заплатит.
Почему вы не хотите использовать WEB-интерфейс. Например ESP32 + WiFi.
Я разрабатываю не массовое устройство. Так что да, заплатят только те, кому это очень нужно. Я промониторил рынок, есть только два похожих прибора в ценовой категории до 250$. Мой девайс обойдется дешевле, при почти тех же возможностях.
Веб интерфейс мне не нужен, это настольный прибор. Допустим как осцилограф. Хотя наличие вебморды было бы интересным решением, но только в связке с соответтствующим ПО для смартфона и возможностью мониторинга удаленно, а не только в домашней сети. За такую опцию точно никто не заплатит))
Рассматриваю кстати использование вместо ESP32 вместо Arduino. Будет и быстрее и даже немного дешевле.
Попутно столкнулся с другими проблемами. Не все комплектующие работают так как задумывалось, приходится импровизировать на ходу. Корпусно-крепежные проблемы.
Так вот. Заполнение 11 строк описательным текстом 16м шрифтом занимает 10 секунд, потом отображаются получаемые данные. Данные бывают либо текст, либо цифры. Это еще 2 секунды.
Боюсь вас огорчить, но по моему мнению за такое никто не заплатит.
Почему вы не хотите использовать WEB-интерфейс. Например ESP32 + WiFi. Программирование то же, что и для Arduino, но в результате получите возможность отобразить ваши результаты мгновенно в "цветах и красках" на WEB странице любого устройства - компьютера, смартфона, планшета. Дополнительно появляется возможность анимации, графики и картинки.
Вот, например структурная схема подобной системы
ESP32 управляет фанкойлами системы кондиционирования, при этом к ней можно подлючиться по WiFi для просмотра параметров и управления процессом.
Для ESP32 мы разработали печатную плату, которая помещается в стандартный подрозетник. Удобно, когда есть сложности с прокладкой проводов, например в действующих офисах.
Watchdog пише:Подскажу:
void bar(void) { // ... } void (*foo)[n](void) = {bar, ...}; for (int i = 0; i < n; i++) foo[i]();
Ваша конструкция не заработала, не знаю почему. Я не силен тонкостях программирования. ...
Не во всех версиях С допустимы массивы функций да ещё и с анонимными типами. Я же привёл псевдокод. Вот это работает в С99 и С11.
void bar(void) {
// ...
}
typedef void (*foo_t)(void);
foo_t foo[] = {bar, bar};
int main ()
{
for (int i = 0; i < 2; i++) foo[i]();
return 0;
}
Есть еще одна проблема. Если плата подключена к компу по USB и комп выключить, то плата виснет. Помогает только передергивание кабеля. Не критично, но раздражает. Думаю как то сторожевого пса приделать, чтоб следил за Serial. Но пока не курил эту тему
Тут пёс ничем не поможет, это же не шахматы. И занятие это не для раздражительных, можно обкуриться до тошноты, если нервничать по мелочам.
лучше заранее предусмотреть защиту от такого поведения.
Ну, тогда предусматривай.
Забыл сказать. Плата не питается от USB, у нее отдельное питание. По USB только передается инфа в Serial. Так что, если даже компу сказать, чтобы он не отрубал питание с USB, не факт, что плата не зависнет.
И потом, расчитывая на все случаи жизни, лучше заранее предусмотреть защиту от такого поведения.
А не проще компьютеры объяснить, чтобы он юсб не вырубал? Ты ж не из розетки выдёргиваешь?
Есть еще одна проблема. Если плата подключена к компу по USB и комп выключить, то плата виснет. Помогает только передергивание кабеля. Не критично, но раздражает. Думаю как то сторожевого пса приделать, чтоб следил за Serial. Но пока не курил эту тему
Подскажу:
void bar(void) { // ... } void (*foo)[n](void) = {bar, ...}; for (int i = 0; i < n; i++) foo[i]();
Ваша конструкция не заработала, не знаю почему. Я не силен тонкостях программирования. Подсмотрел здесь
решение, не все понял, но результат устраивает. То, чего я добивался, получилось. Вот результат:
volatile boolean intFlag = false; // Флаг прерывания
int key = false; // Флаг нажатия кнопки
int newscreen = false; // Флаг нового экрана
pinMode(7, INPUT_PULLUP); // Кнопка на седьмой пин где будет ловиться прерывание №4
char *text1[]={ // Массив текстовых сообщений 1
"Сообщение 0:",
....
"Сообщение 9:",
};
void function_0 (void); // Объявление функций, сами функции расписаны в конце
....
void function_9 (void);
void (*a0)(void) = &function_0; // Создание указателей на адреса функций,
.... // которые получают данные с устройства
void (*a9)(void) = &function_9;
typedef void (* FuncPtr1) (); // Создание типа с названием FuncPtr1
// который представляет собой указатель на функцию
FuncPtr1 param1[10] = {a0, .... , a9}; // Складывание указателей в массив
// То же самое для второго экрана
char *text1[]={ // Массив текстовых сообщений 2
"Сообщение 10:",
....
"Сообщение 19:",
};
void function_10 (void); // Объявление функций, сами функции расписаны ниже
....
void function_19 (void);
void (*b0)(void) = &function_10; // Создание указателей на адреса функций
.... // которые получают данные с устройства
void (*b9)(void) = &function_19;
typedef void (* FuncPtr1) (); // Создание типа с названием FuncPtr2
// который представляет собой указатель на функцию
FuncPtr1 param2[10] = {b0, .... , b9}; // Складывание указателей в массив
void setup()
{
// Тут всякие нужные действия
}
void loop()
{
switch (intFlag) { // Обработчик нажатия кнопки
case true:
intFlag = false; // Сброс флага прерывания
key = !key; // Нажатие на кнопку зафиксировано
newscreen = !newscreen; // Новый экран - Да
LCD_Clear(0x0000); // Очистка всего экрана
break;
}
switch (key) { // Реакция на кнопку выбора экрана
case false: // Первый экран
switch (newscreen) { // Новый экран?
case false: // Да, новый екран
for (int i = 0; i < 10; i++){
Paint_DrawString_EN(x, y(i), text1[i], шрифт, фон, цвет); // Выводить текст 1 с просчетом координаты Y
switch (device_ready()) { // Подключено ли устройство:
case false: // Нет - ничего не выводить
break;
default: // Да - выводить данные 1
param1[i]();
}
}
newscreen = !newscreen; // Сбрасываем флаг "Новый экран"
break;
case true: // Экран уже был, выводить только данные
for (int i = 0; i < 10; i++){
switch (device_ready()) { // Подключено ли устройство:
case false: // Нет - затереть пробелами предыдущие значения
Paint_DrawString_EN(x, y(i), " ", шрифт, фон, цвет); // с просчетом координаты Y
break;
default: // Да - выводить данные 1
param1[i]();
}
}
break;
}
attachInterrupt(4, buttonTick, LOW); // Реакция на кнопку разрешена
break;
case true: // Второй экран
switch (newscreen) { // Новый экран?
case false: // Да, новый экран
for (int i = 0; i < 10; i++){
Paint_DrawString_EN(x, y(i), text2[i], шрифт, фон, цвет); // Выводить текст 2
(device_ready()) { // Подключено ли устройство:
case false: // Нет - ничего не выводить
break;
default: // Да - выводить данные 2
param2[i]();
}
}
newscreen = !newscreen; // Сбрасываем флаг "Новый экран"
break;
case true: // Экран уже был, выводить только данные
for (int i = 0; i < 10; i++){
switch (device_ready()) { // Подключено ли устройство:
case false: // Нет - затереть пробелами предыдущие значения
Paint_DrawString_EN(x, y(i), " ", шрифт, фон, цвет); // с просчетом координаты Y
break;
default: // Да - выводить данные 2
param2[i]();
}
}
break;
}
attachInterrupt(4, buttonTick, LOW); // Реакция на кнопку разрешена
break;
}
// Далее вывод в сериал
}
// Куча полезных функций
void function_0(){} // Функции объявленные в самом начале
....
void function_19(){}
void buttonTick() { // Хитрая реакция на прерывание, подсмотрел на одном форуме
detachInterrupt(digitalPinToInterrupt(7)); // Запрещаем прерывания по пину 7
intFlag = true; // Установка флага прерывания
}
Всем спасибо за идеи, конструктивная критика и новые идеи приветствуются
Не хочу трепаться что именно, вдруг выгорит и стану миллионером
Понятно.
Ну, тогда и я не буду трепаться как это делается, вдруг мне это объяснение кто-нить за миллион закажет.
Задача почти допилена, можно в принципе и так бросить, но я пока жду комплектуху из Китая, поэтому допиливаю по мере просветления мозгов.
По I2C подключен некий прибор, который может выдавать тучу параметров. Не хочу трепаться что именно, вдруг выгорит и стану миллионером ...
Миллиардером! "Пилите шура она золотая!" - из к.ф. Двенадцать стульев.
но надо задачу понимать.
Задача почти допилена, можно в принципе и так бросить, но я пока жду комплектуху из Китая, поэтому допиливаю по мере просветления мозгов.
По I2C подключен некий прибор, который может выдавать тучу параметров. Не хочу трепаться что именно, вдруг выгорит и стану миллионером
По SPI подключен IPS TFT дисплей 320х240.
Стандартная библиотека дисплея умеет выводить 'символы' по коду, "строку из букв", числа ну и рисовать всякие отрезки треугольники и прочие прямоугольники. Я пробовал другие библиотеки под чип ST7789, они не завелись. (почему то не работала треть экрана как я его не вращал, хотя в библиотеках была поддержка дисплея 320х240). Это сейчас не важно, использую, то, что работает.
Так вот. Заполнение 11 строк описательным текстом 16м шрифтом занимает 10 секунд, потом отображаются получаемые данные. Данные бывают либо текст, либо цифры. Это еще 2 секунды.
По нажатию кнопки дисплей стирается и отображаются еще 12 строк с тектом и параметрами.
Были некоторые трудности с приведением этого месива в красивый вид, чтобы не моргало лишний раз, об этом я писал в другом посте про оптимизацию вывода на дисплей. Сейчас все красиво и волшебно, но захотелось уплотнить код (сейчас используется 87% ROM и 55% RAM) так как в будущем хочу добавить пару хотелок, или не хочу. Пока не уверен.
После дисплея инфа выводится в сериал. (это я еще допиливаю, раскрашиваю в цвет и делаю таблицу).
Так вот, по поводу оптимизации. Хочу избавится от бесконечных if и goto. Не знаю почему, но опытных программеров они раздражают. Начал делать. И тут пришла идея вообще нафик все переделать. Чтобы было строка_описательного_текста_1 + данные_1, строка_описательного_текста_2 + данные_2 и так далее. Покурил указатели на функции, вроде бы то, что нужно. Ведь все уже набрано, осталось грубо говоря пронумеровать куски и выдавать их потом в любой последовательности.
Пока не могу вкурить как выдать на дисплей String
String formatted_date = "";
formatted_date += year;
formatted_date += "-";
formatted_date += month;
formatted_date += "-";
formatted_date += day;
Serial.println(formatted_date);
Вот так выдать в сериал можно, на дисплей нет
видосы
А что, читать не умеешь? Беда, если так :-(
Однажды я услышал фразу: не нужно зубрить матчасть, нужно сразу брать и пробовать.
Надеюсь, ты плюнул в рожу тому, кто тебе такой бред сказал?
А по задаче, делай массив указателей на функции, если так приспичило. Только ещё раз говорю - это прошлый век. На С++ так не пишут. Как пишут - могу подсказать, но надо задачу понимать.
luminofor пише:Однажды я услышал фразу: не нужно зубрить матчасть, нужно сразу брать и пробовать. На удачах и ошибках быстрее научишься.
Если только для души - то все отлично, если с дальнейшим развитием и поиском работы по этой специальности то беда. Приходят потом такие "научившиеся"
и вместо простых циклов городят зоопарки с "GOTO", "не ну ачо работает же"
А другие научившиеся таких принимают!
Тем кто хочет простоту
Жизни нет без GOTO.
Однажды я услышал фразу: не нужно зубрить матчасть, нужно сразу брать и пробовать. На удачах и ошибках быстрее научишься.
Если только для души - то все отлично, если с дальнейшим развитием и поиском работы по этой специальности то беда. Приходят потом такие "научившиеся"
и вместо простых циклов городят зоопарки с "GOTO", "не ну ачо работает же"