Помогите с мерзким пианино.

Тема в разделе "Arduino & Shields", создана пользователем prohor-nastya, 6 окт 2017.

  1. prohor-nastya

    prohor-nastya Нерд

    Люди, здравствуйте!

    Подскажите пож. что не так:

    Собрал эксперимент мерзкое пианино...

    http://wiki.amperka.ru/%D0%BA%D0%BE%D0%BD%D1%81%D0%BF%D0%B5%D0%BA%D1%82-arduino:%D0%BC%D0%B5%D1%80%D0%B7%D0%BA%D0%BE%D0%B5-%D0%BF%D0%B8%D0%B0%D0%BD%D0%B8%D0%BD%D0%BE

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

    Но звук тихий с дребезгом, не красивый.

    если пишешь для одного пина, напр. 4 звук чистый как в эксперименте...

    Код (C++):

    01 #define BUZZER_PIN    13 // пин с пищалкой (англ. «buzzer»)
    02 #define FIRST_KEY_PIN 4 // первый пин с клавишей (англ. «key»)
    03 #define LAST_KEY_PIN 10
    04 #define KEY_COUNT     7  // общее количество клавиш
    05
    06
    07 void setup()
    08 {
    09 for (int pin = FIRST_KEY_PIN; pin <= LAST_KEY_PIN; ++pin)
    10 pinMode(pin, INPUT);
    11 pinMode(BUZZER_PIN, OUTPUT);
    12 }
    13
    14 void loop() {
    15

    16
    17   if(digitalRead(4)==LOW)//если кнопка нажата ...
    18 {
    19 tone(BUZZER_PIN,3100, 20);
    20 }
    21 else//если не нажата...
    22 {
    23 noTone(BUZZER_PIN);
    24 }
    25 if(digitalRead(5)==LOW)//если кнопка нажата ...
    26 {
    27 tone(BUZZER_PIN, 3650, 20);
    28 }
    29 else//если не нажата...
    30 {
    31 noTone(BUZZER_PIN);
    32 }
    33 if(digitalRead(6)==LOW)//если кнопка нажата ...
    34 {
    35 tone(BUZZER_PIN, 4200, 20);
    36 }
    37 else//если не нажата...
    38 {
    39 noTone(BUZZER_PIN);
    40 }
    41 }
     
     
    Последнее редактирование: 6 окт 2017
  2. ostrov

    ostrov Гуру

    Сделайте триггером: кнопка нажата, включился звук (однократно), отжали - выключился. Сейчас же у вас команда на включение подается сотни раз в секунду, от того и проблемы.
     
  3. ostrov

    ostrov Гуру

    Или как этот оператор работает? Зависает на 20мс? Никогда им не пользовался.
     
  4. prohor-nastya

    prohor-nastya Нерд

    20 мс, это осталось от кода данного в руководстве, здесь они конечно не нужны. я их убрал
    триггер это жэ преобразователь аналогового сигнала в цифровой. Но у нас же считывается цифровой...? может можете схемку кинуть, я еще плохо понимаю как это может быть реализовано.
    Спасибо!
     
  5. ostrov

    ostrov Гуру

    Триггер это переключатель. Программа видит факт нажатия кнопки (переход от 1 к 0 на пине), дает команду зуммеру пищать и пока он пищит больше такой команды не давать. То есть завести так называемый "флаг". Когда кнопка переходит от 0 к 1, дать команду выключить зуммер и начать сначала. Единственно, я не знаю как реализована функция tone, пищит она независимо или все зависает на время пищания?
     
  6. prohor-nastya

    prohor-nastya Нерд

    т.е. речь не о триггере шмитта?
     
  7. ostrov

    ostrov Гуру

    Нет, о программном триггере.
     
  8. prohor-nastya

    prohor-nastya Нерд

    Сделал так, все равно звук не красивый...

    Код (C++):
    #define BUZZER_PIN    13 // пин с пищалкой (англ. «buzzer»)
    #define FIRST_KEY_PIN 4 // первый пин с клавишей (англ. «key»)
    #define LAST_KEY_PIN 10
    #define KEY_COUNT     7  // общее количество клавиш


    void setup()
    {
    for (int pin = FIRST_KEY_PIN; pin <= LAST_KEY_PIN; ++pin)
    pinMode(pin, INPUT);
    pinMode(BUZZER_PIN, OUTPUT);
    }

    void loop() {
     
    for (int i = 0; i < KEY_COUNT; ++i) {
        // на основе номера кнопки вычисляем номер её пина
        int keyPin = i + FIRST_KEY_PIN;

        // считываем значение с кнопки. Возможны всего 2 варианта:
        //  * высокий сигнал, 5 вольт, истина — кнопка отпущена
        //  * низкий сигнал, земля, ложь — кнопка зажата
        boolean keyUp = digitalRead(keyPin);
       
      if(digitalRead(4)== !keyUp)//если кнопка нажата ...
    {
    tone(BUZZER_PIN,3000);
    }
    else//если не нажата...
    {
    noTone(BUZZER_PIN);
    }
    if(digitalRead(5)== !keyUp)//если кнопка нажата ...
    {
    tone(BUZZER_PIN, 3500);
    }
    else//если не нажата...
    {
    noTone(BUZZER_PIN);
    }
    if(digitalRead(6)== !keyUp)//если кнопка нажата ...
    {
    tone(BUZZER_PIN, 4000);
    }
    else//если не нажата...
    {
    noTone(BUZZER_PIN);
    }
    }
    }
     
  9. prohor-nastya

    prohor-nastya Нерд

    Есть ссылка на программный триггер?
    Пример посмотреть...
     
  10. ostrov

    ostrov Гуру

    Вы сделали еще хуже чем было.
     
  11. prohor-nastya

    prohor-nastya Нерд

    рука лицо... =(
     
  12. prohor-nastya

    prohor-nastya Нерд

    ну подскажите (покажите), пожалуйста, как надо...
     
  13. ostrov

    ostrov Гуру

    Давайте вечером. Трудно на пляжу с смартфона программы писать. )
     
  14. prohor-nastya

    prohor-nastya Нерд

    ок, у нас на часах 22.23 а за бортом +3 по цельсию ... =)
     
  15. ostrov

    ostrov Гуру

    А у нас 16:28 и +28 ))
     
  16. rkit

    rkit Гуру

    Нужен не триггер, а конечный автомат. В вики есть соответствующая статья.
     
  17. rkit

    rkit Гуру

    Код (C++):
    if(digitalRead(4)==LOW)//Если нажата кнопка 1.
    {
       tone(BUZZER_PIN,3100, 20);
    }
    else if(digitalRead(5)==LOW)//Если нажата кнопка 2
    {
      tone(BUZZER_PIN, 3650, 20);
    }
    ... // все остальные кнопки
    else // если ни одна кнопка не нажата
    {
      noTone(BUZZER_PIN);
    }
     
     
  18. fps

    fps Нерд

    в первом примере достаточно delay(20) добавить в конце функции loop
     
  19. ostrov

    ostrov Гуру

    Это мало отличается от первого варианта.
     
  20. rkit

    rkit Гуру

    Подумайте еще