Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: RSLK от TI (Robotic System Learning Kit)

Пт ноя 13, 2020 18:38:25

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

Зато, почитал сайт http://www.micromouseonline.com/ и выяснил, как действуют профессионалы. Они, оказывается, "ходят по квадратам". У меня робот идёт по линии и ждёт перекрёстка, поворота или тупика. У них же робот шагает по клеткам. И всё это делается на базе контроля двигателей. Их цель - точная повторяемость. Там даже было видео, как робот ходит "лесенкой" несколько кругов по лабиринту без стен и не сбивается, не съезжает. Но в "длинных коридорах" и тупиках роботы всё же корректируют своё положение.

Можно было бы мне тоже этим заняться... но есть разница. У нас клетки имеют размер 30х30см, а в этих "международных" соревнованиях 20х20см (минус 2 см толщина стен = 18 см, но шаг остаётся 20 см). В международных трассах эти размеры регламентированы (опорные стойки - держатели стен стоят ровно с шагом 200мм и у каждой стойки должна быть присоединена хотя бы одна стена, кроме "выхода"), а у нас - только примерно (в последнем лабиринте со стенами они вообще, могли сдвинуться, если робот их зацепит). Вот и не знаю под какой стандарт дома строить полигон. Хотя, RSLK однозначно в "международную" трассу не влезает. Поэтому, у меня намечается проект, сделать маленькую модельку 12-14 см шириной и на STшном микроконтроллере.

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

Правда, с SPI EEPROM у меня тоже, как выяснилось, не всё хорошо. Оказалось, я зря игнорировал флаг UCOR - overrun. Оказалось, что микроконтроллер не успевает обслужить в прерывании всё байты приходящие со скоростью 1 мегабит в секунду. Изредка, (какой к черту "изредка" - чуть ли не каждый десятый раз!) терялся один или несколько байт. Был сделавши тестовую программку, которая считывала два раза 4кБ из ПЗУ и сравнивала считанное. Ошибки перестали появляться на скорости 750КБ/с. Но тут я крутанул колесо, чтобы появились прерывания от таходатчиков и... ошибки вернулись. В общем, сбавил скорость до 512КБ/с и контролирую этот флаг - если пропал байт - операция повторяется по-новой. Так что у меня пока нет уверенности, что всё с этим EEPROM работает как надо. Возможно, мой подход не правильный.

p.s. Был создавши тикет по поводу новой версии файлов лабораторных работ. Вот только получил ответ:
Good day, apologies for the late response. With regards to your query, as of now, the latest software for TIRSLK-EVM-SW is in this link (https://www.ti.com/tool/TIRSLK-EVM-SW).

There is no information regarding new version of this software.

I hope the information provided pleases you. If you still have other concern, please let us know by replying to this email.
Называется - "стандартная отписка".

Re: RSLK от TI (Robotic System Learning Kit)

Ср ноя 18, 2020 15:04:29

Так как я забросил linefollower-ы и снова начал заниматься лабиринтом есть интересные данные. Но о них чуть позже.

Пока же я роботу для лабиринта переделал часть, измеряющую напряжение батареи. Делитель подключил через повторитель на ОУ. А еще, когда прошлый раз писал этот модуль, заметил, что каждый канал АЦП можно обрабатывать по разному. Поначалу, я делал опорным напряжением напряжение питания, которое примерно 3.3в, в целях совместимости с дальномерными модулями Sharp. Но потом, решил что каналу для оцифровки напряжения батареи, я могу подключить внутреннее опорное напряжение 2,5в, оставив для каналов, куда подключены дальномеры всё те же 3,3в питания в качестве опорного. Для этого перепаял делитель напряжения с 1:3 на 1:4, так что максимальное напряжение будет 10в. Самое смешное, не пришлось даже менять коэффициент коррекции (вернее пришлось вернуть ему значение 100) для вычисления отображаемого напряжения. После чего решил, гулять так гулять! У этого АЦП есть еще два "окна сравнения" и если значение какого-либо канала, которое подключено к этому "окну" выходит за пределы - возникает прерывание. Ну я прерывание не разрешал, а просто проверяю его флаг. И если в процессе работы напряжение на батарее просядет ниже 7 вольт, я об этом узнаю по этому флагу. Ну это был successful story.

А теперь продолжается поиск утерянных коэффициентов ПИД регулятора двигателя. Правда, я решил взять за основу статью с сайта micromouseonline. Там статья описывает, что параметры системы, если нельзя рассчитать, то можно измерить. А в следующей статье написано, как зная параметры, вычислить коэффициенты ПИД-регулятора. Я создал небольшой проектик в CCS, который включает двигатели и просто фиксирует по 2048 срабатываний таходатчика с каждого колеса и записывает их сначала в память, затем, в ПЗУ. Данные откуда я потом вытаскиваю в электронную таблицу для анализа. Таким образом, я прогнал робота с 3 значениями PWM и записал, какие RPM у меня получились.
Код:
25%   3750   57rpm   75-80ms
50%   7500  124rpm   65-90ms
75%  11250  187rpm   70ms
Прикинул на калькуляторе ( у меня не настолько прямая линия получилась, как у авторов статьи), получил, что Km=1.74 (1,74, а не 0,0174, потому что роботу задаётся скорость в RPM умноженная на 100 ) Tm=70ms. Немного смущает очень маленькая постоянная времени. В результате, коэффициент пропорциональности получился 270. Деривативный коэффициент я не считал, так как у меня учитывается только интегральная составляющая, а дифференциальная равна 0, по причине сильной "зашумлённости" получаемых данных от таходатчика (и, соответственно, бесполезности для регулирования этих данных).

Проблема возникла в правом двигателе при питании 75% ШИМ... Когда я снятые из памяти данные загрузил в электронную таблицу, я не увидел привычную обратноэкспоненциальную кривую, хоть и размазанную, а просто линию около оси координат и 5-6 всплесков. Посмотрел на величины этих всплесков - они на два-три порядка превышали ожидаемые значения.

Сначала думал, что это из-за запаздывания прерывания по переполнению счетчика. дело в том, что захват работает на 16-битном таймере с частотой тактирования 12МГц. Понятно, что счетчик будет переполняться каждые 5,4мс и этого времени ну никак не достаточно для проведения измерений. Поэтому старшие 16 бит я считаю в прерывании по переполнению. А так как прерывание по захвату имеет более высокий приоритет, чем прерывание по переполнению (которое имеет самый низкий приоритет), может быть так, что программе записывающей данные передаётся актуальные младшие 16 бит и устаревшие старшие 16 бит. Но, посмотрев, на захваченные данные - это явно не та ситуация. Удалив с графика данные правого двигателя, посмотрел данные левого - они нормальные и ожидаемые. Пройдясь, по данным правого двигателя и выбросив неверные данные - остальные тоже имеют аналогичный вид. Хм, в чем может быть причина? Может, неисправность таходатчика? Попробовал поменять двигатели с таходатчиками местами (благо это делается легко - двигатели соединяются штыревым разъёмом и держатся на защелках) - увы, правый как давал странные значения, так и продолжает давать.

Анализируя код, эти каналы (левый и правый) различаются прерываниями. По разводке получилось, что левый канал захватывается CCR0, а правый CCR1. А у таймера MSP432, прерывание для нулевого канала идёт отдельно, а все остальные прерывания от этого же таймера, как то: захват/сравнение от CCR1, CCR2, CCR3, CCR4 и переполнение счетчика - отдельно. Ну решил, попробовать, вместо таходатчика подключить контрольный источник импульсов. Не мудрствуя лукаво, вынул из робота плату Ланчпада и проводами соединил выход PWM двигателя и вход захвата таходатчика. Подавал импульсы с периодичностью, соответствующей разным оборотам - дошел до 250rpm - во всех вариантах и по обоим каналам - прямая линия. Нет ни потерь, ни ложных данных. Т.е. причина не в программе.

Следующим на подозрении... или пропадание контакта или помехи. Попробовал двигатель вынести на проводках - выбросы есть, хотя и не такие впечатляющие. Вот как выглядит фрагмент:
Изображение
столбцы A,B - захваченные значения для левого и правого. C,D - разница с предыдущим значением, E,F - RPM*100 вычисленный из разниц, G,H время в миллисекундах (A/12000, B/12000), Столбец I,J (жаль J не виден) - значение AиB в шестнадцатеричном виде. Подозрительные значения выделены красным - они и вызывают эти пики на графике.

Еще пробовал ручками крутить колёса - не подавая питание на двигатели - всплески обнаружены пока не были. Неужели помехи таходатчикам даёт двигатель? Но почему только правому?

Вот "всполошившая" меня картинка - ожидаемые значения должны быть в районе 20000.
Изображение

Кстати, заметили? Вот еще кусок графика, когда я робота катал по полу без питания двигателей:
Изображение
Отсчеты дают четкую "зубчатую" форму с периодом в 3 отсчета. Это к размышлению о том, насколько точно даёт импульсы шестиполюсный магнитный диск. И вот не знаю или это по причине неравномерности намагниченности диска или неравномерности вращения якоря электродвигателя из-за его трёхполюсности. Еще, посмотрел, что за датчики холла ставят на эти таходатчики. Точно нигде не написано, но написан возможный тип и этот тип как раз того сорта что с триггером - так что можно успокоиться, оказывается, об этом люди уже подумали.

Так что я сейчас сижу и думаю, откуда эти искажения данных.

Ну и для развлечения видео: мой робот изучает лабиринт:

Re: RSLK от TI (Robotic System Learning Kit)

Вс ноя 22, 2020 15:00:48

Итак, у меня день прямого доступа.

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

Ну, теперь надо делать то, что я делал полтора года назад, только в обратном направлении. Тогда я уходил с CSS на Кейл, теперь ухожу с Кейл обратно на CSS - здесь я тоже превысил 32 килобайтный барьер. Похоже, что на Кейле у меня остаются только stm32f0, для которых есть бесплатный ключик, которым я могу теперь с чистой совестью воспользоваться. Ай нет, еще остался stm32f103...

Но, тем не менее, робота для лабиринта я перетащил обратно под CSS. Почти бес проблемно. Запускаю, вроде работает. Допилил командный интерпретатор, чтобы работал с разных интерфейсов, поправил команду вывода лог-файла. Вот с лог-файлом всплыла проблема, что опять не читается SPI EEPROM. Вроде должно было 16 килобайт прочитать за долю секунды, а приходится ждать несколько секунд. Ну да, я же не включил оптимизацию и наверняка, прерывания снова не успевают выбрать данные из SPI. Повышаю оптимизацию - вообще всё перестало работать. Ладно, не всё - проблема оказалась снова в коде под авторством Валвано, которая делает задержки. У меня при инициализации есть пара задержек на пару милли и микросекунд, так вот они становятся ненормально большими. Что в этом коде не так?
Код:
// delay function
// which delays about 6*ulCount cycles
// ulCount=8000 => 1ms = (8000 loops)*(6 cycles/loop)*(20.83 ns/cycle)
  //Code Composer Studio Code
void delay(unsigned long ulCount){
  __asm (  "pdloop:  subs    r0, #1\n"
      "    bne    pdloop\n");
}

// ----------
// Simple delay function which delays about n microseconds.
// Inputs: n, number of us to wait
// Outputs: none
void Clock_Delay1us(uint32_t n){
  n = (382*n)/100;; // 1 us, tuned at 48 MHz
  while(n){
    n--;
  }
}
 

// Simple delay function which delays about n milliseconds.
// Inputs: n, number of msec to wait
// Outputs: none
void Clock_Delay1ms(uint32_t n){
  while(n){
    delay(ClockFrequency/9162);   // 1 msec, tuned at 48 MHz
    n--;
  
аргумент надо было обозвать волатильным?

Миллисекундные задержки сделал по-своему, через прерывания SysTick (500мкс), надо бы еще с микросекундными задержками разобраться.

Но всё-равно с SPI EEPROM надо что-то делать. Иного выхода, как использовать DMA - я не вижу. Уже созрел к тому, чтобы перед каждым массивом обменивающимся с EEPROM добавить 4 байта, куда можно вписать команду чтения из EEPROM и пусть ПДП пишет там потоком. Поэтому засел за чтение описания ПДП. Конечно, странно выглядит это ПДП - часть конфигурационных данных надо размещать в ОЗУ, указывается конечный адрес передаваемых данных, но не начальный. Ну и не могу найти в заголовках структуры контрольных слов (кастить магическими числами - не моё). А все примеры, что находил в интернете - все с использованием какой-то driverlib.

Пошел читать про driverlib. Ого, штука занятная. Самое интересное, в том, что в отличии от ST-шного HAL (и наверняка других библиотек), оно не ест память! Не, чудес, конечно, не бывает. Просто объектный код этого driverlib уже находится в ПЗУ микроконтроллера - жёстко прошит. Так что один плюс есть. Начал изучать примеры. Для этого взял 11-ю лабу - подключение OLED дисплея и попытался сделать там SPI через DMA. После некоторого разбирательства, что на что влияет, данные удалось передать. Теперь этот же метод перенёс в фирмварь для робота.

А вот с EEPROM получился облом. Когда разглядывал структуру контрольного слова канала, оказалось, что на количество передаваемых данных отведено всего 10 битиков (а в RM нарисовано только 9. И еще в одном месте было, что вместо 5 бит нарисовано 4 ;-) ), т.е. контроллер может сделать максимально 1024 DMA transfers. Т.е. мечта о том, что я хопом считаю 16 килобайт - развеялась в прах. Потому как, хоть раздел в reference manual и называется громко DMA, на самом деле там uDMA - микроDMA. А про то что микроDMA имеет такое ограничение, я уже читал, когда занимался с EFM32. Так что пока размышляю, какой выделить буфер обмена. У меня для записи в EEPROM уже есть буфер в 260 байт (256+4) - так как за раз можно писать одну страницу в 256 байт. Или для чтения выделить еще 1028 байт? Наверное, останусь на тех 260 байтах. Ну а для копирования из буфера обмена в массив, снова можно применить ПДП. ULP advisor об этом постоянно напоминает.

Re: RSLK от TI (Robotic System Learning Kit)

Сб ноя 28, 2020 22:05:35

Продолжил борьбу с DMA. После такого счастливого запуска дисплея, думал, что с памятью всё будет так же легко. Однако, целый день убил, но так и не смог получить ни одного отправленного байта, не говоря уж о принятом. Вот, разглядывая эту таблицу, подумал, раз уж EUSCI_A3 занял шестой канал, то для EUSCI_B3 я мог бы выделить 4 и 5: eUSCI_B3 TX3 и eUSCI_B3 RX3
Изображение
Правда, что вот эти TX3 и RX3 означают как-то не догадался и в тексте пояснений не было. После того, как у меня ничего не вышло, пошел в гугл искать причину. Нашел. Оказалось, на форуме e2e.ti.com кто-то тоже назначил TX2 и у него тоже не работало. Но было предложено использовать TX0. И там был приведен скриншот с референс мануала про i2c slave (но DMA там упомянут не был). И тогда я вспомнил... что i2c slave может изображать несколько адресов. Так вот эти TX1, 2, 3 - это для них. Т.е. работают только в случае i2c slave, но не i2c master или SPI. Т.е. у меня конфликт каналов. EUSCI_B3 и EUSCI_A3 имеют одинаковые каналы - 6 и 7. Поэтому решил отказаться от DMA для дисплея и сделать только для EEPROM. Опять что-то не так. В самом начале после сброса прекрасно читаются из EEPROM настройки, но чуть погодя, когда я из меню вызываю чтение log-файла - ничего не происходит. Под отладчиком вижу что проходит один байт и всё. Ну тут уж мой косяк был - когда "выключал" дисплей, я исправил функцию выводящую данные, но оставил инициализацию, а там я указывал, что 6-й канал подключается к EUSCI_A3. Поэтому до инициализации дисплея всё работало, а после - нет. Когда это понял, подумал, что я могу этот канал использовать для обоих, и eeprom, и дисплея. По-очереди. В общем, так и поступил и всё теперь работает.

Так же посмотрел в примерах driverlib как делается пересылка данных в памяти с использованием DMA и постарался все места, где ULP advisor мне указывает, что я поступаю не хорошо, копируя массивы в цикле, сделал перенос с использованием DMA. Даже в одном месте где мне нужно один массив проинициализировать значением 0xFFFFFFFF, это сделал с помощью ПДП. В одной переменной записал значение и затем из неё скопировал в весь массив.

Попутно, поднял скорость передачи данных для EEPROM до 4 мегабит в секунду. И тут подумалось, что я теперь могу журнал писать прямо в eeprom на ходу. Для этого сделал два буфера по 256 байт (страница, которая за раз может быть записана в eeprom), и пока один заполняется, второй пишется в eeprom. Потом они меняются местами. Черновик уже набросал, посмотрим, что получится. Хотяя, сейчас пишется всего 16 килобайт и этого хватает на 20 секунд, а тут у меня доступно будет 320к.

Есть сдвиги в "поиске" 21-й лабораторной работы. Удалось разъяснить, что я хочу и вот сделали тему в e2e.

Re: RSLK от TI (Robotic System Learning Kit)

Вс дек 13, 2020 21:07:33

На прошлой неделе свершилось! В пятницу вечером, как обычно заглянул на страничку TI на предмет проверки новой версии лабораторных работ и, смотрю, появилась! Правда скачать никак не удавалось - все линки выдавали ошибку. Но в воскресенье вечером, всё же прорвало и скачать удалось. Я был на той страничке поставивши "уведомлять меня об изменениях". Так вот уведомление пришло только во вторник. Поэтому всю неделю занимался этими и прежними лабами. Так как до сих пор не знаю как перетащить солюшены из предыдущей версии - всё это делаю вручную, вдумчиво повторяя пройденное. Потому как, часть старых файлов требуется, чтобы работало что-то новое. Например, вот взял проект работы с термометром tmp117 - в его составе есть два объектных файла: UART и I2CB1 - т.е. эти исполняемые объекты от меня не зависят и работать будут, а вот SSD1306.c - он требует, чтобы там были написаны некоторые функции, иначе, никакого отображения на дисплее не будет. По поводу моего предположения, что нужны будут функции, для чтения одного байта и записи 1, 2 и 3 байт через i2c - не оправдались. Большинство программ будут работать с функциями, которые там уже приведены.

Вообще-то в лабах этих я разочаровался. Если первые лабы предоставляли проверочные программы для тестирования написанных функций, то в этих ничего уже такого нет. Написал эти четыре функции и не знаю, работоспособны они или нет, да и вообще, нужны ли они или нет? Ну, решил сам заняться игрой с сенсорами. Для начала взял тот самый термодатчик tmp117. Почитал даташит, и, чтобы быть независимым решил прочитать его ID (регистр 0x0F). Выяснил, что ни одна из написанных программ для этого не годится. Ну, воспользовался предоставленными. Хотелось же узнать, будет работать эта busy-wait система или нет? Как ни странно, она работала. Почему же тогда у меня она не работала полтора года назад? Немного по-сравнивал исходники. Оказывается, я пытался отлавливать аварийные ситуации, а этот код ничего не отлавливает. Поэтому, поначалу, когда я был забывши, подать на tmp117 питание, у меня код повисал при передаче, так как устанавливался флаг NAKF (slave-адрес не отзывался), а программа тупо ждала появления флага TX:
Код:
while((EUSCI_B1->IFG & UCTXIFG0)==0){};// wait UCTXIFG0       
Думаю, надо бы попробовать туда переместить мой драйвер. Хотя, я тут смеха для решил в SSD1306.c использовать свой опыт применения DMA и в те, функции, где происходит передача через SPI больше одного байта переделал под работу через ПДП. Однако, всё не захотело так просто работать. Не считая необходимости в пути инклюдов добавлять путь к driverlib, как и саму driverlib, пришлось еще и модифицировать сами программы - переставлять строчку разрешающую прерывания чуть по-выше - до инициализации дисплея, иначе тоже всё зависало.

Еще анализировал видео прохода робота по лабиринту и заметил торможение робота при проходе перекрёстков. Немного модифицировал алгоритм - не сбавлять скорость, если планируется прямой проход. Теперь, если на видео лабиринт проходится за 24 с половиной секунды, то теперь уже 22 с копейками. Правда, случаются моменты, когда робот внезапно поворачивает не туда. Анализируя логи выяснил, что такие ситуации возникают из-за неправильной идентификации конфигурации перекрёстка. Было два момента. В первом при наличии поворота вправо, проскочило всего одно ошибочное считывание левого крайнего сенсора (не знаю, пылинка фотодатчик закрыла?) и, в результате поворот превратился в Т-образный перекрёсток. Пока, для подавления такого рода помех решил проверять показания сенсоров на "непрерывность", т.е. если есть две группы сработавших сенсоров типа (00100110 - есть разрыв, а 00111110 - нет разрыва) - такие показания не использовать для определения конфигурации перекрёстка. Во втором случае, точно так же возникшая не вовремя помеха у центральных сенсоров, превратила Т-образный перекрёсток в Х-образный. В этом случае, чтобы одно ложное срабатывание не создало ложный путь прямо, я проверяю все считывания на "пустоту" т.е. если на пути через перекрёсток линия пропадает на всех сенсорах, считать, что пути прямо нет. Посмотрим, как эти уловки скажутся на надёжности работы робота.

Ах ну да - я тут сделал запись журнала в SPI EEPROM. Поначалу были ошибки, но я их постарался выловить и теперь надо еще погонять и проверить. Пришлось немного перенести места, откуда происходит запись в журнал. Раньше, в ОЗУ я писал отовсюду - даже из прерывания от фотосенсоров, но теперь эти функции не реентерабельные и из прерывания их вызывать нельзя. Ведь они не только делают запись данных в буфер, но и после заполнения буфера инициируют процедуру записи буфера в EEPROM: послать команду разоешения записи, залить буфер и посылать команды чтения статуса, чтобы узнать что запись завершена. И всё это делается в то время, когда происходит заполнение второго буфера.

Re: RSLK от TI (Robotic System Learning Kit)

Чт дек 24, 2020 12:15:43

Пожалуй, это началось с того, что задался вопросом - а зачем на плате дистрибуции питания прямо по центру есть место для какого-то двухрядного разъёма?

Немного подумав, понял, что это собраны все сигналы которые выведены на боковые 2х10 разъёмы для подключения плат в формате Ланчпада. Поэтому, если я на это шасси хочу навесить свой контроллер, мне совершенно не обязательно делать разъёмы как у Launchpad, а достаточно просто два параллельных 2х19 и 2х11, чтобы иметь подключение ко всем цепям платы.

Есть правда один момент: разъём 2х19 поверхностного монтажа, а 2х11 - thruhole. И если запаять обычный разъём - он окажется ниже, чем 2х19. Долго рылся по магазинам в поиске, какой разъём купить. В конце, плюнул, и впаял обычный, но чуть "на весу", чтобы он был такой же высоты, как и для поверхностного монтажа. Теперь, я могу сделать свою макетку, с любым выбранным контроллером - например stm32f407, платы которого мне тут пришли, но которые я никак не мог притулить из-за того, что эти боковые разъёмы пересекались с контактами отладочных плат.

И вот я начал планировать, как распределить ресурсы stm32f407 для работы в этой ипостаси. А попутно, почитывал сайт micromouseonline.com, который я уже упоминал (и, думаю, еще часто буду упоминать - интересное чтиво). Так вот та статья называлась, вроде как - применение квадратурного энкодера в stm32f407 для измерения пройденного расстояния и скорости. Ну про расстояние понятно, а вот скорость? У меня никак скорость внятно таким способом измерить не могу, они же скорость измеряют по прерыванию от SysTick каждую миллисекунду! Потом до меня дошло. Я не могу измерить скорость, потому что у меня при максимальных оборотах двигателя 30 000 rpm, получается всего 0.5 оборотов за миллисекунду и при 3 импульсах на оборот получается всего 1.5 импульсов и даже если контроллер двигателя будет вызываться раз в 10мс - 15 импульсов - это при максимуме, который в обычном режиме никогда не достигается - иначе ПИД регулировка будет насыщаться и регулировать реально ничего не сможет. Так что результат измерений будет иметь... язык не поворачивается назвать это "шумом" квантования - скорее грохот!

Очевидно, что у них стоят моторы с энкодерами которые дают гораздо больше импульсов на оборот, чем 3/6/12. Причем, если отказаться от измерения периода, а измерять именно частоту - исчезнут прерывания по срабатыванию захвата таймера (и чем выше обороты, тем чаще!). Пошел снова на сайт pololu посмотреть, может у них есть что получше? Нашел чуть покрупнее двигатели с энкодерами на 48 cpr. Но эти 48 - такие же как те, что у меня сейчас 12cpr - тоже магнитный диск и неизвестно насколько точно намагниченный - т.е. реально будет 12cpr - и стоит напрягаться ради этого?

Ну и тут мне подумалось, а зачем магнитный - ведь, можно сделать оптический. Дальше, из чего сделать сам диск? на просвет или отражение? Отражение не годится - либо слишком маленькая разрешающая способность, либо не знаю как это сделать. На просвет - надо искать материал и сервис, который может это сделать. И чтобы материал не был прозрачный для ИК - ведь большая часть фотосенсоров чувствительная к инфракрасному излучению. Подумал, что можно было бы в seeedstudio заказать трафарет - они достаточно хорошего качества и не сильно дорого, если брать 10 на 15 см. Пошел в eagle рисовать компонент:
Изображение
Диаметр "колеса" 20.32мм, 60 секторов - 3° прозрачный, 3° - не прозрачный. Семь секторов по краю - это чтобы легче вырезать диск из трафарета. Думаю, не плохо получилось, особенно с учетом того, что рисовалось в трясущейся электричке с помощью тачпада. Что, поверили? Нет - в игле такие регулярные структуры очень легко и красиво делаются при помощи командной строки. Достаточно нарисовать один сектор, а потом его размножить и повернуть с помощью всего двух команд:
copy (C> 0 0) (0 0) и rot R6 (C> 0 0) - где (0 0) - центр вращения. Вся фишка в том, что нужно размножаемый объект взять в группу. Ну и я не повторял 60 раз эту операцию, а сначала размножил до 2, потом до 4, 8, 16, каждый раз увеличивая угол поворота. Потом можно 16-й объект удалить и 3 раза скопировать-повернуть оставшиеся 15 на 90 градусов. При этом нет нужды точно тыкать тачпадом в нужное место - на клавиатуре: стрелка вверх и энтер. Сектор рисуется аналогично - одна из сторон поворачивается на 3°, вторая рисуется в том месте где была первая, а "закруглённые" части делаются установкой параметра curve в число градусов насколько она должна быть изогнута - в данном случае, снова 3.

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

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

Re: RSLK от TI (Robotic System Learning Kit)

Чт дек 24, 2020 13:50:18

Шаговый двигатель в качестве энкодера. 200 шагов/оборот. В корпусе и "кормить не надо".

Re: RSLK от TI (Robotic System Learning Kit)

Чт дек 24, 2020 15:42:23

Мысль с шаговиком хорошая, вот только, а не поплохеет ли ему от 30 000 rpm и как его механически связать с двигателем? пока у меня компоновка не складывается. Разумеется, у меня мысли не было применить для этого NEMA17, они то уж точно создадут слишком большую нагрузку на вал, но думаю, что от 3" дисководиков, может подойдёт?

Шаговик сразу навёл на мысль, что зачем им измерять, когда им можно просто шагать. На сайте micromouseonline.com упоминалось, что еще 15 лет назад все роботы были в основном на шаговых двигателях. И еще там была ссылка на видео от 1985 года об этих соревнованиях (в японии). Брррр, странно было смотреть на конструкции тех времен. Мрачные контроллеры, возможно, тошибовские в многоногих ДИП корпусах. И кстати, те роботы стены определяли смотря на них сверху - в торец. Кстати, на видео с соревнований 8 летней давности - тоже были роботы действующие по такому принципу - но это не те, что занимают первые места.

p.s. Ссылки на странички со старым видео:
http://www.micromouseonline.com/2012/03 ... se-videos/
http://www.micromouseonline.com/2014/10 ... use-video/

p.p.s. нашел видео с трассой очень похожей на ту, что проходил год назад:

Re: RSLK от TI (Robotic System Learning Kit)

Чт янв 07, 2021 20:38:13

Читал вышепомянутый сайт, смотрел видео и размышлял. В соревнованиях помимо самого прохода через лабиринт имеет значение, как быстро робот находит кратчайший для себя путь. Мой робот, используя алгоритм Luke-Tremo пока не излазит весь лабиринт по два раза - не успокоится. В соревнованиях же micromouse это требует очень много времени (которое в тех соревнованиях ограничено, а в соревнованих в UK еще и процентуально добавлялось к времени чистого прохода). Так вот, можно ли на основании каких-то данных принять решение, что исследованной части лабиринта уже достаточно для нахождения кратчайшего пути или надо еще проверять неисследованные проходы?
Изображение
Вот для примера упомянутый в предыдущем сообщении лабиринт (он немного отличается от того что в видео в двух местах). В видео робот проходит по алгоритму "левой руки", а мой робот проход до финиша выполнял по алгоритму "вперед-налево-вправо". Т.е.все перекрёстки проходил прямо, но если нет прямого хода, то влево и уж если и этой возможости нет,то только тогда вправо. Все остальные ветви робот долго и тщательно проверял на обратном пути. Хотя, в этом простом лабиринте можно было и не делать, так как найденный путь с учетом удалённых тупиков и так уже был кратчайшим (дурная особенность односвязных лабиринтов). Но если допустить, что лабиринт не односвязный (предположим, мы этого не знаем), то надо принять решение, искать еще или успокоиться. Я тут подумал, что в общем лабиринте из линий это определить невозможно. Надо иметь знание о границах как минимум. И скажем, "минимальный шаг" - знание, что перекрёстки могут находиться на расстоянии не меньше какой-то величины. Идеальный вариант, когда "шаг" фиксирован, как в лабиринтах для micromouse. Поэтому картинка вверху выполнена в таком стиле.

Ну вот тогда исходя из этих ограничений, можно начинать принимать решения. В одной из статей Питера Харрисона (похоже из владельцев того сайта), упоминается, что его роботы рассчитывают лабиринт постоянно в двух вариантах: "открытый лабиринт", когда все те стены что еще не обнаружены считаются что их нет вообще (кроме внешних стен, которые должны быть по условиям соревнований) и "закрытый лабиринт", когда все неопределённые места имеют стены. И по соотношению длин найденных кратчайших путей и принимается решение - решен лабиринт или нет. Вот, например, как выглядел бы открытый лабиринт для моего робота, когда он нашел выход:
Изображение
Синяя линия показывает кратчайший путь, который в верхней части лабиринта совпадает с найденным уже путём. Поэтому, нет смысла искать все проходы и тупики, так как они на конечный результат не влияют. А вот в нижней части, маршрут пролегает уже через неизведанные ячейки. И не факт, что там можно проехать. Потому предполагается, что та часть лабиринта должна быть дополнительно исследована. Для себя я пока рассматриваю алгоритм - найти финиш, вычислить кратчайший путь исходя из открытости лабиринта и посетить ту ячейку, где путь проходит через неисследованные ячейки. Т.е.выбрать ближайшую неизведанную на пути, посетить её, пересчитать лабиринт и снова направиться к следующей ближайшей неизведанной ячейке. И так до тех пор, пока кратчайший путь не будет проходить по неизведанным ячейкам. Я тут помоделировал этот лабиринт, и, оказалось, что достаточно посетить максимум 3 ячейки сверх уже посещенных, чтобы однозначно утвердждать, что более короткий маршрут не может быть найден, поэтому остальные ячейки посещать нет необходимости.

Также у Питера Харрисона была презентация на соревнованиях Minos в 2009 году, где он представлял свой быстрый метод расчета лабиринта. (Смотрите заголовок: Peter Harrison: Fast maze flooding techniques). Это алгоритм "заполнения", который очень удобен для такого "клетчатого" лабиринта. Вообще-то презентация алгоритма как раз перед его презентацией. Подумалось, что эту же технику можно применить и для алгоритма Дейкстры - надо только сделать сортировку очереди, чтобы сразу брать узел с минимальным расстоянием.

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

Еще меня в этих видео заинтересовали роботы типа 3pi (маленькие и круглые - там было несколько модификаций). Вот такого робота мне хотелось бы сделать. Пошел на сайт pololu почитать про них. А оказывается, в ноябре был выпущен новый 3pi робот. Хоть и на "более мощном" микроконтроллере, но не для меня - и старый и новый - это восьмибитная ардуина. старая классическая:Atmel 328, а новая Atmel 32U4. Эх, был бы там какой ST или Cypress, или какой другой ARM - купил бы. Хотя, я поизучал их конструкции. С сенсорами линии там плохо - 3 центральных сенсора и 2 боковых. И стоят они - в старом на расстоянии 10мм от поверхности, у нового - 20мм! Не, наверное, линию (вернее позицию линии) они разглядеть могут. Но они могут это сделать так же, как и я без очков. Т.е. видят какую-то муть и разглядеть там одна линия или 2 они уже не могут. У нового робота сразу на борту есть таходатчики двигателей и акселерометр. На новый год были скидки у Pololu, и я чуть было шасси не купил, с мыслью сделать свою плату. Но решил пока погодить.

Посмотрел еще раз видео - они тоже при торможении "клюют носом".

Немного подрессировал своего робота. Научил его отличать красный от зеленого на той бумаге, что мне тогда напечатали. Я сделал перед передачей на вычисление Hue проход значений через "аттенюатор" - т.е. каждое значение можно чуть усилить или ослабить. А так как я к этим переменным имею доступ через командный интерфейс, я мог просто введя команду:
Код:
800 ColorRed !
сразу видеть результат. Так что я "слегка" задавив уровень сигнала красного канала сделал достаточно четкое различие - зелёное поле - зелёное, красное поле - красное, белый лист - белый, а цвет моей трассы - желтый. Если робота приподнять - черный. Меня устраивает.

А тут на меня снизошло (вообще-то снизошло полтора месяц назад), что так как я командами могу прочитать все переменные, то я и результат вывода могу сохранить в виде текста. Т.е. для запоминания конфигурации мне не нужно делать копию памяти робота. Всё это доступно в текстовом виде, а путём небольшой модификации (сзади надо добавить только "swap !") получить командный файл, который восстановит мне все конфигурационные переменные в заданное состояние:
Код:
Threshold     800    swap !
MAXspeed      16000    swap !
MINspeed      10000    swap !
MAXmotor      16000    swap !
TurnSpeed     6000    swap !
Accelerat     100    swap !
K*error       10    swap !
K*de/dt       120    swap !
Kintegral     0    swap !
MotorKprop    135    swap !
MotorKint     256    swap !
OnWay         100    swap !
итд.
Вот это фрагмент конфигурации сделанный 31 декабря.

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

Хотя всё это мечты. 2 соревнования уже пролетело, третье, 30 января - тоже, пролетит. Чую, этот коронавирус не даст покоя до лета.

Re: RSLK от TI (Robotic System Learning Kit)

Сб янв 09, 2021 18:40:29

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

Сделал небольшой тест для проверки этих функций сортировки, отладил. Теперь вопрос как проводить benchmark? А тут на днях я вспомнил, что хоть я и горевал, что у MSP432 всего 4 таймера, но это не так. Помимо Timer_A и WDT, есть еще Timer32. Толку от него мало - периферией он командовать не может, зато он может делать прерывания, делиться на два 16-разрядных таймера и в микроконтроллере их целых две штуки! Поэтому я один приспособил к выполнению микросекундных задержек, так как он тактируется от главной частоты МК - 48МГц. Но я всё же включил делитель на 16 (можно делить на 16 и 256), так что один такт счетчика происходит за 1/3 микросекунды. Вот. а второй я приспособил для измерения времени. 32 бита при 3 импульсах на микросекунду хватает на 23 минуты.

Вот протокол:
250111 old 0 optimization
68583 fast 0 optimization

87234 old 4 optimization
41410 fast 4 optimization

Числа в третях микросекунд. Расчитывался лабиринт приведенный на фотографии в предыдущем сообщении. В измеренное время входит считывание карты из EEPROM, расслоение, составление расстояний, создание маршрута, сохранение маршрута. Правда проблема в том, что я что-то наизменял и больше у меня не получается сделать расчет за 41/3 миллисекунды.

Когда я увидел, что расчет занимает почти 15мс, подумал, что, возможно много времени теряю на сортировке. Так как новое значение я кладу в очередь сверху, но его значение как правило больше тех, что уже есть в буфере, поэтому мне его нужно "топить" вниз почти через весь буфер. Поэтому, я решил сделать так, чтобы новые значения добавлялись сразу вниз и "всплывали" до своих величин. Увы результат оказался хуже, поэтому я попытался делать undo, чтобы вернуть то что было. Но буфера undo не хватило чтобы вернуться полностью назад. А когда я написал, то, что по моим представлениям было - получал только в районе 54-56 тысяч (18-19 миллисекунд). Причем, кольцевой буфер быстрее простого меньше чем на 1 мс. Возможно потуги по обеспечению кольцевого буфера съели всё преимущество. С другой стороны, выигрыш особенный не мог получиться, так как на этой трассе максимальное заполнение буфера было всего 12 элементов. Обычно 3-4-5.

В принципе, время расчета без считывания из EEPROM и сохранения маршрута чуть больше 7мс из них составление "карты высот(расстояний)" - 4 с небольшим мс.

p.s. попытался написать составление карты расстояний в "арифметике указателей", а не индексов - получилось, почему-то дольше:
С указателями:
Calculation time: 21261/3 us
Calculation time: 21291/3 us
С индексами:
Calculation time: 19585/3 us
Calculation time: 19534/3 us
(измерялось время на расслоение карты, составление расстояний и составление маршрута)

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

Re: RSLK от TI (Robotic System Learning Kit)

Вс янв 24, 2021 11:06:36

Итак, я тут решил развлечься и всё-таки сделать лабиринт по клеточкам. Для этого подготовил небольшую инфраструктуру. Функции которые отрисовывает лабиринт, инициализируют лабиринт итд. Проблема в том, что построить полигон для проверки я не могу. На куске оргалита который у меня есть, умещается лабиринт максимум 3 х 4. Но и этого я сделать не могу. Чёрная изолента шириной 15 мм у меня на исходе, а из-за локдауна новую купить невозможно затруднительно. Поэтому я решил сделать виртуальный лабиринт. Сделал функции виртуального перемещения по лабиринту из линий, который робот "на ходил" или я принудительно загрузил. Сначала думал как перемещаться: на одну клеточку или как? Но потом решил, что нужно перемещаться до развилки, а пройденное расстояние просто делить на шаг клетки. Таким образом, функции реального перемещения могут остаться те же самые.

Но пока я нарисовал функции виртуального перемещения и реализовал алгоритм Люка-Тремо для поиска выхода. Вот я тут сделал небольшое видео. Функция, которая реализует алгоритм не знает про лабиринт ничего. Информация появляется только тогда, когда робот оказался в клеточке и только тогда узнал о том какие стены там реально есть. Конечно, узнав состояние, скажем, северной стены, мы узнаём и состояние южной стены соседней клетки, что севернее текущей (во загнул...). Но тем не менее - чтобы выяснить, что там не финиш - её надо посетить.

Для демонстрации я выбрал довольно не оптимальный вариант "правой руки" - пока есть выбор - мы ведем рукой по правой стене. Где-то после 1:20, когда, робот пытается посетить клетку, где уже был - по алгоритму Люка-Тремо надо разворачиваться и вот эти "развороты" просто режут глаз. Поэтому, было решено ввести функцию "прогнозирования" - если ту клетку, куда мы собираемся переместиться уже посетили и должны будем вернуться, эти действия выполняем виртуально - "в уме", не делая реального перемещения.

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

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

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

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

Re: RSLK от TI (Robotic System Learning Kit)

Вт мар 09, 2021 16:51:30

С поиском кратчайшего расстояния разобрался - всё оказалось просто. даже не просто, а очень просто. При этом я не создавал в памяти "расслоенную" карту. Одному узлу сделал 2 значения расстояний: для широтного и меридианального направления, а заполнялись они в соответствии с направлением прибытия в узел (то же самое расслоение, но "мысленно"). После чего, возникла мысль провернуть такой же фокус и с "классическим" алгоритмом для лабиринта из линий. Конечно, появилось больше if-ов в алгоритме из-за чего я стал опасаться, что никакого выигрыша может и не быть, но бенчмарк на одном и том же лабиринте показал разницу в 10%:
Код:
Calculation time: 6003/3 us - новый без расслоения
Calculation time: 6745/3 us - старый с расслоением

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

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

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

А для ориентации по стенам - надо строить реальный лабиринт. Вот только, строить такой как на наших соревнованиях - резона нет. Надо строить как для micromouse, Ну и робота соответствующего размера, чтобы он там мог перемещаться. Тут уже прикидывал, сколько времени потребуется, чтобы напечатать стоечки и стены для небольшого лабиринта - ну хотя бы 3х3 - 16 стоек и 16 стен. Вообще-т снова сошлюсь на материалы MINOS от 2018-го года: там была презентация Duncan Louttit по его конструкции лабиринта.

В этих материалах презентаций можно почерпнуть много полезного. Один из интересных вариантов - как записывать в журнал параметры пробега робота. Были рассмотрены разные варианты и самый лучший - использование FRAM. Причем, SPI FRAM. Это самый простой и быстрый способ записи - не нужна буферизация, не нужно квитирование. Скорость, даже если брать самые тормозные микросхемы - 20Мb/s. Недостаток - много ног у контроллера и цена микросхемы. Я тут попытался глянуть микросхему максимально доступной ёмкости 1 мегабайт - 30 евро во вменяемом корпусе или 26 в невменяемом без НДС. Зато, сделав "ручное" управление сигналом CS - в начале записи журнала устанавливаем в 0, передаём команду записи и адрес, а потом только данные до самого конца заезда и в конце надо только снять сигнал CS - всё записано сразу и без задержек! И во время записи ничего читать не нужно. Для попробовать взял не самую дорогую и не очень большую - всего 256К от ROHM.

Хотел начать разработку нового робота в конструктиве для micromouse лабиринта, взяв за основу pololu робот 3pi. Т.е. круглая форма, 4 ААА NiMH батарейки итп. Вот только с батарейками облом. у 3pi эти 4 батарейки дают от 4,8в до 6, что мало для двигателей. Поэтому там стоит повышающий преобразователь. На схеме, конечно, не указан тип. Ну я тут порылся по сайту TI и нарыл TPS61089 - достаточно простая и хорошая для этих целей. Корпус, у неё, конечно, уж очень современный. Но, решил заказать у TI, благо они дали купон на бесплатную доставку. Хочу купить, а их на складе больше нет. Нигде. Срок поставки 20 недель. Впрочем, даже и то что есть в наличии, тоже не спешит - похоже, что у всех поставщиков проблемы. Маузер мой заказ неделю собирал, хорошо, хоть, быстро доехал - у моего знакомого, чуть ранее, была задержка в доставке, похоже, из-за того что в техасе снег выпал. Но невозможность приобрести желаемое - расстраивает. Для этого же робота хотел приобрести датчики холла si7202 - пока добрался до оплаты заказа - уже backordered.

Кажется. что MSP432 для меня иссякла. намедни запользовал еще один блок - CRC. На форуме начитался, что EEPROM имеют дурную привычку портить данные, поэтому добавил к конфигурацинным данным контрольную сумму, чтобы получить предупреждение. если таковое случится. Так что в этом роботе изучено и использовано большая часть возможностей кристалла. Неиспользованными остались RTC, AES, watchdog и еще что-то.

Поэтому, начал размышлять, что взять следующим объектом изучения. Участвуя в воркшопе по BG22 от силикон лаба, понял, что в них я ничего совершенно не понимаю. Вроде, несложные BT устройства могу нарисовать. но копни чуть глубже - ничего не получается. А посмотрев на серию GG - giant gecko, понял, что она выглядит довольно привлекательно по доступным ресурсам. Думал сделать плату в конструктиве Launchpad-а, но так как пока не понимаю возможностей и ограничений по подключению периферии к разным выводам, решил сначала приобрёсти готовую платку SLTB009 с микросхемой EFM32GG12b810 (голый кристалл я планировал приобрести значительно скромнее). Правда выводов у неё маловато, но базовый функционал, похоже обеспечить удастся. Плата уже пришла и сейчас размышляю, как её программировать. Все примеры. что есть в Simplicity Studio ориентированы на SDK. Но если использовать SDK - получится ардуина. Видимо, придётся использовать её без SDK. Правда, пока мне не удаётся создать проект без SDK вообще. А выбора Stackless application - нет. Может, надо что-нибудь еще проинсталлировать?

Re: RSLK от TI (Robotic System Learning Kit)

Вт мар 09, 2021 21:04:31

Но если использовать SDK - получится ардуина. Видимо, придётся использовать её без SDK.
Я не понял в чём проблема с SDK и почему пишите "придётся"? При создании проекта есть опция "Empty C Project". В нём можно пройтись по вызовам функций в sl_system_init() и подобных и убрать всё лишнее, если не нравится. Но смысла я лично в этом не вижу. Или хотите сконфигурировать периферию с нуля через регистры? Если так, то это тоже возможно. Короче, из вышеизложенного мне неясно в чём проблема и чего хотите добиться. Наконец, программирования без SDK не тоже самое, что stackless. Stack относится к протоколам типа Bluetooth, а в самом SDK для EFM32GG нет никакого стека. Примеры конфигурирования периферии через EMLIB находятся на GitHub.

Re: RSLK от TI (Robotic System Learning Kit)

Вт мар 09, 2021 23:19:10

Я еще разбираюсь... Цель, конечно, научиться железо. Поэтому хочу библиотеки использовать по минимуму.

Проблема с настройкой среды. Если делать empty C project я не знаю где и какие хедеры подключить, чтобы были видны регистры в CMSIS стиле. В файле AN0009.1: Getting Started with EFM32 and EFR32 Series 1 написано, что надо добавить em_device.h, но настройки среды не дают найти его. Правда этот документ базируется на SSv4 и SDK.

Ладно, пока сделал с SDK 3.1 - может для начала переживу этот цикл while(1) в main.c. Заодно попробую изучить, что там в стартапе написано.
Для начала попытался написать аналог LaunchPad.c - функции для зажигания светодиодов и опроса кнопок. Если кнопки сделались легко функцией GPIO_PinInGet, то с выводом проблемы. Почему-то есть функции включения, выключения и переключения. Но нет функции вывода того что в аргументе. На ланчпаде был один просто светодиод, и RGB светодиод. Если в первом случае можно простым if-ом выбрать какую функцию включения или выключения вызвать... то для RGB светодиода будет слишком, на мой вкус, много этих if-ов. Разумней всего было бы использовать BITBAND, благо у этого микроконтроллера оно есть. И как выяснилось, есть еще области установки и сброса бит отдельно. Так, BITBAND. Странно, но тут я тоже не нашел макроса BITBAND_PERI(adr, bit). У TI и Cypress есть, а у ST и SL - нет. Но внутри GPIO_PinInGet - я его нахожу, конечно не в виде макроса, но чтение бита порта производится именно через BITBAND область. Пока написал этот макрос и вывод на RGB светодиод сделал через BITBAND.

В общем, светодиоды зажечь и погасить удалось. Нашел по пути ошибку в UG371: Thunderboard EFM32GG12 User's Guide - перепутаны местами в разделе 3.4 номера портов к которым подключен светодиод LED0 - из-за чего у меня сначала не тем цветом светодиод светил.

Re: RSLK от TI (Robotic System Learning Kit)

Ср мар 10, 2021 06:20:26

Хозяин - барин в плане цели. Я поначалу тоже всё на уровне регистров конфигурировал и свои драйверы для I2C/SPI писал, и даже всё полностью на ASM (последнее, правда, под Keil). Но в конце концов мне это надоело. Сейчас даже считаю, что это неправильно и не вижу криминала в исползовании библиотек и конфигураторов. Впрочем, скорее всего Вы правы - в плане освоения железа, наверное, помогло. Хотя и в этом сейчас червячок сомнения точется.

Короче, платы с EFM32GG у меня нет, но есть отдельный чип EFM32JG1B100 на монтажке. Ради интереса попробовал создать под Studio5 проект конгигурации всего с нуля из файла "Empty C project" для мигания светодиодом через RTCC. Никакой автогенерацией не занимался, а сконфигурированные дефолтом в проект Студией файлы просто не использовал. Также не понял проблемы с включением em_device.h - просто добавил его инклюдом и всё собралось. Что получилось см. в .sls файле в архиве ниже. Программировал напрямую J-Link дебаггером.

JG1B100.jpg
(223.32 KiB) Скачиваний: 232

empty.zip
(20.58 KiB) Скачиваний: 258

Re: RSLK от TI (Robotic System Learning Kit)

Ср мар 10, 2021 07:09:34

Ага, у вас тоже присутствует каталог SDK_3.1.1. Собственно, посмотрел, что все объекты указывающие на регистры описаны в файлах которые именно там и находятся. Так что CMSIS, по видимому, там и лежит. Просто я не додумался, что main.c можно написать по-своему. Меня испугала надпись "Do not remove this call":
Код:
  while (1) {
    // Do not remove this call: Silicon Labs components process action routine
    // must be called from the super loop.
    sl_system_process_action();

    // Application process.
    app_process_action();

Да, если копнуть глубже, видно что все 4 функции, которые лежат в sl_system_process_action - пока что пустышки.

Готовые библиотеки и функции хорошо, когда понимаешь что под ними и что от них требуется. Я, например, застрял с "новомодными" драйверами кнопок (как в Lab4 workshop-а). Обычный опрос состояния кнопки: нажата или нет, чтобы стереть бондинги. Крутил-крутил эти функции и так и не понял как сделать такую простую вещь. И даже чтение документации ума не прибавило. Раздел "Usage" - вообще шедевр. Почему-то в голове всплыли снова "Звёздные дневники Йона Тихого", как он выяснял что такое сепульки. Хотя там очевидно, та же проблема, что была и в Лаб4 - структура .context не описана в хедерах потому я не мог добраться до context->state. Но я слишком мало понимаю эту конструкцию, чтобы ручками написать extern.

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

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

Re: RSLK от TI (Robotic System Learning Kit)

Ср мар 10, 2021 19:27:46

В общем, у Вас правильный подход, чтобы со всем разобраться в деталях. Насчёт новомодных драйверов кнопок, хотя я и выступал ранее за библиотеки, но когда столкнулся с этими драйверами то подумал, что это уж слишком и всё у меня внутри запротестовало. Никогда их не использовал и с ними не разбирался. Чтобы сконфигурировать прерывания от кнопки достаточно лишь 3-х строчек при использовании EMLIB (+ callback функция):
На уровне регистров это делается также достаточно просто, особенно в моделях МК серий 0 и 1:
... плюс 1-2 IRQ хендлера для обработки прерываний чётных или нечётных пинов порта:
В моделях серии 2 немного по-другому, но очень похоже. Подход с EMLIB выше работает для всех серий. Насчёт АЦП и OPAMP, действительно очень мудрёная конфигурация аналоговых шин, особенно для серий 1 и 2, а документация по аналовому порту для серии 2 ещё сильно обрезанная. Однако, на Гитхабе по ссылке выше имеется много примеров на все случаи жизни.

Re: RSLK от TI (Robotic System Learning Kit)

Сб мар 13, 2021 20:28:25

Первые результаты - попытался освоить USART в режиме SPI, а затем как UART. Пока читал даташит, даже и не думал, что у него есть столько много разных возможностей! Ладно, про double tx/rx я уже знал - когда читал про i2c раньше. Но вот то, что там внутри есть еще и таймер с тремя регистрами сравнения... Не думаю, что изучая библиотечные функции я об этом узнал бы. И, возможно, что библиотеки этими фичами не пользуются. Хотя, мне они пока тоже не нужны. Сделал простенькие функции для работы с OLED дисплеем (пока по прерываниям) и коммуникацию через J-Link-овский USB CDC. С SPI добился, что на осциллографе увидел, что есть клоки, данные и CS и на том успокоился. Так как делал пока только то, что не требует дополнительного железа. Потому UART делал через набортный J-Link. Ну тут я попрыгал. Дня два угрохал на это. Вроде, вижу, что прерывания происходят, данные в порт грузятся и куда-то уходят, но в терминале глухо. Перепроверял Routing, пересчитывал скорость (всё время, почему-то получались разные коэффициенты деления), пока не загрузил рабочий демо "iostream_usart_baremetal" под отладку и там подсмотрел, что загружено в регистры (оказалось, самый первый раз я правильно вычислил коэффициент деления). Под конец, начал думать, где можно ткнуться осциллографом, чтобы увидеть реальный сигнал с порта. И пока изучал, увидел, что между контроллерами стоит изолирующий ключ. В User Guide был нарисован ключ, но не было нарисовано, кем он управляется. Думал, что он управляется J-Link-ом, а оказалось - целевым кристаллом PA15 (смеха для дал поиск на эту комбинацию в UG - ничего не найдено). Ладно, наконец, получил на терминале "прыгающую через собаку лису". Однако, я не могу разобраться с сигналами RTS/CTS. Если я в конфигурации добавляю USART0->CTRLX = USART_CTRLX_CTSEN; ничего не происходит. Тут я снова полез подсматривать, что делается в "bare-metal" - там этот бит не установлен. Но, помотрел в своём проекте на BGM220P - там я использую готовый iostream - там установлен. Вот теперь и не знаю, где искать ответ на вопрос, когда и почему на этих платках CTS/RTS работает, а когда - нет. Пока пытаюсь читать силабовский форум - но там пока ничего не нашел. Наверное, надо закрепить плату в тиски, чтобы ткнуться в резисторы R149 и R150 - единственные места где эти два сигнала выходят на поверхность платы. Хотя тыкать в резистор типоразмера 0402 - еще то удовольствие.
добавил: RTS - лог.0, CTS - лог.1. RTS идёт с микроконтроллера и если "размыкаю" цепь - лог.0 остаётся. Хм, чего ему еще для полного счастья не хватает?

Когда подключил к SPI OLED дисплей - тоже ничего не заработало. Ну там я напутался. Не в той функции указал передачу MSB first. Когда поправился, заработало, но крайне нестабильно. Проблема была в опознании, когда закончился предыдущий трансфер, чтобы не изменить состояние контакта Data/Command за рано, а только тогда, когда предыдущий трансфер завершился. Ну, немного поигрался, пока нашел, хорошую и стабильную комбинацию, которая давала стабильный результат. Пришлось добавить прерывания по флагу TXC - transfer complete. Это даёт стабильный результат.

Пока с этим игрался, понял, что в этом кристалле надо отходить от старого доброго read-modify-write и не использовать конструкции навроде |= mask или &= ~mask. И всё это благодаря двум областям, запись в которые или устанавливает, или сбрасывает биты в регистре, которые в маске равны единице. Для этого использую готовые макросы... нет - инлайновые функции
Код:
BUS_RegMaskedSet(&USART3->IEN, USART_IEN_TXBL);
BUS_RegMaskedClear(&USART3->IEN, USART_IEN_TXBL);


Добавлено after 4 hours 33 minutes 40 seconds:
В проекте bare-metal-iostream в конфигурации этого самого iostream включил RTS/CTS и тоже нет передачи данных.

Re: RSLK от TI (Robotic System Learning Kit)

Сб мар 13, 2021 23:45:03

Хотя у меня платы SLTB009A нет, но думаю, что устанавливать PA15=1 там нужно в user коде. Неясно про какую плату пишите выше. Если про SLTB009, то там у USART0->CTRLX нет бита USART_CTRLX_CTSEN. Вообще, сложно советовать на расстоянии, но я начал-бы с проверки конфигурации пинов RTS/CTS в регистрах USARTn_ROUTEPEN и USARTn_ROUTELOC1, а также в GPIO_Pх_MODEL/GPIO_Pх_MODEH.

Re: RSLK от TI (Robotic System Learning Kit)

Вс мар 14, 2021 09:40:27

Мммм. Сам чувствую что что-то не то... Мне кажется, что лог.0 у меня стоит на выходе RTS контроллера, что должно запрещать дебуггеру посылать данные, но у меня не идёт передача в обратную сторону (пока, второе направление не проверял) - от контроллера в дебаггер. И нет передачи, когда я активизирую CTSEN (Хотя так и должно быть, если CTS = 0). Хорошо, пройдёмся по документации снова.

Плата SLTB009A ибн BRD2207A-A02 с кристаллом EFM32GG12B810F1024GM64 на борту. Смотрим на картинку 3.7 в UG371-SLTB009a-User-Guide.pdf:
Изображение
То, конечно, туфта. TX должен соединяться RX дебаггера, RX с TX, RTS c CTS и CTS с RTS. Но, по крайней мере, ресурсы, вроде указаны правильно: TX - PE7 USART0 LOC1, RX - PE6 USART0 LOC1, RTS - PB5 USART0 LOC4, CTS - PB6 USART0 LOC4. Смотрим даташит EFM32 Giant Gecko Series 1 Family EFM32GG12 Family Data Sheet
Изображение
Вроде совпадает. Идём смотреть схему:
Изображение
Здесь вообще всё правильно: PB5 становится RTS, проходит R150, ключ, формирователь и становится DBG_CTS.

Но тыкаюсь тестером в резисторы:
Изображение
Откуда на R150 лог.0? Вот прошелся отладчиком и состяние сигналов на резисторах в некоторых точках:
Код:
void UART0_Init(void) {
/* R149 HiZ, R150 HiZ */
  GPIO_PinModeSet(gpioPortE, 6, gpioModeInputPull, 1);  // RX
  GPIO_PinModeSet(gpioPortE, 7, gpioModePushPull, 1);   // TX
  GPIO_PinModeSet(gpioPortB, 6, gpioModeInput, 1);  // CTS
  GPIO_PinModeSet(gpioPortB, 5, gpioModePushPull, 1);   // RTS
/* R149 HiZ, R150 лог1 */
  GPIO_PinModeSet(gpioPortA, 15, gpioModePushPull, 1);  // enable link mcu <-> debug
/* R149 лог1, R150 лог1 */
  CMU_ClockEnable(cmuClock_USART0, 1);

  USART0->CTRL = USART_CTRL_OVS_X16 ;
  USART0->CLKDIV = 0x1a20;
  USART0->ROUTEPEN = USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_CTSPEN | USART_ROUTEPEN_RTSPEN;
  USART0->ROUTELOC0 = USART_ROUTELOC0_RXLOC_LOC1 | USART_ROUTELOC0_TXLOC_LOC1;
  USART0->ROUTELOC1 = USART_ROUTELOC1_CTSLOC_LOC4 | USART_ROUTELOC1_RTSLOC_LOC4;
  USART0->FRAME = USART_FRAME_DATABITS_EIGHT | USART_FRAME_STOPBITS_ONE | USART_FRAME_PARITY_NONE;
  USART0->CMD = USART_CMD_TXEN | USART_CMD_RXEN | USART_CMD_CLEARRX | USART_CMD_CLEARTX;
  USART0->IEN = USART_IEN_RXDATAV;
/* R149 лог1, R150 лог0 */
  USART0->CTRLX  = USART_CTRLX_CTSEN;

  NVIC_EnableIRQ(USART0_TX_IRQn);
  NVIC_SetPriority(USART0_TX_IRQn, 4);
  NVIC_EnableIRQ(USART0_RX_IRQn);
  NVIC_SetPriority(USART0_RX_IRQn, 4);
}
 


Добавлено after 35 minutes 46 seconds:
Кажется, я перепутал полярности.
RTS is an active-low output from the CP210x to talk to the external UART device that it is ready to accept more data. CP210x pulls the RTS to high indicate to the external UART device to stop sending data when the amount of data in the RX FIFO reaches the watermark.

CTS is an active-low input to CP210x. CP210x sends data to external UART only when the CTS is pulled low. If the external UART device's RX FIFO is getting full, it will pull this pin high.
Т.е. мне надо беспокоиться почему на R149 лог1! Но, это приходит от JLink дебаггера и это прекрасно видно, как только я устанавливаю PA15 в лог.1.
Ответить