mikalhart / IridiumSBD

Arduino library for RockBLOCK Iridium satellite modem (http://rock7mobile.com)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

examples cause arduino mega r3 to loop unless #define DIAGNOSTICS true

JimKruk opened this issue · comments

this is very puzzling. I bought a Rockblock, arduino mega r3 and a level shifting board from Sparkfun. I am try to use the example code in the IridiumSBD libraries, BasicSend, SendReceive and all I get in the serial monitor window (set at 115200, CR/LF) is random garbage. If a change the #define DIAGNOSTICS from false to true everything runs ok and I see output in the serial window.

arduino library was downloaded from here: https://github.com/mikalhart/IridiumSBD
this is V2 that was released around November 2017

I added a delay line in SETUP and a few lines like this:
Serial.println(F("RockBlock Test")); in the start of setup and then this line just before the modem.begin
Serial.println("Starting modem...");
err = modem.begin();

it appears it is starting up but somehow just gets stuck inmodem.begin and cause the program to reset over and over and never reaches the LOOP function, but I have no idea why

in the console window I see the "rockblock test" is coming from setup then I see "Sta" and it repeats that sequence over and over.

I think "Sta" is part of this string in setup: Serial.println("Starting modem...");
It does not appear to ever get the the loop function and never reaches the last couple of lines in setup which prints out my menu in setup()

very strange....

I am using IDE 1.8.1 the Serial3 with no changes in the sample code. For power I am using the USB cable from the PC for the arduino mega and for the rockblock power pins a 5v wall adapter 2000 ma. Since everything works ok when I set #define DIAGNOSTICS to true I feel the wiring/level shifting is ok.

any thoughts/comments greatly appreciated !

I can confirm the same issue. Running IDE 1.8.5 with modem on Serial2.
With diagnostics set to false it seems to be resetting after a short amount of time or clock cycles as the higher the baud I set on for Serial0 the more text that gets output before the (WDT?) board is reset. I believe this is what is causing the 'garbage' in the console at lower baud rates (The board resetting before the byte is transmitted). I changed the sleep example very slightly and the lower that the serial baud is set, the less of the initial abcd.... text I get. At 1M baud I am getting millis() returning 0 or 1ms and it does not increase above this.

Copied from console output

ABCDEFGHIJKLMNOPQRSTUVWXYZ
1
Starting modem...
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1
Starting modem...
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1
Starting modem...
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0
Starting modem...
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0
Starting modem...
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1
Starting modem...
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1
Starting modem...

Code:

#include <IridiumSBD.h>

/*
 * Sleep
 * 
 * This sketch demonstrates how to use the RockBLOCK Sleep pin.  The
 * general strategy is to call modem.begin() to start, then modem.sleep()
 * to stop.
 * 
 * Assumptions
 * 
 * The sketch assumes an Arduino Mega or other Arduino-like device with
 * multiple HardwareSerial ports.  It assumes the satellite modem is
 * connected to Serial3.  Change this as needed.  SoftwareSerial on an Uno
 * works fine as well.
 * 
 * This sketch also assumes that pin 4 is connected to Sleep
 */

#define IridiumSerial Serial2
#define SLEEP_PIN 7
#define DIAGNOSTICS false // Change this to see diagnostics

// Declare the IridiumSBD object (note SLEEP pin)
IridiumSBD modem(IridiumSerial, SLEEP_PIN);

void setup()
{ 
  // Start the console serial port
  Serial.begin(1000000);
  Serial.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  Serial.println(millis());
  while (!Serial);

  // Start the serial port connected to the satellite modem
  IridiumSerial.begin(19200);
}

void loop()
{
  // Begin satellite modem operation
  Serial.println("Starting modem...");
  int err = modem.begin();
  if (err != ISBD_SUCCESS)
  {
    Serial.print("Begin failed: error ");
    Serial.println(err);
    if (err == ISBD_NO_MODEM_DETECTED)
      Serial.println("No modem detected: check wiring.");
    return;
  }

  // Send the message
  Serial.print("Trying to send a message.  This might take several minutes.\r\n");
  err = modem.sendSBDText("Hello, world! (Sleep test)");
  if (err != ISBD_SUCCESS)
  {
    Serial.print("sendSBDText failed: error ");
    Serial.println(err);
    if (err == ISBD_SENDRECEIVE_TIMEOUT)
      Serial.println("Try again with a better view of the sky.");
  }

  else
  {
    Serial.println("Hey, it worked!");
  }

  // Put modem to sleep
  Serial.println("Putting modem to sleep.");
  err = modem.sleep();
  if (err != ISBD_SUCCESS)
  {
    Serial.print("sleep failed: error ");
    Serial.println(err);
  }

  // Demonstrate that device is asleep
  Serial.println("Trying to send while asleep.");
  err = modem.sendSBDText("This shouldn't work.");
  if (err == ISBD_IS_ASLEEP)
  {
    Serial.println("Couldn't send: device asleep.");
  }
  else
  {
    Serial.print("Send failed for some other reason: error ");
    Serial.println(err);
  }

  Serial.println("Sleeping for a minute.");
  delay(60 * 1000UL);
}

#if DIAGNOSTICS
void ISBDConsoleCallback(IridiumSBD *device, char c)
{
  Serial.write(c);
}

void ISBDDiagsCallback(IridiumSBD *device, char c)
{
  Serial.write(c);
}
#endif

Hi Justin
Thank you for the comments an interesting observations. What confuses me is in the examples folder all the programs are using serial3. From what I read when using the arduino mega 2560 R3 , only certain pins on that board support interrupts on RX, 10, 11, 12, 13, 14, 15 so I assume that is why the author choose Serial3

According to the doc
Serial3 uses 15 rx and 14 tx
Serial2 uses 17 rx and 16 tx

I will try some different baud rates and delay statements and see if that helps
Thanks

Hey msy380,
I don't believe serial2 instead of serial3 has anything to do with it. That could be an author preference seeing as how in the comments in the example it says to change or use software serial.

Assumptions
 * 
 * The sketch assumes an Arduino Mega or other Arduino-like device with
 * multiple HardwareSerial ports.  It assumes the satellite modem is
 * connected to Serial3.  Change this as needed.  SoftwareSerial on an Uno
 * works fine as well.

Hi! I'm having exactly the same problem, but I'm using AltSoftSerial instead of SoftwareSerial, and using an Arduino Nano. Any idea on how to solve this?

That's a shame @msy380. My understanding was RockSeven helped make this library in the first place so it's a shame they can't contribute to diagnostics and resolution. I haven't had the chance to look through the library to see what might be causing this. It's on my todo list, but so are a heap of other things right now.
Feel free to try and find the problem in the meantime 😄

Hi all--

I'll be looking at this in the next two weeks. Is the common thread here that everyone affected is using the Mega? @AngeloACR, are you using the Mega? If so, I was certainly suggest using one of the "hardware" serial ports in favor of the less reliable software serial implementations.

Using Mega and hardware serial here

I'm using a Nano and and AltSoftSerial. Also tried with SoftwareSerial and didn't work neither @mikalhart

Hi friends--

I'm starting to maybe understand this. Most of the testing we do with IridiumSBD occurs on ARM processors, and I think there may be a difference between the way the ARM compilers handle undefined functions with the "weak" attribute and the Atmel core ones. Could I convince one or more of you to do the following experiment:

  1. Keep DIAGNOSTICS defined as false.
  2. Change the bit at the bottom of the sketches that involves diagnostics from:
#if DIAGNOSTICS
void ISBDConsoleCallback(IridiumSBD *device, char c)
{
  Serial.write(c);
}

void ISBDDiagsCallback(IridiumSBD *device, char c)
{
  Serial.write(c);
}
#endif

to

void ISBDConsoleCallback(IridiumSBD *device, char c)
{
#if DIAGNOSTICS
  Serial.write(c);
#endif
}

void ISBDDiagsCallback(IridiumSBD *device, char c)
{
#if DIAGNOSTICS
  Serial.write(c);
#endif
}

If my guess is right, this should fix the problem.

Full explanation:

These functions are defined as "weak" in the library to indicate that they should be called if and only if the user (or example writer) provides them in the sketch. On ARM systems, their absence simply causes nothing to happen, but I'm starting to guess that on Atmel core devices, the compiler actually generates a call to address 0, which would create the behavior you are reporting.

I don't have a modem around at the moment but will have a new batch coming soon. I'll test it then unless someone else can test before then.

I have tested the proposed solution on an Uno without a Modem, and looks like it works well. I get the "No modem detected" message, and when in the loop, it throws "unexpected error 3". I'll test it in a few days with a Nano and an Iridium Edge to see if it works well with a Modem. Lets see what happen

Thank you @AngeloACR and @justinj0305. I am increasingly certain that this is the problem. The real solution will be a tiny bit of new code in the library to check whether those diagnostic functions have been provided by the user. That'll come soon once we get a bit more confirmation.

Hi Mikal
Thank you so much for commenting on this thread. I just re-read it and saw where you suggested a work around at the bottom of the sketch. I have a rockblock mk2, mega 2560 r3 and will test that fix and report back later today
Jim

Hi Mikal,
I had a chance to update the code at your previous post to:

void ISBDConsoleCallback(IridiumSBD *device, char c)
{
#if DIAGNOSTICS
Serial.write(c);
#endif
}

void ISBDDiagsCallback(IridiumSBD *device, char c)
{
#if DIAGNOSTICS
Serial.write(c);
#endif
}
and it works !!! THANK YOU SO MUCH !!!
I will do some more testing today after work to confirm w/Diagnostics=TRUE that it still works and report back on this thread.

Question - if you are going to update the library any chance you could include a fix for the send routine to clear the buffer after sending a new message, AT+SBDD ?

Thank you again for all your help on this !
Jim

Hi! I've already tested it with a Nano and an Iridium Edge. After a while, it throws the same error as I said before, so I want to ask how to properly connect the Arduino and the Iridium? Currently, these are the connections:

Arduino - Iridium
Pin 8(AltSoftSer Rx) - Pin 4 (Tx)
Pin 9(AltSoftSer Tx) - Pin 3 (Rx)
GND - Pin 2 - Power supply V-
Vin - Pin 5 - Power Supply V+

The pin 6 of the Iridium is floating

Another thing I want to ask, the voltage levels of the Arduino Tx and Rx are high enough for the Iridium Edge to understand them? Or should I use some kind of level shifter?

Thanks in advance for your help!!

Eklavya-Foundation
I am by no means an expert in this area but I believe the arduino nano is a 5v device and the rockblock edge uses rs232 so the voltages are not compatible. If your goal is to use an arduino in think you would need a rockblock 9603 or mk2 device that uses TTL logic levels

Eklavya-Foundation,
I think your question belongs in a different thread. This one is about a specific issue with the code. Perhaps we can discuss your issue somewhere else?
In the meantime, I would suggest reading the excellent documentation that Mikal wrote. It's in the extras folder of this repo. You will notice that RockBLOCK labelled the unit TX/RX from the Arduino view, so you need to connect TX-TX and RX-RX. That is different than most devices.
I think you will also find answers to other questions in the docs. I previously used a 5V Arduino Pro Mini with the 9602 RockBLOCK with no problems. If I recall, it can handle 5V logic, so I did not need any shifter.
And msy380, are you on the microtransat list? :)

Mikal
I did some additional testing with diagnostics true and false and both options are working fine with a rockblock mk2 and arduino mega 2560 r3, ver 1.81. Thank you again for fixing this !

Any chance you could include the clear buffer command AT+SBDD, in the send new message routine when the updated libraries get published ?

Thank you

Please try new release 2.0.0 and see if this is resolved. There was some misunderstanding about how the "weak" attribute works, and this has been changed.