mikaelpatel / Cosa

An Object-Oriented Platform for Arduino/AVR
https://mikaelpatel.github.io/Cosa/
GNU Lesser General Public License v2.1
338 stars 76 forks source link

CosaWirelessDS18B20 with attiny85 unstable ? #226

Closed mazkagaz closed 10 years ago

mazkagaz commented 10 years ago

Hello,

I tried yesterday your CosaWirelessDS18B20 arduino sketch and it worked like a charm (using virtualwire) : one message each 5 seconds, with two DS18B20.

I wanted to tune it for my personnal needs : only one DS18B20. There were no problem except I only received one message, the first one, and nothing else happened.

I thought the attiny did not wake up after deep sleep but I measured the DS18B20 input voltage (as the attiny feeds it when it is awaked) and I could observe this : 4.5v after switching on, message received on the other side (so everything OK), 0v (attiny sleeps), then 4.5v again (attiny woke up), and then, nothing else, 4.5v all the time without any other message send (nor received) and without any other sleep time for the attiny, as if it was in an infinite loop.

I tried to debug with a blinking led : depending on the place I put my debug output in the "loop" code, the code didn't stop at the same place.

I tried changing the attiny with another, reburn the bootloader, changing the emetter, changing the DS18B20: always the same.

I get back to the original sketch with two DS18B20, figuring I did something wrong and wanting to see it working again. The original sketch does the same: +4.5v, temperatures sended, 0v, +4.5v and then locked, nothing else happens.

May you have already had that issue and know what to do ? I wondered if there is an issue with watchdog that make the attiny freeze, because the led blinking debug make the sketch stop in a different state.

I'll go on looking for the problem and give you feed back if i find a/the solution.

Regards,

H. M.

mikaelpatel commented 10 years ago

Let see if I understand you correctly; First you built the example and everything was fine. Then you changed it and it did not work. And now when you go back to the original sketch it also does not work?

Sounds like you have broken some hardware during the changes. Or got the wiring wrong. Or have got the fuse bits wrong. The fuse bits definition in the Cosa boards.txt might be wrong?

Cheers!

mazkagaz commented 10 years ago

You understand correctly.

I did the same analyse you do. So : 1/ I changed all hardware and then, same problem 2/ concerning the wiring, I receive the first message, before "freezing" : so I beleive it is OK, but I go on verifiing it, again and again. 3/ I am going to compare the Cosa boards.txt with the previous one I used with attiny85 and see if there are differences. It may be the cause of my problem because if I remember, the first time, when it worked, i didn't burn the cosa bootlaoder on my attiny85 because it already had its fuse bits set for another project. If there are differences, I will burn a bootloader using my old attiny85 fuse definitions on a new attiny85, and then see if it works again, like the first time.

mazkagaz commented 10 years ago

Fuse bits definition differs from my old boards.txt def. My tests:

I verified the wiring again: seems to be OK. But I have re-done all from zero, to be sure: same issue.

Since it stops in this part of the code (+4.5v measured on pin D4 (pw) after boot, then 0v during sleep time, then +4.5v after wake up and forever): asserted(pw) { DS18B20::convert_request(&owi, 12, true); indoors.read_scratchpad(); outdoors.read_scratchpad(); } I suspect something is blocking in one of these 3 DS18B20 calls. Then I modified the wiring to use the DS18B20 power mode instead of parasite mode: same issue (one message ok, then nothing else) and same voltage measurement (+4.5, then 0, then +4.5 forever). Then I suspected something wrong happened into the DS18B20 class on the second call, so I tested to create both OWI and DS18B20 objects in the loop instead of making global objects, and connect to the sensors in the loop: it is now like if it was the first call every time. Same issue.

If I didn't have seen it work yesterday, I would say it doesn't work. But it worked...

Since this morning, I'm using the last Cosa version, from svn. Maybe I used a previous version yesterday, from download link. I don't remember. I'll try to donwload one again from the "download" link and compare it with the last revision. If no differences... I'll see then what to do...

mikaelpatel commented 10 years ago

Might need to test that on an Arduino first. Just in case.

mazkagaz commented 10 years ago

That's what I suspected last. A problem in the last revision. I downgrade to the last version of july the 28th, and then it works perfectly. I'm not sure, I'm going to test, but I think the last RTC routines changes made on july the 29th do not fit the attiny85.

mazkagaz commented 10 years ago

I am happy to tell you I have found when exactly the problem appears: after commit 97b8eba1d54932d5cf2e673b797b0ca7eb70f1ee. Before, no problem, after, one message and after deep sleep, attiny freezes. For an attiny85, the RTC delay may be a uint16_t and not a uint32_t.

mazkagaz commented 10 years ago

I give you 2 patch i made. They are not beautiful, but they work. (see 2 next comments... some problems with formatting...)

mazkagaz commented 10 years ago

diff -r 770a1016a481 Cosa/cores/cosa/Cosa/RTC.cpp --- a/Cosa/cores/cosa/Cosa/RTC.cpp jeu. juil. 31 10:30:41 2014 +0200 +++ b/Cosa/cores/cosa/Cosa/RTC.cpp jeu. juil. 31 18:19:42 2014 +0200 @@ -56,7 +56,9 @@ TIFR0 = 0; } s_initiated = true; +#ifndef BOARD_ATTINY ::delay = delay; +#endif return (true); }

@@ -101,7 +103,11 @@ }

void +#if defined(BOARD_ATTINY) +RTC::delay(uint16_t ms) +#else RTC::delay(uint32_t ms) +#endif { uint32_t start = RTC::millis(); while (RTC::since(start) < ms) yield();

mazkagaz commented 10 years ago

diff -r 770a1016a481 Cosa/cores/cosa/Cosa/RTC.hh --- a/Cosa/cores/cosa/Cosa/RTC.hh jeu. juil. 31 10:30:41 2014 +0200 +++ b/Cosa/cores/cosa/Cosa/RTC.hh jeu. juil. 31 18:21:58 2014 +0200 @@ -128,7 +128,11 @@ * Delay using the real-time clock. * @param[in] ms sleep period in milli-seconds. */ +#if defined(BOARD_ATTINY)

mikaelpatel commented 10 years ago

Thanks. I think I know where this change occurred. Get back with more details.

mikaelpatel commented 10 years ago

Hi I have had a look at the code and I think that I see a problem with the updated delay(). The DS18B20 driver contains a delay that will require the RTC to be up and running (new delay) but it is still turned off.

https://github.com/mikaelpatel/Cosa/blob/master/examples/Wireless/CosaWirelessDS18B20/CosaWirelessDS18B20.ino#L156 https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/OWI/Driver/DS18B20.cpp#L69

The simple solution should be to move the line 156 to 147 (before the conversion request). Would be great if you could test that.

Cheers!

mazkagaz commented 10 years ago

I re-use the last revision of RTC.cpp and RTC.hh (with uint32_t instead of uint16_t) and move the power_enable call before asking temperature: just tested, work fine. My question: why does it work with old RTC routines ?

mikaelpatel commented 10 years ago

I have pushed a commit with these changes; https://github.com/mikaelpatel/Cosa/commit/c5efdabefe96a9181ba2f465b279fcab9acf656b

The RTC update unified the RTC::delay() to the global delay() function prototype and actually installs itself as the delay() when the RTC is used.

The global init installs first the busy-wait delay based on DELAY. And on Watchdog::begin() this is replaced with the Watchdog version. Which then is replaced by the RTC version. The Watchdog version gives powerdown but is only accurate to at most 16 ms. The RTC version give powerdown but a 1 ms accuracy.

Now to the problem. The sketch uses a lot of powerdown technique; e.g. Power::all_enable/disable but these shutdown timers (not the Watchdog). As the convert_request() calls delay() to it ends up calling RTC delay which starts to loop infinitely as the timers are not yet active.

Opps - excuse the looooong answer. Hope you can make sense of this. And THANKS for your effort testing this.

mazkagaz commented 10 years ago

Ok, I understand. I used a home made arduino sketch for my sensors and also used powerdown and watchdog to keep my batteries alive the longest possible time. I have been attracted by your project because of its generic (object) approach of all devices, protocols... I used to send the DS18B20 serial number as a "MAC address" to identify my sensors (bathroom, bedroom, garden...etc...). Now I will use the device number : I think 256 possibilities is enough for my needs. At the beginning of the sketch, there is a #define DEVICE depending on a #if defined(BOARD_ATTINY), is this necessary ? I didn't understand why the device number had to depend on the micro type, so I deactivated this to choose my own numbers and it worked well.

mikaelpatel commented 10 years ago

Just to quickly answer to your question; That is actually for testing multiple sensors by using different Arduino boards. You should use your own ids and the network and device id should really be in EEMEM to make things easier to configure. Same HEX for all sensors (with the same processor) and then EEMEM files for each device.

duayfabi commented 9 years ago

Hi,

I exactly have the same problem with the latest version of the cosa library.

As client, I'm using the exemple sketch "CosaWirelessDS18B20" with the VirtualWire wireless driver.

As server, the "CosaWirelessReceiver" exemple sketch (with VirtualWire option).

I use the sketch "As is" (I only choose the VirtualWire wireless device driver). On my "Server", I only receive the first message and nothing else more.

I checked my hardware/shema. All seems to be good..

I can do a few check if you want. Let me know what to do..

Regards,

Fabien