День отладки

Сижу на работе, медленно втухаю в интренеты, медитируя на то как комплектуха ко мне едет. Тут звонит заказчик и говорит, что мол у них мною разработанные девайсы не работают. Да ладно? А почему я об этом узнаю только сейчас? А не когда я их вам сдал еще в мае? Кто кипятком ссал и говорил, что ему срочно срочно? Два месяца прошло, а все еще срочно? Впрочем, теперь, наверное, действительно срочно. А они только соизволили их смонтировать в установки и проверить.
Присылает видео, по видео пляшут показания датчика давления. Хорошо так пляшут, с нуля до 65 очков.

Хм. Собираю из говна и палок и недоделанных плат еще один экземпляр того же устройства. Прошиваю. Втыкаю вместо датчика резистор. Там токовая петля от 4 до 20мА и резистором можно вполне годно эмулировать датчик. Все работает. Глюков не вижу. Прошу привезти датчики. Привозит, втыкаю — пляшет. Хм. Может датчик говно? Беру швейцарский, прецизионный — вешаю, пляшет, но уже сильно сильно реже. Ставлю резистор — стоит ровно. Странно…

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

Мда. Лезу в код. 90% его писал не я и он достался в наследство. Благо написан был в целом неплохо, был понятен и легко модифицировался. В подсчете данных с АЦП я ничего не менял, я добавил только обработку одного канала. Что это может быть? Перехлест каналов АЦП? Такое у меня уже было, когда из-за ошибки в коде перепутались каналы АЦП и чтение было со сдвигом. Тут же вроде все ровно. Тем более с резистором все ок работает, напряжение по второму каналу тоже отлично замеряется.

Создаю отдельный бранч, делаю вывод всего что можно на экранчик, чтобы видеть в реалтайме как оно меняется. Замер тока почти эталонный. Стоит не шевелится. А вот давление скачет. Пересчитал коэффициенты. Добавил больше усреднения. Все равно сработка защиты. Хм… срабатывает оно на 65 очков. А почему вдруг 65? Случайность? А может переполнение?

Добавил в функцию запроса давления отладочную строку, которая записывает максимальное давление которое прошло через функцию. Т.е. все запросы которые выполняются сравниваются с предыдущими и берется максимальное значение. Точно. Давление, в чистом виде, выловилось как 65525. Переменная uint_16t. Характерно. А это уже очень похоже на результат переполнения. Опять смотрю в код:

uint16_t PressureSensorGetPressure(void)
{
	if (ADC_GetValue_ma_x100() < 400) return 0;
	uint32_t Temp = (ADC_GetValue_ma_x100() - 400) * (HC_PRESSURESENSOR_VPI / 16);
	return Temp;
}

Хм, вроде переполнения не должно быть. Значение заранее обрезается по 400 (4мА токовой петли, нижняя граница). Вот только...

uint16_t ADC_GetValue_ma_x100(void)
{
uint32_t Integrator = 0;

	for (uint8_t i = 0; i < cADC_INTEGRATOR; i++)
			{
			Integrator += MeasuredValues[i];
			}
	Integrator /= pADC_Calibrate_K2;

	Integrator *= pADC_Calibrate_K1;


return Integrator;
}

Раньше наполнение буфера делалось вручную, в главном цикле. А у меня с добавлением нового канала это было вынесено в прерывание. И после того, как были отсеяны значения ниже нуля шины, ниже 400, вычитание смещения (-400) могло вывзвать косяк, т.к. делалось это с повторным пересчетом буфера, а он мог измениться в прерывании. И возле нулевых значений, который давал подключенный датчик, не нагруженный на давление, это хаотично вызывало переполнение. А вот на резисторе ток был примерно в середине диапазона, примерно на 70 атмосфер и там в переполнение уйти не могло. Сделал одно чтение буфера и проблема исчезла. Бонусом стал отлаженный аналоговый тракт и повысившаяся точность измерний.

Запись опубликована в рубрике Мастерская. Добавьте в закладки постоянную ссылку.

7 комментариев: День отладки

  1. koc9ti говорит:

    Типичный TOCTOU рэйс

    • DI HALT говорит:

      Ага. Поэтому я всегда стараюсь делать использование вывода функции через Temp если оно множественно используется.

  2. Ghiotto говорит:

    рэйс рэйсом но вообще вызывать дважды «тяжелую» функцию для получения одного значения, да еще и рядом — это должно быть запрещено в подкорке :-) впрочем, многие вещи туда попадают пока сам по граблям не походил

    • DI HALT говорит:

      Есть там местами такая хренота. Вроде бы код написан хорошо, очень читаемо и логично, видно опыт. Но порой вот такое вот.

  3. McHummer1 говорит:

    А под какой микрик этот код? stm32?

  4. vam говорит:

    В очень былые времена «микриком» был только микропереключатель ;)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.