синхронизация 3 сервоприводов + аудио модуль wtv020sd-16p через ардуино

kernelkernel
Offline
Зарегистрирован: 20.01.2015

Всем привет! Оочень нужна помощь опытных ардуинщиков с большим срочным проектом - взялись за гуж, да оказались не дюж((

Делаем интерактивную инсталляцию. Суть в следующем: в обычном состоянии конструкция через wtv020sd-16p издает мелодию №1. Когда человек нажимает на датчик давления, запускается мелодия №2, и одновременно с этим 2 сервопривода неполного вращения (к ним прикручен некоторый вес). Если человек нажал на площадку с датчиком только 1 раз, то через пару секунд сервоприводы перестают работать и мелодия №2 меняется на мелодию №1 - магия не происходит. Если человек нажимает на площадку 10 раз, то с момента первого нажатия до 10го играет мелодия №2, работают 2 сервопривода. а после 10го нажатия 2 серва отключаются, запускается сервопривод 3. Потом конструкция возвращается в исходное состояние - играет мелодия №1 и ничего не происходит. Ждет след взаимодействия. 

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

Пожалуйста ХЕЛП!! только начинаем врубаться в ардуино, поэтому не закидывайте какашками сразу)

#define SENSOR_PIN A5
    
    #include "Servo.h"
    Servo servoMain;
    Servo servoLeftHand;
    Servo servoRightHand;
    int counter = 0; 
    
    void setup()
    {
       Serial.begin(9600);
       servoMain.attach(11); 
       servoLeftHand.attach(10);
       servoRightHand.attach(9);
       servoMain.write(20);
    }
     
    void loop()
    {
        int val = analogRead(SENSOR_PIN);
        if(val < 900){
          counter = counter+1;
        }
        if(counter<=10&&counter>=1){
        hands();
        
        }
        Serial.println(val);
        Serial.println(counter);
        delay(500);
        if(counter == 10){
 
        servo();
        counter = 0;
        }
    }
    
    void servo(){
    servoMain.write(180);
    delay(2000);
    servoMain.write(20); 
    delay(2000);    
    }
    
    void hands(){
    servoLeftHand.write(90); 
    servoRightHand.write(0);
    delay(200);
    servoLeftHand.write(0);
    servoRightHand.write(90);
    delay (200);
    }

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

алгоритм-схема нужна - короче и яснее :)  а не как в постановке вопроса :(

kernelkernel
Offline
Зарегистрирован: 20.01.2015

а с блок-схемой понятнее?)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

пока - нет ! датчик давления = кнопка или тензодатчик ?

kernelkernel
Offline
Зарегистрирован: 20.01.2015

сорри)

резистор давления http://amperka.ru/product/force-resistor-6mm

2 сервопривода http://amperka.ru/product/servo-fs5109m

и серв один такой http://amperka.ru/product/servo-fs5106b

kernelkernel
Offline
Зарегистрирован: 20.01.2015

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

очень нужна помощь, плизз ;(

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

зачем резистор давления ? при каком давлении на него считать, что произошло нажатие ?

чем не устраивает нефиксируемая ( тактовая ) кнопка ?

kernelkernel
Offline
Зарегистрирован: 20.01.2015

конструкцией (на нее будет вставать до 100 человек) и погодными условиями (уличная инсталляция при - температуре).

в общем-то все детали в любом случае уже куплены) 

осталось свести все это в единый рабочий код

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

#24 и #31 - при 10 выполнятся обе строки

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

тогда всё снова опишите...

при чём здесь колво нажатий ? вы хотите знать сколько примерно челов на конструкции находится ?

kernelkernel
Offline
Зарегистрирован: 20.01.2015

нам нужно, чтоб человек 10 раз нажал на датчик прежде чем выполнится основное условие (запуск серво 3 и мелодии 3)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

кнопка :

количество нажатий суммируется , время между нажатиями не более 2 сек ?

состояние 1 - нет нажатий , что-то_1 происходит непрерывно

состояние 2 - нажали 1 раз -> что-то_2 происходит 2 секунды, затем всё в исходное положение, колво нажатий обнуляется

состояние 3 - нажали 1 раз , через 0,5 сек - ещё нажатие , через 1,5 сек - ещё нажатие , через 1,5 сек - ещё нажатие , через 2,5 сек - ещё нажатие...... от первого нажатия происходит что-то_2 на время 0,5+1,5+1,5+2,0 , нажатий 4 ( пятое не прошло ) , затем всё в исходное положение, колво нажатий обнуляется

состояние 4 - нажатий получилось 10 , происходит что-то_3 , затем всё в исходное положение, колво нажатий обнуляется

так ?

kernelkernel
Offline
Зарегистрирован: 20.01.2015

да, все верно) 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

ждите....

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
#include "Servo.h"
#define sensor A5
Servo servoM;
Servo servoLH;
Servo servoRH;
byte count; 
unsigned long time;
const int strobT = 2000;
//================================================================================
void setup()
{
  Serial.begin( 9600 );
  servoM.attach( 11 ); 
  servoLH.attach( 10 );
  servoRH.attach( 9 );
  servoM.write( 20 );
  servoLH.write( 0 );
  servoRH.write( 90 );
  time = millis();
  count = 0;
}
//================================================================================
boolean pressSensor()
{
  if ( analogRead( sensor ) < 900 ) return 1;
  else                              return 0;
}
//================================================================================
void moveServoM()
{
  servoM.write( 180 );
  delay( 2000 );
  servoM.write( 20 ); 
  delay( 2000 );    
}
//================================================================================
void moveServoH()
{
  servoLH.write( 90 ); 
  servoRH.write( 0 );
  delay( 200 );
  servoLH.write( 0 );
  servoRH.write( 90 );
  delay ( 200 );
}
//================================================================================
void loop()
{
  if ( ( millis() - time ) < strobT )
    {
      if ( pressSensor() )
        {
          count++;
          time = millis();
        }
    }
  else
    {
      count = 0;
    }
  
  Serial.println( count );
  
  
  
  
  
}
/*
  int val = analogRead( sensor );
  if ( val < 900 )
    {
      counter++;
    }
    
  if ( counter == 1)
    {
       // hands();      ????????????????????????????
    }
    delay( 500 );
    
  if ( ( counter >= 1) && ( counter < 10 ) )
    {
       moveServoH();
    }
    delay( 500 );
    
    if ( counter == 10 )
      {
        moveServoM();
        counter = 0;
      }
    delay( 500 );
}
*/
//================================================================================

нет платки с собой... проверьте сами - в сериале должно быть постоянно =0 , а при нажатиях 1, 2, 3, 4, ..... 9, 10, 11, .... если каждое последущее нажатие не позже от преднажатия на 2 сек , больше двух секунд - опять нули...

могу и ошибаться - я тоже учЮсь ещё :)

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

вот так ближе к теме....

#include "Servo.h"
#define sensor A5
Servo servoM;
Servo servoLH;
Servo servoRH;
byte count; 
unsigned long time;
const int strobT = 2000;
//================================================================================
void setup()
{
  Serial.begin( 9600 );
  servoM.attach( 11 ); 
  servoLH.attach( 10 );
  servoRH.attach( 9 );
  servoM.write( 20 );
  servoLH.write( 0 );
  servoRH.write( 90 );
  time = millis();
  count = 0;
}
//================================================================================
void moveServoM()
{
  servoM.write( 180 );
  delay( 2000 );
  servoM.write( 20 ); 
  delay( 2000 );    
}
//================================================================================
void moveServoH()
{
  servoLH.write( 90 ); 
  servoRH.write( 0 );
  delay( 200 );
  servoLH.write( 0 );
  servoRH.write( 90 );
  delay ( 200 );
}
//================================================================================
void loop()
{
  if ( ( millis() - time ) < strobT )
    {
      if ( analogRead( sensor ) < 900 )
        {
          count++;
          time = millis();
        }
    }
  else
    {
      count = 0;
      time = millis();
    }
  
  Serial.println( count );

}
//================================================================================

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

крайняя версия...

#include "Servo.h"
#define sensor A5
Servo servoM;
Servo servoLH;
Servo servoRH;
byte count; 
unsigned long timeSensor;
const int strobSensor = 2000;
boolean upDown;
//================================================================================
void setup()
{
  Serial.begin( 9600 );
  servoM.attach( 11 ); 
  servoLH.attach( 10 );
  servoRH.attach( 9 );
  servoM.write( 20 );
  servoLH.write( 0 );
  servoRH.write( 90 );
  timeSensor = millis();
  count = 0;
  upDown = 0;
}
//================================================================================
void moveServoM()
{
  servoM.write( 180 );
  delay( 2000 );
  servoM.write( 20 ); 
  delay( 2000 );    
}
//================================================================================
void moveServoH()
{
  servoLH.write( 90 ); 
  servoRH.write( 0 );
  delay( 200 );
  servoLH.write( 0 );
  servoRH.write( 90 );
  delay ( 200 );
}
//================================================================================
void loop()
{
  if ( ( millis() - timeSensor ) < strobSensor )  //////////////////
    {                                                             //
      if ( ( analogRead( sensor ) < 900 ) && ( ! upDown ) )       //
        {                                                         //
          upDown = 1;                                             //
        }                                                         //
      if ( ( analogRead( sensor ) >= 900 ) && ( upDown ) )        //
        {                                                         //
          upDown = 0;                                             // обработка нажатий датчика
          count++;                                                //
          timeSensor = millis();                                  //
        }                                                         //
    }                                                             //
  else                                                            //
    {                                                             //
      count = 0;                                                  //
      timeSensor = millis();                                      //
    }   ////////////////////////////////////////////////////////////
  
  // вывод кол-ва нажатий и времени оставшегося до сброса кол-ва нажатий
  Serial.print( count );   Serial.print( "   " );   Serial.println( ( millis() - timeSensor ) );   

}
//================================================================================

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

а кто или что будет мешать человеку нажимать датчик ? развлекуха для корпаратива ? :)

wtv020sd-16p - с этой штукой я не общался :(

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

это http://arduino.ru/forum/apparatnye-voprosy/vosproizvedenie-muzyki-i-zvukov-cherez-pleer#comment-32340 читать....



#include "Servo.h"
#include <Wtv020sd16p.h>
byte resetPin = 2;
byte clockPin = 3;
byte dataPin = 4;
byte busyPin = 5;
Wtv020sd16p wtv020( resetPin , clockPin , dataPin , busyPin );
#define sensor A5
Servo servoM;
Servo servoLH;
Servo servoRH;
byte count; 
unsigned long timeSensor;
const int strobSensor = 2000;
boolean upDown;
//================================================================================
void setup()
{
  Serial.begin( 9600 );
  servoM.attach( 11 ); 
  servoLH.attach( 10 );
  servoRH.attach( 9 );
  servoM.write( 20 );
  servoLH.write( 0 );
  servoRH.write( 90 );
  wtv020.reset();
  wtv020.sendCommand( 0xFFF4 );    // громкость 1-7 ставим на 5
  wtv020.playVoice( 0 );
  timeSensor = millis();
  count = 0;
  upDown = 0;
}
//================================================================================
void moveServoMup()
{
  servoM.write( 180 ); 
}
//================================================================================
void moveServoMdown()
{
  servoM.write( 20 );   
}
//================================================================================
void moveServoHup()
{
  servoLH.write( 90 ); 
  servoRH.write( 0 );
}
//================================================================================
void moveServoHdown()
{
  servoLH.write( 0 );
  servoRH.write( 90 );
}
//================================================================================
void loop()
{
  if ( ( millis() - timeSensor ) < strobSensor )  //////////////////
    {                                                             //
      if ( ( analogRead( sensor ) < 900 ) && ( ! upDown ) )       //
        {                                                         //
          upDown = 1;                                             //
        }                                                         //
      if ( ( analogRead( sensor ) >= 900 ) && ( upDown ) )        //
        {                                                         //
          upDown = 0;                                             // обработка нажатий датчика
          count++;                                                //
          timeSensor = millis();                                  //
        }                                                         //
    }                                                             //
  else                                                            //
    {                                                             //
      count = 0;                                                  //
      timeSensor = millis();                                      //
    }   ////////////////////////////////////////////////////////////
  
  // вывод кол-ва нажатий и времени оставшегося до сброса кол-ва нажатий
  Serial.print( count );   Serial.print( "   " );   Serial.println( ( millis() - timeSensor ) );   

}
//================================================================================

с музыкой понятно - файл0 - играет постоянно , файл1 - играет 2 сек, 4 сек, ....... 20 сек , файл2 - играет как только пройдёт 10 нажатий - а сколько времени играет ( далее ВРЕМЯ10 )? 

а теперь поточнее про сервы... 

запускаются сервы, перестают работать сервы ? это как ?

1 нажатие - сервы рук меняют положение и через 2 сек возвращаются в иходное положение ? или 2 сек машут руками ?

нажатий 2........9 - сервы рук меняют положение и через 2 сек после 9-го нажатия возвращаются в иходное положение ? или 18 сек машут руками ?

нажатий 10 - сервы рук возвращаются в исходное, главная серва меняет положение на ВРЕМЯ10 и затем возвращается в исходное ? или она ходит туду-сюда ВРЕМЯ10 ?

сервы на руки - ясно, а чё ворочает главная серва ?

kernelkernel
Offline
Зарегистрирован: 20.01.2015

оке, спасибо! код проверить получится только завтра( отпишусь по результату!

а наш чем был плох?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

свой проще написать , чем разбираться в чужом :) - заработает, дык переделаете по своему :)

kernelkernel
Offline
Зарегистрирован: 20.01.2015

щас попробуем) 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

дык, код ещё голый - может только заиграть музычку и в сериал выводить колво нажатий по алгоритму :(

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

кататак....

#include "Servo.h"
#include <Wtv020sd16p.h>
byte resetPin = 2;
byte clockPin = 3;
byte dataPin = 4;
byte busyPin = 5;
Wtv020sd16p wtv020( resetPin , clockPin , dataPin , busyPin );
#define sensor A5
Servo servoM;
Servo servoLH;
Servo servoRH;
byte count; 
unsigned long timeSensor;
const int strobSensor = 2000;
boolean upDown;
//================================================================================
void setup()
{
  Serial.begin( 9600 );
  servoM.attach( 11 ); 
  servoLH.attach( 10 );
  servoRH.attach( 9 );
  servoM.write( 20 );
  servoLH.write( 0 );
  servoRH.write( 90 );
  wtv020.reset();
  wtv020.sendCommand( 0xFFF4 );    // громкость 1-7 ставим на 5
  wtv020.playVoice( 0 );
  timeSensor = millis();
  count = 0;
  upDown = 0;
}
//================================================================================
void moveServoMup()
{
  servoM.write( 180 ); 
}
//================================================================================
void moveServoMdown()
{
  servoM.write( 20 );   
}
//================================================================================
void moveServoHup()
{
  servoLH.write( 90 ); 
  servoRH.write( 0 );
}
//================================================================================
void moveServoHdown()
{
  servoLH.write( 0 );
  servoRH.write( 90 );
}
//================================================================================
void loop()
{
  if ( ( millis() - timeSensor ) < strobSensor )  //////////////////
    {                                                             //
      if ( ( analogRead( sensor ) < 900 ) && ( ! upDown ) )       //
        {                                                         //
          upDown = 1;                                             //
        }                                                         //
      if ( ( analogRead( sensor ) >= 900 ) && ( upDown ) )        //
        {                                                         //
          upDown = 0;                                             // обработка нажатий датчика
          count++;                                                //
          timeSensor = millis();                                  //
        }                                                         //
    }                                                             //
  else                                                            //
    {                                                             //
      count = 0;                                                  //
      timeSensor = millis();                                      //
    }   ////////////////////////////////////////////////////////////
  
  // вывод кол-ва нажатий и времени оставшегося до сброса кол-ва нажатий
  Serial.print( count );   Serial.print( "   " );   Serial.println( ( millis() - timeSensor ) );   

  if ( count == 0 )
    {
      // выключить wtv020.playVoice( 1 );
      // выключить wtv020.playVoice( 2 );
      wtv020.playVoice( 0 );
      moveServoMdown();
      moveServoHdown();
    }
  if ( ( count >= 1 ) && ( count < 10 ) )
    {
      // выключить wtv020.playVoice( 0 );
      wtv020.playVoice( 1 );
      moveServoMdown();
      moveServoHup();
    }
  if ( count >= 10 )
    {
      // выключить wtv020.playVoice( 1 );
      wtv020.playVoice( 2 );
      moveServoMup();
      moveServoHdown();
      delay( 10000 );
      moveServoMdown();
      moveServoHdown();
      // выключить wtv020.playVoice( 2 );
      wtv020.playVoice( 0 );
    }
}
//================================================================================

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

#103 - лишняя

kernelkernel
Offline
Зарегистрирован: 20.01.2015

спасибо огромное за помощь! добавили в своем коде одну строчку, запитали сервоприводы как следует - и пошло поехало

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

код-то покажете ? и wtv020sd-16p заработал ?