Перейти к содержанию

Вопросы от начинающих по МК


Рекомендуемые сообщения

Сделал, но почему то я получаю на 1 больше. 

Передаю 2, получаю 3, и так далее.

Решить проблему просто

void in_bit_port()
{
	unsigned int chislo-1 = 0x0F&(~PINC);
  	chislo = chislo - 1;
}

Но подозреваю что не так.

10 минут назад, IMXO сказал:

накой это загонять?

Функция на много больше приведенного кусочка. 

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов
  • Создана
  • Последний ответ

Топ авторов темы

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

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

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

Подкинете совет??

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

Продолжаем серию тупых вопросов от "начинающего" с пятилетним стажем :D

Усредняю даные АЦП. Использую скользящее среднее.

#define N (6)
uint8_t chanal = 0;

void adc_usred(uint8_t chanal)
{
	uint16_t value = get_value(chanal);
	static uint16_t m[N], n;
	m[n] = value;
	n = (n + 1) % N;
	value = 0;
	for(uint16_t i = 0; i < N; i++)
	{
		value = value + m[i];
	}
	
	value = value/N;
}

Вроде скользит и работает. Возник вопрос. А если в шум АЦП, проскочит какой то "КОНЬ", то он сильно изменит весь массив.

Как избавиться от скачка?

Пример: 

(243 + 245 + 243 + 240 + 241 + 244) / 6 =  242 (это без коня)

а вот с помехами:

(243 + 260 + 243 + 240 + 358 + 244) / 6 =  264 (Пробежал табун, истоптал пшеницу)

Явно видно что от весомых помех не избавились. Как быть?

Ссылка на комментарий
Поделиться на другие сайты

Увеличивать окно, например. Чем больше окно тем меньше влияние аномальных элементов.

Ещё можно применять оконную функцию - перед суммой сортировать массив и брать средние 90% отсекая первые и последние элементы.

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

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

Изменено пользователем si4karuk
Ссылка на комментарий
Поделиться на другие сайты

34 минуты назад, si4karuk сказал:

Усредняю даные АЦП. Использую скользящее среднее.

может напильником доработать?

Скрытый текст




#define N (6)
uint8_t chanal = 0;

void adc_usred(uint8_t chanal)
{
	uint16_t value = get_value(chanal);
        static uint32_t symm 
	static uint16_t m[N], n;

        symm -= m[n];
	m[n] = value;
        symm += value;
	n = (n + 1) % N;

	value = uint16_t symm/N;
}


 

Ссылка на комментарий
Поделиться на другие сайты

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

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

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

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

Ссылка на комментарий
Поделиться на другие сайты

4 часа назад, IMXO сказал:

может напильником доработать?

  Показать содержимое

 




#define N (6)
uint8_t chanal = 0;

void adc_usred(uint8_t chanal)
{
	uint16_t value = get_value(chanal);
        static uint32_t symm 
	static uint16_t m[N], n;

        symm -= m[n];
	m[n] = value;
        symm += value;
	n = (n + 1) % N;

	value = uint16_t symm/N;
}

 

 

 

 

А зачем вы еще раз обьявляете переменную? 

value = uint16_t symm/N;

 

Ссылка на комментарий
Поделиться на другие сайты

16-ю битами суммы можно обойтись только для массива менее 64 элементов, дальше возможно переполнение.

11 час назад, si4karuk сказал:

я совсем не знаю сколько, когда и какие бяки могут проскочить в АЦП в момент измерения

С этого как бы и начинают, выбирая методы фильтрации "помех". Универсального фильтра на все случаи жизни(Хотя фильтр калмана близок к идеалу) не существует, а у существующих есть свои достоинства и недостатки. И особенно при ограничении со стороны железа приходится тщательно выбирать и идти на компромиссы.

В своё время, мне надо было отфильтровать измерения для показа напряжения на цифровом индикаторе. Значения снимаются с частотой 100Гц синхронно с сетью, сначала проходят через простое усреднение по 8 значений, потом через окно в 16 значений(результат потом делить удобно сдвигом). В итоге всё работает очень даже плавно(я бы даже сказал по плавности как стрелочный прибор). Часть выбросов срезается ещё на первом простом усреднении, а то что прошло выравнивается через подвижное окно. Инерция отображаемых значений составляет около полусекунды, сравнимо с человеческой реакцией, а первоначальная реакция на изменение входного напряжения - практически мгновенно(на самом деле около 80мс, геймеры наверно заметят).

Учение - изучение правил. Опыт - изучение исключений.

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Хочу писать step вместо pinc5

#define step pinc5

Как его теперь писать в с++

Нужно проверить на наличие 1 на входе if (step=1)

 

 

 

 

 

 

Нужно проверить на наличие 1 на входе if()

Ссылка на комментарий
Поделиться на другие сайты

19 минут назад, Дмитрий Мамедиев сказал:

Как его теперь писать в с++

#define STEP PINC5
#define STEP_PORT PINC
...
if (STEP_PORT & (1 << STEP)) { // STEP_PORT & _BV(STEP)

}

как то так

Ссылка на комментарий
Поделиться на другие сайты

3 часа назад, Дмитрий Мамедиев сказал:

А что значит _BV где про это почитать

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

STEP_PORT & (1 << STEP)
STEP_PORT & _BV(STEP)

То есть это аналоги, значит 

_BV(STEP) == (1 << STEP)

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

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

#define BitIsSet(reg, bit)  ((reg & (1<<(bit))) != 0)
  
void main() {
	if (BitIsSet(PINC, PINC1)) {
      
    }
  
  	if (BitIsSet(PINC, PINC2)) {
      
    }
  
	if (BitIsSet(PINC, PINC3)) {
      
    }
}

Развернется в 

void main() {
	if (((PINC & (1<<(PINC1))) != 0)) {
      
    }
  
  	if (((PINC & (1<<(PINC2))) != 0)) {
      
    }
  
	if (((PINC & (1<<(PINC3))) != 0)) {
      
    }
}

То есть строка с define не будет скомпилированна вообще, но она подставиться во все места где было к ней обращение.

Ну точнее он развернется еще больше, так как PINС, PINC1, ... это тоже макросы, и они тоже развернутся, то есть 

1 << (PINC2)
// развернется в 
1 << 2
// так как PINC2 определен как PINC2 2

 

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...