初始化提交
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* IRCommandDispatcher.h
|
||||
*
|
||||
* Library to process IR commands by calling functions specified in a mapping array.
|
||||
*
|
||||
* To run this example you need to install the "IRremote" or "IRMP" library under "Tools -> Manage Libraries..." or "Ctrl+Shift+I"
|
||||
*
|
||||
* Copyright (C) 2019-2021 Armin Joachimsmeyer
|
||||
* armin.joachimsmeyer@gmail.com
|
||||
*
|
||||
* This file is part of ServoEasing https://github.com/ArminJo/ServoEasing.
|
||||
* This file is part of IRMP https://github.com/ukw100/IRMP.
|
||||
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
|
||||
*
|
||||
* ServoEasing is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
|
||||
*/
|
||||
|
||||
#ifndef _IR_COMMAND_DISPATCHER_H
|
||||
#define _IR_COMMAND_DISPATCHER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* For command mapping file
|
||||
*/
|
||||
#define IR_COMMAND_FLAG_BLOCKING 0x00 // default - blocking command, repeat not accepted, only one command at a time. Stops an already running command.
|
||||
#define IR_COMMAND_FLAG_REPEATABLE 0x01 // repeat accepted
|
||||
#define IR_COMMAND_FLAG_NON_BLOCKING 0x02 // (Non blocking / non regular) (short) command that can be processed any time and may interrupt other IR commands - used for stop, set direction etc.
|
||||
#define IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING (IR_COMMAND_FLAG_REPEATABLE | IR_COMMAND_FLAG_NON_BLOCKING)
|
||||
/*
|
||||
* if this command is received, requestToStopReceived is set until call of next loop.
|
||||
* This stops ongoing commands which use: RDispatcher.delayAndCheckForStop(100); RETURN_IF_STOP;
|
||||
*/
|
||||
#define IR_COMMAND_FLAG_IS_STOP_COMMAND 0x04 // sets requestToStopReceived (to stop other commands)
|
||||
|
||||
// Basic mapping structure
|
||||
struct IRToCommandMappingStruct {
|
||||
uint8_t IRCode;
|
||||
uint8_t Flags;
|
||||
void (*CommandToCall)();
|
||||
const char *CommandString;
|
||||
};
|
||||
|
||||
struct IRDataForCommandDispatcherStruct {
|
||||
uint16_t address; // to distinguish between multiple senders
|
||||
uint16_t command;
|
||||
bool isRepeat;
|
||||
uint32_t MillisOfLastCode; // millis() of last IR command -including repeats!- received - for timeouts etc.
|
||||
volatile bool isAvailable; // flag for a polling interpreting function, that a new command has arrived.
|
||||
};
|
||||
|
||||
/*
|
||||
* Special codes (hopefully) not sent by the remote - otherwise please redefine it here
|
||||
*/
|
||||
#define COMMAND_EMPTY 0xFE // code no command received
|
||||
#define COMMAND_INVALID 0xFF // code for command received, but not in mapping
|
||||
|
||||
#define RETURN_IF_STOP if (IRDispatcher.requestToStopReceived) return
|
||||
#define BREAK_IF_STOP if (IRDispatcher.requestToStopReceived) break
|
||||
#define DELAY_AND_RETURN_IF_STOP(aDurationMillis) if (IRDispatcher.delayAndCheckForStop(aDurationMillis)) return
|
||||
|
||||
class IRCommandDispatcher {
|
||||
public:
|
||||
void init();
|
||||
|
||||
bool checkAndRunNonBlockingCommands();
|
||||
bool checkAndRunSuspendedBlockingCommands();
|
||||
bool delayAndCheckForStop(uint16_t aDelayMillis);
|
||||
|
||||
// The main dispatcher function
|
||||
void checkAndCallCommand(bool aCallAlsoBlockingCommands);
|
||||
|
||||
void printIRCommandString(Print *aSerial);
|
||||
void setRequestToStopReceived();
|
||||
|
||||
uint8_t currentBlockingCommandCalled = COMMAND_INVALID; // The code for the current called command
|
||||
bool executingBlockingCommand = false; // Lock for recursive calls of regular commands
|
||||
bool justCalledBlockingCommand = false; // Flag that a blocking command was received and called - is set before call of command
|
||||
uint8_t BlockingCommandToRunNext = COMMAND_INVALID; // Storage for command currently suspended to allow the current command to end, before it is called by main loop
|
||||
/*
|
||||
* Flag for running blocking commands to terminate. To check, you can use "if (requestToStopReceived) return;" (available as macro RETURN_IF_STOP).
|
||||
* Is reset by next IR command received. Can be reset by main loop, if command has stopped.
|
||||
*/
|
||||
volatile bool requestToStopReceived;
|
||||
/*
|
||||
* If we have a function, which want to interpret the IR codes by itself e.g. the calibrate function if QuadrupedControl then this flag must be true
|
||||
*/
|
||||
bool doNotUseDispatcher = false;
|
||||
|
||||
struct IRDataForCommandDispatcherStruct IRReceivedData;
|
||||
|
||||
};
|
||||
|
||||
extern IRCommandDispatcher IRDispatcher;
|
||||
|
||||
#endif // _IR_COMMAND_DISPATCHER_H
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* IRCommandDispatcher.hpp
|
||||
*
|
||||
* Library to process IR commands by calling functions specified in a mapping array.
|
||||
* Commands can be tagged as blocking or non blocking.
|
||||
*
|
||||
* To run this example you need to install the "IRremote" or "IRMP" library.
|
||||
* Install it under "Tools -> Manage Libraries..." or "Ctrl+Shift+I"
|
||||
*
|
||||
* The IR library calls a callback function, which executes a non blocking command directly in ISR context!
|
||||
* A blocking command is stored and sets a stop flag for an already running blocking function to terminate.
|
||||
* The blocking command can in turn be executed by main loop by calling IRDispatcher.checkAndRunSuspendedBlockingCommands().
|
||||
*
|
||||
* Copyright (C) 2019-2021 Armin Joachimsmeyer
|
||||
* armin.joachimsmeyer@gmail.com
|
||||
*
|
||||
* This file is part of ServoEasing https://github.com/ArminJo/ServoEasing.
|
||||
* This file is part of IRMP https://github.com/ukw100/IRMP.
|
||||
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
|
||||
*
|
||||
* ServoEasing is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
|
||||
*/
|
||||
#ifndef _IR_COMMAND_DISPATCHER_HPP
|
||||
#define _IR_COMMAND_DISPATCHER_HPP
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "IRCommandDispatcher.h"
|
||||
|
||||
/*
|
||||
* Enable this to see information on each call.
|
||||
* Since there should be no library which uses Serial, it should only be enabled for development purposes.
|
||||
*/
|
||||
#if defined(INFO) && !defined(LOCAL_INFO)
|
||||
#define LOCAL_INFO
|
||||
#else
|
||||
//#define LOCAL_INFO // This enables info output only for this file
|
||||
#endif
|
||||
#if defined(DEBUG) && !defined(LOCAL_DEBUG)
|
||||
#define LOCAL_DEBUG
|
||||
// Propagate debug level
|
||||
#define LOCAL_INFO
|
||||
#else
|
||||
//#define LOCAL_DEBUG // This enables debug output only for this file
|
||||
#endif
|
||||
|
||||
IRCommandDispatcher IRDispatcher;
|
||||
|
||||
#if defined(USE_TINY_IR_RECEIVER)
|
||||
#include "TinyIRReceiver.hpp" // included in "IRremote" library
|
||||
|
||||
#if defined(LOCAL_INFO)
|
||||
#define CD_INFO_PRINT(...) Serial.print(__VA_ARGS__);
|
||||
#define CD_INFO_PRINTLN(...) Serial.println(__VA_ARGS__);
|
||||
#else
|
||||
#define CD_INFO_PRINT(...) void();
|
||||
#define CD_INFO_PRINTLN(...) void();
|
||||
#endif
|
||||
|
||||
void IRCommandDispatcher::init() {
|
||||
initPCIInterruptForTinyReceiver();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the TinyReceiver callback function which is called if a complete command was received
|
||||
* It checks for right address and then call the dispatcher
|
||||
*/
|
||||
#if defined(ESP32) || defined(ESP8266)
|
||||
void IRAM_ATTR handleReceivedTinyIRData(uint16_t aAddress, uint8_t aCommand, bool isRepeat)
|
||||
# else
|
||||
void handleReceivedTinyIRData(uint16_t aAddress, uint8_t aCommand, bool isRepeat)
|
||||
# endif
|
||||
{
|
||||
IRDispatcher.IRReceivedData.address = aAddress;
|
||||
IRDispatcher.IRReceivedData.command = aCommand;
|
||||
IRDispatcher.IRReceivedData.isRepeat = isRepeat;
|
||||
IRDispatcher.IRReceivedData.MillisOfLastCode = millis();
|
||||
|
||||
CD_INFO_PRINT(F("A=0x"));
|
||||
CD_INFO_PRINT(aAddress, HEX);
|
||||
CD_INFO_PRINT(F(" C=0x"));
|
||||
CD_INFO_PRINT(aCommand, HEX);
|
||||
if (isRepeat) {
|
||||
CD_INFO_PRINT(F("R"));
|
||||
}
|
||||
CD_INFO_PRINTLN();
|
||||
|
||||
if (aAddress == IR_ADDRESS) { // IR_ADDRESS is defined in IRCommandMapping.h
|
||||
IRDispatcher.IRReceivedData.isAvailable = true;
|
||||
if(!IRDispatcher.doNotUseDispatcher) {
|
||||
IRDispatcher.checkAndCallCommand(false); // only short commands are executed directly
|
||||
}
|
||||
|
||||
} else {
|
||||
CD_INFO_PRINT(F("Wrong address. Expected 0x"));
|
||||
CD_INFO_PRINTLN(IR_ADDRESS, HEX);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(USE_IRMP_LIBRARY)
|
||||
#if !defined(IRMP_USE_COMPLETE_CALLBACK)
|
||||
# error IRMP_USE_COMPLETE_CALLBACK must be activated for IRMP library
|
||||
#endif
|
||||
|
||||
void IRCommandDispatcher::init() {
|
||||
irmp_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the callback function is called if a complete command was received
|
||||
*/
|
||||
#if defined(ESP32) || defined(ESP8266)
|
||||
void IRAM_ATTR handleReceivedIRData()
|
||||
#else
|
||||
void handleReceivedIRData()
|
||||
#endif
|
||||
{
|
||||
IRMP_DATA tTeporaryData;
|
||||
irmp_get_data(&tTeporaryData);
|
||||
IRDispatcher.IRReceivedData.address = tTeporaryData.address;
|
||||
IRDispatcher.IRReceivedData.command = tTeporaryData.command;
|
||||
IRDispatcher.IRReceivedData.isRepeat = tTeporaryData.flags & IRMP_FLAG_REPETITION;
|
||||
IRDispatcher.IRReceivedData.MillisOfLastCode = millis();
|
||||
|
||||
CD_INFO_PRINT(F("A=0x"));
|
||||
CD_INFO_PRINT(IRDispatcher.IRReceivedData.address, HEX);
|
||||
CD_INFO_PRINT(F(" C=0x"));
|
||||
CD_INFO_PRINT(IRDispatcher.IRReceivedData.command, HEX);
|
||||
if (IRDispatcher.IRReceivedData.isRepeat) {
|
||||
CD_INFO_PRINT(F("R"));
|
||||
}
|
||||
CD_INFO_PRINTLN();
|
||||
|
||||
// To enable delay() for commands
|
||||
#if !defined(ARDUINO_ARCH_MBED)
|
||||
interrupts(); // be careful with always executable commands which lasts longer than the IR repeat duration.
|
||||
#endif
|
||||
|
||||
if (IRDispatcher.IRReceivedData.address == IR_ADDRESS) {
|
||||
IRDispatcher.checkAndCallCommand(true);
|
||||
} else {
|
||||
CD_INFO_PRINT(F("Wrong address. Expected 0x"));
|
||||
CD_INFO_PRINTLN(IR_ADDRESS, HEX);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The main dispatcher function
|
||||
* Sets flags justCalledRegularIRCommand, executingBlockingCommand
|
||||
*/
|
||||
void IRCommandDispatcher::checkAndCallCommand(bool aCallAlsoBlockingCommands) {
|
||||
if (IRReceivedData.command == COMMAND_EMPTY) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for command in Array of IRToCommandMappingStruct
|
||||
*/
|
||||
for (uint_fast8_t i = 0; i < sizeof(IRMapping) / sizeof(struct IRToCommandMappingStruct); ++i) {
|
||||
if (IRReceivedData.command == IRMapping[i].IRCode) {
|
||||
/*
|
||||
* Command found
|
||||
*/
|
||||
#if defined(LOCAL_INFO)
|
||||
const __FlashStringHelper *tCommandName = reinterpret_cast<const __FlashStringHelper*>(IRMapping[i].CommandString);
|
||||
#endif
|
||||
/*
|
||||
* Check for repeat and if it is allowed for the current command
|
||||
*/
|
||||
if (IRReceivedData.isRepeat && !(IRMapping[i].Flags & IR_COMMAND_FLAG_REPEATABLE)) {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Repeats of command \""));
|
||||
Serial.print(tCommandName);
|
||||
Serial.println("\" not accepted");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not accept recursive call of the same command
|
||||
*/
|
||||
if (currentBlockingCommandCalled == IRReceivedData.command) {
|
||||
#if defined(LOCAL_DEBUG)
|
||||
Serial.print(F("Recursive command \""));
|
||||
Serial.print(tCommandName);
|
||||
Serial.println("\" not accepted");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle stop commands
|
||||
*/
|
||||
if (IRMapping[i].Flags & IR_COMMAND_FLAG_IS_STOP_COMMAND) {
|
||||
requestToStopReceived = true;
|
||||
CD_INFO_PRINTLN(F("Stop command received"));
|
||||
} else {
|
||||
// lets start a new turn
|
||||
requestToStopReceived = false;
|
||||
}
|
||||
|
||||
bool tIsNonBlockingCommand = (IRMapping[i].Flags & IR_COMMAND_FLAG_NON_BLOCKING);
|
||||
if (tIsNonBlockingCommand) {
|
||||
// short command here, just call
|
||||
CD_INFO_PRINT(F("Run non blocking command: "));
|
||||
CD_INFO_PRINTLN (tCommandName);
|
||||
IRMapping[i].CommandToCall();
|
||||
} else {
|
||||
if (!aCallAlsoBlockingCommands) {
|
||||
/*
|
||||
* Store for main loop to execute
|
||||
*/
|
||||
BlockingCommandToRunNext = IRReceivedData.command;
|
||||
requestToStopReceived = true; // to stop running command
|
||||
CD_INFO_PRINT(F("Blocking command "));
|
||||
CD_INFO_PRINT (tCommandName);
|
||||
CD_INFO_PRINTLN(F(" stored as next command and requested stop"));
|
||||
} else {
|
||||
if (executingBlockingCommand) {
|
||||
// Logical error has happened
|
||||
CD_INFO_PRINTLN(
|
||||
F("Request to execute blocking command while another command is running. This should not happen!"));
|
||||
/*
|
||||
* A blocking command may not be called as long as another blocking command is running.
|
||||
* Try to stop again
|
||||
*/
|
||||
BlockingCommandToRunNext = IRReceivedData.command;
|
||||
requestToStopReceived = true; // to stop running command
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* here we are called from main loop and execute a command
|
||||
*/
|
||||
justCalledBlockingCommand = true;
|
||||
executingBlockingCommand = true; // set lock for recursive calls
|
||||
currentBlockingCommandCalled = IRReceivedData.command;
|
||||
/*
|
||||
* This call is blocking!!!
|
||||
*/
|
||||
CD_INFO_PRINT(F("Run blocking command: "));
|
||||
CD_INFO_PRINTLN (tCommandName);
|
||||
|
||||
IRMapping[i].CommandToCall();
|
||||
#if defined(TRACE)
|
||||
Serial.println(F("End of blocking command"));
|
||||
#endif
|
||||
executingBlockingCommand = false;
|
||||
currentBlockingCommandCalled = COMMAND_INVALID;
|
||||
}
|
||||
|
||||
}
|
||||
break; // command found
|
||||
}
|
||||
} // for loop
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special delay function for the IRCommandDispatcher. Returns prematurely if requestToStopReceived is set.
|
||||
* To be used in blocking functions as delay
|
||||
* @return true - as soon as stop received
|
||||
*/
|
||||
bool IRCommandDispatcher::delayAndCheckForStop(uint16_t aDelayMillis) {
|
||||
uint32_t tStartMillis = millis();
|
||||
do {
|
||||
if (IRDispatcher.requestToStopReceived) {
|
||||
return true;
|
||||
}
|
||||
} while (millis() - tStartMillis < aDelayMillis);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Intended to be called from main loop
|
||||
* @return true, if command was called
|
||||
*/
|
||||
bool IRCommandDispatcher::checkAndRunSuspendedBlockingCommands() {
|
||||
/*
|
||||
* Take last rejected command and call associated function
|
||||
*/
|
||||
if (BlockingCommandToRunNext != COMMAND_INVALID) {
|
||||
|
||||
CD_INFO_PRINT(F("Take stored command = 0x"));
|
||||
CD_INFO_PRINTLN(BlockingCommandToRunNext, HEX);
|
||||
|
||||
IRReceivedData.command = BlockingCommandToRunNext;
|
||||
BlockingCommandToRunNext = COMMAND_INVALID;
|
||||
IRReceivedData.isRepeat = false;
|
||||
checkAndCallCommand(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void IRCommandDispatcher::printIRCommandString(Print *aSerial) {
|
||||
aSerial->print(F("IRCommand="));
|
||||
for (uint_fast8_t i = 0; i < sizeof(IRMapping) / sizeof(struct IRToCommandMappingStruct); ++i) {
|
||||
if (IRReceivedData.command == IRMapping[i].IRCode) {
|
||||
aSerial->println(reinterpret_cast<const __FlashStringHelper*>(IRMapping[i].CommandString));
|
||||
return;
|
||||
}
|
||||
}
|
||||
aSerial->println(reinterpret_cast<const __FlashStringHelper*>(unknown));
|
||||
}
|
||||
|
||||
void IRCommandDispatcher::setRequestToStopReceived() {
|
||||
requestToStopReceived = true;
|
||||
}
|
||||
|
||||
#if defined(LOCAL_DEBUG)
|
||||
#undef LOCAL_DEBUG
|
||||
#endif
|
||||
#if defined(LOCAL_INFO)
|
||||
#undef LOCAL_INFO
|
||||
#endif
|
||||
#endif // _IR_COMMAND_DISPATCHER_HPP
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* IRCommandMapping.h
|
||||
*
|
||||
* IR remote button codes, strings, and functions to call
|
||||
*
|
||||
* Copyright (C) 2019-2021 Armin Joachimsmeyer
|
||||
* armin.joachimsmeyer@gmail.com
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _IR_COMMAND_MAPPING_H
|
||||
#define _IR_COMMAND_MAPPING_H
|
||||
|
||||
#include <Arduino.h>
|
||||
//#include "Commands.h" // includes all the commands used in the mapping arrays below
|
||||
|
||||
/*
|
||||
* !!! Choose your remote !!!
|
||||
*/
|
||||
//#define USE_KEYES_REMOTE_CLONE With number pad and direction control switched, will be taken as default
|
||||
//#define USE_KEYES_REMOTE
|
||||
#if !defined(USE_KEYES_REMOTE) && !defined(USE_KEYES_REMOTE_CLONE)
|
||||
#define USE_KEYES_REMOTE_CLONE // the one you can buy at aliexpress
|
||||
#endif
|
||||
|
||||
#if (defined(USE_KEYES_REMOTE) && defined(USE_KEYES_REMOTE_CLONE))
|
||||
#error "Please choose only one remote for compile"
|
||||
#endif
|
||||
|
||||
#if defined(USE_KEYES_REMOTE_CLONE)
|
||||
#define IR_REMOTE_NAME "KEYES_CLONE"
|
||||
// Codes for the KEYES CLONE remote control with 17 keys with number pad above direction control
|
||||
#if defined(USE_IRMP_LIBRARY)
|
||||
#define IR_ADDRESS 0xFF00 // IRMP interprets NEC addresses always as 16 bit
|
||||
#else
|
||||
#define IR_ADDRESS 0x00
|
||||
#endif
|
||||
|
||||
#define IR_UP 0x18
|
||||
#define IR_DOWN 0x52
|
||||
#define IR_RIGHT 0x5A
|
||||
#define IR_LEFT 0x08
|
||||
#define IR_OK 0x1C
|
||||
|
||||
#define IR_1 0x45
|
||||
#define IR_2 0x46
|
||||
#define IR_3 0x47
|
||||
#define IR_4 0x44
|
||||
#define IR_5 0x40
|
||||
#define IR_6 0x43
|
||||
#define IR_7 0x07
|
||||
#define IR_8 0x15
|
||||
#define IR_9 0x09
|
||||
#define IR_0 0x19
|
||||
|
||||
#define IR_STAR 0x16
|
||||
#define IR_HASH 0x0D
|
||||
/*
|
||||
* SECOND:
|
||||
* IR button to command mapping for better reading. IR buttons should only referenced here.
|
||||
*/
|
||||
#define COMMAND_ON IR_UP
|
||||
#define COMMAND_OFF IR_DOWN
|
||||
#define COMMAND_INCREASE_BLINK IR_RIGHT
|
||||
#define COMMAND_DECREASE_BLINK IR_LEFT
|
||||
|
||||
#define COMMAND_START IR_OK
|
||||
#define COMMAND_STOP IR_HASH
|
||||
#define COMMAND_RESET IR_STAR
|
||||
#define COMMAND_BLINK IR_0
|
||||
#define COMMAND_TONE1 IR_1
|
||||
|
||||
#define COMMAND_TONE2 IR_2
|
||||
#define COMMAND_TONE3 IR_3
|
||||
//#define IR_4
|
||||
//#define IR_5
|
||||
//#define IR_6
|
||||
//#define IR_7
|
||||
//#define IR_8
|
||||
//#define IR_9
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USE_KEYES_REMOTE)
|
||||
#define IR_REMOTE_NAME "KEYES"
|
||||
/*
|
||||
* FIRST:
|
||||
* IR code to button mapping for better reading. IR codes should only referenced here.
|
||||
*/
|
||||
// Codes for the KEYES remote control with 17 keys and direction control above number pad
|
||||
#if defined(USE_IRMP_LIBRARY)
|
||||
#define IR_ADDRESS 0xFF00 // IRMP interprets NEC addresses always as 16 bit
|
||||
#else
|
||||
#define IR_ADDRESS 0x00
|
||||
#endif
|
||||
|
||||
#define IR_UP 0x46
|
||||
#define IR_DOWN 0x15
|
||||
#define IR_RIGHT 0x43
|
||||
#define IR_LEFT 0x44
|
||||
#define IR_OK 0x40
|
||||
|
||||
#define IR_1 0x16
|
||||
#define IR_2 0x19
|
||||
#define IR_3 0x0D
|
||||
#define IR_4 0x0C
|
||||
#define IR_5 0x18
|
||||
#define IR_6 0x5E
|
||||
#define IR_7 0x08
|
||||
#define IR_8 0x1C
|
||||
#define IR_9 0x5A
|
||||
#define IR_0 0x52
|
||||
|
||||
#define IR_STAR 0x42
|
||||
#define IR_HASH 0x4A
|
||||
|
||||
/*
|
||||
* SECOND:
|
||||
* IR button to command mapping for better reading. IR buttons should only referenced here.
|
||||
*/
|
||||
#define COMMAND_ON IR_UP
|
||||
#define COMMAND_OFF IR_DOWN
|
||||
#define COMMAND_INCREASE_BLINK IR_RIGHT
|
||||
#define COMMAND_DECREASE_BLINK IR_LEFT
|
||||
|
||||
#define COMMAND_RESET IR_OK
|
||||
#define COMMAND_STOP IR_HASH
|
||||
#define COMMAND_STOP IR_STAR
|
||||
#define COMMAND_BLINK IR_0
|
||||
#define COMMAND_TONE2 IR_1
|
||||
|
||||
#define COMMAND_TONE1 IR_2
|
||||
#define COMMAND_TONE2 IR_3
|
||||
#define COMMAND_TONE2 IR_4
|
||||
#define COMMAND_TONE2 IR_5
|
||||
#define COMMAND_TONE2 IR_6
|
||||
#define COMMAND_TONE2 IR_7
|
||||
#define COMMAND_TONE2 IR_8
|
||||
#define COMMAND_TONE2 IR_9
|
||||
#endif
|
||||
|
||||
/*
|
||||
* THIRD:
|
||||
* Main mapping of commands to C functions
|
||||
*/
|
||||
|
||||
// IR strings of functions for output
|
||||
static const char LEDon[] PROGMEM ="LED on";
|
||||
static const char LEDoff[] PROGMEM ="LED off";
|
||||
|
||||
static const char blink20times[] PROGMEM ="blink 20 times";
|
||||
static const char blinkStart[] PROGMEM ="blink start";
|
||||
|
||||
static const char increaseBlink[] PROGMEM ="increase blink frequency";
|
||||
static const char decreaseBlink[] PROGMEM ="decrease blink frequency";
|
||||
|
||||
static const char tone2200[] PROGMEM ="tone 2200";
|
||||
static const char tone1800[] PROGMEM ="tone 1800";
|
||||
static const char printMenu[] PROGMEM ="printMenu";
|
||||
|
||||
static const char reset[] PROGMEM ="reset";
|
||||
static const char stop[] PROGMEM ="stop";
|
||||
|
||||
// not used yet
|
||||
static const char test[] PROGMEM ="test";
|
||||
static const char pattern[] PROGMEM ="pattern";
|
||||
static const char unknown[] PROGMEM ="unknown";
|
||||
|
||||
/*
|
||||
* Main mapping array of commands to C functions and command strings
|
||||
*/
|
||||
const struct IRToCommandMappingStruct IRMapping[] =
|
||||
{
|
||||
{ COMMAND_BLINK, IR_COMMAND_FLAG_BLOCKING, &doLedBlink20times, blink20times },
|
||||
|
||||
/*
|
||||
* Short commands, which can be executed always
|
||||
*/
|
||||
{ COMMAND_TONE1, IR_COMMAND_FLAG_BLOCKING, &doTone1800, tone1800 },
|
||||
{ COMMAND_TONE3, IR_COMMAND_FLAG_BLOCKING, &doPrintMenu, printMenu },
|
||||
{ COMMAND_ON, IR_COMMAND_FLAG_NON_BLOCKING, &doLedOn, LEDon },
|
||||
{ COMMAND_OFF, IR_COMMAND_FLAG_NON_BLOCKING, &doLedOff, LEDoff },
|
||||
{ COMMAND_START, IR_COMMAND_FLAG_NON_BLOCKING, &doLedBlinkStart, blinkStart },
|
||||
{ COMMAND_RESET, IR_COMMAND_FLAG_NON_BLOCKING, &doResetBlinkFrequency, reset },
|
||||
{ COMMAND_STOP, IR_COMMAND_FLAG_IS_STOP_COMMAND, &doStop, stop },
|
||||
|
||||
/*
|
||||
* Repeatable short commands
|
||||
*/
|
||||
{ COMMAND_TONE2, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doTone2200, tone2200 },
|
||||
{ COMMAND_INCREASE_BLINK, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doIncreaseBlinkFrequency, increaseBlink },
|
||||
{ COMMAND_DECREASE_BLINK, IR_COMMAND_FLAG_REPEATABLE_NON_BLOCKING, &doDecreaseBlinkFrequency, decreaseBlink } };
|
||||
|
||||
#endif // _IR_COMMAND_MAPPING_H
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* IRDispatcherDemo.cpp
|
||||
*
|
||||
* Receives NEC IR commands and maps them to different actions by means of a mapping array.
|
||||
*
|
||||
* Copyright (C) 2020-2021 Armin Joachimsmeyer
|
||||
* armin.joachimsmeyer@gmail.com
|
||||
*
|
||||
* This file is part of IRMP https://github.com/ukw100/IRMP.
|
||||
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
|
||||
*
|
||||
* IRMP is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/*
|
||||
* Choose the library to be used for IR receiving
|
||||
*/
|
||||
#define USE_TINY_IR_RECEIVER // Recommended, but only for NEC protocol!!! If disabled and IRMP_INPUT_PIN is defined, the IRMP library is used for decoding
|
||||
//#define TINY_RECEIVER_USE_ARDUINO_ATTACH_INTERRUPT // costs 112 bytes program memory + 4 bytes RAM
|
||||
|
||||
#include "PinDefinitionsAndMore.h" //Define macros for input and output pin etc.
|
||||
// Some kind of auto detect library if USE_TINY_IR_RECEIVER is deactivated
|
||||
#if !defined(USE_TINY_IR_RECEIVER)
|
||||
# if defined(IR_RECEIVE_PIN)
|
||||
#define USE_TINY_IR_RECEIVER
|
||||
# elif !defined(USE_IRMP_LIBRARY) && defined(IRMP_INPUT_PIN)
|
||||
#define USE_IRMP_LIBRARY
|
||||
# else
|
||||
#error No IR library selected
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define IR_INPUT_PIN 2
|
||||
|
||||
//#define NO_LED_FEEDBACK_CODE // You can set it here, before the include of IRCommandDispatcher below
|
||||
|
||||
#if defined(USE_TINY_IR_RECEIVER) && !defined(IR_INPUT_PIN)
|
||||
#if defined(IR_RECEIVE_PIN)
|
||||
#define IR_INPUT_PIN IR_RECEIVE_PIN // The pin where the IR input signal is expected. The pin must be capable of generating a pin change interrupt.
|
||||
#endif
|
||||
#if defined(IRMP_INPUT_PIN)
|
||||
#define IR_INPUT_PIN IRMP_INPUT_PIN // The pin where the IR input signal is expected. The pin must be capable of generating a pin change interrupt.
|
||||
#endif
|
||||
|
||||
#elif defined(USE_IRMP_LIBRARY)
|
||||
/*
|
||||
* IRMP version
|
||||
*/
|
||||
#define IRMP_USE_COMPLETE_CALLBACK 1 // Enable callback functionality. It is required if IRMP library is used.
|
||||
#if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)
|
||||
#define FEEDBACK_LED_PIN ALTERNATIVE_IR_FEEDBACK_LED_PIN
|
||||
#endif
|
||||
|
||||
//#define IRMP_ENABLE_PIN_CHANGE_INTERRUPT // Enable interrupt functionality (not for all protocols) - requires around 376 additional bytes of program memory
|
||||
|
||||
#define IRMP_PROTOCOL_NAMES 1 // Enable protocol number mapping to protocol strings - requires some program memory. Must before #include <irmp*>
|
||||
|
||||
#define IRMP_SUPPORT_NEC_PROTOCOL 1 // this enables only one protocol
|
||||
//#define IRMP_SUPPORT_KASEIKYO_PROTOCOL 1
|
||||
|
||||
# if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)
|
||||
#define IRMP_FEEDBACK_LED_PIN ALTERNATIVE_IR_FEEDBACK_LED_PIN
|
||||
# endif
|
||||
/*
|
||||
* After setting the definitions we can include the code and compile it.
|
||||
*/
|
||||
#include <irmp.hpp>
|
||||
void handleReceivedIRData();
|
||||
void irmp_tone(uint8_t _pin, unsigned int frequency, unsigned long duration);
|
||||
#endif // #if defined(USE_IRMP_LIBRARY)
|
||||
|
||||
bool doBlink = false;
|
||||
uint16_t sBlinkDelay = 200;
|
||||
|
||||
void doPrintMenu();
|
||||
void doLedOn();
|
||||
void doLedOff();
|
||||
void doIncreaseBlinkFrequency();
|
||||
void doDecreaseBlinkFrequency();
|
||||
void doStop();
|
||||
void doResetBlinkFrequency();
|
||||
void doLedBlinkStart();
|
||||
void doLedBlink20times();
|
||||
void doTone1800();
|
||||
void doTone2200();
|
||||
|
||||
/*
|
||||
* Set definitions and include IRCommandDispatcher library after the declaration of all commands to map
|
||||
*/
|
||||
#define INFO // to see some informative output
|
||||
#include "IRCommandDispatcher.h" // Only for required declarations, the library itself is included below after the definitions of the commands
|
||||
#include "IRCommandMapping.h" // must be included before IRCommandDispatcher.hpp to define IR_ADDRESS and IRMapping and string "unknown".
|
||||
#include "IRCommandDispatcher.hpp"
|
||||
|
||||
/*
|
||||
* Helper macro for getting a macro definition as string
|
||||
*/
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
void setup() {
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
Serial.begin(115200);
|
||||
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_PORT_USBVIRTUAL) || defined(SERIAL_USB) /*stm32duino*/|| defined(USBCON) /*STM32_stm32*/|| defined(SERIALUSB_PID) || defined(ARDUINO_attiny3217)
|
||||
delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!
|
||||
#endif
|
||||
#if defined(ESP8266)
|
||||
Serial.println(); // to separate it from the internal boot output
|
||||
#endif
|
||||
|
||||
// Just to know which program is running on my Arduino
|
||||
#if defined(USE_TINY_IR_RECEIVER)
|
||||
Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing TinyIRReceiver"));
|
||||
#elif defined(USE_IRREMOTE_LIBRARY)
|
||||
Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing IRremote library version " VERSION_IRREMOTE));
|
||||
#elif defined(USE_IRMP_LIBRARY)
|
||||
Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing IRMP library version " VERSION_IRMP));
|
||||
#endif
|
||||
|
||||
#if !defined(ESP8266) && !defined(NRF5)
|
||||
// play feedback tone before setup, since it kills the IR timer settings
|
||||
tone(TONE_PIN, 1000, 50);
|
||||
delay(50);
|
||||
#endif
|
||||
|
||||
IRDispatcher.init(); // This just calls irmp_init()
|
||||
#if defined(USE_TINY_IR_RECEIVER)
|
||||
Serial.println(F("Ready to receive NEC IR signals at pin " STR(IR_INPUT_PIN)));
|
||||
#else
|
||||
irmp_register_complete_callback_function(&handleReceivedIRData); // fixed function in IRCommandDispatcher.hpp
|
||||
|
||||
Serial.print(F("Ready to receive IR signals of protocols: "));
|
||||
irmp_print_active_protocols(&Serial);
|
||||
Serial.println(F("at pin " STR(IRMP_INPUT_PIN)));
|
||||
|
||||
# if defined(ALTERNATIVE_IR_FEEDBACK_LED_PIN)
|
||||
irmp_irsnd_LEDFeedback(true); // Enable receive signal feedback at ALTERNATIVE_IR_FEEDBACK_LED_PIN
|
||||
Serial.println(F("IR feedback pin is " STR(ALTERNATIVE_IR_FEEDBACK_LED_PIN)));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
Serial.print(F("Listening to commands of IR remote of type "));
|
||||
Serial.println(IR_REMOTE_NAME);
|
||||
doPrintMenu();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
IRDispatcher.checkAndRunSuspendedBlockingCommands();
|
||||
|
||||
if (doBlink) {
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
DELAY_AND_RETURN_IF_STOP(sBlinkDelay);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
DELAY_AND_RETURN_IF_STOP(sBlinkDelay);
|
||||
}
|
||||
|
||||
if (millis() - IRDispatcher.IRReceivedData.MillisOfLastCode > 120000)
|
||||
{
|
||||
//Short beep as remainder, if we did not receive any command in the last 2 minutes
|
||||
IRDispatcher.IRReceivedData.MillisOfLastCode += 120000;
|
||||
doTone1800();
|
||||
}
|
||||
|
||||
// delay(10);
|
||||
}
|
||||
|
||||
void doPrintMenu(){
|
||||
Serial.println();
|
||||
Serial.println(F("Press 1 for tone 1800 Hz"));
|
||||
Serial.println(F("Press 2 for tone 2200 Hz"));
|
||||
Serial.println(F("Press 3 for this Menu"));
|
||||
Serial.println(F("Press 0 for LED blink 20 times"));
|
||||
Serial.println(F("Press UP for LED on"));
|
||||
Serial.println(F("Press DOWN for LED off"));
|
||||
Serial.println(F("Press OK for LED blink start"));
|
||||
Serial.println(F("Press RIGHT for LED increase blink frequency"));
|
||||
Serial.println(F("Press LEFT for LED decrease blink frequency"));
|
||||
Serial.println(F("Press STAR for reset blink frequency"));
|
||||
Serial.println(F("Press HASH for stop"));
|
||||
Serial.println();
|
||||
}
|
||||
/*
|
||||
* Here the actions that are matched to IR keys
|
||||
*/
|
||||
void doLedOn() {
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
doBlink = false;
|
||||
}
|
||||
void doLedOff() {
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
doBlink = false;
|
||||
}
|
||||
void doIncreaseBlinkFrequency() {
|
||||
doBlink = true;
|
||||
if (sBlinkDelay > 5) {
|
||||
sBlinkDelay -= sBlinkDelay / 4;
|
||||
}
|
||||
}
|
||||
void doDecreaseBlinkFrequency() {
|
||||
doBlink = true;
|
||||
sBlinkDelay += sBlinkDelay / 4;
|
||||
}
|
||||
void doStop() {
|
||||
doBlink = false;
|
||||
}
|
||||
void doResetBlinkFrequency() {
|
||||
sBlinkDelay = 200;
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
}
|
||||
void doLedBlinkStart() {
|
||||
doBlink = true;
|
||||
}
|
||||
/*
|
||||
* This is a blocking function and checks periodically for stop
|
||||
*/
|
||||
void doLedBlink20times() {
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
DELAY_AND_RETURN_IF_STOP(200);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
DELAY_AND_RETURN_IF_STOP(200);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void doTone1800() {
|
||||
#if defined(USE_IRMP_LIBRARY) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)
|
||||
irmp_tone(TONE_PIN, 1800, 200);
|
||||
#else
|
||||
# if !defined(ESP8266) && !defined(NRF5) // tone() stops timer 1 for ESP8266
|
||||
tone(TONE_PIN, 1800, 200);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void doTone2200() {
|
||||
#if defined(USE_IRMP_LIBRARY) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)
|
||||
// use IRMP compatible function for tone()
|
||||
irmp_tone(TONE_PIN, 2200, 50);
|
||||
#else
|
||||
# if !defined(ESP8266) && !defined(NRF5) // tone() stops timer 1 for ESP8266
|
||||
tone(TONE_PIN, 2200, 50);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(USE_IRMP_LIBRARY)
|
||||
/*
|
||||
* Convenience IRMP compatible wrapper function for Arduino tone() if IRMP_ENABLE_PIN_CHANGE_INTERRUPT is NOT activated
|
||||
* It currently disables the receiving of repeats
|
||||
*/
|
||||
void irmp_tone(uint8_t _pin, unsigned int frequency, unsigned long duration) {
|
||||
# if defined(__AVR__) && !defined(IRMP_ENABLE_PIN_CHANGE_INTERRUPT)
|
||||
storeIRTimer();
|
||||
tone(_pin, frequency, 0);
|
||||
if (duration == 0) {
|
||||
duration = 100;
|
||||
}
|
||||
delay(duration);
|
||||
noTone(_pin);
|
||||
restoreIRTimer();
|
||||
#elif defined(ESP8266)
|
||||
// tone() stops timer 1
|
||||
(void) _pin;
|
||||
(void) frequency;
|
||||
(void) duration;
|
||||
#else
|
||||
tone(_pin, frequency, duration);
|
||||
#endif
|
||||
}
|
||||
#endif // #if defined(USE_IRMP_LIBRARY)
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* PinDefinitionsAndMore.h
|
||||
*
|
||||
* Contains pin definitions for IRremote examples for various platforms
|
||||
* as well as definitions for feedback LED and tone() and includes
|
||||
*
|
||||
* Copyright (C) 2021-2022 Armin Joachimsmeyer
|
||||
* armin.joachimsmeyer@gmail.com
|
||||
*
|
||||
* This file is part of IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
|
||||
*
|
||||
* Arduino-IRremote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Pin mapping table for different platforms
|
||||
*
|
||||
* Platform IR input IR output Tone Core/Pin schema
|
||||
* --------------------------------------------------------------
|
||||
* DEFAULT/AVR 2 3 4
|
||||
* ATtinyX5 0|PB0 4|PB4 3|PB3
|
||||
* ATtiny167 3|PA3 2|PA2 7|PA7 ATTinyCore
|
||||
* ATtiny167 9|PA3 8|PA2 5|PA7 Digispark pro
|
||||
* ATtiny3217 18|PA1 19|PA2 20|PA3 MegaTinyCore
|
||||
* ATtiny1604 2 3|PA5 %
|
||||
* SAMD21 3 4 5
|
||||
* ESP8266 14|D5 12|D6 %
|
||||
* ESP32 15 4 27
|
||||
* BluePill PA6 PA7 PA3
|
||||
* APOLLO3 11 12 5
|
||||
* RP2040 3|GPIO15 4|GPIO16 5|GPIO17
|
||||
*/
|
||||
//#define _IR_MEASURE_TIMING // For debugging purposes.
|
||||
|
||||
#if defined(ESP8266)
|
||||
#define FEEDBACK_LED_IS_ACTIVE_LOW // The LED on my board (D4) is active LOW
|
||||
#define IR_RECEIVE_PIN 14 // D5
|
||||
#define IR_SEND_PIN 12 // D6 - D4/pin 2 is internal LED
|
||||
#define _IR_TIMING_TEST_PIN 13 // D7
|
||||
#define APPLICATION_PIN 0 // D3
|
||||
|
||||
#define tone(...) void() // tone() inhibits receive timer
|
||||
#define noTone(a) void()
|
||||
#define TONE_PIN 42 // Dummy for examples using it
|
||||
|
||||
#elif defined(ESP32)
|
||||
#include <Arduino.h>
|
||||
|
||||
// tone() is included in ESP32 core since 2.0.2
|
||||
#if !defined(ESP_ARDUINO_VERSION_VAL)
|
||||
#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) 12345678
|
||||
#endif
|
||||
#if ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)
|
||||
#define TONE_LEDC_CHANNEL 1 // Using channel 1 makes tone() independent of receiving timer -> No need to stop receiving timer.
|
||||
void tone(uint8_t aPinNumber, unsigned int aFrequency){
|
||||
ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);
|
||||
ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);
|
||||
}
|
||||
void tone(uint8_t aPinNumber, unsigned int aFrequency, unsigned long aDuration){
|
||||
ledcAttachPin(aPinNumber, TONE_LEDC_CHANNEL);
|
||||
ledcWriteTone(TONE_LEDC_CHANNEL, aFrequency);
|
||||
delay(aDuration);
|
||||
ledcWriteTone(TONE_LEDC_CHANNEL, 0);
|
||||
}
|
||||
void noTone(uint8_t aPinNumber){
|
||||
ledcWriteTone(TONE_LEDC_CHANNEL, 0);
|
||||
}
|
||||
#endif // ESP_ARDUINO_VERSION <= ESP_ARDUINO_VERSION_VAL(2, 0, 2)
|
||||
|
||||
#define IR_RECEIVE_PIN 15 // D15
|
||||
#define IR_SEND_PIN 4 // D4
|
||||
#define TONE_PIN 27 // D27 25 & 26 are DAC0 and 1
|
||||
#define APPLICATION_PIN 16 // RX2 pin
|
||||
|
||||
#elif defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) // BluePill
|
||||
// Timer 3 blocks PA6, PA7, PB0, PB1 for use by Servo or tone()
|
||||
#define IR_RECEIVE_PIN PA6
|
||||
#define IR_SEND_PIN PA7
|
||||
#define TONE_PIN PA3
|
||||
#define _IR_TIMING_TEST_PIN PA5
|
||||
#define APPLICATION_PIN PA2
|
||||
# if defined(ARDUINO_GENERIC_STM32F103C) || defined(ARDUINO_BLUEPILL_F103C8)
|
||||
// BluePill LED is active low
|
||||
#define FEEDBACK_LED_IS_ACTIVE_LOW
|
||||
# endif
|
||||
|
||||
#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) // Digispark board
|
||||
#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". saves 370 bytes program memory and 38 bytes RAM for digistump core
|
||||
#define IR_RECEIVE_PIN 0
|
||||
#define IR_SEND_PIN 4 // Pin 2 is serial output with ATtinySerialOut. Pin 1 is internal LED and Pin3 is USB+ with pullup on Digispark board.
|
||||
#define TONE_PIN 3
|
||||
#define _IR_TIMING_TEST_PIN 3
|
||||
|
||||
#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__) // Digispark pro board
|
||||
#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut"
|
||||
// For ATtiny167 Pins PB6 and PA3 are usable as interrupt source.
|
||||
# if defined(ARDUINO_AVR_DIGISPARKPRO)
|
||||
#define IR_RECEIVE_PIN 9 // PA3 - on Digispark board labeled as pin 9
|
||||
//#define IR_RECEIVE_PIN 14 // PB6 / INT0 is connected to USB+ on DigisparkPro boards
|
||||
#define IR_SEND_PIN 8 // PA2 - on Digispark board labeled as pin 8
|
||||
#define TONE_PIN 5 // PA7
|
||||
#define _IR_TIMING_TEST_PIN 10 // PA4
|
||||
# else
|
||||
#define IR_RECEIVE_PIN 3
|
||||
#define IR_SEND_PIN 2
|
||||
#define TONE_PIN 7
|
||||
# endif
|
||||
|
||||
#elif defined(__AVR_ATtiny88__) // MH-ET Tiny88 board
|
||||
#include "ATtinySerialOut.hpp" // Available as Arduino library "ATtinySerialOut". Saves 128 bytes program memory
|
||||
// Pin 6 is TX pin 7 is RX
|
||||
#define IR_RECEIVE_PIN 3 // INT1
|
||||
#define IR_SEND_PIN 4
|
||||
#define TONE_PIN 9
|
||||
#define _IR_TIMING_TEST_PIN 8
|
||||
|
||||
#elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__) // Tiny Core Dev board
|
||||
#define IR_RECEIVE_PIN 18
|
||||
#define IR_SEND_PIN 19
|
||||
#define TONE_PIN 20
|
||||
#define APPLICATION_PIN 0 // PA4
|
||||
#undef LED_BUILTIN // No LED available on the TinyCore 32 board, take the one on the programming board which is connected to the DAC output
|
||||
#define LED_BUILTIN 2 // PA6
|
||||
|
||||
#elif defined(__AVR_ATtiny1604__)
|
||||
#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here.
|
||||
#define IR_SEND_PIN 3
|
||||
#define APPLICATION_PIN 5
|
||||
|
||||
#define tone(...) void() // Define as void, since TCB0_INT_vect is also used by tone()
|
||||
#define noTone(a) void()
|
||||
#define TONE_PIN 42 // Dummy for examples using it
|
||||
|
||||
# elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) \
|
||||
|| defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) \
|
||||
|| defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324A__) \
|
||||
|| defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega164A__) \
|
||||
|| defined(__AVR_ATmega164P__) || defined(__AVR_ATmega32__) \
|
||||
|| defined(__AVR_ATmega16__) || defined(__AVR_ATmega8535__) \
|
||||
|| defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) \
|
||||
|| defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__) \
|
||||
|| defined(__AVR_ATmega8515__) || defined(__AVR_ATmega162__)
|
||||
#define IR_RECEIVE_PIN 2
|
||||
#define IR_SEND_PIN 13
|
||||
#define TONE_PIN 4
|
||||
#define APPLICATION_PIN 5
|
||||
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.
|
||||
#define _IR_TIMING_TEST_PIN 7
|
||||
|
||||
#elif defined(ARDUINO_ARCH_APOLLO3) // Sparkfun Apollo boards
|
||||
#define IR_RECEIVE_PIN 11
|
||||
#define IR_SEND_PIN 12
|
||||
#define TONE_PIN 5
|
||||
|
||||
#elif defined(ARDUINO_ARCH_MBED) && defined(ARDUINO_ARCH_MBED_NANO) // Arduino Nano 33 BLE
|
||||
#define IR_RECEIVE_PIN 3 // GPIO15 Start with pin 3 since pin 2|GPIO25 is connected to LED on Pi pico
|
||||
#define IR_SEND_PIN 4 // GPIO16
|
||||
#define TONE_PIN 5
|
||||
#define APPLICATION_PIN 6
|
||||
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 7 // E.g. used for examples which use LED_BUILDIN for example output.
|
||||
#define _IR_TIMING_TEST_PIN 8
|
||||
|
||||
#elif defined(ARDUINO_ARCH_RP2040) // Arduino Nano Connect, Pi Pico with arduino-pico core https://github.com/earlephilhower/arduino-pico
|
||||
#define IR_RECEIVE_PIN 15 // to be compatible with the Arduino Nano RP2040 Connect (pin3)
|
||||
#define IR_SEND_PIN 16
|
||||
#define TONE_PIN 17
|
||||
#define APPLICATION_PIN 18
|
||||
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 19 // E.g. used for examples which use LED_BUILDIN for example output.
|
||||
#define _IR_TIMING_TEST_PIN 20
|
||||
|
||||
// If you program the Nano RP2040 Connect with this core, then you must redefine LED_BUILTIN
|
||||
// and use the external reset with 1 kOhm to ground to enter UF2 mode
|
||||
//#undef LED_BUILTIN
|
||||
//#define LED_BUILTIN 6
|
||||
|
||||
#elif defined(PARTICLE) // !!!UNTESTED!!!
|
||||
#define IR_RECEIVE_PIN A4
|
||||
#define IR_SEND_PIN A5 // Particle supports multiple pins
|
||||
|
||||
#define LED_BUILTIN D7
|
||||
|
||||
/*
|
||||
* 4 times the same (default) layout for easy adaption in the future
|
||||
*/
|
||||
#elif defined(TEENSYDUINO)
|
||||
#define IR_RECEIVE_PIN 2
|
||||
#define IR_SEND_PIN 3
|
||||
#define TONE_PIN 4
|
||||
#define APPLICATION_PIN 5
|
||||
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.
|
||||
#define _IR_TIMING_TEST_PIN 7
|
||||
|
||||
#elif defined(__AVR__) // Default as for ATmega328 like on Uno, Nano etc.
|
||||
#define IR_RECEIVE_PIN 2 // To be compatible with interrupt example, pin 2 is chosen here.
|
||||
#define IR_SEND_PIN 3
|
||||
#define TONE_PIN 4
|
||||
#define APPLICATION_PIN 5
|
||||
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.
|
||||
#define _IR_TIMING_TEST_PIN 7
|
||||
|
||||
# if defined(ARDUINO_AVR_PROMICRO) // Sparkfun Pro Micro is __AVR_ATmega32U4__ but has different external circuit
|
||||
// We have no built in LED at pin 13 -> reuse RX LED
|
||||
#undef LED_BUILTIN
|
||||
#define LED_BUILTIN LED_BUILTIN_RX
|
||||
# endif
|
||||
|
||||
#elif defined(ARDUINO_ARCH_MBED) // Arduino Nano 33 BLE
|
||||
#define IR_RECEIVE_PIN 2
|
||||
#define IR_SEND_PIN 3
|
||||
#define TONE_PIN 4
|
||||
#define APPLICATION_PIN 5
|
||||
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.
|
||||
#define _IR_TIMING_TEST_PIN 7
|
||||
|
||||
#elif defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_SAM)
|
||||
#define IR_RECEIVE_PIN 2
|
||||
#define IR_SEND_PIN 3
|
||||
#define TONE_PIN 4
|
||||
#define APPLICATION_PIN 5
|
||||
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.
|
||||
#define _IR_TIMING_TEST_PIN 7
|
||||
|
||||
// On the Zero and others we switch explicitly to SerialUSB
|
||||
#define Serial SerialUSB
|
||||
|
||||
// Definitions for the Chinese SAMD21 M0-Mini clone, which has no led connected to D13/PA17.
|
||||
// Attention!!! D2 and D4 are swapped on these boards!!!
|
||||
// If you connect the LED, it is on pin 24/PB11. In this case activate the next two lines.
|
||||
//#undef LED_BUILTIN
|
||||
//#define LED_BUILTIN 24 // PB11
|
||||
// As an alternative you can choose pin 25, it is the RX-LED pin (PB03), but active low.In this case activate the next 3 lines.
|
||||
//#undef LED_BUILTIN
|
||||
//#define LED_BUILTIN 25 // PB03
|
||||
//#define FEEDBACK_LED_IS_ACTIVE_LOW // The RX LED on the M0-Mini is active LOW
|
||||
|
||||
#elif defined (NRF51) // BBC micro:bit
|
||||
#define IR_RECEIVE_PIN 2
|
||||
#define IR_SEND_PIN 3
|
||||
#define APPLICATION_PIN 1
|
||||
#define _IR_TIMING_TEST_PIN 4
|
||||
|
||||
#define tone(...) void() // no tone() available
|
||||
#define noTone(a) void()
|
||||
#define TONE_PIN 42 // Dummy for examples using it
|
||||
|
||||
#else
|
||||
#warning Board / CPU is not detected using pre-processor symbols -> using default values, which may not fit. Please extend PinDefinitionsAndMore.h.
|
||||
// Default valued for unidentified boards
|
||||
#define IR_RECEIVE_PIN 2
|
||||
#define IR_SEND_PIN 3
|
||||
#define TONE_PIN 4
|
||||
#define APPLICATION_PIN 5
|
||||
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.
|
||||
#define _IR_TIMING_TEST_PIN 7
|
||||
#endif // defined(ESP8266)
|
||||
|
||||
#if defined(ESP32) || defined(ARDUINO_ARCH_RP2040) || defined(PARTICLE) || defined(ARDUINO_ARCH_MBED)
|
||||
#define SEND_PWM_BY_TIMER // We do not have pin restrictions for this CPU's, so lets use the hardware PWM for send carrier signal generation
|
||||
#else
|
||||
# if defined(SEND_PWM_BY_TIMER)
|
||||
#undef IR_SEND_PIN // SendPin is determined by timer! This avoids warning in IRTimer.hpp
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (FLASHEND)
|
||||
#define FLASHEND 0xFFFF // Dummy value for platforms where FLASHEND is not defined
|
||||
#endif
|
||||
/*
|
||||
* Helper macro for getting a macro definition as string
|
||||
*/
|
||||
#if !defined(STR_HELPER)
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
#endif
|
||||
Reference in New Issue
Block a user