avatar_zap

Универсальный бортовой компьютер iWattnick

Автор zap, 10 Окт. 2014 в 03:53

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

TRO

Цитата: zap от 16 Окт. 2014 в 18:46
....
Насчёт внешней платы датчиков идея хорошая.
Но это усложняет основной вариант - появляются два корпуса вместо одного.
Два корпуса будет как возможный вариант для тех кому нужно два корпуса...
А вы делайте в одном корпусе, просто платы сделайте две с одним итерфейсом между ними, чтобы можно было ракидать в два корпуса, и прокачивать каждую по отдельности (модульность это не дураки придумали, зачастую оч сильно помогает).

Wahoo 2012 29er, +собран складной двухосис на раме"Land Rover" 69er с эл. мотором, и и МОНОКОЛЕСО

zap

#109
Ушёл с головой в STM32 :) Так как часов в сутках всего 24, нет времени даже форум читать.

За прошлую неделю полностью освоился с микроконтроллером, написана среда автоматической сборки проектов, прошивка, пошаговая отладка - всё в одном флаконе. Всё с нуля начинаю заново :) все старые наработки по AVR - в топку.

Написал своё первое мигание лампочкой и реакцию на нажатие кнопки. Прошивка STM32VL-DISCOVERY занимает 1900 байт, моя прошивка, которая делает то же самое - 600 O_O. Это при том, что байт 300 из них - это инициализация микроконтроллера от ST (библиотека CMSIS).

Код для STM32 от ST - полный шлак. Просто слов нет. Такое ощущение, что в ST набирают индусов, которых увольняют за профнепригодность из мелкософта. Примеры на поржать:
uint32_t tmp = 0, pllmull = 0, pllsource = 0;
...
/* PLL multiplication factor = PLL input clock * 6.5 */
pllmull = 13 / 2;
:facepalm:
Это из либы CMSIS, самой базовой либы - там идёт инициализация генератора тактовой частоты!

Вот ещё из либы Standard Peripherals Library Drivers.
ST её рекомендует использовать для работы со всей периферией микроконтроллера :facepalm: :dash:.
Вычисление делителя частоты для работы USART:

  /* Determine the integer part */
  if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
  {
    /* Integer part computing in case Oversampling mode is 8 Samples */
    integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));....
  }
  else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
  {
    /* Integer part computing in case Oversampling mode is 16 Samples */
    integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));....
  }
  tmpreg = (integerdivider / 100) << 4;

  /* Determine the fractional part */
  fractionaldivider = integerdivider - (100 * (tmpreg >> 4));

  /* Implement the fractional part in the register */
  if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
  {
    tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
  }
  else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
  {
    tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
  }

  /* Write to USART BRR */
  USARTx->BRR = (uint16_t)tmpreg;


Мой код, который выполняет ровно то же самое:

if (usart->CR1 & CR1_OVER8)
    bus_freq *= 2;
usart->BRR = (bus_freq + fmt / 2) / fmt;


Короче, от Standard Peripherals Library Drivers я уже отказался, хотя импортировал в свой репозиторий и поначалу кинулся её изучать... :eek:. Более бессмысленно раздутой и неграмотно спроектированной либы я ещё не видел. Единственная от неё польза - есть с чем сверяться в процессе написания своей библиотеки, хотя в некоторых случаях, как например выше, хрен поймёшь что автор хотел сказать.

Написал простенькую библиотеку для работы с USART, вывел через неё printf(), теперь можно печатать что угодно и как угодно - нашёл в сети и адаптировал микроскопический printf/sprintf одного товарища, занимает 600 байт.

Написал простенькую библиотеку для работы с часами реального времени. RTC считает в секундах (у меня вообще в 1/16 секундах), перевод в год/месяц/день делается алгоритмически. Нашёл в сети мелкую приятную функцию перевода, адаптировал, написал обратную функцию для установки времени.

Теперь начну разбираться с DMA и SPI. Думаю, получится сделать так, чтобы фреймбуффер заливался в дисплей почти без участия процессора. Дисплеи уже едут.

Думаю отказаться от INA220. В STM32 свой навороченный 12-битный АЦП, и каналов по горло. Впрочем, внешний ОУ всё равно придётся ставить. Может даже двухканальный сделаю, отдельно для положительного и отрицательного тока, пока не решил.
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

mevial

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

batson

Цитата: zap от 29 Окт. 2014 в 00:20
Думаю отказаться от INA220
мне он всегда казался ненужным
у него одно преимущество - цифровой выход, если наводки не будут оказывать значимое воздействие, тогда он не нужен
Самоходный аппарат из нержавейки: нержавеющий чоботар, инфинеон 12, MXUS 1000

zap

Цитата: mevial от 29 Окт. 2014 в 07:25
А где посмотреть новую реализацию компорта?
Заголовок и код (serio*.c).
Пример использования, инициализация тут.
Соответственно, printf.h и printf.c.


Добавлено 29 Окт 2014 в 19:19:01

Цитата: batson от 29 Окт. 2014 в 12:52
мне он всегда казался ненужным
У него много преимуществ - встроенный усилитель с управляемым коэффициентом усиления, 13 бит разрешения, и он на заводе откалиброван как по току так и по напряжению. У AVR АЦП всего 10 бит, это на порядок хуже по точности.
А вот по сравнению с 12-битным АЦП STM32 он уже смотрится не так кучеряво... придётся калибровать после изготовления, правда. В принципе, в менюшках калибровка всё равно предусмотрена.
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

TRO

#113
Есть такая китайская микросхема с 24 битным АЦП http://www.extron-tech.com/frles/CS1180_Datasheet_EN_V1.0.pdf
Стоит чуть дороже двух баксов за корпус на алиэкспрессах, используется в торговых весах (точность соответствующая).
Имеет диф. вход, умеет оцифровывать с частотой 15 раз в секунду, а больше думаю и не нужно, может имеет смысл присмотрется?

Или эту http://www.dfrobot.com/image/data/SEN0160/hx711_english.pdf
10 герц точно может, и больше распостранена, и дешевле доллара стоит.

Wahoo 2012 29er, +собран складной двухосис на раме"Land Rover" 69er с эл. мотором, и и МОНОКОЛЕСО

mevial


void serio_putc (USART_TypeDef *usart, uint8_t c)
{
    // Wait till transmission register empty
    while (!(usart->SR & USART_SR_TXE))
        ;

Выглядит как залипон. Без управления потоком конечно залипона не будет, оно уйдёт в никуда, но вот если кто-то включит управление потоком, то залипнет при обрыве линии.
Я бы добавил таймаут и статус передачи.

zap

#115
Никакого управления потоком там не планируется. Вот ещё, тратить ноги на CTS/RTS.
Даже если бы было, случиться залип может только если получатель "залипнет" сигнал CTS, т.е. залип уже произошёл, но в другом месте.
Да и вообще, это чисто отладочная функция, единственное её применение - printf(). Сейчас делаю библиотеку для работы с DMA, USART через DMA будет использоваться для обмена с аплинком (телефоном) и слэйвами (датчиками). На AVR приходилось работать через прерывания, а тут в этом необходимости даже нет - точнее прерывание будет уже по окончании отсыла/приёма целого блока, а не побайтно.
Есть простая истина - чем более универсальна библиотека, тем она менее эффективна.
Поэтому я исхожу исключительно из своих потребностей.
Точнее, стараюсь делать универсально, но там где идёт баланс между универсальностью и эффективностью применительно к моим условиям, выбираю последнее.
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

Silvaticus

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

VasiliSk

[user]zap[/user], не вы один находите SPL черезчур громоздкой и неудобной. Порой просто инициализация переферии занимает меньше строк кода чем таже инициализация через SPL.
Я в своей первой версии борткомпа использовал INA213 для усиления сигнала с шунта, но мне она не понравилась, плавает сильно и шум на выходе. Теперь пробую на ОУ с авто-коррекцией нуля.

mevial

#118
Цитата: zap от 30 Окт. 2014 в 00:49
Даже если бы было, случиться залип может только если получатель "залипнет" сигнал CTS, т.е. залип уже произошёл, но в другом месте.
Да и вообще, это чисто отладочная функция, единственное её применение - printf(). Сейчас делаю библиотеку для работы с DMA, USART через DMA будет использоваться для обмена с аплинком (телефоном) и слэйвами (датчиками).
Ясно, а я думал это и будет основной периферией с блютусом. Когда писал монитор смартбмс, то задача стояла очень остро, все реализации i2c были с такими вот вечными циклами, что на аппаратном i2c, что на программном. А смартбмс любит периодически пропадать с шины или путать сигналы. Не проблема сбросить шину и перечитать, но хост залипает и не сбрасывает. Пришлось писать свою i2c без залипонов, с репортами на каждый чих, т.е. каждый цикл с таймаутом выставляет свой бит, и при дебаге я могу чётко знать в каком конкретно месте сработал таймаут. Даже платка iic2serial с ебея, залипала на смартбмс, до полного её отключения, но при этом стабильно работала с еепромом и экраном. А вот линуксовая реализация через ddc залипов не имеет, но имеет таймаут около секунды, после чего выставляет знак в в даблворд данных, тоже без проблем работает со смартбмс.
До dma я пока не дорос, это нужно реально передавать огромные потоки данных на сильнозагруженном контроллере, иначе подготовка данных для dma занимает больше времени, чем передача раз в секунду максимум пары десятков байт, или приём меньше 10 байт через прерывания. Кстати как принимать данные через dma для меня пока тоже загадка. Через прерывания всё просто, клацнуло компортом, смотришь - байт, проверяешь на перевод строки, если да, то строка готова, можно парсить, если нет, кидаешь в буфер и засыпаешь.

zap

#119
Цитата: VasiliSk от 30 Окт. 2014 в 04:30
[user]zap[/user], не вы один находите SPL черезчур громоздкой и неудобной. Порой просто инициализация переферии занимает меньше строк кода чем таже инициализация через SPL.
Я сегодня смотрел на функцию DMA_DeInit() и чувствовал, как холодное дыхание века победивших мышиных программистов задувает мне за шиворот.
Спойлер


void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx)
{
   /* Check the parameters */
   assert_param(IS_DMA_ALL_PERIPH(DMAy_Channelx));
   
   /* Disable the selected DMAy Channelx */
   DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR1_EN);
   
   /* Reset DMAy Channelx control register */
   DMAy_Channelx->CCR  = 0;
   
   /* Reset DMAy Channelx remaining bytes register */
   DMAy_Channelx->CNDTR = 0;
   
   /* Reset DMAy Channelx peripheral address register */
   DMAy_Channelx->CPAR  = 0;
   
   /* Reset DMAy Channelx memory address register */
   DMAy_Channelx->CMAR = 0;
   
   if (DMAy_Channelx == DMA1_Channel1)
   {
     /* Reset interrupt pending bits for DMA1 Channel1 */
     DMA1->IFCR |= DMA1_Channel1_IT_Mask;
   }
   else if (DMAy_Channelx == DMA1_Channel2)
   {
     /* Reset interrupt pending bits for DMA1 Channel2 */
     DMA1->IFCR |= DMA1_Channel2_IT_Mask;
   }
   else if (DMAy_Channelx == DMA1_Channel3)
   {
     /* Reset interrupt pending bits for DMA1 Channel3 */
     DMA1->IFCR |= DMA1_Channel3_IT_Mask;
   }
   else if (DMAy_Channelx == DMA1_Channel4)
   {
     /* Reset interrupt pending bits for DMA1 Channel4 */
     DMA1->IFCR |= DMA1_Channel4_IT_Mask;
   }
   else if (DMAy_Channelx == DMA1_Channel5)
   {
     /* Reset interrupt pending bits for DMA1 Channel5 */
     DMA1->IFCR |= DMA1_Channel5_IT_Mask;
   }
   else if (DMAy_Channelx == DMA1_Channel6)
   {
     /* Reset interrupt pending bits for DMA1 Channel6 */
     DMA1->IFCR |= DMA1_Channel6_IT_Mask;
   }
   else if (DMAy_Channelx == DMA1_Channel7)
   {
     /* Reset interrupt pending bits for DMA1 Channel7 */
     DMA1->IFCR |= DMA1_Channel7_IT_Mask;
   }
   else if (DMAy_Channelx == DMA2_Channel1)
   {
     /* Reset interrupt pending bits for DMA2 Channel1 */
     DMA2->IFCR |= DMA2_Channel1_IT_Mask;
   }
   else if (DMAy_Channelx == DMA2_Channel2)
   {
     /* Reset interrupt pending bits for DMA2 Channel2 */
     DMA2->IFCR |= DMA2_Channel2_IT_Mask;
   }
   else if (DMAy_Channelx == DMA2_Channel3)
   {
     /* Reset interrupt pending bits for DMA2 Channel3 */
     DMA2->IFCR |= DMA2_Channel3_IT_Mask;
   }
   else if (DMAy_Channelx == DMA2_Channel4)
   {
     /* Reset interrupt pending bits for DMA2 Channel4 */
     DMA2->IFCR |= DMA2_Channel4_IT_Mask;
   }
   else
   {
     if (DMAy_Channelx == DMA2_Channel5)
     {
       /* Reset interrupt pending bits for DMA2 Channel5 */
       DMA2->IFCR |= DMA2_Channel5_IT_Mask;
     }
   }
}

Круче только индусский код для функции GetTomorrowDate().

Цитата: VasiliSk от 30 Окт. 2014 в 04:30
Я в своей первой версии борткомпа использовал INA213 для усиления сигнала с шунта, но мне она не понравилась, плавает сильно и шум на выходе. Теперь пробую на ОУ с авто-коррекцией нуля.
Я использовал INA220 в одном проекте, она мне понравилась. Безо всякой калибровки выдаёт правильный ток и напряжение с достаточно высокой точностью, шумов не заметил. Правда, там она подключена не к шунту а к датчику тока с выходом 0-5В, пришлось ставить аттенюатор на операционном усилителе :) И да, автонуль тоже пришлось делать, выход токовой рамки плавает, зараза.

А в какой момент Вы собираетесь обнулять выход? У меня сделано так: если датчик тока на протяжении существенного времени (десятки секунд) показывает небольшой ток (до 200 миллиампер, при диапазоне от -600 до +600А), я считаю что это на самом деле нулевой ток, просто ноль сдвинулся, и перекалибровываю ноль. Но как-то это не очень кошерно.


Добавлено 30 Окт 2014 в 17:12:06

Цитата: Indiсtа Саusа от 30 Окт. 2014 в 03:09
Любопытно, подписываюсь. Важно ведь не только концепцию придумать но и уметь это материализовать.
Спасибо, а то я уж подумывал не слишком ли подробно всё описываю.
Не приближаю ли, так сказать, окончательную победу энтропии над порядком в масштабе вселенной.
С уважением,
Андрей

Поражаю масштабностью некопмпетентность (ц) из лички

Silvaticus

#120
[user]zap[/user], я внимательно прочитаю тему, тогда поделюсь своими соображениями.

GPS-сенсор будет интегрирован?
Если да, то можно реализовать "тревожную кнопку" и/или "звонок другу" с передачей географических координат. А передав со смарта  долготу и широту точки назначения, можно воспользоваться  простейшей навигацией — движение по азимуту, подойдет и для дорог и для полного бездорожья, да и запись трека никогда не будет лишней. Правда в таком случае, без внешнего питания не обойтись.
Модератор 95% времени живущий в единственной теме флудилки это глобальный флудер с фееричным статусом модера.
Нередко красный фломастер это признак бессилия оппонента.

mevial

Цитата: zap от 30 Окт. 2014 в 17:10

   /* Disable the selected DMAy Channelx */
   DMAy_Channelx->CCR &= (uint16_t)(~DMA_CCR1_EN);
   
   /* Reset DMAy Channelx control register */
   DMAy_Channelx->CCR  = 0;

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

zap

#122
Цитата: mevial от 30 Окт. 2014 в 17:40
Особенно брутальный фрагмент.
На самом деле, как оказалось, чтобы остановить DMA в CCR надо писать два раза, почти неважно что, главное чтобы бит ENable был сброшен.
У меня два раза подряд в CCR пишется 0. Пока так не сделал, остановить DMA полностью не получалось. Заполняешь количество пересылок - а оно тут же поскакало.
И главное, всё это абсолютно недокументирвоано :facepalm:.
Так что в выделенном фрагменте имеется недокументированная сермяжная правда.

Весь остальной код, чуточку неоптимизированный, у меня сведён к одной строчке (строка 90).


Добавлено 30 Окт 2014 в 18:10:53

Цитата: Indiсtа Саusа от 30 Окт. 2014 в 17:22
GPS-сенсор будет интегрирован?
Нет, GPS/ГЛОНАСС есть практически в каждом новом телефоне.
Мешать бортовой компьютер и сигнализацию не буду.

Цитата: Indiсtа Саusа от 30 Окт. 2014 в 17:22
Правда в таком случае, без внешнего питания не обойтись.
Питание будет исключительно от бортового аккумулятора.
Литиевая батарейка будет только поддерживать встроенные часы во время спячки.
Это ведь развитие идеи цикланалиста, какой цикланалист на батарейках?

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

Поражаю масштабностью некопмпетентность (ц) из лички

Silvaticus

[user]zap[/user], часто не нужен полноценный навигатор, нужно просто иметь направление на точку (тот же компас, только вместо севера точка назначения). Я не имел в виду сигнализацию, я подразумевал о режиме "позвать на помощь" или "я в беде", который мгновенно срабатывал бы по нажатию хардверной кнопки. Насчет питания я невнимательно прочитал. :)
Модератор 95% времени живущий в единственной теме флудилки это глобальный флудер с фееричным статусом модера.
Нередко красный фломастер это признак бессилия оппонента.

Kullx

[user]Indiсtа Саusа[/user], вы осознаете соотношение раздувания стоимости, усилий на разработку, с полезностью конечного результата?
Купите жпс трекер и не парьте мозги.

P.S.
Направление на точку? Как же эту точку задавать двумя кнопками  :laugh: Перебивая с навигатора в телефоне координаты?

Silvaticus

[user]Kullx[/user], включите мозги и фантазию, тогда у вас все получится.  >:D
Хотя вряд ли, судя по вашим постам копии документов вы набираете каждый раз на клавиатуре вновь и вновь.  :laugh:
Модератор 95% времени живущий в единственной теме флудилки это глобальный флудер с фееричным статусом модера.
Нередко красный фломастер это признак бессилия оппонента.