8000 [Feature] Added Sonoff DUALR3 support with RainMaker example (#5980) · tcumpston/arduino-esp32@fa03966 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fa03966

Browse files
authored
[Feature] Added Sonoff DUALR3 support with RainMaker example (espressif#5980)
* [Feature] Added Sonoff DUALR3 support with RainMaker example * [Feature] Added skip files for C3 and S2
1 parent 3750b14 commit fa03966

File tree

5 files changed

+321
-0
lines changed

5 files changed

+321
-0
lines changed

boards.txt

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10042,3 +10042,104 @@ franzininho_wifi_msc_esp32s2.menu.DebugLevel.verbose=Verbose
1004210042
franzininho_wifi_msc_esp32s2.menu.DebugLevel.verbose.build.code_debug=5
1004310043

1004410044
##############################################################
10045+
10046+
sonoff_dualr3.name=Sonoff DUALR3
10047+
10048+
sonoff_dualr3.upload.tool=esptool_py
10049+
sonoff_dualr3.upload.maximum_size=1310720
10050+
sonoff_dualr3.upload.maximum_data_size=327680
10051+
sonoff_dualr3.upload.flags=
10052+
sonoff_dualr3.upload.extra_flags=
10053+
10054+
sonoff_dualr3.serial.disableDTR=true
10055+
sonoff_dualr3.serial.disableRTS=true
10056+
10057+
sonoff_dualr3.build.tarch=xtensa
10058+
sonoff_dualr3.build.bootloader_addr=0x1000
10059+
sonoff_dualr3.build.target=esp32
10060+
sonoff_dualr3.build.mcu=esp32
10061+
sonoff_dualr3.build.core=esp32
10062+
sonoff_dualr3.build.variant=esp32
10063+
sonoff_dualr3.build.board=SONOFF_DUALR3
10064+
10065+
sonoff_dualr3.build.f_cpu=240000000L
10066+
sonoff_dualr3.build.flash_size=4MB
10067+
sonoff_dualr3.build.flash_freq=40m
10068+
sonoff_dualr3.build.flash_mode=dio
10069+
sonoff_dualr3.build.boot=dio
10070+
sonoff_dualr3.build.partitions=rainmaker
10071+
sonoff_dualr3.build.defines=
10072+
sonoff_dualr3.build.loop_core=
10073+
sonoff_dualr3.build.event_core=
10074+
10075+
sonoff_dualr3.menu.PartitionScheme.rainmaker=RainMaker
10076+
sonoff_dualr3.menu.PartitionScheme.rainmaker.build.partitions=rainmaker
10077+
sonoff_dualr3.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728
10078+
10079+
sonoff_dualr3.menu.CPUFreq.240=240MHz (WiFi/BT)
10080+
sonoff_dualr3.menu.CPUFreq.240.build.f_cpu=240000000L
10081+
sonoff_dualr3.menu.CPUFreq.160=160MHz (WiFi/BT)
10082+
sonoff_dualr3.menu.CPUFreq.160.build.f_cpu=160000000L
10083+
sonoff_dualr3.menu.CPUFreq.80=80MHz (WiFi/BT)
10084+
sonoff_dualr3.menu.CPUFreq.80.build.f_cpu=80000000L
10085+
sonoff_dualr3.menu.CPUFreq.40=40MHz (40MHz XTAL)
10086+
sonoff_dualr3.menu.CPUFreq.40.build.f_cpu=40000000L
10087+
sonoff_dualr3.menu.CPUFreq.26=26MHz (26MHz XTAL)
10088+
sonoff_dualr3.menu.CPUFreq.26.build.f_cpu=26000000L
10089+
sonoff_dualr3.menu.CPUFreq.20=20MHz (40MHz XTAL)
10090+
sonoff_dualr3.menu.CPUFreq.20.build.f_cpu=20000000L
10091+
sonoff_dualr3.menu.CPUFreq.13=13MHz (26MHz XTAL)
10092+
sonoff_dualr3.menu.CPUFreq.13.build.f_cpu=13000000L
10093+
sonoff_dualr3.menu.CPUFreq.10=10MHz (40MHz XTAL)
10094+
sonoff_dualr3.menu.CPUFreq.10.build.f_cpu=10000000L
10095+
10096+
sonoff_dualr3.menu.FlashMode.qio=QIO
10097+
sonoff_dualr3.menu.FlashMode.qio.build.flash_mode=dio
10098+
sonoff_dualr3.menu.FlashMode.qio.build.boot=qio
10099+
sonoff_dualr3.menu.FlashMode.dio=DIO
10100+
sonoff_dualr3.menu.FlashMode.dio.build.flash_mode=dio
10101+
sonoff_dualr3.menu.FlashMode.dio.build.boot=dio
10102+
sonoff_dualr3.menu.FlashMode.qout=QOUT
10103+
sonoff_dualr3.menu.FlashMode.qout.build.flash_mode=dout
10104+
sonoff_dualr3.menu.FlashMode.qout.build.boot=qout
10105+
sonoff_dualr3.menu.FlashMode.dout=DOUT
10106+
sonoff_dualr3.menu.FlashMode.dout.build.flash_mode=dout
10107+
sonoff_dualr3.menu.FlashMode.dout.build.boot=dout
10108+
10109+
sonoff_dualr3.menu.FlashFreq.80=80MHz
10110+
sonoff_dualr3.menu.FlashFreq.80.build.flash_freq=80m
10111+
sonoff_dualr3.menu.FlashFreq.40=40MHz
10112+
sonoff_dualr3.menu.FlashFreq.40.build.flash_freq=40m
10113+
10114+
sonoff_dualr3.menu.FlashSize.4M=4MB (32Mb)
10115+
sonoff_dualr3.menu.FlashSize.4M.build.flash_size=4MB
10116+
10117+
sonoff_dualr3.menu.UploadSpeed.921600=921600
10118+
sonoff_dualr3.menu.UploadSpeed.921600.upload.speed=921600
10119+
sonoff_dualr3.menu.UploadSpeed.115200=115200
10120+
sonoff_dualr3.menu.UploadSpeed.115200.upload.speed=115200
10121+
sonoff_dualr3.menu.UploadSpeed.256000.windows=256000
10122+
sonoff_dualr3.menu.UploadSpeed.256000.upload.speed=256000
10123+
sonoff_dualr3.menu.UploadSpeed.230400.windows.upload.speed=256000
10124+
sonoff_dualr3.menu.UploadSpeed.230400=230400
10125+
sonoff_dualr3.menu.UploadSpeed.230400.upload.speed=230400
10126+
sonoff_dualr3.menu.UploadSpeed.460800.linux=460800
10127+
sonoff_dualr3.menu.UploadSpeed.460800.macosx=460800
10128+
sonoff_dualr3.menu.UploadSpeed.460800.upload.speed=460800
10129+
sonoff_dualr3.menu.UploadSpeed.512000.windows=512000
10130+
sonoff_dualr3.menu.UploadSpeed.512000.upload.speed=512000
10131+
10132+
sonoff_dualr3.menu.DebugLevel.none=None
10133+
sonoff_dualr3.menu.DebugLevel.none.build.code_debug=0
10134+
sonoff_dualr3.menu.DebugLevel.error=Error
10135+
sonoff_dualr3.menu.DebugLevel.error.build.code_debug=1
10136+
sonoff_dualr3.menu.DebugLevel.warn=Warn
10137+
sonoff_dualr3.menu.DebugLevel.warn.build.code_debug=2
10138+
sonoff_dualr3.menu.DebugLevel.info=Info
10139+
sonoff_dualr3.menu.DebugLevel.info.build.code_debug=3
10140+
sonoff_dualr3.menu.DebugLevel.debug=Debug
10141+
sonoff_dualr3.menu.DebugLevel.debug.build.code_debug=4
10142+
sonoff_dualr3.menu.DebugLevel.verbose=Verbose
10143+
sonoff_dualr3.menu.DebugLevel.verbose.build.code_debug=5
10144+
10145+
##############################################################

libraries/RainMaker/examples/RMakerSonoffDualR3/.skip.esp32c3

Whitespace-only changes.

libraries/RainMaker/examples/RMakerSonoffDualR3/.skip.esp32s2

Whitespace-only changes.
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
//This example demonstrates the ESP RainMaker with a standard Switch device.
2+
#include "RMaker.h"
3+
#include "WiFi.h"
4+
#include "WiFiProv.h"
5+
6+
#define DEFAULT_POWER_MODE false
7+
const char *service_name = "PROV_SONOFF_DUALR3";
8+
const char *pop = "123456";
9+
10+
// GPIO for push button
11+
static uint8_t gpio_reset = 0;
12+
// GPIO for switch
13+
static uint8_t gpio_switch1 = 32;
14+
static uint8_t gpio_switch2 = 33;
15+
// GPIO for virtual device
16+
static uint8_t gpio_relay1 = 27;
17+
static uint8_t gpio_relay2 = 14;
18+
/* Variable for reading pin status*/
19+
bool switch_state_ch1 = true;
20+
bool switch_state_ch2 = true;
21+
// GPIO for link status LED
22+
static uint8_t gpio_led = 13;
23+
24+
struct LightSwitch {
25+
const uint8_t pin;
26+
bool pressed;
27+
};
28+
29+
// Define the light switches for channel 1 and 2
30+
LightSwitch switch_ch1 = {gpio_switch1, false};
31+
LightSwitch switch_ch2 = {gpio_switch2, false};
32+
33+
//The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
34+
static Switch my_switch1("Switch_ch1", &gpio_relay1);
35+
static Switch my_switch2("Switch_ch2", &gpio_relay2);
36+
37+
void sysProvEvent(arduino_event_t *sys_event)
38+
{
39+
switch (sys_event->event_id) {
40+
case ARDUINO_EVENT_PROV_START:
41+
#if CONFIG_IDF_TARGET_ESP32
42+
Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
43+
printQR(service_name, pop, "ble");
44+
#else
45+
Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
46+
printQR(service_name, pop, "softap");
47+
#endif
48+
break;
49+
case ARDUINO_EVENT_WIFI_STA_CONNECTED:
50+
Serial.printf("\nConnected to Wi-Fi!\n");
51+
digitalWrite(gpio_led, true);
52+
break;
53+
}
54+
}
55+
56+
void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
57+
{
58+
const char *device_name = device->getDeviceName();
59+
const char *param_name = param->getParamName();
60+
61+
if(strcmp(device_name, "Switch_ch1") == 0) {
62+
63+
Serial.printf("Lightbulb = %s\n", val.val.b? "true" : "false");
64+
65+
if(strcmp(param_name, "Power") == 0) {
66+
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
67+
switch_state_ch1 = val.val.b;
68+
(switch_state_ch1 == false) ? digitalWrite(gpio_relay1, LOW) : digitalWrite(gpio_relay1, HIGH);
69+
param->updateAndReport(val);
70+
}
71+
72+
} else if(strcmp(device_name, "Switch_ch2") == 0) {
73+
74+
Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");
75+
76+
if(strcmp(param_name, "Power") == 0) {
77+
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
78+
switch_state_ch2 = val.val.b;
79+
(switch_state_ch2 == false) ? digitalWrite(gpio_relay2, LOW) : digitalWrite(gpio_relay2, HIGH);
80+
param->updateAndReport(val);
81+
}
82+
83+
}
84+
85+
}
86+
87+
void ARDUINO_ISR_ATTR isr(void* arg) {
88+
LightSwitch* s = static_cast<LightSwitch*>(arg);
89+
s->pressed = true;
90+
}
91+
92+
void setup()
93+
{
94+
uint32_t chipId = 0;
95+
96+
Serial.begin(115200);
97+
98+
// Configure the input GPIOs
99+
pinMode(gpio_reset, INPUT);
100+
pinMode(switch_ch1.pin, INPUT_PULLUP);
101+
attachInterruptArg(switch_ch1.pin, isr, &switch_ch1, CHANGE);
102+
pinMode(switch_ch2.pin, INPUT_PULLUP);
103+
attachInterruptArg(switch_ch2.pin, isr, &switch_ch2, CHANGE);
104+
105+
// Set the Relays GPIOs as output mode
106+
pinMode(gpio_relay1, OUTPUT);
107+
pinMode(gpio_relay2, OUTPUT);
108+
pinMode(gpio_led, OUTPUT);
109+
// Write to the GPIOs the default state on booting
110+
digitalWrite(gpio_relay1, DEFAULT_POWER_MODE);
111+
digitalWrite(gpio_relay2, DEFAULT_POWER_MODE);
112+
digitalWrite(gpio_led, false);
113+
114+
Node my_node;
115+
my_node = RMaker.initNode("Sonoff Dual R3");
116+
117+
//Standard switch device
118+
my_switch1.addCb(write_callback);
119+
my_switch2.addCb(write_callback);
120+
121+
//Add switch device to the node
122+
my_node.addDevice(my_switch1);
123+
my_node.addDevice(my_switch2);
124+
125+
//This is optional
126+
RMaker.enableOTA(OTA_USING_PARAMS);
127+
//If you want to enable scheduling, set time zone for your region using setTimeZone().
128+
//The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
129+
// RMaker.setTimeZone("Asia/Shanghai");
130+
// Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
131+
RMaker.enableTZService();
132+
RMaker.enableSchedule();
133+
134+
//Service Name
135+
for(int i=0; i<17; i=i+8) {
136+
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
137+
}
138+
139+
Serial.printf("\nChip ID: %d Service Name: %s\n", chipId, service_name);
140+
141+
Serial.printf("\nStarting ESP-RainMaker\n");
142+
RMaker.start();
143+
144+
WiFi.onEvent(sysProvEvent);
145+
#if CONFIG_IDF_TARGET_ESP32
146+
WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
147+
#else
148+
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
149+
#endif
150+
}
151+
152+
void loop()
153+
{
154+
155+
if (switch_ch1.pressed) {
156+
Serial.printf("Switch 1 has been changed\n");
157+
switch_ch1.pressed = false;
158+
// Toggle switch 1 device state
159+
switch_state_ch1 = !switch_state_ch1;
160+
Serial.printf("Toggle State to %s.\n", switch_state_ch1 ? "true" : "false");
161+
my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, switch_state_ch1);
162+
(switch_state_ch1 == false) ? digitalWrite(gpio_relay1, LOW) : digitalWrite(gpio_relay1, HIGH);
163+
} else if (switch_ch2.pressed) {
164+
Serial.printf("Switch 2 has been changed\n");
165+
switch_ch2.pressed = false;
166+
// Toggle switch 2 device state
167+
switch_state_ch2 = !switch_state_ch2;
168+
Serial.printf("Toggle State to %s.\n", switch_state_ch2 ? "true" : "false");
169+
my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, switch_state_ch2);
170+
(switch_state_ch2 == false) ? digitalWrite(gpio_relay2, LOW) : digitalWrite(gpio_relay2, HIGH);
171+
}
172+
173+
// Read GPIO0 (external button to reset device
174+
if(digitalRead(gpio_reset) == LOW) { //Push button pressed
175+
Serial.printf("Reset Button Pressed!\n");
176+
// Key debounce handling
177+
delay(100);
178+
int startTime = millis();
179+
while(digitalRead(gpio_reset) == LOW) delay(50);
180+
int endTime = millis();
181+
182+
if ((endTime - startTime) > 10000) {
183+
// If key pressed for more than 10secs, reset all
184+
Serial.printf("Reset to factory.\n");
185+
RMakerFactoryReset(2);
186+
} else if ((endTime - startTime) > 3000) {
187+
Serial.printf("Reset Wi-Fi.\n");
188+
// If key pressed for more than 3secs, but less than 10, reset Wi-Fi
189+
RMakerWiFiReset(2);
190+
}
191+
}
192+
delay(100);
193+
}

variants/sonoff_dualr3/pins_arduino.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef Pins_Arduino_h
2+
#define Pins_Arduino_h
3+
4+
#include <stdint.h>
5+
6+
#define EXTERNAL_NUM_INTERRUPTS 16
7+
#define NUM_DIGITAL_PINS 40
8+
#define NUM_ANALOG_INPUTS 16
9+
10+
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
11+
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
12+
#define digitalPinHasPWM(p) (p < 34)
13+
14+
static const uint8_t TX = 1;
15+
static const uint8_t RX = 3;
16+
17+
static const uint8_t BUTTON = 0;
18+
static const uint8_t LED_LINK = 13;
19+
static const uint8_t RELAY_2 = 14;
20+
static const uint8_t RELAY_1 = 27;
21+
static const uint8_t SWITCH_2 = 33;
22+
static const uint8_t SWITCH_1 = 32;
23+
24+
static const uint8_t CSE7761_TX = 25;
25+
static const uint8_t CSE7761_RX = 26;
26+
27+
#endif /* Pins_Arduino_h */

0 commit comments

Comments
 (0)
0