Light sleep wake-up via gpio on esp32 - sleep

I have a simple code for esp32 here. I can only use gpio pin number 35 on the board.
So esp32 should go to light sleep and wake up on button press.
When I run this program below, my esp32 goes into light sleep, but it doesn't wake up when the button is pressed.
What's the problem? Any idea please? Thank you.
#include <esp_sleep.h>
void setup() {
Serial.begin(115200);
delay(2000);
gpio_wakeup_enable(GPIO_NUM_35, GPIO_INTR_HIGH_LEVEL);
esp_sleep_enable_gpio_wakeup();
delay(2000);
Serial.println("Going to sleep now");
delay(2000);
esp_light_sleep_start();
delay(2000);
Serial.println("This will be NOT printed");
}
void loop() {
delay(2000);
Serial.println("Hi after wake up via GPIO Button!");
delay(2000);
}

I've figured out by myself what the trouble was: just change to rtc_io ext0 and set level on 0. Then it will work fine. (Maybe this will be helpful for other users.)

Related

how do i fix it (arduino)

i want to use AT command
but i cant
i use esp8266 wifi shield model
and i connected jumper line
enter image description here
but
#include <SoftwareSerial.h>
SoftwareSerial mySerial(0,1); //RX, TX
void setup() {
Serial.begin(9600);
mySerial.begin(115200);
}
void loop() {
if(mySerial.available())
{
Serial.write(mySerial.read());
}
if(Serial.available())
{
mySerial.write(Serial.read());
}
}
After uploading, there is no response even if I input to the serial monitor.
i had AT command firmware updated
im bad at english sorry

Arduino Project (TRAFFIC LIGHTS) *need ideas*

This is the code I have so far and I need help making the button which is on pin2 of the Arduino have an interrupt where if the lights can cycle on there own and if the button is pressed then it must kick on the yellow LED for 3sec and give the red LED for 10sec for the pedestrian to walk across. The cycle I have set but I need the pushbutton to work and im having difficulties making this work, any suggestions?
CODE
int red = 10;
int yellow = 9;
int green = 8;
int button = 2; // switch is on pin 2
void setup(){
pinMode(red, OUTPUT);
pinMode(yellow, OUTPUT);
pinMode(green, OUTPUT);
pinMode(button, INPUT);
digitalWrite(green, HIGH);
}
void loop() {
if (digitalRead(button) == HIGH){
delay(15); // software debounce
if (digitalRead(button) == HIGH) {
// if the switch is LOW change the lights
changeLights();
delay(1000); // wait for 1 second
}
}
}
void changeLights(){
// RED ON for 5 sec
digitalWrite(red, HIGH);
digitalWrite(yellow, LOW);
digitalWrite(green, LOW);
delay(5000);
// GREEN ON for 5 sec
digitalWrite(red, LOW);
digitalWrite(yellow, LOW);
digitalWrite(green, HIGH);
delay(5000);
// YELOOW ON for 3 sec
digitalWrite(red, LOW);
digitalWrite(yellow, HIGH);
digitalWrite(green, LOW);
delay(3000);
}
This is Arduinos example code for external interrupts:
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}
void loop() {
digitalWrite(ledPin, state);
}
void blink() {
state = !state;
}
If the state of pinput pin interruptPin changes the microcontroller will service that interrupt calling blink. then it jumps back to into the application where it was interrupted.
So attach an interrupt service routine to your button pin and store in a variable the information that you should start the yellow red phase at the next chance.
as the yellow red phase usually cannot be interrupted you can use blocking code like delay to time it if your program is not controlling anything elss in the meantime.

ESP32 unable to detect interrupt

The code below is suppose to detect a pulse from a rain gauge. It is working in esp8266 but not in esp32 nodemcu. The logic seems fine I suppose I did something wrong while define the pin?
const int interruptPin = 18;
volatile boolean interrupt = false;
const int led = 2 ;
void setup() {
Serial.begin(115200);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), ISR, FALLING);
pinMode(led,OUTPUT);
digitalWrite(led, LOW);
}
void loop() {
if (interrupt == true) {
Serial.println("An interrupt occurred");
delay(500);
digitalWrite(led, LOW);
interrupt = false;
}
delay(1000);
}
IRAM_ATTR void ISR () {
digitalWrite(led, HIGH);
interrupt = true;
}

RPi + ESP8266 stability issues

I was recently working on a home automation project which has finally come to end and I am thinking to install it in my home. First of all, I would like to brief you with the basic architecture.
I am using a Raspberry Pi 3 as the central controller node which is running Node-Red and its Mosca palette. Currently, there are 5 ESP-01 in the project. Four of them are wired up with a relay and the remaining ESP is wired up with a DHT11 temperature sensor. Almost everything is running good but I am facing some stability issues, like, when I recycle the power the ESP-01 doesn't run the program. Serial monitor stays blank. However, when I disconnect the GPIO2 from the relay and then power up the ESP. The program begins. So, I have to pull out the GPIO2 then power up the ESP then connect the GPIO2 with the relay on every power recycle. Another problem which I am facing is sometimes the ESP crashes automatically. It sometimes prints out fatal exception(0) or soft wdt reset even though I have added a watchdog timer.
Here is the code for one of the client ESP:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "........";
const char* password = ".........";
const int led = 13;
const char* mqtt_server = "192.168.1.8";
WiFiClient espClient;
PubSubClient client(espClient);
const int ledGPIO2 = 2;
void setup_wifi() {
int i;
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("WIFI BEGUN");
while (WiFi.status() != WL_CONNECTED) {
ESP.wdtFeed();
delay(500);
i++;
if ((i&0x01)==0){
digitalWrite(led, 0);
} else {
digitalWrite(led, 1); // led should start blinking at .5 seconds
}
Serial.print(".");
if (i>1000) break; // get out after 50 seconds
if (i==1000){
}
Serial.print(".");
Serial.println("");
Serial.print("WiFi connected - ESP IP address: ");
Serial.println(WiFi.localIP());
}
}
void callback(String topic, byte* message, unsigned int length) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < length; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
if(topic=="Lamp1"){
Serial.print("Changing GPIO 2 to ");
if(messageTemp == "on"){
digitalWrite(ledGPIO2, HIGH);
Serial.print("On");
}
else if(messageTemp == "off"){
digitalWrite(ledGPIO2, LOW);
Serial.print("Off");
}
}
Serial.println();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP8266Client")) {
Serial.println("connected");
client.subscribe("Lamp1");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
pinMode(ledGPIO2, OUTPUT);
digitalWrite(ledGPIO2, true);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
if(!client.loop())
client.connect("ESP8266Client");
}
Also, I have been thinking for an efficient power supply for ESP. Batteries cannot be reliable for long-term and powering up via an adapter would be unfeasible as the module is going to be mounted on the wall. Moreover, ac to dc converter was something which seems to be a decent way for power supply.
Vcc - 3.3V
CH_PD - 3.3V
Tx - Tx (Arduino)
Rx - Rx (Arduino)
GPIO0 - GND (while uploading the sketch)/ 3.3V
GND - GND
I am not using capacitors or resistors. I am getting a 5V supply from Arduino which is regulated to 3.3V using LD33V voltage regulator.
Any suggestions would be appreciated. Thank You!!

Why am I getting the same performance from Hardware Serial and Software Serial?

I'm trying to interface (1) LinkSprite JPEG Color Camera TTL Interface - Infrared and (2) Arduino Mega 2560 connected to my laptop. While I am able to print the HEX values of the images, it takes about 30 seconds to print 1 image to the monitor. I thought that it was because I was using SoftwareSerial, so I tried HardwareSerial, but still, 30 seconds per image. Shouldn't it be faster using HardwareSerial? Just wondering, do I need a special cable connecting the arduino to my laptop?
I tried different combinations of baud rates for Serial and Serial1. (Serial.begin(9600), Serial1.begin(38400)), (Serial.begin(38400), Serial1.begin(38400)) etc... This doesn't work when I set Serial1 anything higher than 38400. (It should be able to go higher..) Also, do I have to increase baud rate by a certain interval namely, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 250000?
#include <SoftwareSerial.h>
byte incomingbyte;
//Configure pin 2 and 3 as soft serial port
//SoftwareSerial Serial1 = SoftwareSerial(2, 3);
int a=0x0000, //Read Starting address
j=0,
k=0,
count=0;
uint8_t MH,ML;
boolean EndFlag=0;
void setup() {
Serial.begin(115200);
Serial1.begin(38400); //made changes in ChangeBaudRate()
ChangeBaudRate();[enter image description here][1]
SendResetCmd();
delay(3000);
}
void loop() {
SendTakePhotoCmd();
Serial.println("Start pic");
delay(100);
while(Serial1.available()>0) {
incomingbyte=Serial1.read();
}
byte b[32];
while(!EndFlag) {
j=0;
k=0;
count=0;
SendReadDataCmd();
delay(75); //try going up
while(Serial1.available()>0) {
incomingbyte=Serial1.read();
k++;
if((k>5)&&(j<32)&&(!EndFlag)) {
b[j]=incomingbyte;
if((b[j-1]==0xFF)&&(b[j]==0xD9))
EndFlag=1;
j++;
count++;
}
}
for(j=0;j<count;j++) {
if(b[j]<0x10)
Serial.print("0");
Serial.print(b[j], HEX);
}
Serial.println();
}
delay(3000);
StopTakePhotoCmd(); //stop this picture so another one can be taken
EndFlag = 0; //reset flag to allow another picture to be read
Serial.println("End of pic");
Serial.println();
while(1);
}
//Send Reset command
void SendResetCmd() {
Serial1.write((byte)0x56);
Serial1.write((byte)0x00);
Serial1.write((byte)0x26);
Serial1.write((byte)0x00);
}
//Send take picture command
void SendTakePhotoCmd() {
Serial1.write((byte)0x56);
Serial1.write((byte)0x00);
Serial1.write((byte)0x36);
Serial1.write((byte)0x01);
Serial1.write((byte)0x00);
a = 0x0000; //reset so that another picture can taken
}
void FrameSize() {
Serial1.write((byte)0x56);
Serial1.write((byte)0x00);
Serial1.write((byte)0x34);
Serial1.write((byte)0x01);
Serial1.write((byte)0x00);
}
//Read data
void SendReadDataCmd() {
MH=a/0x100;
ML=a%0x100;
Serial1.write((byte)0x56);
Serial1.write((byte)0x00);
Serial1.write((byte)0x32);
Serial1.write((byte)0x0c);
Serial1.write((byte)0x00);
Serial1.write((byte)0x0a);
Serial1.write((byte)0x00);
Serial1.write((byte)0x00);
Serial1.write((byte)MH);
Serial1.write((byte)ML);
Serial1.write((byte)0x00);
Serial1.write((byte)0x00);
Serial1.write((byte)0x00);
Serial1.write((byte)0x20);
Serial1.write((byte)0x00);
Serial1.write((byte)0x0a);
a+=0x20;
}
void StopTakePhotoCmd() {
Serial1.write((byte)0x56);
Serial1.write((byte)0x00);
Serial1.write((byte)0x36);
Serial1.write((byte)0x01);
Serial1.write((byte)0x03);
}
void ChangeBaudRate(){
Serial1.write((byte)0x56);
Serial1.write((byte)0x00);
Serial1.write((byte)0x24);
Serial1.write((byte)0x03);
Serial1.write((byte)0x01);
Serial1.write((byte)0x0D); // 115200 = 0x0D 0xA6
Serial1.write((byte)0xA6);
Serial1.end(); // Not really necessary
Serial1.begin( 115200 ); // change to match the camera's new baud rate
}
Yes, the baud rate between the Arduino and the camera is the determining factor. The baud rate between the Arduino and the PC (i.e., the Serial Monitor window) is 9600, but you can change that to 115200 in the code with Serial.begin(115200); and in the Serial Monitor window (pulldown in corner).
The default baud rate between the Arduino and the camera is 38400. While at that baud rate, you can send the "Change Baud Rate" command (section 9 on page 6/10 of the spec). That seems to be the purpose of this routine:
void ChangeBaudRate(){
Serial1.write((byte)0x56);
Serial1.write((byte)0x00);
Serial1.write((byte)0x24);
Serial1.write((byte)0x03);
Serial1.write((byte)0x01);
Serial1.write((byte)0x1c);
Serial1.write((byte)0x4c);
}
According to the spec, this sets the new baud rate to 57600. You could choose 115200 by changing the last two bytes to 0x0D and 0xA6. Then you have to set Serial1 to the new baud rate:
void ChangeBaudRate(){
Serial1.write((byte)0x56);
Serial1.write((byte)0x00);
Serial1.write((byte)0x24);
Serial1.write((byte)0x03);
Serial1.write((byte)0x01);
Serial1.write((byte)0x0D); // 115200 = 0x0D 0xA6
Serial1.write((byte)0xA6);
Serial1.end(); // Not really necessary
Serial1.begin( 115200 ); // change to match the camera's new baud rate
}

Resources