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

PubSub Example only works when Yun connected to computer #53

Closed metalshreds closed 7 years ago

metalshreds commented 7 years ago

I have a yun setup with the AWS SDK. When pushing the script through my computer, I get a Subscribe failed -1, but the arduino is still able to publish messages to AWS IoT. If I plug in the arduino to a power adapter only, nothing us pushed to AWS. I tried resetting the arduino and re-launching the script by pressing the 32U4 button twice but nothing. As soon as I launch the script from my computer it works again. Any suggestions?

liuszeng commented 7 years ago

Hi @metalshreds ,

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

The BasicPubSub example contains statements that initialize Serial (USB to your computer) and print out messages to Serial. If you connect the board to a power adapter only, the sketch will be blocked at the Serial initialization: https://github.com/aws/aws-iot-device-sdk-arduino-yun/blob/master/AWS-IoT-Arduino-Yun-Library/examples/BasicPubSub/BasicPubSub.ino#L41

Can you try commenting out all Serial statements and try it again? Also, is there any log output that you can share when you are experiencing issues with the API?

Thanks, Liusu

liuszeng commented 7 years ago

Hi @metalshreds ,

I was able to duplicate your issue after I removed all Serial print-outs.

Some necessary background information:

  1. Yun SDK depends on Serial1 (Note: "Serial1" != "Serial") communication to send your sketch commands from 32u4 to the Python runtime on AR9331 and then performs MQTT operations from there.
  2. Serial1 is hard wired to STDIN of the OpenWRT running on AR9331, which means any command sent to Serial1 from 32u4 will be sent to STDIN in OpenWRT.
  3. Upon power cycle, 32u4 and AR9331 will both be rebooted. If you have uploaded any sketch to the board prior to the power cycle. 32u4 will start the sketch immediately after it boots up.
  4. 32u4 boots up faster than AR9331. For my Yun board, AR9331/OpenWRT takes about 70 seconds to boot up.
  5. While booting up, AR9331 has several time windows that wait on inputs from STDIN to enter U-boot recovery mode. Once inside the U-boot mode, it will not enter the normal OpenWRT.

Here's what happens when you preload the sample sketch and power cycle the board using a standalone power adapter:

  1. Yun board is power cycled. This boots up 32u4 and AR9331.
  2. 32u4 finishes booting up and starts the preloaded SDK sample sketch immediately. Note that AR9331 is still booting up at this time point. It waits on inputs from STDIN to decide if it enters the U-boot mode.
  3. SDK sample sketch starts sending commands to Serial1.
  4. Commands get transmitted over Serial1 to AR9331 and breaks the waiting. AR9331 now decides to enter U-boot mode.
  5. Since AR9331 is not in OpenWRT, SDK samples fails in the following commands.

To fix the issue, you will need to put delays at the beginning of your sketch (setup()) to make sure that your sketch does not send Serial1 commands before AR9331 finishes booting up and enters OpenWRT. Like I mentioned earlier, it could take 70 seconds for OpenWRT to be ready.

Hope the above helps.

Thanks, Liusu

metalshreds commented 7 years ago

Thank you so much for the thorough explanation! I learned a lot today :) I commented anything related to Serial (Although maybe not necessary as you said Serial1 != Serial?), and in place of the "while(!Serial)" i added a 80 second delay to give the AR9331 time to fully boot up. After the 80 seconds the sketch takes about 20 for it to start publishing to AWS IoT, but it's all working from a power supply. Thank you!