Рубрика «diy или сделай сам» - 301

Что было не так

Что было не так c предыдущим принтером:

  • Шум — заглушал телевизор
  • Размеры — 40x30x80 на стол не поставить (не влез даже на балкон, точнее влез но катушка с пластиком уже не влазила)
  • Вес — 8кг (частично из за Nema23 и тяжелых мебельных щитов)

Что мне хотелось

Шум — убрать шум на минимум (в идеале только звук шаговиков в 32 микрошаговом режиме). Один из самых громких источников шума в дельта механике это линейные направляющих и линейные подшипники, в природе лечится рельсовыми направляющими или нехитрой конструкцией с алюминиевым профилем и подшипников скольжения одетыми в оболочку (Kossel). Как по мне, в вертикальном состоянии линейные подшипники и линейные направляющие работают не в правильном режиме.

Размеры — хочется принтер который легко умещается на стол с творческим беспорядком. Далее — размер печатной области должен быть не меньше чем 10x10x10+.
Почему я решил пожертвовать размерами печатной области — а потому что за полгода почти каждодневной печати мне не разу не понадобилось напечатать что то больше, чем 10x10. Я принял решение что мне этой области хватит с головой и даже останется.
Также, на прогрев области 10x10 надо в 4 раза меньше мощности блока питания, а это позволяет использовать обычные внешние блоки питания — я влез всего в 60ватт (с подогреваемой платформой), у меня 8.5A 12v. Большим плюсом является внешний блок питания, который лежит под столом и не занимает место.

Вес — предыдущий параметр уже позволяет серьезно уменьшить вес, плюс укороченные Nema17 (меньший момент, но это не проблема). Cтруктурная сложность для небольших конструкций достигается легче и легкими материалами.

Читать полностью »

Всем привет.

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

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

Новое универсальное 2DIN головное устройство на базе Android для автомобиля. Построй свою мечту - 1

Кто-то скажет: «Засунули Nexus 7 в приборную панель», и отчасти будут правы. На тематических ресурсах Nexus 7 часто используется для сборок подобного типа (у меня у самого N7 2013). Но мы хотим выйти за рамки «просто планшета в авто» и создать достойный продукт.
В связи с тем, что одну из центральных ролей в нашей жизни сейчас играет смартфон, предполагается максимально интегрировать его в будущую систему. По сути сделать смарт — сервером, а головное устройство (далее ГУ) терминалом. Технологий и протоколов для осуществления похожего функционала существует целый набор: Android Auto, Apple CarPlay, MirrorLink, Miracast, MHL и т.д.
Если вам интересна судьба данного устройства, если вы хотите поучаствовать в его создании, поделиться опытом, подсказать интересные решения определить его конечный вид — добро пожаловать под кат.Читать полностью »

image
Привет, Гик Таймс!
Сегодня я поведаю вам одну не очень интересную историю о том, как создал простую игровую консоль на базе arduino и сделал несложную игру для нее в моем любимом игровом движке — Unity.

Игры

Вот уже почти четыре года я занимаюсь разработкой игр на популярном игровом движке Unity (ранее Unity3D). За это время я успел создать несколько небольших игр для мобильных устройств, а также объемный многопользовательский проект.
Это область для меня очень интересна и доставляет огромное удовольствие работать в ней.

Девайсы

Но иногда появляется желание попробовать что-то новое, и в один из таких дней я решил попробовать arduino.
Мне стало очень интересно, как создавать свои собственные устройства и как их программировать. Почему arduino? В интернете и даже на том-же хабре и гик таймс море постов о том, почему стоит брать arduino. Но отмечу, что для меня решающим фактором в выборе arduino является простота в использовании.

А как это объединить?

Однажды на просторах интернета я наткнулся на запись о том, как один из пользователей собрал свою простенькую игровую консоль на базе arduino, снабдив ее маленьким жк дисплеем 84x48 пикселей и написал на нее пару простых игр: понг и арканоид.
Эта разработка меня очень заинтересовала, и я решил создать свою версию игровой консоли на базе микроконтроллера atmega328.
Читать полностью »

Ведение

Попав в отпуске в город на Неве и посетив множество красивых мест, я все таки, вечерами за чашкой пива, разбирался с UARTом. Тем более, что я купил не плохие наушники Fisher FA011, к которым пришлось прикупить USB SOUND BLASTER X-FI HD и хотел послушать музыку.
Предыдущие статьи вначале переехали на Geektime потом я обратно их перегнал, даже и не знаю, куда теперь их деть :)
Но так на всякий случай они тут:
STM32, C++ и FreeRTOS. Разработка с нуля. Часть 1
STM32, C++ и FreeRTOS. Разработка с нуля. Часть 2 и
STM32, C++ и FreeRTOS. Разработка с нуля. Часть 3 (LCD и Экраны)

UART

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

Special function types can be used for static member functions. For example, in the
following example, the function handler is declared as an interrupt function:

class Device
{
 static __irq void handler();
};

Но вот незадача, для Cortex M такой способ не подходит и

On ARM Cortex-M, an interrupt service routine enters and returns in the same way as a
normal function, which means no special keywords are required. Thus, the keywords
__irq, __fiq, and __nested are not available when you compile for ARM Cortex-M.

These exception function names are defined in cstartup_M.c and cstartup_M.s.
They are referred to by the library exception vector code:
NMI_Handler
HardFault_Handler
MemManage_Handler
BusFault_Handler

The vector table is implemented as an array. It should always have the name
__vector_table,

Или по простому, ваш обработчик прерывания должен иметь такое же имя, какое он имеет в таблице векторов определенной в startup файле. Это делается с помощью специального ключевого слова — слабой ссылки __weak (в ассемблере PUBWEAK), которая означает, что данное определение будет использоваться до тех пора, пока не найдется хотя бы одно совпадающее по написанию без ключевого слова __week. Ну т.е., если вы определите функцию с точно таким же именем без этой директивы, то компилятро будет использовать это определение, а если не определите, то которое помечено __weak.
Понятное дело, что я не могу в файл startup_stm32l1xx_md.s или startup_stm32l1xx_md.с вставить С++ имя статического метода типа cUart::USART2_IRQHandler(), ассемблер его просто не поймет.
А просто «USART2_IRQHandler» не совпадает с определением «cUart::USART2_IRQHandler()».
Можно использовать extern «C» { void USART2_IRQHandler(void) {...}}, но это означает, что я тут буду делать встаки из Си, что мне совсем не надо, и вообще доступа из такой функции к атрибутам моего класса, например буферу — не будет, и надо будет городить кучу некрасивого кода :).
Поэтому, я решил пойти другим путем и создать файл startup_stm32l1xx_md.cpp. Поиск в интернете обнаружил, что точно такая же проблема была у некоторых людей
В общем идея заключается в следующем: Определяем startup_stm32l1xx_md.cpp в классы со статическими методами (которые и будут являться обработчиками прерываний), создаем таблицу __vector_table, где на каждом из векторов прерываний стоит указатель на на эти статические методы. Дальше делаем __weak определение каждого метода
И теперь когда в коде компилятор видет реализацию void cUart1::handler(), он не задумываясь берет её. Конечно же при этом ваши классы и методы должны называться точь в точь так, как они определены в startup_stm32l1xx_md.cpp.
Нужно еще не забыть про функции FreeRtos: vPortSVCHandler, xPortPendSVHandler, xPortSysTickHandler и поставить их на нужное прерывание и вуаля — все работает:

startup_stm32l1xx_md.cpp

#pragma language = extended
#pragma segment = "CSTACK"
extern "C" void __iar_program_start( void );
extern "C" void vPortSVCHandler(void);
extern "C" void xPortPendSVHandler(void);
extern "C" void xPortSysTickHandler(void);
class cNMI
{
public:
    static void handler(void);
};
class cHardFault
{
public:
    static void handler(void);
};
class cMemManage
{
public:
    static void handler(void);
};
class cBusFault
{
public:
    static void handler(void);
};
class cUsageFault
{
public:
    static void handler(void);
};
class cDebugMon
{
public:
    static void handler(void);
};
class cWindowWatchdog
{
public:
    static void handler(void);    
};
class cPvd
{
public:
    static void handler(void);    
};
class cTamperTimeStamp
{
public:
    static void handler(void);    
};
class cRtcWakeup
{
public:
    static void handler(void);    
};
class cFlash
{
public:
    static void handler(void);    
};
class cRcc
{
public:
    static void handler(void);    
};
class cExti
{
public:
    static void line0Handler(void);
    static void line1Handler(void);
    static void line2Handler(void);
    static void line3Handler(void);
    static void line4Handler(void);
    static void line9Handler(void);
    static void line15_10Handler(void);
};
class cDma
{
public:
    static void channellHandler(void);    
    static void channel2Handler(void);    
    static void channel3Handler(void);    
    static void channel4Handler(void);    
    static void channel5Handler(void);    
    static void channel6Handler(void);    
    static void channel7Handler(void);    
};
class cAdc
{
public:
    static void handler(void);    
};
class cDac
{
public:
    static void handler(void);    
};
class cUsb
{
public:
    static void highPriorityHandler(void);    
    static void lowPriorityHandler(void);
    static void fsWakeupHandler(void);
};
class cComp
{
public:
    static void handler(void);    
};
class cLcdDriver
{
public:
    static void handler(void);    
};
class cTim9
{
public:
    static void handler(void);    
};
class cTim2
{
public:
    static void handler(void);    
};
class cTim3
{
public:
    static void handler(void);    
};
class cTim4
{
public:
    static void handler(void);    
};
class cTim10
{
public:
    static void handler(void);    
};
class cTim6
{
public:
    static void handler(void);    
};
class cTim7
{
public:
    static void handler(void);    
};
class cTim11
{
public:
    static void handler(void);    
};
class cI2C1
{
public:
    static void eventHandler(void);
    static void errorHandler(void);
};
class cI2C2
{
public:
    static void eventHandler(void);
    static void errorHandler(void);
};
class cSpi1
{
public:
    static void handler(void);    
};
class cSpi2
{
public:
    static void handler(void);    
};
class cUart1
{
public:
    static void handler(void);    
};
class cUart2
{
public:
    static void handler(void);    
};
class cUart3
{
public:
    static void handler(void);    
};
class cRtcAlarm
{
public:
    static void handler(void);    
};
typedef void( *intfunc )( void );
typedef union { intfunc __fun; void * __ptr; } intvec_elem;
// The vector table is normally located at address 0.
// When debugging in RAM, it can be located in RAM, aligned to at least 2^6.
// If you need to define interrupt service routines,
// make a copy of this file and include it in your project.
// The name "__vector_table" has special meaning for C-SPY:
// it is where the SP start value is found, and the NVIC vector
// table register (VTOR) is initialized to this address if != 0.
#pragma location = ".intvec"
extern "C" const intvec_elem __vector_table[] =
{
  { .__ptr = __sfe( "CSTACK" ) },
  __iar_program_start,

  cNMI::handler,
  cHardFault::handler,
  cMemManage::handler,
  cBusFault::handler,
  cUsageFault::handler,
  0,
  0,
  0,
  0,
  vPortSVCHandler,             //функции freeRTOS не трогать!
  cDebugMon::handler,
  0,
  xPortPendSVHandler,          //функции freeRTOS не трогать!
  xPortSysTickHandler,         //функции freeRTOS не трогать!
  //External Interrupts
  cWindowWatchdog::handler,    //Window Watchdog
  cPvd::handler,               //PVD through EXTI Line detect
  cTamperTimeStamp::handler,   //Tamper and Time Stamp
  cRtcWakeup::handler,         //RTC Wakeup
  cFlash::handler,             //FLASH
  cRcc::handler,               //RCC
  cExti::line0Handler,         //EXTI Line 0
  cExti::line1Handler,         //EXTI Line 1
  cExti::line2Handler,         //EXTI Line 2
  cExti::line3Handler,         //EXTI Line 3
  cExti::line4Handler,         //EXTI Line 4
  cDma::channellHandler,       //DMA1 Channel 1
  cDma::channel2Handler,       //DMA1 Channel 2
  cDma::channel3Handler,       //DMA1 Channel 3
  cDma::channel4Handler,       //DMA1 Channel 4
  cDma::channel5Handler,       //DMA1 Channel 5
  cDma::channel6Handler,       //DMA1 Channel 6
  cDma::channel7Handler,       //DMA1 Channel 7
  cAdc::handler,               //ADC1
  cUsb::highPriorityHandler,   //USB High Priority
  cUsb::lowPriorityHandler,    //USB Low  Priority
  cDac::handler,               //DAC
  cComp::handler,              //COMP through EXTI Line
  cExti::line9Handler,         //EXTI Line 9..5
  cLcdDriver::handler,         //LCD
  cTim9::handler,               //TIM9
  cTim10::handler,             //TIM10
  cTim11::handler,             //TIM11
  cTim2::handler,             //TIM2
  cTim3::handler,              //TIM3
  cTim4::handler,              //TIM4
  cI2C1::eventHandler,         //I2C1 Event
  cI2C1::errorHandler,         //I2C1 Error
  cI2C2::eventHandler,         //I2C2 Event
  cI2C2::errorHandler,         //I2C2 Error
  cSpi1::handler,              //SPI1
  cSpi2::handler,              //SPI2
  cUart1::handler,             //USART1
  cUart2::handler,             //USART2
  cUart3::handler,             //USART3
  cExti::line15_10Handler,     //EXTI Line 15..10
  cRtcAlarm::handler,          //RTC Alarm through EXTI Line
  cUsb::fsWakeupHandler,       //USB FS Wakeup from suspend
  cTim6::handler,              //TIM6
  cTim7::handler                //TIM7
};
__weak void cNMI::handler()          { while (1) {} }
__weak void cHardFault::handler()    { while (1) {} }
__weak void cMemManage::handler()    { while (1) {} }
__weak void cBusFault::handler()     { while (1) {} }
__weak void cUsageFault::handler()   { while (1) {} }
__weak void cDebugMon::handler()     { while (1) {} }
__weak void cWindowWatchdog::handler()  { while (1) {} }
__weak void cPvd::handler()             { while (1) {} }
__weak void cTamperTimeStamp::handler() { while (1) {} }
__weak void cRtcWakeup::handler()       { while (1) {} }
__weak void cFlash::handler()           { while (1) {} }
__weak void cRcc::handler()             { while (1) {} }
__weak void cExti::line0Handler()       { while (1) {} }
__weak void cExti::line1Handler()       { while (1) {} }
__weak void cExti::line2Handler()       { while (1) {} }
__weak void cExti::line3Handler()       { while (1) {} }
__weak void cExti::line4Handler()       { while (1) {} }
__weak void cExti::line9Handler()       { while (1) {} }
__weak void cExti::line15_10Handler()   { while (1) {} }
__weak void cDma::channellHandler()     { while (1) {} }
__weak void cDma::channel2Handler()     { while (1) {} }
__weak void cDma::channel3Handler()     { while (1) {} }
__weak void cDma::channel4Handler()     { while (1) {} }
__weak void cDma::channel5Handler()     { while (1) {} }
__weak void cDma::channel6Handler()     { while (1) {} }
__weak void cDma::channel7Handler()     { while (1) {} }
__weak void cAdc::handler()             { while (1) {} }
__weak void cUsb::fsWakeupHandler()     { while (1) {} }
__weak void cUsb::highPriorityHandler() { while (1) {} }
__weak void cUsb::lowPriorityHandler()  { while (1) {} }
__weak void cDac::handler()             { while (1) {} }
__weak void cComp::handler()            { while (1) {} }
__weak void cLcdDriver::handler()       { while (1) {} }
__weak void cTim2::handler()            { while (1) {} }
__weak void cTim3::handler()            { while (1) {} }
__weak void cTim4::handler()            { while (1) {} }
__weak void cTim6::handler()            { while (1) {} }
__weak void cTim7::handler()            { while (1) {} }
__weak void cTim9::handler()            { while (1) {} }
__weak void cTim10::handler()           { while (1) {} }
__weak void cTim11::handler()           { while (1) {} }
__weak void cI2C1::errorHandler()       { while (1) {} }
__weak void cI2C1::eventHandler()       { while (1) {} }
__weak void cI2C2::errorHandler()       { while (1) {} }
__weak void cI2C2::eventHandler()       { while (1) {} }
__weak void cSpi1::handler()            { while (1) {} }
__weak void cSpi2::handler()            { while (1) {} }
__weak void cUart1::handler()           { while (1) {} }
__weak void cUart2::handler()           { while (1) {} }
__weak void cUart3::handler()           { while (1) {} }
__weak void cRtcAlarm::handler()        { while (1) {} }
extern "C" void __cmain( void );
extern "C" __weak void __iar_init_core( void );
extern "C" __weak void __iar_init_vfp( void );

#pragma required=__vector_table
void __iar_program_start( void )
{
  __iar_init_core();
  __iar_init_vfp();
  __cmain();
}

image

Читать полностью »

image
Джим Пэйн и Perlan 2

Любители и энтузиасты авиации собрались на прошлой неделе в городе Ошкош американского штата Висконсин, где проходило авиашоу экспериментальных летательных аппаратов Experimental Aircraft Association AirVenture. Гвоздём программы стал планёр Perlan 2, который в следующем году готовят для нового мирового рекорда высоты. На этом планёре авторы проекта планируют преодолеть планку в 30 км.

Оптимизм авторов основан не на пустом месте. Основатель проекта Эйнар Эневолдсон и инвестор Стив Фоссет в 2006 году на планёре Perlan в качестве пилотов уже установили мировой рекорд, поднявшись на недостижимую до тех пор для планёров высоту в 15460 метров.

Мечта человечества о полёте начала всерьёз реализовываться лишь в начале 20-го века (если не ударяться в теории о космических кораблях в пустыне Наска или Колумбийских золотых самолётах). Смешные «этажерки», поднимавшиеся на сотни метров, ко Второй мировой войне превратились в винтовые самолёты, немного не долетавшие до 20 км. Высоты в 30 км и более покорились уже реактивным самолётам, и, конечно, космическим ракетам.

Энтузиасты-планеристы наслаждаются многочасовыми полётами и могут пролететь на сотни и тысячи километров от места старта, но высота их полётов обычно ограничена как правилами полётов (нижняя часть облаков), так и физической возможностью безмоторного ЛА.

Планёр для набора высоты использует восходящие потоки воздуха. Это может быть нагретый воздух, поток обтекания (там, где ветер сталкивается с вертикальным препятствием), или же волновые потоки – самые мощные, стоячие воздушные волны в атмосфере планеты. Именно последние позволяют пилотам устанавливать рекорды высоты.
Читать полностью »

Как сделать парковку игровой компании неотразимой (одобрено Black Mesa) - 1

Все сотрудники Plarium настолько обожают видеоигры, что готовы рисковать жизнью, каждый день проезжая под барнаклом. Идею того, как сделать парковку интересной, подсказало само помещение – оно сильно напоминает сеттинг Half-Life. Недолго думая, мы решили отдать должное любимой игре, и в итоге у нас поселился замечательный сосед. Для нас он не какой-то там элемент декора, а друг детства – не самый добрый, но чертовски обаятельный. Сегодня мы расскажем о его «внутреннем мире», способе крепления к потолку и о том, почему у него нет языка и слизи.
Читать полностью »

Недавно сбылась моя мечта по оптимальному — на мой взгляд устройству для домашнего комбайна. Изучая опыт других, я понимал, что правильный выбор «железа» — это ключ к успеху. Итак, что я хотел водрузить для одновременной работе на NUC:

— NVR для 3-4 HD IP-камер;
— «контроллер» для умного дома;
— KODI (XMBC) медиа-плеер для IP-телевидения;
— Ну конечно, торренто-качалку.

Комбайн должен работать в режиме 24/7/356. Распишу каждый пункт, что бы было понятны мои мотивы.
Читать полностью »

Сегодня в фокусе нашего внимания конструктор 3D фрезерного станка.

В предыдущей публикации мы остановились на вопросе настройки слайсера Skeinforge.

Собственно с этого места поподробнее. Итак, нажимаем кнопку «Настройка»
Читать полностью »

Мой обычный вечер — это посиделки за компьютером. Холодными вечерами частенько появлялось желание сделать моё место отдыха комфортнее. Точнее, периодически было просто холодно ногам. Идеи были различные, вплоть до покупки USB тапочек с подогревом. Однако, все они казались мне нелепыми и отметались. И вот однажды, просматривая YouTube канал одного из любителей Arduino, я наткнулся на видео, где рассказывалось про инфракрасную плёнку. Увидев эту плёнку, я сразу понял: «Вот то, что мне надо!»

Данный проект можно кратко описать так: я положил кусок инфракрасной плёнки под дополнительный слой паркета, добавив к нему систему автоматического управления с помощью Arduino, нескольких датчиков и VB.NET. Теперь по порядку, что и как получилось.

«Почти умный» тёплый пол на Arduino - 1
Читать полностью »

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

Аудио мультирум своими руками. Многокомнатная музыкальная система на основе бесплатного Logitech Media Server - 1
Проект Tobias на основе HiFiBerry

Один из вопросов, удивляющих своим постоянством — как организировать музыкальную систему на объекте таким образом, чтобы было легко включить её в единый интерфейс управления домом, наравне с освещением, климатом и другими системами. Вспоминая, что сам в первый раз делал это с большими сложностями и ошибками, я решил описать этот процесс подробнее для всех интересующихся.
Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js