Перейти к содержанию

Регулятор громкости на Attiny85 засыпает..


a2a

Рекомендуемые сообщения

Всем привет. Прошу помощи в вопросе, в котором я ничего не понимаю.

Попробую на пальцах. Есть Платка Digispark на 85тиньке и энкодер. Это что-то вроде аналогового регулятора громкости в винде. Очень удобно. Одно но- сабж не включается после ребута или сна компьютера.

Код я прошивал через Arduino IDE. Код

Spoiler

// see tutorial at http://learn.adafruit.com/trinket-usb-volume-knob

#include "TrinketHidCombo.h"

#define PIN_ENCODER_A 0
#define PIN_ENCODER_B 2
#define TRINKET_PINx  PINB
#define PIN_ENCODER_SWITCH 1

static uint8_t enc_prev_pos   = 0;
static uint8_t enc_flags      = 0;
static char    sw_was_pressed = 0;

void setup()
{
  // set pins as input with internal pull-up resistors enabled
  pinMode(PIN_ENCODER_A, INPUT);
  pinMode(PIN_ENCODER_B, INPUT);
  digitalWrite(PIN_ENCODER_A, HIGH);
  digitalWrite(PIN_ENCODER_B, HIGH);

  pinMode(PIN_ENCODER_SWITCH, INPUT);
  // the switch is active-high, not active-low
  // since it shares the pin with Trinket's built-in LED
  // the LED acts as a pull-down resistor
  digitalWrite(PIN_ENCODER_SWITCH, LOW);

  TrinketHidCombo.begin(); // start the USB device engine and enumerate

  // get an initial reading on the encoder pins
  if (digitalRead(PIN_ENCODER_A) == LOW) {
    enc_prev_pos |= (1 << 0);
  }
  if (digitalRead(PIN_ENCODER_B) == LOW) {
    enc_prev_pos |= (1 << 1);
  }
}

void loop()
{
  int8_t enc_action = 0; // 1 or -1 if moved, sign is direction

  // note: for better performance, the code will now use
  // direct port access techniques
  // http://www.arduino.cc/en/Reference/PortManipulation
  uint8_t enc_cur_pos = 0;
  // read in the encoder state first
  if (bit_is_clear(TRINKET_PINx, PIN_ENCODER_A)) {
    enc_cur_pos |= (1 << 0);
  }
  if (bit_is_clear(TRINKET_PINx, PIN_ENCODER_B)) {
    enc_cur_pos |= (1 << 1);
  }

  // if any rotation at all
  if (enc_cur_pos != enc_prev_pos)
  {
    if (enc_prev_pos == 0x00)
    {
      // this is the first edge
      if (enc_cur_pos == 0x01) {
        enc_flags |= (1 << 0);
      }
      else if (enc_cur_pos == 0x02) {
        enc_flags |= (1 << 1);
      }
    }

    if (enc_cur_pos == 0x03)
    {
      // this is when the encoder is in the middle of a "step"
      enc_flags |= (1 << 4);
    }
    else if (enc_cur_pos == 0x00)
    {
      // this is the final edge
      if (enc_prev_pos == 0x02) {
        enc_flags |= (1 << 2);
      }
      else if (enc_prev_pos == 0x01) {
        enc_flags |= (1 << 3);
      }

      // check the first and last edge
      // or maybe one edge is missing, if missing then require the middle state
      // this will reject bounces and false movements
      if (bit_is_set(enc_flags, 0) && (bit_is_set(enc_flags, 2) || bit_is_set(enc_flags, 4))) {
        enc_action = 1;
      }
      else if (bit_is_set(enc_flags, 2) && (bit_is_set(enc_flags, 0) || bit_is_set(enc_flags, 4))) {
        enc_action = 1;
      }
      else if (bit_is_set(enc_flags, 1) && (bit_is_set(enc_flags, 3) || bit_is_set(enc_flags, 4))) {
        enc_action = -1;
      }
      else if (bit_is_set(enc_flags, 3) && (bit_is_set(enc_flags, 1) || bit_is_set(enc_flags, 4))) {
        enc_action = -1;
      }

      enc_flags = 0; // reset for next time
    }
  }

  enc_prev_pos = enc_cur_pos;

  if (enc_action > 0) {
    TrinketHidCombo.pressMultimediaKey(MMKEY_VOL_UP);
  }
  else if (enc_action < 0) {
    TrinketHidCombo.pressMultimediaKey(MMKEY_VOL_DOWN);
  }

  // remember that the switch is active-high
  if (bit_is_set(TRINKET_PINx, PIN_ENCODER_SWITCH)) 
  {
    if (sw_was_pressed == 0) // only on initial press, so the keystroke is not repeated while the button is held down
    {
      TrinketHidCombo.pressMultimediaKey(MMKEY_MUTE);
      delay(5); // debounce delay
    }
    sw_was_pressed = 1;
  }
  else
  {
    if (sw_was_pressed != 0) {
      delay(5); // debounce delay
    }
    sw_was_pressed = 0;
  }

  TrinketHidCombo.poll(); // check if USB needs anything done
}

 

К счастью или нет, но есть решение(как я думаю) Один человек додумался как эту проблему обойти. Под вторым спойлером решение- но я там ничего не понимаю. Надо как-то совокупить эти 2 кода, а куда что- ой. Как я не пробовал- какието ошибки.

Spoiler

Удалось решить эту проблему. Пришлось вносить изменения в библиотеку V-USB. Была добавлена переменная LastRecievedUSBPacket. В эту переменную записывается тип последнего принятого USB пакета. Т.е. если после обнуления в эту переменную попадают данные, значит USB законнектился и все работает нормально. Если данные не меняются значит коннект не произошел. Тогда отправляем устройство на перезагрузку. При этом происходит заново подстройка частоты. И так по циклу, пока не установится коннект.

Пример изменений в коде


#include <avr/wdt.h> //подключаем библиотеку watch dog timer
….
int main(void //Начало программы
{
  MCUSR = 0;
wdt_disable();

……

……
wdt_enable(WDTO_8S); // даем команду перезагрузить контроллер через 8 с если не обнулим время счетчика

LastRecievedUSBPacket = 0;
for(;;){ /* начало основного цикла программы */
if (LastRecievedUSBPacket != 0) //обнуляем счетчик только когда USB соединение установлено
{
LastRecievedUSBPacket = 0;
wdt_reset();
}
}
}

Т.е. после запуска контроллер проверяет значение переменной LastRecievedUSBPacket, если она отлична от нуля, значит подключение произошло и можно обнулить WDT. Если в течение 8 секунд устройство не определилось системой оно уходит в перезагрузку.

 

Буду благодарен за помощь как их скрестить вместе.

Изменено пользователем a2a
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • 4 недели спустя...

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Особенности хранения литиевых аккумуляторов и батареек

Потеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
  • Сообщения

    • У тебя хотя бы питальник мощностью в 50-70 Ватт есть, чтобы это утверждать, или опять по клаве PC-ка в своём Микрокапе настучал? @VIT13, мальчик, ты гонор-то свой  лучше засунул бы себе меж полужопиц! "Мой худ...".(с) При чём здесь твоя кривая поделка в фанерной коробке? Ты хоть первоисточник по JLH-69 видел? Я, если что, этих "худов", начиная с такого же, как ты сейчас, возраста и позже, уже учась в ВУЗ-е, сделал с десяток штук. При чём всегда собирал их на тех транзисторах и по той схеме, что указал в своей статье John Linsley Hood. Если ты считаешь, что он был безмозглым маразматиком, не умеющим ни считать, ни измерять, то... мне жаль тебя - ты безнадёжен. 
    • @dimanaviator где вы тут делитель увидели? Срисуйте правильно.
    • А лучший вариант предложил Огонек:
    • PS Я слепой определенно. Проглядел что было на графике в стартовом посте - температура Но тем не менее, симуляции микрокапа у меня доверия в этом плане ноль. Я про реальные испытания  
    • И в чем же хрень? Вполне соответствует предложенному ТЗ - от насоса поступает постоянное напряжение 10 вольт. Видимо, это не напряжение питания мотора насоса, а от какой-то управляющей схемы. Или это насос от аквариума, маломощный, или еще что-то. "Есть в мире многое такое, друг Горацио, что и не снилось нашим мудрецам!" 
    • @beggar Учитывая, что Вам влом читать статьи, ща я вкратце поясню (но было бы лучше, Вам прочитать учебники). DCA режим мультиметра - это измерение среднего значения тока. в этом режиме, мультиметр измеряет - какой заряд, протёк за одну секунду, через поперечное сечение проводника. ЗЫ имеет значение, какое число электронов, прошло через поперечное сечение, за одну секунду, и не важно: с какой скоростью они двигались, быстро, медленно, толпами или строем,  главное - сколько. Это среднее значение тока. Действующее значение тока - это вовсе не ток, а его мощностной эквивалент. Здесь важна и скорость электронов, чем быстрее движутся электроны, тем больше потери энергии. Когда по проводнику протекает какой-то ток, на проводнике выделяется тепловая энергия, мощностью P=I*I*R. Рассмотрим случай, когда ток в 1 А протекает в течении 1 секунды, через проводник сопротивлением 1 Ом, тогда мощность равна P=I*I*R=1*1*1=1 Вт. Теперь рассмотрим другой случай, когда тот же ток в 1 ампер (среднее значение), протекает импульсом тока величиной 10 А, продолжительностью 0.1 секунды и паузой продолжительностью 0.9 секунды. тогда мощность выделяющаяся в течении 0.1 секунды P=I*I*R=10*10*1=100 Вт, а в течении 0,9 секунды, т.е. ещё 9 раз по 0,1 секунды 0 Вт, таким образом, мощность выделяющаяся в течении секунды 100/10=10 Вт. Получается, что ток, который покажет амперметр среднего значения - одинаковый, а теплота, выделяющаяся на проводнике, во втором случае, в 10 раз больше. Это какой же ток должен протекать через проводник, чтоб выделялась такая же мощность на проводнике? - получается 3.16 А, P=I*I*R=3.16*3.16*1=10 Вт. Вот амперметр среднеквадратичного значения, в первом случае, показал бы 1 А, а во втором 3.16 А. Получается, что заряд таким током (второй вариант - с импульсным током), заряжал бы аккумулятор током 1 А, а: проводники трансформатора, провода, предохранители, шунты амперметров... грелись бы, как будто по ним проходил бы постоянный ток 3.16 А. при этом, амперметр среднего значения, показывал бы ток 1 А, а амперметр действующего значения 3.16 А. ЗЗЫ хочется верить, что Вам не придётся объяснять, чем отличается - емкость конденсатора, от емкости аккумулятора…
    • что нужно изменить и в какую сторону чтобы повысить напряжение? сейчас 12В хочу попробовать сделать 18-20В, что изменить в делителе?  
×
×
  • Создать...