Сейчас это выглядит так: переменной number в цикле по-очереди присваиваются значения из массива. После окончания цикла на экран выводится число (от 0 до 8), что хранится в последней ячейке массива, т.е. уровень сигнала последнего (15-го) канала.
А должно быть так (пока так, а потом скорректируем): в цикле пересматриваем все ячейки массива и в процессе этого, если в ячейке не ноль, то выводим на экран номер этой ячейки, иначе - пустоту.
В частности, вы снова невнимательны и забываете, о чем я недавно уже говорил. Не брезгуйте фигурными скобками в for'ах, if'ах и т.п. Даже, если в цикле или условии, выполняется всего одна команда - заворачивайте ее в фигурные скобки. Вы (да и компилятор тоже) будете видеть границы блока.
То, что вы сделали отступ в строка 2-4, вовсе не значит, что все они относятся к циклу. Так, как у вас написано, к циклу относится только строка 2. Остальные - выполняются вне и после цикла.
upd. И еще в догонку к предыдущему, сразу не заметил. Запомните: все переменные, объявленные внутри блоков, за пределами этих блоков не видны и при выходе из этих блоков уничтожаются.
В данном случае таким блоком является цикл for - это строки 1 и 2. Поскольку переменную number вы объявили во 2-ой строке, т.е. внутри цикла, то в 3-й строке ее уже использовать нельзя, ее уже не будет существовать и функция showNumber(number) понятия не будет иметь, что за переменная такая этот number. Благо, это обнаружится еще на этапе компиляции и компилятор выдаст ошибку.
То, что я только-что написал перекликается с тем, что я писал ранее - если внутри блока объявить переменную с таким же именем, что и у переменной из "внешнего уровня", то это будет совсем другая переменная, хоть и с таким же именем.
Смотрите, давайте чуть-чуть вернемся и расставим точки над "i". Возможно вам будет проще понять.
Вы в сообщении #356 привели набросок скетча. Там есть такая строка:
byte number = LevelStolbik[i];
А почему вы назвали свою переменную number? Разве в массиве мы храним номера каналов? За номера каналов в данном случае отвечает переменная i, а в массиве мы храним уровни этих каналов. Не логичнее было бы назвать эту переменную level, а не number? Вот смотрите, что получается:
for (byte i = 0; i < 16; i++)
{
byte level = LevelStolbik[i];
if (level > 0)
{
// если мы обнаружили, что в этом канале уровень не нулевой, то должны вывести номер этого канала
}
else
{
// а если уровень равен 0, то выводим пусто
}
}
Что касается "showNumber() в скобках должна быть переменная". Да, чтобы вывести какое-то число на экран, в скобках должно быть указано это число или переменная, содержащая это число. В данном случае надо вывести номер канала. А какая переменная в этом цикле содержит номер канала?
upd. В догонку. Не обязательно в качестве параметра функции должна быть переменная. Вы же не пишете всегда:
int zaderzhka = 1000;
delay(zaderzhka);
а сразу:
delay(1000);
Переменная записывается в программе, только если нам заранее не известно, что передавать в функцию, и сначала это нужно вычислить, и то, это вычисление можно делать прямо в скобках при вызове функции:
showNumber( channel); // до меня вот тут не доходит ,
Ну да, до меня тоже :) , почему вы там пишите channel? Ведь мы сейчас находимся внутри цикла for (byte i = 0; i < 16;i++){.....
И каналы перебираем переменной i.
Забудьте пока о строках 1-10. Может так станет немного понятней. Мы сейчас обсуждаем только перебор и анализ значений массива.
Да, так правильно. Можно двигаться дальше. По-отдельности мы уже практически освоили все главные части программы: умеем выводить столбики с уровнями сигналов на каналах, умеем анализировать уровни и выводить номер канала с активным уровнем.
Но, если собрать в кучу эти части, как есть сейчас, и залить в ардуину, то результат, что будет отображаться на экране, нас не устроит вообще. Потому что считываем данные с каналов мы реже, чем делаем их анализ, но даже и так номера каналов будут выводиться так часто, что не успеем их разглядеть. Можно, конечно, поставить секундную задержку после вывода каждого числа и тогда числа на экране сможем разглядеть. Но это еще больше усугубит ситуацию со считыванием сигнала, т.к. каждый канал будет опрашиваться примерно 1 раз в 16 секунд, а на один цикл опроса всех 16 каналов и вовсе будет уходить более 4 минут! Весело, правда?
Т.е., нам надо сделать так, чтобы, как минимум, каналы опрашивались чаще, чем мы будем их анализировать для вывода номеров. Я сейчас пересоберу скетч для этого. Там мало чего поменяется, только поменяю опрос каналов и анализ данных местами, ну и немного переделаю его так, чтобы вам был больше понятен алгоритм (т.е. не буду оптимизировать, а наоборот, немного растяну и детализирую скетч). И уже после этого будем допиливать этот вариант.
да именно так и получиилось после заливки , да сложновато воспринять скетч , ни как не сложиться общая картина , все еще как то запутано , вроде по кусочкам все понятно , а целом не укладываться
Так оно и есть. Чтобы написать всю программу, сначала надо обкатать ее функциональные части. И, когда будет работать по частям, то склеить все в кучу проще.
Вот, что пока получилось. С этим кодом будем работать дальше:
#include "LedControl.h"
#define EN 3
#define S0 4
#define S1 5
#define S2 6
#define S3 7
#define SIG A0
LedControl LC = LedControl(12, 11, 10, 4);
byte LevelStolbik[16];
const byte CountDigits[10][8] =
{
{0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c}, //0
{0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e}, //1
{0x7c, 0x06, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x7e}, //2
{0x7c, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x7c}, //3
{0x06, 0x0e, 0x1e, 0x36, 0x66, 0x7e, 0x06, 0x06}, //4
{0x7e, 0x60, 0x60, 0x7c, 0x06, 0x06, 0x06, 0x7c}, //5
{0x1c, 0x30, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x3c}, //6
{0x7e, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x18}, //7
{0x3c, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x3c}, //8
{0x3c, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x0c, 0x38} //9
};
void setup()
{
Serial.begin(9600);
for (byte i = 0; i < 4; i++)
{
LC.shutdown(i, false);
LC.setIntensity(i, 1);
LC.clearDisplay(i);
}
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
digitalWrite(S0, LOW);
digitalWrite(S1, LOW);
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
pinMode(EN, OUTPUT);
digitalWrite(EN, LOW);
}
void loop()
{
//////// Опрос каналов /////////
// В этой части программы опрашиваем каналы с 0-го до 15-го,
// выводим уровень сигнала каждого канала в виде столбика
// и сохраняем уровни в массив для последующего анализа
for (byte channel = 0; channel < 16; channel++)
{
byte controlPin[] = { S0, S1, S2, S3 };
for (byte i = 0; i < 4; i++)
{
digitalWrite(controlPin[i], bitRead(channel, i));
}
int val = analogRead(SIG);
val = constrain(val, 0, 700);
val = map(val, 0, 700, 0, 8);
LC.setColumn(!(channel / 8), channel % 8, 255 >> (8 - val));
LevelStolbik[channel] = val;
}
///// Конец опроса каналов /////
//////////// Анализ ////////////
// В этой части анализируем массив с данными (со всеми
// уровнями), собранными в предыдущей части при опросе каналов
for (byte channel = 0; channel < 16; channel++)
{
byte level = LevelStolbik[channel];
if (level > 0)
{ // если уровень не нулевой, то выводим число с номером этого канала
byte edinicy = channel % 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(2, i, CountDigits[edinicy][i]);
}
if (channel < 10)
{
LC.clearDisplay(3);
}
else
{
byte desyatki = channel / 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(3, i, CountDigits[desyatki][i]);
}
}
}
else
{ // иначе (если уровень нулевой) - очищаем места под цифры
LC.clearDisplay(2);
LC.clearDisplay(3);
}
}
//////// Конец анализа /////////
}
Я обещал, что "растяну" код, но от showNumber(), как от отдельной функции, я избавился - разделил ее на две части (вывод числа и очистку матриц для "пусто") и перенес в основной код. Во-первых, как она работает, я надеюсь, уже разобрались. А, во-вторых, в коде она вызывалась только из одного места, поэтому не вижу особого смысла ту часть кода оформлять в функцию. От остального ненужного избавимся потом.
Попробуйте понять, как работает сейчас программа. В ардуину ее заливать не обязательно - визуально там почти ничего не изменилось. Когда поймете или не поймете, дайте знать, продолжим.
Хорошо. Подытожу, сейчас программа работает следующим образом: поочередно опрашиваются каналы от 0 до 15. Ихние уровни выводятся на экран и сохраняются в массив. Потом, также по-очереди, анализируются снова все каналы от 0 до 15 и для активных каналов прописываются ихние номера.
Но цифры все так же меняются быстро и разглядеть их не получиться. Надо вводить задержку. Задержку можно ввести в цикл перебора при анализе каналов:
//////////// Анализ ////////////
// В этой части анализируем массив с данными (со всеми
// уровнями), собранными в предыдущей части при опросе каналов
for (byte channel = 0; channel < 16; channel++)
{
byte level = LevelStolbik[channel];
if (level > 0)
{ // если уровень не нулевой, то выводим число с номером этого канала
byte edinicy = channel % 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(2, i, CountDigits[edinicy][i]);
}
if (channel < 10)
{
LC.clearDisplay(3);
}
else
{
byte desyatki = channel / 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(3, i, CountDigits[desyatki][i]);
}
}
}
else
{ // иначе (если уровень нулевой) - очищаем места под цифры
LC.clearDisplay(2);
LC.clearDisplay(3);
}
delay(1000);
}
//////// Конец анализа /////////
Теперь можно будет увидеть цифры. Но такая задержка снова будет влиять на скорость опроса каналов. Уже хоть и не 1 раз в 4 минуты, а всего 1 раз в 16 секунд, но это тоже долго. Немного снизить время ожидания можно, если зажержку ставить не на весь цикл, а только, для вывода цифр (если на экране пусто, то ждать 1 с незачем - нас интересуют только цифры):
//////////// Анализ ////////////
// В этой части анализируем массив с данными (со всеми
// уровнями), собранными в предыдущей части при опросе каналов
for (byte channel = 0; channel < 16; channel++)
{
byte level = LevelStolbik[channel];
if (level > 0)
{ // если уровень не нулевой, то выводим число с номером этого канала
byte edinicy = channel % 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(2, i, CountDigits[edinicy][i]);
}
if (channel < 10)
{
LC.clearDisplay(3);
}
else
{
byte desyatki = channel / 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(3, i, CountDigits[desyatki][i]);
}
}
delay(1000);
}
else
{ // иначе (если уровень нулевой) - очищаем места под цифры
LC.clearDisplay(2);
LC.clearDisplay(3);
}
}
//////// Конец анализа /////////
Т.е. вывели число, подождали 1 с, проверяем следующее. Время бездействия сократится, но не существенно - при одном активном канале будет 1 с, а при 16 - все те же 16 с. Тоже не вариант.
Значит, будем делать по-другому. Кстати, а у вас есть предложения, как?
Не забывайте, что только отображать - мало. Это будет работать, если активный канал только один. Но если их будет хотя бы два, то на экране начнется такая же свистопляска - то одно, то другое число будут перемигиваться на экране с огромной скоростью. Если бы человек успевал с такой же скоростью различать числа - проблем бы не было. Но нам нужна пауза между отображениями чисел. А это получается практически последний код с delay в 97 строке.
И да, никаких условных 255 мы уже никуда не отправляем. То было только для обучения и одного из вариантов. Помотрите код. Мы уже в основном коде делаем анализ - если в элементе массива не ноль, то выводим номер канала, иначе - чистим матрицы.
тогда возможен один вариант разделить столбики и отбражение , тоесть столбики работают сами по себе а цыфры беруться с накопленого буфера , а если значение столбиков достигло нуля чистим матрицы
У нас оно сейчас и так разделено - столбики отдельно, цифры отдельно. Но - сначала столбики, а потом цифры. И цифры, которые надо показывать медленно, не должны мешать быстрой работе столбиков. Т.е. вывод цифр должен работать значительно медленней, чем "прыгать" столбики. Выполнять параллельно два кода одна ардуина не может. Но зато код можно написать так, чтобы это казалось параллельным выполнением (собственно к чему мы и стремимся).
Так вот. Сейчас есть общий цикл, в котором все крутится по кругу - это loop. В этом цикле две "подпрограммы" - сначала одна собирает данные и выводит столбики (тоже по сути цикл с перебором всех каналов), другая - эти данные анализирует и выводит цифры (и эта - тоже цикл с перебором каналов).
Вот что я предлагаю. Это, конечно, тоже не окончательный вариант :) Но все по-порядку.
Первая "подпрограмма" по сбору данных пускай себе так и остается - за один проход loop'а она так и будет опрашивать все 16 каналов. А вот анализ мы будем делать не всех 16-ти каналов за один проход loop'а, а по одному. Т.е. в один проход loop'а изучаем только один элемент массива.
[code]
if(channel == 16)
{
channel = 0;
}
else
{
byte level = LevelStolbik[channel];
if (level > 0)
{ // если уровень не нулевой, то выводим число с номером этого канала
byte edinicy = channel % 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(2, i, CountDigits[channel][i]);
}
if (channel < 10)
{
LC.clearDisplay(3);
}
else
{
byte desyatki = channel / 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(3, i, CountDigits[desyatki][i]);
}
}
}
else
{ // иначе (если уровень нулевой) - очищаем места под цифры
LC.clearDisplay(2);
LC.clearDisplay(3);
}
}
channel++;
[/code]
Не совсем. Вот в 381 сообщении вы написали правильно, но в скетч всунули как-то странно. Почему if вначале и зачем else в 6 строке? Ведь надо всего-то убрать for, и в конце добавить channel++; if(channel == 16) channel = 0;
И еще вот что. В обеих "подпрограммах" - и сбора и анализа используется переменная channel, но это разные переменные, так как они объявлены внутри разных блоков (разных for'ов). Они несут ту же смысловую нагрузку - это счетчики каналов, но все-же они разные.
Первая channel, объявленная в 57-й строке, существует только до 69-й строки (включительно) - пока работает цикл. Цикл закончился - переменная исчезла. Аналогично вторая channel (из второго for'а - анализа данных) - существует только в строках 75-103.
И так они друг другу не мешали. Но сейчас нам надо один for "раскрыть" и, мало того, еще номер канала для анализа нам надо хранить так, чтобы из перехода из loop'а в loop переменная не теряла этот номер. Один из вариантов - это объявить эту переменную глобально, т.е. за пределами любых функций (loop'а и setup'а в том числе) - где-нибудь в начале скетча.
Но это еще не все. Теперь мы можем еще больше запутаться, ведь у нас по-прежнему две channel - только одна стала глобальной, а вторая осталась локальной. Понять, где какая с первого, да и второго, раза будет непросто. Одну из них надо назвать как-то иначе, чтобы было сразу видно, что это разные переменные.
[code]
//////////// Анализ ////////////
// В этой части анализируем массив с данными (со всеми
// уровнями), собранными в предыдущей части при опросе каналов
if(channelA == 16) channelA = 0;
{
byte level = LevelStolbik[channelA];
if (level > 0)
{ // если уровень не нулевой, то выводим число с номером этого канала
byte edinicy = channelA % 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(2, i, CountDigits[channelA][i]);
}
if (channelA < 10)
{
LC.clearDisplay(3);
}
else
{
byte desyatki = channelA / 10;
for (byte i = 0; i < 8; i++)
{
LC.setRow(3, i, CountDigits[desyatki][i]);
}
}
}
else
{ // иначе (если уровень нулевой) - очищаем места под цифры
LC.clearDisplay(2);
LC.clearDisplay(3);
}
}
channelA++;
//////// Конец анализа /////////
[/code]
Я где-то из вашего кода скопировал и не посмотрел.
Сейчас числа должны отображаться нормально. Но все-равно быстро. Надо после вывода числа добавить задержку. После 98 строки добавьте
delay(1000);
И да, фигурные скобки в строках 78 и 105 лишние.
И этот скетч уже должен работать более менее приемлемо. Столбики будут обновляться не реже одного раза в секунду. Приемлемо, но можно и лучше, но это мы уже будем делать завтра.
результа устраивает , я хочу продолжить просто немного работй окружили , да и я вернулся перечитал всю переписку осмылил , законспектировал , а теперь буду изучать millis, я где это встречал уже , помоему это в часах и таймерах часто используют
Нет, эти обе функции хоть и относятся к работе со временем, но выполняют совершенно разные функции. millis() - это, грубо говоря, постоянно тикающие часы, на которые мы можем посмативать и знать время, а delay() - это клин, вбиваемый в работу программы, и тормозящий ее выполнение на определенное время.
Читайте описание (ссылки я уже приводил в сообщении #153), что делают и зачем нужны разные функции. Пока не разберетесь, дальше делать нечего.
я усвоил , замечание , следуюший шг нам нужно создать цикл который будет смотреть значеие по очередно выводить
Пробуйте.
Я не понял, что вы хотите так добиться?
Сейчас это выглядит так: переменной number в цикле по-очереди присваиваются значения из массива. После окончания цикла на экран выводится число (от 0 до 8), что хранится в последней ячейке массива, т.е. уровень сигнала последнего (15-го) канала.
А должно быть так (пока так, а потом скорректируем): в цикле пересматриваем все ячейки массива и в процессе этого, если в ячейке не ноль, то выводим на экран номер этой ячейки, иначе - пустоту.
В частности, вы снова невнимательны и забываете, о чем я недавно уже говорил. Не брезгуйте фигурными скобками в for'ах, if'ах и т.п. Даже, если в цикле или условии, выполняется всего одна команда - заворачивайте ее в фигурные скобки. Вы (да и компилятор тоже) будете видеть границы блока.
То, что вы сделали отступ в строка 2-4, вовсе не значит, что все они относятся к циклу. Так, как у вас написано, к циклу относится только строка 2. Остальные - выполняются вне и после цикла.
upd. И еще в догонку к предыдущему, сразу не заметил. Запомните: все переменные, объявленные внутри блоков, за пределами этих блоков не видны и при выходе из этих блоков уничтожаются.
В данном случае таким блоком является цикл for - это строки 1 и 2. Поскольку переменную number вы объявили во 2-ой строке, т.е. внутри цикла, то в 3-й строке ее уже использовать нельзя, ее уже не будет существовать и функция showNumber(number) понятия не будет иметь, что за переменная такая этот number. Благо, это обнаружится еще на этапе компиляции и компилятор выдаст ошибку.
То, что я только-что написал перекликается с тем, что я писал ранее - если внутри блока объявить переменную с таким же именем, что и у переменной из "внешнего уровня", то это будет совсем другая переменная, хоть и с таким же именем.
К какой функции вы не знаете как обратиться?
что вывода цифр
а какой функцией мы выводим цифры?
showNumber() в скобках должна быть переменная , переменную с новую создать нужно ?
(byte number) или же эту же?
(byte number) или же эту же?
Смотрите, давайте чуть-чуть вернемся и расставим точки над "i". Возможно вам будет проще понять.
Вы в сообщении #356 привели набросок скетча. Там есть такая строка:
А почему вы назвали свою переменную number? Разве в массиве мы храним номера каналов? За номера каналов в данном случае отвечает переменная i, а в массиве мы храним уровни этих каналов. Не логичнее было бы назвать эту переменную level, а не number? Вот смотрите, что получается:
Что касается "showNumber() в скобках должна быть переменная". Да, чтобы вывести какое-то число на экран, в скобках должно быть указано это число или переменная, содержащая это число. В данном случае надо вывести номер канала. А какая переменная в этом цикле содержит номер канала?
upd. В догонку. Не обязательно в качестве параметра функции должна быть переменная. Вы же не пишете всегда:
а сразу:
Переменная записывается в программе, только если нам заранее не известно, что передавать в функцию, и сначала это нужно вычислить, и то, это вычисление можно делать прямо в скобках при вызове функции:
showNumber( channel); // до меня вот тут не доходит ,
Ну да, до меня тоже :) , почему вы там пишите channel? Ведь мы сейчас находимся внутри цикла
for (byte i = 0; i < 16;i++){.....
И каналы перебираем переменной i.
Забудьте пока о строках 1-10. Может так станет немного понятней. Мы сейчас обсуждаем только перебор и анализ значений массива.
Да, так правильно. Можно двигаться дальше. По-отдельности мы уже практически освоили все главные части программы: умеем выводить столбики с уровнями сигналов на каналах, умеем анализировать уровни и выводить номер канала с активным уровнем.
Но, если собрать в кучу эти части, как есть сейчас, и залить в ардуину, то результат, что будет отображаться на экране, нас не устроит вообще. Потому что считываем данные с каналов мы реже, чем делаем их анализ, но даже и так номера каналов будут выводиться так часто, что не успеем их разглядеть. Можно, конечно, поставить секундную задержку после вывода каждого числа и тогда числа на экране сможем разглядеть. Но это еще больше усугубит ситуацию со считыванием сигнала, т.к. каждый канал будет опрашиваться примерно 1 раз в 16 секунд, а на один цикл опроса всех 16 каналов и вовсе будет уходить более 4 минут! Весело, правда?
Т.е., нам надо сделать так, чтобы, как минимум, каналы опрашивались чаще, чем мы будем их анализировать для вывода номеров. Я сейчас пересоберу скетч для этого. Там мало чего поменяется, только поменяю опрос каналов и анализ данных местами, ну и немного переделаю его так, чтобы вам был больше понятен алгоритм (т.е. не буду оптимизировать, а наоборот, немного растяну и детализирую скетч). И уже после этого будем допиливать этот вариант.
да именно так и получиилось после заливки , да сложновато воспринять скетч , ни как не сложиться общая картина , все еще как то запутано , вроде по кусочкам все понятно , а целом не укладываться
Так оно и есть. Чтобы написать всю программу, сначала надо обкатать ее функциональные части. И, когда будет работать по частям, то склеить все в кучу проще.
я имел в виду о сознании обучения ,
Вот, что пока получилось. С этим кодом будем работать дальше:
Я обещал, что "растяну" код, но от showNumber(), как от отдельной функции, я избавился - разделил ее на две части (вывод числа и очистку матриц для "пусто") и перенес в основной код. Во-первых, как она работает, я надеюсь, уже разобрались. А, во-вторых, в коде она вызывалась только из одного места, поэтому не вижу особого смысла ту часть кода оформлять в функцию. От остального ненужного избавимся потом.
Попробуйте понять, как работает сейчас программа. В ардуину ее заливать не обязательно - визуально там почти ничего не изменилось. Когда поймете или не поймете, дайте знать, продолжим.
да мне все понятно стало , если соблюдать правильную последовательнось то все становиться очень простым и понятным
Хорошо. Подытожу, сейчас программа работает следующим образом: поочередно опрашиваются каналы от 0 до 15. Ихние уровни выводятся на экран и сохраняются в массив. Потом, также по-очереди, анализируются снова все каналы от 0 до 15 и для активных каналов прописываются ихние номера.
Но цифры все так же меняются быстро и разглядеть их не получиться. Надо вводить задержку. Задержку можно ввести в цикл перебора при анализе каналов:
Теперь можно будет увидеть цифры. Но такая задержка снова будет влиять на скорость опроса каналов. Уже хоть и не 1 раз в 4 минуты, а всего 1 раз в 16 секунд, но это тоже долго. Немного снизить время ожидания можно, если зажержку ставить не на весь цикл, а только, для вывода цифр (если на экране пусто, то ждать 1 с незачем - нас интересуют только цифры):
Т.е. вывели число, подождали 1 с, проверяем следующее. Время бездействия сократится, но не существенно - при одном активном канале будет 1 с, а при 16 - все те же 16 с. Тоже не вариант.
Значит, будем делать по-другому. Кстати, а у вас есть предложения, как?
интересно
Свои предложения есть, как ускорить?
вытаскивать значения с буфера только те которые больше нуля и отображать а если буфер в сумме будет 0 то отправить 255
Не забывайте, что только отображать - мало. Это будет работать, если активный канал только один. Но если их будет хотя бы два, то на экране начнется такая же свистопляска - то одно, то другое число будут перемигиваться на экране с огромной скоростью. Если бы человек успевал с такой же скоростью различать числа - проблем бы не было. Но нам нужна пауза между отображениями чисел. А это получается практически последний код с delay в 97 строке.
И да, никаких условных 255 мы уже никуда не отправляем. То было только для обучения и одного из вариантов. Помотрите код. Мы уже в основном коде делаем анализ - если в элементе массива не ноль, то выводим номер канала, иначе - чистим матрицы.
тогда возможен один вариант разделить столбики и отбражение , тоесть столбики работают сами по себе а цыфры беруться с накопленого буфера , а если значение столбиков достигло нуля чистим матрицы
У нас оно сейчас и так разделено - столбики отдельно, цифры отдельно. Но - сначала столбики, а потом цифры. И цифры, которые надо показывать медленно, не должны мешать быстрой работе столбиков. Т.е. вывод цифр должен работать значительно медленней, чем "прыгать" столбики. Выполнять параллельно два кода одна ардуина не может. Но зато код можно написать так, чтобы это казалось параллельным выполнением (собственно к чему мы и стремимся).
Так вот. Сейчас есть общий цикл, в котором все крутится по кругу - это loop. В этом цикле две "подпрограммы" - сначала одна собирает данные и выводит столбики (тоже по сути цикл с перебором всех каналов), другая - эти данные анализирует и выводит цифры (и эта - тоже цикл с перебором каналов).
Вот что я предлагаю. Это, конечно, тоже не окончательный вариант :) Но все по-порядку.
Первая "подпрограмма" по сбору данных пускай себе так и остается - за один проход loop'а она так и будет опрашивать все 16 каналов. А вот анализ мы будем делать не всех 16-ти каналов за один проход loop'а, а по одному. Т.е. в один проход loop'а изучаем только один элемент массива.
Мысли, как реализовать это в коде, есть?
это убрать и поставить это
Неплохо. А вписать это в итоговый скетч из поста #371 сможете?
Правильно?
Не совсем. Вот в 381 сообщении вы написали правильно, но в скетч всунули как-то странно. Почему if вначале и зачем else в 6 строке? Ведь надо всего-то убрать for, и в конце добавить channel++; if(channel == 16) channel = 0;
И еще вот что. В обеих "подпрограммах" - и сбора и анализа используется переменная channel, но это разные переменные, так как они объявлены внутри разных блоков (разных for'ов). Они несут ту же смысловую нагрузку - это счетчики каналов, но все-же они разные.
Первая channel, объявленная в 57-й строке, существует только до 69-й строки (включительно) - пока работает цикл. Цикл закончился - переменная исчезла. Аналогично вторая channel (из второго for'а - анализа данных) - существует только в строках 75-103.
И так они друг другу не мешали. Но сейчас нам надо один for "раскрыть" и, мало того, еще номер канала для анализа нам надо хранить так, чтобы из перехода из loop'а в loop переменная не теряла этот номер. Один из вариантов - это объявить эту переменную глобально, т.е. за пределами любых функций (loop'а и setup'а в том числе) - где-нибудь в начале скетча.
Но это еще не все. Теперь мы можем еще больше запутаться, ведь у нас по-прежнему две channel - только одна стала глобальной, а вторая осталась локальной. Понять, где какая с первого, да и второго, раза будет непросто. Одну из них надо назвать как-то иначе, чтобы было сразу видно, что это разные переменные.
переменную то я обьявил , но циферки десятков поплыли
Давайте весь скетч целиком. И все хочу спросить, откуда у вас при вставке сюда кода берутся теги [code] и [/code]?
Строки 7 и 34 не нужны.
Исправьте строку 85, должно быть так:
Я где-то из вашего кода скопировал и не посмотрел.
Сейчас числа должны отображаться нормально. Но все-равно быстро. Надо после вывода числа добавить задержку. После 98 строки добавьте
И да, фигурные скобки в строках 78 и 105 лишние.
И этот скетч уже должен работать более менее приемлемо. Столбики будут обновляться не реже одного раза в секунду. Приемлемо, но можно и лучше, но это мы уже будем делать завтра.
А сейчас пробуйте. И пока внимательно читайте и изучайте http://arduino.ru/tutorials/BlinkWithoutDelay
Да и Serial.begin(9600); из сетапа можно убрать. Нам он не нужен. В общем, скетч за сегодняшний день должен выглядеть так:
Ну, как там движутся дела с освоением millis? Или на этом все - текущий результат устраивает?
результа устраивает , я хочу продолжить просто немного работй окружили , да и я вернулся перечитал всю переписку осмылил , законспектировал , а теперь буду изучать millis, я где это встречал уже , помоему это в часах и таймерах часто используют
я бы не против сделать часы с тернометром уличным например , заодно и научится
millis, я где это встречал уже , помоему это в часах и таймерах часто используют
millis удобно использовать везде, где необходимо выполнять периодические действия, не тормозя выполнение основного кода.
я бы не против сделать часы с тернометром уличным например , заодно и научится
Ну чего чего, а часов уже наделано великое множество, примеров для изучения достаточно. Я свои матричные тоже недавно выкладывал http://arduino.ru/forum/proekty/eshche-odni-chasy-na-matritsakh (но матрицы немного другие, чем у вас).
а millis() можно использовать на прямую в скобках указывать как у delay()
Нет, эти обе функции хоть и относятся к работе со временем, но выполняют совершенно разные функции. millis() - это, грубо говоря, постоянно тикающие часы, на которые мы можем посмативать и знать время, а delay() - это клин, вбиваемый в работу программы, и тормозящий ее выполнение на определенное время.
Читайте описание (ссылки я уже приводил в сообщении #153), что делают и зачем нужны разные функции. Пока не разберетесь, дальше делать нечего.