Alexeyslav

Members
  • Публикации

    10 796
  • Зарегистрирован

  • Посещение

Репутация

644 Очень хороший

2 подписчика

О Alexeyslav

  • Звание
    Старожил

Контакты

  • ICQ
    156858425

Информация

  • Пол
    Мужчина
  • Город
    Украина, Славутич

Электроника

  • Стаж в электронике
    10-20 лет
  • Сфера радиоэлектроники
    микроконтроллеры
  • Оборудование
    осциллограф OWON SDS7102,
    генератор SIGLENT SDG1025,
    мультиметр UNI-T UTM1139С,
    стационарный мультиметр UNI-T UTM1804,
    измеритель RLC CHY FIREMATE 41-R,
    Паяльная станция UIHUA 995D+

Посетители профиля

30 831 просмотр профиля
  1. Склейка переменных типа int в си в CodevisionAVR

    Какой-то мусор. Вроде же задача не такая сложная. Считать значение напряжения при помощи АЦП, пройтись по таблице посмотреть в какой из диапазонов попадает измеренная величина и получить номер клавиши которую нажали, или сделать вывод что ни одна не нажата. Это часть дела. Всё бы хорошо, но нам надо знать не только тот факт что в некий момент клавиша была нажата, но нам нужно отследить момент нажатия и отпускания. И заодно избавится от неопределённости одного момента. Ведь с некоторой вероятностью считывания может произойти в момент наличия помехи или момент перехода в момент нажатия кнопки. Поэтому как минимум нужно пропустить определённые нажатые кнопки через фильтр - принимать во внимание номер нажатой кнопки только если два последовательных измерения на расстоянии не менее 10мс друг от друга дают одну и ту же кнопку. Кстати, для начала можно это всё(измерение-поиск_по_таблице-определение номера кнопки) уместить в одну функцию и в дальнейшем работать с ней. Назовём её ReadKey у которой на выходе, скажем, будет номер удерживаемой кнопки 0...9 или число больше 10 означающее удерживание какой-то ещё кнопки, или отсутствие нажатия(например, число "-1"). С этой абстракцией будет уже гораааздо легче работать в дальнейшем. И так, допустим у нас есть бесконечный цикл(который обычно называют главным циклом программы, или суперлупом) в котором мы каждые 10мс вызываем процедуру ReadKey. И очень важно, чтобы это делалось с интервалом не менее 10мс(ну или 100мс, как удобней или надо будет посмотреть подобрать по отзывчивости на нажатие и количества ложняков). Что нам теперь осталось сделать чтобы избавится от помех и дребезга? Да просто сравнить только что считанное значение с предыдущим, которое предусмотрительно будет сохранено в конце основного цикла, ну или не в конце - главное чтобы не ранее кода обработки клавиатуры. Сравнили, если оно равно - значит его можно принимать в дальнейшую работу, если не равно - идем на следущую итерацию, не забыв сохранить значение нажатой кнопки как предыдущее. Теперь нам надо выделить "фронты". Это делается аналогично предыдущему коду - запоминаем предыдущее очищенное от дребезга значение и сравниваем с текущим. Тут уже есть 4 разных варианта. 1) текущее и предыдущее = "не нажато"(-1?) - ничего не делаем. 2) предыдущее значение = нет клавиши, текущее = <№кнопки> - это собственно сам момент нажатия, а номер нажатой кнопки понятно где брать. 3) предыдущее значение = <№кнопки>, текущее = "не нажато"(-1?) - это момент отпускания кнопки и 4) предыдущее значение = <№кнопки>, текущее = <№кнопки> - состояние "нажатия" кнопки и нам тоже НЕ ИНТЕРЕСНО, причем номера кнопок МОГУТ отличаться, когда не отпуская одну кнопку нажимаешь вторую потом первую отпускаешь - код от этого ломаться не должен и поведение программы должно быть определённым. Вот собственно и вся хитрость работы с кнопками. Лучше всего регистрировать нажатие кнопки по моменту её отпускания, для ввода а командные кнопки - по моменту их нажатия. Как потом вводить цифры? Ловить моменты нажатия запоминать кнопку и переходить на следущую позицию ввода по отпусканию. В эти моменты, можно ставить "флаги" которые потом будут обрабатыватсья в программе. Например флаг "кнопка нажата", в основном цикле смотришь - появился флаг "кнопка нажата" значит надо отреагировать на неё, выполнить код и снять флаг.
  2. Всё что может поставить пользователь - это указать максимальную мощность. А меньше - ставит прошивка радиомодуля по согласованию с роутером. Причем исправить это поведение уже нельзя, эта часть прошивки идет напрямую от производителя в виде двоичного обфусцированного BLOB-а который стандарты соблюдает и не хочет раскрывать внутренние алгоритмы. Что-то поправить можно было только в модулях 10-летней давности, а сейчас - обфусцированные зашифрованные блобы от производителя и хоть что хочешь то и делай.
  3. Ставится ограничение максимальной мощности. А радиочастотная часть только руководствуется этим значением и выбирает меньшую мощность когда это нужно. Иначе модуль не прошел бы тест совместимости, будучи расположенным возле роутера он тупо забъёт всех остальных перегрузив входной усилитель роутера.
  4. Наверно возле роутера делал тесты? Клиент с роутером договариваются об уровне мощности, естественно возле роутера клиентское устройство может снижать мощность и соответственно потребляемый ток.
  5. Склейка переменных типа int в си в CodevisionAVR

    Вы что-то катастрофически делаете не так. Какой поток, какой резануть? Где вообще могут быть какието проблемы в алгоритме - запустил-подождал-считал? Какие нули? с символами ВАМ работать как раз не нужно, вам их потом обратно в числа превращать... работайте сразу с числами 0...9 а всё остальное считайте NAN. чтобы набыло бесконечных 5-5-5-5-5-5-5 вам надо отслеживать установившиеся ИЗМЕНЕНИЯ. Было "отпущено" стало 5 - это изменение, нажатие кнопки. было 5 стало 5 - кнопка ещё держится, нет изменений. было 5 стало "отпущено" - это отпускание кнопки. Но если делать это прямо с измерениями с АЦП будет проблема из-за дребезга и помех, поэтому чтобы получить устойчивое значение оно должно быть зарегистрировано как минимум 5 раз с периодом опроса АЦП скажем 2мс. И потом уже это знаение пропускать через алгоритм выше.
  6. Ионистор не успеет разрядится, он там для этого и стоит. Ну, просядет на десяточку вольта... какой ток с батарейки потом будет? Уж точно не 200мА. Но это касается лишь нормального ионистора. Сколько я не пробовал эти ионисторы на 0.47Ф-2Ф у них очень фиговое внутреннее сопротивление для 0.47Ф заявлено 70 Ом! В таких условиях вся ваша затея на смарку. Сам ионистор будет не лучше батарейки. на 120Ф ионистор пробовал, вот это да вещь... ни один из имеющихся приборов не смог померять его внетреннее сопротивление - оно меньше 0.01 Ома. И ещё один недостаток этих маленьких дешевых ионисторов - они за час-два разряжаются сами, высокий ток саморазряда. Поэтому, будете брать ионистор УТОЧНЯЙТЕ его характеристики заранее.
  7. Управления двумя шаговыми двигателями

    Небось висят на одном порту, и вы перезаписываете весь порт, портя соседние биты от второго шаговика? Вам надо прописывать биты по маске, чтобы остальные не портить. L298 - полумост(несколько полумостов в одном чипе), ULN2003 - просто отдельные транисторы с открытым коллектором. Шаговики разные есть, есть с двумя обмотками - им нужна мостовая схема, а есть с 4-мя обмотками с общим проводом, те управляются отдельными транзисторами(ULN2003).
  8. Склейка переменных типа int в си в CodevisionAVR

    Ничего не понял. Какой поток? Зачем поток? Запускаешь измерение, ждешь результат и работаешь дальше... вырезано-невырезано самому сделать нельзя? По даташиту... я этот Codevision в глаза не видел, поэтому ничего не подскажу. Может, там надо либу подключить? что за функция getch(), гуглил? аааа... это процедура ввода с консоли... а у тебя в МК есть консоль? драйвер клавиатуры? Откуда он будет знать что у тебя какая-то клавиатура есть и её конфигурацию? Чтобы такая функция заработала много чего должно быть реализовано, и соответственно у тебя ЕГО НЕТ И НЕ БУДЕТ. Если так уж хочешь, то возьми и реализуй сам эту функцию. Но тебе она не пойдёт, она по своей природе синхронная - пока кнопку не нажмешь не отпустит и весь контроллер стоять будет ожидая нажатия. Лучше подумай о варианте озвученном выше.
  9. CrystallOscilator - что то пошло не так.

    ICSP это всего лишь интерфейс, определённо он непричем. Более того он работает только со стороны хоста, контроллер на этот вывод ничего не выдаёт в режиме программирования. Надо смотреть альтернативные функции, их у каждого вывода по 3-4. SPI? Вообще странно что загрузчик так работает... Если контроллер стоит точно такой же, то можно попробовать прошить загрузчик программатором правильный, который по дефолту от ардуины идёт - IDE это позволяет сделать. И ещё по-хорошему, запитайте ардуину только от внешнего источника питания, НЕ от компьютера через USB. Есть ли в таком случае мигание?
  10. Склейка переменных типа int в си в CodevisionAVR

    Если бы в Си был аналог, он бы не назывался С++. Это всё относится к тем вещам, которые способны сэкономить время разработки решения. Но если вы не знаете/не понимаете как это работает то значит просто ещё не столкнулись с теми проблемами которые эта штука призвана решать. Например со сложностью проекта. Почитал про union, понял что это такое. В паскале эта штука тоже есть только по другому реализуется. Использовать надо с великой осторожностью и полным пониманием. Иногда эта вещь весьма полезная. например, можно объявить объединение int64 и массива в 8 байт. Теперь вы легко можете принимать по UART данные побайтно и восстанавливать в памяти 64-битное число просто записывая поверх его байты, обращаясь к байтовому массиву. Можно, конечно, взять указатель, и обращаться к этой структуре побайтно... но в таком случае это будет не очевидно, не наглядно, безконтрольно и достаточно уязвимо к программным ошибкам.
  11. Не замечал ни разу за разумный ценник. Или батарейки меняй каждые 2-3 месяца. Неужели на рынке есть внешний термодатчик по цене меньше 10$ и не требующий замены батарей вообще никогда?
  12. Склейка переменных типа int в си в CodevisionAVR

    Всё это как-то костыльно выглядит, когда можно сделать по нормальному. Ардуинки достаточно дешёвые, не хватает одной - поставь две. Есть кстати шилды с клавиатурой для ардуины. 5000 выборок для клавиатуры, это чрезмерно. там и 100 выб/сек хватит. Симуляторы... они с ошибками и слишком порой идеальны, на практике всё совсем по другому выходит. Эффективно использовать симуляторы можно только зная все ньюансы и в симуляцию выносить только то что точно там не будет искажено.
  13. CrystallOscilator - что то пошло не так.

    Так посмотри что это за вывод контроллера, может это UART и загрузчик туда отладку кидает.
  14. Не будет там тока в микроамперы если напряжение не снять. Все производители контроллеров заряда литиевых аккумуляторов думаете идиоты что отключают заряд по его окончанию? Аккумулятор ладно, будет расходником... только он расходником может стать вместе с квартирой если взорвется и загорится. Везде стараются не использовать литиевые аккумуляторы в буфферном режиме, ибо это чревато.
  15. Склейка переменных типа int в си в CodevisionAVR

    Симуляторы... Эх... измельчал народ. Для клавиатур больших есть внешние регистры, хоть 60 клавиш подключай. HC595 называются. У вас классическая проблема, вы не выделяете событие нажатия клавиши? у вас алгоритм крутится в бесконечном цикле, проверяет клавиша нажата? да - ввести и сдвинуть, следущая итерация - то же самое... и всё это проходит в миг глазом моргнуть не успеешь, поэтому и эффект такой на дисплее. Вам надо сначала с клавиатурой разобраться. Выведите например короткий "пик" на каждое нажатие кнопки, посмотрите как они у вас распознаются. Если будет постоянный писк в итоге - значит алгоритм работает ФИГОВО. Вам надо как минимум выделять устойчивые состояния нажатий кнопок и фиксировать их в течении 100мс, например. В варианте с АЦП проблема будет огромная при нажатии более одной кнопки, а их НАЖМУТ. Я бы для начала реализовал бы две процедуры - KeyPressed и ReadKey. Первая процедура - определяет нажата ли кнопка(читает АЦП, сверяет уровни и определяет какой кнопке соответствует уровень), обрабатывает возможный дребезг(ждет когда последние 10 измерений(или за период в 10мс) будут одинаковые) и выдаёт на лету результат: нажата кнопка или нет, если нажата - устанавливает признак нажатия причем исключительно только в момент перехода из состояния НЕ НАЖАТА в состояние НАЖАТА. ReadKey возвращает код последней нажатой клавиши(из переменной устанавливаемой в предыдущей процедуре) и СБРАСЫВАЕТ признак нажатия. В основном цикле уже просто и очевидно пользоваться этими функциями. Если KeyPressed возвращает false - проходим мимо, если true - вызываем ReadKey и делаем что-то в зависимости от кода клавиши.