22 #include <avr/pgmspace.h> 
   27 #include <IPAddress.h> 
   31 #include <IrReceiverSampler.h> 
   35 #include <IrSenderPwm.h> 
   39 #include <IrReceiverSampler.h> 
   43 #include <IrWidgetAggregating.h> 
   47 #include <IrSenderNonMod.h> 
   52 #error DECODER without RECEIVE is nonsensical, aborting. 
   54 #include <MultiDecoder.h> 
   59 #error RENDER without TRANSMIT is nonsensical, aborting. 
   62 #include <Nec1Renderer.h> 
   63 #include <Rc5Renderer.h> 
   67 #error NAMED_COMMANDS is presently not supported 
   79 #if defined(CONFIGURABLE_LEDS) & (! defined(PARAMETERS) | !defined(LED)) 
   80 #error CONFIGURABLE_LEDS defined but not PARAMETERS and LED, aborting. 
   83 #ifdef CONFIGURABLE_LEDS 
   84 #define LED_PARAMETER_CONST 
   86 #define LED_PARAMETER_CONST const 
   90 #define PARAMETERS_NAME Parameters 
   91 #define PARAMETER_CONST 
   93 #define PARAMETERS_NAME 
   94 #define PARAMETER_CONST const 
  122 #if defined(RECEIVE) | defined(CAPTURE) 
  128 #ifdef IRRECEIVER_2_PIN 
  143 #define modulesSupported EXPAND_AND_QUOTE(Base TRANSMIT_NAME CAPTURE_NAME RENDERER_NAME RECEIVE_NAME DECODER_NAME LED_NAME LCD_NAME PARAMETERS_NAME NAMED_COMMANDS_NAME PRONTO_NAME) 
  145 #define PROGNAME "AGirs" 
  151 #define okString "OK" 
  152 #define errorString "ERROR" 
  153 #define timeoutString "." 
  162 static bool sendIrSignal(
const IrSignal &irSignal, 
unsigned int noSends=1) {
 
  170             (irSignal.getFrequency() == 0) ? (IrSender*) 
new IrSenderNonMod(
NON_MOD_PIN) :
 
  172             (IrSender*) IrSenderPwm::getInstance(
true);
 
  174     irSender->sendIrSignal(irSignal, noSends);
 
  177     if (irSignal.getFrequency() == 0)
 
  181         IrSenderPwm::deleteInstance();
 
  192     while (stream.available())
 
  200     MultiDecoder multiDecoder(*irReader);
 
  202     if (multiDecoder.getType() > MultiDecoder::noise) {
 
  204                 ? 
"." : multiDecoder.getDecode(),
 
  205                 multiDecoder.getType() != MultiDecoder::nec_ditto);
 
  206         if (multiDecoder.getType() == MultiDecoder::nec)
 
  216 #if defined(DECODER) & ! defined(DONT_REPORT_DECODES)  
  217     switch (multiDecoder.getType()) {
 
  218         case MultiDecoder::noise:
 
  221         case MultiDecoder::undecoded:
 
  222             irReader->dump(stream); 
 
  226             stream.println(multiDecoder.getDecode()); 
 
  230     if (irReader->isEmpty())
 
  233         irReader->dump(stream);
 
  240     IrReceiverSampler *
irReceiver = IrReceiverSampler::getInstance();
 
  255     while (!
irReceiver->isReady() && stream.available() == 0)
 
  264      IrReceiverSampler::deleteInstance();
 
  272     IrWidget *irWidget = IrWidgetAggregating::newIrWidgetAggregating(
captureSize,
 
  274     if (irWidget == 
nullptr)
 
  275         stream.println(F(
"This cannot happen"));
 
  289     if (!irWidget->isEmpty()) {
 
  292         irWidget->dump(stream);
 
  296     IrWidgetAggregating::deleteInstance();
 
  301 #ifdef NAMED_COMMANDS 
  305 static bool sendNamedCommand(Stream& stream, 
const char* remoteName, 
const char* commandName, 
unsigned int noSends) {
 
  307     if (remote == 
nullptr) {
 
  308         stream.println(F(
"No such remote"));
 
  313     if (command == 
nullptr) {
 
  314         stream.println(F(
"No such command"));
 
  318     bool status = sendIrSignal(*irSignal, noSends); 
 
  323 static void dumpRemote(Stream& stream, 
const char* name) {
 
  324     if (name[0] != 
'\0') {
 
  326             stream.print(remote.
getName());
 
  331         const IrNamedRemote* remote = remoteSet.getIrNamedRemote(name);
 
  332         if (remote == 
nullptr)
 
  333             stream.println(F(
"No such remote"));
 
  336                 stream.print(command.
getName());
 
  349 #if defined(TRANSMIT) 
  351     IrSenderPwm::getInstance(
true)->mute();
 
  353 #pragma GCC diagnostic push 
  354 #pragma GCC diagnostic ignored "-Wpedantic" 
  359 #pragma GCC diagnostic pop 
  378 #ifdef SDCARD_ON_ETHERSHIELD_PIN 
  387     Ethernet.begin(mac, IPAddress(IPADDRESS), IPAddress(DNSSERVER), IPAddress(GATEWAY), IPAddress(SUBNETMASK));
 
  390     sprintf(ipstring, 
"%d.%d.%d.%d", Ethernet.localIP()[0], Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
 
  395     strcpy(url, 
"http://");
 
  396     strcat(url, ipstring);
 
  405 #if ! defined(ETHERNET) | defined(SERIAL_DEBUG) 
  415     Serial.println(Ethernet.localIP());
 
  421 void info(Stream& stream) {
 
  422     stream.print(
"Board: ");
 
  423 #ifdef ARDUINO_AVR_MEGA2560 
  424     stream.print(F(
"Arduino Mega2560"));
 
  425 #elif defined(ARDUINO_AVR_NANO) 
  426     stream.print(F(
"Arduino Nano"));
 
  427 #elif defined(ARDUINO_AVR_LEONARDO) 
  428     stream.print(F(
"Arduino Leonardo"));
 
  429 #elif defined(ARDUINO_AVR_MINI) 
  430     stream.print(F(
"Arduino Leonardo"));
 
  431 #elif defined(ARDUINO_AVR_UNO) 
  432     stream.print(F(
"Arduino Uno"));
 
  434     stream.print(F(
"Unknown"));
 
  443 #pragma GCC diagnostic push 
  444 #pragma GCC diagnostic ignored "-Wunused-function" 
  445 static bool isPrefix(
const char *
string, 
const char* cmd) {
 
  446     return strncmp(cmd, 
string, strlen(
string)) == 0;
 
  449 bool isPrefix(
const char* cmd, 
const __FlashStringHelper *pstring) {
 
  450     return strncmp_PF(cmd, STRCPY_PF_CAST(
reinterpret_cast<uint_farptr_t
>(pstring)), strlen(cmd)) == 0;
 
  453 bool isPrefix(
const __FlashStringHelper *pstring, 
const char* cmd) {
 
  454     return strncmp_PF(cmd, STRCPY_PF_CAST(
reinterpret_cast<uint_farptr_t
>(pstring)), strlen_PF(STRCPY_PF_CAST(
reinterpret_cast<uint_farptr_t
>(pstring)))) == 0;
 
  456 #pragma GCC diagnostic pop 
  459 #if defined(COMMANDLED) & defined(LED) 
  464     while (parser.
getStream().available() == 0)
 
  470 #if defined(DEBUG_CMD) 
  473 #if defined(COMMANDLED) & defined(LED) 
  484     if (cmd[0] == 
'\0') {
 
  490         if (cmd[0] == 
'a' || cmd[0] == 
'c') {
 
  497             constexpr 
size_t buflen = 40U;
 
  507         pin_t no = 
static_cast<pin_t
>(parser.
parseAbsInt());
 
  536         unsigned long *variable32 = 
nullptr;
 
  537         uint16_t *variable16 = 
nullptr;
 
  538         uint8_t *variable8 = 
nullptr;
 
  539 #if defined(RECEIVE) || defined(CAPTURE) 
  540            if (
isPrefix(F(
"beg"), variableName))
 
  545             if (
isPrefix(F(
"capturee"), variableName))
 
  549            if (
isPrefix(F(
"receivee"), variableName))
 
  553 #if defined(RECEIVE) & defined(IRRECEIVER_2_PIN) 
  554             if (
isPrefix(variableName, F(
"receiver")))
 
  559         if (
isPrefix(F(
"captures"), variableName)) {
 
  565 #ifdef CONFIGURABLE_LEDS 
  567             if (
isPrefix(F(
"transmitl"), variableName))
 
  572             if (
isPrefix(F(
"capturel"), variableName))
 
  577             if (
isPrefix(F(
"receivel"), variableName))
 
  582             if (
isPrefix(F(
"commandl"), variableName))
 
  593         if (variable32 != 
nullptr) {
 
  598         } 
else if (variable16 != 
nullptr) {
 
  600                 *variable16 = 
static_cast<uint16_t
>(value);
 
  603         } 
else if (variable8 != 
nullptr) {
 
  605                 *variable8 = (uint8_t) value;
 
  609             stream.println(F(
"No such variable"));
 
  628 #ifdef NAMED_COMMANDS 
  630         uint16_t noSends = 
static_cast<uint16_t
>(parser.
parseAbsInt());
 
  635         bool success = sendNamedCommand(stream, remoteName, commandName, noSends);
 
  643         dumpRemote(stream, name);
 
  656         uint16_t noSends = 
static_cast<uint16_t
>(parser.
parseAbsInt());
 
  657         frequency_t frequency = 
static_cast<frequency_t
>(parser.
parseAbsInt());
 
  658         uint16_t introLength = 
static_cast<uint16_t
>(parser.
parseAbsInt());
 
  659         uint16_t repeatLength = 
static_cast<uint16_t
>(parser.
parseAbsInt());
 
  660         uint16_t endingLength = 
static_cast<uint16_t
>(parser.
parseAbsInt());
 
  661         microseconds_t *intro = 
new microseconds_t[introLength];
 
  663         microseconds_t *repeat = 
new microseconds_t[repeatLength];
 
  665         microseconds_t *ending = 
new microseconds_t[endingLength];
 
  667         IrSignal irSignal(intro, introLength, repeat, repeatLength, ending, endingLength, frequency);
 
  668         bool status = sendIrSignal(irSignal, noSends); 
 
  676         uint16_t noSends = 
static_cast<uint16_t
>(parser.
parseAbsInt());
 
  680         if (irSignal != 
nullptr) {
 
  681             status = sendIrSignal(*irSignal, noSends); 
 
  692         uint16_t noSends = 
static_cast<uint16_t
>(parser.
parseAbsInt());
 
  693         constexpr 
size_t buflen = 20U;
 
  694         char protocol[buflen];
 
  696         const IrSignal *irSignal = 
nullptr;
 
  697         if (
isPrefix(protocol, F(
"nec1"))) {
 
  698             int D = 
static_cast<unsigned>(parser.
parseAbsInt());
 
  699             int second = 
static_cast<unsigned>(parser.
parseAbsInt());
 
  703                     ? Nec1Renderer::newIrSignal(D, second)
 
  704                     : Nec1Renderer::newIrSignal(D, second, third);
 
  705         } 
else if (
isPrefix(protocol, F(
"rc5"))) {
 
  706             int D = 
static_cast<unsigned>(parser.
parseAbsInt());
 
  707             int F = 
static_cast<unsigned>(parser.
parseAbsInt());
 
  711                     ? Rc5Renderer::newIrSignal(D, F)
 
  712                     : Rc5Renderer::newIrSignal(D, F, T);
 
  714             stream.print(F(
"no such protocol: "));
 
  715             stream.println(protocol);
 
  718         if (irSignal != 
nullptr) {
 
  719             status = sendIrSignal(*irSignal, noSends); 
 
  753     Serial.print(F(
"Command: "));
 
  760 #if defined(ETHERNET) 
  762     while (client.available() == 0) {
 
  767         if (!client.connected())
 
  781     EthernetClient client = 
server.available();
 
  784     client.setTimeout(10000);
 
  788     sprintf(ip, 
"%d.%d.%d.%d", Ethernet.localIP()[0], Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]);
 
  792     Serial.print(F(
"Connection from "));
 
  795 #if defined(COMMANDLED) & defined(LED) 
  800 #if defined(COMMANDLED) & defined(LED) 
  808     Serial.println(F(
"Connection closed!"));
 
  810     client.println(F(
"Bye"));
 
  812 #if defined(COMMANDLED) & defined(LED) 
  816     if (client.connected())
 
  822     Stream& stream = Serial;
 
#define SDCARD_ON_ETHERSHIELD_PIN
Pin to disable (put low) on Ethernet shield.
 
#define SERIALTIMEOUT
Timeout for serial line.
 
#define SERIALBAUD
Configured speed of the serial port.
 
#define DEFAULT_BEGINTIMEOUT
Time to wait for signal to start.
 
#define DEFAULT_RECEIVE_ENDINGTIMEOUT
By receive, time to wait before signal is considered ended.
 
#define RECEIVELED
Number of logical LED to light when waiting for reception.
 
#define DEFAULT_CAPTURESIZE
Size of capture and receive arrays.
 
#define DECODELED
Define to support blinking with LED according to decoding outcome.
 
#define PORT
TCP port to use.
 
#define IRRECEIVER_MARK_EXCESS
This quantity is added to all gaps and subtracted from all marks when receiving.
 
#define COMMANDLED
Number of logical LED to light when waiting for command.
 
#define MACADDRESS
Must define MAC-Address to use here (!!).
 
#define TRANSMITLED
Number of logical LED to light when transmission takings place.
 
#define CAPTURELED
Number of logical LED to light when waiting for capture.
 
#define DEFAULT_CAPTURE_ENDINGTIMEOUT
By capture, time to wait before signal is considered ended.
 
#define IRSENSOR_MARK_EXCESS
This quantity is added to all gaps and subtracted from all marks when capturing.
 
static bool receive(StreamParser &parser)
 
static bool readProcessOneCommand(Stream &stream)
 
static bool capture(Stream &stream)
 
static PARAMETER_CONST unsigned long beginTimeout
 
EthernetServer server(PORT)
 
static void flushIn(Stream &stream)
 
static PARAMETER_CONST unsigned long receiveEndingTimeout
 
static void readCommand(char *cmd, size_t cmdLength, StreamParser &parser)
 
static bool isPrefix(const char *string, const char *cmd)
 
static PARAMETER_CONST uint16_t captureSize
 
static const uint8_t receiverNo
 
#define LED_PARAMETER_CONST
 
static void decodeOrDump(IrReader *irReader, Stream &stream)
 
static constexpr size_t cmdLength
Allocated length (-1) for commands etc.
 
bool readProcessOneTcpCommand(EthernetClient &client)
 
static bool processCommand(const char *cmd, StreamParser &parser)
 
static PARAMETER_CONST unsigned long captureEndingTimeout
 
static const unsigned sensorNo
 
static IrReader * irReceiver
 
static void printVariable(Stream &stream, const char *variableName, unsigned long value)
 
static bool sensorPullup(uint8_t sensorNo UNUSED)
 
static unsigned long freeRam()
 
static void setupSensors()
 
static pin_t receiverPin(uint8_t receiverNo UNUSED)
 
static bool receiverPullup(uint8_t receiverNo UNUSED)
 
static void setupReceivers()
 
For now, just a dummy skeleton.
 
const char * getName() const
 
const IrSignal * getIrSignal() const
 
const IrNamedRemote * getIrNamedRemote(const char *) const
 
const char * getName() const
 
const IrNamedCommand * getIrNamedCommand(const char *) const
 
static void lcdPrint(const char *str, bool clear=true, int x=invalidLine, int y=invalidLine)
 
static void setupShouldTimeout(led_t logicLed, bool state)
 
static void setupLedGroundPins()
 
static bool setLogicLed(led_t logicLed, LedState state)
 
static void lcdSetCursor(uint8_t x=0, uint8_t y=0)
 
static void setup(int8_t i2cAddress, uint8_t columns=defaultLcdColumns, uint8_t rows=defaultLcdRows, const pin_t physicalLeds[maxLeds]=NULL, const led_t logicalLeds[maxLeds]=NULL, const bool shouldTimeOut[maxLeds]=NULL)
Sets up the instance, to be called before using the instance.
 
static void selfTest(const char *text)
 
static void checkTurnoff()
Turn off if it is due.
 
Simple class for parsing stuff from an (input) Stream.
 
int32_t parseAbsInt()
Reads a number and returns it as 16 bit unsigned.
 
const char * getLine(char *buf, size_t buflen)
 
int32_t parseAbsIntDefault(int32_t fallback)
Reads a number and returns it as 16 bit unsigned.
 
const char * parseWord(char *buf, size_t buflen)
Returns a word (separated by whitespace).
 
microseconds_t * parseData(microseconds_t *buffer, size_t length)
 
IrSignal * parsePronto()
Reads a Pronto Hex format IR signal.
 
static constexpr int invalid
 
#define EXPAND_AND_QUOTE(str)
 
#define VERSION
Version of the current library.