This is not quite what I meant, but if you want to send the Core to sleep after the first publish, but not earlier than 30sec after last wake, then yes, you can do that too.
I might understand you wrong, but I though that you mean that:
and this can be done by doing this line:
And for this one:
For this, I can do:
Therefore, I'll try to think more deeper about doing that but not in the same loop as I though in my last post, because I want my code to stay connect to the cloud and publish the data whenever there is a data coming from Serial2 and not go to sleep unless there is no data from Serial2.
@ScruffR
Edit: Does this condition solve the issue?
while ( !Serial2.available() && idx >= 38 && millis() - msPublish > 1000)
{
Spark.sleep(D0,RISING);
}
Or I might just need to put the condition when Serial2 is not available?
// test for https://community.particle.io/t/the-core-didnt-connect-to-the-cloud-after-waking-up-from-a-pin-triggered-sleep/13907
//#include "application.h"
#include "Serial2/Serial2.h"
const int wakePin = D0; // use Serial2 RX pin as wake pin
char szReceive[64] = { '\0' };
int idx = 0;
uint32_t ms;
uint32_t msPublish;
uint32_t msLastSerial;
bool frameStart = false;
void setup()
{
pinMode(wakePin, INPUT_PULLDOWN);
Serial.begin(115200);
if(digitalRead(wakePin)) // if pin is held HIGH wait for OTA eternally
while(true)
{
Spark.process();
Serial.println("Waiting for OTA");
}
Serial2.begin(19200);
msLastSerial = millis();
}
void loop()
{
ms = millis();
Serial2.flush();
idx = 0;
while (idx < 38 && millis() - ms < 1000 )
{
if(Serial2.available())
{
msLastSerial = millis();
char c = Serial2.read();
Serial.write(c);
if (c == 'S')
{
frameStart = TRUE;
idx = 0;
}
if (frameStart)
{
szReceive[idx++] = c;
szReceive[idx] = '\0';
}
}
}
Serial.println("Fallen out of while");
if (idx >= 38 && millis() - msPublish > 1000)
{
Serial.println(szReceive);
Spark.publish("Carpet1", szReceive, PRIVATE);
msPublish = millis();
idx = 0;
frameStart = FALSE;
}
else
Serial.println(" Timed out");
if (millis() - msLastSerial > 5000) // stay awake 5sec after last serial byte
Spark.sleep(wakePin, RISING);
}
And for this reason
You might consider using SEMI_AUTOMATIC to catch as much of your serial transmission as possible and only after you captured a full packet avtually connect and publish.
For this I'll let you investigate the system modes a bit
Thanks @ScruffR
I flashed this code to my device and this what is happening for now:
1- At the beginning, the device is flashed successfully with your code, and it is connected to the cloud but it stayed online even with no input from Serial2.
2- After that, I press the RST button to see if this will happen each time or not. Fortunately, after the restart, the device waited for 5 second, and when there is no input from Serial2, it went to sleep.
3- Finally, I plug the Serial2 input (Pin D0) and the device woke up successfully from the sleep, connected to the cloud, and started working, but the core didnāt go to sleep again when I unplug the input from Serial2 !
Does this mean the code will not let the core go to sleep again until it receives the whole (38 byte) frame? Or the code should wait to check if there is no data from Serial2 , and go to sleep again?
Edit: One more update is that I couldnāt see any published data at the Particle Dashboard when I supplied the core from external power, but sometimes I do see published data when I supplied the core from USB.
@ScruffR
Actually I noticed a weird behavior from the spark core. When Iām using Serial1 instead of Serial2 and disable the Sleep part in the code, the core works perfectly and it is publish the data to the dashboard with the power from USB or from external power supply. Does this mean that the D0 pin for Serial2 is unstable? OR it means that the sleep function is not stable?
@ScruffR
Edit: I tried to work with the code to see which portion is causing the instability, and I discovered that when I comment this part the core start working normally without being unstable:
//if(digitalRead(wakePin)) // if pin is held HIGH wait for OTA eternally
//while(true)
//{
//Spark.process();
//Serial.println("Waiting for OTA");
//}
Actually, the core started to go to sleep again if I unplug the D0 pin. All of this magic happened after I comment the above part of the code
Thank you so much.
In this case youād need to use a different pin for the OTA loop to make sure youāll keep being able to flash OTA
e.g.
const int LED = D7;
const int otaPin = D6; // pin to force code into an OTA loop
...
void setup()
{
pinMode(LED, OUTPUT);
pinMode(otaPin, INPUT_PULLDOWN);
...
if(digitalRead(otaPin)) // if pin is held HIGH wait for OTA eternally
{
while(true)
{
digitalWrite(LED, millis() & 0x0100); // flip every 256ms
Spark.process();
}
}
...
}
Did you understand what the previous version of this part did and why it caused the behaviour you saw?
It would be crucial to build up that kind of skill to read and understand the meaning of the code you use before youāll be able to write your own working code.
Thanks for this explanation @ScruffR
What I understood from this part of the code is Iāll need a pin to enable me to flash the core when I have a modification on the code, so Iāll not need to do a factory reset or download a tinker before flashing the modified code. But, how can the code give value to D6 to make it High (to enter to the OTA loop)?
Also for this reason, the core was not going to sleep again if I unplug the D0 pin, is that correct?
But Iām not understanding is why the core could sometimes publish the data when it is on USB power, while it couldnāt publish when it was taking the power from the external source? Also, there was another weird behavior that I saw yesterday. When I could see the publish data (supply the core through the USB), the PC that Iām using to supply the power was starting to be uncontrolled and the pages or the softwares that Iām opening is pop up and pop down in a strange way. Therefore, I should unplug the power cable to stop that. Do you have an explanation for that? Iāll try to updload the video for this strange behavior.
Thanks in advance.
Yes, I do have explanations for some of the things you see
The odd PC behaviour must have been while the Core got trapped in the tight OTA loop, permanently printing out the serial message - thatās why I replaced it with an LED blink.
Some more info can be found in this forum - one of the topics Issues using serial debugging (Mouse moving)
The reason for the Core sometimes going to sleep and other times not at all has to do with the OTA loop and the use od D0 as OTA trigger as well.
If the sender has sent a HIGH bit in the very moment the if pin was read to enter the loop the Core got trapped and never would go to sleep, otherwise the Core would just jump that part and carry on as usual.
To pull D6 high you donāt use code but hardware. Attach a button between D6 and 3V3. When you close the switch the Core will get trapped for OTA, if itās open, the pull-down will ensure normal code flow.
For the other questions Iād need more insight in your actual hardware setup (non USB power source, common ground, behaviour of your sender, ā¦)
Thanks @ScruffR
Thatās very clear now. I have another question about the D6 pin. Can I use a MODE button which is built on the core to control the core or in other word, does the MODE button is connected internally to one of the Pins inside the core?
I appreciated all of your help.
Thanks for responding to me. I probably search in the forum to find some answers to my question, but I asked you since you have a great experience with the core as I saw from your explanation.
Have a great day.
Thanks again.
Ahmed.