PCCar.ru - Ваш автомобильный компьютер

Вернуться   PCCar.ru - Ваш автомобильный компьютер > MP3Car ТехИнфа > AndroidCar > Дополнительные устройства

Ответ
 
Опции темы
Старый 06.03.2019, 21:03   #871
mazay66
Старший Пользователь
 
Регистрация: 17.10.2015
Город: Санкт-Петербург
Регион: 78, 98
Машина: Рено Колеос
Сообщений: 576
mazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to all
По умолчанию

Цитата:
Сообщение от Alex15BV Посмотреть сообщение
Сам скетч:
PHP код:
#include <avr/wdt.h>
#include <Mouse.h>
#include <Keyboard.h>
#include <Tablet.h>

// ----- пины Ардуино -----------------

#define KeyAppPin 0     // кнопка APPs
#define KeyModePin 1    // кнопка Mode
#define KeyEncPin 2     // кнопка энкодера
#define EncAcPin 3      // энкодер - канал А
#define EncBcPin 5      // энкодер - канал В
#define KeysPin A0      // кнопки управления
#define MousePin A1     // кнопки джойстика
#define LedPin 6        // светодиод медиа-режима

// ----- рабочие переменные -----------

unsigned long EventStart 0;         // момент нажатия
unsigned long TimePress 0;          // длительность нажатия

// ----- различные флаги --------------

volatile bool RightMove false;      // направления вращения энкодера
volatile bool LeftMove false;    
volatile bool EncPress false;       // нажатия кнопки энкодера
volatile bool AppPress false;       // кнопки APPs
volatile bool MediaMode false;      // кнопки MODE

// ----- обработчики прерываний -------

void EncoderMove() {        // вращение энкодера
  
if (digitalRead(EncBcPin) == HIGH) {
    
RightMove true;
  }
  else {
    
LeftMove true;
  }
}

void KeyEncPress() {        // кнопка энкодера
  
EncPress true;
}

void KeyAppPress() {        // кнопка APPs
  
AppPress true;
}

void KeyModePress() {       // кнопка MODE
  
MediaMode = !MediaMode;
  if (
MediaMode){
    
digitalWrite(LedPinHIGH);
  }
  else {
    
digitalWrite(LedPinLOW);
  }
}

void setup() {
  
pinMode(KeyModePinINPUT_PULLUP);                                          // кнопка "Mode" - управляем интерфейсом / медиа-функциями
  
attachInterrupt(digitalPinToInterrupt(KeyModePin), KeyModePressFALLING);
  
pinMode(KeyAppPinINPUT_PULLUP);                                           // кнопка "APP" - при нажатии список запущеных приложений (ALT/TAB)
  
attachInterrupt(digitalPinToInterrupt(KeyAppPin), KeyAppPressFALLING);
  
pinMode(KeyEncPinINPUT_PULLUP);                                           // кнопка энкодера - при нажатии PLAY/PAUSE либо ENTER/ESCAPE
  
attachInterrupt(digitalPinToInterrupt(KeyEncPin), KeyEncPressFALLING);
  
pinMode(EncAcPinINPUT_PULLUP);                                            // канал-А энкодера - для отслеживания вращения
  
attachInterrupt(digitalPinToInterrupt(EncAcPin), EncoderMoveFALLING);
  
pinMode(EncBcPinINPUT_PULLUP);                                            // канал-В энкодера - для определения направления вращения
  
pinMode(LedPinOUTPUT);
  
digitalWrite(LedPinLOW);

  
analogReference(DEFAULT);           // Aref = 5V, подтягивающий резистор на линии кнопок - 4,7 кОм

  
Keyboard.begin();                   // инициализация USB-HID интерфейсов
  
Mouse.begin();
  
wdt_enable(WDTO_4S);                // Активируем сторожевой таймер с интервалом 4 секунд
}

void loop() {
  
  static 
bool FindKey;                // признак найденной кнопки
  
static int DataKey;                 // значение ADC-кнопки
  
  
if (RightMove) {                    // обработка вращения энкодера: если вращаем вправо - увеличить громкость/стрелка вверх
    
if (MediaMode) {
      
Tablet.vol_up();
      
Tablet.clear();
    }
    else {
      
Keyboard.press(KEY_UP_ARROW);
      
Keyboard.release(KEY_UP_ARROW);
    }
    
RightMove false;
  }

  if (
LeftMove) {                     // если вращаем влево - уменьшаем громкость/стрелка вниз
    
if (MediaMode) {
      
Tablet.vol_down();
      
Tablet.clear();
    }
    else {
      
Keyboard.press(KEY_DOWN_ARROW);
      
Keyboard.release(KEY_DOWN_ARROW);
    }
    
LeftMove false;
  }

  if (
AppPress) {                     // кнопка "APPs"
    
Keyboard.press(KEY_LEFT_ALT);
    while (
digitalRead(KeyAppPin) == LOW) {
      
Keyboard.press(KEY_TAB);
      
Keyboard.release(KEY_TAB);
      
delay(1000);
      
wdt_reset();
    }
    
Keyboard.release(KEY_LEFT_ALT);
    
AppPress false;
  }  
    
  if (
analogRead(MousePin) > 800 && analogRead(KeysPin) > 800 && !EncPress) {   // пока кнопки не нажаты взводим на всякий случай таймер обработки нажатия
    
EventStart millis();
  }
 
  if (
EncPress) {                               // обнаружили факт нажатия кнопки энкодера - определяем длительность нажатия
    
delay(20);
    while (
digitalRead(KeyEncPin) == LOW) {     // пока не отпустим -
      
TimePress millis() - EventStart;        // считаем время нажатия
      
delay(10);
      
wdt_reset();
    }
    if (
TimePress <= 200) {                     // действуем по длительности нажатия, если короткое:
      
if (MediaMode) {                          // в медиа-режиме - play/pause
        
Tablet.play_pause();
        
Tablet.clear();
      }
      else {
        
Keyboard.press(KEY_RETURN);        // в режиме интерфейса - enter
        
Keyboard.release(KEY_RETURN);        
      }
    }
    else {                                 
// если длинное:
      
if (MediaMode) {                     // в медиа-режиме - mute
        
Tablet.mute();
        
Tablet.clear();
      }
      else {                               
// в режиме интерфейса - escape
        
Keyboard.press(KEY_ESC);
        
Keyboard.release(KEY_ESC);        
      }
    }
    
EncPress false;                      // сбрасываем флаг нажатия
  
}

  if (
analogRead(MousePin) < 800) {        // обнаружили факт нажатия кнопки джойстика
    
delay(20);
    
FindKey false;
    
DataKey analogRead(MousePin);
    if (
DataKey 100 && !FindKey) {       // кнопка "UP" - резистор 1 кОм
      
if (MediaMode) {
        
Tablet.forward();
        
Tablet.clear();
        
delay(100);
      }
      else {
        
Mouse.move(0, -100);
      }
    
FindKey true;
    }
    if (
DataKey 350 && !FindKey) {       // кнопка "LEFT" - резистор 2 кОм
      
if (MediaMode) {
        
Tablet.previous();
        
Tablet.clear();
        
delay(100);
      }
      else {
        
Mouse.move(-1000);
      }
    
FindKey true;
    }
    if (
DataKey 600 && !FindKey) {       // кнопка "RIGHT" - резистор 3,9 кОм
      
if (MediaMode) {
        
Tablet.next();
        
Tablet.clear();
        
delay(100);
      }
      else {
        
Mouse.move(1000);
      }
    
FindKey true;
    }
    if (
DataKey 800 && !FindKey) {       // кнопка "DOWN" - резистор 10 кОм
      
if (MediaMode) {
        
Tablet.rewind();
        
Tablet.clear();
        
delay(100);
      }
      else {
        
Mouse.move(0100);
      }
    }
  }
  
  if (
analogRead(KeysPin) < 800) {         // обнаружили факт нажатия кнопки управления
    
delay(20);
    
FindKey false;
    
DataKey analogRead(KeysPin);
    while (
analogRead(KeysPin) < 800) {
      
TimePress millis() - EventStart;
      
delay(10);
      
wdt_reset();
    }
    if (
DataKey 100) {                   // кнопка "Home/Menu" - на землю
      
if (TimePress <= 200) {                     
        
Tablet.home();
        
Tablet.clear();
      }
      else {
        
Keyboard.press(KEY_LEFT_CTRL);
        
Keyboard.press(KEY_ESC);
        
Keyboard.releaseAll();      
      }
    
FindKey true;  
    }
    if (
DataKey 350 && !FindKey) {      // кнопка "Enter/Esc" - резистор 1 кОм
      
if (TimePress <= 200) {                     
        
Mouse.click(MOUSE_LEFT);
      }
      else {
        
Mouse.click(MOUSE_RIGHT);
      }
    }                      
  }
  
wdt_reset();                            // производим периодический сброс таймера

Подскажите, с какой целью в скетч добавлена функция watchdog? Механизм watchdog встроен в контроллеры Atmega, но, не всякий загрузчик (bootloader) Arduino правильно обрабатывает эту функцию и система заходит в жестокий bootloop. Как в этой ситуации ведет себя про микро?

Последний раз редактировалось admin; 20.05.2019 в 11:22.
mazay66 вне форума   Ответить с цитированием
Старый 06.03.2019, 21:21   #872
Alex15BV
Пользователь
 
Регистрация: 01.11.2017
Возраст: 45
Город: Лобня
Регион: 50, 90, 150
Машина: BMW 530D Touring
Сообщений: 67
Alex15BV is a jewel in the roughAlex15BV is a jewel in the roughAlex15BV is a jewel in the rough
По умолчанию

Цитата:
Сообщение от mazay66 Посмотреть сообщение
Подскажите, с какой целью в скетч добавлена функция watchdog? Механизм watchdog встроен в контроллеры Atmega, но, не всякий загрузчик (bootloader) Arduino правильно обрабатывает эту функцию и система заходит в жестокий bootloop. Как в этой ситуации ведет себя про микро?
Добрый вечер.
Добавлена именно по прямому назначению: сбросить контроллер в случае зависания программы. Когда начал заниматься этим вопросом - тоже помучался. И оптибут пробовал, и МК убивал, и читал кучу статей всяких разных...
А потом товарищ показал, как он сделал у себя: я повторил, и оно заработало "как есть" - с оригинальным бутлоадером и вышеизложеным скетчем.
Alex15BV вне форума   Ответить с цитированием
Старый 06.03.2019, 21:57   #873
mazay66
Старший Пользователь
 
Регистрация: 17.10.2015
Город: Санкт-Петербург
Регион: 78, 98
Машина: Рено Колеос
Сообщений: 576
mazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to all
По умолчанию

Т.е оптибут не обязательно? Оригинальный бутлоадер не уйдет в bootloop? А насколько часто зависает устройства без отсутствия этой функции?
P.S. Я вот думаю, что mic5219 можно исключить из схемы, если питать устройство стабилизированным напряжением планшета или mp1584. ИХМО, это тот случай, когда на плате про микро предусмотрена возможность замыкания перемычки J1
mazay66 вне форума   Ответить с цитированием
Старый 06.03.2019, 22:13   #874
Alex15BV
Пользователь
 
Регистрация: 01.11.2017
Возраст: 45
Город: Лобня
Регион: 50, 90, 150
Машина: BMW 530D Touring
Сообщений: 67
Alex15BV is a jewel in the roughAlex15BV is a jewel in the roughAlex15BV is a jewel in the rough
По умолчанию

Цитата:
Сообщение от mazay66 Посмотреть сообщение
Т.е оптибут не обязательно? Оригинальный бутлоадер не уйдет в bootloop? А насколько часто зависает устройства без отсутствия этой функции?
P.S. Я вот думаю, что mic5219 можно исключить из схемы, если питать устройство стабилизированным напряжением планшета или mp1584. ИХМО, это тот случай, когда на плате про микро предусмотрена возможность замыкания перемычки J1
1. Когда в первый раз добавил собаку - МК ушёл в бутлуп, пришлось перешивать через программатор. Прошил оптибут - вообще Дуню убил, восстанавливал путем подмены файлов в системных папках ИДЕ и ручного редактирования конфигов. Вернул всё назад и отказался от ВДТ... А потом вдруг заработало само. За всё время экспериментов зависания были два раза (оно было на промежуточных версиях, но "береженого Бог бережёт"). На крайней версии скетча глюков не было пока.
2. Я просто перенёс на плату Дуню один-в-один. Можно, конечно, питание сделать по нормальному - но я просто не задумался об этом (коли за 200 рублей мне дают полный набор комплектующих)...
Alex15BV вне форума   Ответить с цитированием
Старый 07.03.2019, 00:32   #875
skanch
Модератор
 
Аватар для skanch
 
Регистрация: 19.01.2010
Возраст: 53
Город: Санкт-Петербург
Регион: 78, 98
Машина: Mitsubishi Lancer X
Сообщений: 1,804
skanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant future
По умолчанию

Цитата:
Сообщение от mazay66 Посмотреть сообщение
... Я вот думаю, что mic5219 можно исключить из схемы, если питать устройство стабилизированным напряжением планшета или mp1584...
С Pro Micro работал мало, в основном с Pro Mini, но стабилизаторы на этих китайских платах стоят как правило одинаковые. И если сравнивать потребление платой (Pro Mini) на родном стабилизаторе и от MP1584, то mic5219 - это почти 25-30 мА, а MP1584 9-12мА. И ещё один момент: по даташиту максимальное напряжение на mic5219 до 20В, но почему-то мрут уже на 14В... Поэтому если делаешь с "нуля", лучше питание на MP1584.
skanch вне форума   Ответить с цитированием
Старый 07.03.2019, 10:30   #876
mazay66
Старший Пользователь
 
Регистрация: 17.10.2015
Город: Санкт-Петербург
Регион: 78, 98
Машина: Рено Колеос
Сообщений: 576
mazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to all
По умолчанию

skanch, Это все верно, если питать схему джойстик от бортовой сети авто. Но как я понял, в данном случае, устройство питается от хаба. Т.е. получает уже стабилизированное напряжение +5В. И далее по схеме модуля Про Микро, через диод Шотки идет на понижающий стабилизатор 5В - MIC5219. Получается "масло масляное". А вот если питать джойстик от бортовой сети, а не от хаба, то понижающий стабилизатор нужен.
mazay66 вне форума   Ответить с цитированием
Старый 07.03.2019, 11:08   #877
skanch
Модератор
 
Аватар для skanch
 
Регистрация: 19.01.2010
Возраст: 53
Город: Санкт-Петербург
Регион: 78, 98
Машина: Mitsubishi Lancer X
Сообщений: 1,804
skanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant future
По умолчанию

Цитата:
Сообщение от mazay66 Посмотреть сообщение
skanch, Это все верно, если питать схему джойстик от бортовой сети авто. Но как я понял, в данном случае, устройство питается от хаба. Т.е. получает уже стабилизированное напряжение +5В. И далее по схеме модуля Про Микро, через диод Шотки идет на понижающий стабилизатор 5В - MIC5219. Получается "масло масляное". А вот если питать джойстик от бортовой сети, а не от хаба, то понижающий стабилизатор нужен.
Если ProMicro используется по назначению в виде "джойстика", то питание идёт по линии USB и при этом любое внешнее питание должно быть отключено. На "фирменных" платах Arduino Micro стоят ключи автоматического отключения линии внешнего питания при подключении USB штеккера. На китайских клонах этого нет. Если повторить трассировку печатной платы китайского клона, то просто стабилизатор не использовать, а линии питания VCC, VCC1, AVCC, AVCC1, UVCC и VBUS должны быть соединены и питание заводить по линии от HUB-а. Или делать отдельный DC-DC преобразователь прямо на плате, но линию "плюс" от USB нужно разрывать.
skanch вне форума   Ответить с цитированием
Старый 14.05.2019, 12:34   #878
mazay66
Старший Пользователь
 
Регистрация: 17.10.2015
Город: Санкт-Петербург
Регион: 78, 98
Машина: Рено Колеос
Сообщений: 576
mazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to allmazay66 is a name known to all
По умолчанию

Цитата:
Сообщение от Alex15BV Посмотреть сообщение
Если честно, я выкладываю свои поделки скорее как "идеи", нежели как "проекты"... Как их использовать (копировать полностью, или брать только нужное, а или игнорировать вовсе) - это уж каждый сам решает.
Отпишусь и я по результатам теста собранного изделия. За основу взята идея уважаемого Алексея (Alex15BV). Немного изменена схема питания платы (убрал лишние, на мой взгляд, элементы, добавил пару диодов). Вообщем ничего существенного. Частично изменил функционал и назначение кнопок, для чего пришлось "поковырять" скетч. В результате, получилось, что 9 кнопок и энкодер выполняют более 25 различных задач, которые полностью перекрыли мои "хотелки". Зафиналил два изделия. Распаивал параллельно две платы в надежде на то, что хоть одна да заработает. Заработали обе, нигде не "накосячил".
Подобрал корпус. На мой взгляд, немного не эстетично. Тут, ИХМО, лучше встраивать плату в обшивку/отделку автомобиля, предварительно определившись с местом в авто. Сейчас, в Рено Колеос, это выглядит как на фото. Есть желание убрать корпус и разместить плату джойстика в этой же нише, закрыв её. Ну и что бы "разбавить сухой" текст, выкладываю несколько фото и ссылку на видео получившегося устройства.
P.S. После того, как были потрачено много времени, нервов и денег в поисках подходящего устройства ( на фото только некоторые из них) для управления автомобильным планшетом, наконец-то обрел то, что хотел. Основные недостатки трекбола, клавиатуры и пр. кнопок - не полный функционал управления, не эстетичный вид и габариты, опасность/невозможность использования в движении, т.к. требуется концентрация внимания на устройстве. В получившемся джойстике управление интуитивно понятно и не требует отвлечения. Еще раз спасибо Алексею за идею.
Миниатюры
Нажмите на изображение для увеличения
Название: IMG_20190513_165739.jpg
Просмотров: 17
Размер:	65.5 Кб
ID:	51201   Нажмите на изображение для увеличения
Название: IMG_20190513_165747.jpg
Просмотров: 19
Размер:	73.7 Кб
ID:	51202   Нажмите на изображение для увеличения
Название: IMG_20190512_185302.jpg
Просмотров: 18
Размер:	106.1 Кб
ID:	51203   Нажмите на изображение для увеличения
Название: IMG_20190514_112111.jpg
Просмотров: 17
Размер:	102.1 Кб
ID:	51204  
mazay66 вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 3 (пользователей: 0 , гостей: 3)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.



Часовой пояс GMT +4, время: 04:54.


Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
Перевод: zCarot
Яндекс.Метрика