roboforum.ru

Технический форум по робототехнике.

Одновременное мигание светодиодом и воспроизвеление звука

Как собрать и запрограммировать робота на Arduino(Freeduino, Roboduino, Seeduino ...). Используем Wiring и Processing.

Одновременное мигание светодиодом и воспроизвеление звука

Сообщение KitaPro » 10 окт 2011, 22:33

Добрый вечер. Собрал такую схему. Изображение При не нажатой кнопке должен гореть D2, при нажатии гасится D2 и мигает D1. И в это время должна играть мелодия с пьезоизлучателя. По отдельности это все работает, а вместе с пьезо кнопка и светодиоды ведут себя как то странно( Вообщем не работает. В чем может быть проблема? Или нельзя вообще выполнять несколько параллельных действий?
Код: Выделить всёРазвернуть


int ledPin = 13;                // сетодиод 1
int led2Pin=7;                  //светодиод 2
int btnPin = 12;                // кнопка
int val=0;
int speakerPin = 9;            //пьезо

int length = 15;                  // число нот
char notes[] = "ccggaagffeeddc "; // пробел - пауза
int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 300;

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
 
  // проиграть тон, соответствующий ноте
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}



void setup()                     
{
  pinMode(ledPin, OUTPUT);      // это выход - светодиод
  pinMode(btnPin, INPUT);       // а это вход - кнопка
  pinMode(led2Pin, OUTPUT);   //выход светодиод 2     
  pinMode(speakerPin, OUTPUT); //выход пьезо
}

void loop()                     
{
   
 
  val = digitalRead(btnPin);    // узнаём состояние кнопки
  if(val==HIGH)                 // кнопка нажата
  {
    digitalWrite(led2Pin, LOW); //гасим светодиод 2
    digitalWrite(ledPin, HIGH); // мигаем светодиодом 1
    delay(100);
    digitalWrite(ledPin, LOW);
    delay(100);
   
  }
  else                          // кнопка не нажата
  {
    digitalWrite(ledPin, LOW);  // гасим светодиод 1
    digitalWrite(led2Pin, HIGH); //зажигаем светодиод 2
   
  } 
/* воспроизведение мелодии */
  for (int i = 0; i < length; i++) {
    if (notes[i] == ' ') {
      delay(beats[i] * tempo); // пауза
    } else {
      playNote(notes[i], beats[i] * tempo);
    }
   
    // пауза между нотами
    delay(tempo / 2);
  }
 
delay(100);
}
KitaPro
 
Сообщения: 127
Зарегистрирован: 30 сен 2011, 20:33
Откуда: Мурманск
ФИО: Никита

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение HarryStar » 10 окт 2011, 22:49

Параллельно выполнять действия можно. А вот в программе у вас все последовательно.
Рассмотрим, что вы написали
1) Сценарий 1. Нажата кнопка.
- 1 раз мигнуть светодиодом 1
- проиграть целиком мелодию
- Вернуться к проверке кнопки
Т.о. если вы держите нажатой кнопку, то у вас должна играть мелодия и после ее окончания 1 раз мигать светодиод 1, потом заново
2) Сценарий 2. Кнопка не нажата.
- Зажечь светодиод 2
- Проиграть целиком мелодию
- Вернуться к проверке
Т.о. у вас играет музыка по циклу и горит светодиод 2

Соотв нажатие-отпускание кнопки меняет сценарии, но только после доигрывания мелодии до конца. Измените программу в соответствии со своими требованиями и она будет делать то, что нужно. И одновременно в том числе.
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение KitaPro » 11 окт 2011, 23:54

HarryStar, спасибо за ответ
Работает точно как Вы описали. В программировании не очень шарю, и примеров таких не нашел. Что хоть менять надо?
KitaPro
 
Сообщения: 127
Зарегистрирован: 30 сен 2011, 20:33
Откуда: Мурманск
ФИО: Никита

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение HarryStar » 12 окт 2011, 00:32

Ну очевидны 2 вещи:
раз постоянно должна играть мелодия и она не зависит от кнопок, значит ее проигрывание это "главный цикл".
Внутри него нужно мигать светодиодами в зависимости от нажатых/не нажатых кнопок.
Вот и все. Подумайте, как немного изменить программу, чтоб все это выполнялось. На самом деле программа даже немного упростится.
Еще одна подсказка: мигать светодиодами надо не используя функцию delay (т.к. это нарушит мелодию), а используя естественную длительность нот например.

PS: Можно сделать все совсем по другому, используя прерывания по таймерам, но я так понимаю, вы до них еще не дошли, поэтому делайте как я написал выше.
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение KitaPro » 12 окт 2011, 22:56

HarryStar, спасибо)
Вообщем с программированием у меня пока тяжко, получилось вот так только:
Код: Выделить всёРазвернуть
/*
* LED with button
*/

int ledPin = 13;                // сетодиод 1
int led2Pin=7;                  //светодиод 2
int btnPin = 12;                // кнопка
int val=0;
int value = LOW;           // предыдущее состояние светодиода
long previousMillis = 0;   // здесь будет храниться время последнего изменения состояния светодиода
long interval = 100;      // интервал мигания в миллисекундах



int speakerPin = 9;

int length = 15;                  // число нот
char notes[] = "ccggaagffeeddc "; // пробел - пауза
int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 300;

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
 
  // проиграть тон, соответствующий ноте
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}


void setup()                     
{
  pinMode(ledPin, OUTPUT);      // это выход - светодиод
  pinMode(btnPin, INPUT);       // а это вход - кнопка
  pinMode(led2Pin, OUTPUT);   //выход светодиод 2     
  pinMode(speakerPin, OUTPUT); //выход пьезо
}

void loop()                     
{
   /* воспроизведение мелодии */
  for (int i = 0; i < length; i++) {
     val = digitalRead(btnPin);    // узнаём состояние кнопки
  if(val==HIGH)                 // кнопка нажата
  {
    digitalWrite(led2Pin, LOW); //гасим светодиод 2
      if (millis() - previousMillis > interval) {
    previousMillis = millis();   // запоминаем текущее время
    // если светодиод был выключен – включаем и наоборот :)
    if (value == LOW)
      value = HIGH;
    else
      value = LOW;

    digitalWrite(ledPin, value);
  }
   
  }
  else                          // кнопка не нажата
  {
    digitalWrite(ledPin, LOW);  // гасим светодиод 1
    digitalWrite(led2Pin, HIGH); //зажигаем светодиод 2
   
  } 
 
    /*if (notes[i] == ' ') {
      delay(beats[i] * tempo); // пауза
    }
    else*/
    {
      playNote(notes[i], beats[i] * tempo);
    }
   
    // пауза между нотами
    delay(tempo / 2);
  }
 


 
delay(100);
}


Так то все работает, только пришлось убрать паузу между воспроизведением мелодии заново, потому что в этот момент опять не правильно работает

Добавлено спустя 33 минуты 53 секунды:
Re: Одновременное мигание светодиодом и воспроизвеление звука
А с прерываниями я еще не знаком

Добавлено спустя 1 час 7 минут 19 секунд:
Re: Одновременное мигание светодиодом и воспроизвеление звука
Можно я буду задавать сюда свои тупые вопросы. Вообщем взял пример button. Собрал схему Изображение. Если ключ изначально не зажат, то все работает. Если ключ был замкнут, то ничего не происходит( приходится жать два раза на ключ. В чем проблема?
Код: Выделить всёРазвернуть
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);     
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);     
}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {     
    // turn LED on:   
    digitalWrite(ledPin, HIGH); 
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}


жаль что не могу это пробовать на железе( не пришла еще платка

Добавлено спустя 10 минут 20 секунд:
Re: Одновременное мигание светодиодом и воспроизвеление звука
и еще вопросик: вот замкнул я ключ такой, должна заиграть музыка и замигать светодиод. Разомкнул ключ в любой момент, все должно погаснуть и прекратиться музыка. Здесь без прерываний не обойтись?
KitaPro
 
Сообщения: 127
Зарегистрирован: 30 сен 2011, 20:33
Откуда: Мурманск
ФИО: Никита

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение HarryStar » 13 окт 2011, 00:21

1) С первого взгляда косяков нет, должно работать.

2) Можно без прерываний. Подумайте немного, вы же решили предыдущую задачу. Эта еще проще.
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение KitaPro » 13 окт 2011, 07:48

Нашел где косяк с ключем, нужно было питание 5в а не 1,5. Видимо там неопределенность при 1,5
KitaPro
 
Сообщения: 127
Зарегистрирован: 30 сен 2011, 20:33
Откуда: Мурманск
ФИО: Никита

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение HarryStar » 13 окт 2011, 14:59

А ну да, я и не посмотрел что у вас там 1.5 вольта
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение KitaPro » 13 окт 2011, 23:00

Не могу никак сделать( Проблема в цикле воспроизведения мелодии, не знаю как его прервать. Без мелодии я сделал, все работает.

Добавлено спустя 14 минут 11 секунд:
Re: Одновременное мигание светодиодом и воспроизвеление звука
о) Сделал с помощью break. Так правильно? Код правда какой то корявый

Код: Выделить всёРазвернуть
/*
* LED with button
*/

int ledPin = 13;                // сетодиод 1
int led2Pin=7;                  //светодиод 2
int btnPin = 12;                // кнопка 1
int swtPin=8;
int val=0;
int val2=0;
int value = LOW;           // предыдущее состояние светодиода
long previousMillis = 0;   // здесь будет храниться время последнего изменения состояния светодиода
long interval = 100;      // интервал мигания в миллисекундах



int speakerPin = 9;

int length = 15;                  // число нот
char notes[] = "ccggaagffeeddc "; // пробел - пауза
int beats[] = { 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 4 };
int tempo = 300;

void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
 
  // проиграть тон, соответствующий ноте
  for (int i = 0; i < 8; i++) {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}


void setup()                     
{
  pinMode(ledPin, OUTPUT);      // это выход - светодиод
  pinMode(btnPin, INPUT);       // а это вход - кнопка
  pinMode(led2Pin, OUTPUT);   //выход светодиод 2     
  pinMode(speakerPin, OUTPUT); //выход пьезо
  pinMode(swtPin, INPUT);      //вход - кнопка 2
}

void loop()                     
{

  val2= digitalRead(swtPin);
  if(val2==HIGH) {
  for (int i = 0; i < length; i++)
{    /* воспроизведение мелодии */
     val = digitalRead(btnPin);    // узнаём состояние кнопки
  if(val==HIGH)                 // кнопка нажата
  {
    digitalWrite(led2Pin, LOW); //гасим светодиод 2
      if (millis() - previousMillis > interval) {
    previousMillis = millis();   // запоминаем текущее время
    // если светодиод был выключен – включаем и наоборот :)
    if (value == LOW)
      value = HIGH;
    else
      value = LOW;

    digitalWrite(ledPin, value);
  }
   
  }
  else                          // кнопка не нажата
  {
    digitalWrite(ledPin, LOW);  // гасим светодиод 1
    digitalWrite(led2Pin, HIGH); //зажигаем светодиод 2
   
  } 

   playNote(notes[i], beats[i] * tempo);
   
   val2= digitalRead(swtPin);
  if(val2==LOW)
  break;
   
    // пауза между нотами
    delay(tempo / 2);
  }
  }
  else {
digitalWrite(ledPin, LOW); 
digitalWrite(led2Pin, LOW);
digitalWrite(speakerPin, LOW);}
 
delay(100);
}


можно ли по другому решить эту задачу?
KitaPro
 
Сообщения: 127
Зарегистрирован: 30 сен 2011, 20:33
Откуда: Мурманск
ФИО: Никита

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение HarryStar » 14 окт 2011, 00:11

KitaPro писал(а):можно ли по другому решить эту задачу?

да можно по всякому, главное самому больше пробовать
вот например такой вариант:
Код: Выделить всёРазвернуть
void loop()                      
{
// Главный цикл - воспроизведение мелодии
for (int i = 0; i < length; i++)
   {
      val = digitalRead(btnPin);    // узнаём состояние кнопки
      if(val==HIGH)                 // кнопка нажата
      {
         if(i&1)   digitalWrite(ledPin, LOW);      // гасим светодиод 1
         else   digitalWrite(ledPin, HIGH);      // зажигаем светодиод 1
         playNote(notes[i], beats[i] * tempo);   // играем музыку
      }
      else                          // кнопка не нажата
      {
         digitalWrite(ledPin, LOW);  // гасим светодиод 1
      } 
         delay(tempo / 2);                   // пауза
   }
delay(100);
}


Управляется по 1й кнопке. Нажимаете ее - все мигает и играет. Отпускаете - тишина и тьма.
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Одновременное мигание светодиодом и воспроизвеление звук

Сообщение KitaPro » 14 окт 2011, 20:06

HarryStar, спасибо. Отличный вариант. Не знал о существовании такой функции как &.
Так лампочками я помигал, музыку повоспроизводил, что еще можно такое не сложное симулировать?
KitaPro
 
Сообщения: 127
Зарегистрирован: 30 сен 2011, 20:33
Откуда: Мурманск
ФИО: Никита


Вернуться в Arduino и другие Xduino

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10