Swarm M138 do not send messages

Hello!

Modem already registered. Connected to an ESP32 NodeMCU. Communication with the modem is ok. I can receive GPS data. But when I try do send a text message, I cant see it in Hive. I got 11 unsent messages. Modem Is blinking green every 5 seconds. I dont receive the TD SENT. Any idea?

18:34:14.619 → The message has been added to the transmit queue. The message ID is 4964473929750

18:34:14.652 → Waiting for the $TD SENT

Thanks a lot!

Are you testing outside with a clear view of the sky?

Tried right outside the window but I will put it on the rooftop next time. Ground plate needs to be grounded right?

Antenna ground and transmitter ground must be tied (usually taken care of by the coax) but they don’t need to be earth grounded.

Finally got a response last day at 7pm. Powered on the device again today at the morning (about 10AM) to try to send another message. Its 6:53PM and nothing appeared in Hive…

I got everything working well when I placed the antenna in the middle of a field, free of everything. The antenna was placed on top of a 1.5 meters wood support, so I kept it this distance of the ground. Once I turned the device on I could see the blue light (never seen before) blinking, telling me there was some communication with a satellite. This time I was using M138 GUI and connected the device via USB-C cable into the Macbook. I could finally receive the $TD SENT. It happened accordingly to Pass Checker time range. I could get the text sent in Hive after about 2 hours.

The only thing I could not do is to send the message when the device was plugged into an ESP32 NodeMCU receiving 5V and the ESP32 was connected to the Macbook via USB. I sent the messages to the modem but when it tried to send the message to the satellite, the modem restarted. My question is: Could it be because of the voltage?

The modem needs up to 600mA during transit. I suspect your power source isn’t able to supply enough current causing a brown out. This could also be caused but insufficient wiring between the power source and the modem.

Changed cable and everything. I can receive test messages from satellite, but never receive TDSENT…

Any idea?

09:52:42.769 → New receive test message received: rssi_background: -108 (Great)

09:52:44.747 → New receive test message received: rssi_background: -108 (Great)

09:52:46.761 → New receive test message received: rssi_background: -108 (Great)

09:52:49.463 → New receive test message received: rssi_sat: -106 snr: 2 fdev: -2374 2024/02/25 12:52:50 sat_id: 0xC065B

09:52:49.761 → New receive test message received: rssi_background: -106 (Great)

09:52:51.773 → New receive test message received: rssi_background: -107 (Great)

09:52:53.222 → New receive test message received: rssi_sat: -106 snr: 2 fdev: -2311 2024/02/25 12:52:54 sat_id: 0xC065B

09:52:53.746 → New receive test message received: rssi_background: -107 (Great)

09:52:55.756 → New receive test message received: rssi_background: -107 (Great)

09:52:57.766 → New receive test message received: rssi_background: -108 (Great)

#include <SparkFun_Swarm_Satellite_Arduino_Library.h> //Click here to get the library: http://librarymanager/All#SparkFun_Swarm_Satellite

SWARM_M138 mySwarm;

//#define swarmSerial Serial1 // Use Serial1 to communicate with the modem. Change this if required.

HardwareSerial swarmSerial(2);

// If you are using the Swarm Satellite Transceiver MicroMod Function Board:

//

// The Function Board has an onboard power switch which controls the power to the modem.

// The power is disabled by default.

// To enable the power, you need to pull the correct PWR_EN pin high.

//

// Uncomment and adapt a line to match your Main Board and Processor configuration:

//#define swarmPowerEnablePin A1 // MicroMod Main Board Single (DEV-18575) : with a Processor Board that supports A1 as an output

//#define swarmPowerEnablePin 39 // MicroMod Main Board Single (DEV-18575) : with e.g. the Teensy Processor Board using pin 39 (SDIO_DATA2) to control the power

//#define swarmPowerEnablePin 4 // MicroMod Main Board Single (DEV-18575) : with e.g. the Artemis Processor Board using pin 4 (SDIO_DATA2) to control the power

//#define swarmPowerEnablePin G5 // MicroMod Main Board Double (DEV-18576) : Slot 0 with the ALT_PWR_EN0 set to G5<->PWR_EN0

//#define swarmPowerEnablePin G6 // MicroMod Main Board Double (DEV-18576) : Slot 1 with the ALT_PWR_EN1 set to G6<->PWR_EN1

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

// Callback: printRxTest will be called when a new unsolicited $RT receive test message arrives

// See SparkFun_Swarm_Satellite_Arduino_Library.h for the full definition of Swarm_M138_Receive_Test_t

// _____ You can use any name you like for the callback. Use the same name when you call setReceiveTestCallback

// / _____ This must be Swarm_M138_Receive_Test_t

// | / _____ You can use any name you like for the struct

// | | /

// | | |

void printRxTest(const Swarm_M138_Receive_Test_t *rxTest)

{

Serial.print(F(“New receive test message received:”));

if (rxTest->background) // Check if rxTest contains only the background RSSI

{

Serial.print(F(" rssi_background: "));

Serial.print(rxTest->rssi_background);

if (rxTest->rssi_background <= -105)

Serial.println(F(" (Great)"));

else if (rxTest->rssi_background <= -100)

Serial.println(F(" (Good)"));

else if (rxTest->rssi_background <= -97)

Serial.println(F(" (OK)"));

else if (rxTest->rssi_background <= -93)

Serial.println(F(" (Marginal)"));

else

Serial.println(F(" (Bad)"));

}

else

{

Serial.print(F(" rssi_sat: "));

Serial.print(rxTest->rssi_sat);

Serial.print(F(" snr: "));

Serial.print(rxTest->snr);

Serial.print(F(" fdev: "));

Serial.print(rxTest->fdev);

Serial.print(F(" "));

Serial.print(rxTest->time.YYYY);

Serial.print(F(“/”));

if (rxTest->time.MM < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.MM); // Print the month. Add a leading zero if required

Serial.print(F(“/”));

if (rxTest->time.DD < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.DD); // Print the day of month. Add a leading zero if required

Serial.print(F(" "));

if (rxTest->time.hh < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.hh); // Print the hour. Add a leading zero if required

Serial.print(F(“:”));

if (rxTest->time.mm < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.mm); // Print the minute. Add a leading zero if required

Serial.print(F(“:”));

if (rxTest->time.ss < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.ss); // Print the second. Add a leading zero if required

Serial.print(F(" sat_id: 0x"));

Serial.println(rxTest->sat_id, HEX);

}

}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void setup()

{

// Swarm Satellite Transceiver MicroMod Function Board PWR_EN

#ifdef swarmPowerEnablePin

pinMode(swarmPowerEnablePin, OUTPUT); // Enable modem power

digitalWrite(swarmPowerEnablePin, HIGH);

#endif

delay(1000);

Serial.begin(115200);

while (!Serial)

; // Wait for the user to open the Serial console

Serial.println(F(“Swarm Satellite example”));

Serial.println();

swarmSerial.begin(115200, SERIAL_8N1, 17, 16);

//mySwarm.enableDebugging(); // Uncomment this line to enable debug messages on Serial

bool modemBegun = mySwarm.begin(swarmSerial); // Begin communication with the modem

while (!modemBegun) // If the begin failed, keep trying to begin communication with the modem

{

Serial.println(F(“Could not communicate with the modem. It may still be booting…”));

delay(2000);

modemBegun = mySwarm.begin(swarmSerial);

}

// Just to prove it works, call getReceiveTest to request the most recent RSSI etc.

Swarm_M138_Receive_Test_t *rxTest = new Swarm_M138_Receive_Test_t; // Allocate memory for the information

mySwarm.getReceiveTest(rxTest);

Serial.print(F(“getReceiveTest returned:”));

if (rxTest->background) // Check if rxTest contains only the background RSSI

{

Serial.print(F(" rssi_background: "));

Serial.println(rxTest->rssi_background);

}

else

{

Serial.print(F(" rssi_sat: "));

Serial.print(rxTest->rssi_sat);

Serial.print(F(" snr: "));

Serial.print(rxTest->snr);

Serial.print(F(" fdev: "));

Serial.print(rxTest->fdev);

Serial.print(F(" "));

Serial.print(rxTest->time.YYYY);

Serial.print(F(“/”));

if (rxTest->time.MM < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.MM); // Print the month. Add a leading zero if required

Serial.print(F(“/”));

if (rxTest->time.DD < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.DD); // Print the day of month. Add a leading zero if required

Serial.print(F(" "));

if (rxTest->time.hh < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.hh); // Print the hour. Add a leading zero if required

Serial.print(F(“:”));

if (rxTest->time.mm < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.mm); // Print the minute. Add a leading zero if required

Serial.print(F(“:”));

if (rxTest->time.ss < 10) Serial.print(F(“0”)); Serial.print(rxTest->time.ss); // Print the second. Add a leading zero if required

Serial.print(F(" sat_id: 0x"));

Serial.println(rxTest->sat_id, HEX);

}

delete rxTest; // Free the memory

// Set up the callback for the receive test message. Call printRxTest when a new $RT message arrives

mySwarm.setReceiveTestCallback(&printRxTest);

// Set the $RT message rate: send the message every 2 seconds

Swarm_M138_Error_e err = mySwarm.setReceiveTestRate(2);

if (err == SWARM_M138_SUCCESS)

{

Serial.println(F(“setReceiveTestRate was successful”));

}

else

{

Serial.print(F("Swarm communication error: "));

Serial.print((int)err);

Serial.print(F(" : "));

Serial.print(mySwarm.modemErrorString(err)); // Convert the error into printable text

if (err == SWARM_M138_ERROR_ERR) // If we received a command error (ERR), print it

{

Serial.print(F(" : "));

Serial.print(mySwarm.commandError);

Serial.print(F(" : "));

Serial.println(mySwarm.commandErrorString((const char *)mySwarm.commandError));

}

else

Serial.println();

}

// Just to prove it works, call getReceiveTestRate to check the message rate

uint32_t rate;

mySwarm.getReceiveTestRate(&rate);

Serial.print(F("Message rate is "));

Serial.println(rate);

// Wait until the modem has valid Date/Time

Swarm_M138_DateTimeData_t dateTime;

err = mySwarm.getDateTime(&dateTime);

while (err != SWARM_M138_SUCCESS)

{

Serial.print(F("Swarm communication error: "));

Serial.print((int)err);

Serial.print(F(" : "));

Serial.println(mySwarm.modemErrorString(err)); // Convert the error into printable text

Serial.println(F(“The modem may not have acquired a valid GPS date/time reference…”));

delay(2000);

err = mySwarm.getDateTime(&dateTime);

}

// Set up the callback for the unsolicited $TD SENT messages. Call printMessageSent when a new message arrives

mySwarm.setTransmitDataCallback(&printMessageSent);

}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

void loop()

{

mySwarm.checkUnsolicitedMsg();

}

void serialPrintUint64_t(uint64_t theNum)

{

// Convert uint64_t to string

// Based on printLLNumber by robtillaart

// https://forum.arduino.cc/index.php?topi … msg1519824

char rev[21]; // Char array to hold to theNum (reversed order)

char fwd[21]; // Char array to hold to theNum (correct order)

unsigned int i = 0;

if (theNum == 0ULL) // if theNum is zero, set fwd to “0”

{

fwd[0] = ‘0’;

fwd[1] = 0; // mark the end with a NULL

}

else

{

while (theNum > 0)

{

rev[i++] = (theNum % 10) + ‘0’; // divide by 10, convert the remainder to char

theNum /= 10; // divide by 10

}

unsigned int j = 0;

while (i > 0)

{

fwd[j++] = rev[–i]; // reverse the order

fwd[j] = 0; // mark the end with a NULL

}

}

Serial.print(fwd);

}

void printMessageSent(const int16_t *rssi_sat, const int16_t *snr, const int16_t *fdev, const uint64_t *msg_id)

{

Serial.print(F(“New $TD SENT message received:”));

Serial.print(F(" RSSI = "));

Serial.print(*rssi_sat);

Serial.print(F(" SNR = "));

Serial.print(*snr);

Serial.print(F(" FDEV = "));

Serial.print(*fdev);

Serial.print(F(" Message ID: "));

serialPrintUint64_t(*msg_id);

Serial.println();

}

Did not renew service with Swarm in May this year due to high latency. Sunspots damaged many satellites and latency for transmission about 12 hours. My M138 unit now gathering dust. Successfully operated unit for 1 year. In my one year test, did a binary data transmission for about 6 months (weather plus solar charge controller data) and a json data transmission for about 6 months (weather only). Looking forward to the IoT option with direct cell to satellite (2025).