Полезная задача для начинающих

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

Задача родилась из практики - мне пришлось это делать. Подумал, что тем, кто только начинает, будет полезно её решить. И пригодится, может, ещё не раз. Для решения достаточно знать закон Ома и математику на уровне средней школы.

Предыстория:

Потребовалось мне цифровое управление аналоговой схемой (а именно, уровнем напряжения стабилизатора LM317). Было выбрано решение использовать линейный цифровой потенциометр (ЦП). Но под рукой оказался только X9C103P  на 10 кОм, а нужно было на 3,8 кОм (не думаю, что такие ЦП бывают в природе!). Использовать не полностью -  не вариант, т.к. это означало начисто лишиться плавности регулировки. Там и так-то всего 100 градаций, а здесь я себе только 38 оставляю. Номинал можно изменить, включив параллельно ЦП правильно рассчитанный резистор. Например, для моего случая ( требуется потенциометр на 3,8кОм, а в наличии только на 10кОм), включаем параллельно резистор на 6,2кОм

и получаем

Казалось бы, всё – задача решена, но не тут-то было! :(

Из-за нашего «финта ушами» получившийся комбинированный потенциометр оказался нелинейным! Если мы теперь будем подавать на него 1, 2, 3, … до его предела, его сопротивление будет расти не линейно, как у оригинального ЦП, а вот так:

Беда, да и только :(

Хочется всё-таки передавать ему некую n и понимать, что при этом его сопротивление составит n сотых (у X9C103P всего 100 градаций) от номинального, а не как на графике!

Задача:

Имеется ЦП с номинальным сопротивлением Rd и количеством градации Total. Параллельно ему включён резистор сопротивлением Rc. Найти такую функцию f(n) (где n – от 0 до Total-1), чтобы при передаче ЦП величины f(n), сопротивление комбинированного потенциометра становилось равным n/Total от максимального, т.е., чтобы комбинированный потенциометр был линейным.

Замечание:

Кончено, поскольку мы не имеем возможности передавать ЦП дробные величины, идеальной линейности не получится из-за ошибок окгругления до целого. Но, «более или менее» – вполне. У меня получилось вот так:

Куда как «линейнее», чем на рисунке выше!

b707
Онлайн
Зарегистрирован: 26.05.2017

Несколько смущает, что это задачка "для начинающих". То ли я такой тупой... но как-то непросто все...  аналитического решения найти так и не смог. Ну раз никто не отвечает - попробую.

"На словах" - надо взять эту же функцию и отразить ее относительно графика y=x, как-то так:

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

1. Рискну немного подправить условие задачи: "Найти такую функцию f(n) (где n – от 0 до Total-1), чтобы при передаче ЦП величины f(n), сопротивление комбинированного потенциометра становилось равным n/(Total-1) от максимального".

2. В каком виде изволите?

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

andriano пишет:

2. В каком виде изволите?

Нещитова! :))) Вы привели три аппроксимации.

Формула же для f(n) получается аналитически -  абсолютно точная (до тех пор пока округлять до целых не начнём). И если рисовать график без округлений - голимая прямая.

Я так вижу, задачей заинтересовались исключительно начинающие :))))

Вот мужики, им что правда ни хрена, кроме готового кода, не нужно? Никогда не понимал какой кайф от хобби, когда я делаю это не сам :(

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Привожу самый точный и одновременно самый быстрый вариант (в предположении, что total == 100, т.е. количеству ступеней резистора, что в общем случае необязательно)

#define total 100

inline byte resist_n(byte n) {
  const byte nr[total] = {
    0, 0, 1, 1, 2, 2, 2, 3, 3, 4, 
    4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 
    9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 
    14, 15, 15, 16, 17, 17, 18, 18, 19, 20, 
    20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 
    28, 29, 29, 30, 31, 32, 33, 34, 35, 36, 
    37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 
    48, 49, 50, 51, 53, 54, 55, 57, 58, 60, 
    61, 63, 64, 66, 68, 69, 71, 73, 75, 77, 
    78, 81, 83, 85, 87, 89, 92, 94, 96, 99};
  return nr[n];  
}

float resistance(int n) {
  const float R1 = 6.2; // постоянный резистор
  const float R2 = 10.0; // переменный резистор
  float R2i = n*(R2/(total-1));
  return R1*R2i/(R1 + R2i);
}

void setup() {
  Serial.begin(115200);
  for(byte i = 0; i < total; i++) {
    Serial.print(i);
    Serial.print('\t');
    Serial.println(resistance(resist_n(i)));
  }
}

void loop() {
}

Цитата:
Я так вижу, задачей заинтересовались исключительно начинающие :))))

Куда ж без них!

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

Нам учитель задает

С иксами задачи...

----------------------------------

Женя, а чему вы хотели научить новичков? Составить уравнение в проводимостях вместо сопротивлений и решить в уме? Так этого и старички не стали делать.

Все это бесперспективно.

Жизнь пуста и бессмысленна.

sadman41
Offline
Зарегистрирован: 19.10.2016

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

Вот мужики, им что правда ни хрена, кроме готового кода, не нужно? Никогда не понимал какой кайф от хобби, когда я делаю это не сам :(

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

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

Ну, вот опять пришёл поручик Ржевский! :) andriano, ну задача-то функцию придумать - формулу вывести :)

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

wdrakula пишет:
чему вы хотели научить новичков?
Да, ничему не хотел. Развлекаюсь так. 

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

У меня настроение "постижения дзена", поэтому я все опошлю: объясню, как решать такую хню в уме.

------------------------------------

Задача: сопротивления Y(x) и R включены параллельно, полученное сопротивление - X = ax, то есть линейно от параметра сопротивления Y.

--------------------------------------

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

Зато помним волшебное слово "проводимость" и то, что она обратна сопротивлению, то есть равна 1/R.

Афигеть!

1/Y(x) + 1/R = 1/ax, решим для 1/Y(x) -> 1/Y(x) = 1/ax - 1/R

Чуть-чуть напрягаем мозговые ганглии, но не до геморроя. Себя бережем. Раскрываем дроби... страшно, а что делать?

Y(x) = axR/(R - ax).

 

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

:

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

Ну, вот опять пришёл поручик Ржевский! :) andriano, ну задача-то функцию придумать - формулу вывести :)

Не надо передергивать.

Речь шла о функции - она написана. И размещенный Вами последним график подтверждает, что функция в данном конкретном случае понимается с точки зрения программирования, а не алгебры (кстати алгебраические аппроксимации Вам тоже не понравились, - на Вас не угодишь!).

Про формулу речи не было. От слова совсем.

Да и представленное мной решение:

1. Оптимально.

2. Наглядно демонстрирует начинающим (см. название темы), как следует решать подобные задачи.

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

andriano пишет:

Не надо передергивать. Речь шла о функции - она написана. 

Так и я ж про тоже - не надо. Речь шла о функции в математическом смысле f(n) = ....

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ну да.

Тема, как и положено, начинается с формулировки задачи.

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

Как это характерно для нашего форума!

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

andriano пишет:

ТС имел в виду совершенно не то, о чем написал.

 ТС написал

ЕвгенийП пишет:
Найти такую функцию f(n) ..., чтобы

Для меня очевидно, что речь об аналитическом виде, иначе было бы сказано не "найти", а "написать".

Может это читатель невнимательно прочитал пост ТС?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

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

Вот только я не понимаю, целью создания данной темы было написать нечто полезное для начинающих или выяснить, кто виновен в возникшем недопонимании.

 

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

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

wdrakula
wdrakula аватар
Онлайн
Зарегистрирован: 15.03.2016

Я вот, напрмер, всегда яйцо разбиваю с тупого конца. Как известно, прочность купольной конструкциии обратно пропорциональна (квадрату?) радиуса кривизны. Следовательно усилия, затрачиваемые на разрушение оболочки яйца, будут значительно ниже со стороны большего радиуса кривизны.

Таким образом, эффективность завтрака, как разница портаченных калорий на разбивку яйца и калорий,  полученных путем его употребления,  повышается с выбором правильного, то есть ТУПОГО конца яйца.

Ч.и Т.Д.

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

andriano,

Господь с ним, что Вы неправильно поняли задачу. Давайте поговрим о Вашем заявлении, что у Вас мол дескать:

andriano пишет:

1. Оптимально.

Вот смотрите. Если решить задачу аналитически, то получается вот такое решение:

           n * C1
f(n) = -----------  (1)
           C2 - n

Где:
     С1 = Total * Rc / Rd
     C2 = Total * (Rc + Rd) / Rd
     ---
     Rd - номинал потенциометра,
     Rc - номинал постоянного резистора
     Total - количество градаций.

Разумеется, константы С1 и С2 можно и нужно посчитать заранее, еще на этапе компиляции препроцессор их отлично посчитает.

Для проверки это можно подставить (1) в формулу для сопротивления комбинированного резистора

         Rc * f(n) * Rd / Total
Rk = ------------------------------
         Rc + f(n) * Rd / Total

Руками подставлять я и не пытался :) но Mapple радостно выдал

Rk = n * Rd / Total

Что и требовалось.

------------------

Теперь давайте сравним время и память Этого решения и Вашего. 

У Вас вычисление аналога этой f (строка 21) требуют: вычитания, деления, умножения и выборки из массива по индексу.

У меня, (по формуле выше), тоже требуется вычитание, деление и умножение. Но никакой выборки из массива и никакого собственно массива на количество элементов, равное числу градаций у меня нет.

Получается, что Ваше решение проигрывает по времени на выборку из массива, а по памяти, на массив, размером в Total элементов. Ну и по каким же тогда парамтерам оптимальности, оно у Вас оптимально?

Даже, если Вы предложите, всё, что стоит в строке 21 после знака умножения, посчитать заранее (что правильно), Ваша оптимальность будет выглядеть как выигрыш одного деления и одного вычитания против проигрыша массива в Total элементов и выборки из него (сиречь умножения!) - согласитесь, весьма сомнительная "оптимальность".

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

wdrakula пишет:
яйцо разбиваю с тупого конца
Причём тут яйцо? Хорошее аналитическое решение почти всегда даёт лучший программный код. Гляньте на разбор заявленной andriano "оптимальноти" в моём предыдущем посте. Что от неё ("оптимальности") осталось? 

sadman41
Offline
Зарегистрирован: 19.10.2016

wdrakula пишет:

Я вот, напрмер, всегда яйцо разбиваю с тупого конца. 

Вы просто пока еще не резали себе палец, разбивая яйцо означенным способом...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

wdrakula пишет:

Я вот, напрмер, всегда яйцо разбиваю с тупого конца. Как известно, прочность купольной конструкциии обратно пропорциональна (квадрату?) радиуса кривизны. Следовательно усилия, затрачиваемые на разрушение оболочки яйца, будут значительно ниже со стороны большего радиуса кривизны.

Таким образом, эффективность завтрака, как разница портаченных калорий на разбивку яйца и калорий,  полученных путем его употребления,  повышается с выбором правильного, то есть ТУПОГО конца яйца.

Ч.и Т.Д.

Но если стоит обратная задача. Сбросить вес. То надо разбивать с острого. А еще лучше взять шарик от шарикоподшипника и начать разбивать уже его до нужного похудения.

Шутка.

ПС: Но если яйцо вареное, то я разбиваю  разместив ее между двух тарелок- глубокой и тонкой. После этого яйцо чистится легче.

ssss
Offline
Зарегистрирован: 01.07.2016

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

Руками подставлять я и не пытался :) но Mapple радостно выдал

Rk = n * Rd / Total

Что и требовалось.

И что это такое??? Нахрен оно вообще нужно???

sadman41
Offline
Зарегистрирован: 19.10.2016

qwone пишет:

ПС: Но если яйцо вареное, то я разбиваю  разместив ее между двух тарелок- глубокой и тонкой. После этого яйцо чистится легче.

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

Какой следует вывод из этой лирики? Очень простой: «Все истинно верующие да разбивают яйца с того конца, с какого удобнее.» О чем нам, собственно, и сообщил Люстрог посредством пера в руках Джонатана Свифта.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

sadman41. Можно. Но почему-то между тарелками скорлупа легче отделяется. Может удар по очень твердой поверхности приводит к большим колличествам микротрещин. Опять же если вы делаете оливье или яйцо под майонезом, то выковыривать ложкой яйцо из скорлупы не очень удачный ход. Разумеется можно сначало яйцо, а потом заглотнуть майонез и попрыгать до полного перемешания. Но если вы готовите это блюдо не только для себя.

sadman41
Offline
Зарегистрирован: 19.10.2016

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

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

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

wdrakula пишет:

Я вот, напрмер, всегда яйцо разбиваю с тупого конца. Как известно, прочность купольной конструкциии обратно пропорциональна (квадрату?) радиуса кривизны. Следовательно усилия, затрачиваемые на разрушение оболочки яйца, будут значительно ниже со стороны большего радиуса кривизны.

Таким образом, эффективность завтрака, как разница портаченных калорий на разбивку яйца и калорий,  полученных путем его употребления,  повышается с выбором правильного, то есть ТУПОГО конца яйца.

Ч.и Т.Д.

1. Дожен заметить, что не могу согласиться с Вами по поводу критерия оптимизации. Дабы избежать обвинения в переходе на личности, говорю только за себя: лично у меня наблюдается избыток веса. Поэтому искренне полагаю, что оптимизация по минимуму затраченных калорий лично мне не пойдет на пользу. Впрочем, каждый вибирает для себя сам.

2. Миниммальный радиус кривизны наблюдается на "боковой" поверхности яйца, поэтому идея разбивать яйцо с любого из "концов" порочна по определению!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

Теперь давайте сравним время и память Этого решения и Вашего. 

Это возможно будет следать не ранее, чем оба исходника будут опубликованы. Сравнивать конкретный исходник с общими рассуждениями - нонсенс.

Скетч в студию!

Цитата:

У Вас вычисление аналога этой f (строка 21) требуют: вычитания, деления, умножения и выборки из массива по индексу.

Какое деление? Какое умножение?

Затребованная Вами функция расположена в строках с 1-й по 16-ю. Далее идет демонстрационный код. Вы всерьез собираетесь анализировать оптимальность демонстрационного кода? С какой целью?

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

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

andriano пишет:

Скетч в студию!

Т.е. Вы не согласны с тем, что массива на 100 целых в моём решении нет, а если не дай бог 10-битный ЦП, то и массива на 1024 целых, что равно ВСЕЙ памяти Нанки.

Ну, не согласны, и не надо. Скетча не будет. Холивара тоже. Тема создавалась не для холиваров.

Была предложена задача, желающим вывести формулу (кстати, b707 и wdracula поняли её правильно, в отличие от Вас). Желающие вывели или хотя бы попытались.

Собственно, всё.

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

ssss пишет:

И что это такое??? Нахрен оно вообще нужно???

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

ssss
Offline
Зарегистрирован: 01.07.2016

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

Понимаете, у людей, у которых есть мозги

Видите ли... "Гложут меня смутные сомнения."(с)...

Мозги... чтобы делать всё проще... а не усложнять... чтобы потом мужественно с этим бороться...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

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

Т.е. Вы не согласны с тем, что массива на 100 целых в моём решении нет,

Я не могу быть согласен либо несогласен с тем, чего я никогда не видел.

Я не комментирую то, чего нет.

Цитата:

а если не дай бог 10-битный ЦП, то и массива на 1024 целых, что равно ВСЕЙ памяти Нанки.

У "Нанки" 32 кбайта памяти.

Потрудитесь считать корректно.

(на всякий случай напомню, что никакой непосредственной связи между свойствами потенциометра и размером массива не существует. Я лишь последовал Вашему примеру, чтобы совпадение графиков было более наглядным. В реальной жизни, скорее всего, я бы выбрал 256 градаций, если бы мне нужна была максимальная точность и 30-50, если бы такая точность была не нужна)

Цитата:

Скетча не будет.

Я так и думал.

Хотя - надеялся.

Цитата:
(кстати, b707 и wdracula поняли её правильно, в отличие от Вас)

Ну правильно, когда нет надежды привести лучшее решение, остается только поиск виновных.

 

В любом случае, думаю, что тема выиграла от того, что в ней появилось несколько разных взглядов на задачу, и проиграла от того, что некоторые участники форума вопреки здравому смыслу и имеющейся на форуме практике исходят из якобы имеющейся у ТС презумпции истины в последней инстанции.

alexbmd
Offline
Зарегистрирован: 15.01.2016

Цитата:
смотришь со стороны умные дядьки а некоторые и деды а каждая вторая тема холивар и даже новички не нужны для этого

FAI4
Offline
Зарегистрирован: 23.09.2016

В этой задаче НИКАК не учтен ток управляющего вывода LM317.

Зависимость там поэтому будет еще сложнее.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

FAI4 пишет:

Зависимость там поэтому будет еще сложнее.

С чего?

И какая же она будет?

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

Ворота пишет:

С чего?

И какая же она будет?

Не буди дэмона, пожалеешь.

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Так интересно же, как ток, проходящий через двухполюсник может на его (двухполюсника) внутренности влиять :)

Logik
Offline
Зарегистрирован: 05.08.2014

Ворота пишет:

Так интересно же, как ток, проходящий через двухполюсник может на его (двухполюсника) внутренности влиять :)

Действительно, как ток через лампу накаливания может менять её сопротивление.

Хотя посчитай сразу правильно выводы у ЛМ-ки, тогда поговорим о двухполюсниках. Возможно ;)

LM317_Pinout-300x178.png

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

И каким боком тут лампа накаливания? А почему лампа, а не, например, предохранитеь? Тоже двухполюсник и тоже ток влияет на нутро ещё похлеще, чем у лампы. Лишь бы пукнуть, а там хоть волна не иди?

Logik пишет:

Хотя посчитай 

Тебе надо посчитать? Не вопрос – 300 баксов.

А вообще, надо было в школу ходить, а то вот теперь сам посчитать не можешь ввиду врождённого тупоумия, а мне заказать не можешь, ввиду приобретённого нищебродства. Беда!

Ирокез
Offline
Зарегистрирован: 27.08.2019

Переходим от сопротивлений к проводимостям, при параллельном соединении они складываются, отсюда Sш=Sc-Sп, теперь обратный переход: 1/Rш=1/Rс-1/Rп, Rш=1/(1/Rс-/1/Rп). Аналогично находим положение потенциомета, но теперь известная величина – сопротивления шунта. Sп=Sт-Sш, 1/Rп=1/Rт-1/Rш, Rп=1/(1/Rт-1/Rш), u=(1/(1/Rт-1/Rш))/k (u – индекс сопротивления, k – цена деленяи потенциометра). Всё, никакого обрашения функций не нужно и выводить градуировочную характеристку незачем. Можно даже заранее вычислить и Rш, и Sш=1/Rш и в программе записать Sш как константу, тогда функция Rп=1/(1/Rт-Sш), u=(1/(1/Rт-Sш))/k. Только разрешение будет неравномерным и крайние значения обработать отдельно. Ещё можно заранее табулировать R=1/(1/Rп-Sш) и искать в полученной таблице, между какими значениями оказалось требуемое сопротивление, весить она будет не много.