SpenceKonde / ATTinyCore

Arduino core for ATtiny 1634, 828, x313, x4, x41, x5, x61, x7 and x8
Other
1.59k stars 308 forks source link

Can support WakeUp by UART Rx ? #246

Closed nagaokashi closed 6 years ago

nagaokashi commented 6 years ago

Thank you for great source. I did a program on ATTiny85, transceives data from/to a BLE module using UART. Everything works fine. Now I want to put ATTiny85 to sleep then wake up by UART Rx event. But it did not work. It seems to be lost Rx data. Before going to depth debug, may I ask that This Library can support to receive the first char from UART on interrupt ?

sleemanj commented 6 years ago

UART wakeup only works from IDLE sleep mode from memory, maybe ADC Noise Reduciton too, consult the datasheet.

sleemanj commented 6 years ago

Actually, of course the Tiny85 does not have a UART, serial on this chip is implemented in software.

Since the Software Serial uses the analog comparator interrupt, it's that interrupt that will have to be the wakeup source I expect. And as per the datasheet this is only active in IDLE mode. So, yes, you can probably use IDLE mode, but not any deeper sleeps.

(this is also try generally speaking for hardware uart chips, only IDLE mode will wake from serial input)

nagaokashi commented 6 years ago

Thank you. Can this library support to cache up the first coming data on interrupt from IDLE sleep?

sleemanj commented 6 years ago

I would expect it to work ok from IDLE.

nagaokashi commented 6 years ago

Thank you. As you said, Since the Software Serial uses the analog comparator interrupt, so I have to keep enable ADC during IDLE sleep. Is that right?

sleemanj commented 6 years ago

Not sure if the ADC needs to be active, probably details it in the datasheet but easier for you to try and see I imagine.

nagaokashi commented 6 years ago

Ok. Thank you. I'll try and feedback.

nagaokashi commented 6 years ago

I tried but could not get it work yet. Attiny could go to sleep, but wake-up instantly although I did not touch anything. Try more.

void system_sleep() {
  wdt_disable();
   power_adc_disable();

  set_sleep_mode(SLEEP_MODE_IDLE); // sleep mode is set here
  noInterrupts ();          // make sure we don't get interrupted before we sleep
  sleep_enable();          // enables the sleep bit in the mcucr register
                             // so sleep is possible. just a safety pin
  interrupts ();           // interrupts allowed now, next instruction WILL be executed                          
  sleep_cpu();
  sleep_mode();                        // System actually sleeps here

  sleep_disable();                     // System continues execution here when watchdog timed out 

  power_adc_enable();
}
sleemanj commented 6 years ago

That is correct, because basically everything can wake up in IDLE, including the millis timer, so it can only stay asleep for at most the period of the millis timer counter.

SpenceKonde commented 6 years ago

Thanks for all your help with responding to these @sleemanj

As a general point, I would suggest that the ATtiny85 is not an ideal chip to use if you want advanced UART functionality - you're still stuck with a software serial implementation (either via "Serial" which uses the ACO interrupt, or SoftwareSerial using PCINT's);

What about the ATTiny841? It's got a real hardware UART, which has start frame detection to wake the chip from power down sleep mode, and if the baud rate is slow enough, you won't miss anything.

nagaokashi commented 6 years ago

Thanks @sleemanj and @SpenceKonde I understood IDLE now. With my original issue, I think the point is I used Serial.

either via "Serial" which uses the ACO interrupt, or SoftwareSerial using PCINT's

So, I changed from Serial to SoftwareSerial, forced sleep to POWER DOWN MODE, (also 1Mhz internal and 9600 baud rate). It works fine now. Anyway, I'm considering switch to ATTiny841 for expanding of inout pin.

nagaokashi commented 6 years ago

I just want to feedback that the 1Mhz does not work with 9600. Rx data is lost frequently. The "POWER DOWN MODE" works fine. ( I've not confirmed with baud rate 1200 yet. I hope 1Mhz will work with 1200. ) For stable, and almost operation time, my Attiny85 goes to sleep mode, so I decided to set 8Mhz and 9600 as a default value.

jassing commented 6 years ago

I recall having problems with serial data & using sleep -- just a thought, are you using flush() before going to sleep?

On Wed, Sep 26, 2018 at 6:05 AM nagaokashi notifications@github.com wrote:

I just want to feedback that the 1Mhz does not work with 9600. Rx data is lost frequently. ( I've not confirmed with baud rate 1200 yet. I hope 1Mhz will work with

  1. ) For stable, and almost operation time, my Attiny85 goes to sleep mode, so I decided to set 8Mhz and 9600 as a default value.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/246#issuecomment-424707481, or mute the thread https://github.com/notifications/unsubscribe-auth/ALKu4lZFd-yeF8x0TGGNfvHrVeeavXu9ks5ue3ukgaJpZM4Wzg8H .

nagaokashi commented 6 years ago

Hi @jassing

are you using flush() before going to sleep?

No. Actually, I don't know what flush() is and what is this use for. Your comment sound promising! FYI, with 1Mhz and 9600 baud rate, I see that, after powered for Attiny85, the first Rx data (whole data, NOT the first character) are usually right. After that, Attiny is going to sleep, then when the next Rx data comes, it wakes up Attiny, but from this timing, Rx data is lost frequently.

SpenceKonde commented 6 years ago

You may be asking too much of the t85 - at only 1MHz, receiving the characters that woke it from sleep at 9600 baud may be too much for it. Why must it be clocked at 1MHz? If it's in deep sleep most of the time, you aren't saving much power by running at 1MHz instead of 8. If it must be 1MHz, can you slow down the serial any more?


Spence Konde Azzy’S Electronics

New products! Check them out at tindie.com/stores/DrAzzy GitHub: github.com/SpenceKonde ATTinyCore: Arduino support for almost every ATTiny microcontroller Contact: spencekonde@gmail.com

On Wed, Sep 26, 2018, 19:32 nagaokashi notifications@github.com wrote:

Hi @jassing https://github.com/jassing

are you using flush() before going to sleep?

No. Actually, I don't know what flush() is and what is this use for. Your comment sound promising! FYI, with 1Mhz and 9600 baud rate, I see that, after powered for Attiny85, the first Rx data (whole data, NOT the first character) are usually right. After that, Attiny is going to sleep, then when the next Rx data comes, it wakes up Attiny, but from this timing, Rx data is lost frequently.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/246#issuecomment-424904159, or mute the thread https://github.com/notifications/unsubscribe-auth/AGdyW_Ogf-sYV94o1LiNRWf0FYCYdL-Iks5ufA6igaJpZM4Wzg8H .

nagaokashi commented 6 years ago

Yeah, you're right. At the beginning, my concern between 1 and 8Mhz is just about power consumption. And because almost operation time of t85 is sleep, so I decided to use 8Mhz.

SpenceKonde commented 6 years ago

As an aside for power consumption - remember to turn off the adc before you go to sleep (or in setup if you aren't using it at all). A lot of people forget or dont know about this issue - leaving the adc on wastes like 270 uA or so.


Spence Konde Azzy’S Electronics

New products! Check them out at tindie.com/stores/DrAzzy GitHub: github.com/SpenceKonde ATTinyCore: Arduino support for almost every ATTiny microcontroller Contact: spencekonde@gmail.com

On Wed, Sep 26, 2018, 19:56 nagaokashi notifications@github.com wrote:

Yeah, you're right. At the beginning, my concern between 1 and 8Mhz is just about power consumption. And because almost operation time of t85 is sleep, so I decided to use 8Mhz.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/246#issuecomment-424908192, or mute the thread https://github.com/notifications/unsubscribe-auth/AGdyW2agsU6PHeZ45XTa7owhP-EtP7syks5ufBRCgaJpZM4Wzg8H .

nagaokashi commented 6 years ago

Thanks for your advice. I did it, including the Analog Comparator, Power Reduction Register (PRR), and set all ports to INPUT mode.

nagaokashi commented 6 years ago

Hi @SpenceKonde Might I ask you another advice ?! I'm connecting ATTiny85 to a BLE module. Currently, I put t85 into deep sleep mode while keep BLE in active mode. T85 will be wake up by Rx from BLE. A smartphone sends connection request and also data to BLE anytime. Now, I intent to improve power consumption of BLE by putting BLE to sleep mode for 1 second and then wake up it for 1 second. Of course, this whole process is controlled by t85. Do you think this is normal process in BLE world?

SpenceKonde commented 6 years ago

What BLE module is this? Is it meeting it's power consumption spec from the datasheet? I thought BLE was supposed to be such low power that you wouldn't have to take measures like that. I mean, it's right in the name....

nagaokashi commented 6 years ago

The BLE named AT-09. As datasheet, BLE takes 8.5mA in active mode. I have not measure the power consumption of my own module yet (actually, I don't know measure method. Not yet). I just want to improve power consumption as much as possible. Target of project is the whole IoT device must to work (at least 5 years) with power from a 8650 BAT (2000mah) and a 5v-1Wh Solar panel. The most power is used by this BLE. I think, with this kind of project (long time life), reality experience is very important to judg that how long the power would do as our expectaion.

jassing commented 6 years ago

No. Actually, I don't know what flush() is and what is this use for. Your comment sound promising!

I think it's Serial.flush() -- You would issue it after your last Serial.Print() before you start setting up for sleep time... (on one I had some werid stuff, so I put it after every serial.print() which took some extra time, but it fixed data loss in sending

Did it work for you?

nagaokashi commented 6 years ago

I did a search on google about flush(). And same as you said, this function is used for sending side. My problem is Rx side. Although I've not tried yet, but I think this function will not impact.

jassing commented 6 years ago

My apologies... I misread your original issue -- I thought you were having two issues (one receive, the other send)

On Fri, Sep 28, 2018 at 5:40 AM nagaokashi notifications@github.com wrote:

I did a search on google about flush(). And same as you said, this function is used for sending side. My problem is Rx side. Although I've not tried yet, but I think this function will not impact.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/SpenceKonde/ATTinyCore/issues/246#issuecomment-425422847, or mute the thread https://github.com/notifications/unsubscribe-auth/ALKu4p_wPmfsv2jlzk0b4mZUdz1cghtPks5ufhjOgaJpZM4Wzg8H .

SpenceKonde commented 6 years ago

Serial.flush() also doesn't do anything with software serial - software serial transmits are blocking, so it's always as if you called flush immediately after every serial.print() on a board with hardware serial.

jassing commented 6 years ago

Serial.flush() also doesn't do anything with software serial - software serial transmits are blocking, so it's always as if you called flush immediately after every serial.print() on a board with hardware serial.'

Always something to learn... I did not know that. Thank you.