Расчет резисторов для нестандартной клавиатуры или других нужд

CheBuraw
Offline
Зарегистрирован: 10.02.2015

   Всем известна «классическая» схема Keypad shield для Arduino. Все номиналы резисторов известны и так хитро распределены что при нажатии на кнопки значения АЦП распределены равномерно. Можно конечно использовать все резисторы с одним номиналом, но тогда Значения АЦП будут, скажем так не очень удобными. Проблемы данного метода подключения и работы с кнопками тут описывать не будем. Тут разговор о другом.
   Предположим, что нам потребовалась клавиатура не с 5-ю кнопками, а допустим с 6-ю или мне 9 кнопок потребовалось, всякое же может приключиться. Со мной такое было. Я по природе лентяй и мне всегда охота найти быстрый и простой способ решения моей задачи. К сожалению я его не нашел (допускаю что плохо искал). Самый простой и ускоряющий время способ, который я нашёл это ввод формул в Excel и ручной подбор резисторов. Дело скучное и меня сильно угнетающее. А тут мне потребовалось сделать простейший датчик уровня с аналоговым выходом. Я решил его делать на основе резисторного делителя.

Окончим с прелюдией. В общем написал я программу для подбора номиналов резисторов исходя из нужного их количества. С программированием я не очень, и единственное что мало-мальски знаю это IDE Arduino. Понимаю что прогу по расчету целесообразнее было бы делать на какой-нибудь JS и нафигачить на сайте каком-нибудь, но для этого надо еще сайт найти …

Как работает программа в двух словах, подробнее можно почитать в комментариях к коду.

В качестве исходных данных нужных для дальнейшего расчета мы в скетче указываем величину R1 в Ом`ах!  Количество сопротивлений, их должно быть (согласно приведенной схеме) на один меньше нужного количества кнопок. И битность используемого АЦП. Например, PCF8591 - 8 Bit - 256 значений, Arduino - 10 bit - 1024 значений, MCP3201 - 12 bit - 4096 значений. Загружаете в Arduino и открываете Serial – Всё!

Вычисляем количество значений согласно битности АЦП. Определяем среднее значение АЦП, для того чтобы между значениями был примерно один диапазон. Перебором номиналов находим сопротивление, подходящее под среднее значение АЦП. Подбираем ближнее значение резистора из номинального ряда E24. Считаем значение АЦП исходя из найденного значения сопротивления из ряда E24. Отображаем результат расчетов. Повторяем столько раз сколько нужно резисторов.

Не претендую на звание идеального кода и грамотные люди наверняка сделали бы все куда проще и эстетичнее.
оптимизация и конструктивная критика приветствуется.

#define R1 2000     // Укажите сопротивление R1 в Ом
#define KolvoR2 11  // Укажите количество R2 (на одно меньше количества кнопок)
#define ACPbyte 10  // Укажите сколько бит Ваш АЦП
// Например:
// PCF8591 - 8 Bit - 256 значений
// Arduino - 10 bit - 1024 значений
// MCP3201 - 12 bit - 4096 значений
// =================================

// Далее код для подбора резисторов R2.
int count = 0;      // переменная для счетчика в цикле номиналов
int countR2 = 1;    // 
// Номинальный ряд E192 используем для подбора сопротивления согласно нужного значения АЦП
// Данный номинальный ряд был выбран как самый большой
int NomResE192[] = {100,101,102,104,105,106,107,109,110,111,113,114,115,117,118,120,121,123,124,126,127,129,130,132,133,135,137,138,140,142,143,145,147,149,150,152,154,156,158,160,162,164,165,167,169,172,174,176,178,180,182,184,187,189,191,193,196,198,200,203,205,208,210,213,215,218,221,223,226,229,232,234,237,240,243,246,249,252,255,258,261,264,267,271,274,277,280,284,287,291,294,298,301,305,309,312,316,320,324,328,332,336,340,344,348,352,357,361,365,370,374,379,383,388,392,397,402,407,412,417,422,427,432,437,442,448,453,459,464,470,475,481,487,493,499,505,511,517,523,530,536,542,549,556,562,569,576,583,590,597,604,612,619,626,634,642,649,657,665,673,681,690,698,706,715,723,732,741,750,759,768,777,787,796,806,816,825,835,845,856,866,876,887,898,909,919,931,942,953,965,976,988,};
// Номинальный ряд E24 по значениям которого будет происходить подбор нужного резистора.
// Чтобы не делать массив Float типа, умножил значение на 10, тем самым ушел от дробной части.
// Использовал этот номинальный ряд так как считаю его наиболее распространенным и доступным
int NomResE24[] = {10,11,12,13,15,16,18,20,22,24,27,30,33,36,39,43,47,51,56,62,68,75,82,91};
boolean out1 = 0;  // флаг для выхода из цикла номиналов
boolean out2 = 0;  // флаг для выхода из цикла множителей
unsigned long mnozhitel = 1;  // Чтобы не указывать в массиве номинального ряда все значения от Ом до МОм, будем умножать каждый проход номинального ряда на 10
unsigned long R2, R2old, R2raznica, E24Summ;  // Объявляем переменные для расчета R2
int PopTemp, ACPznach, PopSrZnach, PopSumZnach, R2K, R2Kold;  // Переменные для расчета


void setup()
// Так как нам достаточно единичного запуска, то разместим весь код в setup()
{
 Serial.begin(9600);  // Инициализируем UART

 ACPznach = pow(2, ACPbyte);  // расчитываем количество значений АЦП с учётом его битности
 PopSrZnach =  ACPznach / (KolvoR2 + 1);  // Считаем среднее значение АЦП с учетом количества кнопок (кнопок на одну больше чем резисторов R2)
 PopSumZnach = PopSrZnach;  // Переменная для хранения искомого в данный момент значения АЦП
// Отображаем наши исходные данные
   Serial.println("ISHODNIE DANNIE:");   
   Serial.print("ACP " );                       
   Serial.print(ACPbyte);
   Serial.print(" byte, " );                       
   Serial.print(ACPznach);
   Serial.println(" znacheniy" ); 
   Serial.print("R1: " );                       
   Serial.print(R1);
   Serial.println(" Om" ); 
   Serial.print("Kolichestvo R2: " );                       
   Serial.print(KolvoR2);
   Serial.println(" sht" ); 
   Serial.print("Srednee znachenie ACP: " );                       
   Serial.println(PopSrZnach);   
   Serial.println("==================================" );   

 for (int i=1; i <= KolvoR2; i++){  // Цикл подбора резисторов. Остановиться когда вычислит указанное количество R2
do  // Цикл Множителей
{
    do  // Цикл номиналов
      {
      R2 = NomResE192[count] * mnozhitel;  // берем значение R2 из ряда номиналов и умножаем на число множителя
      PopTemp = (ACPznach * R2) / (R2 + R1);  // Вычисляем значение АЦП для выбранного номинала резистора
     
      if (PopTemp >= PopSumZnach || count > 192) out1 = 1; // Условия для выхода из цикла подбора номинала:
  // если текущее значение АЦП больше или равно искомому или цикл прошел 192 раза (количество наоминалов в ряду) и не нашёл нужного
      count++; // отмечаем пройденный круг цикла
    } while (out1 == 0); // Выходим из цикла номиналов
 
  count = 0; // обнуляем счетчик количества пройденных циклов в цикле номиналов
  out1 = 0; // обнуляем флаг для выхода из цикла номиналов, чтобы в него вновь можно было зайти
  mnozhitel *= 10; // увеличиваем множитель для номинала на 10, чтобы перейти к большим значениям R2
  if (PopTemp >= PopSumZnach || mnozhitel > 100000) out2 = 1;  // Условия для выхода из цикла подбора множителей:
// если текущее значение АЦП больше или равно искомому или значения R2 пошли на МегаОмы (10 * множитель 100 000 = 1 000 000)
} while (out2 == 0); // Выходим из цикла множителей
    // так как нам нужно знать не суммарное сопротивление всех R2.n, а только текущего, 
    // то из найденного общего сопротивления вычитаем предыдущее значение

 /* R2 это суммарное сопротивление всех резисторов в цепочке, а нам надо найти номинал именно последнего
     /------------R2---------------\
       ___     ___     ___      ___
    --|___|---|___|---|___|----|___|--
     \--------R2old--------/ \разница/
 Для этого из полученного значения сопротивления всей цепи вычитаем предыдущее значени...
 */
    R2raznica = R2 - R2old; // ...и получаем нужный нам номинал
        
    // для вичисления конкретно текущего 
   Serial.print("R2." );                       
   Serial.print(i);
   Serial.print(" = " ); 
if (R2raznica >= 10000){  // Если значение больше 10 000 
   Serial.print(R2raznica/1000); // то делим на 1000 Для отображения целого значения
   Serial.print(" KOm" ); // обозначаем что это КОм`ы
} else  if (R2raznica >= 1000){ // Если значение больше 1000, 
 R2Kold = R2raznica/100;  // то для отображения значений после запятой
   Serial.print((float)R2Kold / 10.0);  // переменную надо преобразовать во FLOAT
   Serial.print(" KOm" );  // обозначаем что это КОм`ы
}   else {  
   Serial.print(R2raznica);
   Serial.print(" Om" ); 
} 
    Nom24();   // функция поиска ближайшего номинала в ряду E24
   
PopSumZnach += PopSrZnach;  // Увеличиваем значение АЦП на величину среднего значения АЦП
mnozhitel = 1;  // Сбрасываем занчение множителя для запуска нового цикла подбора R2
out2 = 0;  // Сбрасываем флаг выхода из цикла множителей, для возможности вновь в него войти
R2old = R2; // отныне текущее значени считается старым :)
 }
   Serial.println("==================================" );   
   Serial.println("DONE!" ); // по нахождению всех нужных номиналов сигнализируем о завершении
}

void Nom24() // получив значение R2 из номинального ряда E192 надо подобрать ближайшее значение в номинальном ряду E24
// функция, по сути, точно такая же как и основная, только перебор осуществляется в номинальном ряду E24
{
unsigned long R24, R24old, E24Blozh; // переменные для расчета
unsigned long mnozh = 1; // тобы не указывать в массиве номинального ряда все значения от Ом до МОм, будем умножать каждый проход номинального ряда на 10
int cnt = 0; // переменная для счетчика в цикле номиналов
int E24temp; // 
boolean outCikl1 = 0; // флаг для выхода из цикла номиналов
boolean outCikl2 = 0; // флаг для выхода из цикла множителей

   do // Цикл подбора множителей
    {
      do // Цикл подбора резисторов
      {
 // выход из цикла происходит если расчитанное значение АЦП, из подобранного номанала резистора, 
 // больше нужного значения АЦП. Но не всегда получается что следующий номинал резистора 
 // наиболее близок к нужному нам значению. Поэтому мы сразу получаем следующее и предыдущее 
 // значение R2 из номинального ряда, для дальнейшего находжения наиболее близкого.
 
 // Если это первый проход цикла, то 
        if (cnt == 0) {R24old = NomResE24[cnt] * mnozh;} // старым занчением будем считать первое значение
        else {R24old = NomResE24[cnt-1] * mnozh;} // если не первый круг, то берём предыдущий номинал
        R24 = NomResE24[cnt] * mnozh; // и подбираем как бы следующий номинал
      if (R24 >= R2raznica || cnt > 24) outCikl1 = 1; // Условия для выхода из цикла подбора номинала:
  // если текущее значение АЦП больше или равно искомому или цикл прошел 24 раза (количество наоминалов в ряду) и не нашёл нужного
      cnt++; // отмечаем пройденный круг цикла
    } while (outCikl1 == 0); // Выходим из цикла номиналов
  cnt = 0; // обнуляем счетчик количества пройденных циклов в цикле номиналов
  outCikl1 = 0; // обнуляем флаг для выхода из цикла номиналов, чтобы в него вновь можно было зайти
  mnozh *= 10; // увеличиваем множитель для номинала на 10, чтобы перейти к большим значениям R2
  if (R24 >= R2raznica || mnozh > 100000) outCikl2 = 1;  // Условия для выхода из цикла подбора множителей:
// если текущее значение АЦП больше или равно искомому или значения R2 пошли на МегаОмы (10 * множитель 100 000 = 1 000 000)
} while (outCikl2 == 0); // Выходим из цикла множителей
   Serial.print(" | E24 = " );
// вичисляем ближайшее значение для этого из номинала текущего сопротивления из ряда E192 вычитаем предыдущее значение сопротивления из ряда E24 
// и сравниваем его с разницей сопротивлений следующего E24 и текущего E192.
// в зависомости от того какая разница значений меньше, мы и делаем вывод какой номинал E24 ближе к найденому E192
  if ((R2raznica - R24old) >= (R24 - R2raznica)) E24Blozh = R24;
  else E24Blozh = R24old;
// отображаем найденный ближний номинал из ряда E24 по аналогии с отображением номинала из ряда E192
if (E24Blozh >= 10000){  
   Serial.print(E24Blozh/1000);
   Serial.print(" KOm" ); 
} else  if (E24Blozh >= 1000){ 
 E24temp = E24Blozh/100;   
   Serial.print((float)E24temp / 10.0);  
   Serial.print(" KOm" ); 
}   else {      
   Serial.print(E24Blozh);
   Serial.print(" Om" ); 
} 
// А вот для расчета значения АЦП на данном резисторе нам нужно знать суммарное сопротивление резисторов из найденных ранее номиналов E24
  E24Summ += E24Blozh; // суммируем номиналы подходящих нам резисторов из ряда E24
   Serial.print(" | ACP = " ); 
   Serial.println((ACPznach * E24Summ) / (E24Summ + R1)); // расчитываем значение АЦП на основе суммы номиналов R24
}

void loop() // в этот раз нам не пригодился, но без него код не компилиться
{
}

Если лень грузить в Arduino, то ниже уже рассчитанные таблички в зависимости от количества нужных резисторов. От 5 резисторов (6 кнопок) до 19 (20 кнопок). 

Наблюдательные смогут заметить, что результат расчета номинала у последних резисторов в скетче выше может отличаться о приведенного в данных табличках. Сейчас уже не знаю почему там появляется это расхождение и искать лень. все равно итог один Сопротивление рассчитано и на его основе посчитано значение АЦП.

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 5 шт
Средние значения АЦП:
8bit = 51 | 10bit = 204 | 12bit = 819
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 402 Ом   | 390 Ом  |  41   |  167  |  668  |
 2  || 598 Ом   | 620 Ом  |  85   |  343  |  1374 |
 3  || 1.00 KОм | 1.00 KОм|  128  |  513  |  2053 |
 4  || 1.90 KОм | 2.00 KОм|  170  |  683  |  2732 |
 5  || 5.90 KОм | 6.20 KОм|  214  |  856  |  3425 |
===================================================
* Значения АЦП исходя номинального ряда E24 

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 6 шт
Средние значения АЦП:
8bit = 42 | 10bit = 170 | 12bit = 682
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 336 Ом   | 330 Ом  |  36   |  145  |  580  |
 2  || 470 Ом   | 470 Ом  |  73   |  292  |  1170 |
 3  || 694 Ом   | 680 Ом  |  108  |  435  |  1741 |
 4  || 1.10 KОм | 1.20 KОм|  146  |  586  |  2345 |
 5  || 2.30 KОм | 2.40 KОм|  183  |  734  |  2938 |
 6  || 7.00 KОм | 6.80 KОм|  219  |  876  |  3505 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 7 шт
Средние значения АЦП:
8bit = 36 | 10bit = 146 | 12bit = 585
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 287 Ом   | 300 Ом  |  33   |  133  |  534  |
 2  || 386 Ом   | 390 Ом  |  65   |  262  |  1050 |
 3  || 527 Ом   | 510 Ом  |  96   |  384  |  1536 |
 4  || 800 Ом   | 820 Ом  |  128  |  514  |  2058 |
 5  || 1.30 KОм | 1.30 KОм|  159  |  639  |  2556 |
 6  || 2.60 KОм | 2.70 KОм|  192  |  768  |  3074 |
 7  || 7.90 KОм | 8.20 KОм|  224  |  897  |  3590 |
===================================================
* Значения АЦП исходя номинального ряда E24
 
ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 8 шт
Средние значения АЦП:
8bit = 32 | 10bit = 128 | 12bit = 512
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 249 Ом   | 240 Ом  |  27   |  109  |  438  |
 2  || 320 Ом   | 330 Ом  |  56   |  227  |  908  |
 3  || 431 Ом   | 430 Ом  |  85   |  341  |  1365 |
 4  || 600 Ом   | 620 Ом  |  114  |  458  |  1833 |
 5  || 890 Ом   | 910 Ом  |  142  |  571  |  2287 |
 6  || 1.40 KОм | 1.50 KОм|  171  |  684  |  2737 |
 7  || 2.80 KОм | 3.00 KОм|  199  |  797  |  3188 |
 8  || 8.30 KОм | 8.20 KОм|  226  |  905  |  3620 |
===================================================
* Значения АЦП исходя номинального ряда E24
 
ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 9 шт
Средние значения АЦП:
8bit = 28 | 10bit = 113 | 12bit = 455
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 223 Ом   | 220 Ом  |  25   |  101  |  405  |
 2  || 276 Ом   | 270 Ом  |  50   |  201  |  806  |
 3  || 357 Ом   | 360 Ом  |  76   |  305  |  1221 |
 4  || 474 Ом   | 470 Ом  |  101  |  407  |  1628 |
 5  || 670 Ом   | 680 Ом  |  128  |  512  |  2048 |
 6  || 980 Ом   | 1.00 KОм|  153  |  614  |  2457 |
 7  || 1.60 KОм | 1.60 KОм|  178  |  713  |  2854 |
 8  || 3.20 KОм | 3.30 KОм|  204  |  817  |  3268 |
 9  || 9.50 KОм | 9.10 KОм|  229  |  916  |  3664 |
===================================================
* Значения АЦП исходя номинального ряда E24
 
ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 10 шт
Средние значения АЦП:
8bit = 25 | 10bit = 102 | 12bit = 409
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 200 Ом   | 200 Ом  |  23   |  93   |  372  |
 2  || 248 Ом   | 240 Ом  |  46   |  184  |  738  |
 3  || 302 Ом   | 300 Ом  |  69   |  276  |  1106 |
 4  || 400 Ом   | 390 Ом  |  92   |  369  |  1478 |
 5  || 520 Ом   | 510 Ом  |  115  |  461  |  1845 |
 6  || 730 Ом   | 750 Ом  |  139  |  557  |  2229 |
 7  || 1.10 KОм | 1.10 KОм|  162  |  650  |  2603 |
 8  || 1.80 KОм | 1.80 KОм|  185  |  743  |  2972 |
 9  || 3.60 KОм | 3.60 KОм|  208  |  835  |  3343 |
 10 || 10 KОм   | 11 KОм  |  232  |  930  |  3721 |
===================================================
* Значения АЦП исходя номинального ряда E24
 
ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 11 шт
Средние значения АЦП:
8bit = 23 | 10bit = 93 | 12bit = 372
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 182 Ом   | 180 Ом  |  21   |  84   |  338  |
 2  || 220 Ом   | 220 Ом  |  42   |  170  |  682  |
 3  || 263 Ом   | 270 Ом  |  64   |  256  |  1027 |
 4  || 335 Ом   | 330 Ом  |  85   |  341  |  1365 |
 5  || 420 Ом   | 430 Ом  |  106  |  426  |  1707 |
 6  || 580 Ом   | 560 Ом  |  127  |  510  |  2042 |
 7  || 800 Ом   | 820 Ом  |  149  |  598  |  2392 |
 8  || 1.10 KОм | 1.20 KОм|  170  |  683  |  2732 |
 9  || 2.00 KОм | 2.00 KОм|  192  |  768  |  3073 |
 10 || 3.90 KОм | 3.90 KОм|  213  |  852  |  3408 |
 11 || 11 KОм   | 11 KОм  |  233  |  934  |  3738 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 12 шт
Средние значения АЦП:
8bit = 21 | 10bit = 85 | 12bit = 341
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 165 Ом   | 160 Ом  |  18   |  75   |  303  |
 2  || 196 Ом   | 200 Ом  |  39   |  156  |  624  |
 3  || 236 Ом   | 240 Ом  |  59   |  236  |  945  |
 4  || 290 Ом   | 300 Ом  |  79   |  317  |  1271 |
 5  || 353 Ом   | 360 Ом  |  98   |  395  |  1583 |
 6  || 450 Ом   | 470 Ом  |  118  |  474  |  1899 |
 7  || 600 Ом   | 620 Ом  |  138  |  553  |  2212 |
 8  || 830 Ом   | 820 Ом  |  156  |  627  |  2511 |
 9  || 1.20 KОм | 1.30 KОм|  176  |  707  |  2829 |
 10 || 2.00 KОм | 2.00 KОм|  195  |  782  |  3128 |
 11 || 3.90 KОм | 3.90 KОм|  214  |  858  |  3433 |
 12 || 10 KОм   | 11 KОм  |  234  |  936  |  3745 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 13 шт
Средние значения АЦП:
8bit = 19 | 10bit = 78 | 12bit = 315
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 154 Ом   | 150 Ом  |  17   |  71   |  285  |
 2  || 182 Ом   | 180 Ом  |  36   |  145  |  580  |
 3  || 213 Ом   | 220 Ом  |  55   |  220  |  883  |
 4  || 257 Ом   | 270 Ом  |  74   |  297  |  1191 |
 5  || 304 Ом   | 300 Ом  |  91   |  367  |  1470 |
 6  || 390 Ом   | 390 Ом  |  110  |  440  |  1762 |
 7  || 500 Ом   | 510 Ом  |  128  |  514  |  2058 |
 8  || 670 Ом   | 680 Ом  |  147  |  588  |  2353 |
 9  || 940 Ом   | 910 Ом  |  164  |  658  |  2635 |
 10 || 1.30 KОм | 1.30 KОм|  181  |  727  |  2910 |
 11 || 2.30 KОм | 2.40 KОм|  201  |  804  |  3216 |
 12 || 4.60 KОм | 4.70 KОм|  219  |  877  |  3511 |
 13 || 13 KОм   | 13 KОм  |  237  |  948  |  3792 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 14 шт
Средние значения АЦП:
8bit = 18 | 10bit = 73 | 12bit = 292
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 143 Ом   | 150 Ом  |  17   |  71   |  285  |
 2  || 166 Ом   | 160 Ом  |  34   |  137  |  549  |
 3  || 190 Ом   | 200 Ом  |  52   |  208  |  832  |
 4  || 233 Ом   | 240 Ом  |  69   |  279  |  1117 |
 5  || 268 Ом   | 270 Ом  |  86   |  345  |  1383 |
 6  || 330 Ом   | 330 Ом  |  103  |  412  |  1650 |
 7  || 410 Ом   | 430 Ом  |  120  |  482  |  1928 |
 8  || 550 Ом   | 560 Ом  |  138  |  552  |  2208 |
 9  || 690 Ом   | 680 Ом  |  154  |  616  |  2464 |
 10 || 990 Ом   | 1.00 KОм|  170  |  683  |  2735 |
 11 || 1.50 KОм | 1.50 KОм|  187  |  751  |  3006 |
 12 || 2.30 KОм | 2.40 KОм|  204  |  817  |  3270 |
 13 || 4.80 KОм | 4.70 KОм|  220  |  883  |  3535 |
 14 || 14 KОм   | 15 KОм  |  238  |  954  |  3819 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 15 шт
Средние значения АЦП:
8bit = 17 | 10bit = 68 | 12bit = 273
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 135 Ом   | 130 Ом  |  15   |  62   |  249  |
 2  || 152 Ом   | 150 Ом  |  31   |  125  |  503  |
 3  || 177 Ом   | 180 Ом  |  47   |  191  |  765  |
 4  || 209 Ом   | 200 Ом  |  63   |  254  |  1016 |
 5  || 246 Ом   | 240 Ом  |  79   |  317  |  1271 |
 6  || 281 Ом   | 270 Ом  |  94   |  377  |  1511 |
 7  || 360 Ом   | 360 Ом  |  110  |  443  |  1775 |
 8  || 440 Ом   | 430 Ом  |  126  |  506  |  2027 |
 9  || 580 Ом   | 560 Ом  |  142  |  570  |  2283 |
 10 || 780 Ом   | 750 Ом  |  158  |  635  |  2541 |
 11 || 1.00 KОм | 1.10 KОм|  175  |  702  |  2809 |
 12 || 1.60 KОм | 1.60 KОм|  191  |  767  |  3068 |
 13 || 2.70 KОм | 2.70 KОм|  208  |  832  |  3328 |
 14 || 5.20 KОм | 5.10 KОм|  223  |  894  |  3576 |
 15 || 16 KОм   | 16 KОм  |  239  |  959  |  3838 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 16 шт
Средние значения АЦП:
8bit = 16 | 10bit = 64 | 12bit = 256
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 126 Ом   | 130 Ом  |  15   |  62   |  249  |
 2  || 141 Ом   | 150 Ом  |  31   |  125  |  503  |
 3  || 160 Ом   | 160 Ом  |  46   |  184  |  738  |
 4  || 192 Ом   | 200 Ом  |  62   |  248  |  992  |
 5  || 216 Ом   | 220 Ом  |  76   |  307  |  1231 |
 6  || 255 Ом   | 270 Ом  |  92   |  369  |  1478 |
 7  || 310 Ом   | 300 Ом  |  106  |  426  |  1707 |
 8  || 380 Ом   | 390 Ом  |  121  |  487  |  1951 |
 9  || 480 Ом   | 470 Ом  |  136  |  546  |  2186 |
 10 || 580 Ом   | 560 Ом  |  150  |  601  |  2406 |
 11 || 810 Ом   | 820 Ом  |  165  |  662  |  2651 |
 12 || 1.10 KОм | 1.10 KОм|  180  |  721  |  2885 |
 13 || 1.60 KОм | 1.60 KОм|  194  |  779  |  3117 |
 14 || 2.70 KОм | 2.70 KОм|  209  |  838  |  3355 |
 15 || 5.50 KОм | 5.60 KОм|  225  |  901  |  3604 |
 16 || 15 KОм   | 15 KОм  |  239  |  959  |  3837 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 17 шт
Средние значения АЦП:
8bit = 15 | 10bit = 60 | 12bit = 240
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 117 Ом   | 120 Ом  |  14   |  57   |  231  |
 2  || 129 Ом   | 130 Ом  |  28   |  113  |  455  |
 3  || 151 Ом   | 150 Ом  |  42   |  170  |  682  |
 4  || 165 Ом   | 160 Ом  |  56   |  224  |  896  |
 5  || 197 Ом   | 200 Ом  |  70   |  281  |  1127 |
 6  || 229 Ом   | 220 Ом  |  84   |  336  |  1347 |
 7  || 272 Ом   | 270 Ом  |  98   |  393  |  1575 |
 8  || 300 Ом   | 300 Ом  |  111  |  447  |  1788 |
 9  || 400 Ом   | 390 Ом  |  126  |  504  |  2016 |
 10 || 470 Ом   | 470 Ом  |  139  |  559  |  2238 |
 11 || 620 Ом   | 620 Ом  |  154  |  616  |  2467 |
 12 || 780 Ом   | 750 Ом  |  167  |  669  |  2678 |
 13 || 1.10 KОм | 1.10 KОм|  181  |  726  |  2905 |
 14 || 1.60 KОм | 1.60 KОм|  195  |  782  |  3129 |
 15 || 2.60 KОм | 2.70 KОм|  210  |  840  |  3363 |
 16 || 4.80 KОм | 4.70 KОм|  223  |  895  |  3580 |
 17 || 12 KОм   | 13 KОм  |  238  |  953  |  3812 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 18 шт
Средние значения АЦП:
8bit = 14 | 10bit = 56 | 12bit = 227
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 110 Ом   | 110 Ом  |  13   |  53   |  213  |
 2  || 122 Ом   | 120 Ом  |  26   |  105  |  422  |
 3  || 138 Ом   | 130 Ом  |  39   |  156  |  624  |
 4  || 153 Ом   | 150 Ом  |  52   |  208  |  832  |
 5  || 183 Ом   | 180 Ом  |  65   |  262  |  1050 |
 6  || 203 Ом   | 200 Ом  |  78   |  315  |  1261 |
 7  || 231 Ом   | 240 Ом  |  92   |  369  |  1478 |
 8  || 280 Ом   | 270 Ом  |  105  |  421  |  1686 |
 9  || 340 Ом   | 330 Ом  |  118  |  474  |  1899 |
 10 || 390 Ом   | 390 Ом  |  131  |  526  |  2107 |
 11 || 520 Ом   | 510 Ом  |  145  |  581  |  2326 |
 12 || 610 Ом   | 620 Ом  |  158  |  633  |  2535 |
 13 || 840 Ом   | 820 Ом  |  171  |  686  |  2746 |
 14 || 1.10 KОм | 1.20 KОм|  185  |  742  |  2969 |
 15 || 1.60 KОм | 1.60 KОм|  198  |  793  |  3172 |
 16 || 2.60 KОм | 2.70 KОм|  211  |  846  |  3387 |
 17 || 5.00 KОм | 5.10 KОм|  225  |  901  |  3604 |
 18 || 12 KОм   | 13 KОм  |  238  |  954  |  3819 |
===================================================
* Значения АЦП исходя номинального ряда E24

ИСХОДНЫЕ ДАННЫЕ:
R1: 2 КОм
Количество R2: 19 шт
Средние значения АЦП:
8bit = 13 | 10bit = 53 | 12bit = 215
===================================================
    ||  Номинальный ряд   |     Значение АЦП*     |
R2.#||--------------------|-----------------------|
    ||   E192   |   E24   |  8bit | 10bit | 12bit |
====||==========|=========|=======|=======|=======|
 1  || 105 Ом   | 110 Ом  |  13   |  53   |  213  |
 2  || 118 Ом   | 120 Ом  |  26   |  105  |  422  |
 3  || 129 Ом   | 130 Ом  |  39   |  156  |  624  |
 4  || 147 Ом   | 150 Ом  |  52   |  208  |  832  |
 5  || 166 Ом   | 160 Ом  |  64   |  256  |  1027 |
 6  || 191 Ом   | 200 Ом  |  77   |  310  |  1241 |
 7  || 234 Ом   | 240 Ом  |  91   |  365  |  1461 |
 8  || 240 Ом   | 240 Ом  |  103  |  412  |  1650 |
 9  || 310 Ом   | 300 Ом  |  115  |  462  |  1851 |
 10 || 360 Ом   | 360 Ом  |  128  |  513  |  2053 |
 11 || 430 Ом   | 430 Ом  |  140  |  562  |  2250 |
 12 || 550 Ом   | 560 Ом  |  153  |  614  |  2457 |
 13 || 720 Ом   | 750 Ом  |  166  |  667  |  2671 |
 14 || 940 Ом   | 910 Ом  |  179  |  716  |  2865 |
 15 || 1.30 KОм | 1.30 KОм|  191  |  766  |  3066 |
 16 || 1.90 KОм | 2.00 KОм|  204  |  818  |  3273 |
 17 || 3.20 KОм | 3.30 KОм|  217  |  869  |  3478 |
 18 || 6.30 KОм | 6.20 KОм|  229  |  918  |  3675 |
 19 || 18 KОм   | 18 KОм  |  242  |  969  |  3877 |
===================================================
* Значения АЦП исходя номинального ряда E24

А еще на базе схемы Keypad и кучи транзисторов можно сделать примитивный датчик уровня воды с аналоговым выходом. Я использовал SMD-транзисторы взятые с убитой материнской платы. Не знаю их номиналов и маркировки, но дс данной задачей справляются на ура.

CheBuraw
Offline
Зарегистрирован: 10.02.2015
Судя по отсутсвию коментариев в данном топике, тема резистивной клавиатуры не так актуальна. Так как если бы кто-то использовал код, то обнаружил, что он не рабочий! Не подумайте, это не заговор. Самому недавно потребовалось рассчитать резисторы для клавиатуры на 3 кнопки, запустил свой код... а он не работает как надо.
В итоге код был поправлен и немного допилен. точно работающий вариант предыдущего кода выглядит так:
/*
Скетч для рассчета сопротивлений к резистивной кнопочной клавиатуре.
     Версия: 2
Дата версии: 2019.04.05
*/

// Настройки для рассчета
#define R1 2000     // Укажите сопротивление R1 в Ом
// опыты показали что R1 лучше располагать в диапазоне 2КОм ... 100КОм
#define KolvoButton 100  // Укажите необходимое количество кнопок.
// меньше 2-х нет смысла, а больше 100 уже будет сложно отловить АЦП Arduino
// ...оно, конечно, и 100 кнопок на аналоговом входе то ещё извращенство
// =========================================================================


// Больше настроек не потребуется, дальше то что менять не нужно.
// Так как данный скетч все таки призван для получения цепочки сопротивлений к кнопкам 
// для более-менее равномерного распределения значений АЦП при нажатии на кнопки
// то битность АЦП менять не требуется, а в итоговой табличке будут примерные значения
// АЦП для Arduino. Все равно они примерные, а итоговые для ваших АЦП и итоговой цепочки кнопок
// надежнее будет считать по месту через обычный AnalogRead с выводом в Serial


#define ACPbyte 10  // Укажите сколько бит Ваш АЦП
int count = 0;      // переменная для счетчика в цикле номиналов
int countR2 = 1;    // 
// Номинальный ряд E192 используем для подбора сопротивления согласно нужного значения АЦП
// Данный номинальный ряд был выбран как самый большой
// Чтобы не делать массив Float типа, умножил значение на 100, тем самым ушел от дробной части
// но для получения значений менее 100 пришлось добавить ещё значений к ряду
int NomResE192[] = {1,10,11,12,13,15,16,18,20,22,24,27,30,33,36,39,43,47,51,56,62,68,75,82,91,100,101,102,104,105,106,107,109,110,111,113,114,115,117,118,120,121,123,124,126,127,129,130,132,133,135,137,138,140,142,143,145,147,149,150,152,154,156,158,160,162,164,165,167,169,172,174,176,178,180,182,184,187,189,191,193,196,198,200,203,205,208,210,213,215,218,221,223,226,229,232,234,237,240,243,246,249,252,255,258,261,264,267,271,274,277,280,284,287,291,294,298,301,305,309,312,316,320,324,328,332,336,340,344,348,352,357,361,365,370,374,379,383,388,392,397,402,407,412,417,422,427,432,437,442,448,453,459,464,470,475,481,487,493,499,505,511,517,523,530,536,542,549,556,562,569,576,583,590,597,604,612,619,626,634,642,649,657,665,673,681,690,698,706,715,723,732,741,750,759,768,777,787,796,806,816,825,835,845,856,866,876,887,898,909,919,931,942,953,965,976,988};
// Номинальный ряд E24 по значениям которого будет происходить подбор нужного резистора.
// Чтобы не делать массив Float типа, умножил значение на 10, тем самым ушел от дробной части.
// Использовал этот номинальный ряд так как считаю его наиболее распространенным и доступным
int NomResE24[] = {10,11,12,13,15,16,18,20,22,24,27,30,33,36,39,43,47,51,56,62,68,75,82,91};
boolean out1 = 0;  // флаг для выхода из цикла номиналов
boolean out2 = 0;  // флаг для выхода из цикла множителей
unsigned long mnozhitel = 1;  // Чтобы не указывать в массиве номинального ряда все значения от Ом до МОм, будем умножать каждый проход номинального ряда на 10
unsigned long R2, R2old, R2raznica, E24Summ, PopTemp, ACPznach, PopSumZnach, R2K, R2Kold;  // Объявляем переменные для расчета R2
int PopSrZnach;  // Переменные для расчета


void setup()
// Так как нам достаточно единичного запуска, то разместим весь код в setup()
{
 Serial.begin(9600);  // Инициализируем UART

 ACPznach = pow(2, ACPbyte);  // расчитываем количество значений АЦП с учётом его битности
 PopSrZnach =  ACPznach / (KolvoButton);  // Считаем среднее значение АЦП с учетом количества кнопок (кнопок на одну больше чем резисторов R2)
 PopSumZnach = PopSrZnach;  // Переменная для хранения искомого в данный момент значения АЦП
// Отображаем наши исходные данные
   Serial.println("ISHODNIE DANNIE:");   
   Serial.print("R1: " );                       
   Serial.print(R1);
   Serial.println(" Om" ); 
   Serial.print("Kolichestvo knopok: " );                       
   Serial.print(KolvoButton);
   Serial.println(" sht" ); 
   Serial.print("ACP " );
   Serial.print(ACPbyte);
   Serial.print(" byte, " );
   Serial.print(ACPznach);
   Serial.println(" znacheniy" ); 
   Serial.print("Srednee znachenie ACP: " );                       
   Serial.println(PopSrZnach);   
   Serial.println("==================================" );   

 for (int i=1; i <= KolvoButton-1; i++){  // Цикл подбора резисторов. Остановиться когда вычислит указанное количество R2
do  // Цикл Множителей
{
    do  // Цикл номиналов
      {
      R2 = NomResE192[count] * mnozhitel;  // берем значение R2 из ряда номиналов и умножаем на число множителя
      PopTemp = (ACPznach * R2) / (R2 + R1);  // Вычисляем значение АЦП для выбранного номинала резистора

      count++; // отмечаем пройденный круг цикла
      if (PopTemp >= PopSumZnach || count > 216) out1 = 1; // Условия для выхода из цикла подбора номинала:
  // если текущее значение АЦП больше или равно искомому или цикл прошел 216 раз (количество наоминалов в ряду+мои дополнения) и не нашёл нужного
    } while (out1 == 0); // Выходим из цикла номиналов
 
  count = 0; // обнуляем счетчик количества пройденных циклов в цикле номиналов
  out1 = 0; // обнуляем флаг для выхода из цикла номиналов, чтобы в него вновь можно было зайти
  mnozhitel *= 10; // увеличиваем множитель для номинала на 10, чтобы перейти к большим значениям R2
  if (PopTemp >= PopSumZnach || mnozhitel > 100000) out2 = 1;  // Условия для выхода из цикла подбора множителей:
// если текущее значение АЦП больше или равно искомому или значения R2 пошли на МегаОмы (10 * множитель 100 000 = 1 000 000)
} while (out2 == 0); // Выходим из цикла множителей
    // так как нам нужно знать не суммарное сопротивление всех R2.n, а только текущего, 
    // то из найденного общего сопротивления вычитаем предыдущее значение

 /* R2 это суммарное сопротивление всех резисторов в цепочке, а нам надо найти номинал именно последнего
     /------------R2---------------\
       ___     ___     ___      ___
    --|___|---|___|---|___|----|___|--
     \--------R2old--------/ \разница/
 Для этого из полученного значения сопротивления всей цепи вычитаем предыдущее значени...
 */
    R2raznica = R2 - R2old; // ...и получаем нужный нам номинал
        
    // для вичисления конкретно текущего 
   Serial.print("R2." );                       
   Serial.print(i);
   Serial.print(" = " ); 
if (R2raznica >= 10000){  // Если значение больше 10 000 
   Serial.print(R2raznica/1000); // то делим на 1000 Для отображения целого значения
   Serial.print(" KOm" ); // обозначаем что это КОм`ы
} else  if (R2raznica >= 1000){ // Если значение больше 1000, 
 R2Kold = R2raznica/100;  // то для отображения значений после запятой
   Serial.print((float)R2Kold / 10.0);  // переменную надо преобразовать во FLOAT
   Serial.print(" KOm" );  // обозначаем что это КОм`ы
}   else {  
   Serial.print(R2raznica);
   Serial.print(" Om" ); 
} 
    Nom24();   // функция поиска ближайшего номинала в ряду E24
   
PopSumZnach += PopSrZnach;  // Увеличиваем значение АЦП на величину среднего значения АЦП
mnozhitel = 1;  // Сбрасываем занчение множителя для запуска нового цикла подбора R2
out2 = 0;  // Сбрасываем флаг выхода из цикла множителей, для возможности вновь в него войти
R2old = R2; // отныне текущее значени считается старым :)
 }
   Serial.println("==================================" );   
   Serial.println("DONE!" ); // по нахождению всех нужных номиналов сигнализируем о завершении
}

void Nom24() // получив значение R2 из номинального ряда E192 надо подобрать ближайшее значение в номинальном ряду E24
// функция, по сути, точно такая же как и основная, только перебор осуществляется в номинальном ряду E24
{
unsigned long R24, R24old, E24Blozh; // переменные для расчета
unsigned long mnozh = 1; // тобы не указывать в массиве номинального ряда все значения от Ом до МОм, будем умножать каждый проход номинального ряда на 10
int cnt = 0; // переменная для счетчика в цикле номиналов
int E24temp; // 
boolean outCikl1 = 0; // флаг для выхода из цикла номиналов
boolean outCikl2 = 0; // флаг для выхода из цикла множителей

   do // Цикл подбора множителей
    {
      do // Цикл подбора резисторов
      {
 // выход из цикла происходит если расчитанное значение АЦП, из подобранного номанала резистора, 
 // больше нужного значения АЦП. Но не всегда получается что следующий номинал резистора 
 // наиболее близок к нужному нам значению. Поэтому мы сразу получаем следующее и предыдущее 
 // значение R2 из номинального ряда, для дальнейшего находжения наиболее близкого.
 
 // Если это первый проход цикла, то 
        if (cnt == 0) {R24old = NomResE24[cnt] * mnozh;} // старым занчением будем считать первое значение
        else {R24old = NomResE24[cnt-1] * mnozh;} // если не первый круг, то берём предыдущий номинал
        R24 = NomResE24[cnt] * mnozh; // и подбираем как бы следующий номинал
      cnt++; // отмечаем пройденный круг цикла
      if (R24 >= R2raznica || cnt > 23) outCikl1 = 1; // Условия для выхода из цикла подбора номинала:
  // если текущее значение АЦП больше или равно искомому или цикл прошел 24 раза (количество наоминалов в ряду) и не нашёл нужного
    } while (outCikl1 == 0); // Выходим из цикла номиналов
  cnt = 0; // обнуляем счетчик количества пройденных циклов в цикле номиналов
  outCikl1 = 0; // обнуляем флаг для выхода из цикла номиналов, чтобы в него вновь можно было зайти
  mnozh *= 10; // увеличиваем множитель для номинала на 10, чтобы перейти к большим значениям R2
  if (R24 >= R2raznica || mnozh > 100000) outCikl2 = 1;  // Условия для выхода из цикла подбора множителей:
// если текущее значение АЦП больше или равно искомому или значения R2 пошли на МегаОмы (10 * множитель 100 000 = 1 000 000)
} while (outCikl2 == 0); // Выходим из цикла множителей

   Serial.print(" | E24 = " );
// вичисляем ближайшее значение для этого из номинала текущего сопротивления из ряда E192 вычитаем предыдущее значение сопротивления из ряда E24 
// и сравниваем его с разницей сопротивлений следующего E24 и текущего E192.
// в зависомости от того какая разница значений меньше, мы и делаем вывод какой номинал E24 ближе к найденому E192
  if ((R2raznica - R24old) >= (R24 - R2raznica)) E24Blozh = R24;
  else E24Blozh = R24old;

// отображаем найденный ближний номинал из ряда E24 по аналогии с отображением номинала из ряда E192
if (E24Blozh >= 10000){  
   Serial.print(E24Blozh/1000);
   Serial.print(" KOm" ); 
} else  if (E24Blozh >= 1000){ 
 E24temp = E24Blozh/100;   
   Serial.print((float)E24temp / 10.0);  
   Serial.print(" KOm" ); 
}   else {      
   Serial.print(E24Blozh);
   Serial.print(" Om" ); 
} 
// А вот для расчета значения АЦП на данном резисторе нам нужно знать суммарное сопротивление резисторов из найденных ранее номиналов E24
  E24Summ += E24Blozh; // суммируем номиналы подходящих нам резисторов из ряда E24
   Serial.print(" | ACP = " ); 
   Serial.println((ACPznach * E24Summ) / (E24Summ + R1)); // расчитываем значение АЦП на основе суммы номиналов R24 
}


void loop() // в этот раз нам не пригодился, но без него код не компилиться
{
}

   Но у данного варианта тоже имеется неудобство. При изменении количества кнопок или номинала R1 необходимо вносить изменения в код и перезаливать в Arduino. Это меня и ранее смущало, но тогда я не знал как это победить, поэтому приходилось мириться с этим. Недавно попался вариант как можно модернизировать код и исправить это неудобство.

Код ниже это вариация работающего кода с возможностью указания количества кнопок и номиналов через UART. Тепрь можно менять вводные без перезаливки кода.
Вопросы писал транслитом, так как думаю, что транслит для многих более читабелен, нежели английский язык.     Вопросов всего два:
1/2 Укажите сопротивление R1 в Оммах. Опыты показали. что R1 лучше располагать в диапазоне от 2КОм до 100 КОм.
(под опытами я имею в виду опыты с данным кодом - бОльшие значения приводили к усложнению кода)
2/2 Укажите количество кнопок. Меньше 2-х нет смысла, а больше 100 уже будет сложно отловить АЦП Arduino ...оно, конечно, и 100 кнопок на аналоговом входе то ещё извращенство :)
   Так как данный скетч все таки призван для получения цепочки сопротивлений к кнопкам для более-менее равномерного распределения значений АЦП при нажатии на кнопки. то битность АЦП менять не требуется, а в итоговой табличке будут примерные значения АЦП для Arduino. Все равно они примерные, а итоговые для ваших АЦП и итоговой цепочки кнопок надежнее будет считать по месту через обычный AnalogRead с выводом в Serial.

// Больше настроек не потребуется, дальше то что менять не нужно.
// Так как данный скетч все таки призван для получения цепочки сопротивлений к конпкам 
// для более-менее равномерного распределения значений АЦП при нажатии на кнопки
// то битность АЦП менять не требуется, а в итоговой табличке будут примерные значения
// АЦП для Arduino. Все равно они примерные, а итоговые для ваших АЦП и итоговой цепочки кнопок
// надежнее будет считать по месту через обычный AnalogRead с выводом в Serial

byte KolvoButton; 
#define ACPbyte 10  // Укажите сколько бит Ваш АЦП
int count = 0;      // переменная для счетчика в цикле номиналов
int countR2 = 1;    // 
// Номинальный ряд E192 используем для подбора сопротивления согласно нужного значения АЦП
// Данный номинальный ряд был выбран как самый большой
// Чтобы не делать массив Float типа, умножил значение на 100, тем самым ушел от дробной части
// но для получения значений менее 100 пришлось добавить ещё значений к ряду
int NomResE192[] = {1,10,11,12,13,15,16,18,20,22,24,27,30,33,36,39,43,47,51,56,62,68,75,82,91,100,101,102,104,105,106,107,109,110,111,113,114,115,117,118,120,121,123,124,126,127,129,130,132,133,135,137,138,140,142,143,145,147,149,150,152,154,156,158,160,162,164,165,167,169,172,174,176,178,180,182,184,187,189,191,193,196,198,200,203,205,208,210,213,215,218,221,223,226,229,232,234,237,240,243,246,249,252,255,258,261,264,267,271,274,277,280,284,287,291,294,298,301,305,309,312,316,320,324,328,332,336,340,344,348,352,357,361,365,370,374,379,383,388,392,397,402,407,412,417,422,427,432,437,442,448,453,459,464,470,475,481,487,493,499,505,511,517,523,530,536,542,549,556,562,569,576,583,590,597,604,612,619,626,634,642,649,657,665,673,681,690,698,706,715,723,732,741,750,759,768,777,787,796,806,816,825,835,845,856,866,876,887,898,909,919,931,942,953,965,976,988};
// Номинальный ряд E24 по значениям которого будет происходить подбор нужного резистора.
// Чтобы не делать массив Float типа, умножил значение на 10, тем самым ушел от дробной части.
// Использовал этот номинальный ряд так как считаю его наиболее распространенным и доступным
int NomResE24[] = {10,11,12,13,15,16,18,20,22,24,27,30,33,36,39,43,47,51,56,62,68,75,82,91};
boolean out1 = 0;  // флаг для выхода из цикла номиналов
boolean out2 = 0;  // флаг для выхода из цикла множителей
unsigned long mnozhitel = 1;  // Чтобы не указывать в массиве номинального ряда все значения от Ом до МОм, будем умножать каждый проход номинального ряда на 10
unsigned long R1, R2, R2old, R2raznica, E24Summ, PopTemp, ACPznach, PopSumZnach, R2K, R2Kold, data;  // Объявляем переменные для расчета R2
int PopSrZnach, Etemp;  // Переменные для расчета
byte mode, KolvoR2;


void setup() {
  Serial.begin(9600); 
read_UART();

}

void loop() {
// =\/= Прием и обработка UART =\/= 
int i=0;
char buffer[10]; 
//если есть данные - читаем
  if(Serial.available()){
     delay(100);
     //загоняем прочитанное в буфер
     while( Serial.available() && i< 99) {
        buffer[i++] = Serial.read();
     }
     //закрываем массив
     buffer[i++]='\0';
  }
//если буфер наполнен
  if(i>0){  
data = strtoul(buffer,0,10);
read_UART();
  }
// =/\= Прием и обработка UART =/\= 
}

void read_UART() { // 
     switch (mode) {
  case 0 : // 
    Serial.println("?? Vopros 1/2: Ukazhite soprotivlenie R1 v Om ??");
    Serial.println("Dopustimie znacheniya: 2 000 ... 100 000");
    Serial.println("Opyty pokazali chto R1 luchshe raspolagat v diapazone 2KOm ... 100KOm");   
    mode = 1;
    break;
  case 1 : // 
  if (data >= 2000 && data <= 100000){
    R1 = data;
    Serial.print("Vi ukazali R1 = ");
if (R1 >= 10000){  
   Serial.print(R1/1000);
   Serial.println(" KOm" ); 
} else  if (R1 >= 1000){ 
 Etemp = R1/100;   
   Serial.print((float)Etemp / 10.0);  
   Serial.println(" KOm" ); 
}   else {      
   Serial.print(R1);
   Serial.println(" Om" ); 
}
    Serial.println();
    Serial.println("?? Vopros 2/2:  Ukazhite kolichestvo knopok ??");
    Serial.println("Dopustimie znacheniya: 2 ... 100");
    Serial.println("Knopok, soglasno sheme, ha odnu bolshe chem R2");    
    mode = 2;
  }
  else {
     Serial.println(" !! Chislo vne dopustimogo diapazona !!");
  }
    break;
  case 2 : // 
  if (data > 1 && data <= 100){
    KolvoButton = data;
    Serial.print("Vi ukazali ");
    Serial.print(KolvoButton);
    Serial.println(" knopok");
    Serial.println();
    calcR2();
    Serial.println("Nado pereschitat?");  
    Serial.println("esli DA otpravte - 1"); 
    mode = 3;
  }
  else {
     Serial.println(" !! Chislo vne dopustimogo diapazona !!");        
  }
    break;
  case 3 : // 
    if (data){
      Serial.println();     
      mode = 0;
      read_UART();
    }
    break;
   }
}

void calcR2(){
 ACPznach = pow(2, ACPbyte);  // расчитываем количество значений АЦП с учётом его битности
 PopSrZnach =  ACPznach / (KolvoButton);  // Считаем среднее значение АЦП с учетом количества кнопок (кнопок на одну больше чем резисторов R2)
 PopSumZnach = PopSrZnach;  // Переменная для хранения искомого в данный момент значения АЦП
// Отображаем наши исходные данные
   Serial.println("ISHODNIE DANNIE:");   
   Serial.print("R1: " );                       
if (R1 >= 10000){  
   Serial.print(R1/1000);
   Serial.println(" KOm" ); 
} else  if (R1 >= 1000){ 
 Etemp = R1/100;   
   Serial.print((float)Etemp / 10.0);  
   Serial.println(" KOm" ); 
}   else {      
   Serial.print(R1);
   Serial.println(" Om" ); 
}
   Serial.print("Kolichestvo knopok: " );                       
   Serial.print(KolvoButton);
   Serial.println(" sht" ); 
   Serial.print("ACP " );
   Serial.print(ACPbyte);
   Serial.print(" byte, " );
   Serial.print(ACPznach);
   Serial.println(" znacheniy" ); 
   Serial.print("Srednee znachenie ACP: " );                       
   Serial.println(PopSrZnach);   
   Serial.println("==================================" );   

 for (int i=1; i <= KolvoButton-1; i++){  // Цикл подбора резисторов. Остановиться когда вычислит указанное количество R2
do  // Цикл Множителей
{
    do  // Цикл номиналов
      {
      R2 = NomResE192[count] * mnozhitel;  // берем значение R2 из ряда номиналов и умножаем на число множителя
      PopTemp = (ACPznach * R2) / (R2 + R1);  // Вычисляем значение АЦП для выбранного номинала резистора

      count++; // отмечаем пройденный круг цикла
      if (PopTemp >= PopSumZnach || count > 216) out1 = 1; // Условия для выхода из цикла подбора номинала:
  // если текущее значение АЦП больше или равно искомому или цикл прошел 216 раз (количество наоминалов в ряду+мои дополнения) и не нашёл нужного
    } while (out1 == 0); // Выходим из цикла номиналов
 
  count = 0; // обнуляем счетчик количества пройденных циклов в цикле номиналов
  out1 = 0; // обнуляем флаг для выхода из цикла номиналов, чтобы в него вновь можно было зайти
  mnozhitel *= 10; // увеличиваем множитель для номинала на 10, чтобы перейти к большим значениям R2
  if (PopTemp >= PopSumZnach || mnozhitel > 100000) out2 = 1;  // Условия для выхода из цикла подбора множителей:
// если текущее значение АЦП больше или равно искомому или значения R2 пошли на МегаОмы (10 * множитель 100 000 = 1 000 000)
} while (out2 == 0); // Выходим из цикла множителей
    // так как нам нужно знать не суммарное сопротивление всех R2.n, а только текущего, 
    // то из найденного общего сопротивления вычитаем предыдущее значение

 /* R2 это суммарное сопротивление всех резисторов в цепочке, а нам надо найти номинал именно последнего
     /------------R2---------------\
       ___     ___     ___      ___
    --|___|---|___|---|___|----|___|--
     \--------R2old--------/ \разница/
 Для этого из полученного значения сопротивления всей цепи вычитаем предыдущее значени...
 */
    R2raznica = R2 - R2old; // ...и получаем нужный нам номинал
        
    // для вичисления конкретно текущего 
   Serial.print("R2." );                       
   Serial.print(i);
   Serial.print(" = " ); 
if (R2raznica >= 10000){  // Если значение больше 10 000 
   Serial.print(R2raznica/1000); // то делим на 1000 Для отображения целого значения
   Serial.print(" KOm" ); // обозначаем что это КОм`ы
} else  if (R2raznica >= 1000){ // Если значение больше 1000, 
 R2Kold = R2raznica/100;  // то для отображения значений после запятой
   Serial.print((float)R2Kold / 10.0);  // переменную надо преобразовать во FLOAT
   Serial.print(" KOm" );  // обозначаем что это КОм`ы
}   else {  
   Serial.print(R2raznica);
   Serial.print(" Om" ); 
} 
    Nom24();   // функция поиска ближайшего номинала в ряду E24
   
PopSumZnach += PopSrZnach;  // Увеличиваем значение АЦП на величину среднего значения АЦП
mnozhitel = 1;  // Сбрасываем занчение множителя для запуска нового цикла подбора R2
out2 = 0;  // Сбрасываем флаг выхода из цикла множителей, для возможности вновь в него войти
R2old = R2; // отныне текущее значени считается старым :)
 }
   Serial.println("==================================" );   
   Serial.println("DONE!" ); // по нахождению всех нужных номиналов сигнализируем о завершении
}

void Nom24() // получив значение R2 из номинального ряда E192 надо подобрать ближайшее значение в номинальном ряду E24
// функция, по сути, точно такая же как и основная, только перебор осуществляется в номинальном ряду E24
{
unsigned long R24, R24old, E24Blozh; // переменные для расчета
unsigned long mnozh = 1; // тобы не указывать в массиве номинального ряда все значения от Ом до МОм, будем умножать каждый проход номинального ряда на 10
int cnt = 0; // переменная для счетчика в цикле номиналов
int E24temp; // 
boolean outCikl1 = 0; // флаг для выхода из цикла номиналов
boolean outCikl2 = 0; // флаг для выхода из цикла множителей

   do // Цикл подбора множителей
    {
      do // Цикл подбора резисторов
      {
 // выход из цикла происходит если расчитанное значение АЦП, из подобранного номанала резистора, 
 // больше нужного значения АЦП. Но не всегда получается что следующий номинал резистора 
 // наиболее близок к нужному нам значению. Поэтому мы сразу получаем следующее и предыдущее 
 // значение R2 из номинального ряда, для дальнейшего находжения наиболее близкого.
 
 // Если это первый проход цикла, то 
        if (cnt == 0) {R24old = NomResE24[cnt] * mnozh;} // старым занчением будем считать первое значение
        else {R24old = NomResE24[cnt-1] * mnozh;} // если не первый круг, то берём предыдущий номинал
        R24 = NomResE24[cnt] * mnozh; // и подбираем как бы следующий номинал
      cnt++; // отмечаем пройденный круг цикла
      if (R24 >= R2raznica || cnt > 23) outCikl1 = 1; // Условия для выхода из цикла подбора номинала:
  // если текущее значение АЦП больше или равно искомому или цикл прошел 24 раза (количество наоминалов в ряду) и не нашёл нужного
    } while (outCikl1 == 0); // Выходим из цикла номиналов
  cnt = 0; // обнуляем счетчик количества пройденных циклов в цикле номиналов
  outCikl1 = 0; // обнуляем флаг для выхода из цикла номиналов, чтобы в него вновь можно было зайти
  mnozh *= 10; // увеличиваем множитель для номинала на 10, чтобы перейти к большим значениям R2
  if (R24 >= R2raznica || mnozh > 100000) outCikl2 = 1;  // Условия для выхода из цикла подбора множителей:
// если текущее значение АЦП больше или равно искомому или значения R2 пошли на МегаОмы (10 * множитель 100 000 = 1 000 000)
} while (outCikl2 == 0); // Выходим из цикла множителей

   Serial.print(" | E24 = " );
// вичисляем ближайшее значение для этого из номинала текущего сопротивления из ряда E192 вычитаем предыдущее значение сопротивления из ряда E24 
// и сравниваем его с разницей сопротивлений следующего E24 и текущего E192.
// в зависомости от того какая разница значений меньше, мы и делаем вывод какой номинал E24 ближе к найденому E192
  if ((R2raznica - R24old) >= (R24 - R2raznica)) E24Blozh = R24;
  else E24Blozh = R24old;

// отображаем найденный ближний номинал из ряда E24 по аналогии с отображением номинала из ряда E192
if (E24Blozh >= 10000){  
   Serial.print(E24Blozh/1000);
   Serial.print(" KOm" ); 
} else  if (E24Blozh >= 1000){ 
 E24temp = E24Blozh/100;   
   Serial.print((float)E24temp / 10.0);  
   Serial.print(" KOm" ); 
}   else {      
   Serial.print(E24Blozh);
   Serial.print(" Om" ); 
} 
// А вот для расчета значения АЦП на данном резисторе нам нужно знать суммарное сопротивление резисторов из найденных ранее номиналов E24
  E24Summ += E24Blozh; // суммируем номиналы подходящих нам резисторов из ряда E24
   Serial.print(" | ACP = " ); 
   Serial.println((ACPznach * E24Summ) / (E24Summ + R1)); // расчитываем значение АЦП на основе суммы номиналов R24 
}

   Дополню своими вариантами плат для резистивной клавиатуры. Не то что я люблю очень резистивные клавиатуры, просто решил собрать из разных проектов. Может кому пригодиться.

Вариант на 5 кнопок. Это не мое, честно скажу, но тем не менее приложу сюда.
Вариант на 8 кнопок.
Масштабируемый универсальный вариант. Сколько Вам необходимо кнопок - множите модули. вот вариант использования:
b707
Offline
Зарегистрирован: 26.05.2017

CheBuraw - начали вроде хорошо, а потом.... сами же рассуждаете о битности АЦП и вдруг - табличка для 19 кнопок на 8 битах???

Вам не приходило в голову, что количество независимо опредляемых кнопок никак НЕ МОЖЕТ ПРЕВЫШАТь битности аналогового входа? - это даже в теории. А на практике количество кнопок как минимум на 2 меньше.

Код уже не смотрел.

nik182
Offline
Зарегистрирован: 04.05.2015

У меня замечательно работает 16 кнопок  на 12 битном АЦП. Номер кнопки одндозначно определяется делением кода АЦП на 256. 

b707
Offline
Зарегистрирован: 26.05.2017

nik182 пишет:

У меня замечательно работает 16 кнопок  на 12 битном АЦП. Номер кнопки одндозначно определяется делением кода АЦП на 256. 

Независимо? если нажать 2-3 кнопки разом - сможете определить, какие именно? (вопрос риторический)

bwn
Offline
Зарегистрирован: 25.08.2014

b707 пишет:

Независимо? если нажать 2-3 кнопки разом - сможете определить, какие именно? (вопрос риторический)

Так схема то, неопределяемая, как не нажимай, будет код кнопки максимально близкой к OUT.

CheBuraw
Offline
Зарегистрирован: 10.02.2015

b707 пишет:

Вам не приходило в голову, что количество независимо опредляемых кнопок никак НЕ МОЖЕТ ПРЕВЫШАТь битности аналогового входа? - это даже в теории. А на практике количество кнопок как минимум на 2 меньше.

b707, предполагаю, что Вы не разобравшись в сути сразу же бросились писать разгромный пост. Думаю Вас смутило то, что я назвал её резистивной и Вы подумали о мультитаче и прочих плюшках. Но данная тема не о том.
bwn очень точно описал принцип работы данной клавиатуры. Она (клавиатура) далеко не идеальна, но для некоторых задач её вполне достаточно.

Попробуйте сами на бредборде или в эмуляторе каком-нибудь собрать, согласно представленной схеме, данную клавиатуру. Вы увидите что 10 битный АЦП Arduino справиться и с 30 и с 40 кнопками, тут вопрос чисто в надежности и целесообразности данного решения (я про 30-40 кнопок).

Green
Offline
Зарегистрирован: 01.10.2015

А с комбинацИями?

bwn
Offline
Зарегистрирован: 25.08.2014

CheBuraw пишет:

и с 30 и с 40 кнопками, тут вопрос чисто в надежности и целесообразности данного решения (я про 30-40 кнопок).

Эт уже очень оптимистично, может на каких герконовых, а на обычных китайских, дай бог штук десять. Там под сотню попугаев значения ползают от силы нажатия. ИМХО.

CheBuraw
Offline
Зарегистрирован: 10.02.2015

Green пишет:

А с комбинацИями?

Не совсем понятно о каких комбинациях идет речь. Уточните, пожалуйста.

bwn пишет:

Эт уже очень оптимистично, может на каких герконовых, а на обычных китайских, дай бог штук десять. Там под сотню попугаев значения ползают от силы нажатия. ИМХО.

:) это да! Тут много нюансов и кнопки и итоговые номиналы резисторов и ... в общем-то много кнопок, как я писал выше, это то ещё извращенство. Для этого уже другие способы ввода лучше использовать Куда надежнее будет клавиатуру от ПК использовать, но это тема уже другая.
С герконами это тоже как вариант. Просто разные задачи у людей бывают и иногда может и 40 "кнопок" приходиться использовать. Опять же нужен был срочно датчик уровня воды и сделал его по схеме из первого поста. 30 контактов :) - жесть! Но работает. там правда пришлось еще поставить транзистор на отключение в момент когда замеры не далаются, чтобы не заниматься электролизом.

В общем-то код это просто лентяйка для быстрого рассчета резисторов. А куда её применят, это уже на усмотрение читателей :).

nik182
Offline
Зарегистрирован: 04.05.2015

Объясните, зачем нужны комбинации кнопок на микроконтроллере? У меня кнопки выбирают режим работы устройства. Нажитие одновременно двух кнопок не имеет смысла. В любом случае будет определяться та которая ближе к выходной ноге. 

Green
Offline
Зарегистрирован: 01.10.2015

А если подумать?) Обычно комбинации из за экономии. Но, бывает что нужны комбинации типа SHIFT+ или CTRL+.

nik182
Offline
Зарегистрирован: 04.05.2015

Shift & ctrl можно на другую аналоговую ногу загнуть, где выполнить условие разрядность = количеству кнопок и жать их вдоль и поперёк, а там где по одной жать можно сотню повесить и получить хоть 1000 сочетаний, но зачем? Долго думал, так и не придумал зачем для микроконтроллера может понадбится SHIFT+ или CTRL+.  

Green
Offline
Зарегистрирован: 01.10.2015

Нужно тренировать фантазию, иначе она может... тогось.(

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Нужны комбинации - делайте R2R - там, кстати, всё напмного проще - все резисторы одинаковые, поэтому код ТС в одну строчку умещается :)

Green
Offline
Зарегистрирован: 01.10.2015

И я о том же. И тогда к чему все эти рассчёты?
Единственное, это ограничение на к-во кнопкок, 8-10 макс.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, нет, если ADC 10-битный с точностью 2 lsb (как на ATMega328), то не более 7-ми кнопок.

У меня вот такая красавица (на 4 конпки) уже два года работает как часы.

b707
Offline
Зарегистрирован: 26.05.2017

ЕвгенийП пишет:

Нужны комбинации - делайте R2R - там, кстати, всё напмного проще - все резисторы одинаковые, поэтому код ТС в одну строчку умещается :)

вот и я о том же с самого начала. Нафига эти формулы. когда просто берешь пачку одинаковых резисторов и собираешь. Количество кнопок ограничено - зато это действительно независимые кнопки, а не как у ТС, где при случайном нажатии более одной кнопки результат может быть совершенно не тем, что ожидаешь.

nik182
Offline
Зарегистрирован: 04.05.2015

Вот уж нет. Результат всегда однозначный. Кнопка нажатая ближе всего к выходу. Резистор замыкается на землю. Остальные никак не влияют на результат. И всё же. Кто нибудь ответит зачем нажимать несколько кнопок одновременно на микроконтроллерном устройстве? На часах, регуляторе температуры, контроллере полива и прочих устройствах, которые не являются компьютерами и имеют конкретный функционал с ограниченным набором функций? В остальных случаях проще воткнуть полноразмерную клавиатуру, благо их сейчас любого размера море. 

b707
Offline
Зарегистрирован: 26.05.2017

nik182 пишет:

И всё же. Кто нибудь ответит зачем нажимать несколько кнопок одновременно на микроконтроллерном устройстве? На часах, регуляторе температуры, контроллере полива и прочих устройствах, которые не являются компьютерами и имеют конкретный функционал с ограниченным набором функций?

так вроде выше уже ответили - увеличение набора функций. В вашем варианте 4 кнопки дают только 4 функции, а при возможности различать одновременное нажатие хотя бы пары кнопок получаем уже 10 вариантов - в 2.5 раза больше!

А теперь вы мне в свою очередь ответьте, нафига вообще на микропроцессорном устройстве 10, 15 или 20 кнопок? - это ж не клавиатура для ввода текста? ИМХО, когда кнопок становится более десятка - это признак необходимости перехода на меню

так что в любом случае подключение к аналоговому входу кучи кнопок - задача скорее теоретическая, на практике лграничения системы R2R вполне достаточно и никаких резисторов рассчитываить вообще не требуется.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nik182 пишет:
Кто нибудь ответит зачем нажимать несколько кнопок одновременно на микроконтроллерном устройстве?
Я отвечу. В том устройстве на которое я здесь ссылался четыре кнопки дистанционно включают/выключают четыре элемента освещения моего двора. Нет возражений, что это нормальное применение микроконтроллера? Вы предлагаете мне включать прожекторы строго по одному? Или присобачивать для этого полноценную клавиатуру?

nik182
Offline
Зарегистрирован: 04.05.2015

У меня стенд проверки электрожелезок. На нем работает далёкий от всего компьютерного человек. Нужно выставить 2 напряжения от 100 до 300 вольт, выбрать один из 4 режимов проверки, сброс и вспомогательные функции. Всего 16 кнопок. Каждая подписана. Человек по карте проверки нажимает одну из кнопок. Меню он точно не осилит. Кнопки висят на одном аналоговом входе. 

bwn
Offline
Зарегистрирован: 25.08.2014

nik182 пишет:

 И всё же. Кто нибудь ответит зачем нажимать несколько кнопок одновременно на микроконтроллерном устройстве? На часах, регуляторе температуры, контроллере полива и прочих устройствах, которые не являются компьютерами и имеют конкретный функционал с ограниченным набором функций? В остальных случаях проще воткнуть полноразмерную клавиатуру, благо их сейчас любого размера море. 

Как по мне, то три штуки весьма удобно. Прибавить, убавить, подтвердить. А вот в меню попасть, как раз две и подержать еще, от ручек шаловливых.)))) ИМХО.

nik182
Offline
Зарегистрирован: 04.05.2015

Евгений! Четыре элемента - четыре кнопки. Вы хотите сказать что нажимаете одновременно 4 кнопки что бы включить все 4 элемента? Каждый человек может делать так как ему удобно. Мне в такой конфигурации проще поставить пятую кнопку и назначить на неё функцию включения всех элементов одновременно. Мне проще попасть пальцем в одну кнопку, чем попадать четырьмя пальцами в четыре кнопки.

Но я ещё раз повторю. Я никому ничего не навязываю. Делайте как Вам удобнее и привычнее. Я прошу объяснить почему именно так. Если окажется что в таком применении есть какие то дополнительные преимущества, то в следующий раз я сделаю так же и скажу спасибо.      

CheBuraw
Offline
Зарегистрирован: 10.02.2015

Ладно уж Вам ругаться-то :) ! У всех разные задачи и каждый реализует их так как считает нужным, и как хватает знаний и умений.
Лично у меня, пока не было задач где необходимо много кнопок с одновременным нажатием нескольких. А если и встречались схемы, то обычно свободных ног на контроллере хватало и тогда кнопки вешали на разные ноги контроллера.

Данный топик был создан для тех кому это может потребоваться данный вид клавиатуры. У меня была проблема с быстрым рассчетом резисторов, для себя я нашел решение. Наверняка я не один кому может потребоваться рассчитать резисторы для данного вида подключения кнопок. Если кому-то поможет, будет хорошо.

Я, вот например раньше никогда не сталкивался с вариантом R2R и сегодня впервый раз об этом узнал. Так что уже не зря топик создавал. :)
Правда для себя пока не вижу куда это можно применить, даже банально из-за того что требуется кнопка с переключением контактов (если я правильно понял), а у меня куча обычных тактовых кнопок и их куда-то надо применять. Стараюсь использовать то, что уже имеется и закупать дополнительно если уж никак не обойтись имеющимися деталями. Но если вдруг потребуется, теперь буду иметь данный вариант в виду.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nik182 пишет:

Евгений! Четыре элемента - четыре кнопки. Вы хотите сказать что нажимаете одновременно 4 кнопки что бы включить все 4 элемента? Каждый человек может делать так как ему удобно. Мне в такой конфигурации проще поставить пятую кнопку и назначить на неё функцию включения всех элементов одновременно. 

Да, нет, Вы не поняли. Кнопки у меня фиксируемые. Нажимаю я их по мере надобности (разумеется, по одной). Всегда горят те прожекторы, чьи кнопки нажаты. А при схеме из этого топика никогда нельзя знать какие нажаты, кроме одной - самой близкой к питанию.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

CheBuraw пишет:
не сталкивался с вариантом R2R

Она мне очень нравится своим изяществом и лаконичностью. Вот моё эссе про саму схему, а вот - про её главные грабли.

CheBuraw
Offline
Зарегистрирован: 10.02.2015

Уже прочитал Вашу статью :). Интересное решение. Отложу себе в закладки с кнопками. Спасибо!