Skip to content

Commit fa03966

Browse files
authored
[Feature] Added Sonoff DUALR3 support with RainMaker example (#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

Diff for: boards.txt

+101
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+
##############################################################

Diff for: libraries/RainMaker/examples/RMakerSonoffDualR3/.skip.esp32c3

Whitespace-only changes.

Diff for: libraries/RainMaker/examples/RMakerSonoffDualR3/.skip.esp32s2

Whitespace-only changes.
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+
}

Diff for: variants/sonoff_dualr3/pins_arduino.h

+27
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)