//******************************************************************// // ESP32 Send IR DATA automatically // 2020.6.7 // ESP32_IRsend06_1.ino // Send data = Sellect Table DATA by tapping accelerometer randomly // ADXL345(I2C) accelerometer //******************************************************************// #include "driver/rmt.h" const int rmtDataLength = 34; // NEC format data length 34 bit rmt_item32_t rmtData[rmtDataLength]; // data to send const rmt_channel_t channel = RMT_CHANNEL_0; const gpio_num_t irPin = GPIO_NUM_25; //****************************************// const gpio_num_t PTMPin = GPIO_NUM_32; // Potentiometer input const gpio_num_t AMBPin = GPIO_NUM_33; // Ambient senser const gpio_num_t MICPin = GPIO_NUM_34; // Audio senser //****************************************// const int leaderOnUs = 9000; const int leaderOffUs = 4500; const int dataOnUs = 560; const int data1OffUs = 1690; const int data0OffUs = 560; const int stopbitOnUs = 560; const int stopbitOffUs = 0x7fff; //*************************************************************// // LED Brink Pattern Table definition //*************************************************************// /* LED pattern variable */ int LEDpatNo = 0; //LED pattern int LEDpatCnt = 0; //LED data counter int actionmode = 0;//インプットデバイスを使って色を変える int singletap = 0;//setupでもloopの中でも使えるように int Randomcounter = 0;//何回に一回ランダム表示を切り替えるか /* Define KEY Code */ #define K0 0x16 #define K1 0x0C #define K2 0x18 #define K3 0x5E #define K4 0x08 #define K5 0x1C #define K6 0x5A #define K7 0x42 /* define LED pattern */ uint8_t LED0[] = { 1, K0 }; // --- uint8_t LED1[] = { 1, K1 }; // --B uint8_t LED2[] = { 1, K2 }; // -G- uint8_t LED3[] = { 1, K3 }; // -GB uint8_t LED4[] = { 1, K4 }; // R-- uint8_t LED5[] = { 1, K5 }; // R-B uint8_t LED6[] = { 1, K6 }; // RG- uint8_t LED7[] = { 1, K7 }; // RGB uint8_t LED8[] = { 4, K4, K0, K4, K0 }; // uint8_t LED9[] = { 4, K4, K2, K1, K0 }; // uint8_t LED10[] = { 7, K2, K2, K2, K0, K2, K2, K0 }; // uint8_t LED11[] = { 8, K4, K4, K0, K2, K2, K0, K1, K1, K0 }; // uint8_t LED12[] = { 7, K1, K2, K3, K4, K5, K6, K7 }; // uint8_t LED13[] = { 14, K1, K1, K2, K2, K3, K3, K4, K4, K5, K5, K6, K6, K7, K7 }; // uint8_t LED14[] = { 6, K4, K0, K4, K0, K0, K0 }; // uint8_t LED15[] = { 16, K4, K2, K1, K0, K4, K2, K1, K0, K4, K0, K2, K0, K6, K0, K0 }; // Pattern15 uint8_t *LEDTBL[] = { LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7, LED8, LED9, LED10, LED11, LED12, LED13, LED14, LED15 }; //*** End of LED Brink Pattern Table definition ****************************// //***** Accelerometer ***** #include #include ADXL345 adxl; /* send NEC format remote control data */ void sendData(uint16_t customCode, uint8_t dataCode) { /* leader code 1bit: ON 9000us, OFF 4500us */ rmtData[0].duration0 = leaderOnUs; rmtData[0].level0 = 1; rmtData[0].duration1 = leaderOffUs; rmtData[0].level1 = 0; /* * custom code 16 bit * INPUT series: b15 b14 b13 b12 b11 b10 b09 b08 b07 b06 b05 b04 b03 b02 b01 b00 * SEND series: b08 b09 b10 b11 b12 b13 b14 b15 b00 b01 b02 b03 b04 b05 b06 b07 */ for (int i = 0; i < 2; i++) { for (int j = 0; j < 8; j++) { /* * 1: ON 560us + OFF 1690us * 0: ON 560us + OFF 560us */ rmtData[8 * i + j + 1].duration0 = dataOnUs; rmtData[8 * i + j + 1].level0 = 1; if (customCode & (1 << ((1 - i) * 8 + j))) { rmtData[8 * i + j + 1].duration1 = data1OffUs; } else { rmtData[8 * i + j + 1].duration1 = data0OffUs; } rmtData[8 * i + j + 1].level1 = 0; } } /* * data code 8bit * INPUT series: b7 b6 b5 b4 b3 b2 b1 b0 * SEND series: b0 b1 b2 b3 b4 b5 b6 b7 ~b0 ~b1 ~b2 ~b3 ~b4 ~b5 ~b6 ~b7 */ for (int i = 0; i < 8; i++) { rmtData[i + 17].duration0 = dataOnUs; rmtData[i + 25].duration0 = dataOnUs; rmtData[i + 17].level0 = 1; rmtData[i + 25].level0 = 1; if (dataCode & (1 << i)) { rmtData[i + 17].duration1 = data1OffUs; rmtData[i + 25].duration1 = data0OffUs; } else { rmtData[i + 17].duration1 = data0OffUs; rmtData[i + 25].duration1 = data1OffUs; } rmtData[i + 17].level1 = 0; rmtData[i + 25].level1 = 0; } /* stop bit 1bit: ON 560 */ rmtData[33].duration0 = stopbitOnUs; rmtData[33].level0 = 1; rmtData[33].duration1 = stopbitOffUs; rmtData[33].level1 = 0; rmt_write_items(channel, rmtData, rmtDataLength, true); } //*************************************************// // Print 8bit data in HEX to console //*************************************************// void hexprint(uint8_t data){ char HEXTBL[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; Serial.print(HEXTBL[ (data & 0xF0) >> 4 ]); Serial.print(HEXTBL[ (data & 0x0F)]); } //*************************************************// // MAIN PROCESS //*************************************************// void setup() { rmt_config_t rmtConfig; rmtConfig.rmt_mode = RMT_MODE_TX; // transmit mode rmtConfig.channel = channel; // channel to use 0 - 7 rmtConfig.clk_div = 80; // clock divider 1 - 255. source clock is 80MHz -> 80MHz/80 = 1MHz -> 1 tick = 1 us rmtConfig.gpio_num = irPin; // pin to use rmtConfig.mem_block_num = 1; // memory block size rmtConfig.tx_config.loop_en = 0; // no loop rmtConfig.tx_config.carrier_freq_hz = 38000; // IR remote controller uses 38kHz carrier frequency rmtConfig.tx_config.carrier_duty_percent = 33; // duty rmtConfig.tx_config.carrier_level = RMT_CARRIER_LEVEL_HIGH; // carrier level rmtConfig.tx_config.carrier_en = 1; // carrier enable rmtConfig.tx_config.idle_level = RMT_IDLE_LEVEL_LOW ; // signal level at idle rmtConfig.tx_config.idle_output_en = 1; // output if idle rmt_config(&rmtConfig); rmt_driver_install(rmtConfig.channel, 0, 0); Serial.begin(115200); pinMode( PTMPin, INPUT ); pinMode( AMBPin, INPUT ); pinMode( MICPin, INPUT ); adxl.powerOn(); //set activity/ inactivity thresholds (0-255) adxl.setActivityThreshold(75); //62.5mg per increment adxl.setInactivityThreshold(75); //62.5mg per increment adxl.setTimeInactivity(10); // how many seconds of no activity is inactive? //look of activity movement on this axes - 1 == on; 0 == off adxl.setActivityX(1); adxl.setActivityY(1); adxl.setActivityZ(1); //look of inactivity movement on this axes - 1 == on; 0 == off adxl.setInactivityX(1); adxl.setInactivityY(1); adxl.setInactivityZ(1); //look of tap movement on this axes - 1 == on; 0 == off adxl.setTapDetectionOnX(0); adxl.setTapDetectionOnY(0); adxl.setTapDetectionOnZ(1); //set values for what is a tap, and what is a double tap (0-255) adxl.setTapThreshold(50); //62.5mg per increment adxl.setTapDuration(15); //625μs per increment adxl.setDoubleTapLatency(80); //1.25ms per increment adxl.setDoubleTapWindow(200); //1.25ms per increment //set values for what is considered freefall (0-255) adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per increment adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment //setting all interupts to take place on int pin 1 //I had issues with int pin 2, was unable to reset it adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN ); //register interupt actions - 1 == on; 0 == off adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1); adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1); adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1); /* initialize variables */ LEDpatNo = 0; LEDpatCnt = 0; } void loop() { //光と音の検出 int amb = analogRead(AMBPin); int mic = analogRead(MICPin); int ptm = analogRead(PTMPin); //加速度センサーの検出 //Boring accelerometer stuff //int x,y,z; //adxl.readXYZ(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Output x,y,z values - Commented out //Serial.print(x); //Serial.print(y); //Serial.println(z); //read interrupts source and look for triggerd actions //getInterruptSource clears all triggered actions after returning value //so do not call again until you need to recheck for triggered actions byte interrupts = adxl.getInterruptSource(); // freefall //if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){ //Serial.println("Free-fall detected."); //自由落下を検出しました。 //add code here to do when freefall is sensed //} //inactivity //if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){ //Serial.println("No motion detected."); //動きを検出しなかった。 //add code here to do when inactivity is sensed //} //activity //if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){ //Serial.println("Motion detected."); //動きを検出しました。 // LEDpatNo = random( 0, 7 ); // LEDpatCnt = 0; //} //double tap if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){ Serial.println("Double tap detected."); //ダブルタップを検出しました。 actionmode = actionmode+1; if(actionmode>5){//ここを4から5に変えないとRam2までいかなかった actionmode = 0;//ダブルタップをしたらアクションモードが1つずつ変わる } LEDpatCnt = 0;//テーブルが変わってもいいようにしておく } /* //tap if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){ Serial.println("Single tap detected."); //シングルタップを検出しました。 LEDpatNo = random( 8, 15 ); LEDpatCnt = 0; } */ //tap if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP) && !adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){ Serial.println("Single tap detected."); //シングルタップを検出しました。 singletap = 1;//シングルタップされたことを記憶するだけ LEDpatCnt = 0; } //actionmodeを切り替える switch(actionmode){ case 0: Ambmode(amb); break; case 1: Micmode(mic); break; case 2: Tapmode(); break; case 3: Potmode(ptm); break; case 4: Ram1mode(); break; case 5: Ram2mode(); break; } //表示 /* Send LED data sequncially in the LED Pattern Table */ uint8_t *p; // Define KeyPatternAddress pointer p = LEDTBL[LEDpatNo]; // Set pointer address int i = *p; // Get pattern length uint8_t kdata = *(p + LEDpatCnt + 1); // get Keydata sendData(0x00ff, kdata); // hexprint(kdata); // Serial.print(" "); LEDpatCnt++; if ( LEDpatCnt > i-1 ) { LEDpatCnt = 0; // Serial.println(); } // delay(30); } void Micmode(int analogdata3){ //音センサーで制御するプログラム if(analogdata3<500){ LEDpatNo = 0; } else if(analogdata3<1000){ LEDpatNo = 1; } else if(analogdata3<1500){ LEDpatNo = 2; } else if(analogdata3<2000){ LEDpatNo = 3; } else if(analogdata3<2500){ LEDpatNo = 4; } else if(analogdata3<3000){ LEDpatNo = 5; } else if(analogdata3<3500){ LEDpatNo = 6; } else{ LEDpatNo = 7; } LEDpatCnt = 0; } void Ambmode(int analogdata2){ //光センサーで制御するプログラム if(analogdata2<500){ LEDpatNo = 0; } else if(analogdata2<1000){ LEDpatNo = 1; } else if(analogdata2<1500){ LEDpatNo = 2; } else if(analogdata2<2000){ LEDpatNo = 3; } else if(analogdata2<2500){ LEDpatNo = 4; } else if(analogdata2<3000){ LEDpatNo = 5; } else if(analogdata2<3500){ LEDpatNo = 6; } else{ LEDpatNo = 7; } LEDpatCnt = 0; } void Potmode(int analogdata1){ //ポテンショメータで制御するプログラム if(analogdata1<500){ LEDpatNo = 0; } else if(analogdata1<1000){ LEDpatNo = 1; } else if(analogdata1<1500){ LEDpatNo = 2; } else if(analogdata1<2000){ LEDpatNo = 3; } else if(analogdata1<2500){ LEDpatNo = 4; } else if(analogdata1<3000){ LEDpatNo = 5; } else if(analogdata1<3500){ LEDpatNo = 6; } else{ LEDpatNo = 7; } LEDpatCnt = 0; } void Tapmode(){ if(singletap = 1){ LEDpatNo = random(8,16); singletap = 0; LEDpatCnt = 0; } } void Ram1mode(){ LEDpatNo = random(0,8); LEDpatCnt = 0; } void Ram2mode(){ Randomcounter++; if(Randomcounter>20){//約2秒に1回パターンが変わる LEDpatNo = random(8,16); LEDpatCnt = 0; Randomcounter = 0; } }