Skip to content

Commit 0d8b15f

Browse files
committed
Modified to conform with Arduino library specifications
1 parent f404544 commit 0d8b15f

File tree

8 files changed

+482
-442
lines changed

8 files changed

+482
-442
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <Arduino.h>
2+
#include <midea_ir.h>
3+
4+
const uint8_t MIDEA_RMT_CHANNEL = 0;
5+
const uint8_t MIDEA_TX_PIN = 4;
6+
7+
MideaIR ir;
8+
9+
void setup()
10+
{
11+
// init library
12+
midea_ir_init(&ir, MIDEA_RMT_CHANNEL, MIDEA_TX_PIN);
13+
14+
// set mode, temperature and fan level and internal state to enabled
15+
ir.enabled = true;
16+
ir.mode = MODE_COOL;
17+
ir.fan_level = 3;
18+
ir.temperature = 23;
19+
20+
// send the IR signal with the previously set properties which will switch the A/C on
21+
midea_ir_send(&ir);
22+
23+
delay(5000);
24+
25+
// starts moving the deflector
26+
midea_ir_move_deflector();
27+
28+
delay(5000);
29+
30+
// set state to disabled
31+
ir.enabled = false;
32+
33+
// send the IR signal which will turn the A/C off
34+
midea_ir_send(&ir);
35+
}
36+
37+
void loop()
38+
{
39+
delay(1000);
40+
}
File renamed without changes.

library.properties

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
name=ESP32_RMT_MIDEA_IR_TX
2-
version=0.1
1+
name=Midea AC infrared remote controller with ESP32 RMT Peripheral
2+
version=1.0.0
33
author=Peter Pinter <pinterpeti@gmail.com>
44
maintainer=Peter Pinter
55
sentence=ESP32 RMT Peripheral IR remote control library for Midea Air conditioner.
66
paragraph=
7-
category=Other
8-
url=
7+
category=Communication
8+
url=https://github.com/morcibacsi/esp32_rmt_midea_ir_tx
99
architectures=esp32

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
### Schema
66

7-
![schema](https://github.com/morcibacsi/esp32_rmt_midea_ir_tx/raw/master/schema/esp32_ir.jpg)
7+
![schema](https://github.com/morcibacsi/esp32_rmt_midea_ir_tx/raw/master/extras/schema/esp32_ir.jpg)
88

99
### Usage
1010

Lines changed: 163 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,164 @@
1-
#include "esp32_rmt_midea_ir_tx.h"
2-
3-
#define PULSE_LENGTH 557; // Each pulse (one "time" unit or 1T) is 21 cycles of a 38KHz carrier burst (about 550µs long)
4-
5-
volatile uint8_t _rmt_midea_ir_tx_txPin;
6-
volatile uint8_t _rmt_midea_ir_tx_channel;
7-
8-
/*
9-
Convert a byte to its midea-protocol encoded counterpart as a RMT duration
10-
Idea borrowed from here: https://github.com/kimeckert/ESP32-RMT-Rx-raw
11-
*/
12-
void ConvertByteToMideaRmtValues(uint8_t byteValue, int16_t rmtValues[], int16_t rmtValuesIndex, int16_t *rmtCount)
13-
{
14-
// A logic "1" is a 1T pulse followed by a 3T space and takes 2.25ms to transmit
15-
// A logic "0" is a 1T pulse followed by a 1T space and takes 1.125ms
16-
17-
int16_t currentIndex = rmtValuesIndex;
18-
19-
for (int8_t j = 7; j >= 0; j--)
20-
{
21-
currentIndex++;
22-
rmtValues[currentIndex] = 1*PULSE_LENGTH; // 1T pulse
23-
currentIndex++;
24-
25-
int8_t currentBitValue = (byteValue >> j) & 1;
26-
if (currentBitValue == 1)
27-
{
28-
rmtValues[currentIndex] = -3*PULSE_LENGTH; // 3T space
29-
}
30-
else
31-
{
32-
rmtValues[currentIndex] = -1*PULSE_LENGTH; // 1T space
33-
}
34-
}
35-
*rmtCount = currentIndex;
36-
}
37-
38-
/* Converts RMT durations to an array of rmt_item32_t */
39-
void ConvertRmtValuesToRmtObjects(int16_t rmtValues[], int16_t rmtValuesCount, rmt_item32_t rmtObjects[], int16_t *rmtObjectsCount)
40-
{
41-
int16_t rmtObjectsIndex = 0;
42-
bool isFirstPartOfRmtObjectOccupied = false;
43-
44-
for (int16_t i = 0; i < rmtValuesCount; i++)
45-
{
46-
if (isFirstPartOfRmtObjectOccupied == false)
47-
{
48-
rmtObjects[rmtObjectsIndex].duration0 = abs(rmtValues[i]);
49-
rmtObjects[rmtObjectsIndex].level0 = (rmtValues[i] > 0) ? 0 : 1;
50-
isFirstPartOfRmtObjectOccupied = true;
51-
52-
rmtObjects[rmtObjectsIndex].duration1 = 0;
53-
rmtObjects[rmtObjectsIndex].level1 = 0;
54-
}
55-
else
56-
{
57-
rmtObjects[rmtObjectsIndex].duration1 = abs(rmtValues[i]);
58-
rmtObjects[rmtObjectsIndex].level1 = (rmtValues[i] > 0) ? 0 : 1;
59-
rmtObjectsIndex++;
60-
isFirstPartOfRmtObjectOccupied = false;
61-
}
62-
}
63-
*rmtObjectsCount = rmtObjectsIndex + 1;
64-
}
65-
66-
/* Add the bytes and their complements to the RmtArray */
67-
void AddBytesToRmtArray(uint8_t data[], uint8_t lengthOfData, int16_t rmtValues[], int16_t rmtValuesIndex, int16_t *rmtCount)
68-
{
69-
int16_t rmtValueIndex = rmtValuesIndex;
70-
71-
for (int8_t i = 0; i < lengthOfData; i++)
72-
{
73-
ConvertByteToMideaRmtValues(data[i], rmtValues, rmtValueIndex, &rmtValueIndex);
74-
int8_t flipped = (int8_t) ~data[i];
75-
ConvertByteToMideaRmtValues(flipped, rmtValues, rmtValueIndex, &rmtValueIndex);
76-
}
77-
*rmtCount = rmtValueIndex;
78-
}
79-
80-
/* Send the message using RMT */
81-
void rmt_midea_ir_tx_send_raw_message(uint8_t data[], uint8_t lengthOfData)
82-
{
83-
int16_t rmtValues[200] = { 0 };
84-
int16_t rmtValueIndex = -1;
85-
86-
// #pragma region Add the whole message to the RmtArray for the first time
87-
88-
// The AGC burst consists of a 4.5ms burst followed by 4.5ms space (8T pulse + 8T space)
89-
// frame start markers 4T down, 4T up
90-
rmtValues[0] = 8*PULSE_LENGTH;
91-
rmtValues[1] = -8*PULSE_LENGTH;
92-
93-
rmtValueIndex = 1;
94-
95-
// add the bytes and its complements to the RmtArray
96-
AddBytesToRmtArray(data, lengthOfData, rmtValues, rmtValueIndex, &rmtValueIndex);
97-
98-
// add the end of frame marker to the RmtArray
99-
rmtValueIndex++;
100-
rmtValues[rmtValueIndex] = PULSE_LENGTH;
101-
rmtValueIndex++;
102-
rmtValues[rmtValueIndex] = -9*PULSE_LENGTH;
103-
104-
// #pragma endregion
105-
106-
// #pragma region Add the whole message to the RmtArray again
107-
108-
// frame start markers 4T down, 4T up
109-
rmtValueIndex++;
110-
rmtValues[rmtValueIndex] = 8*PULSE_LENGTH;
111-
rmtValueIndex++;
112-
rmtValues[rmtValueIndex] = -8*PULSE_LENGTH;
113-
114-
// add the bytes and its complements to the RmtArray
115-
AddBytesToRmtArray(data, lengthOfData, rmtValues, rmtValueIndex, &rmtValueIndex);
116-
117-
// add the end of frame marker to the RmtArray
118-
rmtValueIndex++;
119-
rmtValues[rmtValueIndex] = PULSE_LENGTH;
120-
rmtValueIndex++;
121-
rmtValues[rmtValueIndex] = 0;
122-
123-
// #pragma endregion
124-
125-
rmt_item32_t rmtObjects[100];
126-
int16_t rmtObjectsCount;
127-
ConvertRmtValuesToRmtObjects(rmtValues, rmtValueIndex + 1, rmtObjects, &rmtObjectsCount);
128-
129-
rmt_write_items(_rmt_midea_ir_tx_channel, rmtObjects, rmtObjectsCount, true);
130-
}
131-
132-
/* Initialize RMT transmit channel */
133-
void rmt_midea_ir_tx_channel_init(uint8_t channel, uint8_t txPin)
134-
{
135-
_rmt_midea_ir_tx_channel = channel;
136-
_rmt_midea_ir_tx_txPin = txPin;
137-
138-
rmt_config_t rmt_tx;
139-
140-
rmt_tx.channel = channel;
141-
rmt_tx.gpio_num = txPin;
142-
rmt_tx.clk_div = 80; // 1 MHz, 1 us - we set up sampling to every 1 microseconds
143-
rmt_tx.mem_block_num = 2;
144-
rmt_tx.rmt_mode = RMT_MODE_TX;
145-
rmt_tx.tx_config.loop_en = false;
146-
rmt_tx.tx_config.carrier_duty_percent = 25;
147-
rmt_tx.tx_config.carrier_freq_hz = 38000;
148-
rmt_tx.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
149-
rmt_tx.tx_config.carrier_en = true;
150-
rmt_tx.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH;
151-
rmt_tx.tx_config.idle_output_en = true;
152-
153-
rmt_config(&rmt_tx);
154-
rmt_driver_install(rmt_tx.channel, 0, 0);
155-
156-
// start the channel
157-
rmt_tx_start(_rmt_midea_ir_tx_channel, 1);
158-
}
159-
160-
/* Uninstall the RMT driver */
161-
void rmt_midea_ir_tx_channel_stop(uint8_t channel)
162-
{
163-
rmt_driver_uninstall(channel);
1+
#include "esp32_rmt_midea_ir_tx.h"
2+
3+
#define PULSE_LENGTH 557; // Each pulse (one "time" unit or 1T) is 21 cycles of a 38KHz carrier burst (about 550µs long)
4+
5+
volatile uint8_t _rmt_midea_ir_tx_txPin;
6+
volatile uint8_t _rmt_midea_ir_tx_channel;
7+
8+
/*
9+
Convert a byte to its midea-protocol encoded counterpart as a RMT duration
10+
Idea borrowed from here: https://github.com/kimeckert/ESP32-RMT-Rx-raw
11+
*/
12+
void ConvertByteToMideaRmtValues(uint8_t byteValue, int16_t rmtValues[], int16_t rmtValuesIndex, int16_t *rmtCount)
13+
{
14+
// A logic "1" is a 1T pulse followed by a 3T space and takes 2.25ms to transmit
15+
// A logic "0" is a 1T pulse followed by a 1T space and takes 1.125ms
16+
17+
int16_t currentIndex = rmtValuesIndex;
18+
19+
for (int8_t j = 7; j >= 0; j--)
20+
{
21+
currentIndex++;
22+
rmtValues[currentIndex] = 1*PULSE_LENGTH; // 1T pulse
23+
currentIndex++;
24+
25+
int8_t currentBitValue = (byteValue >> j) & 1;
26+
if (currentBitValue == 1)
27+
{
28+
rmtValues[currentIndex] = -3*PULSE_LENGTH; // 3T space
29+
}
30+
else
31+
{
32+
rmtValues[currentIndex] = -1*PULSE_LENGTH; // 1T space
33+
}
34+
}
35+
*rmtCount = currentIndex;
36+
}
37+
38+
/* Converts RMT durations to an array of rmt_item32_t */
39+
void ConvertRmtValuesToRmtObjects(int16_t rmtValues[], int16_t rmtValuesCount, rmt_item32_t rmtObjects[], int16_t *rmtObjectsCount)
40+
{
41+
int16_t rmtObjectsIndex = 0;
42+
bool isFirstPartOfRmtObjectOccupied = false;
43+
44+
for (int16_t i = 0; i < rmtValuesCount; i++)
45+
{
46+
if (isFirstPartOfRmtObjectOccupied == false)
47+
{
48+
rmtObjects[rmtObjectsIndex].duration0 = abs(rmtValues[i]);
49+
rmtObjects[rmtObjectsIndex].level0 = (rmtValues[i] > 0) ? 0 : 1;
50+
isFirstPartOfRmtObjectOccupied = true;
51+
52+
rmtObjects[rmtObjectsIndex].duration1 = 0;
53+
rmtObjects[rmtObjectsIndex].level1 = 0;
54+
}
55+
else
56+
{
57+
rmtObjects[rmtObjectsIndex].duration1 = abs(rmtValues[i]);
58+
rmtObjects[rmtObjectsIndex].level1 = (rmtValues[i] > 0) ? 0 : 1;
59+
rmtObjectsIndex++;
60+
isFirstPartOfRmtObjectOccupied = false;
61+
}
62+
}
63+
*rmtObjectsCount = rmtObjectsIndex + 1;
64+
}
65+
66+
/* Add the bytes and their complements to the RmtArray */
67+
void AddBytesToRmtArray(uint8_t data[], uint8_t lengthOfData, int16_t rmtValues[], int16_t rmtValuesIndex, int16_t *rmtCount)
68+
{
69+
int16_t rmtValueIndex = rmtValuesIndex;
70+
71+
for (int8_t i = 0; i < lengthOfData; i++)
72+
{
73+
ConvertByteToMideaRmtValues(data[i], rmtValues, rmtValueIndex, &rmtValueIndex);
74+
int8_t flipped = (int8_t) ~data[i];
75+
ConvertByteToMideaRmtValues(flipped, rmtValues, rmtValueIndex, &rmtValueIndex);
76+
}
77+
*rmtCount = rmtValueIndex;
78+
}
79+
80+
/* Send the message using RMT */
81+
void rmt_midea_ir_tx_send_raw_message(uint8_t data[], uint8_t lengthOfData)
82+
{
83+
int16_t rmtValues[200] = { 0 };
84+
int16_t rmtValueIndex = -1;
85+
86+
// #pragma region Add the whole message to the RmtArray for the first time
87+
88+
// The AGC burst consists of a 4.5ms burst followed by 4.5ms space (8T pulse + 8T space)
89+
// frame start markers 4T down, 4T up
90+
rmtValues[0] = 8*PULSE_LENGTH;
91+
rmtValues[1] = -8*PULSE_LENGTH;
92+
93+
rmtValueIndex = 1;
94+
95+
// add the bytes and its complements to the RmtArray
96+
AddBytesToRmtArray(data, lengthOfData, rmtValues, rmtValueIndex, &rmtValueIndex);
97+
98+
// add the end of frame marker to the RmtArray
99+
rmtValueIndex++;
100+
rmtValues[rmtValueIndex] = PULSE_LENGTH;
101+
rmtValueIndex++;
102+
rmtValues[rmtValueIndex] = -9*PULSE_LENGTH;
103+
104+
// #pragma endregion
105+
106+
// #pragma region Add the whole message to the RmtArray again
107+
108+
// frame start markers 4T down, 4T up
109+
rmtValueIndex++;
110+
rmtValues[rmtValueIndex] = 8*PULSE_LENGTH;
111+
rmtValueIndex++;
112+
rmtValues[rmtValueIndex] = -8*PULSE_LENGTH;
113+
114+
// add the bytes and its complements to the RmtArray
115+
AddBytesToRmtArray(data, lengthOfData, rmtValues, rmtValueIndex, &rmtValueIndex);
116+
117+
// add the end of frame marker to the RmtArray
118+
rmtValueIndex++;
119+
rmtValues[rmtValueIndex] = PULSE_LENGTH;
120+
rmtValueIndex++;
121+
rmtValues[rmtValueIndex] = 0;
122+
123+
// #pragma endregion
124+
125+
rmt_item32_t rmtObjects[100];
126+
int16_t rmtObjectsCount;
127+
ConvertRmtValuesToRmtObjects(rmtValues, rmtValueIndex + 1, rmtObjects, &rmtObjectsCount);
128+
129+
rmt_write_items(_rmt_midea_ir_tx_channel, rmtObjects, rmtObjectsCount, true);
130+
}
131+
132+
/* Initialize RMT transmit channel */
133+
void rmt_midea_ir_tx_channel_init(uint8_t channel, uint8_t txPin)
134+
{
135+
_rmt_midea_ir_tx_channel = channel;
136+
_rmt_midea_ir_tx_txPin = txPin;
137+
138+
rmt_config_t rmt_tx;
139+
140+
rmt_tx.channel = channel;
141+
rmt_tx.gpio_num = txPin;
142+
rmt_tx.clk_div = 80; // 1 MHz, 1 us - we set up sampling to every 1 microseconds
143+
rmt_tx.mem_block_num = 2;
144+
rmt_tx.rmt_mode = RMT_MODE_TX;
145+
rmt_tx.tx_config.loop_en = false;
146+
rmt_tx.tx_config.carrier_duty_percent = 25;
147+
rmt_tx.tx_config.carrier_freq_hz = 38000;
148+
rmt_tx.tx_config.carrier_level = RMT_CARRIER_LEVEL_LOW;
149+
rmt_tx.tx_config.carrier_en = true;
150+
rmt_tx.tx_config.idle_level = RMT_IDLE_LEVEL_HIGH;
151+
rmt_tx.tx_config.idle_output_en = true;
152+
153+
rmt_config(&rmt_tx);
154+
rmt_driver_install(rmt_tx.channel, 0, 0);
155+
156+
// start the channel
157+
rmt_tx_start(_rmt_midea_ir_tx_channel, 1);
158+
}
159+
160+
/* Uninstall the RMT driver */
161+
void rmt_midea_ir_tx_channel_stop(uint8_t channel)
162+
{
163+
rmt_driver_uninstall(channel);
164164
}

0 commit comments

Comments
 (0)