Линейность датчика

IhKa
Offline
Зарегистрирован: 08.05.2013

На каждый милиметр перемещения датчик выдаёт следующие цифры (плюс минус дрожание):

875,725,606,522,457,408,365,330,303,282,260,240,226,212,201,190,181,173,166,161,154,150,147,143,138,135,131.

Показания крайне нелинейны, начиная с разницы в 150 и заканчивая в 3.

Как проще их перещитывать в реальное перемещение в мм, хотя бы в большей, центральной части?

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

Datchik = sqrt((analogRead(A5) * 30));

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Вам надо почитать статьи по математике на тему "сглаживание результатов измерений", там всякие полиномы и ряды Фурье использовать можно...

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

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

IhKa
Offline
Зарегистрирован: 08.05.2013

Хотелось бы более продуктивного совета. Думаю можно обойтись без сложной математики. Обычное деление строит график с похожей зависимостью.

Это датчик Холла, измеряет зазор в мм, где то 10-12мм.

Клапауций
Offline
Зарегистрирован: 10.02.2013

IhKa пишет:

Хотелось бы более продуктивного совета. Думаю можно обойтись без сложной математики. Обычное деление строит график с похожей зависимостью.

Это датчик Холла, измеряет зазор в мм, где то 10-12мм.

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

IhKa
Offline
Зарегистрирован: 08.05.2013

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

Michal
Michal аватар
Offline
Зарегистрирован: 26.04.2013

IhKa пишет:

Это датчик Холла, измеряет зазор в мм, где то 10-12мм.

вот поэтому и разброс

IhKa
Offline
Зарегистрирован: 08.05.2013

Ещё раз.

Никакого разброса нет. Есть закономерный прирост с квадратичной прогрессией. Нужно только преобразовать в линейный результат.

Никто с математикой не дружит что ли. Все только кнопки вкл./выкл. програмируют.

Клапауций
Offline
Зарегистрирован: 10.02.2013

IhKa пишет:

Ещё раз.

Никакого разброса нет. Есть закономерный прирост с квадратичной прогрессией. Нужно только преобразовать в линейный результат.

Никто с математикой не дружит что ли. Все только кнопки вкл./выкл. програмируют.

Ещё раз(с) - видели штангенциркуль с датчиком холла или другой измерительный инструмент?

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

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

IhKa пишет:

Требуется только гиперболу преобразовать в линейный график.

Ну так и преобразуйте... Уравнение гиперболы легко находится в интернете.

В чем проблема то?

IhKa
Offline
Зарегистрирован: 08.05.2013

Если мне покажут как замерить посредине толщину листа  2х2 метра штангенциркулем, то я перестану заниматься ерундой.

Гипербола, это грубая аналогия, чтоб было понятно о чём речь.

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

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

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

IhKa пишет:

Если мне покажут как замерить посредине толщину листа  2х2 метра штангенциркулем, то я перестану заниматься ерундой.

Самое простое и надежное - механическим индикатором.

Следующий вопрос в теме "Программирование" будет - "как закрепить индикатор" в произвольной точке листа? :)

IhKa
Offline
Зарегистрирован: 08.05.2013

У меня есть набор всевозможного мерительного инструмента, но как правильно заметили, это уже не в тему. Какая разница, вобще для чего это нужно, есть задача и её надо решить, даже если она просто так, для интереса. Кому то может пригодится.

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

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Я думаю вам надо построить график, а на него наложить какую либо фонкцию. Проделывать это надо в математической программе MathCAD, MATLAB(если знать программу то достаточно пару кликов).

leshak
Offline
Зарегистрирован: 29.09.2011

IhKa пишет:

Ещё раз.

Никакого разброса нет. Есть закономерный прирост с квадратичной прогрессией. Нужно только преобразовать в линейный результат.

Вот это "в линейный результат" и мешает что-то сделать.

Вам нужно не "линейный результат", а "апроксимация функцией".

Грубо говоря: у вас есть набор намерянных пар-значений "показание-датчика - толщина".

Этот набор, представляет собой "дискретную функцию" (определена в определенных точках, но неизвестно ее значение между ними).

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

Имея такую функцию - вы уже подаете на ее любые  значения датчика, а на выходе - получаете толщину.

Значит вопрос стоит "как подобрать такую функцию". Тут мы гуглим либо "апроксимирование" (или учебники по математики), либо... берем какой-то "математический пакет", который умеет это делать.

Если и с мат. пакетами лень разбиратеся - гуглим их онлайновые варианты.

К примеру, у вас есть, такой набор "пар-значение"

{15.2,8.9},{31.1,9.9},{38.6,10.3},{52.2,10.7},{75.4,11.4}

Кормим его wolframalpha

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

-0.000414838 x^2+0.0782818 x+7.83381 (quadratic)

Ну, что-же берем ее и пишем что-то типа

double map_to_depth(int rawValue){
  return -0.000414838*rawValue*rawValue+0.0782818*rawValue+7.83381;
}

А потом пользуемся ей,что-бы прочитать значение датчика:

....
int rawValue=analogRead(A0);
double value=map_to_depth(rawValue);

Serial.print("Value=");
Serial.println(value);

 

Вот еще чуток примеров Wolfram|Alpha по-русски: Аппроксимация функций в Wolfram|Alpha

IhKa
Offline
Зарегистрирован: 08.05.2013

Спасибо, за более конкретные рекомендации, сейчас попробую.

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

IhKa
Offline
Зарегистрирован: 08.05.2013

Всё сделал, вывел формулу!!! Вот она:  X = 37000 / (Y+4) – 30  Лёгкая, простая и даже без дробных чисел в моём случае.

Объясняю методику подстройки формулы под свои показания:

Для начала скачиваем програмку для постройки графиков. Я скачал бесплатную для частного использования "Advanced Grapher". Настройка программы сводится к установке пределов по осям в меню "графики - свойства документа", иначе график может оказаться за пределами видимости. Затем выбираем значок "добавить график таблицы" и вводим замеряные показания. У меня по X - мм, а по Y - показания датчика. Для точности 0,1 мм вводим по X не в мм, а в десятых миллиметра, то есть не 1,2,3… а 10,20,30…  и жмём ОК. Получаем график на основе наших данных. Далее выбираем значок "добавить график" и вводим мою формулу, должно получится: X(y)=37000/(Y+4)-30. Жмём ОК. Появляется второй график. Меняя число 37000 увеличиваем/уменьшаем участок изгиба графика, пока он не совпадёт с первым графиком. Меняя числа +4 , -30 перемещаем график левее-правее, выше-ниже. Наша задача уложить его точно на первый график. Уложив, ещё точнее подгоняем изгиб, затем снова положение, пока графики не совпадут максимально. У меня чуть-чуть концы разошлись, но это мизерная погрешность. После этого в формуле и будут ваши значения.

Только что проверил на практике, всё работает!!!  Магнитная линейка на эффекте Холла - круто )))

Метод применим и к другим типам датчиков, дающих нелинейный прирост показаний.

pit_student
Offline
Зарегистрирован: 05.01.2022
const float data[][2] PROGMEM = {
// ADC mv, ток  
  {00, 03},
  {10, 11},
  {20, 22},
  {30, 35},
  {40, 46},
  {50, 58},
  {60, 63},
  {70, 79},
  {80, 97},
  {90, 109},
  {100, 119},
};

void setup() {  
  Serial.begin(9600); 
  range(1.47); 
}

void range(float val){
float search = 0;
float min = 0;
float max = 0;   
for (byte i = 0; i < 11; i++){
 search = pgm_read_float(&data[i][0]);
 if(val <= search){
    max = search;
    float val_max = pgm_read_float(&data[i][1]);
    i=i-1; 
    min = pgm_read_float(&data[i][0]);
    float val_min = pgm_read_float(&data[i][1]);
    Serial.println();
    Serial.print("значение ");
    Serial.print(val);
    Serial.print(" попадает в диапазон: ");
    Serial.print(min);
    Serial.print(" - ");
    Serial.println(max);    
    float t = (max-min)/(val-min);
    float r = ((val_max-val_min)/t)+val_min;
    Serial.print("значение по таблице: ");
    Serial.println(r,3);
    return;}       
  }  
}
 
void loop() {
  }

 

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

pit_student, это что такое было в теме 8летней давности?

pit_student
Offline
Зарегистрирован: 05.01.2022

Тема актуальна в связи с дефицитом полупроводников. Приходится использовать не самые лучшие датчики, которые не отличаются линейностью.  Кому надо пусть пользуются. 

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

код кривоватенький, например при входном значении val = 0 будет выход за границы масива и на выходе фигня

pit_student
Offline
Зарегистрирован: 05.01.2022
значение 0.00 попадает в диапазон: 0.00 - 0.00
значение по таблице: 0.000
 
 
значение 0.01 попадает в диапазон: 0.00 - 10.00
значение по таблице: 3.008
 
 

 

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

pit_student не стоит спорить, если не видите сути своего(своего ли?) кода - тогда просто слушайте

при входном значении 0 у вас поиск сработает на первой же строке, при этом итератор цикла for i будет равен чему? - нулю. А дальше вы из этого нуля в строчке 30 вычитаете единицу и пытаетесь использовать полученное значение как индекс массива. Что получается на выходе? - фигня

 

А то, что вы этот элементарный код считаете настолько нужным, чтобы поднимать ветку восьмилетней давности - уже говорит о том, что в программировании вы человек новый :)))

 

 

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

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

Да и кроме того, это конечно хорошо, что таблица в прогмем, прям прорыв... Только вот может имело смысл обойтись 16 или 8 битными данными, ацп один хрен всего 10 бит ?

pit_student
Offline
Зарегистрирован: 05.01.2022

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

IhKa
Offline
Зарегистрирован: 08.05.2013

Спустя время, для информации: для подобных целей, как мне понадобилась тогда, сейчас выпускаются датчики Холла с линейными характеристиками, со всеми термо и токо стабилизациями и стоят копейки. Схожи с теми, что стоят в датчиках тока на эффекте Холла. Например SS49E