Skip to content

Commit

Permalink
add support for Trotec AC
Browse files Browse the repository at this point in the history
  • Loading branch information
stufisher committed Jul 23, 2017
1 parent 2bb53e5 commit 50b90fc
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/Contributors.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [Massimiliano Pinto](https://github.com/pintomax/)
- [Darsh Patel](https://github.com/darshkpatel/)
- [Jonny Graham](https://github.com/jonnygraham/)
- [Stu Fisher](https://github.com/stufisher/)

All contributors can be found on the [contributors site](https://github.com/markszabo/IRremoteESP8266/graphs/contributors).

Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ script:
- arduino --verify --board $BD $PWD/examples/TurnOnKelvinatorAC/TurnOnKelvinatorAC.ino
- arduino --verify --board $BD $PWD/examples/TurnOnMitsubishiAC/TurnOnMitsubishiAC.ino
- arduino --verify --board $BD $PWD/examples/IRsendProntoDemo/IRsendProntoDemo.ino
- arduino --verify --board $BD $PWD/examples/TurnOnTrotecAC/TurnOnTrotecAC.ino
# Check for lint issues.
- shopt -s nullglob
- python cpplint.py --extensions=c,cc,cpp,ino --headers=h,hpp {src,test}/*.{h,c,cc,cpp,hpp,ino} examples/*/*.{h,c,cc,cpp,hpp,ino}
Expand Down
52 changes: 52 additions & 0 deletions examples/TurnOnTrotecAC/TurnOnTrotecAC.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* Copyright 2017 stufisher
* An IR LED circuit *MUST* be connected to ESP8266 pin 4 (D2).
*
* TL;DR: The IR LED needs to be driven by a transistor for a good result.
*
* Suggested circuit:
* https://github.com/markszabo/IRremoteESP8266/wiki#ir-sending
*
* Common mistakes & tips:
* * Don't just connect the IR LED directly to the pin, it won't
* have enough current to drive the IR LED effectively.
* * Make sure you have the IR LED polarity correct.
* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity
* * Typical digital camera/phones can be used to see if the IR LED is flashed.
* Replace the IR LED with a normal LED if you don't have a digital camera
* when debugging.
* * Avoid using the following pins unless you really know what you are doing:
* * Pin 0/D3: Can interfere with the boot/program mode & support circuits.
* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere.
* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere.
* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs
* for your first time. e.g. ESP-12 etc.
*/

#ifndef UNIT_TEST
#include <Arduino.h>
#endif
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include <ir_Trotec.h>

IRTrotecESP trotecir(D2); // An IR LED is controlled by GPIO pin 4 (D2)

void setup() {
trotecir.begin();
Serial.begin(115200);
}

void loop() {
Serial.println("Sending...");

// Set up what we want to send. See ir_Trotec.cpp for all the options.
trotecir.setPower(true);
trotecir.setSpeed(TROTEC_FAN_LOW);
trotecir.setMode(TROTEC_COOL);
trotecir.setTemp(25);

// Now send the IR signal.
trotecir.send();

delay(5000);
}
17 changes: 17 additions & 0 deletions examples/TurnOnTrotecAC/platformio.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[platformio]
lib_extra_dirs = ../../
src_dir=.

[common]
build_flags =
lib_deps_builtin =
lib_deps_external =

[env:nodemcuv2]
platform = espressif8266
framework = arduino
board = nodemcuv2
build_flags = ${common.build_flags}
lib_deps =
${common.lib_deps_builtin}
${common.lib_deps_external}
8 changes: 7 additions & 1 deletion src/IRremoteESP8266.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* Updated by sillyfrog for Daikin, adopted from
* (https://github.com/mharizanov/Daikin-AC-remote-control-over-the-Internet/)
* Fujitsu A/C code added by jonnygraham
* Trotec AC code by stufisher
* GPL license, all text above must be included in any redistribution
****************************************************/

Expand Down Expand Up @@ -125,6 +126,9 @@
#define DECODE_PRONTO false // Not written.
#define SEND_PRONTO true

#define DECODE_TROTEC false // Not implemented.
#define SEND_TROTEC true

/*
* Always add to the end of the list and should never remove entries
* or change order. Projects may save the type number for later usage
Expand Down Expand Up @@ -158,7 +162,8 @@ enum decode_type_t {
RC5X,
GREE,
PRONTO,
NEC_LIKE
NEC_LIKE,
TROTEC
};

// Message lengths & required repeat values
Expand Down Expand Up @@ -210,6 +215,7 @@ enum decode_type_t {
#define SONY_20_BITS 20U
#define SONY_MIN_BITS SONY_12_BITS
#define SONY_MIN_REPEAT 2U
#define TROTEC_COMMAND_LENGTH 9U
#define WHYNTER_BITS 32U

// Turn on Debugging information by uncommenting the following line.
Expand Down
6 changes: 6 additions & 0 deletions src/IRsend.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ class IRsend {
void sendPronto(uint16_t data[], uint16_t len, uint16_t repeat = 0);
#endif

#if SEND_TROTEC
void sendTrotec(unsigned char data[],
uint16_t nbytes = TROTEC_COMMAND_LENGTH,
uint16_t repeat = 0);
#endif

protected:
#ifdef UNIT_TEST
#ifndef HIGH
Expand Down
151 changes: 151 additions & 0 deletions src/ir_Trotec.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// Copyright 2017 stufisher

#include "ir_Trotec.h"
#include "IRremoteESP8266.h"
#include "IRutils.h"

// Constants
#define TROTEC_HDR_MARK 5952U
#define TROTEC_HDR_SPACE 7364U
#define TROTEC_ONE_MARK 592U
#define TROTEC_ONE_SPACE 1560U
#define TROTEC_ZERO_MARK 592U
#define TROTEC_ZERO_SPACE 592U
#define TROTEC_GAP 6184U
#define TROTEC_GAP_END 1500U // made up value

#if SEND_TROTEC

void IRsend::sendTrotec(unsigned char data[], uint16_t nbytes,
uint16_t repeat) {
if (nbytes < TROTEC_COMMAND_LENGTH)
return;

enableIROut(36);

for (uint16_t r = 0; r <= repeat; r++) {
// Header
mark(TROTEC_HDR_MARK);
space(TROTEC_HDR_SPACE);

// Data
for (uint16_t i = 0; i < nbytes; i++)
sendData(TROTEC_ONE_MARK, TROTEC_ONE_SPACE, TROTEC_ZERO_MARK,
TROTEC_ZERO_SPACE, data[i], 8, false);

// Footer
mark(TROTEC_ONE_MARK);
space(TROTEC_GAP);
mark(TROTEC_ONE_MARK);
space(TROTEC_GAP_END);
}
}

IRTrotecESP::IRTrotecESP(uint16_t pin) : _irsend(pin) {
stateReset();
}

void IRTrotecESP::begin() {
_irsend.begin();
}

void IRTrotecESP::send() {
checksum();
_irsend.sendTrotec(trotec);
}

void IRTrotecESP::checksum() {
uint8_t sum = 0;
uint8_t i;

for (i = 2; i < 8; i++) sum += trotec[i];

trotec[8] = sum & 0xFF;
}

void IRTrotecESP::stateReset() {
for (uint8_t i = 2; i < TROTEC_COMMAND_LENGTH; i++)
trotec[i] = 0x0;

trotec[0] = TROTEC_INTRO1;
trotec[1] = TROTEC_INTRO2;

setPower(false);
setTemp(TROTEC_DEF_TEMP);
setSpeed(TROTEC_FAN_MED);
setMode(TROTEC_AUTO);
}

uint8_t* IRTrotecESP::getRaw() {
checksum();
return trotec;
}

void IRTrotecESP::setPower(bool state) {
if (state)
trotec[2] |= (TROTEC_ON << 3);
else
trotec[2] &= ~(TROTEC_ON << 3);
}

uint8_t IRTrotecESP::getPower() {
return trotec[2] & (TROTEC_ON << 3);
}

void IRTrotecESP::setSpeed(uint8_t speed) {
trotec[2] = (trotec[2] & 0xcf) | (speed << 4);
}

uint8_t IRTrotecESP::getSpeed() {
return trotec[2] & 0x30;
}

void IRTrotecESP::setMode(uint8_t mode) {
trotec[2] = (trotec[2] & 0xfc) | mode;
}

uint8_t IRTrotecESP::getMode() {
return trotec[2] & 0x03;
}

void IRTrotecESP::setTemp(uint8_t temp) {
if (temp < TROTEC_MIN_TEMP)
temp = TROTEC_MIN_TEMP;
else if (temp > TROTEC_MAX_TEMP)
temp = TROTEC_MAX_TEMP;

trotec[3] = (trotec[3] & 0x80) | (temp - TROTEC_MIN_TEMP);
}

uint8_t IRTrotecESP::getTemp() {
return trotec[3] & 0x7f;
}

void IRTrotecESP::setSleep(bool sleep) {
if (sleep)
trotec[3] |= (TROTEC_SLEEP_ON << 7);
else
trotec[3] &= ~(TROTEC_SLEEP_ON << 7);
}

bool IRTrotecESP::getSleep(void) {
return trotec[3] & (TROTEC_SLEEP_ON << 7);
}

void IRTrotecESP::setTimer(uint8_t timer) {
if (timer > TROTEC_MAX_TIMER) timer = TROTEC_MAX_TIMER;

if (timer) {
trotec[5] |= (TROTEC_TIMER_ON << 6);
trotec[6] = timer;
} else {
trotec[5] &= ~(TROTEC_TIMER_ON << 6);
trotec[6] = 0;
}
}

uint8_t IRTrotecESP::getTimer() {
return trotec[6];
}

#endif // SEND_TROTEC
80 changes: 80 additions & 0 deletions src/ir_Trotec.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2017 stufisher

#ifndef IR_TROTEC_H_
#define IR_TROTEC_H_

#include "IRremoteESP8266.h"
#include "IRsend.h"

// Constants
// Byte 0
#define TROTEC_INTRO1 0x12

// Byte 1
#define TROTEC_INTRO2 0x34

// Byte 2
#define TROTEC_AUTO 0
#define TROTEC_COOL 1
#define TROTEC_DRY 2
#define TROTEC_FAN 3

#define TROTEC_ON 1
#define TROTEC_OFF 0

#define TROTEC_FAN_LOW 1
#define TROTEC_FAN_MED 2
#define TROTEC_FAN_HIGH 3

// Byte 3
#define TROTEC_MIN_TEMP 18
#define TROTEC_MAX_TEMP 32
#define TROTEC_DEF_TEMP 25

#define TROTEC_SLEEP_ON 1

// Byte 5
#define TROTEC_TIMER_ON 1

// Byte 6
#define TROTEC_MIN_TIMER 0
#define TROTEC_MAX_TIMER 23

#if SEND_TROTEC

class IRTrotecESP {
public:
explicit IRTrotecESP(uint16_t pin);

void send();
void begin();

void setPower(bool state);
uint8_t getPower();

void setTemp(uint8_t temp);
uint8_t getTemp();

void setSpeed(uint8_t fan);
uint8_t getSpeed();

uint8_t getMode();
void setMode(uint8_t mode);

bool getSleep();
void setSleep(bool sleep);

uint8_t getTimer();
void setTimer(uint8_t timer);

uint8_t* getRaw();

private:
uint8_t trotec[TROTEC_COMMAND_LENGTH];
void stateReset();
void checksum();
IRsend _irsend;
};
#endif

#endif // IR_TROTEC_H_

0 comments on commit 50b90fc

Please sign in to comment.