aws / aws-iot-device-sdk-arduino-yun

SDK for connecting to AWS IoT from an Arduino Yún.
Apache License 2.0
163 stars 77 forks source link

The BasicPubSub Example gives Generic Error and Yield Error when delay is > 10,000 #21

Closed robin1152 closed 8 years ago

robin1152 commented 8 years ago

Hi,

I was trying the BasicPubSub example and everything was fine in the beginning. However, after I changed the delay in the loop from 1000ms to 10000ms, the program started reporting generic error and yield error. Only the first message was delivered.

I've tried several different delay time, this only happen when the delay is greater then 10000.

Thanks.

robin1152 commented 8 years ago

Sorry...problem solved. I just found in the intro: "...When you are using thing shadow API, make sure you set the timeout to a proper value and frequently call yield to free subscribe resources. Long timeout with low rate of yielding and high rate of shadow request will result in exhaustion of subscribe resources"

liuszeng commented 8 years ago

Hi @robin1152 ,

Thank you very much for using AWS IoT Arduino Yun SDK!

The issue you are experiencing here is that your loop delay time has exceeded the pre-configured maximum time for the Python runtime (built on AWS IoT Python SDK) to determine a timeout for ATmega32u4. You can find the default configuration statement here: https://github.com/aws/aws-iot-device-sdk-arduino-yun/blob/master/AWS-IoT-Arduino-Yun-Library/aws_iot_config_SDK.h#L21

What's behind the scene is that the AWS IoT Arduino Yun SDK is built with two main cores, the one (C++ library) that is running on the ATmega32u4 that translates user Arduino sketch commands into serial commands, and the one (Python runtime) that receives the serial commands and does the actual heavy-lifting. This mechanism is more like a Remote Procedure Call (RPC) process.

Therefore, as a protection mechanism, the SDK has a default configuration of 10 seconds (which is exactly the amount of time you are delaying in your sketch) timeout. The Python runtime continuously checked the interval between received serial commands and will terminate itself once the reception gets timed out in case there is a serial communication error/ATmega board issue on the ATmega32u4. See lines below: https://github.com/aws/aws-iot-device-sdk-arduino-yun/blob/master/AWS-IoT-Python-Runtime/lib/comm/serialCommunicationServer.py#L47 https://github.com/aws/aws-iot-device-sdk-arduino-yun/blob/master/AWS-IoT-Python-Runtime/lib/comm/serialCommunicationServer.py#L83 https://github.com/aws/aws-iot-device-sdk-arduino-yun/blob/master/AWS-IoT-Python-Runtime/runtime/runtimeHub.py#L299 https://github.com/aws/aws-iot-device-sdk-arduino-yun/blob/master/AWS-IoT-Python-Runtime/runtime/runtimeHub.py#L331

To resolve your issue, say we want to do publishes at a much slower rate, e.g., 1 min or so, you will need to update the SDK configuration mentioned above (NOT the configuration file along with the samples) to specify a longer timeout for the Python runtime to wait before it terminates itself. Keep in mind that by doing so you are also expanding the time within which the Python runtime is able to detect a potential issue happened on ATmega32u4.

Hope that answers your question.

Thanks, Liusu