[Из песочницы] 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; }
}}