So I need to put a function to my ESP8266 module, It is connected to the Expansion board of my Arduino along side the wires of IR remote sensor, ultrasonic sensor, Bluetooth module. My main problem is I cannot put a function code to the ESP8266 wifi module (sorry I'm a complete beginner with no knowledge to these things). Below is my code for the movement of my RC car with their respective file names on top (Can you guys create a function to my wifi module [any would do]):
code_of_the_current_rc.ino:
// Include necessary libraries and header files
#include "IR_remote.h"
#include "keymap.h"
// Define an IRremote object with pin 12 for IR communication
IRremote ir(12);
// Include the Servo library for controlling the servo motor
#include <Servo.h>
// Declare global variables
String BT_value;
String BT_value_temp;
volatile boolean Funtion_FLag;
volatile int Left_Tra_Value;
volatile int Center_Tra_Value;
volatile int Right_Tra_Value;
volatile int Black;
volatile int white;
volatile int Front_Distance;
volatile int Left_Distance;
volatile int Right_Distance;
volatile char IR_Car_Mode;
volatile boolean IR_Mode_Flag;
Servo servo_A2;
// Function to perform infrared tracing based on sensor readings
void Infrared_Tracing() {
Left_Tra_Value = digitalRead(9);
Center_Tra_Value = digitalRead(10);
Right_Tra_Value = digitalRead(11);
// Check the sensor readings and perform corresponding actions
if (Left_Tra_Value != Black && (Center_Tra_Value == Black && Right_Tra_Value != Black)) {
Move_Forward(130);
} else if (Left_Tra_Value == Black && (Center_Tra_Value == Black && Right_Tra_Value != Black)) {
Rotate_Left(180);
} else if (Left_Tra_Value == Black && (Center_Tra_Value != Black && Right_Tra_Value != Black)) {
Rotate_Left(160);
} else if (Left_Tra_Value != Black && (Center_Tra_Value != Black && Right_Tra_Value == Black)) {
Rotate_Right(160);
} else if (Left_Tra_Value != Black && (Center_Tra_Value == Black && Right_Tra_Value == Black)) {
Rotate_Right(180);
} else if (Left_Tra_Value == Black && (Center_Tra_Value == Black && Right_Tra_Value == Black)) {
STOP();
}
}
// Function to move the car forward with a specified speed
void Move_Forward(int car_speed) {
digitalWrite(2, LOW);
digitalWrite(4, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
analogWrite(5, car_speed);
analogWrite(6, car_speed);
}
// Function to move the car backward with a specified speed
void Move_Backward(int car_speed) {
digitalWrite(2, HIGH);
digitalWrite(4, LOW);
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
analogWrite(5, car_speed);
analogWrite(6, car_speed);
}
// Function to rotate the car left with a specified speed
void Rotate_Left(int car_speed) {
digitalWrite(2, LOW);
digitalWrite(4, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
analogWrite(5, car_speed);
analogWrite(6, car_speed);
}
// Function to rotate the car right with a specified speed
void Rotate_Right(int car_speed) {
digitalWrite(2, HIGH);
digitalWrite(4, LOW);
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
analogWrite(5, car_speed);
analogWrite(6, car_speed);
}
// Function to stop the car
void STOP() {
digitalWrite(2, HIGH);
digitalWrite(4, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
analogWrite(5, 0);
analogWrite(6, 0);
}
// Function to check the distance using an ultrasonic sensor
float checkdistance() {
digitalWrite(A1, LOW);
delayMicroseconds(2);
digitalWrite(A1, HIGH);
delayMicroseconds(10);
digitalWrite(A1, LOW);
float distance = pulseIn(A0, HIGH) / 58.00;
delay(10);
return distance;
}
// Function to perform obstacle avoidance using ultrasonic sensor
void Ultrasonic_Avoidance() {
Front_Distance = checkdistance();
// Check the front distance and take action accordingly
if (0 < Front_Distance && Front_Distance <= 20) {
STOP();
delay(100);
// Rotate the servo to measure distances on the left and right
servo_A2.write(180);
delay(500);
Left_Distance = checkdistance();
delay(100);
servo_A2.write(0);
delay(500);
Right_Distance = checkdistance();
delay(100);
// Determine whether to turn left or right based on distances
if (Right_Distance <= Left_Distance) {
Rotate_Left(255);
servo_A2.write(90);
delay(300);
} else {
Rotate_Right(255);
servo_A2.write(90);
delay(300);
}
} else {
Move_Forward(150);
}
}
// Function to handle IR remote control commands
void IR_remote_control() {
switch (IR_Car_Mode) {
case 'b':
Move_Backward(255);
delay(300);
STOP();
IR_Car_Mode = ' ';
break;
case 'f':
Move_Forward(255);
delay(300);
STOP();
IR_Car_Mode = ' ';
break;
case 'l':
Rotate_Left(255);
delay(300);
STOP();
IR_Car_Mode = ' ';
break;
case 'r':
Rotate_Right(255);
delay(300);
STOP();
IR_Car_Mode = ' ';
break;
case 's':
STOP();
IR_Car_Mode = ' ';
break;
}
// Check IR remote key presses and update car mode
if (ir.getIrKey(ir.getCode(), 1) == IR_KEYCODE_UP) {
IR_Car_Mode = 'f';
IR_Mode_Flag = true;
} else if (ir.getIrKey(ir.getCode(), 1) == IR_KEYCODE_LEFT) {
IR_Car_Mode = 'l';
IR_Mode_Flag = true;
} else if (ir.getIrKey(ir.getCode(), 1) == IR_KEYCODE_DOWN) {
IR_Car_Mode = 'b';
IR_Mode_Flag = true;
} else if (ir.getIrKey(ir.getCode(), 1) == IR_KEYCODE_RIGHT) {
IR_Car_Mode = 'r';
IR_Mode_Flag = true;
} else if (ir.getIrKey(ir.getCode(), 1) == IR_KEYCODE_OK) {
IR_Car_Mode = 's';
IR_Mode_Flag = true;
}
}
// Setup function to initialize hardware and variables
void setup() {
Serial.begin(9600);
BT_value = "";
BT_value_temp = "";
Funtion_FLag = false;
Left_Tra_Value = 1;
Center_Tra_Value = 1;
Right_Tra_Value = 1;
Black = 1;
white = 0;
Front_Distance = 0;
Left_Distance = 0;
Right_Distance = 0;
IR_Car_Mode = ' ';
IR_Mode_Flag = false;
// Set pin modes for sensors, motors, and servo
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(A0, INPUT);
servo_A2.attach(A2);
}
// Loop function to continuously run the car control logic
void loop() {
while (true) {
// Read Bluetooth input and update BT_value
while (Serial.available() > 0) {
BT_value_temp = BT_value_temp + ((char)(Serial.read()));
delay(2);
if (!Serial.available() > 0) {
BT_value = BT_value_temp;
BT_value_temp = "";
}
}
// Process Bluetooth input and perform corresponding actions
if (0 < String(BT_value).length()) {
Serial.println(BT_value);
Serial.println(String(BT_value).length());
// Check if the received Bluetooth command is valid
if (4 >= String(BT_value).length()) {
if ('%' == String(BT_value).charAt(0) && '#' == String(BT_value).charAt((String(BT_value).length() - 1))) {
// Check and execute the command based on the second character of the command
if (IR_Mode_Flag == true) {
STOP();
IR_Car_Mode = ' ';
IR_Mode_Flag = false;
}
switch (String(BT_value).charAt(1)) {
case 'F':
Move_Forward(255);
delay(500);
BT_value = "";
break;
case 'B':
Move_Backward(255);
delay(500);
BT_value = "";
break;
case 'L':
Rotate_Left(230);
delay(300);
BT_value = "";
break;
case 'R':
Rotate_Right(230);
delay(300);
BT_value = "";
break;
case 'T':
Infrared_Tracing();
break;
case 'S':
BT_value = "";
STOP();
break;
case 'A':
Ultrasonic_Avoidance();
break;
case 'Z':
break;
}
}
} else {
BT_value = "";
STOP();
}
} else {
STOP();
}
// Check and process IR remote control commands
IR_remote_control();
}
}
IR_remote.cpp:
#include "IR_remote.h"
#include "Keymap.h"
// Provides ISR
#ifndef __AVR_ATmega32U4__
#include <avr/interrupt.h>
volatile irparams_t irparams;
bool MATCH(uint8_t measured_ticks, uint8_t desired_us)
{
// Serial.print(measured_ticks);Serial.print(",");Serial.println(desired_us);
return(measured_ticks >= desired_us - (desired_us>>2)-1 && measured_ticks <= desired_us + (desired_us>>2)+1);
}
ISR(TIMER_INTR_NAME)
{
// Serial.println("ISR");
//Serial.println(millis());
uint8_t irdata = (uint8_t)digitalRead(irparams.recvpin);
// uint32_t new_time = micros();
// uint8_t timer = (new_time - irparams.lastTime)>>6;
irparams.timer++; // One more 50us tick
if (irparams.rawlen >= RAWBUF)
{
// Buffer overflow
irparams.rcvstate = STATE_STOP;
}
switch(irparams.rcvstate)
{
case STATE_IDLE: // In the middle of a gap
if (irdata == MARK)
{
irparams.rawlen = 0;
irparams.timer = 0;
irparams.rcvstate = STATE_MARK;
}
break;
case STATE_MARK: // timing MARK
if (irdata == SPACE)
{
// MARK ended, record time
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
irparams.timer = 0;
irparams.rcvstate = STATE_SPACE;
}
break;
case STATE_SPACE: // timing SPACE
if (irdata == MARK)
{
// SPACE just ended, record it
irparams.rawbuf[irparams.rawlen++] = irparams.timer;
irparams.timer = 0;
irparams.rcvstate = STATE_MARK;
}
else
{ // SPACE
if (irparams.timer > GAP_TICKS)
{
// big SPACE, indicates gap between codes
// Mark current code as ready for processing
// Switch to STOP
// Don't reset timer; keep counting space width
irparams.rcvstate = STATE_STOP;
irparams.lastTime = millis();
}
}
break;
case STATE_STOP: // waiting, measuring gap
if(millis() - irparams.lastTime > 120)
{
irparams.rawlen = 0;
irparams.timer = 0;
irparams.rcvstate = STATE_IDLE;
}
else if (irdata == MARK)
{
// reset gap timer
irparams.timer = 0;
}
break;
}
// irparams.lastTime = new_time;
}
/**
* Alternate Constructor which can call your own function to map the IR to arduino port,
* no pins are used or initialized here.
* \param[in]
* None
*/
IRremote::IRremote(int pin)
{
pinMode(pin,INPUT);
irparams.recvpin = pin;
// attachInterrupt(INT0, irISR, CHANGE);
irDelayTime = 0;
irIndex = 0;
irRead = 0;
irReady = false;
irBuffer = "";
irPressed = false;
begin();
}
/**
* \par Function
* begin
* \par Description
* Initialize interrupt.
* \param[in]
* None
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::begin()
{
cli();
// setup pulse clock timer interrupt
//Prescale /8 (16M/8 = 0.5 microseconds per tick)
// Therefore, the timer interval can range from 0.5 to 128 microseconds
// depending on the reset value (255 to 0)
TIMER_CONFIG_NORMAL();
//Timer2 Overflow Interrupt Enable
TIMER_ENABLE_INTR;
// TIMER_RESET;
sei(); // enable interrupts
// initialize state machine variables
irparams.rawlen = 0;
irparams.rcvstate = STATE_IDLE;
}
/**
* \par Function
* end
* \par Description
* Close the interrupt.
* \param[in]
* None
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::end()
{
EIMSK &= ~(1 << INT0);
}
/**
* \par Function
* decode
* \par Description
* Decodes the received IR message.
* \param[in]
* None
* \par Output
* None
* \par Return
* Returns 0 if no data ready, 1 if data ready.
* \par Others
* Results of decoding are stored in results.
*/
ErrorStatus IRremote::decode()
{
rawbuf = irparams.rawbuf;
rawlen = irparams.rawlen;
if (irparams.rcvstate != STATE_STOP)
{
return ERROR;
}
if (decodeNEC())
{
begin();
return SUCCESS;
}
begin();
return ERROR;
}
/**
* \par Function
* decodeNEC
* \par Description
* Decodes NEC the received IR message.
* \param[in]
* None
* \par Output
* None
* \par Return
* Returns ERROR if decode NEC no done, SUCCESS if decode NEC done.
* \par Others
* Results of decode NEC.
*/
// NECs have a repeat only 4 items long
ErrorStatus IRremote::decodeNEC()
{
static unsigned long repeat_value = 0xFFFFFFFF;
static byte repeta_time = 0;
uint32_t data = 0;
int offset = 0; // Skip first space
// Initial mark
if (!MATCH(rawbuf[offset], NEC_HDR_MARK/50))
{
return ERROR;
}
offset++;
// Check for repeat
if (rawlen == 3 &&
MATCH(rawbuf[offset], NEC_RPT_SPACE/50) &&
MATCH(rawbuf[offset+1], NEC_BIT_MARK/50))
{
rawbuf[offset] = 0;
rawbuf[offset+1] = 0;
repeta_time++;
// if(repeta_time > 1) {
repeta_time = 0;
bits = 0;
value = repeat_value;
// Serial.println("REPEAT");
decode_type = NEC;
return SUCCESS;
// }
}
if (rawlen < (2 * NEC_BITS + 3))
{
return ERROR;
}
// Initial space
if (!MATCH(rawbuf[offset], NEC_HDR_SPACE/50))
{
return ERROR;
}
rawbuf[offset] = 0;
offset++;
for (int i = 0; i < NEC_BITS; i++)
{
if (!MATCH(rawbuf[offset], NEC_BIT_MARK/50))
{
return ERROR;
}
rawbuf[offset] = 0;
offset++;
if (MATCH(rawbuf[offset], NEC_ONE_SPACE/50))
{
//data = (data << 1) | 1;
data = (data >> 1) | 0x80000000;
}
else if (MATCH(rawbuf[offset], NEC_ZERO_SPACE/50))
{
//data <<= 1;
data >>= 1;
}
else
{
return ERROR;
}
offset++;
}
// Success
bits = NEC_BITS;
value = data;
repeat_value = data;
decode_type = NEC;
repeta_time = 0;
return SUCCESS;
}
/**
* \par Function
* mark
* \par Description
* Sends an IR mark for the specified number of microseconds.
* \param[in]
* us - THe time of a PWM.
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::mark(uint16_t us)
{
// Sends an IR mark for the specified number of microseconds.
// The mark output is modulated at the PWM frequency.
TIMER_ENABLE_PWM; // Enable pin 3 PWM output
delayMicroseconds(us);
}
/**
* \par Function
* space
* \par Description
* Sends an IR mark for the specified number of microseconds.
* \param[in]
* us - THe time of a PWM.
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
/* Leave pin off for time (given in microseconds) */
void IRremote::space(uint16_t us)
{
// Sends an IR space for the specified number of microseconds.
// A space is no output, so the PWM output is disabled.
TIMER_DISABLE_PWM; // Disable pin 3 PWM output
delayMicroseconds(us);
}
/**
* \par Function
* enableIROut
* \par Description
* Enable an IR for the specified number of khz.
* \param[in]
* us - THe time of a INTR.
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::enableIROut(uint8_t khz)
{
TIMER_DISABLE_INTR; //Timer2 disable Interrupt
TIMER_CONFIG_KHZ(khz);
}
/**
* \par Function
* enableIRIn
* \par Description
* Enable an IR to write in.
* \param[in]
* None
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
// initialization
void IRremote::enableIRIn() {
cli();
// setup pulse clock timer interrupt
//Prescale /8 (16M/8 = 0.5 microseconds per tick)
// Therefore, the timer interval can range from 0.5 to 128 microseconds
// depending on the reset value (255 to 0)
TIMER_CONFIG_NORMAL();
//Timer2 Overflow Interrupt Enable
TIMER_ENABLE_INTR;
//TIMER_RESET;
sei(); // enable interrupts
// initialize state machine variables
irparams.rcvstate = STATE_IDLE;
irparams.rawlen = 0;
// set pin modes
pinMode(irparams.recvpin, INPUT);
}
/**
* \par Function
* sendRaw
* \par Description
* Send the length of data with hz.
* \param[in]
* buf[] - The data's buffer.
* \param[in]
* len - The data's length.
* \param[in]
* hz - The hz for sending data.
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::sendRaw(unsigned int buf[], int len, uint8_t hz)
{
enableIROut(hz);
for (int i = 0; i < len; i++)
{
if (i & 1)
{
space(buf[i]);
}
else
{
mark(buf[i]);
}
}
space(0); // Just to be sure
}
/**
* \par Function
* getString
* \par Description
* Get string in a INTR.
* \param[in]
* None
* \par Output
* None
* \par Return
* Return the result in a IRQ.
* \par Others
* None
*/
String IRremote::getString()
{
if(decode())
{
irRead = ((value >> 8) >> 8) & 0xff;
if(irRead == 0xa || irRead == 0xd)
{
irIndex = 0;
irReady = true;
}
else
{
irBuffer += irRead;
irIndex++;
}
irDelayTime = millis();
}
else
{
if(irRead > 0)
{
if(millis() - irDelayTime > 100)
{
irPressed = false;
irRead = 0;
irDelayTime = millis();
Pre_Str = "";
}
}
}
if(irReady)
{
irReady = false;
String s = String(irBuffer);
Pre_Str = s;
irBuffer = "";
return s;
}
return Pre_Str;
}
/**
* \par Function
* getCode
* \par Description
* Get the reading code.
* \param[in]
* None
* \par Output
* None
* \par Return
* Return the result of reading.
* \par Others
* None
*/
unsigned char IRremote::getCode()
{
irIndex = 0;
loop();
return irRead;
}
String IRremote::getKeyMap(byte keycode, byte ir_type)
{
byte i;
ST_KEY_MAP *irkeymap = normal_ir_keymap;
if (ir_type == IR_TYPE_EM) irkeymap = em_ir_keymap;
for (i = 0; i < KEY_MAX; i++) {
if (irkeymap[i].keycode == keycode)
return irkeymap[i].keyname;
}
return "";
}
byte IRremote::getIrKey(byte keycode, byte ir_type)
{
byte i;
ST_KEY_MAP *irkeymap = normal_ir_keymap;
if (ir_type == IR_TYPE_EM) irkeymap = em_ir_keymap;
for (i = 0; i < KEY_MAX; i++) {
if (irkeymap[i].keycode == keycode)
return i;
}
return 0xFF;
}
/**
* \par Function
* sendString
* \par Description
* Send data.
* \param[in]
* s - The string you want to send.
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::sendString(String s)
{
unsigned long l;
uint8_t data;
s.concat('\n');
for(int i = 0;i < s.length();i++)
{
data = s.charAt(i);
l = 0x0000ffff & (uint8_t)(~data);
l = l << 8;
l = l + ((uint8_t)data);
l = l << 16;
l = l | 0x000000ff;
sendNEC(l,32);
delay(20);
}
enableIRIn();
}
/**
* \par Function
* sendString
* \par Description
* Send data.
* \param[in]
* v - The string you want to send.
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::sendString(float v)
{
dtostrf(v,5, 8, floatString);
sendString(floatString);
}
/**
* \par Function
* sendNEC
* \par Description
* Send NEC.
* \param[in]
* data - The data you want to send.
* \param[in]
* nbits - The data bit you want to send.
* \par Output
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::sendNEC(unsigned long data, int nbits)
{
enableIROut(38);
mark(NEC_HDR_MARK);
space(NEC_HDR_SPACE);
for (int i = 0; i < nbits; i++)
{
if (data & 1)
{
mark(NEC_BIT_MARK);
space(NEC_ONE_SPACE);
}
else
{
mark(NEC_BIT_MARK);
space(NEC_ZERO_SPACE);
}
data >>= 1;
}
mark(NEC_BIT_MARK);
space(0);
}
/**
* \par Function
* loop
* \par Description
* A circle of operation.
* \param[in]
* None
* \par Output0
* None
* \par Return
* None
* \par Others
* None
*/
void IRremote::loop()
{
if(decode())
{
irRead = ((value >> 8) >> 8) & 0xff;
irPressed = true;
if(irRead == 0xa || irRead == 0xd)
{
irIndex = 0;
irReady = true;
}
else
{
irBuffer += irRead;
irIndex++;
if(irIndex > 64)
{
irIndex = 0;
irBuffer = "";
}
}
irDelayTime = millis();
}
else
{
if(irRead > 0)
{
// Serial.println(millis() - irDelayTime);
if(millis() - irDelayTime > 0)
{
irPressed = false;
irRead = 0;
irDelayTime = millis();
}
}
}
// Serial.println(irRead, HEX);
}
/**
* \par Function
* keyPressed
* \par Description
* Press key.
* \param[in]
* None
* \par Output
* None
* \par Return
* Return you the pressed key or not.
* \par Others
* None
*/
boolean IRremote::keyPressed(unsigned char r)
{
irIndex = 0;
loop();
return irRead == r;
}
#endif // !defined(__AVR_ATmega32U4__)
IR_remote.h:
#ifndef IRremote_h
#define IRremote_h
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
#include <Arduino.h>
#ifdef ME_PORT_DEFINED
#endif // ME_PORT_DEFINED
#ifndef __AVR_ATmega32U4__
#define MARK 0
#define SPACE 1
#define NEC_BITS 32
#define USECPERTICK 50 // microseconds per clock interrupt tick
#define RAWBUF 80 // Length of raw duration buffer
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
#define NEC_HDR_MARK 9000
#define NEC_HDR_SPACE 4500
#define NEC_BIT_MARK 560
#define NEC_ONE_SPACE 1600
#define NEC_ZERO_SPACE 560
#define NEC_RPT_SPACE 2250
#define NEC_RPT_PERIOD 110000
#define _GAP 5000 // Minimum map between transmissions
// receiver states
#define STATE_IDLE 2
#define STATE_MARK 3
#define STATE_SPACE 4
#define STATE_STOP 5
// Values for decode_type
#define NEC 1
#define SONY 2
#define RC5 3
#define RC6 4
#define DISH 5
#define SHARP 6
#define PANASONIC 7
#define JVC 8
#define SANYO 9
#define MITSUBISHI 10
#define SAMSUNG 11
#define LG 12
#define UNKNOWN -1
#define TOPBIT 0x80000000
#ifdef F_CPU
#define SYSCLOCK F_CPU // main Arduino clock
#else
#define SYSCLOCK 16000000 // main Arduino clock
#endif
#define _GAP 5000 // Minimum map between transmissions
#define GAP_TICKS (_GAP/USECPERTICK)
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
#define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1))
#define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1)))
#define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A))
#define TIMER_DISABLE_INTR (TIMSK2 = 0)
#define TIMER_INTR_NAME TIMER2_COMPA_vect
#define TIMER_CONFIG_KHZ(val) ({ \
const uint8_t pwmval = F_CPU / 2000 / (val); \
TCCR2A = _BV(WGM20); \
TCCR2B = _BV(WGM22) | _BV(CS20); \
OCR2A = pwmval; \
OCR2B = pwmval / 3; \
})
#define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000)
#if (TIMER_COUNT_TOP < 256)
#define TIMER_CONFIG_NORMAL() ({ \
TCCR2A = _BV(WGM21); \
TCCR2B = _BV(CS20); \
OCR2A = TIMER_COUNT_TOP; \
TCNT2 = 0; \
})
#else
#define TIMER_CONFIG_NORMAL() ({ \
TCCR2A = _BV(WGM21); \
TCCR2B = _BV(CS21); \
OCR2A = TIMER_COUNT_TOP / 8; \
TCNT2 = 0; \
})
#endif
// information for the interrupt handler
typedef struct {
uint8_t recvpin; // pin for IR data from detector
volatile uint8_t rcvstate; // state machine
volatile uint32_t lastTime;
unsigned int timer; //
volatile uint8_t rawbuf[RAWBUF]; // raw data
volatile uint8_t rawlen; // counter of entries in rawbuf
} irparams_t;
class IRremote
{
public:
IRremote(int pin);
ErrorStatus decode();
void begin();
void end();
void loop();
boolean keyPressed(unsigned char r);
// void resume();
int8_t decode_type; // NEC, SONY, RC5, UNKNOWN
unsigned long value; // Decoded value
uint8_t bits; // Number of bits in decoded value
volatile uint8_t *rawbuf; // Raw intervals in .5 us ticks
int rawlen; // Number of records in rawbuf.
String getString();
unsigned char getCode();
String getKeyMap(byte keycode, byte ir_type = 1);
byte getIrKey(byte keycode, byte ir_type = 1);
void sendString(String s);
void sendString(float v);
void sendNEC(unsigned long data, int nbits);
void sendRaw(unsigned int buf[], int len, uint8_t hz);
void enableIROut(uint8_t khz);
void enableIRIn();
void mark(uint16_t us);
void space(uint16_t us);
private:
ErrorStatus decodeNEC();
int16_t irIndex;
char irRead;
char floatString[5];
boolean irReady;
boolean irPressed;
String irBuffer;
String Pre_Str;
double irDelayTime;
};
#endif // !__AVR_ATmega32U4__
#endif
Keymap.cpp:
#include "Keymap.h"
// ST_KEY_MAP normal_ir_keymap[18] = {
// {"1", 0x45},
// {"2", 0x46},
// {"3", 0x47},
// {"4", 0x44},
// {"5", 0x40},
// {"6", 0x43},
// {"7", 0x07},
// {"8", 0x15},
// {"9", 0x09},
// {"0", 0x19},
// {"*", 0x16},
// {"#", 0x0D},
// {"up", 0x18},
// {"down", 0x52},
// {"ok", 0x1C},
// {"left", 0x08},
// {"right", 0x5A}
// };
// ST_KEY_MAP normal_ir_keymap[18] = {
// {"up", 0x46},
// {"left", 0x44},
// {"ok", 0x40},
// {"right", 0x43},
// {"down", 0x15},
// {"1", 0x16},
// {"2", 0x19},
// {"3", 0x0d},
// {"4", 0x0c},
// {"5", 0x18},
// {"6", 0x5e},
// {"7", 0x08},
// {"8", 0x1c},
// {"9", 0x5A},
// {"*", 0x42},
// {"0", 0x52},
// {"#", 0x4A}
// };
ST_KEY_MAP normal_ir_keymap[18] = {
{"1", 0x16},
{"2", 0x19},
{"3", 0x0d},
{"4", 0x0c},
{"5", 0x18},
{"6", 0x5e},
{"7", 0x08},
{"8", 0x1c},
{"9", 0x5A},
{"0", 0x52},
{"*", 0x42},
{"#", 0x4A},
{"up", 0x46},
{"down", 0x15},
{"ok", 0x40},
{"left", 0x44},
{"right", 0x43},
};//带logo LA
// ST_KEY_MAP em_ir_keymap[21] = {
// {"A", 0x45},
// {"B", 0x46},
// {"C", 0x47},
// {"D", 0x44},
// {"up", 0x40},
// {"+", 0x43},
// {"left", 0x07},
// {"ok", 0x15},
// {"right", 0x09},
// {"0", 0x16},
// {"down", 0x19},
// {"-", 0x0d},
// {"1", 0x0c},
// {"2", 0x18},
// {"3", 0x5e},
// {"4", 0x08},
// {"5", 0x1c},
// {"6", 0x5A},
// {"7", 0x42},
// {"8", 0x52},
// {"9", 0x4A}
// };
Keymap.h:
#ifndef _KEYMAY_H_
#define _KEYMAY_H_
#include <Arduino.h>
#define KEY_MAX 21
typedef struct
{
String keyname;
byte keycode;
}ST_KEY_MAP;
#define IR_TYPE_NORMAL 1
#define IR_TYPE_EM 2
typedef enum {
IR_KEYCODE_1 = 0,
IR_KEYCODE_2,
IR_KEYCODE_3,
IR_KEYCODE_4,
IR_KEYCODE_5,
IR_KEYCODE_6,
IR_KEYCODE_7,
IR_KEYCODE_8,
IR_KEYCODE_9,
IR_KEYCODE_0,
IR_KEYCODE_STAR, // *
IR_KEYCODE_POUND, // #
IR_KEYCODE_UP,
IR_KEYCODE_DOWN,
IR_KEYCODE_OK,
IR_KEYCODE_LEFT,
IR_KEYCODE_RIGHT,
}E_NORMAL_IR_KEYCODE;
typedef enum {
EM_IR_KEYCODE_A = 0,
EM_IR_KEYCODE_B,
EM_IR_KEYCODE_C,
EM_IR_KEYCODE_D,
EM_IR_KEYCODE_UP,
EM_IR_KEYCODE_PLUS,
EM_IR_KEYCODE_LEFT,
EM_IR_KEYCODE_OK,
EM_IR_KEYCODE_RIGHT,
EM_IR_KEYCODE_0,
EM_IR_KEYCODE_DOWN,
EM_IR_KEYCODE_REDUCE,
EM_IR_KEYCODE_1,
EM_IR_KEYCODE_2,
EM_IR_KEYCODE_3,
EM_IR_KEYCODE_4,
EM_IR_KEYCODE_5,
EM_IR_KEYCODE_6,
EM_IR_KEYCODE_7,
EM_IR_KEYCODE_8,
EM_IR_KEYCODE_9,
}E_EM_IR_KEYCODE;
extern ST_KEY_MAP normal_ir_keymap[];
extern ST_KEY_MAP em_ir_keymap[];
#endif /* _KEYMAY_H_ */