├── .gitattributes
├── .github
└── workflows
│ ├── add_issue_to_project.yml
│ └── compile-sketch.yml
├── .gitignore
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE.md
├── README.md
├── Utils
├── Multi_TCP_Echo.py
└── Multi_UDP_Echo.py
├── examples
├── SARA-R5_Example10_SocketPingPong
│ └── SARA-R5_Example10_SocketPingPong.ino
├── SARA-R5_Example10_SocketPingPong_BinaryTCP
│ └── SARA-R5_Example10_SocketPingPong_BinaryTCP.ino
├── SARA-R5_Example10_SocketPingPong_MultipleTCP
│ └── SARA-R5_Example10_SocketPingPong_MultipleTCP.ino
├── SARA-R5_Example10_SocketPingPong_MultipleUDP
│ └── SARA-R5_Example10_SocketPingPong_MultipleUDP.ino
├── SARA-R5_Example11_Clock
│ └── SARA-R5_Example11_Clock.ino
├── SARA-R5_Example12_AssistNowOnline
│ ├── SARA-R5_AssistNow_Online.ino
│ ├── SARA-R5_Example12_AssistNowOnline.ino
│ └── secrets.h
├── SARA-R5_Example13_SetClockWithNTP
│ ├── SARA-R5_Example13_SetClockWithNTP.ino
│ └── SARA-R5_NTP.ino
├── SARA-R5_Example14_AssistNowOffline
│ ├── SARA-R5_AssistNow_Offline.ino
│ ├── SARA-R5_Example14_AssistNowOffline.ino
│ ├── SARA-R5_NTP.ino
│ └── secrets.h
├── SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks
│ ├── GNSS_Callbacks.ino
│ ├── SARA-R5_Callbacks.ino
│ ├── SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks.ino
│ ├── SARA-R5_NTRIP_Client.ino
│ ├── Utils.ino
│ └── secrets.h
├── SARA-R5_Example16_GNSS_NTRIP_Caster__Polling
│ ├── SARA-R5_Example16_GNSS_NTRIP_Caster__Polling.ino
│ ├── SARA-R5_NTRIP_Client.ino
│ └── secrets.h
├── SARA-R5_Example17_ThingSpeak_MQTT
│ └── SARA-R5_Example17_ThingSpeak_MQTT.ino
├── SARA-R5_Example1_GNSS_GPRMC
│ └── SARA-R5_Example1_GNSS_GPRMC.ino
├── SARA-R5_Example2_Identification
│ └── SARA-R5_Example2_Identification.ino
├── SARA-R5_Example2_Identification_ESPSoftwareSerial
│ └── SARA-R5_Example2_Identification_ESPSoftwareSerial.ino
├── SARA-R5_Example3_NetworkInfo
│ └── SARA-R5_Example3_NetworkInfo.ino
├── SARA-R5_Example4_RegisterOperator
│ └── SARA-R5_Example4_RegisterOperator.ino
├── SARA-R5_Example5_ReceiveSMS
│ └── SARA-R5_Example5_ReceiveSMS.ino
├── SARA-R5_Example6_SendSMS
│ └── SARA-R5_Example6_SendSMS.ino
├── SARA-R5_Example7_ConfigurePacketSwitchedData
│ └── SARA-R5_Example7_ConfigurePacketSwitchedData.ino
├── SARA-R5_Example8_Ping
│ └── SARA-R5_Example8_Ping.ino
└── SARA-R5_Example9_ThingSpeak
│ └── SARA-R5_Example9_ThingSpeak.ino
├── img
└── Contributing.JPG
├── keywords.txt
├── library.properties
└── src
├── SparkFun_u-blox_SARA-R5_Arduino_Library.cpp
└── SparkFun_u-blox_SARA-R5_Arduino_Library.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
--------------------------------------------------------------------------------
/.github/workflows/add_issue_to_project.yml:
--------------------------------------------------------------------------------
1 | name: Add new issue to our main project
2 |
3 | on:
4 | issues:
5 | types:
6 | - opened
7 |
8 | jobs:
9 | add-to-project:
10 | name: Add issue to project
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/add-to-project@main
14 | with:
15 | # You can target a project in a different organization
16 | # to the issue
17 | project-url: https://github.com/orgs/sparkfun/projects/19
18 | github-token: ${{ secrets.DEFECT_ADD_TO_PROJECT }}
19 |
--------------------------------------------------------------------------------
/.github/workflows/compile-sketch.yml:
--------------------------------------------------------------------------------
1 | name: Compile Sketch
2 |
3 | on:
4 | # push:
5 |
6 | pull_request:
7 |
8 | workflow_dispatch:
9 |
10 | jobs:
11 | compile-sketch:
12 | runs-on: ubuntu-latest
13 |
14 | strategy:
15 | fail-fast: false
16 |
17 | matrix:
18 | board:
19 | # ATmega2560
20 | # https://github.com/arduino/ArduinoCore-avr/blob/master/boards.txt
21 | - fqbn: arduino:avr:mega
22 | platforms: |
23 | - name: arduino:avr
24 | source-url: https://downloads.arduino.cc/packages/package_index.json
25 |
26 | # ESP32
27 | # https://github.com/espressif/arduino-esp32/blob/master/boards.txt
28 | - fqbn: esp32:esp32:esp32
29 | platforms: |
30 | - name: esp32:esp32
31 | source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
32 |
33 | # ESP32-S2
34 | # https://github.com/espressif/arduino-esp32/blob/master/boards.txt
35 | - fqbn: esp32:esp32:esp32s2
36 | platforms: |
37 | - name: esp32:esp32
38 | source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
39 |
40 | # ESP32-C3
41 | # https://github.com/espressif/arduino-esp32/blob/master/boards.txt
42 | - fqbn: esp32:esp32:esp32c3
43 | platforms: |
44 | - name: esp32:esp32
45 | source-url: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
46 |
47 | # Artemis / Apollo3
48 | # https://github.com/sparkfun/Arduino_Apollo3/blob/main/boards.txt
49 | - fqbn: SparkFun:apollo3:sfe_artemis_atp
50 | platforms: |
51 | - name: SparkFun:apollo3
52 | source-url: https://raw.githubusercontent.com/sparkfun/Arduino_Apollo3/master/package_sparkfun_apollo3_index.json
53 |
54 | # ESP8266
55 | # https://github.com/esp8266/Arduino/blob/master/boards.txt
56 | - fqbn: esp8266:esp8266:thingdev
57 | platforms: |
58 | - name: esp8266:esp8266
59 | source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json
60 |
61 | # SAMD21
62 | # https://github.com/arduino/ArduinoCore-samd/blob/master/boards.txt
63 | - fqbn: arduino:samd:mkr1000
64 | platforms: |
65 | - name: arduino:samd
66 | # source-url: https://downloads.arduino.cc/packages/package_index.json
67 |
68 | # Nano BLE 33 / nRF52840
69 | # https://github.com/arduino/ArduinoCore-mbed/blob/master/boards.txt
70 | - fqbn: arduino:mbed:nano33ble
71 | platforms: |
72 | - name: arduino:mbed
73 | # source-url: https://downloads.arduino.cc/packages/package_index.json
74 |
75 | # RP2040
76 | # https://github.com/arduino/ArduinoCore-mbed/blob/master/boards.txt
77 | - fqbn: rp2040:rp2040:sparkfun_promicrorp2040
78 | platforms: |
79 | - name: rp2040:rp2040
80 | source-url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
81 |
82 | # STM32
83 | # https://github.com/arduino/ArduinoCore-mbed/blob/master/boards.txt
84 | - fqbn: STMicroelectronics:stm32:GenF4
85 | platforms: |
86 | - name: STMicroelectronics:stm32
87 | source-url: https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
88 |
89 | steps:
90 | - name: Checkout
91 | uses: actions/checkout@v2
92 |
93 | - name: Branch name
94 | run: echo running on branch ${GITHUB_REF##*/}
95 |
96 | - name: Compile Sketch
97 | uses: arduino/compile-sketches@v1
98 | with:
99 | platforms: ${{ matrix.board.platforms }}
100 | fqbn: ${{ matrix.board.fqbn }}
101 | libraries: |
102 | - source-path: ./
103 | sketch-paths: |
104 | - examples/SARA-R5_Example10_SocketPingPong
105 | enable-warnings-report: true
106 | enable-deltas-report: true
107 | # verbose: true
108 |
109 | # outputs:
110 | # report-artifact-name: ${{ steps.report-artifact-name.outputs.report-artifact-name }}
111 |
112 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # IDE settings directories/folders
2 | .vscode/
3 |
4 | # Windows image file caches
5 | Thumbs.db
6 | ehthumbs.db
7 |
8 | # Folder config file
9 | Desktop.ini
10 |
11 | # Recycle Bin used on file shares
12 | $RECYCLE.BIN/
13 |
14 | # Windows Installer files
15 | *.cab
16 | *.msi
17 | *.msm
18 | *.msp
19 |
20 | # Windows shortcuts
21 | *.lnk
22 |
23 | # C build files
24 | _build
25 | *.elf
26 | *.hex
27 | *.exe
28 |
29 | # Arduino CLI config file
30 | *.yml
31 | Makefile
32 |
33 | # =========================
34 | # Operating System Files
35 | # =========================
36 |
37 | # OSX
38 | # =========================
39 |
40 | .DS_Store
41 | .AppleDouble
42 | .LSOverride
43 |
44 | # Thumbnails
45 | ._*
46 |
47 | # Files that might appear in the root of a volume
48 | .DocumentRevisions-V100
49 | .fseventsd
50 | .Spotlight-V100
51 | .TemporaryItems
52 | .Trashes
53 | .VolumeIcon.icns
54 |
55 | # Directories potentially created on remote AFP share
56 | .AppleDB
57 | .AppleDesktop
58 | Network Trash Folder
59 | Temporary Items
60 | .apdisk
61 |
62 | # Test examples
63 | test
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | Thank you so *much* for offering to help out. We truly appreciate it.
4 |
5 | If you'd like to contribute, start by searching through the [issues](https://github.com/sparkfun/SparkFun_u-blox_SARA-R5_Arduino_Library/issues) and [pull requests](https://github.com/sparkfun/SparkFun_u-blox_SARA-R5_Arduino_Library/pulls) to see whether someone else has raised a similar idea or question.
6 | Please check the [closed issues](https://github.com/sparkfun/SparkFun_u-blox_SARA-R5_Arduino_Library/issues?q=is%3Aissue+is%3Aclosed)
7 | and [closed pull requests](https://github.com/sparkfun/SparkFun_u-blox_SARA-R5_Arduino_Library/pulls?q=is%3Apr+is%3Aclosed) too - you may find that your issue or feature has already been discussed.
8 |
9 | If you decide to add a feature to this library, please create a PR and follow these best practices:
10 |
11 | * Change as little as possible. Do not submit a PR that changes 100 lines of whitespace. Break up into multiple PRs if necessary.
12 | * If you've added a new feature document it with a simple example sketch. This serves both as a test of your PR and as a quick way for users to quickly learn how to use your new feature.
13 | * If you add new functions also add them to _keywords.txt_ so that they are properly highlighted in Arduino. [Read more](https://www.arduino.cc/en/Hacking/libraryTutorial).
14 | * **Important:** Please submit your PR using the [release_candidate branch](https://github.com/sparkfun/SparkFun_u-blox_SARA-R5_Arduino_Library/tree/release_candidate). That way, we can merge and test your PR quickly without changing the _master_ branch
15 |
16 | 
17 |
18 | ## Style guide
19 |
20 | Please read and follow the [Arduino API style guide](https://www.arduino.cc/en/Reference/APIStyleGuide). Also read and consider the [Arduino style guide](https://www.arduino.cc/en/Reference/StyleGuide).
21 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Subject of the issue
2 | Describe your issue here.
3 |
4 | ### Your workbench
5 | * What platform are you using?
6 | * What version of the device are you using? Is there a firmware version?
7 | * How is the device wired to your platform?
8 | * How is everything being powered?
9 | * Are there any additional details that may help us help you?
10 |
11 | ### Steps to reproduce
12 | Tell us how to reproduce this issue. Please post stripped down example code demonstrating your issue to a gist.
13 |
14 | ### Expected behaviour
15 | Tell us what should happen
16 |
17 | ### Actual behaviour
18 | Tell us what happens instead
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | SparkFun License Information
2 | ============================
3 |
4 | SparkFun uses two different licenses for our files — one for hardware and one for code.
5 |
6 | Hardware
7 | ---------
8 |
9 | **SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).**
10 |
11 | Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode).
12 |
13 | You are free to:
14 |
15 | Share — copy and redistribute the material in any medium or format
16 | Adapt — remix, transform, and build upon the material
17 | for any purpose, even commercially.
18 | The licensor cannot revoke these freedoms as long as you follow the license terms.
19 | Under the following terms:
20 |
21 | Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
22 | ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
23 | No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
24 | Notices:
25 |
26 | You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
27 | No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
28 |
29 |
30 | Code
31 | --------
32 |
33 | **SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).**
34 |
35 | The MIT License (MIT)
36 |
37 | Copyright (c) 2020 SparkFun Electronics
38 |
39 | Permission is hereby granted, free of charge, to any person obtaining a copy
40 | of this software and associated documentation files (the "Software"), to deal
41 | in the Software without restriction, including without limitation the rights
42 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
43 | copies of the Software, and to permit persons to whom the Software is
44 | furnished to do so, subject to the following conditions:
45 |
46 | The above copyright notice and this permission notice shall be included in all
47 | copies or substantial portions of the Software.
48 |
49 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55 | SOFTWARE.
56 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | SparkFun u-blox SARA-R5 Arduino Library
2 | ==============================
3 |
4 |
16 |
17 | An Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the [SparkFun MicroMod Asset Tracker](https://www.sparkfun.com/products/17272), the [SparkFun LTE GNSS Breakout - SARA-R5](https://www.sparkfun.com/products/18031), and the [SparkFun MicroMod LTE GNSS Function Board - u-blox SARA-R5](https://www.sparkfun.com/products/18431)
18 |
19 | v1.1 has had a thorough update and includes new features and examples. This library now supports up to 7 simultaneous TCP or UDP sockets. There are new examples to show how to play ping pong with multiple TCP and UDP sockets.
20 |
21 | v1.1 also supports binary data transfers correctly. There are new examples showing how you can integrate this library with the [SparkFun u-blox GNSS Arduino Library](https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library) and use the SARA-R5 to: download AssistNow Online and Offline data and push it to the GNSS; open a connection to a NTRIP Caster (such as RTK2go, Skylark or Emlid Caster) and push RTK correction data to the GNSS.
22 |
23 | You can install this library using the Arduino IDE Library Manager: search for _**SparkFun u-blox SARA-R5**_
24 |
25 | ## Repository Contents
26 |
27 | * **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE.
28 | * **/src** - Source files for the library (.cpp, .h).
29 | * **keywords.txt** - Keywords from this library that will be highlighted in the Arduino IDE.
30 | * **library.properties** - General library properties for the Arduino package manager.
31 |
32 | ## Contributing
33 |
34 | If you would like to contribute to this library: please do, we truly appreciate it, but please follow [these guidelines](./CONTRIBUTING.md). Thanks!
35 |
36 | ## Documentation
37 |
38 | * **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library.
39 | * **MicroMod Asset Tracker**
40 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/micromod-asset-tracker-carrier-board-hookup-guide)** - Hookup Guide for the MicroMod Asset Tracker Carrier Board.
41 | * **[GitHub Product Repository](https://github.com/sparkfun/MicroMod_Asset_Tracker)** - MicroMod Asset Tracker repository (including hardware files).
42 | * **SparkFun LTE GNSS Breakout - SARA-R5**
43 | * **[Hookup Guide](https://learn.sparkfun.com/tutorials/lte-gnss-breakout---sara-r5-hookup-guide)** - Hookup Guide for the LTE GNSS Breakout - SARA-R5.
44 | * **[GitHub Product Repository](https://github.com/sparkfun/SparkFun_LTE_GNSS_Breakout_SARA-R510M8S)** - LTE GNSS Breakout - SARA-R5 repository (including hardware files).
45 | * **SparkFun MicroMod LTE GNSS Function Board - u-blox SARA - R5**
46 | * **[Hookup Guide](https://docs.sparkfun.com/SparkFun_MicroMod_LTE_GNSS_Function_Board_u-blox_SARA-R5/)** - Hookup Guide for the SparkFun MicroMod LTE GNSS Function Board - u-blox SARA-R5.
47 | * **[GitHub Product Repository](https://github.com/sparkfun/SparkFun_MicroMod_LTE_GNSS_Function_Board_u-blox_SARA-R5)** - SparkFun MicroMod LTE GNSS Function Board - u-blox SARA-R5 repository (including hardware files).
48 | * **[LICENSE.md](./LICENSE.md)** - License Information
49 |
50 | ## Products that use this library
51 |
52 | * **[DEV-17272](https://www.sparkfun.com/products/17272)** - MicroMod Asset Tracker
53 | * **[GPS-18031](https://www.sparkfun.com/products/18031)** - SparkFun LTE GNSS Breakout - SARA-R5
54 | * **[DEV-18031](https://www.sparkfun.com/products/18431)** - SparkFun MicroMod LTE GNSS Function Board - u-blox SARA-R5
55 |
56 | - Your friends at SparkFun.
57 |
--------------------------------------------------------------------------------
/Utils/Multi_TCP_Echo.py:
--------------------------------------------------------------------------------
1 | # Multiple TCP Echo Server
2 | # Based on the third example from:
3 | # https://rosettacode.org/wiki/Echo_server#Python
4 |
5 | #!usr/bin/env python
6 | import socket
7 | import threading
8 |
9 | NUM_PORTS = 5 # Echo on this many ports starting at PORT_BASE
10 | PORT_BASE = 1200 # Change this if required
11 | HOST = '192.168.0.50' # Change this to match your local IP
12 | SOCKET_TIMEOUT = 30
13 |
14 | # This function handles reading data sent by a client, echoing it back
15 | # and closing the connection in case of timeout (30s) or "quit" command
16 | # This function is meant to be started in a separate thread
17 | # (one thread per client)
18 | def handle_echo(client_connection, client_address, port):
19 | client_connection.settimeout(SOCKET_TIMEOUT)
20 | try:
21 | while True:
22 | data = client_connection.recv(1024)
23 | # Close connection if "quit" received from client
24 | if data == b'quit\r\n' or data == b'quit\n':
25 | print('{} : {} disconnected'.format(client_address,port))
26 | client_connection.shutdown(1)
27 | client_connection.close()
28 | break
29 | # Echo back to client
30 | elif data:
31 | print('FROM {} : {} : {}'.format(client_address,port,data))
32 | client_connection.send(data)
33 | # Timeout and close connection after 30s of inactivity
34 | except socket.timeout:
35 | print('{} : {} timed out'.format(client_address,port))
36 | client_connection.shutdown(1)
37 | client_connection.close()
38 |
39 | # This function opens a socket and listens on specified port. As soon as a
40 | # connection is received, it is transfered to another socket so that the main
41 | # socket is not blocked and can accept new clients.
42 | def listen(host, port):
43 | # Create the main socket (IPv4, TCP)
44 | connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
45 | connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
46 | connection.bind((host, port))
47 | # Listen for clients (max 10 clients in waiting)
48 | connection.listen(10)
49 | # Every time a client connects, allow a dedicated socket and a dedicated
50 | # thread to handle communication with that client without blocking others.
51 | # Once the new thread has taken over, wait for the next client.
52 | while True:
53 | current_connection, client_address = connection.accept()
54 | print('{} : {} connected'.format(client_address, port))
55 | handler_thread = threading.Thread( \
56 | target = handle_echo, \
57 | args = (current_connection,client_address,port) \
58 | )
59 | # daemon makes sure all threads are killed if the main server process
60 | # gets killed
61 | handler_thread.daemon = True
62 | handler_thread.start()
63 |
64 | if __name__ == "__main__":
65 | print('starting')
66 |
67 | threads = list()
68 |
69 | for i in range(NUM_PORTS):
70 | threads.append( threading.Thread( \
71 | target = listen, args = (HOST, PORT_BASE + i)) )
72 | threads[i].daemon = True
73 | threads[i].start()
74 |
75 |
--------------------------------------------------------------------------------
/Utils/Multi_UDP_Echo.py:
--------------------------------------------------------------------------------
1 | # Multiple UDP Echo Server
2 | # Based on code by David Manouchehri
3 | # Threading added by PaulZC
4 |
5 | #!/usr/bin/env python2
6 | # -*- coding: utf-8 -*-
7 |
8 | # Original author: David Manouchehri
9 | # This script will always echo back data on the UDP port of your choice.
10 | # Useful if you want nmap to report a UDP port as "open" instead of "open|filtered" on a standard scan.
11 | # Works with both Python 2 & 3.
12 |
13 | import socket
14 | import threading
15 |
16 | num_ports = 5 # Echo on this many ports starting at server_port_base
17 | server_port_base = 1200 # Change this if required
18 | server_address = '192.168.0.50' # Change this to match your local IP
19 |
20 | def echo(address, port):
21 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
22 | serv = (address, port)
23 | sock.bind(serv)
24 | while True:
25 | payload, client_address = sock.recvfrom(4) # Try to receive 4 bytes
26 | print("Port " + str(port) + ": Echoing 4 bytes back to " + str(client_address))
27 | sent = sock.sendto(payload, client_address)
28 |
29 | if __name__ == "__main__":
30 | print("Listening on " + server_address)
31 |
32 | threads = list()
33 |
34 | for i in range(num_ports):
35 | threads.append( threading.Thread( \
36 | target = echo, args = (server_address, server_port_base + i)) )
37 | threads[i].daemon = True
38 | threads[i].start()
39 |
40 |
41 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example11_Clock/SARA-R5_Example11_Clock.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Clock
7 |
8 | Written by: Paul Clark
9 | Date: January 3rd 2022
10 |
11 | This example demonstrates how to use the clock function to read the time from the SARA-R5.
12 |
13 | Note: the clock will be set to network time only if your network supports NITZ (Network Identity and Time Zone)
14 |
15 | Feel like supporting open source hardware?
16 | Buy a board from SparkFun!
17 |
18 | Licence: MIT
19 | Please see LICENSE.md for full details
20 |
21 | */
22 |
23 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
24 |
25 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
26 | #define saraSerial Serial1
27 |
28 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
29 | //SoftwareSerial saraSerial(8, 9);
30 |
31 | // Create a SARA_R5 object to use throughout the sketch
32 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
33 | // but we can start the SARA without a power pin. It just means we need to manually
34 | // turn the power on if required! ;-D
35 | SARA_R5 mySARA;
36 |
37 | // Create a SARA_R5 object to use throughout the sketch
38 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
39 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
40 | // the pin name is G2 which is connected to pin AD34.
41 | // Change the pin number if required.
42 | //SARA_R5 mySARA(34);
43 |
44 | void setup()
45 | {
46 | Serial.begin(115200); // Start the serial console
47 |
48 | // Wait for user to press key to begin
49 | Serial.println(F("SARA-R5 Example"));
50 |
51 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
52 |
53 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
54 | // Comment the next line if required
55 | mySARA.invertPowerPin(true);
56 |
57 | // Initialize the SARA
58 | if (mySARA.begin(saraSerial, 9600) )
59 | {
60 | Serial.println(F("SARA-R5 connected!"));
61 | }
62 | else
63 | {
64 | Serial.println(F("Unable to communicate with the SARA."));
65 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
66 | while (1) ; // Loop forever on fail
67 | }
68 | Serial.println();
69 |
70 | // Make sure automatic time zone updates are enabled
71 | if (mySARA.autoTimeZone(true) != SARA_R5_SUCCESS)
72 | Serial.println(F("Enable autoTimeZone failed!"));
73 |
74 | // Read and print the clock as a String
75 | String theTime = mySARA.clock();
76 | Serial.println(theTime);
77 |
78 | // Read and print the hour, minute, etc. separately
79 | uint8_t year, month, day, hour, minute, second;
80 | int8_t timeZone;
81 | if (mySARA.clock( &year, &month, &day, &hour, &minute, &second, &timeZone ) == SARA_R5_SUCCESS)
82 | // Note: not all Arduino boards implement printf correctly. The formatting may not be correct on some boards.
83 | // Note: the timeZone is defined in 15 minute increments, not hours. -28 indicates the time zone is 7 hours behind UTC/GMT.
84 | Serial.printf("%02d/%02d/%02d %02d:%02d:%02d %+d\r\n", year, month, day, hour, minute, second, timeZone);
85 |
86 | }
87 |
88 | void loop()
89 | {
90 | // Nothing to do here
91 | }
92 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example12_AssistNowOnline/SARA-R5_AssistNow_Online.ino:
--------------------------------------------------------------------------------
1 |
2 | #include "secrets.h" // Update secrets.h with your AssistNow token string
3 |
4 | // u-blox AssistNow https servers
5 | const char assistNowServer[] = "online-live1.services.u-blox.com";
6 | //const char assistNowServer[] = "online-live2.services.u-blox.com"; // Alternate server
7 |
8 | const char getQuery[] = "GetOnlineData.ashx?";
9 | const char tokenPrefix[] = "token=";
10 | const char tokenSuffix[] = ";";
11 | const char getGNSS[] = "gnss=gps,glo;"; // GNSS can be: gps,qzss,glo,bds,gal
12 | const char getDataType[] = "datatype=eph,alm,aux;"; // Data type can be: eph,alm,aux,pos
13 |
14 | volatile bool httpResultSeen = false; // Flag to indicate that the HTTP URC was received
15 |
16 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
17 |
18 | // processHTTPcommandResult is provided to the SARA-R5 library via a
19 | // callback setter -- setHTTPCommandCallback. (See the end of setup())
20 | void processHTTPcommandResult(int profile, int command, int result)
21 | {
22 | Serial.println();
23 | Serial.print(F("HTTP Command Result: profile: "));
24 | Serial.print(profile);
25 | Serial.print(F(" command: "));
26 | Serial.print(command);
27 | Serial.print(F(" result: "));
28 | Serial.print(result);
29 | if (result == 0)
30 | Serial.print(F(" (fail)"));
31 | if (result == 1)
32 | Serial.print(F(" (success)"));
33 | Serial.println();
34 |
35 | // Get and print the most recent HTTP protocol error
36 | int error_class;
37 | int error_code;
38 | mySARA.getHTTPprotocolError(0, &error_class, &error_code);
39 | Serial.print(F("Most recent HTTP protocol error: class: "));
40 | Serial.print(error_class);
41 | Serial.print(F(" code: "));
42 | Serial.print(error_code);
43 | if (error_code == 0)
44 | Serial.print(F(" (no error)"));
45 | Serial.println();
46 |
47 | httpResultSeen = true; // Set the flag
48 | }
49 |
50 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
51 |
52 | bool getAssistNowOnlineData(String theFilename)
53 | {
54 | // Use HTTP GET to receive the AssistNow_Online data. Store it in the SARA-R5's internal file system.
55 |
56 | String theServer = assistNowServer; // Convert the AssistNow server to String
57 |
58 | const int REQUEST_BUFFER_SIZE = 256;
59 | char theRequest[REQUEST_BUFFER_SIZE];
60 |
61 | // Assemble the request
62 | // Note the slash at the beginning
63 | snprintf(theRequest, REQUEST_BUFFER_SIZE, "/%s%s%s%s%s%s",
64 | getQuery,
65 | tokenPrefix,
66 | myAssistNowToken,
67 | tokenSuffix,
68 | getGNSS,
69 | getDataType);
70 |
71 | String theRequestStr = theRequest; // Convert to String
72 |
73 | Serial.print(F("getAssistNowOnlineData: HTTP GET is https://"));
74 | Serial.print(theServer);
75 | Serial.println(theRequestStr);
76 |
77 | Serial.print(F("getAssistNowOnlineData: the AssistNow data will be stored in: "));
78 | Serial.println(theFilename);
79 |
80 | // Reset HTTP profile 0
81 | mySARA.resetHTTPprofile(0);
82 |
83 | // Set the server name
84 | mySARA.setHTTPserverName(0, theServer);
85 |
86 | // Use HTTPS
87 | mySARA.setHTTPsecure(0, false); // Setting this to true causes the GET to fail. Maybe due to the default CMNG profile?
88 |
89 | // Set a callback to process the HTTP command result
90 | mySARA.setHTTPCommandCallback(&processHTTPcommandResult);
91 |
92 | httpResultSeen = false; // Clear the flag
93 |
94 | // HTTP GET
95 | mySARA.sendHTTPGET(0, theRequestStr, theFilename);
96 |
97 | // Wait for 20 seconds while calling mySARA.bufferedPoll() to see the HTTP result.
98 | Serial.print(F("getAssistNowOnlineData: Waiting up to 20 seconds for the HTTP Result"));
99 | int i = 0;
100 | while ((i < 20000) && (httpResultSeen == false))
101 | {
102 | mySARA.bufferedPoll(); // Keep processing data from the SARA so we can catch the HTTP command result
103 | i++;
104 | delay(1);
105 | if (i % 1000 == 0)
106 | Serial.print(F("."));
107 | }
108 | Serial.println();
109 |
110 | if (httpResultSeen == false)
111 | {
112 | Serial.print(F("getAssistNowOnlineData: HTTP GET failed!"));
113 | return false;
114 | }
115 |
116 | int fileSize;
117 | if (mySARA.getFileSize(theFilename, &fileSize) != SARA_R5_SUCCESS)
118 | {
119 | Serial.print(F("getAssistNowOnlineData: No file written?!"));
120 | return false;
121 | }
122 |
123 | Serial.print(F("File size is: "));
124 | Serial.println(fileSize);
125 |
126 | return true;
127 | }
128 |
129 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
130 |
131 | void prettyPrintString(String theString) // Pretty-print a String in HEX and ASCII format
132 | {
133 | int theLength = theString.length();
134 |
135 | Serial.println();
136 | Serial.print(F("String length is "));
137 | Serial.print(theLength);
138 | Serial.print(F(" (0x"));
139 | Serial.print(theLength, HEX);
140 | Serial.println(F(")"));
141 | Serial.println();
142 |
143 | for (int i = 0; i < theLength; i += 16)
144 | {
145 | if (i < 10000) Serial.print(F("0"));
146 | if (i < 1000) Serial.print(F("0"));
147 | if (i < 100) Serial.print(F("0"));
148 | if (i < 10) Serial.print(F("0"));
149 | Serial.print(i);
150 |
151 | Serial.print(F(" 0x"));
152 |
153 | if (i < 0x1000) Serial.print(F("0"));
154 | if (i < 0x100) Serial.print(F("0"));
155 | if (i < 0x10) Serial.print(F("0"));
156 | Serial.print(i, HEX);
157 |
158 | Serial.print(F(" "));
159 |
160 | int j;
161 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
162 | {
163 | if (theString[i + j] < 0x10) Serial.print(F("0"));
164 | Serial.print(theString[i + j], HEX);
165 | Serial.print(F(" "));
166 | }
167 |
168 | if (((i + j) == theLength) && (j < 16))
169 | {
170 | for (int k = 0; k < (16 - (theLength % 16)); k++)
171 | {
172 | Serial.print(F(" "));
173 | }
174 | }
175 |
176 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
177 | {
178 | if ((theString[i + j] >= 0x20) && (theString[i + j] <= 0x7E))
179 | Serial.write(theString[i + j]);
180 | else
181 | Serial.print(F("."));
182 | }
183 |
184 | Serial.println();
185 | }
186 |
187 | Serial.println();
188 | }
189 |
190 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
191 |
192 | void prettyPrintChars(char *theData, int theLength) // Pretty-print char data in HEX and ASCII format
193 | {
194 | Serial.println();
195 | Serial.print(F("String length is "));
196 | Serial.print(theLength);
197 | Serial.print(F(" (0x"));
198 | Serial.print(theLength, HEX);
199 | Serial.println(F(")"));
200 | Serial.println();
201 |
202 | for (int i = 0; i < theLength; i += 16)
203 | {
204 | if (i < 10000) Serial.print(F("0"));
205 | if (i < 1000) Serial.print(F("0"));
206 | if (i < 100) Serial.print(F("0"));
207 | if (i < 10) Serial.print(F("0"));
208 | Serial.print(i);
209 |
210 | Serial.print(F(" 0x"));
211 |
212 | if (i < 0x1000) Serial.print(F("0"));
213 | if (i < 0x100) Serial.print(F("0"));
214 | if (i < 0x10) Serial.print(F("0"));
215 | Serial.print(i, HEX);
216 |
217 | Serial.print(F(" "));
218 |
219 | int j;
220 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
221 | {
222 | if (theData[i + j] < 0x10) Serial.print(F("0"));
223 | Serial.print(theData[i + j], HEX);
224 | Serial.print(F(" "));
225 | }
226 |
227 | if (((i + j) == theLength) && (j < 16))
228 | {
229 | for (int k = 0; k < (16 - (theLength % 16)); k++)
230 | {
231 | Serial.print(F(" "));
232 | }
233 | }
234 |
235 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
236 | {
237 | if ((theData[i + j] >= 0x20) && (theData[i + j] <= 0x7E))
238 | Serial.write(theData[i + j]);
239 | else
240 | Serial.print(F("."));
241 | }
242 |
243 | Serial.println();
244 | }
245 |
246 | Serial.println();
247 | }
248 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example12_AssistNowOnline/SARA-R5_Example12_AssistNowOnline.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | u-blox AssistNow Online
7 |
8 | Written by: Paul Clark
9 | Date: January 8th 2021
10 |
11 | This example uses the SARA's mobile data connection to:
12 | * Request AssistNow Online data from the u-blox server
13 | * Provide assistance data to an external u-blox GNSS module over I2C (not to the one built-in to the SARA-R510M8S)
14 |
15 | The PDP profile is read from NVM. Please make sure you have run examples 4 & 7 previously to set up the profile.
16 |
17 | You will need to have a token to be able to access Thingstream. See the AssistNow README for more details:
18 | https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library/tree/main/examples/AssistNow
19 |
20 | Update secrets.h with your AssistNow token string
21 |
22 | Note: this code does not use the AssistNow or CellLocate features built-in to the SARA-R510M8S.
23 | Those features are great but the assistance data remains 'hidden' and cannot be read and passed to an external GNSS.
24 | This code downloads the assistance data to the SARA-R5's internal file system where it can be accessed,
25 | used and re-used with an external GNSS.
26 |
27 | Feel like supporting open source hardware?
28 | Buy a board from SparkFun!
29 |
30 | Licence: MIT
31 | Please see LICENSE.md for full details
32 |
33 | */
34 |
35 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
36 |
37 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
38 |
39 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
40 | #define saraSerial Serial1
41 |
42 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
43 | //SoftwareSerial saraSerial(8, 9);
44 |
45 | // Create a SARA_R5 object to use throughout the sketch
46 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
47 | // but we can start the SARA without a power pin. It just means we need to manually
48 | // turn the power on if required! ;-D
49 | SARA_R5 mySARA;
50 |
51 | // Create a SARA_R5 object to use throughout the sketch
52 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
53 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
54 | // the pin name is G2 which is connected to pin AD34.
55 | // Change the pin number if required.
56 | //SARA_R5 mySARA(34);
57 |
58 | // Create a SARA_R5 object to use throughout the sketch
59 | // If you are using the LTE GNSS Breakout, and have access to the SARA's RESET_N pin, you can pass that to the library too
60 | // allowing it to do an emergency shutdown if required.
61 | // Change the pin numbers if required.
62 | //SARA_R5 mySARA(34, 35); // PWR_ON, RESET_N
63 |
64 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
65 |
66 | #include //http://librarymanager/All#SparkFun_u-blox_GNSS
67 | SFE_UBLOX_GNSS myGNSS;
68 |
69 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
70 |
71 | void setup()
72 | {
73 | String currentOperator = "";
74 |
75 | Serial.begin(115200); // Start the serial console
76 |
77 | // Wait for user to press key to begin
78 | Serial.println(F("SARA-R5 Example"));
79 | Serial.println(F("Wait for the SARA NI LED to light up - then press any key to begin"));
80 |
81 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
82 | ;
83 | while (Serial.available()) // Empty the serial RX buffer
84 | Serial.read();
85 |
86 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
87 |
88 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
89 |
90 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
91 | // Comment the next line if required
92 | mySARA.invertPowerPin(true);
93 |
94 | // Initialize the SARA
95 | if (mySARA.begin(saraSerial, 115200) )
96 | {
97 | Serial.println(F("SARA-R5 connected!"));
98 | }
99 | else
100 | {
101 | Serial.println(F("Unable to communicate with the SARA."));
102 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
103 | while (1) ; // Loop forever on fail
104 | }
105 | Serial.println();
106 |
107 | // First check to see if we're connected to an operator:
108 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
109 | {
110 | Serial.print(F("Connected to: "));
111 | Serial.println(currentOperator);
112 | }
113 | else
114 | {
115 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
116 | while (1)
117 | ; // Do nothing more
118 | }
119 |
120 | // Deactivate the PSD profile - in case one is already active
121 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
122 | {
123 | Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
124 | }
125 |
126 | // Load the PSD profile from NVM - these were saved by a previous example
127 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_LOAD) != SARA_R5_SUCCESS)
128 | {
129 | Serial.println(F("performPDPaction (load from NVM) failed! Freezing..."));
130 | while (1)
131 | ; // Do nothing more
132 | }
133 |
134 | // Activate the profile
135 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
136 | {
137 | Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
138 | while (1)
139 | ; // Do nothing more
140 | }
141 |
142 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
143 |
144 | // Start I2C. Connect to the GNSS.
145 |
146 | Wire.begin(); //Start I2C
147 |
148 | //myGNSS.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
149 |
150 | if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port
151 | {
152 | Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
153 | while (1);
154 | }
155 | Serial.println(F("u-blox module connected"));
156 |
157 | myGNSS.setI2COutput(COM_TYPE_UBX); //Turn off NMEA noise
158 |
159 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
160 |
161 | // Request the AssistNow data from the server. Data is stored in the SARA's file system.
162 |
163 | String theFilename = "assistnow_online.ubx"; // The file that will contain the AssistNow Online data
164 |
165 | if (getAssistNowOnlineData(theFilename) == false) // See SARA-R5_AssistNow_Online.ino
166 | {
167 | Serial.println(F("getAssistNowOnlineData failed! Freezing..."));
168 | while (1)
169 | ; // Do nothing more
170 | }
171 |
172 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
173 |
174 | // Read the AssistNow data from file and push it to the module
175 |
176 | int fileSize;
177 | if (mySARA.getFileSize(theFilename, &fileSize) != SARA_R5_SUCCESS)
178 | {
179 | Serial.print(F("getFileSize failed! Freezing..."));
180 | while (1)
181 | ; // Do nothing more
182 | }
183 |
184 | Serial.print(F("AssistNow file size is: "));
185 | Serial.println(fileSize);
186 |
187 | // Read the data from file
188 | char *theAssistData = new char[fileSize];
189 | if (mySARA.getFileContents(theFilename, theAssistData) != SARA_R5_SUCCESS)
190 | {
191 | Serial.println(F("getFileContents failed! Freezing..."));
192 | while (1)
193 | ; // Do nothing more
194 | }
195 |
196 | //prettyPrintChars(theAssistData, fileSize); // Uncomment this line to see the whole file contents (including the HTTP header)
197 |
198 | // Tell the module to return UBX_MGA_ACK_DATA0 messages when we push the AssistNow data
199 | myGNSS.setAckAiding(1);
200 |
201 | // Speed things up by setting setI2CpollingWait to 1ms
202 | myGNSS.setI2CpollingWait(1);
203 |
204 | // Push all the AssistNow data.
205 | //
206 | // pushAssistNowData is clever and will only push valid UBX-format data.
207 | // It will ignore the HTTP header at the start of the AssistNow file.
208 | //
209 | // We have called setAckAiding(1) to instruct the module to return MGA-ACK messages.
210 | // So, set the pushAssistNowData mgaAck parameter to SFE_UBLOX_MGA_ASSIST_ACK_YES.
211 | // Wait for up to 100ms for each ACK to arrive! 100ms is a bit excessive... 7ms is nearer the mark.
212 | myGNSS.pushAssistNowData((const uint8_t *)theAssistData, fileSize, SFE_UBLOX_MGA_ASSIST_ACK_YES, 100);
213 |
214 | // Delete the memory allocated to store the AssistNow data
215 | delete[] theAssistData;
216 |
217 | // Set setI2CpollingWait to 125ms to avoid pounding the I2C bus
218 | myGNSS.setI2CpollingWait(125);
219 |
220 | // Delete the file after use. This is optional as the SARA will automatically overwrite the file.
221 | // And you might want to reuse it? AssistNow Online data is valid for 2-4 hours.
222 | //if (mySARA.deleteFile(theFilename) != SARA_R5_SUCCESS)
223 | //{
224 | // Serial.println(F("Warning: deleteFile failed!"));
225 | //}
226 | }
227 |
228 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
229 |
230 | void loop()
231 | {
232 | // Print the UBX-NAV-PVT data so we can see how quickly the fixType goes to 3D
233 |
234 | long latitude = myGNSS.getLatitude();
235 | Serial.print(F("Lat: "));
236 | Serial.print(latitude);
237 |
238 | long longitude = myGNSS.getLongitude();
239 | Serial.print(F(" Long: "));
240 | Serial.print(longitude);
241 | Serial.print(F(" (degrees * 10^-7)"));
242 |
243 | long altitude = myGNSS.getAltitude();
244 | Serial.print(F(" Alt: "));
245 | Serial.print(altitude);
246 | Serial.print(F(" (mm)"));
247 |
248 | byte SIV = myGNSS.getSIV();
249 | Serial.print(F(" SIV: "));
250 | Serial.print(SIV);
251 |
252 | byte fixType = myGNSS.getFixType();
253 | Serial.print(F(" Fix: "));
254 | if(fixType == 0) Serial.print(F("No fix"));
255 | else if(fixType == 1) Serial.print(F("Dead reckoning"));
256 | else if(fixType == 2) Serial.print(F("2D"));
257 | else if(fixType == 3) Serial.print(F("3D"));
258 | else if(fixType == 4) Serial.print(F("GNSS + Dead reckoning"));
259 | else if(fixType == 5) Serial.print(F("Time only"));
260 |
261 | Serial.println();
262 | }
263 |
264 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
265 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example12_AssistNowOnline/secrets.h:
--------------------------------------------------------------------------------
1 | //Your AssistNow token
2 | const char myAssistNowToken[] = "58XXXXXXXXXXXXXXXXXXYQ";
3 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example13_SetClockWithNTP/SARA-R5_Example13_SetClockWithNTP.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Set Clock With NTP
7 |
8 | Written by: Paul Clark
9 | Date: January 9th 2022
10 |
11 | This example demonstrates how to set the SARA-R5's internal Real Time Clock using NTP.
12 | When the SARA-R5 registers on a network, it will set its clock automatically if:
13 | Automatic time zone is enabled
14 | Your network supports NITZ (Network Identity and Time Zone)
15 | But for things like AssistNow Offline, it is convenient to have the SARA's RTC set to UTC.
16 | Then the clock can be used to select the AssistNow data for now/today without time zone headaches.
17 | This example shows how to:
18 | Disable the automatic time zone (using autoTimeZoneForBegin before .begin)
19 | Set the SARA's clock to UTC using NTP (see SARA-R5_NTP.ino)
20 |
21 | The PDP profile is read from NVM. Please make sure you have run examples 4 & 7 previously to set up the profile.
22 |
23 | Feel like supporting open source hardware?
24 | Buy a board from SparkFun!
25 |
26 | Licence: MIT
27 | Please see LICENSE.md for full details
28 |
29 | */
30 |
31 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
32 |
33 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
34 |
35 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
36 | #define saraSerial Serial1
37 |
38 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
39 | //SoftwareSerial saraSerial(8, 9);
40 |
41 | // Create a SARA_R5 object to use throughout the sketch
42 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
43 | // but we can start the SARA without a power pin. It just means we need to manually
44 | // turn the power on if required! ;-D
45 | SARA_R5 mySARA;
46 |
47 | // Create a SARA_R5 object to use throughout the sketch
48 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
49 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
50 | // the pin name is G2 which is connected to pin AD34.
51 | // Change the pin number if required.
52 | //SARA_R5 mySARA(34);
53 |
54 | // Create a SARA_R5 object to use throughout the sketch
55 | // If you are using the LTE GNSS Breakout, and have access to the SARA's RESET_N pin, you can pass that to the library too
56 | // allowing it to do an emergency shutdown if required.
57 | // Change the pin numbers if required.
58 | //SARA_R5 mySARA(34, 35); // PWR_ON, RESET_N
59 |
60 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
61 |
62 | void setup()
63 | {
64 | String currentOperator = "";
65 |
66 | Serial.begin(115200); // Start the serial console
67 |
68 | // Wait for user to press key to begin
69 | Serial.println(F("SARA-R5 Example"));
70 | Serial.println(F("Wait for the SARA NI LED to light up - then press any key to begin"));
71 |
72 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
73 | ;
74 | while (Serial.available()) // Empty the serial RX buffer
75 | Serial.read();
76 |
77 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
78 |
79 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
80 |
81 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
82 | // Comment the next line if required
83 | mySARA.invertPowerPin(true);
84 |
85 | // Disable the automatic time zone so we can use UTC. We need to do this _before_ .begin
86 | mySARA.autoTimeZoneForBegin(false);
87 |
88 | // Initialize the SARA
89 | if (mySARA.begin(saraSerial, 115200) )
90 | {
91 | Serial.println(F("SARA-R5 connected!"));
92 | }
93 | else
94 | {
95 | Serial.println(F("Unable to communicate with the SARA."));
96 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
97 | while (1) ; // Loop forever on fail
98 | }
99 | Serial.println();
100 |
101 | // First check to see if we're connected to an operator:
102 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
103 | {
104 | Serial.print(F("Connected to: "));
105 | Serial.println(currentOperator);
106 | }
107 | else
108 | {
109 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
110 | while (1)
111 | ; // Do nothing more
112 | }
113 |
114 | // Deactivate the PSD profile - in case one is already active
115 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
116 | {
117 | Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
118 | }
119 |
120 | // Load the PSD profile from NVM - these were saved by a previous example
121 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_LOAD) != SARA_R5_SUCCESS)
122 | {
123 | Serial.println(F("performPDPaction (load from NVM) failed! Freezing..."));
124 | while (1)
125 | ; // Do nothing more
126 | }
127 |
128 | // Activate the profile
129 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
130 | {
131 | Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
132 | while (1)
133 | ; // Do nothing more
134 | }
135 |
136 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
137 |
138 | //Get the time from an NTP server and use it to set the clock. See SARA-R5_NTP.ino
139 | uint8_t y, mo, d, h, min, s;
140 | bool success = getNTPTime(&y, &mo, &d, &h, &min, &s);
141 | if (!success)
142 | {
143 | Serial.println(F("getNTPTime failed! Freezing..."));
144 | while (1)
145 | ; // Do nothing more
146 | }
147 |
148 | //Set the SARA's RTC. Set the time zone to zero so the clock uses UTC
149 | if (mySARA.setClock(y, mo, d, h, min, s, 0) != SARA_R5_SUCCESS)
150 | {
151 | Serial.println(F("setClock failed! Freezing..."));
152 | while (1)
153 | ; // Do nothing more
154 | }
155 |
156 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
157 |
158 | // Read and print the clock as a String
159 | Serial.print(F("The UTC time is: "));
160 | String theTime = mySARA.clock();
161 | Serial.println(theTime);
162 | }
163 |
164 | void loop()
165 | {
166 | // Nothing to do here
167 | }
168 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example13_SetClockWithNTP/SARA-R5_NTP.ino:
--------------------------------------------------------------------------------
1 |
2 | #include // Note: this is the standard c time library, not Time.h
3 |
4 | // Get the time from NTP
5 | // This code is based heavily on:
6 | // https://docs.arduino.cc/tutorials/mkr-nb-1500/mkr-nb-library-examples#mkr-nb-gprs-udp-ntp-client
7 | // Many thanks to: Michael Margolis, Tom Igoe, Arturo Guadalupi, et al
8 |
9 | // NTP Server
10 | const char* ntpServer = "pool.ntp.org"; // The Network Time Protocol Server
11 | //const char* ntpServer = "africa.pool.ntp.org"; // The Network Time Protocol Server
12 | //const char* ntpServer = "asia.pool.ntp.org"; // The Network Time Protocol Server
13 | //const char* ntpServer = "europe.pool.ntp.org"; // The Network Time Protocol Server
14 | //const char* ntpServer = "north-america.pool.ntp.org"; // The Network Time Protocol Server
15 | //const char* ntpServer = "oceania.pool.ntp.org"; // The Network Time Protocol Server
16 | //const char* ntpServer = "south-america.pool.ntp.org"; // The Network Time Protocol Server
17 |
18 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
19 |
20 | bool getNTPTime(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s)
21 | {
22 | int serverPort = 123; //NTP requests are to port 123
23 |
24 | // Set up the packetBuffer for the NTP request
25 | const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
26 | byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
27 |
28 | // set all bytes in the buffer to 0
29 | memset(packetBuffer, 0, NTP_PACKET_SIZE);
30 |
31 | // Initialize values needed to form NTP request
32 | packetBuffer[0] = 0b11100011; // LI, Version, Mode
33 | packetBuffer[1] = 0; // Stratum, or type of clock
34 | packetBuffer[2] = 6; // Polling Interval
35 | packetBuffer[3] = 0xEC; // Peer Clock Precision
36 | // 8 bytes of zero for Root Delay & Root Dispersion
37 | packetBuffer[12] = 49;
38 | packetBuffer[13] = 0x4E;
39 | packetBuffer[14] = 49;
40 | packetBuffer[15] = 52;
41 |
42 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
43 |
44 | //Allocate a UDP socket to talk to the NTP server
45 |
46 | int socketNum = mySARA.socketOpen(SARA_R5_UDP);
47 | if (socketNum == -1)
48 | {
49 | Serial.println(F("getNTPTime: socketOpen failed!"));
50 | return (false);
51 | }
52 |
53 | Serial.print(F("getNTPTime: using socket "));
54 | Serial.println(socketNum);
55 |
56 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
57 |
58 | // Send the request - NTP uses UDP
59 |
60 | if (mySARA.socketWriteUDP(socketNum, ntpServer, serverPort, (const char *)&packetBuffer, NTP_PACKET_SIZE) != SARA_R5_SUCCESS) // Send the request
61 | {
62 | Serial.println(F("getNTPTime: socketWrite failed!"));
63 | mySARA.socketClose(socketNum); // Be nice. Close the socket
64 | return (false);
65 | }
66 |
67 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
68 |
69 | // Wait up to 10 seconds for the response
70 | unsigned long requestTime = millis();
71 |
72 | while (millis() < (requestTime + 10000))
73 | {
74 | // We could use the Socket Read Callback to get the data, but, just for giggles,
75 | // and to prove it works, let's poll the arrival of the data manually...
76 | int avail = 0;
77 | if (mySARA.socketReadAvailableUDP(socketNum, &avail) != SARA_R5_SUCCESS)
78 | {
79 | Serial.println(F("getNTPTime: socketReadAvailable failed!"));
80 | mySARA.socketClose(socketNum); // Be nice. Close the socket
81 | return (false);
82 | }
83 |
84 | if (avail >= NTP_PACKET_SIZE) // Is enough data available?
85 | {
86 | if (avail > NTP_PACKET_SIZE) // Too much data?
87 | {
88 | Serial.print(F("getNTPTime: too much data received! Length: "));
89 | Serial.print(avail);
90 | Serial.print(F(". Reading "));
91 | Serial.print(NTP_PACKET_SIZE);
92 | Serial.println(F(" bytes..."));
93 | }
94 |
95 | if (mySARA.socketReadUDP(socketNum, NTP_PACKET_SIZE, (char *)&packetBuffer) != SARA_R5_SUCCESS)
96 | {
97 | Serial.println(F("getNTPTime: socketRead failed!"));
98 | mySARA.socketClose(socketNum); // Be nice. Close the socket
99 | return (false);
100 | }
101 |
102 | // Extract the time from the reply
103 |
104 | Serial.print(F("getNTPTime: received "));
105 | Serial.print(avail);
106 | Serial.println(F(" bytes. Extracting the time..."));
107 |
108 | //the timestamp starts at byte 40 of the received packet and is four bytes,
109 | // or two words, long. First, esxtract the two words:
110 | unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
111 | unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
112 |
113 | // combine the four bytes (two words) into a long integer
114 | // this is NTP time (seconds since Jan 1 1900):
115 | unsigned long secsSince1900 = highWord << 16 | lowWord;
116 |
117 | Serial.print(F("getNTPTime: seconds since Jan 1 1900 = "));
118 | Serial.println(secsSince1900);
119 |
120 | // now convert NTP time into everyday time:
121 | Serial.print(F("getNTPTime: Unix time = "));
122 |
123 | // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
124 | const unsigned long seventyYears = 2208988800UL;
125 |
126 | // subtract seventy years:
127 | unsigned long epoch = secsSince1900 - seventyYears;
128 |
129 | // print Unix time:
130 | Serial.println(epoch);
131 |
132 | // Instead of calculating the year, month, day, etc. manually, let's use time_t and tm to do it for us!
133 | time_t dateTime = epoch;
134 | tm *theTime = gmtime(&dateTime);
135 |
136 | // Load the time into y, mo, d, h, min, s
137 | *y = theTime->tm_year - 100; // tm_year is years since 1900. Convert to years since 2000.
138 | *mo = theTime->tm_mon + 1; //tm_mon starts at zero. Add 1 for January.
139 | *d = theTime->tm_mday;
140 | *h = theTime->tm_hour;
141 | *min = theTime->tm_min;
142 | *s = theTime->tm_sec;
143 |
144 | // Finish off by printing the time
145 | Serial.print(F("getNTPTime: YY/MM/DD HH:MM:SS : "));
146 | if (*y < 10) Serial.print(F("0"));
147 | Serial.print(*y);
148 | Serial.print(F("/"));
149 | if (*mo < 10) Serial.print(F("0"));
150 | Serial.print(*mo);
151 | Serial.print(F("/"));
152 | if (*d < 10) Serial.print(F("0"));
153 | Serial.print(*d);
154 | Serial.print(F(" "));
155 | if (*h < 10) Serial.print(F("0"));
156 | Serial.print(*h);
157 | Serial.print(F(":"));
158 | if (*min < 10) Serial.print(F("0"));
159 | Serial.print(*min);
160 | Serial.print(F(":"));
161 | if (*s < 10) Serial.print(F("0"));
162 | Serial.println(*s);
163 |
164 | mySARA.socketClose(socketNum); // Be nice. Close the socket
165 | return (true); // We are done!
166 | }
167 |
168 | delay(100); // Wait before trying again
169 | }
170 |
171 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
172 |
173 | Serial.println(F("getNTPTime: no NTP data received!"));
174 | mySARA.socketClose(socketNum); // Be nice. Close the socket
175 | return (false);
176 | }
177 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example14_AssistNowOffline/SARA-R5_AssistNow_Offline.ino:
--------------------------------------------------------------------------------
1 |
2 | #include "secrets.h" // Update secrets.h with your AssistNow token string
3 |
4 | // u-blox AssistNow https servers
5 | const char assistNowOfflineServer[] = "offline-live1.services.u-blox.com";
6 | //const char assistNowOfflineServer[] = "offline-live2.services.u-blox.com"; // Alternate server
7 |
8 | const char getQuery[] = "GetOfflineData.ashx?";
9 | const char tokenPrefix[] = "token=";
10 | const char tokenSuffix[] = ";";
11 | const char getGNSS[] = "gnss=gps,glo;"; // GNSS can be: gps,qzss,glo,bds,gal
12 | const char getFormat[] = "format=mga;"; // Data format. Leave set to mga for M8 onwards. Can be aid.
13 | const char getPeriod[] = "period=1;"; // Optional. The number of weeks into the future that the data will be valid. Can be 1-5. Default = 4.
14 | const char getMgaResolution[] = "resolution=1;"; // Optional. Data resolution: 1 = every day; 2 = every other day; 3 = every 3rd day.
15 | //Note: always use resolution=1. findMGAANOForDate does not yet support finding the 'closest' date. It needs an exact match.
16 |
17 | volatile bool httpResultSeen = false; // Flag to indicate that the HTTP URC was received
18 |
19 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20 |
21 | // processHTTPcommandResult is provided to the SARA-R5 library via a
22 | // callback setter -- setHTTPCommandCallback. (See the end of setup())
23 | void processHTTPcommandResult(int profile, int command, int result)
24 | {
25 | Serial.println();
26 | Serial.print(F("HTTP Command Result: profile: "));
27 | Serial.print(profile);
28 | Serial.print(F(" command: "));
29 | Serial.print(command);
30 | Serial.print(F(" result: "));
31 | Serial.print(result);
32 | if (result == 0)
33 | Serial.print(F(" (fail)"));
34 | if (result == 1)
35 | Serial.print(F(" (success)"));
36 | Serial.println();
37 |
38 | // Get and print the most recent HTTP protocol error
39 | int error_class;
40 | int error_code;
41 | mySARA.getHTTPprotocolError(0, &error_class, &error_code);
42 | Serial.print(F("Most recent HTTP protocol error: class: "));
43 | Serial.print(error_class);
44 | Serial.print(F(" code: "));
45 | Serial.print(error_code);
46 | if (error_code == 0)
47 | Serial.print(F(" (no error)"));
48 | Serial.println();
49 |
50 | httpResultSeen = true; // Set the flag
51 | }
52 |
53 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
54 |
55 | bool getAssistNowOfflineData(String theFilename)
56 | {
57 | // Use HTTP GET to receive the AssistNow_Offline data. Store it in the SARA-R5's internal file system.
58 |
59 | String theServer = assistNowOfflineServer; // Convert the AssistNow server to String
60 |
61 | const int REQUEST_BUFFER_SIZE = 256;
62 | char theRequest[REQUEST_BUFFER_SIZE];
63 |
64 | // Assemble the request
65 | // Note the slash at the beginning
66 | snprintf(theRequest, REQUEST_BUFFER_SIZE, "/%s%s%s%s%s%s%s%s",
67 | getQuery,
68 | tokenPrefix,
69 | myAssistNowToken,
70 | tokenSuffix,
71 | getGNSS,
72 | getFormat,
73 | getPeriod,
74 | getMgaResolution
75 | );
76 |
77 |
78 | String theRequestStr = theRequest; // Convert to String
79 |
80 | Serial.print(F("getAssistNowOfflineData: HTTP GET is https://"));
81 | Serial.print(theServer);
82 | Serial.println(theRequestStr);
83 |
84 | Serial.print(F("getAssistNowOfflineData: the AssistNow data will be stored in: "));
85 | Serial.println(theFilename);
86 |
87 | // Reset HTTP profile 0
88 | mySARA.resetHTTPprofile(0);
89 |
90 | // Set the server name
91 | mySARA.setHTTPserverName(0, theServer);
92 |
93 | // Use HTTPS
94 | mySARA.setHTTPsecure(0, false); // Setting this to true causes the GET to fail. Maybe due to the default CMNG profile?
95 |
96 | // Set a callback to process the HTTP command result
97 | mySARA.setHTTPCommandCallback(&processHTTPcommandResult);
98 |
99 | httpResultSeen = false; // Clear the flag
100 |
101 | // HTTP GET
102 | mySARA.sendHTTPGET(0, theRequestStr, theFilename);
103 |
104 | // Wait for 20 seconds while calling mySARA.bufferedPoll() to see the HTTP result.
105 | Serial.print(F("getAssistNowOfflineData: Waiting up to 20 seconds for the HTTP Result"));
106 | int i = 0;
107 | while ((i < 20000) && (httpResultSeen == false))
108 | {
109 | mySARA.bufferedPoll(); // Keep processing data from the SARA so we can catch the HTTP command result
110 | i++;
111 | delay(1);
112 | if (i % 1000 == 0)
113 | Serial.print(F("."));
114 | }
115 | Serial.println();
116 |
117 | if (httpResultSeen == false)
118 | {
119 | Serial.print(F("getAssistNowOfflineData: HTTP GET failed!"));
120 | return false;
121 | }
122 |
123 | return true;
124 | }
125 |
126 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
127 |
128 | void prettyPrintString(String theString) // Pretty-print a String in HEX and ASCII format
129 | {
130 | int theLength = theString.length();
131 |
132 | Serial.println();
133 | Serial.print(F("String length is "));
134 | Serial.print(theLength);
135 | Serial.print(F(" (0x"));
136 | Serial.print(theLength, HEX);
137 | Serial.println(F(")"));
138 | Serial.println();
139 |
140 | for (int i = 0; i < theLength; i += 16)
141 | {
142 | if (i < 10000) Serial.print(F("0"));
143 | if (i < 1000) Serial.print(F("0"));
144 | if (i < 100) Serial.print(F("0"));
145 | if (i < 10) Serial.print(F("0"));
146 | Serial.print(i);
147 |
148 | Serial.print(F(" 0x"));
149 |
150 | if (i < 0x1000) Serial.print(F("0"));
151 | if (i < 0x100) Serial.print(F("0"));
152 | if (i < 0x10) Serial.print(F("0"));
153 | Serial.print(i, HEX);
154 |
155 | Serial.print(F(" "));
156 |
157 | int j;
158 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
159 | {
160 | if (theString[i + j] < 0x10) Serial.print(F("0"));
161 | Serial.print(theString[i + j], HEX);
162 | Serial.print(F(" "));
163 | }
164 |
165 | if (((i + j) == theLength) && (j < 16))
166 | {
167 | for (int k = 0; k < (16 - (theLength % 16)); k++)
168 | {
169 | Serial.print(F(" "));
170 | }
171 | }
172 |
173 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
174 | {
175 | if ((theString[i + j] >= 0x20) && (theString[i + j] <= 0x7E))
176 | Serial.write(theString[i + j]);
177 | else
178 | Serial.print(F("."));
179 | }
180 |
181 | Serial.println();
182 | }
183 |
184 | Serial.println();
185 | }
186 |
187 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
188 |
189 | void prettyPrintChars(char *theData, int theLength) // Pretty-print char data in HEX and ASCII format
190 | {
191 | Serial.println();
192 | Serial.print(F("String length is "));
193 | Serial.print(theLength);
194 | Serial.print(F(" (0x"));
195 | Serial.print(theLength, HEX);
196 | Serial.println(F(")"));
197 | Serial.println();
198 |
199 | for (int i = 0; i < theLength; i += 16)
200 | {
201 | if (i < 10000) Serial.print(F("0"));
202 | if (i < 1000) Serial.print(F("0"));
203 | if (i < 100) Serial.print(F("0"));
204 | if (i < 10) Serial.print(F("0"));
205 | Serial.print(i);
206 |
207 | Serial.print(F(" 0x"));
208 |
209 | if (i < 0x1000) Serial.print(F("0"));
210 | if (i < 0x100) Serial.print(F("0"));
211 | if (i < 0x10) Serial.print(F("0"));
212 | Serial.print(i, HEX);
213 |
214 | Serial.print(F(" "));
215 |
216 | int j;
217 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
218 | {
219 | if (theData[i + j] < 0x10) Serial.print(F("0"));
220 | Serial.print(theData[i + j], HEX);
221 | Serial.print(F(" "));
222 | }
223 |
224 | if (((i + j) == theLength) && (j < 16))
225 | {
226 | for (int k = 0; k < (16 - (theLength % 16)); k++)
227 | {
228 | Serial.print(F(" "));
229 | }
230 | }
231 |
232 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
233 | {
234 | if ((theData[i + j] >= 0x20) && (theData[i + j] <= 0x7E))
235 | Serial.write(theData[i + j]);
236 | else
237 | Serial.print(F("."));
238 | }
239 |
240 | Serial.println();
241 | }
242 |
243 | Serial.println();
244 | }
245 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example14_AssistNowOffline/SARA-R5_NTP.ino:
--------------------------------------------------------------------------------
1 |
2 | #include // Note: this is the standard c time library, not Time.h
3 |
4 | // Get the time from NTP
5 | // This code is based heavily on:
6 | // https://docs.arduino.cc/tutorials/mkr-nb-1500/mkr-nb-library-examples#mkr-nb-gprs-udp-ntp-client
7 | // Many thanks to: Michael Margolis, Tom Igoe, Arturo Guadalupi, et al
8 |
9 | // NTP Server
10 | const char* ntpServer = "pool.ntp.org"; // The Network Time Protocol Server
11 | //const char* ntpServer = "africa.pool.ntp.org"; // The Network Time Protocol Server
12 | //const char* ntpServer = "asia.pool.ntp.org"; // The Network Time Protocol Server
13 | //const char* ntpServer = "europe.pool.ntp.org"; // The Network Time Protocol Server
14 | //const char* ntpServer = "north-america.pool.ntp.org"; // The Network Time Protocol Server
15 | //const char* ntpServer = "oceania.pool.ntp.org"; // The Network Time Protocol Server
16 | //const char* ntpServer = "south-america.pool.ntp.org"; // The Network Time Protocol Server
17 |
18 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
19 |
20 | bool getNTPTime(uint8_t *y, uint8_t *mo, uint8_t *d, uint8_t *h, uint8_t *min, uint8_t *s)
21 | {
22 | int serverPort = 123; //NTP requests are to port 123
23 |
24 | // Set up the packetBuffer for the NTP request
25 | const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
26 | byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
27 |
28 | // set all bytes in the buffer to 0
29 | memset(packetBuffer, 0, NTP_PACKET_SIZE);
30 |
31 | // Initialize values needed to form NTP request
32 | packetBuffer[0] = 0b11100011; // LI, Version, Mode
33 | packetBuffer[1] = 0; // Stratum, or type of clock
34 | packetBuffer[2] = 6; // Polling Interval
35 | packetBuffer[3] = 0xEC; // Peer Clock Precision
36 | // 8 bytes of zero for Root Delay & Root Dispersion
37 | packetBuffer[12] = 49;
38 | packetBuffer[13] = 0x4E;
39 | packetBuffer[14] = 49;
40 | packetBuffer[15] = 52;
41 |
42 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
43 |
44 | //Allocate a UDP socket to talk to the NTP server
45 |
46 | int socketNum = mySARA.socketOpen(SARA_R5_UDP);
47 | if (socketNum == -1)
48 | {
49 | Serial.println(F("getNTPTime: socketOpen failed!"));
50 | return (false);
51 | }
52 |
53 | Serial.print(F("getNTPTime: using socket "));
54 | Serial.println(socketNum);
55 |
56 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
57 |
58 | // Send the request - NTP uses UDP
59 |
60 | if (mySARA.socketWriteUDP(socketNum, ntpServer, serverPort, (const char *)&packetBuffer, NTP_PACKET_SIZE) != SARA_R5_SUCCESS) // Send the request
61 | {
62 | Serial.println(F("getNTPTime: socketWrite failed!"));
63 | mySARA.socketClose(socketNum); // Be nice. Close the socket
64 | return (false);
65 | }
66 |
67 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
68 |
69 | // Wait up to 10 seconds for the response
70 | unsigned long requestTime = millis();
71 |
72 | while (millis() < (requestTime + 10000))
73 | {
74 | // We could use the Socket Read Callback to get the data, but, just for giggles,
75 | // and to prove it works, let's poll the arrival of the data manually...
76 | int avail = 0;
77 | if (mySARA.socketReadAvailableUDP(socketNum, &avail) != SARA_R5_SUCCESS)
78 | {
79 | Serial.println(F("getNTPTime: socketReadAvailable failed!"));
80 | mySARA.socketClose(socketNum); // Be nice. Close the socket
81 | return (false);
82 | }
83 |
84 | if (avail >= NTP_PACKET_SIZE) // Is enough data available?
85 | {
86 | if (avail > NTP_PACKET_SIZE) // Too much data?
87 | {
88 | Serial.print(F("getNTPTime: too much data received! Length: "));
89 | Serial.print(avail);
90 | Serial.print(F(". Reading "));
91 | Serial.print(NTP_PACKET_SIZE);
92 | Serial.println(F(" bytes..."));
93 | }
94 |
95 | if (mySARA.socketReadUDP(socketNum, NTP_PACKET_SIZE, (char *)&packetBuffer) != SARA_R5_SUCCESS)
96 | {
97 | Serial.println(F("getNTPTime: socketRead failed!"));
98 | mySARA.socketClose(socketNum); // Be nice. Close the socket
99 | return (false);
100 | }
101 |
102 | // Extract the time from the reply
103 |
104 | Serial.print(F("getNTPTime: received "));
105 | Serial.print(avail);
106 | Serial.println(F(" bytes. Extracting the time..."));
107 |
108 | //the timestamp starts at byte 40 of the received packet and is four bytes,
109 | // or two words, long. First, esxtract the two words:
110 | unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
111 | unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
112 |
113 | // combine the four bytes (two words) into a long integer
114 | // this is NTP time (seconds since Jan 1 1900):
115 | unsigned long secsSince1900 = highWord << 16 | lowWord;
116 |
117 | Serial.print(F("getNTPTime: seconds since Jan 1 1900 = "));
118 | Serial.println(secsSince1900);
119 |
120 | // now convert NTP time into everyday time:
121 | Serial.print(F("getNTPTime: Unix time = "));
122 |
123 | // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
124 | const unsigned long seventyYears = 2208988800UL;
125 |
126 | // subtract seventy years:
127 | unsigned long epoch = secsSince1900 - seventyYears;
128 |
129 | // print Unix time:
130 | Serial.println(epoch);
131 |
132 | // Instead of calculating the year, month, day, etc. manually, let's use time_t and tm to do it for us!
133 | time_t dateTime = epoch;
134 | tm *theTime = gmtime(&dateTime);
135 |
136 | // Load the time into y, mo, d, h, min, s
137 | *y = theTime->tm_year - 100; // tm_year is years since 1900. Convert to years since 2000.
138 | *mo = theTime->tm_mon + 1; //tm_mon starts at zero. Add 1 for January.
139 | *d = theTime->tm_mday;
140 | *h = theTime->tm_hour;
141 | *min = theTime->tm_min;
142 | *s = theTime->tm_sec;
143 |
144 | // Finish off by printing the time
145 | Serial.print(F("getNTPTime: YY/MM/DD HH:MM:SS : "));
146 | if (*y < 10) Serial.print(F("0"));
147 | Serial.print(*y);
148 | Serial.print(F("/"));
149 | if (*mo < 10) Serial.print(F("0"));
150 | Serial.print(*mo);
151 | Serial.print(F("/"));
152 | if (*d < 10) Serial.print(F("0"));
153 | Serial.print(*d);
154 | Serial.print(F(" "));
155 | if (*h < 10) Serial.print(F("0"));
156 | Serial.print(*h);
157 | Serial.print(F(":"));
158 | if (*min < 10) Serial.print(F("0"));
159 | Serial.print(*min);
160 | Serial.print(F(":"));
161 | if (*s < 10) Serial.print(F("0"));
162 | Serial.println(*s);
163 |
164 | mySARA.socketClose(socketNum); // Be nice. Close the socket
165 | return (true); // We are done!
166 | }
167 |
168 | delay(100); // Wait before trying again
169 | }
170 |
171 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
172 |
173 | Serial.println(F("getNTPTime: no NTP data received!"));
174 | mySARA.socketClose(socketNum); // Be nice. Close the socket
175 | return (false);
176 | }
177 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example14_AssistNowOffline/secrets.h:
--------------------------------------------------------------------------------
1 | //Your AssistNow token
2 | const char myAssistNowToken[] = "58XXXXXXXXXXXXXXXXXXYQ";
3 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks/GNSS_Callbacks.ino:
--------------------------------------------------------------------------------
1 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2 |
3 | // Callback: pushGPGGA will be called when new GPGGA NMEA data arrives
4 | // See u-blox_structs.h for the full definition of NMEA_GGA_data_t
5 | // _____ You can use any name you like for the callback. Use the same name when you call setNMEAGPGGAcallback
6 | // / _____ This _must_ be NMEA_GGA_data_t
7 | // | / _____ You can use any name you like for the struct
8 | // | | /
9 | // | | |
10 | void pushGPGGA(NMEA_GGA_data_t nmeaData)
11 | {
12 | if (connectionOpen)
13 | {
14 | Serial.print(F("Pushing GGA to server: "));
15 | Serial.print((const char *)nmeaData.nmea); // .nmea is printable (NULL-terminated) and already has \r\n on the end
16 |
17 | //Push our current GGA sentence to caster
18 | mySARA.socketWrite(socketNum, (const char *)nmeaData.nmea);
19 | }
20 | }
21 |
22 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 |
24 | // Callback: printPVTdata will be called when new NAV PVT data arrives
25 | // See u-blox_structs.h for the full definition of UBX_NAV_PVT_data_t
26 | // _____ You can use any name you like for the callback. Use the same name when you call setAutoPVTcallback
27 | // / _____ This _must_ be UBX_NAV_PVT_data_t
28 | // | / _____ You can use any name you like for the struct
29 | // | | /
30 | // | | |
31 | void printPVTdata(UBX_NAV_PVT_data_t ubxDataStruct)
32 | {
33 | double latitude = ubxDataStruct.lat; // Print the latitude
34 | Serial.print(F("Lat: "));
35 | Serial.print(latitude / 10000000.0, 7);
36 |
37 | double longitude = ubxDataStruct.lon; // Print the longitude
38 | Serial.print(F(" Long: "));
39 | Serial.print(longitude / 10000000.0, 7);
40 |
41 | double altitude = ubxDataStruct.hMSL; // Print the height above mean sea level
42 | Serial.print(F(" Height: "));
43 | Serial.print(altitude / 1000.0, 3);
44 |
45 | uint8_t fixType = ubxDataStruct.fixType; // Print the fix type
46 | Serial.print(F(" Fix: "));
47 | Serial.print(fixType);
48 | if (fixType == 0)
49 | Serial.print(F(" (None)"));
50 | else if (fixType == 1)
51 | Serial.print(F(" (Dead Reckoning)"));
52 | else if (fixType == 2)
53 | Serial.print(F(" (2D)"));
54 | else if (fixType == 3)
55 | Serial.print(F(" (3D)"));
56 | else if (fixType == 3)
57 | Serial.print(F(" (GNSS + Dead Reckoning)"));
58 | else if (fixType == 5)
59 | Serial.print(F(" (Time Only)"));
60 | else
61 | Serial.print(F(" (UNKNOWN)"));
62 |
63 | uint8_t carrSoln = ubxDataStruct.flags.bits.carrSoln; // Print the carrier solution
64 | Serial.print(F(" Carrier Solution: "));
65 | Serial.print(carrSoln);
66 | if (carrSoln == 0)
67 | Serial.print(F(" (None)"));
68 | else if (carrSoln == 1)
69 | Serial.print(F(" (Floating)"));
70 | else if (carrSoln == 2)
71 | Serial.print(F(" (Fixed)"));
72 | else
73 | Serial.print(F(" (UNKNOWN)"));
74 |
75 | uint32_t hAcc = ubxDataStruct.hAcc; // Print the horizontal accuracy estimate
76 | Serial.print(F(" Horizontal Accuracy Estimate: "));
77 | Serial.print(hAcc);
78 | Serial.print(F(" (mm)"));
79 |
80 | Serial.println();
81 | }
82 |
83 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
84 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks/SARA-R5_Callbacks.ino:
--------------------------------------------------------------------------------
1 | // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
2 |
3 | // processSocketData is provided to the SARA-R5 library via a
4 | // callback setter -- setSocketReadCallbackPlus. (See setup())
5 | void processSocketData(int socket, const char *theData, int dataLength, IPAddress remoteAddress, int remotePort)
6 | {
7 | Serial.print(F("processSocketData: Data received on socket "));
8 | Serial.print(socket);
9 | Serial.print(F(". Length is "));
10 | Serial.print(dataLength);
11 |
12 | if (connectionOpen)
13 | {
14 | Serial.println(F(". Pushing it to the GNSS..."));
15 | myGNSS.pushRawData((uint8_t *)theData, (size_t)dataLength);
16 |
17 | lastReceivedRTCM_ms = millis(); // Update lastReceivedRTCM_ms
18 | }
19 | else
20 | {
21 | Serial.println();
22 | }
23 | }
24 |
25 | // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
26 |
27 | // processSocketClose is provided to the SARA-R5 library via a
28 | // callback setter -- setSocketCloseCallback. (See setup())
29 | //
30 | // Note: the SARA-R5 only sends a +UUSOCL URC when the socket is closed by the remote
31 | void processSocketClose(int socket)
32 | {
33 | Serial.print(F("processSocketClose: Socket "));
34 | Serial.print(socket);
35 | Serial.println(F(" closed!"));
36 |
37 | if (socket == socketNum)
38 | {
39 | socketNum = -1;
40 | connectionOpen = false;
41 | }
42 | }
43 |
44 | // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
45 |
46 | // processPSDAction is provided to the SARA-R5 library via a
47 | // callback setter -- setPSDActionCallback. (See setup())
48 | void processPSDAction(int result, IPAddress ip)
49 | {
50 | Serial.print(F("processPSDAction: result: "));
51 | Serial.print(String(result));
52 | if (result == 0)
53 | Serial.print(F(" (success)"));
54 | Serial.print(F(" IP Address: \""));
55 | Serial.print(String(ip[0]));
56 | Serial.print(F("."));
57 | Serial.print(String(ip[1]));
58 | Serial.print(F("."));
59 | Serial.print(String(ip[2]));
60 | Serial.print(F("."));
61 | Serial.print(String(ip[3]));
62 | Serial.println(F("\""));
63 | }
64 |
65 | // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
66 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks/SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | u-blox GNSS NTRIP Caster Client
7 |
8 | Written by: Paul Clark
9 | Date: January 14th 2021
10 |
11 | This example uses the SARA's mobile data connection to:
12 | * Request RTK RTCM data from a NTRIP Caster service
13 | * Push the RTCM data to an external u-blox GNSS module over I2C (not to the one built-in to the SARA-R510M8S)
14 |
15 | The PDP profile is read from NVM. Please make sure you have run examples 4 & 7 previously to set up the profile.
16 |
17 | Update secrets.h with your NTRIP Caster username and password
18 |
19 | **************************************************************************************************
20 | * Important Note: *
21 | * *
22 | * This example pulls kBytes of correction data from the NTRIP Caster. *
23 | * Depending on your location and service provider, the data rate may exceed the allowable *
24 | * rates for LTE-M or NB-IoT. *
25 | * Worst case, your service provider may throttle or block the connection - now or in the future. *
26 | * We are looking for a long-term solution to this - almost certainly using LTE Cat 1 instead. *
27 | **************************************************************************************************
28 |
29 | Feel like supporting open source hardware?
30 | Buy a board from SparkFun!
31 |
32 | Licence: MIT
33 | Please see LICENSE.md for full details
34 |
35 | */
36 |
37 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
38 |
39 | // The ESP32 core has a built in base64 library but not every platform does
40 | // We'll use an external lib if necessary.
41 |
42 | #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_APOLLO3) || defined(ARDUINO_ARDUINO_NANO33BLE)
43 | #include "base64.h" //Built-in ESP32 library
44 | #else
45 | #include //nfriendly library from https://github.com/adamvr/arduino-base64, will work with any platform
46 | #endif
47 |
48 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
49 |
50 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
51 |
52 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
53 | #define saraSerial Serial1
54 |
55 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
56 | //SoftwareSerial saraSerial(8, 9);
57 |
58 | // Create a SARA_R5 object to use throughout the sketch
59 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
60 | // but we can start the SARA without a power pin. It just means we need to manually
61 | // turn the power on if required! ;-D
62 | SARA_R5 mySARA;
63 |
64 | // Create a SARA_R5 object to use throughout the sketch
65 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
66 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
67 | // the pin name is G2 which is connected to pin AD34.
68 | // Change the pin number if required.
69 | //SARA_R5 mySARA(34);
70 |
71 | // Create a SARA_R5 object to use throughout the sketch
72 | // If you are using the LTE GNSS Breakout, and have access to the SARA's RESET_N pin, you can pass that to the library too
73 | // allowing it to do an emergency shutdown if required.
74 | // Change the pin numbers if required.
75 | //SARA_R5 mySARA(34, 35); // PWR_ON, RESET_N
76 |
77 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
78 |
79 | #include //http://librarymanager/All#SparkFun_u-blox_GNSS
80 | SFE_UBLOX_GNSS myGNSS;
81 |
82 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
83 |
84 | // Globals
85 |
86 | volatile int socketNum = -1; // The TCP socket number. -1 indicates invalid/closed socket
87 | volatile bool connectionOpen = false; // Flag to indicate if the connection to the NTRIP Caster is open
88 | volatile unsigned long lastReceivedRTCM_ms; // Record when data last arrived - so we can time out if required
89 |
90 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
91 |
92 | void setup()
93 | {
94 | String currentOperator = "";
95 |
96 | Serial.begin(115200); // Start the serial console
97 |
98 | // Wait for user to press key to begin
99 | Serial.println(F("SARA-R5 Example"));
100 | Serial.println(F("Wait for the SARA NI LED to light up - then press any key to begin"));
101 |
102 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
103 | ;
104 | while (Serial.available()) // Empty the serial RX buffer
105 | Serial.read();
106 |
107 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
108 |
109 | // Start communication with the SARA-R5. Load and activate the Packet Switched Data profile.
110 |
111 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
112 |
113 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
114 | // Comment the next line if required
115 | mySARA.invertPowerPin(true);
116 |
117 | // Initialize the SARA
118 | if (mySARA.begin(saraSerial, 115200) )
119 | {
120 | Serial.println(F("SARA-R5 connected!"));
121 | }
122 | else
123 | {
124 | Serial.println(F("Unable to communicate with the SARA."));
125 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
126 | while (1) ; // Loop forever on fail
127 | }
128 | Serial.println();
129 |
130 | // First check to see if we're connected to an operator:
131 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
132 | {
133 | Serial.print(F("Connected to: "));
134 | Serial.println(currentOperator);
135 | }
136 | else
137 | {
138 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
139 | while (1)
140 | ; // Do nothing more
141 | }
142 |
143 | // Deactivate the PSD profile - in case one is already active
144 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
145 | {
146 | Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
147 | }
148 |
149 | // Load the PSD profile from NVM - these were saved by a previous example
150 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_LOAD) != SARA_R5_SUCCESS)
151 | {
152 | Serial.println(F("performPDPaction (load from NVM) failed! Freezing..."));
153 | while (1)
154 | ; // Do nothing more
155 | }
156 |
157 | // Set a callback to process the results of the PSD Action - OPTIONAL
158 | mySARA.setPSDActionCallback(&processPSDAction);
159 |
160 | // Activate the profile
161 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
162 | {
163 | Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
164 | while (1)
165 | ; // Do nothing more
166 | }
167 |
168 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
169 |
170 | //Print the dynamic IP Address (for profile 0)
171 | IPAddress myAddress;
172 | mySARA.getNetworkAssignedIPAddress(0, &myAddress);
173 | Serial.print(F("\r\nMy IP Address is: "));
174 | Serial.print(myAddress[0]);
175 | Serial.print(F("."));
176 | Serial.print(myAddress[1]);
177 | Serial.print(F("."));
178 | Serial.print(myAddress[2]);
179 | Serial.print(F("."));
180 | Serial.println(myAddress[3]);
181 |
182 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
183 |
184 | // Set a callback to process the socket data
185 | // This will push the RTCM data to the GNSS
186 | mySARA.setSocketReadCallbackPlus(&processSocketData);
187 |
188 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
189 |
190 | // Set a callback to process the socket close
191 | //
192 | // Note: the SARA-R5 only sends a +UUSOCL URC when the socket os closed by the remote
193 | mySARA.setSocketCloseCallback(&processSocketClose);
194 |
195 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
196 |
197 | // Start I2C. Connect to the GNSS.
198 |
199 | Wire.begin(); //Start I2C
200 |
201 | // Uncomment the next line to enable the 'major' GNSS debug messages on Serial so you can see what AssistNow data is being sent
202 | //myGNSS.enableDebugging(Serial, true);
203 |
204 | if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port
205 | {
206 | Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
207 | while (1);
208 | }
209 | Serial.println(F("u-blox module connected"));
210 |
211 | myGNSS.setI2COutput(COM_TYPE_UBX | COM_TYPE_NMEA); //Set the I2C port to output both NMEA and UBX messages
212 | myGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_RTCM3); //Be sure RTCM3 input is enabled. UBX + RTCM3 is not a valid state.
213 |
214 | myGNSS.setDGNSSConfiguration(SFE_UBLOX_DGNSS_MODE_FIXED); // Set the differential mode - ambiguities are fixed whenever possible
215 |
216 | myGNSS.setNavigationFrequency(1); //Set output in Hz.
217 |
218 | // Set the Main Talker ID to "GP". The NMEA GGA messages will be GPGGA instead of GNGGA
219 | myGNSS.setMainTalkerID(SFE_UBLOX_MAIN_TALKER_ID_GP);
220 |
221 | myGNSS.setNMEAGPGGAcallback(&pushGPGGA); // Set up the callback for GPGGA
222 |
223 | myGNSS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_I2C, 10); // Tell the module to output GGA every 10 seconds
224 |
225 | myGNSS.setAutoPVTcallback(&printPVTdata); // Enable automatic NAV PVT messages with callback to printPVTdata so we can watch the carrier solution go to fixed
226 |
227 | //myGNSS.saveConfiguration(VAL_CFG_SUBSEC_IOPORT | VAL_CFG_SUBSEC_MSGCONF); //Optional: Save the ioPort and message settings to NVM
228 |
229 | }
230 |
231 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
232 |
233 | void loop()
234 | {
235 | myGNSS.checkUblox(); // Check for the arrival of new GNSS data and process it.
236 | myGNSS.checkCallbacks(); // Check if any GNSS callbacks are waiting to be processed.
237 |
238 | mySARA.bufferedPoll(); // Process the SARA-R5 URC's. This pushes the incoming RTCM data to the GNSS.
239 |
240 | enum states // Use a 'state machine' to open and close the connection
241 | {
242 | open_connection,
243 | check_connection_and_wait_for_keypress,
244 | close_connection,
245 | waiting_for_keypress
246 | };
247 | static states state = open_connection;
248 |
249 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
250 |
251 | switch (state)
252 | {
253 | case open_connection:
254 | Serial.println(F("Connecting to the NTRIP caster..."));
255 | if (beginClient((int *)&socketNum, (bool *)&connectionOpen)) // Try to open the connection to the caster
256 | {
257 | Serial.println(F("Connected to the NTRIP caster! Press any key to disconnect..."));
258 | state = check_connection_and_wait_for_keypress; // Move on
259 | }
260 | else
261 | {
262 | Serial.print(F("Could not connect to the caster. Trying again in 5 seconds."));
263 | for (int i = 0; i < 5; i++)
264 | {
265 | delay(1000);
266 | Serial.print(F("."));
267 | }
268 | Serial.println();
269 | }
270 | break;
271 |
272 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
273 |
274 | case check_connection_and_wait_for_keypress:
275 | // If the connection has dropped or timed out, or if the user has pressed a key
276 | if ((checkConnection((int)socketNum, (bool)connectionOpen) == false) || (keyPressed()))
277 | {
278 | state = close_connection; // Move on
279 | }
280 | break;
281 |
282 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
283 |
284 | case close_connection:
285 | Serial.println(F("Closing the connection to the NTRIP caster..."));
286 | closeConnection((int *)&socketNum, (bool *)&connectionOpen);
287 | Serial.println(F("Press any key to reconnect..."));
288 | state = waiting_for_keypress; // Move on
289 | break;
290 |
291 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
292 |
293 | case waiting_for_keypress:
294 | // Wait for the user to press a key
295 | if (keyPressed())
296 | state = open_connection; // Move on
297 | break;
298 | }
299 | }
300 |
301 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
302 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks/SARA-R5_NTRIP_Client.ino:
--------------------------------------------------------------------------------
1 |
2 | #include "secrets.h" // Update secrets.h with your AssistNow token string
3 |
4 | const unsigned long maxTimeBeforeHangup_ms = 20000UL; //If we fail to get a complete RTCM frame after 20s, then disconnect from caster
5 |
6 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 |
8 | //Connect to NTRIP Caster. Return true is connection is successful.
9 | bool beginClient(int *theSocket, bool *connectionIsOpen)
10 | {
11 | // Sanity check - return now if the socket is already open (should be impossible, but still...)
12 | if (*theSocket >= 0)
13 | {
14 | Serial.print(F("beginClient: Socket is already open"));
15 | if (*connectionIsOpen)
16 | {
17 | Serial.println(F(" and the connection is open!"));
18 | }
19 | else
20 | {
21 | Serial.println(F("!"));
22 | }
23 | return (false);
24 | }
25 |
26 | Serial.println(F("beginClient: Opening TCP socket"));
27 |
28 | *theSocket = mySARA.socketOpen(SARA_R5_TCP);
29 | if (*theSocket == -1)
30 | {
31 | Serial.println(F("beginClient: socketOpen failed!"));
32 | return (false);
33 | }
34 |
35 | Serial.print(F("beginClient: Using socket "));
36 | Serial.println(*theSocket);
37 |
38 | Serial.print(F("beginClient: Connecting to "));
39 | Serial.print(casterHost);
40 | Serial.print(F(" on port "));
41 | Serial.println(casterPort);
42 |
43 | if (mySARA.socketConnect(*theSocket, casterHost, casterPort) != SARA_R5_SUCCESS)
44 | {
45 | Serial.println(F("beginClient: socketConnect failed!"));
46 | }
47 | else
48 | {
49 | Serial.print(F("beginClient: Connected to "));
50 | Serial.print(casterHost);
51 | Serial.print(F(" : "));
52 | Serial.println(casterPort);
53 |
54 | Serial.print(F("beginClient: Requesting NTRIP Data from mount point "));
55 | Serial.println(mountPoint);
56 |
57 | // Set up the server request (GET)
58 | const int SERVER_BUFFER_SIZE = 512;
59 | char *serverRequest = new char[SERVER_BUFFER_SIZE];
60 | memset(serverRequest, 0, SERVER_BUFFER_SIZE);
61 | snprintf(serverRequest,
62 | SERVER_BUFFER_SIZE,
63 | "GET /%s HTTP/1.0\r\nUser-Agent: NTRIP SparkFun u-blox Client v1.0\r\n",
64 | mountPoint);
65 |
66 | // Set up the credentials
67 | const int CREDENTIALS_BUFFER_SIZE = 512;
68 | char *credentials = new char[CREDENTIALS_BUFFER_SIZE];
69 | memset(credentials, 0, CREDENTIALS_BUFFER_SIZE);
70 | if (strlen(casterUser) == 0)
71 | {
72 | strncpy(credentials, "Accept: */*\r\nConnection: close\r\n", CREDENTIALS_BUFFER_SIZE);
73 | }
74 | else
75 | {
76 | //Pass base64 encoded user:pw
77 | int userCredentialsSize = sizeof(casterUser) + sizeof(casterUserPW) + 1; //The ':' takes up a spot
78 | char *userCredentials = new char[userCredentialsSize];
79 | memset(userCredentials, 0, userCredentialsSize);
80 | snprintf(userCredentials, userCredentialsSize, "%s:%s", casterUser, casterUserPW);
81 |
82 | Serial.print(F("beginClient: Sending credentials: "));
83 | Serial.println(userCredentials);
84 |
85 | #if defined(ARDUINO_ARCH_ESP32)
86 | //Encode with ESP32 built-in library
87 | base64 b;
88 | String strEncodedCredentials = b.encode(userCredentials);
89 | int encodedCredentialsSize = strEncodedCredentials.length() + 1;
90 | char *encodedCredentials = new char[encodedCredentialsSize];
91 | memset(encodedCredentials, 0, encodedCredentialsSize);
92 | strEncodedCredentials.toCharArray(encodedCredentials, encodedCredentialsSize); //Convert String to char array
93 | #elif defined(ARDUINO_ARCH_APOLLO3) || defined(ARDUINO_ARDUINO_NANO33BLE)
94 | int encodedCredentialsSize = userCredentialsSize * 8;
95 | char *encodedCredentials = new char[encodedCredentialsSize];
96 | memset(encodedCredentials, 0, encodedCredentialsSize);
97 | size_t olen;
98 | mbedtls_base64_encode((unsigned char *)encodedCredentials, encodedCredentialsSize, &olen, (const unsigned char *)userCredentials, strlen(userCredentials));
99 | #else
100 | //Encode with nfriendly library
101 | int encodedLen = base64_enc_len(userCredentialsSize);
102 | char *encodedCredentials = new char[encodedLen]; //Create array large enough to house encoded data
103 | memset(encodedCredentials, 0, encodedLen);
104 | base64_encode(encodedCredentials, userCredentials, strlen(userCredentials)); //Note: Input array is consumed
105 | #endif
106 |
107 | snprintf(credentials, CREDENTIALS_BUFFER_SIZE, "Authorization: Basic %s\r\n", encodedCredentials);
108 | delete[] userCredentials;
109 | delete[] encodedCredentials;
110 | }
111 |
112 | // Add the encoded credentials to the server request
113 | strncat(serverRequest, credentials, SERVER_BUFFER_SIZE - 1);
114 | strncat(serverRequest, "\r\n", SERVER_BUFFER_SIZE - 1);
115 |
116 | Serial.print(F("beginClient: serverRequest size: "));
117 | Serial.print(strlen(serverRequest));
118 | Serial.print(F(" of "));
119 | Serial.print(SERVER_BUFFER_SIZE);
120 | Serial.println(F(" bytes available"));
121 |
122 | // Send the server request
123 | Serial.println(F("beginClient: Sending server request: "));
124 | Serial.println(serverRequest);
125 |
126 | mySARA.socketWrite(*theSocket, (const char *)serverRequest);
127 |
128 | //Wait up to 5 seconds for response. Poll the number of available bytes. Don't use the callback yet.
129 | unsigned long startTime = millis();
130 | int availableLength = 0;
131 | while (availableLength == 0)
132 | {
133 | mySARA.socketReadAvailable(*theSocket, &availableLength);
134 | if (millis() > (startTime + 5000))
135 | {
136 | Serial.println(F("beginClient: Caster timed out!"));
137 | closeConnection(theSocket, connectionIsOpen);
138 | delete[] serverRequest;
139 | delete[] credentials;
140 | return (false);
141 | }
142 | delay(100);
143 | }
144 |
145 | Serial.print(F("beginClient: server replied with "));
146 | Serial.print(availableLength);
147 | Serial.println(F(" bytes"));
148 |
149 | //Check reply
150 | int connectionResult = 0;
151 | char *response = new char[512 * 4];
152 | memset(response, 0, 512 * 4);
153 | size_t responseSpot = 0;
154 | while ((availableLength > 0) && (connectionResult == 0)) // Read bytes from the caster and store them
155 | {
156 | if ((responseSpot + availableLength) >= ((512 * 4) - 1)) // Exit the loop if we get too much data
157 | break;
158 |
159 | mySARA.socketRead(*theSocket, availableLength, &response[responseSpot]);
160 | responseSpot += availableLength;
161 |
162 | //Serial.print(F("beginClient: response is: "));
163 | //Serial.println(response);
164 |
165 | if (connectionResult == 0) // Only print success/fail once
166 | {
167 | if (strstr(response, "200") != NULL) //Look for '200 OK'
168 | {
169 | Serial.println(F("beginClient: 200 seen!"));
170 | connectionResult = 200;
171 | }
172 | if (strstr(response, "401") != NULL) //Look for '401 Unauthorized'
173 | {
174 | Serial.println(F("beginClient: Hey - your credentials look bad! Check your caster username and password."));
175 | connectionResult = 401;
176 | }
177 | }
178 |
179 | mySARA.socketReadAvailable(*theSocket, &availableLength); // Update availableLength
180 |
181 | Serial.print(F("beginClient: socket now has "));
182 | Serial.print(availableLength);
183 | Serial.println(F(" bytes available"));
184 | }
185 | response[responseSpot] = '\0'; // NULL-terminate the response
186 |
187 | //Serial.print(F("beginClient: Caster responded with: ")); Serial.println(response); // Uncomment this line to see the full response
188 |
189 | // Free the memory allocated for serverRequest, credentials and response
190 | delete[] serverRequest;
191 | delete[] credentials;
192 | delete[] response;
193 |
194 | if (connectionResult != 200)
195 | {
196 | Serial.print(F("beginClient: Failed to connect to "));
197 | Serial.println(casterHost);
198 | closeConnection(theSocket, connectionIsOpen);
199 | return (false);
200 | }
201 | else
202 | {
203 | Serial.print(F("beginClient: Connected to: "));
204 | Serial.println(casterHost);
205 | lastReceivedRTCM_ms = millis(); //Reset timeout
206 | }
207 |
208 | } //End attempt to connect
209 |
210 | *connectionIsOpen = true;
211 | return (true);
212 | } // /beginClient
213 |
214 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
215 |
216 | //Check the connection
217 | //Return false if: the connection has dropped, or if we receive no data for maxTimeBeforeHangup_ms
218 | bool checkConnection(int theSocket, bool connectionIsOpen)
219 | {
220 | if ((theSocket >= 0) && connectionIsOpen) // Check that the connection is still open
221 | {
222 | ; // Nothing to do here. The RTCM is pushed to the GNSS by the callabck.
223 | }
224 | else
225 | {
226 | Serial.println(F("checkConnection: Connection dropped!"));
227 | return (false); // Connection has dropped - return false
228 | }
229 |
230 | //Timeout if we don't have new data for maxTimeBeforeHangup_ms
231 | if ((millis() - lastReceivedRTCM_ms) > maxTimeBeforeHangup_ms)
232 | {
233 | Serial.println(F("checkConnection: RTCM timeout!"));
234 | return (false); // Connection has timed out - return false
235 | }
236 |
237 | return (true);
238 | } // /processConnection
239 |
240 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
241 |
242 | void closeConnection(int *theSocket, bool *connectionIsOpen)
243 | {
244 | // Check the socket is actually open, otherwise we'll get an error when we try to close it
245 | if (*theSocket >= 0)
246 | {
247 | mySARA.socketClose(*theSocket);
248 | Serial.println(F("closeConnection: Connection closed!"));
249 | }
250 | else
251 | {
252 | Serial.println(F("closeConnection: Connection was already closed!"));
253 | }
254 |
255 | *theSocket = -1; // Clear the socket number to indicate it is closed
256 | *connectionIsOpen = false; // Flag that the connection is closed
257 | }
258 |
259 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
260 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks/Utils.ino:
--------------------------------------------------------------------------------
1 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
2 |
3 | void prettyPrintString(String theString) // Pretty-print a String in HEX and ASCII format
4 | {
5 | int theLength = theString.length();
6 |
7 | Serial.println();
8 | Serial.print(F("String length is "));
9 | Serial.print(theLength);
10 | Serial.print(F(" (0x"));
11 | Serial.print(theLength, HEX);
12 | Serial.println(F(")"));
13 | Serial.println();
14 |
15 | for (int i = 0; i < theLength; i += 16)
16 | {
17 | if (i < 10000) Serial.print(F("0"));
18 | if (i < 1000) Serial.print(F("0"));
19 | if (i < 100) Serial.print(F("0"));
20 | if (i < 10) Serial.print(F("0"));
21 | Serial.print(i);
22 |
23 | Serial.print(F(" 0x"));
24 |
25 | if (i < 0x1000) Serial.print(F("0"));
26 | if (i < 0x100) Serial.print(F("0"));
27 | if (i < 0x10) Serial.print(F("0"));
28 | Serial.print(i, HEX);
29 |
30 | Serial.print(F(" "));
31 |
32 | int j;
33 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
34 | {
35 | if (theString[i + j] < 0x10) Serial.print(F("0"));
36 | Serial.print(theString[i + j], HEX);
37 | Serial.print(F(" "));
38 | }
39 |
40 | if (((i + j) == theLength) && (j < 16))
41 | {
42 | for (int k = 0; k < (16 - (theLength % 16)); k++)
43 | {
44 | Serial.print(F(" "));
45 | }
46 | }
47 |
48 | for (j = 0; ((i + j) < theLength) && (j < 16); j++)
49 | {
50 | if ((theString[i + j] >= 0x20) && (theString[i + j] <= 0x7E))
51 | Serial.write(theString[i + j]);
52 | else
53 | Serial.print(F("."));
54 | }
55 |
56 | Serial.println();
57 | }
58 |
59 | Serial.println();
60 | }
61 |
62 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
63 |
64 | //Return true if a key has been pressed
65 | bool keyPressed()
66 | {
67 | if (Serial.available()) // Check for a new key press
68 | {
69 | delay(100); // Wait for any more keystrokes to arrive
70 | while (Serial.available()) // Empty the serial buffer
71 | Serial.read();
72 | return (true);
73 | }
74 |
75 | return (false);
76 | }
77 |
78 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
79 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example15_GNSS_NTRIP_Caster_With_Callbacks/secrets.h:
--------------------------------------------------------------------------------
1 | //Your WiFi credentials
2 | const char ssid[] = "yourSSID";
3 | const char password[] = "yourPassword";
4 |
5 | //RTK2Go works well and is free
6 | //const char casterHost[] = "rtk2go.com";
7 | //const uint16_t casterPort = 2101;
8 | //const char casterUser[] = "myEmail@test.com"; //User must provide their own email address to use RTK2Go
9 | //const char casterUserPW[] = "";
10 | //const char mountPoint[] = "bldr_SparkFun1"; //The mount point you want to get data from
11 |
12 | //Emlid Caster also works well and is free
13 | //const char casterHost[] = "caster.emlid.com";
14 | //const uint16_t casterPort = 2101;
15 | //const char casterUser[] = "u99696"; //User name and pw must be obtained through their web portal
16 | //const char casterUserPW[] = "466zez";
17 | //const char mountPoint[] = "MP1979"; //The mount point you want to get data from
18 |
19 | // Skylark (Swift Navigation) is awesome - but requires a subscription:
20 | // https://www.swiftnav.com/skylark
21 | // https://account.swiftnav.com/sign-up
22 | // Use the promo-code ONEMONTHFREE for a free one month access to Skylark on one device
23 | const char casterHost[] = "na.skylark.swiftnav.com"; // na = North Americs L1+L2; eu = Europe L1+L2
24 | const uint16_t casterPort = 2101;
25 | const char casterUser[] = "NTRIPusername+accountSubdomain"; // This is generated when you add a device to your Skylark account
26 | const char casterUserPW[] = "devicePassword";
27 | const char mountPoint[] = "CRS"; // The mount point you want to get data from. Select CRS (Cloud Reference Station) for the ZED-F9x
28 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example16_GNSS_NTRIP_Caster__Polling/SARA-R5_Example16_GNSS_NTRIP_Caster__Polling.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | u-blox GNSS NTRIP Caster Client - Polling
7 |
8 | This version uses polling to check for the arrival of new RTK correction and NMEA GPGGA data.
9 | It performs better on Mbed OS platforms: SparkFun Artemis; Arduino Nano
10 |
11 | Written by: Paul Clark
12 | Date: January 18th 2021
13 |
14 | This example uses the SARA's mobile data connection to:
15 | * Request RTK RTCM data from a NTRIP Caster service
16 | * Push the RTCM data to an external u-blox GNSS module over I2C (not to the one built-in to the SARA-R510M8S)
17 | * NMEA GPGGA data is pushed to the Caster every 10 seconds
18 |
19 | The PDP profile is read from NVM. Please make sure you have run examples 4 & 7 previously to set up the profile.
20 |
21 | Update secrets.h with your NTRIP Caster username and password
22 |
23 | **************************************************************************************************
24 | * Important Note: *
25 | * *
26 | * This example pulls kBytes of correction data from the NTRIP Caster. *
27 | * Depending on your location and service provider, the data rate may exceed the allowable *
28 | * rates for LTE-M or NB-IoT. *
29 | * Worst case, your service provider may throttle or block the connection - now or in the future. *
30 | * We are looking for a long-term solution to this - almost certainly using LTE Cat 1 instead. *
31 | **************************************************************************************************
32 |
33 | Feel like supporting open source hardware?
34 | Buy a board from SparkFun!
35 |
36 | Licence: MIT
37 | Please see LICENSE.md for full details
38 |
39 | */
40 |
41 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
42 |
43 | // The ESP32 core has a built in base64 library but not every platform does
44 | // We'll use an external lib if necessary.
45 |
46 | #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_APOLLO3) || defined(ARDUINO_ARDUINO_NANO33BLE)
47 | #include "base64.h" //Built-in ESP32 library
48 | #else
49 | #include //nfriendly library from https://github.com/adamvr/arduino-base64, will work with any platform
50 | #endif
51 |
52 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
53 |
54 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
55 |
56 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
57 | #define saraSerial Serial1
58 |
59 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
60 | //SoftwareSerial saraSerial(8, 9);
61 |
62 | // Create a SARA_R5 object to use throughout the sketch
63 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
64 | // but we can start the SARA without a power pin. It just means we need to manually
65 | // turn the power on if required! ;-D
66 | SARA_R5 mySARA;
67 |
68 | // Create a SARA_R5 object to use throughout the sketch
69 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
70 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
71 | // the pin name is G2 which is connected to pin AD34.
72 | // Change the pin number if required.
73 | //SARA_R5 mySARA(34);
74 |
75 | // Create a SARA_R5 object to use throughout the sketch
76 | // If you are using the LTE GNSS Breakout, and have access to the SARA's RESET_N pin, you can pass that to the library too
77 | // allowing it to do an emergency shutdown if required.
78 | // Change the pin numbers if required.
79 | //SARA_R5 mySARA(34, 35); // PWR_ON, RESET_N
80 |
81 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
82 |
83 | #include //http://librarymanager/All#SparkFun_u-blox_GNSS
84 | SFE_UBLOX_GNSS myGNSS;
85 |
86 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
87 |
88 | // Globals
89 |
90 | volatile int socketNum = -1; // The TCP socket number. -1 indicates invalid/closed socket
91 | volatile bool connectionOpen = false; // Flag to indicate if the connection to the NTRIP Caster is open
92 | volatile unsigned long lastReceivedRTCM_ms; // Record when data last arrived - so we can time out if required
93 |
94 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
95 |
96 | void setup()
97 | {
98 | String currentOperator = "";
99 |
100 | Serial.begin(115200); // Start the serial console
101 |
102 | // Wait for user to press key to begin
103 | Serial.println(F("SARA-R5 Example"));
104 | Serial.println(F("Wait for the SARA NI LED to light up - then press any key to begin"));
105 |
106 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
107 | ;
108 | while (Serial.available()) // Empty the serial RX buffer
109 | Serial.read();
110 |
111 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
112 |
113 | // Start communication with the SARA-R5. Load and activate the Packet Switched Data profile.
114 |
115 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
116 |
117 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
118 | // Comment the next line if required
119 | mySARA.invertPowerPin(true);
120 |
121 | // Initialize the SARA
122 | if (mySARA.begin(saraSerial, 115200) )
123 | {
124 | Serial.println(F("SARA-R5 connected!"));
125 | }
126 | else
127 | {
128 | Serial.println(F("Unable to communicate with the SARA."));
129 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
130 | while (1) ; // Loop forever on fail
131 | }
132 | Serial.println();
133 |
134 | // First check to see if we're connected to an operator:
135 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
136 | {
137 | Serial.print(F("Connected to: "));
138 | Serial.println(currentOperator);
139 | }
140 | else
141 | {
142 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
143 | while (1)
144 | ; // Do nothing more
145 | }
146 |
147 | // Deactivate the PSD profile - in case one is already active
148 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
149 | {
150 | Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
151 | }
152 |
153 | // Load the PSD profile from NVM - these were saved by a previous example
154 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_LOAD) != SARA_R5_SUCCESS)
155 | {
156 | Serial.println(F("performPDPaction (load from NVM) failed! Freezing..."));
157 | while (1)
158 | ; // Do nothing more
159 | }
160 |
161 | // Activate the profile
162 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
163 | {
164 | Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
165 | while (1)
166 | ; // Do nothing more
167 | }
168 |
169 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
170 |
171 | //Print the dynamic IP Address (for profile 0)
172 | IPAddress myAddress;
173 | mySARA.getNetworkAssignedIPAddress(0, &myAddress);
174 | Serial.print(F("\r\nMy IP Address is: "));
175 | Serial.print(myAddress[0]);
176 | Serial.print(F("."));
177 | Serial.print(myAddress[1]);
178 | Serial.print(F("."));
179 | Serial.print(myAddress[2]);
180 | Serial.print(F("."));
181 | Serial.println(myAddress[3]);
182 |
183 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
184 |
185 | // Start I2C. Connect to the GNSS.
186 |
187 | Wire.begin(); //Start I2C
188 |
189 | // Uncomment the next line to enable the 'major' GNSS debug messages on Serial so you can see what AssistNow data is being sent
190 | //myGNSS.enableDebugging(Serial, true);
191 |
192 | if (myGNSS.begin() == false) //Connect to the Ublox module using Wire port
193 | {
194 | Serial.println(F("u-blox GPS not detected at default I2C address. Please check wiring. Freezing."));
195 | while (1);
196 | }
197 | Serial.println(F("u-blox module connected"));
198 |
199 | myGNSS.setI2COutput(COM_TYPE_UBX | COM_TYPE_NMEA); //Set the I2C port to output both NMEA and UBX messages
200 | myGNSS.setPortInput(COM_PORT_I2C, COM_TYPE_UBX | COM_TYPE_NMEA | COM_TYPE_RTCM3); //Be sure RTCM3 input is enabled. UBX + RTCM3 is not a valid state.
201 |
202 | myGNSS.setDGNSSConfiguration(SFE_UBLOX_DGNSS_MODE_FIXED); // Set the differential mode - ambiguities are fixed whenever possible
203 |
204 | myGNSS.setNavigationFrequency(1); //Set the navigation rate to 1Hz
205 |
206 | myGNSS.setAutoPVT(true); // Enable automatic PVT reports at the navigation frequency
207 |
208 | // Set the Main Talker ID to "GP". The NMEA GGA messages will be GPGGA instead of GNGGA
209 | myGNSS.setMainTalkerID(SFE_UBLOX_MAIN_TALKER_ID_GP);
210 |
211 | myGNSS.enableNMEAMessage(UBX_NMEA_GGA, COM_PORT_I2C, 10); // Tell the module to output GGA every 10 seconds
212 |
213 | //myGNSS.saveConfiguration(VAL_CFG_SUBSEC_IOPORT | VAL_CFG_SUBSEC_MSGCONF); //Optional: Save the ioPort and message settings to NVM
214 |
215 | }
216 |
217 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
218 |
219 | void loop()
220 | {
221 | enum states // Use a 'state machine' to open and close the connection
222 | {
223 | open_connection,
224 | check_connection_and_wait_for_keypress,
225 | close_connection,
226 | waiting_for_keypress
227 | };
228 | static states state = open_connection;
229 |
230 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
231 |
232 | switch (state)
233 | {
234 | case open_connection:
235 | Serial.println(F("Connecting to the NTRIP caster..."));
236 | if (beginClient((int *)&socketNum, (bool *)&connectionOpen)) // Try to open the connection to the caster
237 | {
238 | Serial.println(F("Connected to the NTRIP caster! Press any key to disconnect..."));
239 | state = check_connection_and_wait_for_keypress; // Move on
240 | }
241 | else
242 | {
243 | Serial.print(F("Could not connect to the caster. Trying again in 5 seconds."));
244 | for (int i = 0; i < 5; i++)
245 | {
246 | delay(1000);
247 | Serial.print(F("."));
248 | }
249 | Serial.println();
250 | }
251 | break;
252 |
253 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
254 |
255 | case check_connection_and_wait_for_keypress:
256 | // If the connection has dropped or timed out, or if the user has pressed a key
257 | if ((checkConnection((int)socketNum, (bool)connectionOpen) == false) || (keyPressed()))
258 | {
259 | state = close_connection; // Move on
260 | }
261 | delay(50);
262 | break;
263 |
264 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
265 |
266 | case close_connection:
267 | Serial.println(F("Closing the connection to the NTRIP caster..."));
268 | closeConnection((int *)&socketNum, (bool *)&connectionOpen);
269 | Serial.println(F("Press any key to reconnect..."));
270 | state = waiting_for_keypress; // Move on
271 | break;
272 |
273 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
274 |
275 | case waiting_for_keypress:
276 | // Wait for the user to press a key
277 | checkConnection((int)socketNum, (bool)connectionOpen); // 'Check' the connection - to print the latest PVT data
278 | if (keyPressed())
279 | state = open_connection; // Move on
280 | break;
281 | }
282 | }
283 |
284 | //=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
285 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example16_GNSS_NTRIP_Caster__Polling/secrets.h:
--------------------------------------------------------------------------------
1 | //Your WiFi credentials
2 | const char ssid[] = "yourSSID";
3 | const char password[] = "yourPassword";
4 |
5 | //RTK2Go works well and is free
6 | //const char casterHost[] = "rtk2go.com";
7 | //const uint16_t casterPort = 2101;
8 | //const char casterUser[] = "myEmail@test.com"; //User must provide their own email address to use RTK2Go
9 | //const char casterUserPW[] = "";
10 | //const char mountPoint[] = "bldr_SparkFun1"; //The mount point you want to get data from
11 |
12 | //Emlid Caster also works well and is free
13 | //const char casterHost[] = "caster.emlid.com";
14 | //const uint16_t casterPort = 2101;
15 | //const char casterUser[] = "u99696"; //User name and pw must be obtained through their web portal
16 | //const char casterUserPW[] = "466zez";
17 | //const char mountPoint[] = "MP1979"; //The mount point you want to get data from
18 |
19 | // Skylark (Swift Navigation) is awesome - but requires a subscription:
20 | // https://www.swiftnav.com/skylark
21 | // https://account.swiftnav.com/sign-up
22 | // Use the promo-code ONEMONTHFREE for a free one month access to Skylark on one device
23 | const char casterHost[] = "na.skylark.swiftnav.com"; // na = North Americs L1+L2; eu = Europe L1+L2
24 | const uint16_t casterPort = 2101;
25 | const char casterUser[] = "NTRIPusername+accountSubdomain"; // This is generated when you add a device to your Skylark account
26 | const char casterUserPW[] = "devicePassword";
27 | const char mountPoint[] = "CRS"; // The mount point you want to get data from. Select CRS (Cloud Reference Station) for the ZED-F9x
28 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example17_ThingSpeak_MQTT/SARA-R5_Example17_ThingSpeak_MQTT.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | ThingSpeak (MQTT)
7 |
8 | Written by: Paul Clark
9 | Date: November 14th 2023
10 |
11 | This example uses the SARA's mobile data connection and MQTT to publish random temperatures on ThingSpeak.
12 | It also subscribes to the same topic (channel) so you can read the data back again!
13 |
14 | See: https://thingspeak.com/
15 |
16 | And: https://uk.mathworks.com/help/thingspeak/mqtt-basics.html#responsive_offcanvas
17 |
18 | You will need to:
19 | Create a ThingSpeak User Account – https://thingspeak.com/login
20 | Create a new Channel by selecting Channels, My Channels, and then New Channel
21 | Note the Channel ID and copy&paste it into myChannelID below
22 | Click on the Devices drop-down at the top of the screen and select MQTT
23 | Create a new MQTT Device using "Add a new device". Give it a name
24 | Authorize the New Channel you created above, then Add Channel, then Add Device
25 | Copy the Username, Client ID and password into myUsername, myClientID and myPassword below
26 | The random temperature reading will be added to the channel as "Field 1"
27 |
28 | Feel like supporting open source hardware?
29 | Buy a board from SparkFun!
30 |
31 | Licence: MIT
32 | Please see LICENSE.md for full details
33 |
34 | */
35 |
36 | #include
37 |
38 | // ThingSpeak via MQTT Publish
39 |
40 | String brokerName = "mqtt3.thingspeak.com"; // MQTT Broker
41 |
42 | const int brokerPort = 1883; // MQTT port (TCP, no encryption)
43 |
44 | String myUsername = "OAAxOjYHIwooJykfCiYoEx0";
45 |
46 | String myClientID = "OAAxOjYHIwooJykfCiYoEx0";
47 |
48 | String myPassword = "RqY/6L246tULLVWUzCqJBX/V";
49 |
50 | String myChannelID = "1225363"; // Public View: https://thingspeak.com/channels/1225363
51 |
52 | // SARA-R5
53 |
54 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
55 |
56 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
57 | #define saraSerial Serial1
58 |
59 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
60 | //SoftwareSerial saraSerial(8, 9);
61 |
62 | // Create a SARA_R5 object to use throughout the sketch
63 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
64 | // but we can start the SARA without a power pin. It just means we need to manually
65 | // turn the power on if required! ;-D
66 | SARA_R5 mySARA;
67 |
68 | // Create a SARA_R5 object to use throughout the sketch
69 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
70 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
71 | // the pin name is G2 which is connected to pin AD34.
72 | // Change the pin number if required.
73 | //SARA_R5 mySARA(34);
74 |
75 | // processMQTTcommandResult is provided to the SARA-R5 library via a
76 | // callback setter -- setMQTTCommandCallback. (See the end of setup())
77 | void processMQTTcommandResult(int command, int result)
78 | {
79 | Serial.println();
80 | Serial.print(F("MQTT Command Result: command: "));
81 | Serial.print(command);
82 | Serial.print(F(" result: "));
83 | Serial.print(result);
84 | if (result == 0)
85 | Serial.print(F(" (fail)"));
86 | if (result == 1)
87 | Serial.print(F(" (success)"));
88 | Serial.println();
89 |
90 | // Get and print the most recent MQTT protocol error
91 | int error_class;
92 | int error_code;
93 | mySARA.getMQTTprotocolError(&error_class, &error_code);
94 | Serial.print(F("Most recent MQTT protocol error: class: "));
95 | Serial.print(error_class);
96 | Serial.print(F(" code: "));
97 | Serial.print(error_code);
98 | if (error_code == 0)
99 | Serial.print(F(" (no error)"));
100 | Serial.println();
101 | }
102 |
103 | void setup()
104 | {
105 | delay(1000);
106 |
107 | String currentOperator = "";
108 |
109 | Serial.begin(115200); // Start the serial console
110 |
111 | // Wait for user to press key to begin
112 | Serial.println(F("SARA-R5 Example"));
113 | Serial.println(F("Wait for the SARA NI LED to light up - then press any key to begin"));
114 |
115 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
116 | ;
117 | while (Serial.available()) // Empty the serial RX buffer
118 | Serial.read();
119 |
120 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
121 |
122 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
123 | // Comment the next line if required
124 | mySARA.invertPowerPin(true);
125 |
126 | // Initialize the SARA
127 | if (mySARA.begin(saraSerial, 115200) )
128 | {
129 | Serial.println(F("SARA-R5 connected!"));
130 | }
131 | else
132 | {
133 | Serial.println(F("Unable to communicate with the SARA."));
134 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
135 | while (1) ; // Loop forever on fail
136 | }
137 | Serial.println();
138 |
139 | // First check to see if we're connected to an operator:
140 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
141 | {
142 | Serial.print(F("Connected to: "));
143 | Serial.println(currentOperator);
144 | }
145 | else
146 | {
147 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
148 | while (1)
149 | ; // Do nothing more
150 | }
151 |
152 | // Deactivate the PSD profile - in case one is already active
153 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
154 | {
155 | Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
156 | }
157 |
158 | // Load the PSD profile from NVM - these were saved by a previous example
159 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_LOAD) != SARA_R5_SUCCESS)
160 | {
161 | Serial.println(F("performPDPaction (load from NVM) failed! Freezing..."));
162 | while (1)
163 | ; // Do nothing more
164 | }
165 |
166 | // Activate the PSD profile
167 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
168 | {
169 | Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
170 | while (1)
171 | ; // Do nothing more
172 | }
173 |
174 | // Set up the MQTT command callback
175 | mySARA.setMQTTCommandCallback(processMQTTcommandResult);
176 |
177 | // Disable the security profile
178 | mySARA.setMQTTsecure(false);
179 |
180 | // Set Client ID
181 | mySARA.setMQTTclientId(myClientID);
182 |
183 | // Set the broker name and port
184 | mySARA.setMQTTserver(brokerName, brokerPort);
185 |
186 | // Set the user name and password
187 | mySARA.setMQTTcredentials(myUsername, myPassword);
188 |
189 | // Connect
190 | if (mySARA.connectMQTT() == SARA_R5_SUCCESS)
191 | Serial.println(F("MQTT connect: success"));
192 | else
193 | Serial.println(F("MQTT connect: failed!"));
194 |
195 | // The LTE modem has difficulties subscribing/unsubscribing more than one topic at the same time.
196 | // We can only start one operation at a time wait for the URC and add a extra delay before we can
197 | // do the next operation.
198 | // Wait for ~2 seconds
199 | for (int i = 0; i < 200; i++)
200 | {
201 | mySARA.bufferedPoll(); // Keep processing data from the SARA
202 | delay(10);
203 | }
204 |
205 | // Subscribe to the channel topic, so we can read the data back again
206 | String subscribeTopic = "channels/" + myChannelID + "/subscribe/fields/field1";
207 | if (mySARA.subscribeMQTTtopic(0, subscribeTopic) == SARA_R5_SUCCESS) // QoS = 0
208 | Serial.println(F("MQTT subscribe: success"));
209 | else
210 | Serial.println(F("MQTT subscribe: failed!"));
211 |
212 | // Wait for ~2 seconds
213 | for (int i = 0; i < 200; i++)
214 | {
215 | mySARA.bufferedPoll(); // Keep processing data from the SARA
216 | delay(10);
217 | }
218 | }
219 |
220 | void loop()
221 | {
222 | float temperature = ((float)random(2000,3000)) / 100.0; // Create a random temperature between 20 and 30
223 |
224 | // Send data using MQTT Publish
225 | String Topic = "channels/" + myChannelID + "/publish";
226 | String DataField = "field1=" + String(temperature) + "&status=MQTTPUBLISH";
227 |
228 | Serial.println();
229 | Serial.print(F("Publishing a temperature of "));
230 | Serial.print(String(temperature));
231 | Serial.println(F(" to ThingSpeak"));
232 |
233 | // Publish the text message
234 | mySARA.mqttPublishTextMsg(Topic, DataField.c_str(), 0, true); // QoS = 0, retain = true
235 |
236 | // Wait for ~10 seconds
237 | for (int i = 0; i < 1000; i++)
238 | {
239 | mySARA.bufferedPoll(); // Keep processing data from the SARA
240 | delay(10);
241 | }
242 |
243 | // Check for any received data
244 | // The MQTT API does not allow getting the size before actually reading the data.
245 | // So we have to allocate a big enough buffer.
246 | const int MQTT_MAX_MSG_SIZE = 1024;
247 | static uint8_t buf[MQTT_MAX_MSG_SIZE];
248 | String topic;
249 | int len = -1;
250 | int qos = -1;
251 | if (mySARA.readMQTT(&qos, &topic, buf, MQTT_MAX_MSG_SIZE, &len) == SARA_R5_SUCCESS)
252 | {
253 | if (len > 0)
254 | {
255 | Serial.println();
256 | Serial.print(F("Subscribed MQTT data: "));
257 | Serial.write((const char *)buf, len);
258 | Serial.println();
259 | }
260 | }
261 |
262 | // Wait for ~10 seconds
263 | for (int i = 0; i < 1000; i++)
264 | {
265 | mySARA.bufferedPoll(); // Keep processing data from the SARA
266 | delay(10);
267 | }
268 | }
269 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example1_GNSS_GPRMC/SARA-R5_Example1_GNSS_GPRMC.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | GNSS GPRMC
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example enables the SARA-R5nnM8S' built-in GNSS receiver and reads the GPRMC message to
12 | get position, speed and time data.
13 |
14 | Feel like supporting open source hardware?
15 | Buy a board from SparkFun!
16 |
17 | Licence: MIT
18 | Please see LICENSE.md for full details
19 |
20 | */
21 |
22 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
23 |
24 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
25 | #define saraSerial Serial1
26 |
27 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
28 | //SoftwareSerial saraSerial(8, 9);
29 |
30 | // Create a SARA_R5 object to use throughout the sketch
31 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
32 | // but we can start the SARA without a power pin. It just means we need to manually
33 | // turn the power on if required! ;-D
34 | SARA_R5 mySARA;
35 |
36 | // Create a SARA_R5 object to use throughout the sketch
37 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
38 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
39 | // the pin name is G2 which is connected to pin AD34.
40 | // Change the pin number if required.
41 | //SARA_R5 mySARA(34);
42 |
43 | PositionData gps;
44 | SpeedData spd;
45 | ClockData clk;
46 | boolean valid;
47 |
48 | #define GPS_POLL_RATE 5000 // Read GPS every 5 seconds
49 | unsigned long lastGpsPoll = 0;
50 |
51 | void setup()
52 | {
53 | Serial.begin(115200); // Start the serial console
54 |
55 | // Wait for user to press key to begin
56 | Serial.println(F("SARA-R5 Example"));
57 | Serial.println(F("Press any key to begin GNSS'ing"));
58 |
59 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
60 | ;
61 | while (Serial.available()) // Empty the serial RX buffer
62 | Serial.read();
63 |
64 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
65 |
66 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
67 | // Comment the next line if required
68 | mySARA.invertPowerPin(true);
69 |
70 | // Initialize the SARA
71 | if (mySARA.begin(saraSerial, 9600) ) {
72 | Serial.println(F("SARA-R5 connected!"));
73 | }
74 |
75 | // Enable power for the GNSS active antenna
76 | // On the MicroMod Asset Tracker, the SARA GPIO2 pin is used to control power for the antenna.
77 | // We need to pull GPIO2 (Pin 23) high to enable the power.
78 | mySARA.setGpioMode(mySARA.GPIO2, mySARA.GPIO_OUTPUT, 1);
79 |
80 | // From the u-blox SARA-R5 Positioning Implementation Application Note UBX-20012413 - R01
81 | // To enable the PPS output we need to:
82 | // Configure GPIO6 for TIME_PULSE_OUTPUT - .init does this
83 | // Enable the timing information request with +UTIMEIND=1 - setUtimeIndication()
84 | // Reset the time offset configuration with +UTIMECFG=0,0 - setUtimeConfiguration()
85 | // Request PPS output using GNSS+LTE (Best effort) with +UTIME=1,1 - setUtimeMode()
86 | // The bits that don't seem to be mentioned in the documentation are:
87 | // +UTIME=1,1 also enables the GNSS module and so we don't need to call gpsPower.
88 | // +UTIME=1,1 only works when the GNSS module if off. It returns an ERROR if the GNSS is already on.
89 |
90 | // Enable the timing information request (URC)
91 | //mySARA.setUtimeIndication(); // Use default (SARA_R5_UTIME_URC_CONFIGURATION_ENABLED)
92 |
93 | // Clear the time offset
94 | mySARA.setUtimeConfiguration(); // Use default offset (offsetNanoseconds = 0, offsetSeconds = 0)
95 |
96 | // Set the UTIME mode to pulse-per-second output using a best effort from GNSS and LTE
97 | mySARA.setUtimeMode(); // Use defaults (mode = SARA_R5_UTIME_MODE_PPS, sensor = SARA_R5_UTIME_SENSOR_GNSS_LTE)
98 |
99 | mySARA.gpsEnableRmc(); // Enable GPRMC messages
100 | }
101 |
102 | void loop()
103 | {
104 | if ((lastGpsPoll == 0) || (lastGpsPoll + GPS_POLL_RATE < millis()))
105 | {
106 | // Call (mySARA.gpsGetRmc to get coordinate, speed, and timing data
107 | // from the GPS module. Valid can be used to check if the GPS is
108 | // reporting valid data
109 | if (mySARA.gpsGetRmc(&gps, &spd, &clk, &valid) == SARA_R5_SUCCESS)
110 | {
111 | printGPS();
112 | lastGpsPoll = millis();
113 | }
114 | else
115 | {
116 | delay(1000); // If RMC read fails, wait a second and try again
117 | }
118 | }
119 | }
120 |
121 | void printGPS(void)
122 | {
123 | Serial.println();
124 | Serial.println("UTC: " + String(gps.utc));
125 | Serial.print("Time: ");
126 | if (clk.time.hour < 10) Serial.print('0'); // Print leading 0
127 | Serial.print(String(clk.time.hour) + ":");
128 | if (clk.time.minute < 10) Serial.print('0'); // Print leading 0
129 | Serial.print(String(clk.time.minute) + ":");
130 | if (clk.time.second < 10) Serial.print('0'); // Print leading 0
131 | Serial.print(String(clk.time.second) + ".");
132 | if (clk.time.ms < 10) Serial.print('0'); // Print leading 0
133 | Serial.println(String(clk.time.ms));
134 | Serial.println("Latitude: " + String(gps.lat, 7));
135 | Serial.println("Longitude: " + String(gps.lon, 7));
136 | Serial.println("Speed: " + String(spd.speed, 4) + " @ " + String(spd.cog, 4));
137 | Serial.println("Date (MM/DD/YY): " + String(clk.date.month) + "/" +
138 | String(clk.date.day) + "/" + String(clk.date.year));
139 | Serial.println("Magnetic variation: " + String(spd.magVar));
140 | Serial.println("Status: " + String(gps.status));
141 | Serial.println("Mode: " + String(gps.mode));
142 | Serial.println();
143 | }
144 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example2_Identification/SARA-R5_Example2_Identification.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Identification
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example demonstrates how to read the SARA's:
12 | Manufacturer identification
13 | Model identification
14 | Firmware version identification
15 | Product Serial No.
16 | IMEI identification
17 | IMSI identification
18 | SIM CCID
19 | Subscriber number
20 | Capabilities
21 | SIM state
22 |
23 | Feel like supporting open source hardware?
24 | Buy a board from SparkFun!
25 |
26 | Licence: MIT
27 | Please see LICENSE.md for full details
28 |
29 | */
30 |
31 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
32 |
33 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
34 | #define saraSerial Serial1
35 |
36 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
37 | //SoftwareSerial saraSerial(8, 9);
38 |
39 | // Create a SARA_R5 object to use throughout the sketch
40 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
41 | // but we can start the SARA without a power pin. It just means we need to manually
42 | // turn the power on if required! ;-D
43 | SARA_R5 mySARA;
44 |
45 | // Create a SARA_R5 object to use throughout the sketch
46 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
47 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
48 | // the pin name is G2 which is connected to pin AD34.
49 | // Change the pin number if required.
50 | //SARA_R5 mySARA(34);
51 |
52 | // Map SIM states to more readable strings
53 | String simStateString[] =
54 | {
55 | "Not present", // 0
56 | "PIN needed", // 1
57 | "PIN blocked", // 2
58 | "PUK blocked", // 3
59 | "Not operational", // 4
60 | "Restricted", // 5
61 | "Operational" // 6
62 | };
63 |
64 | // processSIMstate is provided to the SARA-R5 library via a
65 | // callback setter -- setSIMstateReadCallback. (See setup())
66 | void processSIMstate(SARA_R5_sim_states_t state)
67 | {
68 | Serial.println();
69 | Serial.print(F("SIM state: "));
70 | Serial.print(String(state));
71 | Serial.println();
72 | }
73 |
74 | void setup()
75 | {
76 | Serial.begin(115200); // Start the serial console
77 |
78 | // Wait for user to press key to begin
79 | Serial.println(F("SARA-R5 Example"));
80 | Serial.println(F("Press any key to begin"));
81 |
82 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
83 | ;
84 | while (Serial.available()) // Empty the serial RX buffer
85 | Serial.read();
86 |
87 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
88 |
89 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
90 | // Comment the next line if required
91 | mySARA.invertPowerPin(true);
92 |
93 | // Initialize the SARA
94 | if (mySARA.begin(saraSerial, 9600) )
95 | {
96 | Serial.println(F("SARA-R5 connected!"));
97 | }
98 | else
99 | {
100 | Serial.println(F("Unable to communicate with the SARA."));
101 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
102 | while (1) ; // Loop forever on fail
103 | }
104 | Serial.println();
105 |
106 | Serial.println("Manufacturer ID: " + String(mySARA.getManufacturerID()));
107 | Serial.println("Model ID: " + String(mySARA.getModelID()));
108 | Serial.println("Firmware Version: " + String(mySARA.getFirmwareVersion()));
109 | Serial.println("Product Serial No.: " + String(mySARA.getSerialNo()));
110 | Serial.println("IMEI: " + String(mySARA.getIMEI()));
111 | Serial.println("IMSI: " + String(mySARA.getIMSI()));
112 | Serial.println("SIM CCID: " + String(mySARA.getCCID()));
113 | Serial.println("Subscriber No.: " + String(mySARA.getSubscriberNo()));
114 | Serial.println("Capabilities: " + String(mySARA.getCapabilities()));
115 |
116 | // Set a callback to return the SIM state once requested
117 | mySARA.setSIMstateReportCallback(&processSIMstate);
118 | // Now enable SIM state reporting for states 0 to 6 (by setting the reporting mode LSb)
119 | if (mySARA.setSIMstateReportingMode(1) == SARA_R5_SUCCESS)
120 | Serial.println("SIM state reports requested...");
121 | // You can disable the SIM staus reports again by calling assetTracker.setSIMstateReportingMode(0)
122 | }
123 |
124 | void loop()
125 | {
126 | mySARA.poll(); // Keep processing data from the SARA so we can extract the SIM status
127 | }
128 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example2_Identification_ESPSoftwareSerial/SARA-R5_Example2_Identification_ESPSoftwareSerial.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Identification - using ESPSoftwareSerial
7 |
8 | Written by: Paul Clark
9 | Date: December 29th 2021
10 |
11 | This example demonstrates how to read the SARA's:
12 | Manufacturer identification
13 | Model identification
14 | Firmware version identification
15 | Product Serial No.
16 | IMEI identification
17 | IMSI identification
18 | SIM CCID
19 | Subscriber number
20 | Capabilities
21 | SIM state
22 |
23 | The ESP32 core doesn't include SoftwareSerial. Instead we use the library by Peter Lerup and Dirk O. Kaar:
24 | https://github.com/plerup/espsoftwareserial
25 |
26 | Feel like supporting open source hardware?
27 | Buy a board from SparkFun!
28 |
29 | Licence: MIT
30 | Please see LICENSE.md for full details
31 |
32 | */
33 |
34 | // Include SoftwareSerial.h _before_ including SparkFun_u-blox_SARA-R5_Arduino_Library.h
35 | // to allow the SARA-R5 library to detect SoftwareSerial.h using an #if __has_include
36 | #include //Click here to get the library: http://librarymanager/All#ESPSoftwareSerial_ESP8266/ESP32
37 |
38 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
39 |
40 | // Create a SoftwareSerial object to pass to the SARA-R5 library
41 | // Note: we need to call saraSerial.begin and saraSerial.end in setup() - see below for details
42 | SoftwareSerial saraSerial;
43 |
44 | // Create a SARA_R5 object to use throughout the sketch
45 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
46 | // but we can start the SARA without a power pin. It just means we need to manually
47 | // turn the power on if required! ;-D
48 | SARA_R5 mySARA;
49 |
50 | // Create a SARA_R5 object to use throughout the sketch
51 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
52 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
53 | // the pin name is G2 which is connected to pin AD34.
54 | // Change the pin number if required.
55 | //SARA_R5 mySARA(34);
56 |
57 | // Map SIM states to more readable strings
58 | String simStateString[] =
59 | {
60 | "Not present", // 0
61 | "PIN needed", // 1
62 | "PIN blocked", // 2
63 | "PUK blocked", // 3
64 | "Not operational", // 4
65 | "Restricted", // 5
66 | "Operational" // 6
67 | };
68 |
69 | // processSIMstate is provided to the SARA-R5 library via a
70 | // callback setter -- setSIMstateReadCallback. (See setup())
71 | void processSIMstate(SARA_R5_sim_states_t state)
72 | {
73 | Serial.println();
74 | Serial.print(F("SIM state: "));
75 | Serial.print(String(state));
76 | Serial.println();
77 | }
78 |
79 | void setup()
80 | {
81 | Serial.begin(115200); // Start the serial console
82 |
83 | // Wait for user to press key to begin
84 | Serial.println(F("SARA-R5 Example"));
85 | Serial.println(F("Press any key to begin"));
86 |
87 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
88 | ;
89 | while (Serial.available()) // Empty the serial RX buffer
90 | Serial.read();
91 |
92 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
93 |
94 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
95 | // Comment the next line if required
96 | mySARA.invertPowerPin(true);
97 |
98 | // ESPSoftwareSerial does not like repeated .begin's without a .end in between.
99 | // We need to .begin and .end the saraSerial port here, before the mySARA.begin, to set up the pin numbers etc.
100 | // E.g. to use: 57600 baud; 8 databits, no parity, 1 stop bit; RXD on pin 33; TXD on pin 32; no inversion.
101 | Serial.println(F("Configuring SoftwareSerial saraSerial"));
102 | saraSerial.begin(57600, SWSERIAL_8N1, 33, 32, false);
103 | saraSerial.end();
104 |
105 | // Initialize the SARA
106 | if (mySARA.begin(saraSerial, 57600) )
107 | {
108 | Serial.println(F("SARA-R5 connected!"));
109 | }
110 | else
111 | {
112 | Serial.println(F("Unable to communicate with the SARA."));
113 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
114 | while (1) ; // Loop forever on fail
115 | }
116 | Serial.println();
117 |
118 | Serial.println("Manufacturer ID: " + String(mySARA.getManufacturerID()));
119 | Serial.println("Model ID: " + String(mySARA.getModelID()));
120 | Serial.println("Firmware Version: " + String(mySARA.getFirmwareVersion()));
121 | Serial.println("Product Serial No.: " + String(mySARA.getSerialNo()));
122 | Serial.println("IMEI: " + String(mySARA.getIMEI()));
123 | Serial.println("IMSI: " + String(mySARA.getIMSI()));
124 | Serial.println("SIM CCID: " + String(mySARA.getCCID()));
125 | Serial.println("Subscriber No.: " + String(mySARA.getSubscriberNo()));
126 | Serial.println("Capabilities: " + String(mySARA.getCapabilities()));
127 |
128 | // Set a callback to return the SIM state once requested
129 | mySARA.setSIMstateReportCallback(&processSIMstate);
130 | // Now enable SIM state reporting for states 0 to 6 (by setting the reporting mode LSb)
131 | if (mySARA.setSIMstateReportingMode(1) == SARA_R5_SUCCESS)
132 | Serial.println("SIM state reports requested...");
133 | // You can disable the SIM staus reports again by calling assetTracker.setSIMstateReportingMode(0)
134 | }
135 |
136 | void loop()
137 | {
138 | mySARA.poll(); // Keep processing data from the SARA so we can extract the SIM status
139 | }
140 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example3_NetworkInfo/SARA-R5_Example3_NetworkInfo.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Network Info
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example demonstrates how to register the SARA on the selected network.
12 |
13 | Feel like supporting open source hardware?
14 | Buy a board from SparkFun!
15 |
16 | Licence: MIT
17 | Please see LICENSE.md for full details
18 |
19 | */
20 |
21 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
22 |
23 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
24 | #define saraSerial Serial1
25 |
26 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
27 | //SoftwareSerial saraSerial(8, 9);
28 |
29 | // Create a SARA_R5 object to use throughout the sketch
30 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
31 | // but we can start the SARA without a power pin. It just means we need to manually
32 | // turn the power on if required! ;-D
33 | SARA_R5 mySARA;
34 |
35 | // Create a SARA_R5 object to use throughout the sketch
36 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
37 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
38 | // the pin name is G2 which is connected to pin AD34.
39 | // Change the pin number if required.
40 | //SARA_R5 mySARA(34);
41 |
42 | // Map registration status messages to more readable strings
43 | String registrationString[] =
44 | {
45 | "Not registered", // 0
46 | "Registered, home", // 1
47 | "Searching for operator", // 2
48 | "Registration denied", // 3
49 | "Registration unknown", // 4
50 | "Registered, roaming", // 5
51 | "Registered, home (SMS only)", // 6
52 | "Registered, roaming (SMS only)", // 7
53 | "Registered, emergency service only", // 8
54 | "Registered, home, CSFB not preferred", // 9
55 | "Registered, roaming, CSFB not prefered" // 10
56 | };
57 |
58 | // Network operator can be set to e.g.:
59 | // MNO_SW_DEFAULT -- DEFAULT (Undefined / regulatory)
60 | // MNO_SIM_ICCID -- SIM DEFAULT
61 | // MNO_ATT -- AT&T
62 | // MNO_VERIZON -- Verizon
63 | // MNO_TELSTRA -- Telstra
64 | // MNO_TMO -- T-Mobile US
65 | // MNO_CT -- China Telecom
66 | // MNO_SPRINT
67 | // MNO_VODAFONE
68 | // MNO_NTT_DOCOMO
69 | // MNO_TELUS
70 | // MNO_SOFTBANK
71 | // MNO_DT -- Deutsche Telekom
72 | // MNO_US_CELLULAR
73 | // MNO_SKT
74 | // MNO_GLOBAL -- SARA factory-programmed value
75 | // MNO_STD_EUROPE
76 | // MNO_STD_EU_NOEPCO
77 |
78 | // If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE
79 |
80 | const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL;
81 |
82 | void setup()
83 | {
84 | Serial.begin(115200); // Start the serial console
85 |
86 | // Wait for user to press key to begin
87 | Serial.println(F("SARA-R5 Example"));
88 | Serial.println(F("Press any key to begin"));
89 |
90 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
91 | ;
92 | while (Serial.available()) // Empty the serial RX buffer
93 | Serial.read();
94 |
95 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
96 |
97 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
98 | // Comment the next line if required
99 | mySARA.invertPowerPin(true);
100 |
101 | // Initialize the SARA
102 | if (mySARA.begin(saraSerial, 9600) )
103 | {
104 | Serial.println(F("SARA-R5 connected!"));
105 | }
106 | else
107 | {
108 | Serial.println(F("Unable to communicate with the SARA."));
109 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
110 | while (1) ; // Loop forever on fail
111 | }
112 | Serial.println();
113 |
114 | if (!mySARA.setNetworkProfile(MOBILE_NETWORK_OPERATOR))
115 | {
116 | Serial.println(F("Error setting network. Try cycling the power."));
117 | while (1) ;
118 | }
119 |
120 | Serial.println(F("Network profile set. Ready to go!"));
121 |
122 | // RSSI: Received signal strength:
123 | Serial.println("RSSI: " + String(mySARA.rssi()));
124 | // Registration Status
125 | int regStatus = mySARA.registration();
126 | if ((regStatus >= 0) && (regStatus <= 10))
127 | {
128 | Serial.println("Network registration: " + registrationString[regStatus]);
129 | }
130 |
131 | // Print the Context IDs, Access Point Names and IP Addresses
132 | Serial.println(F("Available PDP (Packet Data Protocol) APNs (Access Point Names) and IP Addresses:"));
133 | Serial.println(F("Context ID:\tAPN Name:\tIP Address:"));
134 | for (int cid = 0; cid < SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS; cid++)
135 | {
136 | String apn = "";
137 | IPAddress ip(0, 0, 0, 0);
138 | mySARA.getAPN(cid, &apn, &ip);
139 | if (apn.length() > 0)
140 | {
141 | Serial.print(cid);
142 | Serial.print(F("\t"));
143 | Serial.print(apn);
144 | Serial.print(F("\t"));
145 | Serial.println(ip);
146 | }
147 | }
148 |
149 | Serial.println();
150 |
151 | if (regStatus > 0)
152 | {
153 | Serial.println(F("All set. Go to the next example!"));
154 | }
155 | }
156 |
157 | void loop()
158 | {
159 | // Do nothing. Now that we're registered move on to the next example.
160 | }
161 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example4_RegisterOperator/SARA-R5_Example4_RegisterOperator.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Register Operator
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example demonstrates how to register the SARA with a network operator.
12 |
13 | Feel like supporting open source hardware?
14 | Buy a board from SparkFun!
15 |
16 | Licence: MIT
17 | Please see LICENSE.md for full details
18 |
19 | */
20 |
21 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
22 |
23 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
24 | #define saraSerial Serial1
25 |
26 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
27 | //SoftwareSerial saraSerial(8, 9);
28 |
29 | // Create a SARA_R5 object to use throughout the sketch
30 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
31 | // but we can start the SARA without a power pin. It just means we need to manually
32 | // turn the power on if required! ;-D
33 | SARA_R5 mySARA;
34 |
35 | // Create a SARA_R5 object to use throughout the sketch
36 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
37 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
38 | // the pin name is G2 which is connected to pin AD34.
39 | // Change the pin number if required.
40 | //SARA_R5 mySARA(34);
41 |
42 | // Map registration status messages to more readable strings
43 | String registrationString[] =
44 | {
45 | "Not registered", // 0
46 | "Registered, home", // 1
47 | "Searching for operator", // 2
48 | "Registration denied", // 3
49 | "Registration unknown", // 4
50 | "Registered, roaming", // 5
51 | "Registered, home (SMS only)", // 6
52 | "Registered, roaming (SMS only)", // 7
53 | "Registered, emergency service only", // 8
54 | "Registered, home, CSFB not preferred", // 9
55 | "Registered, roaming, CSFB not prefered" // 10
56 | };
57 |
58 | // Network operator can be set to e.g.:
59 | // MNO_SW_DEFAULT -- DEFAULT (Undefined / regulatory)
60 | // MNO_SIM_ICCID -- SIM DEFAULT
61 | // MNO_ATT -- AT&T
62 | // MNO_VERIZON -- Verizon
63 | // MNO_TELSTRA -- Telstra
64 | // MNO_TMO -- T-Mobile US
65 | // MNO_CT -- China Telecom
66 | // MNO_SPRINT
67 | // MNO_VODAFONE
68 | // MNO_NTT_DOCOMO
69 | // MNO_TELUS
70 | // MNO_SOFTBANK
71 | // MNO_DT -- Deutsche Telekom
72 | // MNO_US_CELLULAR
73 | // MNO_SKT
74 | // MNO_GLOBAL -- SARA factory-programmed value
75 | // MNO_STD_EUROPE
76 | // MNO_STD_EU_NOEPCO
77 |
78 | // MNO_GLOBAL is the factory-programmed default
79 | // If you are in Europe, you may find no operators unless you choose MNO_STD_EUROPE
80 | const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL;
81 |
82 | const String MOBILE_NETWORK_STRINGS[] = {"default (Undefined/Regulatory)", "SIM ICCID", "AT&T", "Verizon",
83 | "Telstra", "T-Mobile US", "China Telecom", "Sprint", "Vodafone", "NTT DoCoMo", "Telus", "SoftBank",
84 | "Deutsche Telekom", "US Cellular", "SKT", "global (factory default)", "standard Europe",
85 | "standard Europe No-ePCO", "NOT RECOGNIZED"};
86 |
87 | // Convert the operator number into an index for MOBILE_NETWORK_STRINGS
88 | int convertOperatorNumber( mobile_network_operator_t mno)
89 | {
90 | switch (mno)
91 | {
92 | case 0:
93 | case 1:
94 | case 2:
95 | case 3:
96 | case 4:
97 | case 5:
98 | case 6:
99 | return ((int)mno);
100 | break;
101 | case 8:
102 | return 7;
103 | break;
104 | case 19:
105 | return 8;
106 | break;
107 | case 20:
108 | return 9;
109 | break;
110 | case 21:
111 | return 10;
112 | break;
113 | case 28:
114 | return 11;
115 | break;
116 | case 31:
117 | return 12;
118 | break;
119 | case 32:
120 | return 13;
121 | break;
122 | case 39:
123 | return 14;
124 | break;
125 | case 90:
126 | return 15;
127 | break;
128 | case 100:
129 | return 16;
130 | break;
131 | case 101:
132 | return 17;
133 | break;
134 | default: // NOT RECOGNIZED
135 | return 18;
136 | break;
137 | }
138 | }
139 |
140 | // This defines the size of the ops struct array. To narrow the operator
141 | // list, set MOBILE_NETWORK_OPERATOR to AT&T, Verizon etc. instead
142 | // of MNO_SW_DEFAULT.
143 | #define MAX_OPERATORS 10
144 |
145 | // Uncomment this line if you want to be able to communicate directly with the SARA in the main loop
146 | //#define DEBUG_PASSTHROUGH_ENABLED
147 |
148 | void setup()
149 | {
150 | int opsAvailable;
151 | struct operator_stats ops[MAX_OPERATORS];
152 | String currentOperator = "";
153 | bool newConnection = true;
154 |
155 | Serial.begin(115200); // Start the serial console
156 |
157 | // Wait for user to press key to begin
158 | Serial.println(F("SARA-R5 Example"));
159 | Serial.println(F("Press any key to begin"));
160 |
161 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
162 | ;
163 | while (Serial.available()) // Empty the serial RX buffer
164 | Serial.read();
165 |
166 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
167 |
168 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
169 | // Comment the next line if required
170 | mySARA.invertPowerPin(true);
171 |
172 | // Initialize the SARA
173 | if (mySARA.begin(saraSerial, 9600) )
174 | {
175 | Serial.println(F("SARA-R5 connected!"));
176 | }
177 | else
178 | {
179 | Serial.println(F("Unable to communicate with the SARA."));
180 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
181 | while (1) ; // Loop forever on fail
182 | }
183 | Serial.println();
184 |
185 | // First check to see if we're already connected to an operator:
186 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS) {
187 | Serial.print(F("Already connected to: "));
188 | Serial.println(currentOperator);
189 | // If already connected provide the option to type y to connect to new operator
190 | Serial.println(F("Press y to connect to a new operator, or any other key to continue.\r\n"));
191 | while (!Serial.available()) ;
192 | if (Serial.read() != 'y')
193 | {
194 | newConnection = false;
195 | }
196 | else
197 | {
198 | mySARA.deregisterOperator(); // Deregister from the current operator so we can connect to a new one
199 | }
200 | while (Serial.available()) Serial.read();
201 | }
202 |
203 | if (newConnection) {
204 | // Set MNO to either Verizon, T-Mobile, AT&T, Telstra, etc.
205 | // This will narrow the operator options during our scan later
206 | Serial.println(F("Setting mobile-network operator"));
207 | if (mySARA.setNetworkProfile(MOBILE_NETWORK_OPERATOR))
208 | {
209 | Serial.print(F("Set mobile network operator to "));
210 | Serial.println(MOBILE_NETWORK_STRINGS[convertOperatorNumber(MOBILE_NETWORK_OPERATOR)] + "\r\n");
211 | }
212 | else
213 | {
214 | Serial.println(F("Error setting MNO. Try cycling the power. Freezing..."));
215 | while (1) ;
216 | }
217 |
218 | // Wait for user to press button before initiating network scan.
219 | Serial.println(F("Press any key scan for networks.."));
220 | serialWait();
221 |
222 | Serial.println(F("Scanning for networks...this may take up to 3 minutes\r\n"));
223 | // mySARA.getOperators takes in a operator_stats struct pointer and max number of
224 | // structs to scan for, then fills up those objects with operator names and numbers
225 | opsAvailable = mySARA.getOperators(ops, MAX_OPERATORS); // This will block for up to 3 minutes
226 |
227 | if (opsAvailable > 0)
228 | {
229 | // Pretty-print operators we found:
230 | Serial.println("Found " + String(opsAvailable) + " operators:");
231 | printOperators(ops, opsAvailable);
232 | Serial.println(String(opsAvailable + 1) + ": use automatic selection");
233 | Serial.println();
234 |
235 | // Wait until the user presses a key to initiate an operator connection
236 | Serial.println("Press 1-" + String(opsAvailable + 1) + " to select an operator.");
237 | char c = 0;
238 | bool selected = false;
239 | while (!selected) {
240 | while (!Serial.available()) ;
241 | c = Serial.read();
242 | int selection = c - '0';
243 | if ((selection >= 1) && (selection <= (opsAvailable + 1))) {
244 | selected = true;
245 | Serial.println("Connecting to option " + String(selection));
246 | if (selection == (opsAvailable + 1))
247 | {
248 | if (mySARA.automaticOperatorSelection() == SARA_R5_SUCCESS)
249 | {
250 | Serial.println("Automatic operator selection: successful\r\n");
251 | }
252 | else
253 | {
254 | Serial.println(F("Automatic operator selection: error. Reset and try again, or try another network."));
255 | }
256 | }
257 | else
258 | {
259 | if (mySARA.registerOperator(ops[selection - 1]) == SARA_R5_SUCCESS)
260 | {
261 | Serial.println("Network " + ops[selection - 1].longOp + " registered\r\n");
262 | }
263 | else
264 | {
265 | Serial.println(F("Error connecting to operator. Reset and try again, or try another network."));
266 | }
267 | }
268 | }
269 | }
270 | }
271 | else
272 | {
273 | Serial.println(F("Did not find an operator. Double-check SIM and antenna, reset and try again, or try another network."));
274 | while (1) ;
275 | }
276 | }
277 |
278 | // At the very end print connection information
279 | printInfo();
280 | }
281 |
282 | void loop()
283 | {
284 | // Loop provides a debugging interface.
285 | if (saraSerial.available()) {
286 | Serial.write((char) saraSerial.read());
287 | }
288 | #ifdef DEBUG_PASSTHROUGH_ENABLED
289 | if (Serial.available()) {
290 | saraSerial.write((char) Serial.read());
291 | }
292 | #endif
293 | }
294 |
295 | void printInfo(void) {
296 | String currentApn = "";
297 | IPAddress ip(0, 0, 0, 0);
298 | String currentOperator = "";
299 |
300 | Serial.println(F("Connection info:"));
301 | Serial.println(F("Context ID:\tAPN Name:\tIP Address:"));
302 | for (int cid = 0; cid < SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS; cid++)
303 | {
304 | String apn = "";
305 | IPAddress ip(0, 0, 0, 0);
306 | mySARA.getAPN(cid, &apn, &ip);
307 | if (apn.length() > 0)
308 | {
309 | Serial.print(cid);
310 | Serial.print(F("\t"));
311 | Serial.print(apn);
312 | Serial.print(F("\t"));
313 | Serial.println(ip);
314 | }
315 | }
316 |
317 | // Operator name or number
318 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
319 | {
320 | Serial.print(F("Operator: "));
321 | Serial.println(currentOperator);
322 | }
323 |
324 | // Received signal strength
325 | Serial.println("RSSI: " + String(mySARA.rssi()));
326 | Serial.println();
327 | }
328 |
329 | void printOperators(struct operator_stats * ops, int operatorsAvailable)
330 | {
331 | for (int i = 0; i < operatorsAvailable; i++)
332 | {
333 | Serial.print(String(i + 1) + ": ");
334 | Serial.print(ops[i].longOp + " (" + String(ops[i].numOp) + ") - ");
335 | switch (ops[i].stat)
336 | {
337 | case 0:
338 | Serial.print(F("UNKNOWN"));
339 | break;
340 | case 1:
341 | Serial.print(F("AVAILABLE"));
342 | break;
343 | case 2:
344 | Serial.print(F("CURRENT"));
345 | break;
346 | case 3:
347 | Serial.print(F("FORBIDDEN"));
348 | break;
349 | }
350 | switch (ops[i].act)
351 | {
352 | case 0:
353 | Serial.print(F(" - GSM"));
354 | break;
355 | case 2:
356 | Serial.print(F(" - UTRAN"));
357 | break;
358 | case 3:
359 | Serial.print(F(" - GSM/GPRS with EDGE"));
360 | break;
361 | case 7:
362 | Serial.print(F(" - LTE")); // SARA-R5 only supports LTE
363 | break;
364 | }
365 | Serial.println();
366 | }
367 | Serial.println();
368 | }
369 |
370 | void serialWait()
371 | {
372 | while (Serial.available()) Serial.read();
373 | while (!Serial.available()) ;
374 | delay(100);
375 | while (Serial.available()) Serial.read();
376 | }
377 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example5_ReceiveSMS/SARA-R5_Example5_ReceiveSMS.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Receive SMS
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example demonstrates how to receive SMS messages using the SARA.
12 |
13 | Feel like supporting open source hardware?
14 | Buy a board from SparkFun!
15 |
16 | Licence: MIT
17 | Please see LICENSE.md for full details
18 |
19 | */
20 |
21 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
22 |
23 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
24 | #define saraSerial Serial1
25 |
26 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
27 | //SoftwareSerial saraSerial(8, 9);
28 |
29 | // Create a SARA_R5 object to use throughout the sketch
30 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
31 | // but we can start the SARA without a power pin. It just means we need to manually
32 | // turn the power on if required! ;-D
33 | SARA_R5 mySARA;
34 |
35 | // Create a SARA_R5 object to use throughout the sketch
36 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
37 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
38 | // the pin name is G2 which is connected to pin AD34.
39 | // Change the pin number if required.
40 | //SARA_R5 mySARA(34);
41 |
42 | void setup()
43 | {
44 | String currentOperator = "";
45 |
46 | Serial.begin(115200); // Start the serial console
47 |
48 | // Wait for user to press key to begin
49 | Serial.println(F("SARA-R5 Example"));
50 | Serial.println(F("Press any key to begin"));
51 |
52 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
53 | ;
54 | while (Serial.available()) // Empty the serial RX buffer
55 | Serial.read();
56 |
57 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
58 |
59 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
60 | // Comment the next line if required
61 | mySARA.invertPowerPin(true);
62 |
63 | // Initialize the SARA
64 | if (mySARA.begin(saraSerial, 9600) )
65 | {
66 | Serial.println(F("SARA-R5 connected!"));
67 | }
68 | else
69 | {
70 | Serial.println(F("Unable to communicate with the SARA."));
71 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
72 | while (1) ; // Loop forever on fail
73 | }
74 | Serial.println();
75 |
76 | // First check to see if we're connected to an operator:
77 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
78 | {
79 | Serial.print(F("Connected to: "));
80 | Serial.println(currentOperator);
81 | }
82 | else
83 | {
84 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
85 | while (1)
86 | ; // Do nothing more
87 | }
88 |
89 | while (Serial.available()) // Empty the serial RX buffer
90 | Serial.read();
91 | }
92 |
93 | void loop()
94 | {
95 | static bool printReadMessages = true; // Print all messages once. Then only print new messages. Unless a message is deleted.
96 | static int previousUsed = -1; // Store the previous number of used memory locations
97 |
98 | // Read the number of used and total messages
99 | int used;
100 | int total;
101 | if (mySARA.getPreferredMessageStorage(&used, &total) != SARA_R5_SUCCESS)
102 | {
103 | Serial.println(F("An error occurred when trying to read ME memory!"));
104 | }
105 | else
106 | {
107 | if ((used != previousUsed) || printReadMessages) // Has a new message arrived? Or was the delete menu opened?
108 | {
109 | Serial.print(F("\r\nNumber of used memory locations: "));
110 | Serial.println(used);
111 | Serial.print(F("Total number of memory locations: "));
112 | Serial.println(total);
113 | Serial.println();
114 |
115 | int memoryLocation = 1;
116 | int foundMessages = 0;
117 | // Keep reading until we find all the messages or we reach the end of the memory
118 | while ((foundMessages < used) && (memoryLocation <= total))
119 | {
120 | String unread = "";
121 | String from = "";
122 | String dateTime = "";
123 | String message = "";
124 | // Read the message from this location. Reading from empty message locations returns an ERROR
125 | // unread can be: "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT"
126 | // If the location is empty, readSMSmessage will return a SARA_R5_ERROR_UNEXPECTED_RESPONSE
127 | if (mySARA.readSMSmessage(memoryLocation, &unread, &from, &dateTime, &message) == SARA_R5_SUCCESS)
128 | {
129 | if (printReadMessages || (unread == "REC UNREAD"))
130 | {
131 | Serial.print(F("Message location: "));
132 | Serial.println(memoryLocation);
133 | Serial.print(F("Status: "));
134 | Serial.println(unread);
135 | Serial.print(F("Originator: "));
136 | Serial.println(from);
137 | Serial.print(F("Date and time: "));
138 | Serial.println(dateTime);
139 | Serial.println(message);
140 | Serial.println();
141 | }
142 | foundMessages++; // We found a message
143 | }
144 | memoryLocation++; // Move on to the next memory location
145 | }
146 |
147 | printReadMessages = false;
148 | previousUsed = used; // Update previousUsed
149 |
150 | Serial.println(F("Waiting for a new message..."));
151 | Serial.println();
152 | Serial.println(F("Hit any key to delete a message..."));
153 | Serial.println();
154 | }
155 | }
156 |
157 | int delayCount = 0;
158 | while (delayCount < 5000)
159 | {
160 | delay(1); // Delay for five seconds, unless the user presses a key
161 | delayCount++;
162 |
163 | if (Serial.available())
164 | {
165 | Serial.println(F("To delete a single message: enter its location followed by LF / Newline"));
166 | Serial.println(F("To delete all read messages: enter r followed by LF / Newline"));
167 | Serial.println(F("To delete all read and sent messages: enter s followed by LF / Newline"));
168 | Serial.println(F("To delete all read, sent and unsent messages: enter u followed by LF / Newline"));
169 | Serial.println(F("To delete all messages, including unread messages: enter a followed by LF / Newline"));
170 | Serial.println(F("To exit: enter LF / Newline"));
171 |
172 | Serial.read(); // Read and discard the char that opened the menu
173 |
174 | int location = 0;
175 | bool selected = false;
176 | while (!selected)
177 | {
178 | while (!Serial.available()) ; // Wait for a character to arrive
179 | char c = Serial.read(); // Read it
180 | if (c == '\n') // Is it a LF?
181 | {
182 | if ((location >= 1) && (location <= total)) // Delete a single message at location
183 | {
184 | if (mySARA.deleteSMSmessage(location) == SARA_R5_SUCCESS)
185 | {
186 | Serial.println(F("\r\nMessage deleted!\r\n"));
187 | printReadMessages = true;
188 | }
189 | else
190 | {
191 | Serial.println(F("\r\nMessage not deleted!\r\n"));
192 | }
193 | }
194 | else if (location == 1001) // r
195 | {
196 | if (mySARA.deleteReadSMSmessages() == SARA_R5_SUCCESS)
197 | {
198 | Serial.println(F("\r\nRead messages deleted!\r\n"));
199 | printReadMessages = true;
200 | }
201 | else
202 | {
203 | Serial.println(F("\r\nMessages not deleted!\r\n"));
204 | }
205 | }
206 | else if (location == 1002) // s
207 | {
208 | if (mySARA.deleteReadSentSMSmessages() == SARA_R5_SUCCESS)
209 | {
210 | Serial.println(F("\r\nRead and sent messages deleted!\r\n"));
211 | printReadMessages = true;
212 | }
213 | else
214 | {
215 | Serial.println(F("\r\nMessages not deleted!\r\n"));
216 | }
217 | }
218 | else if (location == 1003) // u
219 | {
220 | if (mySARA.deleteReadSentUnsentSMSmessages() == SARA_R5_SUCCESS)
221 | {
222 | Serial.println(F("\r\nRead, sent and unsent messages deleted!\r\n"));
223 | printReadMessages = true;
224 | }
225 | else
226 | {
227 | Serial.println(F("\r\nMessages not deleted!\r\n"));
228 | }
229 | }
230 | else if (location == 1004) // a
231 | {
232 | if (mySARA.deleteAllSMSmessages() == SARA_R5_SUCCESS)
233 | {
234 | Serial.println(F("\r\nAll messages deleted!\r\n"));
235 | printReadMessages = true;
236 | }
237 | else
238 | {
239 | Serial.println(F("\r\nMessages not deleted!\r\n"));
240 | }
241 | }
242 | else
243 | Serial.println(F("\r\nExit...\r\n"));
244 | selected = true;
245 | }
246 | else if ((c >= '0') && (c <= '9'))
247 | {
248 | location *= 10; // Multiply by 10
249 | location += c - '0'; // Add the digit
250 | }
251 | else if (c == 'r')
252 | {
253 | location = 1001;
254 | }
255 | else if (c == 's')
256 | {
257 | location = 1002;
258 | }
259 | else if (c == 'u')
260 | {
261 | location = 1003;
262 | }
263 | else if (c == 'a')
264 | {
265 | location = 1004;
266 | }
267 | }
268 |
269 | delayCount = 5000;
270 | }
271 | }
272 | }
273 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example6_SendSMS/SARA-R5_Example6_SendSMS.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Send SMS
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example demonstrates how to send SMS messages using the SARA.
12 |
13 | Feel like supporting open source hardware?
14 | Buy a board from SparkFun!
15 |
16 | Licence: MIT
17 | Please see LICENSE.md for full details
18 |
19 | */
20 |
21 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
22 |
23 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
24 | #define saraSerial Serial1
25 |
26 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
27 | //SoftwareSerial saraSerial(8, 9);
28 |
29 | // Create a SARA_R5 object to use throughout the sketch
30 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
31 | // but we can start the SARA without a power pin. It just means we need to manually
32 | // turn the power on if required! ;-D
33 | SARA_R5 mySARA;
34 |
35 | // Create a SARA_R5 object to use throughout the sketch
36 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
37 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
38 | // the pin name is G2 which is connected to pin AD34.
39 | // Change the pin number if required.
40 | //SARA_R5 mySARA(34);
41 |
42 | void setup()
43 | {
44 | String currentOperator = "";
45 |
46 | Serial.begin(115200); // Start the serial console
47 |
48 | // Wait for user to press key to begin
49 | Serial.println(F("SARA-R5 Example"));
50 | Serial.println(F("Press any key to begin"));
51 |
52 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
53 | ;
54 | while (Serial.available()) // Empty the serial RX buffer
55 | Serial.read();
56 |
57 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
58 |
59 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
60 | // Comment the next line if required
61 | mySARA.invertPowerPin(true);
62 |
63 | // Initialize the SARA
64 | if (mySARA.begin(saraSerial, 9600) )
65 | {
66 | Serial.println(F("SARA-R5 connected!"));
67 | }
68 | else
69 | {
70 | Serial.println(F("Unable to communicate with the SARA."));
71 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
72 | while (1) ; // Loop forever on fail
73 | }
74 | Serial.println();
75 |
76 | // First check to see if we're connected to an operator:
77 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
78 | {
79 | Serial.print(F("Connected to: "));
80 | Serial.println(currentOperator);
81 | }
82 | else
83 | {
84 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
85 | while (1)
86 | ; // Do nothing more
87 | }
88 |
89 | Serial.println();
90 | Serial.println(F("*** Set the Serial Monitor line ending to Newline ***"));
91 | }
92 |
93 | void loop()
94 | {
95 | String destinationNumber = "";
96 | String message = "";
97 | boolean keepGoing = true;
98 |
99 | Serial.println();
100 | Serial.println(F("Enter the destination number (followed by LF / Newline): "));
101 |
102 | while (keepGoing)
103 | {
104 | if (Serial.available())
105 | {
106 | char c = Serial.read();
107 | if (c == '\n')
108 | {
109 | keepGoing = false; // Stop if we receive a newline
110 | }
111 | else
112 | {
113 | destinationNumber += c; // Add serial characters to the destination number
114 | }
115 | }
116 | }
117 |
118 | keepGoing = true;
119 | Serial.println();
120 | Serial.println(F("Enter the message (followed by LF): "));
121 |
122 | while (keepGoing)
123 | {
124 | if (Serial.available())
125 | {
126 | char c = Serial.read();
127 | if (c == '\n')
128 | {
129 | keepGoing = false; // Stop if we receive a newline
130 | }
131 | else
132 | {
133 | message += c; // Add serial characters to the destination number
134 | }
135 | }
136 | }
137 |
138 | // Once we receive a newline, send the text.
139 | Serial.println("Sending: \"" + message + "\" to " + destinationNumber);
140 | // Call mySARA.sendSMS(String number, String message) to send an SMS message.
141 | if (mySARA.sendSMS(destinationNumber, message) == SARA_R5_SUCCESS)
142 | {
143 | Serial.println(F("sendSMS was successful"));
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example7_ConfigurePacketSwitchedData/SARA-R5_Example7_ConfigurePacketSwitchedData.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Configure Packet Switched Data
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example demonstrates how to configure Packet Switched Data on the SARA-R5.
12 |
13 | The earlier examples let you configure the network profile and select an operator.
14 | The default operator - defined in your SIM - will be allocated to "Context ID 1".
15 | This example defines a Packet Switched Data Profile ID, based on the selected Context ID, and then activates it.
16 | The profile parameters are also saved to NVM so they can be used by the next examples.
17 | The only complicated bit is that - strictly - we need to disconnect from the network first in order to find out what
18 | the defined IP type is for the chosen Context ID - as opposed to what is granted by the network. However, we'll
19 | take a guess that it is the default (IPv4v6). You can change this if required by editing the call to setPDPconfiguration.
20 |
21 | Feel like supporting open source hardware?
22 | Buy a board from SparkFun!
23 |
24 | Licence: MIT
25 | Please see LICENSE.md for full details
26 |
27 | */
28 |
29 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
30 |
31 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
32 | #define saraSerial Serial1
33 |
34 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
35 | //SoftwareSerial saraSerial(8, 9);
36 |
37 | // Create a SARA_R5 object to use throughout the sketch
38 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
39 | // but we can start the SARA without a power pin. It just means we need to manually
40 | // turn the power on if required! ;-D
41 | SARA_R5 mySARA;
42 |
43 | // Create a SARA_R5 object to use throughout the sketch
44 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
45 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
46 | // the pin name is G2 which is connected to pin AD34.
47 | // Change the pin number if required.
48 | //SARA_R5 mySARA(34);
49 |
50 | // processPSDAction is provided to the SARA-R5 library via a
51 | // callback setter -- setPSDActionCallback. (See setup())
52 | void processPSDAction(int result, IPAddress ip)
53 | {
54 | Serial.println();
55 | Serial.print(F("PSD Action: result: "));
56 | Serial.print(String(result));
57 | if (result == 0)
58 | Serial.print(F(" (success)"));
59 | Serial.print(F(" IP Address: \""));
60 | Serial.print(String(ip[0]));
61 | Serial.print(F("."));
62 | Serial.print(String(ip[1]));
63 | Serial.print(F("."));
64 | Serial.print(String(ip[2]));
65 | Serial.print(F("."));
66 | Serial.print(String(ip[3]));
67 | Serial.println(F("\""));
68 | }
69 |
70 | void setup()
71 | {
72 | String currentOperator = "";
73 |
74 | Serial.begin(115200); // Start the serial console
75 |
76 | // Wait for user to press key to begin
77 | Serial.println(F("SARA-R5 Example"));
78 | Serial.println(F("Press any key to begin"));
79 |
80 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
81 | ;
82 | while (Serial.available()) // Empty the serial RX buffer
83 | Serial.read();
84 |
85 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
86 |
87 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
88 | // Comment the next line if required
89 | mySARA.invertPowerPin(true);
90 |
91 | // Initialize the SARA
92 | if (mySARA.begin(saraSerial, 9600) )
93 | {
94 | Serial.println(F("SARA-R5 connected!"));
95 | }
96 | else
97 | {
98 | Serial.println(F("Unable to communicate with the SARA."));
99 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
100 | while (1) ; // Loop forever on fail
101 | }
102 | Serial.println();
103 |
104 | // First check to see if we're connected to an operator:
105 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
106 | {
107 | Serial.print(F("Connected to: "));
108 | Serial.println(currentOperator);
109 | }
110 | else
111 | {
112 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
113 | while (1)
114 | ; // Do nothing more
115 | }
116 |
117 | int minCID = SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS; // Keep a record of the highest and lowest CIDs
118 | int maxCID = 0;
119 |
120 | Serial.println(F("The available Context IDs are:"));
121 | Serial.println(F("Context ID:\tAPN Name:\tIP Address:"));
122 | for (int cid = 0; cid < SARA_R5_NUM_PDP_CONTEXT_IDENTIFIERS; cid++)
123 | {
124 | String apn = "";
125 | IPAddress ip(0, 0, 0, 0);
126 | mySARA.getAPN(cid, &apn, &ip);
127 | if (apn.length() > 0)
128 | {
129 | Serial.print(cid);
130 | Serial.print(F("\t"));
131 | Serial.print(apn);
132 | Serial.print(F("\t"));
133 | Serial.println(ip);
134 | }
135 | if (cid < minCID)
136 | minCID = cid; // Record the lowest CID
137 | if (cid > maxCID)
138 | maxCID = cid; // Record the highest CID
139 | }
140 | Serial.println();
141 |
142 | Serial.println(F("Which Context ID do you want to use for your Packet Switched Data connection?"));
143 | Serial.println(F("Please enter the number (followed by LF / Newline): "));
144 |
145 | char c = 0;
146 | bool selected = false;
147 | int selection = 0;
148 | while (!selected)
149 | {
150 | while (!Serial.available()) ; // Wait for a character to arrive
151 | c = Serial.read(); // Read it
152 | if (c == '\n') // Is it a LF?
153 | {
154 | if ((selection >= minCID) && (selection <= maxCID))
155 | {
156 | selected = true;
157 | Serial.println("Using CID: " + String(selection));
158 | }
159 | else
160 | {
161 | Serial.println(F("Invalid CID. Please try again:"));
162 | selection = 0;
163 | }
164 | }
165 | else
166 | {
167 | selection *= 10; // Multiply selection by 10
168 | selection += c - '0'; // Add the new digit to selection
169 | }
170 | }
171 |
172 | // Deactivate the profile
173 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
174 | {
175 | Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
176 | }
177 |
178 | // Map PSD profile 0 to the selected CID
179 | if (mySARA.setPDPconfiguration(0, SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID, selection) != SARA_R5_SUCCESS)
180 | {
181 | Serial.println(F("setPDPconfiguration (map to CID) failed! Freezing..."));
182 | while (1)
183 | ; // Do nothing more
184 | }
185 |
186 | // Set the protocol type - this needs to match the defined IP type for the CID (as opposed to what was granted by the network)
187 | if (mySARA.setPDPconfiguration(0, SARA_R5_PSD_CONFIG_PARAM_PROTOCOL, SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF) != SARA_R5_SUCCESS)
188 | // You _may_ need to change the protocol type: ----------------------------------------^
189 | {
190 | Serial.println(F("setPDPconfiguration (set protocol type) failed! Freezing..."));
191 | while (1)
192 | ; // Do nothing more
193 | }
194 |
195 | // Set a callback to process the results of the PSD Action
196 | mySARA.setPSDActionCallback(&processPSDAction);
197 |
198 | // Activate the profile
199 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
200 | {
201 | Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
202 | while (1)
203 | ; // Do nothing more
204 | }
205 |
206 | for (int i = 0; i < 100; i++) // Wait for up to a second for the PSD Action URC to arrive
207 | {
208 | mySARA.poll(); // Keep processing data from the SARA so we can process the PSD Action
209 | delay(10);
210 | }
211 |
212 | // Save the profile to NVM - so we can load it again in the later examples
213 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_STORE) != SARA_R5_SUCCESS)
214 | {
215 | Serial.println(F("performPDPaction (save to NVM) failed! Freezing..."));
216 | while (1)
217 | ; // Do nothing more
218 | }
219 |
220 | }
221 |
222 | void loop()
223 | {
224 | mySARA.poll(); // Keep processing data from the SARA so we can process URCs from the PSD Action
225 | }
226 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example8_Ping/SARA-R5_Example8_Ping.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | Ping
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example uses the SARA's mobile data connection to ping a server.
12 |
13 | Feel like supporting open source hardware?
14 | Buy a board from SparkFun!
15 |
16 | Licence: MIT
17 | Please see LICENSE.md for full details
18 |
19 | */
20 |
21 | #include
22 |
23 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
24 |
25 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
26 | #define saraSerial Serial1
27 |
28 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
29 | //SoftwareSerial saraSerial(8, 9);
30 |
31 | // Create a SARA_R5 object to use throughout the sketch
32 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
33 | // but we can start the SARA without a power pin. It just means we need to manually
34 | // turn the power on if required! ;-D
35 | SARA_R5 mySARA;
36 |
37 | // Create a SARA_R5 object to use throughout the sketch
38 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
39 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
40 | // the pin name is G2 which is connected to pin AD34.
41 | // Change the pin number if required.
42 | //SARA_R5 mySARA(34);
43 |
44 | String pingMe = ""; // The name of the server we are going to ping
45 |
46 | // processPingResult is provided to the SARA-R5 library via a
47 | // callback setter -- setPingCallback. (See the end of setup())
48 | void processPingResult(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)
49 | {
50 | Serial.println();
51 | Serial.print(F("Ping Result: Retry #:"));
52 | Serial.print(retry);
53 | Serial.print(F(" Ping Size (Bytes):"));
54 | Serial.print(p_size);
55 | Serial.print(F(" Remote Host:\""));
56 | Serial.print(remote_hostname);
57 | Serial.print(F("\" IP Address:\""));
58 | Serial.print(String(ip[0]));
59 | Serial.print(F("."));
60 | Serial.print(String(ip[1]));
61 | Serial.print(F("."));
62 | Serial.print(String(ip[2]));
63 | Serial.print(F("."));
64 | Serial.print(String(ip[3]));
65 | Serial.print(F("\" Time To Live (hops):"));
66 | Serial.print(ttl);
67 | Serial.print(F(" Round Trip (ms):"));
68 | Serial.print(rtt);
69 | Serial.println();
70 | }
71 |
72 | void setup()
73 | {
74 | String currentOperator = "";
75 |
76 | Serial.begin(115200); // Start the serial console
77 |
78 | // Wait for user to press key to begin
79 | Serial.println(F("SARA-R5 Example"));
80 | Serial.println(F("Press any key to begin"));
81 |
82 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
83 | ;
84 | while (Serial.available()) // Empty the serial RX buffer
85 | Serial.read();
86 |
87 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
88 |
89 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
90 | // Comment the next line if required
91 | mySARA.invertPowerPin(true);
92 |
93 | // Initialize the SARA
94 | if (mySARA.begin(saraSerial, 9600) )
95 | {
96 | Serial.println(F("SARA-R5 connected!"));
97 | }
98 | else
99 | {
100 | Serial.println(F("Unable to communicate with the SARA."));
101 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
102 | while (1) ; // Loop forever on fail
103 | }
104 | Serial.println();
105 |
106 | // First check to see if we're connected to an operator:
107 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
108 | {
109 | Serial.print(F("Connected to: "));
110 | Serial.println(currentOperator);
111 | }
112 | else
113 | {
114 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
115 | while (1)
116 | ; // Do nothing more
117 | }
118 |
119 | // Deactivate the profile - in case one is already active
120 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
121 | {
122 | Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
123 | }
124 |
125 | // Load the profile from NVM - these were saved by a previous example
126 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_LOAD) != SARA_R5_SUCCESS)
127 | {
128 | Serial.println(F("performPDPaction (load from NVM) failed! Freezing..."));
129 | while (1)
130 | ; // Do nothing more
131 | }
132 |
133 | // Activate the profile
134 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
135 | {
136 | Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
137 | while (1)
138 | ; // Do nothing more
139 | }
140 |
141 | Serial.println();
142 | Serial.println(F("*** Set the Serial Monitor line ending to Newline ***"));
143 |
144 | Serial.println();
145 | Serial.println(F("Enter the name of the server you want to ping (followed by LF / Newline): "));
146 |
147 | // Set a callback to process the Ping result
148 | mySARA.setPingCallback(&processPingResult);
149 | }
150 |
151 | void loop()
152 | {
153 | if (Serial.available())
154 | {
155 | char c = Serial.read();
156 | if (c == '\n')
157 | {
158 | // Newline received so let's do that ping!
159 | mySARA.ping(pingMe); // Use the default parameters
160 |
161 | // Use custom parameters
162 | //int retries = 4; // number of retries
163 | //int p_size = 32; // packet size (bytes)
164 | //unsigned long timeout = 5000; // timeout (ms)
165 | //int ttl = 32; // Time To Live
166 | //mySARA.ping(pingMe, retries, p_size, timeout, ttl);
167 |
168 | pingMe = ""; // Clear the server name for the next try
169 | }
170 | else
171 | {
172 | // Add serial characters to the server address
173 | pingMe += c;
174 | }
175 | }
176 |
177 | mySARA.poll(); // Keep processing data from the SARA so we can catch the Ping result
178 | }
179 |
--------------------------------------------------------------------------------
/examples/SARA-R5_Example9_ThingSpeak/SARA-R5_Example9_ThingSpeak.ino:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | SARA-R5 Example
4 | ===============
5 |
6 | ThingSpeak (HTTP POST / GET)
7 |
8 | Written by: Paul Clark
9 | Date: November 18th 2020
10 |
11 | This example uses the SARA's mobile data connection to send random temperatures to ThingSpeak using HTTP POST or GET.
12 | https://thingspeak.com/
13 |
14 | You will need to:
15 | Create a ThingSpeak User Account – https://thingspeak.com/login
16 | Create a new Channel by selecting Channels, My Channels, and then New Channel
17 | Note the Write API Key and copy&paste it into myWriteAPIKey below
18 | The random temperature reading will be added to the channel as "Field 1"
19 |
20 | Feel like supporting open source hardware?
21 | Buy a board from SparkFun!
22 |
23 | Licence: MIT
24 | Please see LICENSE.md for full details
25 |
26 | */
27 |
28 | #include
29 |
30 | // ThingSpeak via HTTP POST / GET
31 |
32 | String myWriteAPIKey = "PFIOEXW1VF21T7O6"; // Change this to your API key
33 |
34 | String serverName = "api.thingspeak.com"; // Domain Name for HTTP POST / GET
35 |
36 | // SARA-R5
37 |
38 | #include //Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library
39 |
40 | // Uncomment the next line to connect to the SARA-R5 using hardware Serial1
41 | #define saraSerial Serial1
42 |
43 | // Uncomment the next line to create a SoftwareSerial object to pass to the SARA-R5 library instead
44 | //SoftwareSerial saraSerial(8, 9);
45 |
46 | // Create a SARA_R5 object to use throughout the sketch
47 | // Usually we would tell the library which GPIO pin to use to control the SARA power (see below),
48 | // but we can start the SARA without a power pin. It just means we need to manually
49 | // turn the power on if required! ;-D
50 | SARA_R5 mySARA;
51 |
52 | // Create a SARA_R5 object to use throughout the sketch
53 | // We need to tell the library what GPIO pin is connected to the SARA power pin.
54 | // If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board,
55 | // the pin name is G2 which is connected to pin AD34.
56 | // Change the pin number if required.
57 | //SARA_R5 mySARA(34);
58 |
59 | // processHTTPcommandResult is provided to the SARA-R5 library via a
60 | // callback setter -- setHTTPCommandCallback. (See the end of setup())
61 | void processHTTPcommandResult(int profile, int command, int result)
62 | {
63 | Serial.println();
64 | Serial.print(F("HTTP Command Result: profile: "));
65 | Serial.print(profile);
66 | Serial.print(F(" command: "));
67 | Serial.print(command);
68 | Serial.print(F(" result: "));
69 | Serial.print(result);
70 | if (result == 0)
71 | Serial.print(F(" (fail)"));
72 | if (result == 1)
73 | Serial.print(F(" (success)"));
74 | Serial.println();
75 |
76 | // Get and print the most recent HTTP protocol error
77 | int error_class;
78 | int error_code;
79 | mySARA.getHTTPprotocolError(0, &error_class, &error_code);
80 | Serial.print(F("Most recent HTTP protocol error: class: "));
81 | Serial.print(error_class);
82 | Serial.print(F(" code: "));
83 | Serial.print(error_code);
84 | if (error_code == 0)
85 | Serial.print(F(" (no error)"));
86 | Serial.println();
87 |
88 | // Read and print the HTTP POST result
89 | String postResult = "";
90 | mySARA.getFileContents("post_response.txt", &postResult);
91 | Serial.print(F("HTTP command result was: "));
92 | Serial.println(postResult);
93 |
94 | Serial.println();
95 | }
96 |
97 | void setup()
98 | {
99 | String currentOperator = "";
100 |
101 | Serial.begin(115200); // Start the serial console
102 |
103 | // Wait for user to press key to begin
104 | Serial.println(F("SARA-R5 Example"));
105 | Serial.println(F("Press any key to begin"));
106 |
107 | while (!Serial.available()) // Wait for the user to press a key (send any serial character)
108 | ;
109 | while (Serial.available()) // Empty the serial RX buffer
110 | Serial.read();
111 |
112 | //mySARA.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
113 |
114 | // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
115 | // Comment the next line if required
116 | mySARA.invertPowerPin(true);
117 |
118 | // Initialize the SARA
119 | if (mySARA.begin(saraSerial, 9600) )
120 | {
121 | Serial.println(F("SARA-R5 connected!"));
122 | }
123 | else
124 | {
125 | Serial.println(F("Unable to communicate with the SARA."));
126 | Serial.println(F("Manually power-on (hold the SARA On button for 3 seconds) on and try again."));
127 | while (1) ; // Loop forever on fail
128 | }
129 | Serial.println();
130 |
131 | // First check to see if we're connected to an operator:
132 | if (mySARA.getOperator(¤tOperator) == SARA_R5_SUCCESS)
133 | {
134 | Serial.print(F("Connected to: "));
135 | Serial.println(currentOperator);
136 | }
137 | else
138 | {
139 | Serial.print(F("The SARA is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing..."));
140 | while (1)
141 | ; // Do nothing more
142 | }
143 |
144 | // Deactivate the PSD profile - in case one is already active
145 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_DEACTIVATE) != SARA_R5_SUCCESS)
146 | {
147 | Serial.println(F("Warning: performPDPaction (deactivate profile) failed. Probably because no profile was active."));
148 | }
149 |
150 | // Load the PSD profile from NVM - these were saved by a previous example
151 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_LOAD) != SARA_R5_SUCCESS)
152 | {
153 | Serial.println(F("performPDPaction (load from NVM) failed! Freezing..."));
154 | while (1)
155 | ; // Do nothing more
156 | }
157 |
158 | // Activate the PSD profile
159 | if (mySARA.performPDPaction(0, SARA_R5_PSD_ACTION_ACTIVATE) != SARA_R5_SUCCESS)
160 | {
161 | Serial.println(F("performPDPaction (activate profile) failed! Freezing..."));
162 | while (1)
163 | ; // Do nothing more
164 | }
165 |
166 | // Reset HTTP profile 0
167 | mySARA.resetHTTPprofile(0);
168 |
169 | // Set the server name
170 | mySARA.setHTTPserverName(0, serverName);
171 |
172 | // Use HTTPS
173 | mySARA.setHTTPsecure(0, false); // Setting this to true causes the POST / GET to fail. Not sure why...
174 |
175 | // Set a callback to process the HTTP command result
176 | mySARA.setHTTPCommandCallback(&processHTTPcommandResult);
177 | }
178 |
179 | void loop()
180 | {
181 | float temperature = ((float)random(2000,3000)) / 100.0; // Create a random temperature between 20 and 30
182 |
183 | //---
184 |
185 | // Send data using HTTP POST
186 | String httpRequestData = "api_key=" + myWriteAPIKey + "&field1=" + String(temperature);
187 |
188 | Serial.print(F("POSTing a temperature of "));
189 | Serial.print(String(temperature));
190 | Serial.println(F(" to ThingSpeak"));
191 |
192 | // Send HTTP POST request to /update. The reponse will be written to post_response.txt in the SARA's file system
193 | mySARA.sendHTTPPOSTdata(0, "/update", "post_response.txt", httpRequestData, SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW);
194 |
195 | //---
196 |
197 | // // Send data using HTTP GET
198 | // String path = "/update?api_key=" + myWriteAPIKey + "&field1=" + String(temperature);
199 | //
200 | // Serial.print(F("Send a temperature of "));
201 | // Serial.print(String(temperature));
202 | // Serial.println(F(" to ThingSpeak using HTTP GET"));
203 | //
204 | // // Send HTTP POST request to /update. The reponse will be written to post_response.txt in the SARA's file system
205 | // mySARA.sendHTTPGET(0, path, "post_response.txt");
206 |
207 | //---
208 |
209 | // Wait for 20 seconds
210 | for (int i = 0; i < 20000; i++)
211 | {
212 | mySARA.poll(); // Keep processing data from the SARA so we can catch the HTTP command result
213 | delay(1);
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/img/Contributing.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparkfun/SparkFun_u-blox_SARA-R5_Arduino_Library/c9cb44d27401b968b1ef7cf6f63e487447b3155a/img/Contributing.JPG
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes KEYWORD1
7 | #######################################
8 |
9 | SARA_R5 KEYWORD1
10 | SARA_R5_flow_control_t KEYWORD1
11 | mobile_network_operator_t KEYWORD1
12 | SARA_R5_error_t KEYWORD1
13 | SARA_R5_registration_status_t KEYWORD1
14 | DateData KEYWORD1
15 | TimeData KEYWORD1
16 | ClockData KEYWORD1
17 | PositionData KEYWORD1
18 | SpeedData KEYWORD1
19 | operator_stats KEYWORD1
20 | SARA_R5_socket_protocol_t KEYWORD1
21 | SARA_R5_message_format_t KEYWORD1
22 | SARA_R5_utime_mode_t KEYWORD1
23 | SARA_R5_utime_sensor_t KEYWORD1
24 | SARA_R5_utime_urc_configuration_t KEYWORD1
25 | SARA_R5_sim_states_t KEYWORD1
26 | SARA_R5_http_op_codes_t KEYWORD1
27 | SARA_R5_http_commands_t KEYWORD1
28 | SARA_R5_http_content_types_t KEYWORD1
29 | SARA_R5_mqtt_nv_parameter_t KEYWORD1
30 | SARA_R5_mqtt_profile_opcode_t KEYWORD1
31 | SARA_R5_mqtt_command_opcode_t KEYWORD1
32 | SARA_R5_pdp_configuration_parameter_t KEYWORD1
33 | SARA_R5_pdp_protocol_type_t KEYWORD1
34 | SARA_R5_pdp_actions_t KEYWORD1
35 | SARA_R5_sec_profile_parameter_t KEYWORD1
36 | SARA_R5_sec_profile_certval_op_code_t KEYWORD1
37 | SARA_R5_sec_profile_tls_op_code_t KEYWORD1
38 | SARA_R5_sec_profile_suite_op_code_t KEYWORD1
39 | SARA_R5_sec_manager_opcode_t KEYWORD1
40 | SARA_R5_sec_manager_parameter_t KEYWORD1
41 | SARA_R5_functionality_t KEYWORD1
42 | SARA_R5_pdp_type KEYWORD1
43 | SARA_R5_l2p_t KEYWORD1
44 | SARA_R5_gpio_t KEYWORD1
45 | SARA_R5_gpio_mode_t KEYWORD1
46 | gnss_system_t KEYWORD1
47 | gnss_aiding_mode_t KEYWORD1
48 |
49 | #######################################
50 | # Methods and Functions KEYWORD2
51 | #######################################
52 |
53 | begin KEYWORD2
54 | enableDebugging KEYWORD2
55 | enableAtDebugging KEYWORD2
56 | invertPowerPin KEYWORD2
57 | modulePowerOff KEYWORD2
58 | modulePowerOn KEYWORD2
59 | bufferedPoll KEYWORD2
60 | processReadEvent KEYWORD2
61 | poll KEYWORD2
62 | setSocketListenCallback KEYWORD2
63 | setSocketReadCallback KEYWORD2
64 | setSocketReadCallbackPlus KEYWORD2
65 | setSocketCloseCallback KEYWORD2
66 | setGpsReadCallback KEYWORD2
67 | setSIMstateReportCallback KEYWORD2
68 | setPSDActionCallback KEYWORD2
69 | setPingCallback KEYWORD2
70 | setHTTPCommandCallback KEYWORD2
71 | setMQTTCommandCallback KEYWORD2
72 | setRegistrationCallback KEYWORD2
73 | setEpsRegistrationCallback KEYWORD2
74 | write KEYWORD2
75 | at KEYWORD2
76 | enableEcho KEYWORD2
77 | getManufacturerID KEYWORD2
78 | getModelID KEYWORD2
79 | getFirmwareVersion KEYWORD2
80 | getSerialNo KEYWORD2
81 | getIMEI KEYWORD2
82 | getIMSI KEYWORD2
83 | getCCID KEYWORD2
84 | getSubscriberNo KEYWORD2
85 | getCapabilities KEYWORD2
86 | reset KEYWORD2
87 | clock KEYWORD2
88 | setClock KEYWORD2
89 | autoTimeZoneForBegin KEYWORD2
90 | autoTimeZone KEYWORD2
91 | setUtimeMode KEYWORD2
92 | getUtimeMode KEYWORD2
93 | setUtimeIndication KEYWORD2
94 | getUtimeIndication KEYWORD2
95 | setUtimeConfiguration KEYWORD2
96 | getUtimeConfiguration KEYWORD2
97 | rssi KEYWORD2
98 | registration KEYWORD2
99 | setNetworkProfile KEYWORD2
100 | getNetworkProfile KEYWORD2
101 | setAPN KEYWORD2
102 | getAPN KEYWORD2
103 | getSimStatus KEYWORD2
104 | setSimPin KEYWORD2
105 | setSIMstateReportingMode KEYWORD2
106 | getSIMstateReportingMode KEYWORD2
107 | enterPPP KEYWORD2
108 | getOperators KEYWORD2
109 | registerOperator KEYWORD2
110 | automaticOperatorSelection KEYWORD2
111 | getOperator KEYWORD2
112 | deregisterOperator KEYWORD2
113 | setSMSMessageFormat KEYWORD2
114 | sendSMS KEYWORD2
115 | getPreferredMessageStorage KEYWORD2
116 | readSMSmessage KEYWORD2
117 | deleteSMSmessage KEYWORD2
118 | deleteReadSMSmessages KEYWORD2
119 | deleteReadSentSMSmessages KEYWORD2
120 | deleteReadSentUnsentSMSmessages KEYWORD2
121 | deleteAllSMSmessages KEYWORD2
122 | setBaud KEYWORD2
123 | setFlowControl KEYWORD2
124 | setGpioMode KEYWORD2
125 | getGpioMode KEYWORD2
126 | socketOpen KEYWORD2
127 | socketClose KEYWORD2
128 | socketConnect KEYWORD2
129 | socketWrite KEYWORD2
130 | socketWriteUDP KEYWORD2
131 | socketRead KEYWORD2
132 | socketReadAvailable KEYWORD2
133 | socketReadUDP KEYWORD2
134 | socketReadAvailableUDP KEYWORD2
135 | socketListen KEYWORD2
136 | socketDirectLinkMode KEYWORD2
137 | socketDirectLinkTimeTrigger KEYWORD2
138 | socketDirectLinkDataLengthTrigger KEYWORD2
139 | socketDirectLinkCharacterTrigger KEYWORD2
140 | socketDirectLinkCongestionTimer KEYWORD2
141 | querySocketType KEYWORD2
142 | querySocketLastError KEYWORD2
143 | querySocketTotalBytesSent KEYWORD2
144 | querySocketTotalBytesReceived KEYWORD2
145 | querySocketRemoteIPAddress KEYWORD2
146 | querySocketStatusTCP KEYWORD2
147 | querySocketOutUnackData KEYWORD2
148 | socketSetSecure KEYWORD2
149 | socketGetLastError KEYWORD2
150 | lastRemoteIP KEYWORD2
151 | ping KEYWORD2
152 | resetHTTPprofile KEYWORD2
153 | setHTTPserverIPaddress KEYWORD2
154 | setHTTPserverName KEYWORD2
155 | setHTTPusername KEYWORD2
156 | setHTTPpassword KEYWORD2
157 | setHTTPauthentication KEYWORD2
158 | setHTTPserverPort KEYWORD2
159 | setHTTPcustomHeader KEYWORD2
160 | setHTTPsecure KEYWORD2
161 | getHTTPprotocolError KEYWORD2
162 | sendHTTPGET KEYWORD2
163 | sendHTTPPOSTdata KEYWORD2
164 | sendHTTPPOSTfile KEYWORD2
165 | nvMQTT KEYWORD2
166 | setMQTTclientId KEYWORD2
167 | setMQTTserver KEYWORD2
168 | setMQTTcredentials KEYWORD2
169 | setMQTTsecure KEYWORD2
170 | connectMQTT KEYWORD2
171 | disconnectMQTT KEYWORD2
172 | subscribeMQTTtopic KEYWORD2
173 | unsubscribeMQTTtopic KEYWORD2
174 | readMQTT KEYWORD2
175 | mqttPublishTextMsg KEYWORD2
176 | mqttPublishBinaryMsg KEYWORD2
177 | mqttPublishFromFile KEYWORD2
178 | getMQTTprotocolError KEYWORD2
179 | resetSecurityProfile KEYWORD2
180 | configSecurityProfileString KEYWORD2
181 | configSecurityProfile KEYWORD2
182 | setSecurityManager KEYWORD2
183 | setPDPconfiguration KEYWORD2
184 | performPDPaction KEYWORD2
185 | activatePDPcontext KEYWORD2
186 | getNetworkAssignedIPAddress KEYWORD2
187 | isGPSon KEYWORD2
188 | gpsPower KEYWORD2
189 | # gpsEnableClock KEYWORD2
190 | # gpsGetClock KEYWORD2
191 | # gpsEnableFix KEYWORD2
192 | # gpsGetFix KEYWORD2
193 | # gpsEnablePos KEYWORD2
194 | # gpsGetPos KEYWORD2
195 | # gpsEnableSat KEYWORD2
196 | # gpsGetSat KEYWORD2
197 | gpsEnableRmc KEYWORD2
198 | gpsGetRmc KEYWORD2
199 | # gpsEnableSpeed KEYWORD2
200 | # gpsGetSpeed KEYWORD2
201 | gpsRequest KEYWORD2
202 | gpsAidingServerConf KEYWORD2
203 | getFileContents KEYWORD2
204 | appendFileContents KEYWORD2
205 | getFileSize KEYWORD2
206 | deleteFile KEYWORD2
207 | functionality KEYWORD2
208 | sendCustomCommandWithResponse KEYWORD2
209 |
210 | #######################################
211 | # Constants LITERAL1
212 | #######################################
213 |
214 | SARA_R5_DISABLE_FLOW_CONTROL LITERAL1
215 | SARA_R5_ENABLE_FLOW_CONTROL LITERAL1
216 | MNO_INVALID LITERAL1
217 | MNO_SW_DEFAULT LITERAL1
218 | MNO_SIM_ICCID LITERAL1
219 | MNO_ATT LITERAL1
220 | MNO_VERIZON LITERAL1
221 | MNO_TELSTRA LITERAL1
222 | MNO_TMO LITERAL1
223 | MNO_CT LITERAL1
224 | MNO_SPRINT LITERAL1
225 | MNO_VODAFONE LITERAL1
226 | MNO_NTT_DOCOMO LITERAL1
227 | MNO_TELUS LITERAL1
228 | MNO_SOFTBANK LITERAL1
229 | MNO_DT LITERAL1
230 | MNO_US_CELLULAR LITERAL1
231 | MNO_SKT LITERAL1
232 | MNO_GLOBAL LITERAL1
233 | MNO_STD_EUROPE LITERAL1
234 | MNO_STD_EU_NOEPCO LITERAL1
235 | SARA_R5_ERROR_INVALID LITERAL1
236 | SARA_R5_ERROR_SUCCESS LITERAL1
237 | SARA_R5_ERROR_OUT_OF_MEMORY LITERAL1
238 | SARA_R5_ERROR_TIMEOUT LITERAL1
239 | SARA_R5_ERROR_UNEXPECTED_PARAM LITERAL1
240 | SARA_R5_ERROR_UNEXPECTED_RESPONSE LITERAL1
241 | SARA_R5_ERROR_NO_RESPONSE LITERAL1
242 | SARA_R5_ERROR_DEREGISTERED LITERAL1
243 | SARA_R5_ERROR_ERROR LITERAL1
244 | SARA_R5_SUCCESS LITERAL1
245 | SARA_R5_REGISTRATION_INVALID LITERAL1
246 | SARA_R5_REGISTRATION_NOT_REGISTERED LITERAL1
247 | SARA_R5_REGISTRATION_HOME LITERAL1
248 | SARA_R5_REGISTRATION_SEARCHING LITERAL1
249 | SARA_R5_REGISTRATION_DENIED LITERAL1
250 | SARA_R5_REGISTRATION_UNKNOWN LITERAL1
251 | SARA_R5_REGISTRATION_ROAMING LITERAL1
252 | SARA_R5_REGISTRATION_HOME_SMS_ONLY LITERAL1
253 | SARA_R5_REGISTRATION_ROAMING_SMS_ONLY LITERAL1
254 | SARA_R5_REGISTRATION_EMERGENCY_SERV_ONLY LITERAL1
255 | SARA_R5_REGISTRATION_HOME_CSFB_NOT_PREFERRED LITERAL1
256 | SARA_R5_REGISTRATION_ROAMING_CSFB_NOT_PREFERRED LITERAL1
257 | day LITERAL1
258 | month LITERAL1
259 | year LITERAL1
260 | hour LITERAL1
261 | minute LITERAL1
262 | second LITERAL1
263 | ms LITERAL1
264 | tzh LITERAL1
265 | tzm LITERAL1
266 | date LITERAL1
267 | time LITERAL1
268 | utc LITERAL1
269 | lat LITERAL1
270 | lon LITERAL1
271 | alt LITERAL1
272 | mode LITERAL1
273 | status LITERAL1
274 | speed LITERAL1
275 | cog LITERAL1
276 | magVar LITERAL1
277 | stat LITERAL1
278 | shortOp LITERAL1
279 | longOp LITERAL1
280 | numOp LITERAL1
281 | act LITERAL1
282 | SARA_R5_TCP LITERAL1
283 | SARA_R5_UDP LITERAL1
284 | SARA_R5_MESSAGE_FORMAT_PDU LITERAL1
285 | SARA_R5_MESSAGE_FORMAT_TEXT LITERAL1
286 | SARA_R5_UTIME_MODE_STOP LITERAL1
287 | SARA_R5_UTIME_MODE_PPS LITERAL1
288 | SARA_R5_UTIME_MODE_ONE_SHOT LITERAL1
289 | SARA_R5_UTIME_MODE_EXT_INT LITERAL1
290 | SARA_R5_UTIME_SENSOR_NONE LITERAL1
291 | SARA_R5_UTIME_SENSOR_GNSS_LTE LITERAL1
292 | SARA_R5_UTIME_SENSOR_LTE LITERAL1
293 | SARA_R5_UTIME_URC_CONFIGURATION_DISABLED LITERAL1
294 | SARA_R5_UTIME_URC_CONFIGURATION_ENABLED LITERAL1
295 | SARA_R5_SIM_NOT_PRESENT LITERAL1
296 | SARA_R5_SIM_PIN_NEEDED LITERAL1
297 | SARA_R5_SIM_PIN_BLOCKED LITERAL1
298 | SARA_R5_SIM_PUK_BLOCKED LITERAL1
299 | SARA_R5_SIM_NOT_OPERATIONAL LITERAL1
300 | SARA_R5_SIM_RESTRICTED LITERAL1
301 | SARA_R5_SIM_OPERATIONAL LITERAL1
302 | SARA_R5_HTTP_OP_CODE_SERVER_IP LITERAL1
303 | SARA_R5_HTTP_OP_CODE_SERVER_NAME LITERAL1
304 | SARA_R5_HTTP_OP_CODE_USERNAME LITERAL1
305 | SARA_R5_HTTP_OP_CODE_PASSWORD LITERAL1
306 | SARA_R5_HTTP_OP_CODE_AUTHENTICATION LITERAL1
307 | SARA_R5_HTTP_OP_CODE_SERVER_PORT LITERAL1
308 | SARA_R5_HTTP_OP_CODE_SECURE LITERAL1
309 | SARA_R5_HTTP_OP_CODE_REQUEST_TIMEOUT LITERAL1
310 | SARA_R5_HTTP_OP_CODE_ADD_CUSTOM_HEADERS LITERAL1
311 | SARA_R5_HTTP_COMMAND_HEAD LITERAL1
312 | SARA_R5_HTTP_COMMAND_GET LITERAL1
313 | SARA_R5_HTTP_COMMAND_DELETE LITERAL1
314 | SARA_R5_HTTP_COMMAND_PUT LITERAL1
315 | SARA_R5_HTTP_COMMAND_POST_FILE LITERAL1
316 | SARA_R5_HTTP_COMMAND_POST_DATA LITERAL1
317 | SARA_R5_HTTP_COMMAND_GET_FOTA LITERAL1
318 | SARA_R5_HTTP_CONTENT_APPLICATION_X_WWW LITERAL1
319 | SARA_R5_HTTP_CONTENT_TEXT_PLAIN LITERAL1
320 | SARA_R5_HTTP_CONTENT_APPLICATION_OCTET LITERAL1
321 | SARA_R5_HTTP_CONTENT_MULTIPART_FORM LITERAL1
322 | SARA_R5_HTTP_CONTENT_APPLICATION_JSON LITERAL1
323 | SARA_R5_HTTP_CONTENT_APPLICATION_XML LITERAL1
324 | SARA_R5_HTTP_CONTENT_USER_DEFINED LITERAL1
325 | SARA_R5_PSD_CONFIG_PARAM_PROTOCOL LITERAL1
326 | SARA_R5_PSD_CONFIG_PARAM_APN LITERAL1
327 | SARA_R5_PSD_CONFIG_PARAM_DNS1 LITERAL1
328 | SARA_R5_PSD_CONFIG_PARAM_DNS2 LITERAL1
329 | SARA_R5_PSD_CONFIG_PARAM_MAP_TO_CID LITERAL1
330 | SARA_R5_PSD_PROTOCOL_IPV4 LITERAL1
331 | SARA_R5_PSD_PROTOCOL_IPV6 LITERAL1
332 | SARA_R5_PSD_PROTOCOL_IPV4V6_V4_PREF LITERAL1
333 | SARA_R5_PSD_PROTOCOL_IPV4V6_V6_PREF LITERAL1
334 | SARA_R5_PSD_ACTION_RESET LITERAL1
335 | SARA_R5_PSD_ACTION_STORE LITERAL1
336 | SARA_R5_PSD_ACTION_LOAD LITERAL1
337 | SARA_R5_PSD_ACTION_ACTIVATE LITERAL1
338 | SARA_R5_PSD_ACTION_DEACTIVATE LITERAL1
339 | MINIMUM_FUNCTIONALITY LITERAL1
340 | FULL_FUNCTIONALITY LITERAL1
341 | AIRPLANE_MODE LITERAL1
342 | SIM_TOOLKIT_ENABLE_DEDICATED LITERAL1
343 | SIM_TOOLKIT_DISABLE_DEDICATED LITERAL1
344 | SIM_TOOLKIT_ENABLE_RAW LITERAL1
345 | FAST_SAFE_POWER_OFF LITERAL1
346 | SILENT_RESET_WITH_SIM LITERAL1
347 | PDP_TYPE_INVALID LITERAL1
348 | PDP_TYPE_IP LITERAL1
349 | PDP_TYPE_NONIP LITERAL1
350 | PDP_TYPE_IPV4V6 LITERAL1
351 | PDP_TYPE_IPV6 LITERAL1
352 | L2P_DEFAULT LITERAL1
353 | L2P_PPP LITERAL1
354 | L2P_M_HEX LITERAL1
355 | L2P_M_RAW_IP LITERAL1
356 | L2P_M_OPT_PPP LITERAL1
357 | GPIO1 LITERAL1
358 | GPIO2 LITERAL1
359 | GPIO3 LITERAL1
360 | GPIO4 LITERAL1
361 | GPIO5 LITERAL1
362 | GPIO6 LITERAL1
363 | GPIO_MODE_INVALID LITERAL1
364 | GPIO_OUTPUT LITERAL1
365 | GPIO_INPUT LITERAL1
366 | NETWORK_STATUS LITERAL1
367 | GNSS_SUPPLY_ENABLE LITERAL1
368 | GNSS_DATA_READY LITERAL1
369 | GNSS_RTC_SHARING LITERAL1
370 | JAMMING_DETECTION LITERAL1
371 | SIM_CARD_DETECTION LITERAL1
372 | HEADSET_DETECTION LITERAL1
373 | GSM_TX_BURST_INDICATION LITERAL1
374 | MODULE_STATUS_INDICATION LITERAL1
375 | MODULE_OPERATING_MODE_INDICATION LITERAL1
376 | I2S_DIGITAL_AUDIO_INTERFACE LITERAL1
377 | SPI_SERIAL_INTERFACE LITERAL1
378 | MASTER_CLOCK_GENRATION LITERAL1
379 | UART_INTERFACE LITERAL1
380 | WIFI_ENABLE LITERAL1
381 | RING_INDICATION LITERAL1
382 | LAST_GASP_ENABLE LITERAL1
383 | EXTERNAL_GNSS_ANTENNA LITERAL1
384 | TIME_PULSE_GNSS LITERAL1
385 | TIME_PULSE_OUTPUT LITERAL1
386 | TIMESTAMP LITERAL1
387 | FAST_POWER_OFF LITERAL1
388 | LWM2M_PULSE LITERAL1
389 | HARDWARE_FLOW_CONTROL LITERAL1
390 | ANTENNA_TUNING LITERAL1
391 | EXT_GNSS_TIME_PULSE LITERAL1
392 | EXT_GNSS_TIMESTAMP LITERAL1
393 | DTR_MODE LITERAL1
394 | KHZ_32768_OUT LITERAL1
395 | PAD_DISABLED LITERAL1
396 | SARA_R5_TCP_SOCKET_STATUS_INACTIVE LITERAL1
397 | SARA_R5_TCP_SOCKET_STATUS_LISTEN LITERAL1
398 | SARA_R5_TCP_SOCKET_STATUS_SYN_SENT LITERAL1
399 | SARA_R5_TCP_SOCKET_STATUS_SYN_RCVD LITERAL1
400 | SARA_R5_TCP_SOCKET_STATUS_ESTABLISHED LITERAL1
401 | SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_1 LITERAL1
402 | SARA_R5_TCP_SOCKET_STATUS_FIN_WAIT_2 LITERAL1
403 | SARA_R5_TCP_SOCKET_STATUS_CLOSE_WAIT LITERAL1
404 | SARA_R5_TCP_SOCKET_STATUS_CLOSING LITERAL1
405 | SARA_R5_TCP_SOCKET_STATUS_LAST_ACK LITERAL1
406 | SARA_R5_TCP_SOCKET_STATUS_TIME_WAIT LITERAL1
407 | GNSS_SYSTEM_GPS LITERAL1
408 | GNSS_SYSTEM_SBAS LITERAL1
409 | GNSS_SYSTEM_GALILEO LITERAL1
410 | GNSS_SYSTEM_BEIDOU LITERAL1
411 | GNSS_SYSTEM_IMES LITERAL1
412 | GNSS_SYSTEM_QZSS LITERAL1
413 | GNSS_SYSTEM_GLONASS LITERAL1
414 | GNSS_AIDING_MODE_NONE LITERAL1
415 | GNSS_AIDING_MODE_AUTOMATIC LITERAL1
416 | GNSS_AIDING_MODE_ASSISTNOW_OFFLINE LITERAL1
417 | GNSS_AIDING_MODE_ASSISTNOW_ONLINE LITERAL1
418 | GNSS_AIDING_MODE_ASSISTNOW_AUTONOMOUS LITERAL1
419 |
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=SparkFun u-blox SARA-R5 Arduino Library
2 | version=1.1.13
3 | author=SparkFun Electronics
4 | maintainer=SparkFun Electronics
5 | sentence=Library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud
6 | paragraph=An Arduino library for the u-blox SARA-R5 LTE-M / NB-IoT modules with secure cloud, as used on the SparkFun MicroMod Asset Tracker and the SparkFun LTE GNSS Breakout - SARA-R5.
v1.1 has had a thorough update and includes new features and examples. This library now supports up to 7 simultaneous TCP or UDP sockets. There are new examples to show how to play ping pong with both TCP and UDP sockets.
v1.1 also supports binary data transfers correctly. There are new examples showing how you can integrate this library with the SparkFun u-blox GNSS Arduino Library, to use the SARA-R5 to: download AssistNow Online and Offline data and push it to the GNSS; open a connection to a NTRIP Caster (such as RTK2go, Skylark or Emlid Caster) and push RTK correction data to the GNSS.
7 | category=Communication
8 | url=https://github.com/sparkfun/SparkFun_u-blox_SARA-R5_Arduino_Library
9 | architectures=*
10 |
--------------------------------------------------------------------------------