Skip to content

Version 1.1.9 #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
/*

SARA-R5 Example
===============

ThingSpeak (MQTT)

Written by: Paul Clark
Date: November 14th 2023

This example uses the SARA's mobile data connection and MQTT to publish random temperatures on ThingSpeak.
It also subscribes to the same topic (channel) so you can read the data back again!

See: https://thingspeak.com/

And: https://uk.mathworks.com/help/thingspeak/mqtt-basics.html#responsive_offcanvas

You will need to:
Create a ThingSpeak User Account – https://thingspeak.com/login
Create a new Channel by selecting Channels, My Channels, and then New Channel
Note the Channel ID and copy&paste it into myChannelID below
Click on the Devices drop-down at the top of the screen and select MQTT
Create a new MQTT Device using "Add a new device". Give it a name
Authorize the New Channel you created above, then Add Channel, then Add Device
Copy the Username, Client ID and password into myUsername, myClientID and myPassword below
The random temperature reading will be added to the channel as "Field 1"

Feel like supporting open source hardware?
Buy a board from SparkFun!

Licence: MIT
Please see LICENSE.md for full details

*/

#include <IPAddress.h>

// ThingSpeak via MQTT Publish

String brokerName = "mqtt3.thingspeak.com"; // MQTT Broker

const int brokerPort = 1883; // MQTT port (TCP, no encryption)

String myUsername = "OAAxOjYHIwooJykfCiYoEx0";

String myClientID = "OAAxOjYHIwooJykfCiYoEx0";

String myPassword = "RqY/6L246tULLVWUzCqJBX/V";

String myChannelID = "1225363"; // Public View: https://thingspeak.com/channels/1225363

// SARA-R5

#include <SparkFun_u-blox_SARA-R5_Arduino_Library.h> //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library

// Uncomment the next line to connect to the SARA-R5 using hardware Serial1
#define saraSerial Serial1

// Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
//SoftwareSerial saraSerial(8, 9);

// Create a SARA_R5 object to use throughout the sketch
// Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
// but we can start the SARA without a power pin. It just means we need to manually
// turn the power on if required! ;-D
SARA_R5 mySARA;

// Create a SARA_R5 object to use throughout the sketch
// We need to tell the library what GPIO pin is connected to the SARA power pin.
// If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
// the pin name is G2 which is connected to pin AD34.
// Change the pin number if required.
//SARA_R5 mySARA(34);

// processMQTTcommandResult is provided to the SARA-R5 library via a
// callback setter -- setMQTTCommandCallback. (See the end of setup())
void processMQTTcommandResult(int command, int result)
{
Serial.println();
Serial.print(F("MQTT Command Result: command: "));
Serial.print(command);
Serial.print(F(" result: "));
Serial.print(result);
if (result == 0)
Serial.print(F(" (fail)"));
if (result == 1)
Serial.print(F(" (success)"));
Serial.println();

// Get and print the most recent MQTT protocol error
int error_class;
int error_code;
mySARA.getMQTTprotocolError(&error_class, &error_code);
Serial.print(F("Most recent MQTT protocol error: class: "));
Serial.print(error_class);
Serial.print(F(" code: "));
Serial.print(error_code);
if (error_code == 0)
Serial.print(F(" (no error)"));
Serial.println();
}

void setup()
{
delay(1000);

String currentOperator = "";

Serial.begin(115200); // Start the serial console

// Wait for user to press key to begin
Serial.println(F("SARA-R5 Example"));
Serial.println(F("Wait for the SARA NI LED to light up - then press any key to begin"));

while (!Serial.available()) // Wait for the user to press a key (send any serial character)
;
while (Serial.available()) // Empty the serial RX buffer
Serial.read();

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

// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
// Comment the next line if required
mySARA.invertPowerPin(true);

// Initialize the SARA
if (mySARA.begin(saraSerial, 115200) )
{
Serial.println(F("SARA-R5 connected!"));
}
else
{
Serial.println(F("Unable to communicate with the SARA."));
Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
while (1) ; // Loop forever on fail
}
Serial.println();

// First check to see if we're connected to an operator:
if (mySARA.getOperator(&currentOperator) == SARA_R5_SUCCESS)
{
Serial.print(F("Connected to: "));
Serial.println(currentOperator);
}
else
{
Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
while (1)
; // Do nothing more
}

// Deactivate the PSD profile - in case one is already active
if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
{
Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
}

// Load the PSD profile from NVM - these were saved by a previous example
if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_LOAD) != SARA_R5_SUCCESS)
{
Serial.println(F("performPDPaction (load from NVM) failed! Freezing..."));
while (1)
; // Do nothing more
}

// Activate the PSD profile
if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
{
Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
while (1)
; // Do nothing more
}

// Set up the MQTT command callback
mySARA.setMQTTCommandCallback(processMQTTcommandResult);

// Disable the security profile
mySARA.setMQTTsecure(false);

// Set Client ID
mySARA.setMQTTclientId(myClientID);

// Set the broker name and port
mySARA.setMQTTserver(brokerName, brokerPort);

// Set the user name and password
mySARA.setMQTTcredentials(myUsername, myPassword);

// Connect
if (mySARA.connectMQTT() == SARA_R5_SUCCESS)
Serial.println(F("MQTT connect: success"));
else
Serial.println(F("MQTT connect: failed!"));

// The LTE modem has difficulties subscribing/unsubscribing more than one topic at the same time.
// We can only start one operation at a time wait for the URC and add a extra delay before we can
// do the next operation.
// Wait for ~2 seconds
for (int i = 0; i < 200; i++)
{
mySARA.bufferedPoll(); // Keep processing data from the SARA
delay(10);
}

// Subscribe to the channel topic, so we can read the data back again
String subscribeTopic = "channels/" + myChannelID + "/subscribe/fields/field1";
if (mySARA.subscribeMQTTtopic(0, subscribeTopic) == SARA_R5_SUCCESS) // QoS = 0
Serial.println(F("MQTT subscribe: success"));
else
Serial.println(F("MQTT subscribe: failed!"));

// Wait for ~2 seconds
for (int i = 0; i < 200; i++)
{
mySARA.bufferedPoll(); // Keep processing data from the SARA
delay(10);
}
}

void loop()
{
float temperature = ((float)random(2000,3000)) / 100.0; // Create a random temperature between 20 and 30

// Send data using MQTT Publish
String Topic = "channels/" + myChannelID + "/publish";
String DataField = "field1=" + String(temperature) + "&status=MQTTPUBLISH";

Serial.println();
Serial.print(F("Publishing a temperature of "));
Serial.print(String(temperature));
Serial.println(F(" to ThingSpeak"));

// Publish the text message
mySARA.mqttPublishTextMsg(Topic, DataField.c_str(), 0, true); // QoS = 0, retain = true

// Wait for ~10 seconds
for (int i = 0; i < 1000; i++)
{
mySARA.bufferedPoll(); // Keep processing data from the SARA
delay(10);
}

// Check for any received data
// The MQTT API does not allow getting the size before actually reading the data.
// So we have to allocate a big enough buffer.
const int MQTT_MAX_MSG_SIZE = 1024;
static uint8_t buf[MQTT_MAX_MSG_SIZE];
String topic;
int len = -1;
int qos = -1;
if (mySARA.readMQTT(&qos, &topic, buf, MQTT_MAX_MSG_SIZE, &len) == SARA_R5_SUCCESS)
{
if (len > 0)
{
Serial.println();
Serial.print(F("Subscribed MQTT data: "));
Serial.write((const char *)buf, len);
Serial.println();
}
}

// Wait for ~10 seconds
for (int i = 0; i < 1000; i++)
{
mySARA.bufferedPoll(); // Keep processing data from the SARA
delay(10);
}
}
4 changes: 4 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,16 @@ sendHTTPPOSTfile KEYWORD2
nvMQTT KEYWORD2
setMQTTclientId KEYWORD2
setMQTTserver KEYWORD2
setMQTTcredentials KEYWORD2
setMQTTsecure KEYWORD2
connectMQTT KEYWORD2
disconnectMQTT KEYWORD2
subscribeMQTTtopic KEYWORD2
unsubscribeMQTTtopic KEYWORD2
readMQTT KEYWORD2
mqttPublishTextMsg KEYWORD2
mqttPublishBinaryMsg KEYWORD2
mqttPublishFromFile KEYWORD2
getMQTTprotocolError KEYWORD2
resetSecurityProfile KEYWORD2
configSecurityProfileString KEYWORD2
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=SparkFun u-blox SARA-R5 Arduino Library
version=1.1.8
version=1.1.9
author=SparkFun Electronics <[email protected]>
maintainer=SparkFun Electronics <sparkfun.com>
sentence=Library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud<br/><br/>
Expand Down
2 changes: 1 addition & 1 deletion src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4814,7 +4814,7 @@ SARA_R5_error_t SARA_R5::setSecurityManager(SARA_R5_sec_manager_opcode_t opcode,
_debugPort->println(F(" bytes"));
}
hwWriteData(data.c_str(), dataLen);
err = waitForResponse(SARA_R5_RESPONSE_OK, SARA_R5_RESPONSE_ERROR, SARA_R5_STANDARD_RESPONSE_TIMEOUT*3);
err = waitForResponse(SARA_R5_RESPONSE_OK, SARA_R5_RESPONSE_ERROR, SARA_R5_SECURITY_RESPONSE_TIMEOUT);
}


Expand Down
1 change: 1 addition & 0 deletions src/SparkFun_u-blox_SARA-R5_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
#define SARA_R5_IP_CONNECT_TIMEOUT 130000
#define SARA_R5_POLL_DELAY 1
#define SARA_R5_SOCKET_WRITE_TIMEOUT 10000
#define SARA_R5_SECURITY_RESPONSE_TIMEOUT 10000

// ## Suported AT Commands
// ### General
Expand Down