[Из песочницы] Arduino в автомобиле. Озвучивание панели приборов

Из текста прошивки можно легко увидеть, куда заведены все анализируемые сигналы, куда прописать коды вашего ИК-пульта (взять их можно с помощью демо-скетча IRRecvDump). Также константами явно прописаны моменты срабатывания озвучки скоростей (обратите внимание на то, что скорости озвучиваются несколько раньше, чем будут реально достигнуты — чтоб успеть сбавить, не превысив).

#include  
//#include 
#include 
#include 
#include 
#include 
int RECV_PIN = 6; //пин подключения IR приёмника
IRrecv irrecv(RECV_PIN);
decode_results results;
byte cfg[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
byte mp3stek[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte mp3stekpos = 0;
volatile byte busy = 1; //mp3 busy  0=play
volatile byte softbusy = 0; 
volatile byte nomer_mp3 = 1; 

volatile unsigned long micros_sp = 0;
volatile byte sz = 0; //счетчик обнуления
volatile unsigned int sp = 0; //скорость
volatile unsigned int sp20 = 0; //скорость*10
volatile boolean st = false; //триггер
volatile byte ruka = 1; //ручник
volatile byte dsvet = 0; //д.свет
volatile byte gaba = 0; //габариты
volatile byte lastspeed = 0; //последняя скорость
volatile byte lastdsvet = 0; //переменная для отсчета д.света
volatile byte lastgaba = 0; //переменная для отсчета DHO
volatile byte lastgabaonoff = 0; //переменная для отсчета щелчкоф габаритов
volatile word gabaonofftimer = 0; //переменная для отсчета времени щелчкоф габаритов
volatile byte gabaonoffcounter = 0; //переменная для отсчета времени щелчкоф габаритов
volatile byte speed40 = 38; // 40
volatile byte speed60 = 58; // 60
volatile byte speed80 = 78; // 80
volatile byte speed110 = 108; // 110
volatile byte unspeed40 = 36; // no 40
volatile byte unspeed60 = 56; // no 60
volatile byte unspeed80 = 76; // no 80
volatile byte unspeed110 = 106; // no 110
volatile byte speed50 = 48; // 50
volatile byte unspeed50 = 46; // no 50
volatile byte speed70 = 68; // 70
volatile byte unspeed70 = 66; // no 70
volatile byte speed90 = 88; // 90
volatile byte unspeed90 = 86; // no 90
volatile byte speed100 = 98; // 100
volatile byte unspeed100 = 96; // no 100
volatile byte speed120 = 118; // 120
volatile byte unspeed120 = 116; // no 120
volatile byte speed130 = 128; // 130
volatile byte unspeed130 = 126; // no 130
volatile byte s40 = 0;
volatile byte s50 = 0;
volatile byte s60 = 0;
volatile byte s70 = 0;
volatile byte s80 = 0;
volatile byte s90 = 0;
volatile byte s100 = 0;
volatile byte s110 = 0;
volatile byte s120 = 0;
volatile byte s130 = 0;


//LiquidCrystal_I2C lcd(0x3F, 16, 2);

float sensorValue = 0; //V
float outputValue = 0;  //V

void setup()
{
       Serial.begin(9600);
       Serial.println("start programm NEXIA 1.0");
       //start IR reciver 
        irrecv.enableIRIn(); // Start the receiver
        // initialize the LCD
        //lcd.begin();
        // Turn on the blacklight and print a message.
        //lcd.backlight();
//      lcd.print("Hello, world!");
        //tone (17,3000); //тестовый сигнал на выводе D3
        pinMode(2, INPUT);      //  пин будет работать на вход speed
        digitalWrite(2, HIGH);//подключаем подтягивающий резистор
        pinMode(3, INPUT);      //  пин будет работать на вход
        digitalWrite(3, HIGH);//подключаем подтягивающий резистор
        pinMode(4, INPUT);      //  пин будет работать на вход
        digitalWrite(4, HIGH);//подключаем подтягивающий резистор
        pinMode(5, INPUT);      //  пин будет работать на вход
        digitalWrite(5, HIGH);//подключаем подтягивающий резистор
//      pinMode(13, OUTPUT);    // 
        lastgabaonoff = digitalRead(5); //gaba
        attachInterrupt(0,speedometr, RISING);
        cfg[0]=EEPROM.read(5); //0=all sound  1=no sound(ruka) 2=no sound all
        cfg[1]=EEPROM.read(6); //volume mp3 0..30
        cfg[2]=EEPROM.read(7); //0 = dsvet sound? 1 = no dsvet sound
        cfg[3]=EEPROM.read(8); //0 = 40sound
        cfg[4]=EEPROM.read(9); //0 = 60sound
        cfg[5]=EEPROM.read(10);//0 = 80sound
        cfg[6]=EEPROM.read(11);//0 = 110 sound
        cfg[7]=EEPROM.read(12);//0 = Voltmetr sound 
        cfg[8]=EEPROM.read(13);//0 = DHO sound
        cfg[9]=EEPROM.read(14);//0 = 50sound
        cfg[10]=EEPROM.read(15);//0 = 70sound
        cfg[11]=EEPROM.read(16);//0 = 90sound
        cfg[12]=EEPROM.read(17);//0 = 100sound
        cfg[13]=EEPROM.read(18);//0 = 120sound
        cfg[14]=EEPROM.read(19);//0 = 130sound
        cfg[15]=EEPROM.read(20);//0 = голос0, 1=голос1
        //управление мр3
        pinMode(7, INPUT);  //busy
        mp3_set_serial (Serial);    
//      mp3_set_volume (25);
        mp3setvol();
        delay (100); 
        add_mp3(32); //включен голосовой режим
       // Вольтметр
       analogReference (INTERNAL);
    //    voltmeter();
        if (cfg[7]==0){voltmetertest();} // вольтметр
}

void loop()
{
  //индикация режимов датчиков
    dsvet = digitalRead(3); // Получить состояние пина : 
//  if (dsvet==1) {  lcd.setCursor(3, 0);  lcd.print("DD ");}
//  else{lcd.setCursor(3, 0); lcd.print("_s ");};
  
      ruka = digitalRead(4); // Получить состояние пина : 
//  if (ruka==1) {  lcd.setCursor(0, 0);  lcd.print("_r ");}
//  else{lcd.setCursor(0, 0); lcd.print("RR ");};
  
      gaba = digitalRead(5); // Получить состояние пина : 
//  if (gaba==1) {  lcd.setCursor(6, 0);  lcd.print("GG");}
//  else{lcd.setCursor(6, 0); lcd.print("_g");};

//voltmetertest(); //тест вольтметра

//    digitalWrite(13, !digitalRead(2));
  
  //измерение скорости
//  lcd.setCursor(10, 0);
//  lcd.print("     ");
//  lcd.setCursor(10, 0);
//  lcd.print(sp);
//  lcd.setCursor(0, 1);
//  lcd.print("     ");
//  lcd.setCursor(0, 1);
//  lcd.print(sp20);
  if (sz != 0){sz--;}else{sp20=0;sp=0;};
  delay(50);
  //  sdisplay();
//действия
gabamute(); //управление звуком по тройному щелчку габаритами
if ((sp20>0)&(ruka==0)) {rukabeep();}//пищит ручник
else
{ //обрабатываем д.свет и скорость только если не пищит ручник
if (dsvet==1) { if ( lastdsvet<200){lastdsvet=lastdsvet+1;};}
if (dsvet==1) { if ((lastdsvet>35)&(lastdsvet<38)){svetbeep();}; }
if (dsvet==0) {lastdsvet=0;};
//конец обработки д. света

//предупреждение о дхо
if ((gaba==0)&&(sp20>0)) { if ( lastgaba<150){lastgaba=lastgaba+1;};}
if ((gaba==0)&&(sp20>0)) { if ((lastgaba>20)&(lastgaba<23)){DHO_beep();}; }
if (gaba==1) {lastgaba=0;};
if (sp20==0) {lastgaba=0;};

//обрабатываем контроль превышения скорости 40, 60, 80, 110
if ((lastspeed=speed40)) {
 if (s40<1) { svet1beep(); s40=1; }};
if ((lastspeed>=unspeed40)&(sp0) { nsvet1beep(); s40=0; }};
if ((lastspeed=speed50)) {
 if (s50<1) { svet50beep(); s50=1; }};
if ((lastspeed>=unspeed50)&(sp0) { nsvet50beep(); s50=0; }};
if ((lastspeed=speed60)) {
 if (s60<1) { svet2beep(); s60=1; }};
if ((lastspeed>=unspeed60)&(sp0) { nsvet2beep(); s60=0; }};
if ((lastspeed=speed70)) {
 if (s70<1) { svet70beep(); s70=1; }}; 
if ((lastspeed>=unspeed70)&(sp0) { nsvet70beep(); s70=0; }}; //костыль. иначе на 66км/ч без конца твердит "нет 70"почему - непонятно. поставил костыли на все скорости.
if ((lastspeed=speed80)) {
 if (s80<1) { svet3beep(); s80=1; }};
if ((lastspeed>=unspeed80)&(sp0) { nsvet3beep(); s80=0; }};
if ((lastspeed=speed90)) {
 if (s90<1) { svet90beep(); s90=1; }};
if ((lastspeed>=unspeed90)&(sp0) { nsvet90beep(); s90=0; }};
if ((lastspeed=speed100)) {
 if (s100<1) { svet100beep(); s100=1; }};
if ((lastspeed>=unspeed100)&(sp0) { nsvet100beep(); s100=0; }};
if ((lastspeed=speed110)) {
 if (s110<1) { svet4beep(); s110=1; }};
if ((lastspeed>=unspeed110)&(sp0) { nsvet4beep(); s110=0; }};
if ((lastspeed=speed120)) {
 if (s120<1) { svet120beep(); s120=1; }};
if ((lastspeed>=unspeed120)&(sp0) { nsvet120beep(); s120=0; }};
if ((lastspeed=speed130)) {
 if (s130<1) { svet130beep(); s130=1; }};
if ((lastspeed>=unspeed130)&(sp0) { nsvet130beep(); s130=0; }};
lastspeed=sp;
delay(50);
//конец обработки превышения скорости
}//конец обработки при молчащем рчнике
// voltmeter();
  
//обработка очереди мр3
if (mp3stekpos != 0) 
{ busy = digitalRead(7); // Получить состояние пина 7: 
  if (softbusy > 0) softbusy = softbusy-1;//предварительная задержка, т.к. busy возникает не сразу
  if ((busy>0) && (softbusy ==0)) //если не занят мр3
  {mp3stekpos = mp3stekpos-1;
   nomer_mp3 = mp3stek[1];
   if (cfg[15]==0) {mp3_play (mp3stek[1]);} else {mp3_play (mp3stek[1]+100);} //выбор голоса
   softbusy = 25;   delay(50);
   for (int i=1; i < 9; i++){mp3stek[i]=mp3stek[i+1]; }
   mp3stek[9]= 0;  };}

//обработка ПДУ сигналов
/**/ if (irrecv.decode(&results)) 
  {
    Serial.println(results.value);
//    lcd.setCursor(6, 1); 
//    lcd.print(results.value);
    
    //проверяем кнопки
    //кнопка повер или муте  общий выкл звука 0-2
    if ((results.value==2255209021)|| (results.value==2255218711))
    {  cfg[0]=cfg[0]+1;
       if (cfg[0]>2) { cfg[0]=0; };    EEPROM.write(5,cfg[0]);
       if (cfg[0]==0) {add_mp3(5);}; //sound on
       if (cfg[0]==1) {add_mp3(3);}; //sound off krome ruka
       if (cfg[0]==2) {add_mp3(4);}; }//sound off all

    //кнопка V+ - прибавить громкость мр3
    if ((results.value==2255188111)||(results.value==2155866645))
    {   cfg[1]=cfg[1]+1;
    if (cfg[1]>4) {cfg[1]=4;add_mp3(41);}
    if (cfg[1]==1) {add_mp3(38);}
    if (cfg[1]==2) {add_mp3(39);}
    if (cfg[1]==3) {add_mp3(40);}
    if (cfg[1]==4) {add_mp3(41);}
    mp3setvol();   EEPROM.write(6,cfg[1]);  }
    
    //кнопка V- - убавить громкость мр3
    if ((results.value==2255210551)||(results.value==2155809015))  
    { if (cfg[1]<1)  {add_mp3(37); }  else  {cfg[1]=cfg[1]-1;}
      if (cfg[1]==1) {add_mp3(38);}
      if (cfg[1]==2) {add_mp3(39);}
      if (cfg[1]==3) {add_mp3(40);}
      mp3setvol();     EEPROM.write(6,cfg[1]);   }

    if (results.value==2255192191)  //кнопка sourse - переключить голос на +100
    { if (cfg[15]==0){  cfg[15]=1;}  
      else  {           cfg[15]=0;} add_mp3(42);    
      EEPROM.write(20,cfg[15]);    }

    if (results.value==2255222791)    //кнопка синяя - отключение д.свет
    { if (cfg[2]==0) {  cfg[2]=1;   add_mp3(18);} //no dsvet
      else {            cfg[2]=0;   add_mp3(19); }//dsvet on
      EEPROM.write(7,cfg[2]);    }

    if (results.value==2255220751)    //кнопка 4 - отключение скорости 40
    { if (cfg[3]==0) {  cfg[3]=1;   add_mp3(36); }//40 off
      else  {           cfg[3]=0;   add_mp3(35); }//40 on
      EEPROM.write(8,cfg[3]);   }
    
    if (results.value==2255200351)    //кнопка 5 - отключение скорости 50
    {  if (cfg[9]==0) { cfg[9]=1;   add_mp3(65); } //50 off
       else  {          cfg[9]=0;   add_mp3(66); }//50 on
       EEPROM.write(14,cfg[9]);    }
    
    if (results.value==2255184031)    //кнопка 6 - отключение скорости 60
    {  if (cfg[4]==0) { cfg[4]=1;   add_mp3(12); }//60 off
       else   {         cfg[4]=0;   add_mp3(13); }//60 on
       EEPROM.write(9,cfg[4]);   }
    
    if (results.value==2255171791)    //кнопка 7 - отключение скорости 70
    {  if (cfg[10]==0) {cfg[10]=1;  add_mp3(45);} //70 off
       else   {         cfg[10]=0;  add_mp3(46); }//70 on
       EEPROM.write(15,cfg[10]); }
    
    if (results.value==2255204431)   //кнопка 8 - отключение скорости 80
    { if (cfg[5]==0) {  cfg[5]=1;   add_mp3(14); }//80 off
      else  {           cfg[5]=0;   add_mp3(15); }//80 on
      EEPROM.write(10,cfg[5]);   }

    if (results.value==2255179951)    //кнопка 9 - отключение скорости 90
    { if (cfg[11]==0) {cfg[11]=1;  add_mp3(49);} //90 off
      else {           cfg[11]=0;  add_mp3(50);} //90 on
      EEPROM.write(16,cfg[11]);  }

    if (results.value==2255194231)    //кнопка 0 - отключение скорости 100
    { if (cfg[12]==0) {cfg[12]=1;  add_mp3(53);} //100 off
      else  {          cfg[12]=0;  add_mp3(54);} //100 on
      EEPROM.write(17,cfg[12]);  }

    if (results.value==2255167711)    //кнопка 1 - отключение скорости 110
    { if (cfg[6]==0) { cfg[6]=1;   add_mp3(16);} //110 off
      else   {         cfg[6]=0;   add_mp3(17);} //110 on
      EEPROM.write(11,cfg[6]);   }

    if (results.value==2255163631)    //кнопка 2 - отключение скорости 120
    { if (cfg[13]==0) { cfg[13]=1;  add_mp3(57);} //120 off
      else {            cfg[13]=0;  add_mp3(58);} //120 on
      EEPROM.write(18,cfg[13]);   }

    if (results.value==2255175871)    //кнопка 3 - отключение скорости 130
    { if (cfg[14]==0) { cfg[14]=1;  add_mp3(61);} //130 off
      else   {          cfg[14]=0;  add_mp3(62);} //130 on
      EEPROM.write(19,cfg[14]);   }

    if ((results.value==2255206471)||(results.value==2155829925)) //кнопка зеленая? - отключение вольтметра
    { if (cfg[7]==0)  { cfg[7]=1;   add_mp3(27);} //no Вольтметр
      else    {         cfg[7]=0;   add_mp3(28);  voltmetertest(); }//Вольтметр on
      EEPROM.write(12,cfg[7]);   }
    
    if (results.value==2255190151)   //кнопка желтая - отключение DHO
    { if (cfg[8]==0) {  cfg[8]=1;   add_mp3(31);} //no DHO
      else    {         cfg[8]=0;   add_mp3(30);} //DHO on
      EEPROM.write(13,cfg[8]);    }
     
    irrecv.resume(); // Receive the next value
  }
}

//вывод в монитор порта текущих параметров
void sdisplay(){
 if (ruka==1) {  Serial.print("ruka=off ");}  else{ Serial.print("RUKA=ON  ");}; 
 if (dsvet==1) {  Serial.print("dsvet=off ");}  else{ Serial.print("DSVET=ON  ");};  
 if (gaba==1) {  Serial.print("gaba=off ");}  else{ Serial.print("GABA=ON  ");};  
 Serial.println(" ");
 Serial.print(" speed=");
 Serial.println(sp);
 Serial.println("++++++++++++++++++ END ++++++");
}

void speedometr(){ if (!st){micros_sp = micros();} else {sp20 = (12000000/(micros() - micros_sp));}  sp=sp20/20;  st = !st;  sz=10;}

void rukabeep()    { if  (cfg[2]!=2) {mp3_play (1);} delay(1000);}
void svetbeep()    { if ((cfg[2]==0)&&(cfg[0]==0))   {add_mp3(2);}}
void DHO_beep()    { if ((cfg[8]==0)&&(cfg[0]==0))   {add_mp3(29);}}
void svet1beep()   { if ((cfg[3]==0)&&(cfg[0]==0))   {add_mp3(33);}} //40
void nsvet1beep()  { if ((cfg[3]==0)&&(cfg[0]==0))   {add_mp3(34);}} //n40
void svet50beep()  { if ((cfg[9]==0)&&(cfg[0]==0))   {add_mp3(63);}} //50
void nsvet50beep() { if ((cfg[9]==0)&&(cfg[0]==0))   {add_mp3(64);}} //n50
void svet2beep()   { if ((cfg[4]==0)&&(cfg[0]==0))   {add_mp3(6);}}  //60
void nsvet2beep()  { if ((cfg[4]==0)&&(cfg[0]==0))   {add_mp3(7);}}  //n60
void svet70beep()  { if ((cfg[10]==0)&&(cfg[0]==0))  {add_mp3(43);}} //70
void nsvet70beep() { if ((cfg[10]==0)&&(cfg[0]==0))  {add_mp3(44);}} //n70
void svet3beep()   { if ((cfg[5]==0)&&(cfg[0]==0))   {add_mp3(8);}}  //80
void nsvet3beep()  { if ((cfg[5]==0)&&(cfg[0]==0))   {add_mp3(9);}}  //n80
void svet90beep()  { if ((cfg[11]==0)&&(cfg[0]==0))  {add_mp3(47);}} //90
void nsvet90beep() { if ((cfg[11]==0)&&(cfg[0]==0))  {add_mp3(48);}} //n90
void svet100beep() { if ((cfg[12]==0)&&(cfg[0]==0))  {add_mp3(51);}} //100
void nsvet100beep(){ if ((cfg[12]==0)&&(cfg[0]==0))  {add_mp3(52);}} //n100
void svet4beep()   { if ((cfg[6]==0)&&(cfg[0]==0))   {add_mp3(10);}} //110
void nsvet4beep()  { if ((cfg[6]==0)&&(cfg[0]==0))   {add_mp3(11);}} //n110
void svet120beep() { if ((cfg[13]==0)&&(cfg[0]==0))  {add_mp3(55);}} //120
void nsvet120beep(){ if ((cfg[13]==0)&&(cfg[0]==0))  {add_mp3(56);}} //n120
void svet130beep() { if ((cfg[14]==0)&&(cfg[0]==0))  {add_mp3(59);}} //130
void nsvet130beep(){ if ((cfg[14]==0)&&(cfg[0]==0))  {add_mp3(60);}} //n130
//void svet1unbeep(){  tone (17,1000);  delay(200);  noTone(17);}


void add_mp3(byte nomermp3)
{  if ((mp3stekpos > 8)&&(cfg[0]<2))//если переполнение очереди то пищалка
  {  if (cfg[0]==0)  { tone (17,1000);  delay(200);  tone (17,1400);  delay(200);  noTone(17);  }}//пищалку не включать если все звуки отключены
     else   {  mp3stekpos = mp3stekpos+1;  mp3stek[mp3stekpos] = nomermp3;   }} //собственно постановка в очередь

void mp3setvol() //перекодировка уровней громкости из 0-4 в 0-30
{if(cfg[1]==0){mp3_set_volume(10);}if(cfg[1]==1){mp3_set_volume(15);}if(cfg[1]==2){mp3_set_volume(20);}if(cfg[1]==3){mp3_set_volume(25);}if(cfg[1]>3){mp3_set_volume(30);}}

void voltmetertest()
{ outputValue = 0; 
  int u_x10 =0 ; 
  int u_x1 =0 ; 
  int u_x0 =0 ;
  for (int iii=0; iii <10 ; iii++) {  outputValue =outputValue + float(analogRead(A0));  delay(100); }//усреднение нескольких измерений
  outputValue =  outputValue/620;//коэффициент прямого пересчета в вольты
  u_x10=round(outputValue*10); //напряжение х10 
  u_x1=floor(u_x10/10); //целая часть вольтов
  add_mp3(70+u_x1);
  u_x0=u_x10-(10*u_x1);   //десятые = 10U-10Uокруг
  add_mp3(90+u_x0);
}

void gabamute()
{  if (lastgabaonoff==gaba)
{//габариты не трогали
gabaonofftimer=gabaonofftimer+1;
if (gabaonofftimer>250 ) 
 {//давно не трогали габариты - обнуляем ожидание
 gabaonofftimer=250;
 gabaonoffcounter=0;
 }
}
else
{//габариты щелкнули
lastgabaonoff=gaba;
if (gabaonoffcounter==0) {gabaonofftimer=0;} //первый щелчок
// Serial.println(gabaonofftimer);
if (gabaonofftimer<25)
 {//щелчок недавно был
 gabaonoffcounter=gabaonoffcounter+1;
 gabaonofftimer=0;
 if (gabaonoffcounter>5) 
   {//блок отключения-включения звука по циклу
    gabaonoffcounter=0;
    cfg[0]=cfg[0]+1;
    if (cfg[0]>2) { cfg[0]=0; };
    EEPROM.write(5,cfg[0]);
    if (cfg[0]==0) {add_mp3(5);}; //sound on
    if (cfg[0]==1) {add_mp3(3);}; //sound off krome ruka
    if (cfg[0]==2) {add_mp3(4);}; //sound off all
   } }
 else  {   gabaonoffcounter=0;   gabaonofftimer=0; }
}}


© Geektimes