├── .gitattributes ├── .gitignore ├── ARTIC_firmware ├── ARTIC004 │ ├── ARTIC_R2_004_Firmware_Converter.py │ ├── ARTIC_R2_Firmware.h │ ├── ARTIC_R2_Firmware_PMEM.h │ ├── ARTIC_R2_Firmware_XMEM.h │ ├── ARTIC_R2_Firmware_YMEM.h │ └── Firmware_ARTIC004_flash_image.bin └── ARTIC006 │ ├── ARTIC.flash │ ├── ARTIC_R2_006_Firmware_Converter.py │ ├── ARTIC_R2_Firmware.h │ ├── ARTIC_R2_Firmware_PMEM.h │ ├── ARTIC_R2_Firmware_XMEM.h │ └── ARTIC_R2_Firmware_YMEM.h ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.md ├── README.md ├── examples ├── Example10_TransmitARGOS3ZEWithPrediction │ └── Example10_TransmitARGOS3ZEWithPrediction.ino ├── Example11_TransmitARGOS3WithPrediction │ └── Example11_TransmitARGOS3WithPrediction.ino ├── Example12_TransmitARGOS2WithPrediction │ └── Example12_TransmitARGOS2WithPrediction.ino ├── Example13_TransmitARGOS4VLDWithPrediction │ └── Example13_TransmitARGOS4VLDWithPrediction.ino ├── Example14_TransmitARGOS4VLDShortWithPrediction │ └── Example14_TransmitARGOS4VLDShortWithPrediction.ino ├── Example15_TransmitARGOS4VLDLongExample │ └── Example15_TransmitARGOS4VLDLongExample.ino ├── Example16_TransmitARGOS3ZEExample │ └── Example16_TransmitARGOS3ZEExample.ino ├── Example17_TransmitARGOS2Example │ └── Example17_TransmitARGOS2Example.ino ├── Example18_TransmitARGOS3Example │ └── Example18_TransmitARGOS3Example.ino ├── Example1_FirmwareVersion │ └── Example1_FirmwareVersion.ino ├── Example2_FirmwareStatus │ └── Example2_FirmwareStatus.ino ├── Example3_ReadSettings │ └── Example3_ReadSettings.ino ├── Example4_SatelliteDetection │ └── Example4_SatelliteDetection.ino ├── Example5_ReceiveOneMessage │ └── Example5_ReceiveOneMessage.ino ├── Example6_ReceiveOneMessageWithFiltering │ └── Example6_ReceiveOneMessageWithFiltering.ino ├── Example7_ContinuousReceiveWithAOPParsing │ └── Example7_ContinuousReceiveWithAOPParsing.ino ├── Example8_ContinuousReceiveWithAbort │ └── Example8_ContinuousReceiveWithAbort.ino ├── Example9_TestJSONSatellitePassPredictor │ ├── ARTIC_R2_Allcast_Converter.py │ ├── Example9_TestJSONSatellitePassPredictor.ino │ ├── allcast_2021_03_06_13_27_618.h │ └── allcast_2021_03_06_13_27_618.txt ├── Example9_TestSatellitePassPredictor │ └── Example9_TestSatellitePassPredictor.ino └── smol_ARTIC_R2 │ ├── Example1_TransmitARGOS2WithPrediction │ └── Example1_TransmitARGOS2WithPrediction.ino │ ├── Example2_TransmitARGOS3WithPredictionAndSleep │ └── Example2_TransmitARGOS3WithPredictionAndSleep.ino │ ├── Example3_SatelliteDetection │ └── Example3_SatelliteDetection.ino │ └── Example4_TransmitARGOS4VLDLongExample │ └── Example4_TransmitARGOS4VLDLongExample.ino ├── keywords.txt ├── library.properties └── src ├── ARTIC_R2_Firmware.h ├── ARTIC_R2_Firmware_PMEM.h ├── ARTIC_R2_Firmware_XMEM.h ├── ARTIC_R2_Firmware_YMEM.h ├── SparkFun_ARGOS_ARTIC_R2_Arduino_Library.cpp └── SparkFun_ARGOS_ARTIC_R2_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 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /ARTIC_firmware/ARTIC004/ARTIC_R2_004_Firmware_Converter.py: -------------------------------------------------------------------------------- 1 | # This code converts the ARTIC R2 ARTIC004 firmware from "flash_image.bin" format 2 | # into header files containing arrays of const uint32_t. 3 | # The arrays can then be downloaded to the ARTIC R2. 4 | # The array LENgths come from the ARTIC R2 datasheet. 5 | # The array CHECKSUMs come from the ARTIC itself as I don't have the Release_README.txt for ARTIC004. 6 | 7 | # Written by Paul Clark, October 1st 2020 8 | 9 | # License: please see the license file at: 10 | # https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 11 | 12 | 13 | with open("Firmware_ARTIC004_flash_image.bin", "r") as reader: 14 | line = reader.readline() 15 | #print (line) 16 | if (line[0:4] != '0xd1'): 17 | raise ValueError("First byte was not 0xd1!") 18 | line = reader.readline() 19 | line = reader.readline() 20 | #print (line) 21 | if (line[0:4] != '0x20'): 22 | raise ValueError("Second byte was not 0x20!") 23 | with open("ARTIC_R2_Firmware_PMEM.h", "w") as PMEM: 24 | PMEM.write("// ARTIC R2 ARTIC004 Firmware PMEM\n") 25 | PMEM.write("// Converted from Firmware_ARTIC004_flash_image.bin\n") 26 | for x in range(10240): 27 | PMEM.write("\t0x") 28 | line = reader.readline() 29 | line = reader.readline() 30 | PMEM.write(line[2:4]) 31 | line = reader.readline() 32 | line = reader.readline() 33 | PMEM.write(line[2:4]) 34 | line = reader.readline() 35 | line = reader.readline() 36 | PMEM.write(line[2:4]) 37 | line = reader.readline() 38 | line = reader.readline() 39 | PMEM.write(line[2:4]) 40 | if (x < 10239): 41 | PMEM.write(",") 42 | PMEM.write("\n") 43 | with open("ARTIC_R2_Firmware_XMEM.h", "w") as XMEM: 44 | XMEM.write("// ARTIC R2 ARTIC004 Firmware XMEM\n") 45 | XMEM.write("// Converted from Firmware_ARTIC004_flash_image.bin\n") 46 | for x in range(21845): 47 | XMEM.write("\t0x") 48 | line = reader.readline() 49 | line = reader.readline() 50 | XMEM.write(line[2:4]) 51 | line = reader.readline() 52 | line = reader.readline() 53 | XMEM.write(line[2:4]) 54 | line = reader.readline() 55 | line = reader.readline() 56 | XMEM.write(line[2:4]) 57 | if (x < 21844): 58 | XMEM.write(",") 59 | XMEM.write("\n") 60 | with open("ARTIC_R2_Firmware_YMEM.h", "w") as YMEM: 61 | YMEM.write("// ARTIC R2 ARTIC004 Firmware YMEM\n") 62 | YMEM.write("// Converted from Firmware_ARTIC004_flash_image.bin\n") 63 | for x in range(6826): 64 | YMEM.write("\t0x") 65 | line = reader.readline() 66 | line = reader.readline() 67 | YMEM.write(line[2:4]) 68 | line = reader.readline() 69 | line = reader.readline() 70 | YMEM.write(line[2:4]) 71 | line = reader.readline() 72 | line = reader.readline() 73 | YMEM.write(line[2:4]) 74 | if (x < 6825): 75 | YMEM.write(",") 76 | YMEM.write("\n") 77 | -------------------------------------------------------------------------------- /ARTIC_firmware/ARTIC004/ARTIC_R2_Firmware.h: -------------------------------------------------------------------------------- 1 | // These are the firmware parameter memory locations for the ARTIC004 firmware 2 | // They are defined in the ARTIC Datasheet and Arribada Horizon 3 | // The locations for ARTIC006 are very different! 4 | 5 | #ifndef ARTIC_R2_MEM_LOC_H 6 | #define ARTIC_R2_MEM_LOC_H 7 | 8 | const uint8_t ARTIC_R2_FIRMWARE_VERSION = 4; // Make it clear that we are using ARTIC004 9 | 10 | const uint32_t ARTIC_R2_PMEM_LEN = 10240; // PMEM Length in 32-Bit Words 11 | const uint32_t ARTIC_R2_XMEM_LEN = 21845; // XMEM Length in 24-Bit Words 12 | const uint32_t ARTIC_R2_YMEM_LEN = 6826; // YMEM Length in 24-Bit Words 13 | 14 | const uint32_t ARTIC_R2_PMEM_CHECKSUM = 0x493982; // ARTIC004 15 | const uint32_t ARTIC_R2_XMEM_CHECKSUM = 0x32DBBA; // ARTIC004 16 | const uint32_t ARTIC_R2_YMEM_CHECKSUM = 0x65CC81; // ARTIC004 17 | 18 | // P Memory Locations 19 | const uint16_t MEM_LOC_FIRMWARE_VERSION = 0x0010; // 2 * 32-bit words = 8 bytes: 'ARTICnnn' 20 | 21 | // X Memory locations 22 | const uint16_t MEM_LOC_ARGOS_CONFIGURATION = 0x0384; // Size 1. Read only 23 | const uint16_t MEM_LOC_RX_PAYLOAD = 0x0200; // Size 9. Read only 24 | const uint16_t MEM_LOC_RX_FILTERING_CONFIGURATION = 0x0209; // Size 104. Read/Write (Was 0x120D in ARTIC006) 25 | const uint16_t MEM_LOC_RX_FILTERING_ENABLE_CRC = 0x0209; // Size 1. Read/Write 26 | const uint16_t MEM_LOC_RX_FILTERING_TRANSPARENT_MODE = 0x020A; // Size 1. Read/Write 27 | const uint16_t MEM_LOC_RX_FILTERING_LUT_LENGTH = 0x020B; // Size 1. Read/Write 28 | const uint16_t MEM_LOC_RX_FILTERING_LUT_FIRST_ADDRESS = 0x020C; // Read/Write 29 | const uint16_t MEM_LOC_RX_TIMEOUT = 0x0271; // Size 1. Read/Write 30 | const uint16_t MEM_LOC_SATELLITE_DETECTION_TIMEOUT = 0x0272; // Size 1. Read/Write 31 | const uint16_t MEM_LOC_TX_PAYLOAD = 0x0273; // Size 220. Write only 32 | const uint16_t MEM_LOC_TX_FREQ_ARGOS_2_3 = 0x034F; // Size 1. Read/Write 33 | const uint16_t MEM_LOC_TX_FREQ_ARGOS_4 = 0x035F; // Size 1. Read/Write 34 | const uint16_t MEM_LOC_TCXO_WARMUP_TIME = 0x036F; // Sizde 1. Read/Write 35 | const uint16_t MEM_LOC_TCXO_CONTROL = 0x0370; // Size 1. Read/Write 36 | const uint16_t MEM_LOC_CRC_RESULTS = 0x0371; // Size 3. Read only 37 | const uint16_t MEM_LOC_TX_CERTIFICATION_INTERVAL = 0x0379; // Size 1. Read/Write 38 | 39 | // IO Memory locations 40 | const uint16_t MEM_LOC_FIRMWARE_STATUS_REGISTER = 0x8018; 41 | 42 | // Include the firmware for SPI upload - if desired 43 | #ifdef ARTIC_R2_UPLOAD_FIRMWARE 44 | 45 | // Include firmware binary data 46 | // P 32-bit 10240 DSP Program memory 47 | const uint32_t ARTIC_R2_PMEM[ARTIC_R2_PMEM_LEN] = { 48 | #include "ARTIC_R2_Firmware_PMEM.h" 49 | }; 50 | 51 | // X 24-bit 21845 DSP X memory 52 | const uint32_t ARTIC_R2_XMEM[ARTIC_R2_XMEM_LEN] = { 53 | #include "ARTIC_R2_Firmware_XMEM.h" 54 | }; 55 | 56 | // Y 24-bit 6826 DSP Y memory 57 | const uint32_t ARTIC_R2_YMEM[ARTIC_R2_YMEM_LEN] = { 58 | #include "ARTIC_R2_Firmware_YMEM.h" 59 | }; 60 | 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /ARTIC_firmware/ARTIC006/ARTIC_R2_006_Firmware_Converter.py: -------------------------------------------------------------------------------- 1 | # This code converts the ARTIC R2 ARTIC006 firmware from "flash" format 2 | # into header files containing arrays of const uint32_t. 3 | # The arrays can then be downloaded to the ARTIC R2. 4 | # The array LENgths come from the ARTIC R2 datasheet. 5 | # The array CHECKSUMs come from the ARTIC006 Release_README.txt. 6 | 7 | # Written by Paul Clark, October 1st 2020 8 | 9 | # License: please see the license file at: 10 | # https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 11 | 12 | 13 | with open("ARTIC.flash", "r") as reader: 14 | line = reader.readline() 15 | #print (line) 16 | if (line[0:2] != 'D1'): 17 | raise ValueError("First byte was not 0xD1!") 18 | line = reader.readline() 19 | #print (line) 20 | if (line[0:2] != '20'): 21 | raise ValueError("Second byte was not 0x20!") 22 | with open("ARTIC_R2_Firmware_PMEM.h", "w") as PMEM: 23 | PMEM.write("// ARTIC R2 ARTIC006 Firmware PMEM\n") 24 | PMEM.write("// Converted from ARTIC.flash\n") 25 | for x in range(10240): 26 | PMEM.write("\t0x") 27 | line = reader.readline() 28 | PMEM.write(line[0:2]) 29 | line = reader.readline() 30 | PMEM.write(line[0:2]) 31 | line = reader.readline() 32 | PMEM.write(line[0:2]) 33 | line = reader.readline() 34 | PMEM.write(line[0:2]) 35 | if (x < 10239): 36 | PMEM.write(",") 37 | PMEM.write("\n") 38 | with open("ARTIC_R2_Firmware_XMEM.h", "w") as XMEM: 39 | XMEM.write("// ARTIC R2 ARTIC006 Firmware XMEM\n") 40 | XMEM.write("// Converted from ARTIC.flash\n") 41 | for x in range(21845): 42 | XMEM.write("\t0x") 43 | line = reader.readline() 44 | XMEM.write(line[0:2]) 45 | line = reader.readline() 46 | XMEM.write(line[0:2]) 47 | line = reader.readline() 48 | XMEM.write(line[0:2]) 49 | if (x < 21844): 50 | XMEM.write(",") 51 | XMEM.write("\n") 52 | with open("ARTIC_R2_Firmware_YMEM.h", "w") as YMEM: 53 | YMEM.write("// ARTIC R2 ARTIC006 Firmware YMEM\n") 54 | YMEM.write("// Converted from ARTIC.flash\n") 55 | for x in range(6826): 56 | YMEM.write("\t0x") 57 | line = reader.readline() 58 | YMEM.write(line[0:2]) 59 | line = reader.readline() 60 | YMEM.write(line[0:2]) 61 | line = reader.readline() 62 | YMEM.write(line[0:2]) 63 | if (x < 6825): 64 | YMEM.write(",") 65 | YMEM.write("\n") 66 | -------------------------------------------------------------------------------- /ARTIC_firmware/ARTIC006/ARTIC_R2_Firmware.h: -------------------------------------------------------------------------------- 1 | // These are the firmware parameter memory locations for the ARTIC006 firmware 2 | // They are defined in the Release_README.txt for ARTIC006 3 | // The locations for ARTIC004 are very different! 4 | 5 | #ifndef ARTIC_R2_MEM_LOC_H 6 | #define ARTIC_R2_MEM_LOC_H 7 | 8 | const uint8_t ARTIC_R2_FIRMWARE_VERSION = 6; // Make it clear that we are using ARTIC006 9 | 10 | const uint32_t ARTIC_R2_PMEM_LEN = 10240; // PMEM Length in 32-Bit Words 11 | const uint32_t ARTIC_R2_XMEM_LEN = 21845; // XMEM Length in 24-Bit Words 12 | const uint32_t ARTIC_R2_YMEM_LEN = 6826; // YMEM Length in 24-Bit Words 13 | 14 | const uint32_t ARTIC_R2_PMEM_CHECKSUM = 0x4DC69E; // ARTIC006 15 | const uint32_t ARTIC_R2_XMEM_CHECKSUM = 0x4A51F6; // ARTIC006 16 | const uint32_t ARTIC_R2_YMEM_CHECKSUM = 0x65CC81; // ARTIC006 17 | 18 | // P Memory Locations 19 | const uint16_t MEM_LOC_FIRMWARE_VERSION = 0x0010; // 2 * 32-bit words = 8 bytes: 'ARTICnnn' 20 | 21 | // X Memory locations 22 | const uint16_t MEM_LOC_ARGOS_CONFIGURATION = 0x137E; // Size 1. Read only (Was 0x0384 in ARTIC004) 23 | const uint16_t MEM_LOC_RX_PAYLOAD = 0x1204; // Size 9. Read only (Was 0x0200 in ARTIC004) 24 | const uint16_t MEM_LOC_RX_FILTERING_CONFIGURATION = 0x120D; // Size 104. Read/Write (Was 0x0209 in ARTIC004) 25 | const uint16_t MEM_LOC_RX_FILTERING_ENABLE_CRC = 0x120D; // Size 1. Read/Write 26 | const uint16_t MEM_LOC_RX_FILTERING_TRANSPARENT_MODE = 0x120E; // Size 1. Read/Write 27 | const uint16_t MEM_LOC_RX_FILTERING_LUT_LENGTH = 0x120F; // Size 1. Read/Write 28 | const uint16_t MEM_LOC_RX_FILTERING_LUT_FIRST_ADDRESS = 0x1210; // Read/Write 29 | const uint16_t MEM_LOC_RX_TIMEOUT = 0x1275; // Size 1. Read/Write (Was 0x0271 in ARTIC004) 30 | const uint16_t MEM_LOC_SATELLITE_DETECTION_TIMEOUT = 0x1276; // Size 1. Read/Write (Was 0x0272 in ARTIC004) 31 | const uint16_t MEM_LOC_TX_PAYLOAD = 0x1277; // Size 220. Write only. (Was 0x0273 in ARTIC004) 32 | const uint16_t MEM_LOC_TX_FREQ_ARGOS_2_3 = 0x1353; // Size 1. Read/Write (Was 0x034F in ARTIC004) 33 | const uint16_t MEM_LOC_TX_FREQ_ARGOS_4 = 0x1363; // Size 1. Read/Write (Was 0x035F in ARTIC004) 34 | const uint16_t MEM_LOC_TCXO_WARMUP_TIME = 0x1373; // Sizde 1. Read/Write (Was 0x036F in ARTIC004) 35 | const uint16_t MEM_LOC_TCXO_CONTROL = 0x1374; // Size 1. Read/Write (Was 0x0370 in ARTIC004) 36 | const uint16_t MEM_LOC_CRC_RESULTS = 0x1375; // Size 3. Read only. (Was 0x0371 in ARTIC004) 37 | const uint16_t MEM_LOC_TX_CERTIFICATION_INTERVAL = 0x137D; // Size 1. Read/Write (Was 0x0379 in ARTIC004) 38 | const uint16_t MEM_LOC_FLASH_PROG_BUFFER = 0x137F; // Flash Programming Buffer (New in ARTIC006) 39 | 40 | // IO Memory locations 41 | const uint16_t MEM_LOC_FIRMWARE_STATUS_REGISTER = 0x8018; 42 | 43 | // Include the firmware for SPI upload - if desired 44 | #ifdef ARTIC_R2_UPLOAD_FIRMWARE 45 | 46 | // Include firmware binary data 47 | // P 32-bit 10240 DSP Program memory 48 | const uint32_t ARTIC_R2_PMEM[ARTIC_R2_PMEM_LEN] = { 49 | #include "ARTIC_R2_Firmware_PMEM.h" 50 | }; 51 | 52 | // X 24-bit 21845 DSP X memory 53 | const uint32_t ARTIC_R2_XMEM[ARTIC_R2_XMEM_LEN] = { 54 | #include "ARTIC_R2_Firmware_XMEM.h" 55 | }; 56 | 57 | // Y 24-bit 6826 DSP Y memory 58 | const uint32_t ARTIC_R2_YMEM[ARTIC_R2_YMEM_LEN] = { 59 | #include "ARTIC_R2_Firmware_YMEM.h" 60 | }; 61 | 62 | #endif 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /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_ARGOS_ARTIC_R2_Arduino_Library/issues) and [pull requests](https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/pulls) to see whether someone else has raised a similar idea or question. 6 | 7 | If you decide to add a feature to this library, please create a PR following these best practices: 8 | 9 | - Change as little as possible. Do not sumbit a PR that changes 100 lines of whitespace. Break up into multiple PRs if necessary. 10 | - 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. 11 | - 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). 12 | - Please submit your PR using the [release_candidate branch](https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/tree/release_candidate). That way, we can merge and test your PR quickly without changing the _master_ branch 13 | 14 | ## Style guide 15 | 16 | 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). 17 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Subject of the issue 2 | Describe your issue here. 3 | 4 | ### Your workbench 5 | * What development board or microcontroller are you using? 6 | * What version of hardware or breakout board are you using? 7 | * How is the breakout board connected to your microcontroller? 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. 13 | 14 | ### Expected behavior 15 | Tell us what should happen 16 | 17 | ### Actual behavior 18 | Tell us what happens instead 19 | -------------------------------------------------------------------------------- /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 ARGOS ARTIC R2 Arduino Library 2 | =========================================================== 3 | 4 | [![ARGOS ARTIC R2 Shield](https://cdn.sparkfun.com//assets/parts/1/6/2/1/7/17236-Artic_R2_Breakout-01a.jpg)](https://www.sparkfun.com/products/17236) 5 | 6 | [*ARGOS ARTIC R2 Shield*](https://www.sparkfun.com/products/17236) 7 | 8 | The ARTIC R2 chipset allows you to send and receive short data messages to and from anywhere via the ARGOS satellite network. Dedicated to programs which are related to environmental protection, 9 | awareness or study, or to protecting human life, the ARGOS constellation provides full global coverage including the polar regions. 10 | 11 | The ARTIC is an integrated low power small size ARGOS 2/3/4 single chip radio. ARTIC implements a message based wireless interface. For satellite uplink communication, ARTIC will encode, modulate and transmit 12 | provided user messages. For downlink communication, ARTIC will lock to the downstream, demodulate and decode and extract the satellite messages. 13 | 14 | The ARTIC can transmit signals in frequency bands around 400MHz and receive signals in the bands around 466MHz, in accordance with the ARGOS satellite system specifications. 15 | 16 | The ARTIC is compliant and certified for all ARGOS 2 and ARGOS 3 TX standards. It contains a RF transceiver, a frequency synthesiser and a digital baseband modem. 17 | 18 | This library provides access to the ARTIC via its SPI interface. Full support is provided for both standard mode and burst mode communication. 19 | 20 | Library written by Paul Clark ([SparkFun](http://www.sparkfun.com)). 21 | 22 | Repository Contents 23 | ------------------- 24 | 25 | * [**/examples**](./examples) - Example sketches for the library (.ino). Run these from the Arduino IDE. 26 | * [**/src**](./src) - Source files for the library (.cpp, .h). 27 | * [**keywords.txt**](./keywords.txt) - Keywords from this library that will be highlighted in the Arduino IDE. 28 | * [**library.properties**](./library.properties) - General library properties for the Arduino package manager. 29 | * [**CONTRIBUTING.md**](./CONTRIBUTING.md) - Guidance on how to contribute to this library. 30 | 31 | Documentation 32 | -------------- 33 | 34 | * **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library. 35 | * **[ARGOS ARTIC R2 Shield Product Repository](https://github.com/sparkfunX/ARGOS-ARTIC-R2-Shield)** - Main repository (including hardware files) 36 | * **[IOTA Product Repository](https://github.com/sparkfunX/IOTA-ARTIC-R2-Module)** 37 | * **[smôl ARTIC R2 Product Repository](https://github.com/sparkfunX/SparkX_smol_ARTIC_R2)** 38 | 39 | v1.1 40 | ------------------- 41 | 42 | From v1.1.0 of the library: 43 | 44 | We were instructed by Kineis to ensure that the Platform ID was written directly into each module 45 | and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 46 | ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. When you buy a board from SparkFun, 47 | it will come with a card showing what the Platform ID for that board is. You will need to contact CLS or 48 | Woods Hole Group to have the Platform ID added to your account. 49 | 50 | The library functions have been modified so that the Platform ID is read from PMEM instead of being a passed as an argument. 51 | The library examples and functions read the Platform ID from the ARTIC R2 memory using ```readPlatformID```. 52 | Early boards will return a value of zero, later boards will return an ID starting with (e.g.) 0x3368. 53 | If the example stalls because the Platform ID is zero, you can: 54 | - use the Arduino IDE Library Manager to install v1.0.9 of the library (which does allow the Platform ID to be passed as an argument) 55 | - manually download and install the library using [this link to the v1.0.9 zip file](https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/archive/refs/tags/v1.0.9.zip) 56 | or [this link to the v1.0.9 tar.gz file](https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/archive/refs/tags/v1.0.9.tar.gz) 57 | 58 | Booting 59 | ------------------- 60 | 61 | The ARTIC R2 can either boot from on-board flash memory, or the firmware can be downloaded by the MCU via SPI. 62 | This library supports both methods but defaults to booting from on-board flash. 63 | 64 | If you want to change this, you will need to edit [the library header file](https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/blob/master/src/SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h#L44) 65 | and uncomment the line which says ```#define ARTIC_R2_UPLOAD_FIRMWARE```. From then on the ARTIC R2 will be booted via SPI instead. 66 | 67 | **Note: the ARTIC006 firmware occupies 127KBytes of program memory. You will need an MCU with adequate memory if you choose to boot via SPI.** 68 | 69 | License Information 70 | ------------------- 71 | 72 | This product is _**open source**_! 73 | 74 | Please review the LICENSE.md file for license information. 75 | 76 | If you have any questions or concerns on licensing, please contact techsupport@sparkfun.com. 77 | 78 | Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release any derivative under the same license. 79 | 80 | Distributed as-is; no warranty is given. 81 | 82 | - Your friends at SparkFun. 83 | -------------------------------------------------------------------------------- /examples/Example15_TransmitARGOS4VLDLongExample/Example15_TransmitARGOS4VLDLongExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the TCXO voltage; 12 | sets the TCXO warmup time; 13 | sets the satellite detection timeout to 60 seconds; 14 | sets the TX mode to ARGOS A4 VLD; 15 | sets the TX frequency; 16 | instructs the ARTIC to Transmit One Package And Go Idle; 17 | keeps checking the MCU status until transmit is complete; 18 | repeats. 19 | 20 | The transmit power can be reduced by 8dB by uncommenting the line: myARTIC.attenuateTXgain(true); 21 | 22 | The messages are ARGOS 4 VLD (Long) and contain the example used in A4-SS-TER-SP-0079-CNES. 23 | 24 | License: please see the license file at: 25 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 26 | 27 | Feel like supporting our work? Buy a board from SparkFun! 28 | https://www.sparkfun.com/products/17236 29 | 30 | Hardware Connections: 31 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 32 | https://www.sparkfun.com/products/15574 33 | CS_Pin = A5 (D24) 34 | GAIN8_Pin = D3 35 | BOOT_Pin = D4 36 | INT1_Pin = D5 37 | INT2_Pin = D6 38 | RESET_Pin = D7 39 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 40 | RF_PWR_EN_Pin = D9 41 | (SPI COPI = D11) 42 | (SPI CIPO = D12) 43 | (SPI SCK = D13) 44 | 45 | If you are using IOTA, uncomment the #define IOTA below. 46 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 47 | 48 | */ 49 | 50 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 51 | 52 | // From v1.1.0 of the library, the platform ID is stored in PMEM and, for this example, should be 0x01234567 53 | 54 | const unsigned long repetitionPeriod = 50000; // Define the repetition period in milliseconds 55 | 56 | const uint32_t tcxoWarmupTime = 10; // Define the TCXO warmup time 57 | 58 | #include 59 | 60 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 61 | ARTIC_R2 myARTIC; 62 | 63 | // Pin assignments for the SparkFun Thing Plus - Artemis 64 | // (Change these if required) 65 | int CS_Pin = 24; 66 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 67 | int BOOT_Pin = 4; 68 | int INT1_Pin = 5; 69 | int INT2_Pin = 6; 70 | int RESET_Pin = 7; 71 | #ifdef IOTA 72 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 73 | #else 74 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 75 | int RF_PWR_EN_Pin = 9; 76 | #endif 77 | 78 | // Loop Steps - these are used by the switch/case in the main loop 79 | // This structure makes it easy to jump between any of the steps 80 | enum { 81 | configure_ARTIC, // Configure the ARTIC (set the satellite detection timeout and TX mode) 82 | ARTIC_TX, // Start the ARTIC TX 83 | wait_for_ARTIC_TX, // Wait for the ARTIC to transmit 84 | } loop_steps; 85 | int loop_step = configure_ARTIC; // Make sure loop_step is set to configure_ARTIC 86 | 87 | // A4-SS-TER-SP-0079-CNES specifies a ±10% 'jitter' on the repetition period to reduce the risk of transmission collisions 88 | unsigned long nextTransmitTime; // Time of the next satellite transmission (before jitter is added) 89 | unsigned long nextTransmitTimeActual; // Actual time of the next satellite transmission (including jitter) 90 | 91 | void setup() 92 | { 93 | Serial.begin(115200); 94 | Serial.println(); 95 | Serial.println(F("ARGOS ARTIC R2 Example")); 96 | Serial.println(); 97 | 98 | SPI.begin(); 99 | 100 | // Uncomment the next line to enable the helpful debug messages 101 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 102 | 103 | Serial.println(F("Starting the ARTIC R2...")); 104 | Serial.println(); 105 | 106 | // Begin the ARTIC: enable power and upload firmware or boot from flash 107 | #ifdef IOTA 108 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 109 | #else 110 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 111 | #endif 112 | { 113 | Serial.println("ARTIC R2 not detected. Freezing..."); 114 | while (1) 115 | ; // Do nothing more 116 | } 117 | 118 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 119 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 120 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 121 | // earlier versions of the board will need to use version 1.0.9 of the library. 122 | uint32_t platformID = myARTIC.readPlatformID(); 123 | if (platformID == 0) 124 | { 125 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 126 | Serial.println(F("Please use the Library Manager to select version 1.0.9 of this library.")); 127 | Serial.println(F("Freezing...")); 128 | while (1) 129 | ; // Do nothing more 130 | } 131 | else 132 | { 133 | Serial.print(F("Your Platform ID is: 0x")); 134 | Serial.println(platformID, HEX); 135 | } 136 | 137 | // Define the time of the first transmit 138 | nextTransmitTime = repetitionPeriod; 139 | nextTransmitTimeActual = nextTransmitTime - tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 140 | } 141 | 142 | void loop() 143 | { 144 | // loop is one large switch/case that controls the sequencing of the code 145 | switch (loop_step) { 146 | 147 | // ************************************************************************************************ 148 | // Configure the ARTIC 149 | case configure_ARTIC: 150 | { 151 | // Set the TCXO voltage to 1.8V and autoDisable to 1 152 | if (myARTIC.setTCXOControl(1.8, true) == false) 153 | { 154 | Serial.println("setTCXOControl failed. Freezing..."); 155 | while (1) 156 | ; // Do nothing more 157 | } 158 | 159 | // Set the TCXO warm-up time 160 | if (myARTIC.setTCXOWarmupTime(tcxoWarmupTime) == false) 161 | { 162 | Serial.println("setTCXOWarmupTime failed. Freezing..."); 163 | while (1) 164 | ; // Do nothing more 165 | } 166 | 167 | // Set the satellite detection timeout to 60 seconds 168 | if (myARTIC.setSatelliteDetectionTimeout(60) == false) 169 | { 170 | Serial.println("setSatelliteDetectionTimeout failed. Freezing..."); 171 | while (1) 172 | ; // Do nothing more 173 | } 174 | 175 | // Set the TX mode to ARGOS 4 VLD 176 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_ARGOS_4_PTT_VLD_TX_MODE); 177 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 178 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 179 | { 180 | Serial.println("sendConfigurationCommand failed. Freezing..."); 181 | while (1) 182 | ; // Do nothing more 183 | } 184 | 185 | // Read and print the ARGOS configuration 186 | ARGOS_Configuration_Register configuration; 187 | myARTIC.readARGOSconfiguration(&configuration); 188 | myARTIC.printARGOSconfiguration(configuration); 189 | 190 | // Set the ARGOS 4 TX frequency to 401.630 MHz 191 | // From A4-SS-TER-SP-0079-CNES: 192 | // The transmission frequency for PTT-VLD-A4 platforms shall be set between 399.91 MHz to 401.68 MHz. 193 | // Due to frequency regulations, the frequency ranges [400.05 MHz to 401.0 MHz] and [401.2 MHz to 401.3 MHz] are forbidden for VLD-A4 transmissions. 194 | if (myARTIC.setARGOS4TxFrequency(401.630) == false) 195 | { 196 | Serial.println("setARGOS4TxFrequency failed. Freezing..."); 197 | while (1) 198 | ; // Do nothing more 199 | } 200 | 201 | // Print the TX frequency 202 | float tx4freq = myARTIC.getARGOS4TxFrequency(); 203 | Serial.print(F("The ARGOS 4 TX Frequency is ")); 204 | Serial.print(tx4freq, 3); 205 | Serial.println(F(" MHz.")); 206 | 207 | // Uncomment the next line if you want to attenuate the transmit power by 8dB 208 | //myARTIC.attenuateTXgain(true); 209 | 210 | loop_step = ARTIC_TX; // Move on 211 | } 212 | break; 213 | 214 | // ************************************************************************************************ 215 | // Start the ARTIC in Transmit One Package And Go Idle mode 216 | case ARTIC_TX: 217 | { 218 | // Configure the Tx payload for ARGOS 4 VLD (A4-SS-TER-SP-0079-CNES) 219 | // If the Platform ID has also been set to 0x01234567, the complete over-air data stream, including sync pattern and length, should be: 220 | // 0xAC5353DC651CECA2F6E328E76517B719473B28BD followed by 0b1 221 | if (myARTIC.setPayloadARGOS4VLDLong(0x01234567, 0x01234567) == false) 222 | { 223 | Serial.println(F("setPayloadARGOS4VLDLatLon failed!")); 224 | Serial.println(); 225 | // Read the payload back again and print it 226 | myARTIC.readTxPayload(); 227 | myARTIC.printTxPayload(); 228 | Serial.println(); 229 | Serial.println(F("Freezing...")); 230 | while (1) 231 | ; // Do nothing more 232 | } 233 | 234 | /* 235 | // Read the payload back again and print it 236 | myARTIC.readTxPayload(); 237 | myARTIC.printTxPayload(); 238 | Serial.println(); 239 | */ 240 | 241 | // Wait for the next repetition period 242 | while (nextTransmitTimeActual > millis()) 243 | { 244 | if ((millis() % 1000) < 50) // Print how long it is until the next transmit 245 | { 246 | Serial.print(F("The next transmit will take place in ")); 247 | unsigned long remaining = (nextTransmitTimeActual - millis()) / 1000; 248 | Serial.print(remaining); 249 | Serial.println(F(" seconds")); 250 | } 251 | delay(50); 252 | } 253 | nextTransmitTime += repetitionPeriod; 254 | nextTransmitTimeActual = nextTransmitTime + random((-0.1 * repetitionPeriod), (0.1 * repetitionPeriod)); 255 | nextTransmitTimeActual -= tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 256 | 257 | // Tell the ARTIC to do its thing! 258 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE); 259 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 260 | { 261 | Serial.println("sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE) failed!"); 262 | Serial.println(); 263 | ARTIC_R2_Firmware_Status status; 264 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 265 | Serial.println(F("ARTIC R2 Firmware Status:")); 266 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 267 | Serial.println(); 268 | Serial.println(F("ARTIC_R2_MCU_Command_Result:")); 269 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 270 | Serial.println(); 271 | Serial.println("Freezing..."); 272 | while (1) 273 | ; // Do nothing more 274 | } 275 | 276 | loop_step = wait_for_ARTIC_TX; // Move on 277 | } 278 | break; 279 | 280 | // ************************************************************************************************ 281 | // Start the ARTIC in Transmit One Package And Go Idle mode 282 | case wait_for_ARTIC_TX: 283 | { 284 | delay(1000); // Check the status every second 285 | 286 | // Read and print the ARTIC R2 status register 287 | ARTIC_R2_Firmware_Status status; 288 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 289 | Serial.println(F("ARTIC R2 Firmware Status:")); 290 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 291 | 292 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when TX is finished 293 | { 294 | Serial.println(F("INT1 pin is high. TX is finished (or MCU is in IDLE_STATE)!")); 295 | } 296 | 297 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT2) // Check the interrupt 2 flag. This will go high when if the message was invalid 298 | { 299 | Serial.println(F("INT2 pin is high. TX message was invalid! (Something really bad must have happened...)")); 300 | } 301 | 302 | Serial.println(); 303 | 304 | // Read and print the instruction progress 305 | ARTIC_R2_MCU_Instruction_Progress progress; 306 | // checkMCUinstructionProgress will return true if the instruction is complete 307 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 308 | Serial.println(F("ARTIC R2 instruction progress:")); 309 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 310 | 311 | Serial.println(); 312 | 313 | if (instructionComplete) 314 | { 315 | Serial.println(F("Transmission is complete!")); 316 | Serial.println(); 317 | 318 | Serial.println(F("Clearing INT1.")); 319 | Serial.println(); 320 | 321 | // Clear INT1 322 | if (myARTIC.clearInterrupts(1) == false) 323 | { 324 | Serial.println("clearInterrupts failed! Freezing..."); 325 | while (1) 326 | ; // Do nothing more 327 | } 328 | 329 | loop_step = ARTIC_TX; // Do over... 330 | } 331 | } 332 | break; 333 | } 334 | } 335 | -------------------------------------------------------------------------------- /examples/Example16_TransmitARGOS3ZEExample/Example16_TransmitARGOS3ZEExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the TCXO voltage; 12 | sets the TCXO warmup time; 13 | sets the satellite detection timeout to 60 seconds; 14 | sets the TX mode to ARGOS A3 ZE; 15 | sets the TX frequency; 16 | instructs the ARTIC to Transmit One Package And Go Idle; 17 | keeps checking the MCU status until transmit is complete; 18 | repeats. 19 | 20 | The messages are ARGOS 3 ZE and contain the example used in AS3-SP-516-274-CNES. 21 | 22 | License: please see the license file at: 23 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 24 | 25 | Feel like supporting our work? Buy a board from SparkFun! 26 | https://www.sparkfun.com/products/17236 27 | 28 | Hardware Connections: 29 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 30 | https://www.sparkfun.com/products/15574 31 | CS_Pin = A5 (D24) 32 | GAIN8_Pin = D3 33 | BOOT_Pin = D4 34 | INT1_Pin = D5 35 | INT2_Pin = D6 36 | RESET_Pin = D7 37 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 38 | RF_PWR_EN_Pin = D9 39 | (SPI COPI = D11) 40 | (SPI CIPO = D12) 41 | (SPI SCK = D13) 42 | 43 | If you are using IOTA, uncomment the #define IOTA below. 44 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 45 | 46 | */ 47 | 48 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 49 | 50 | // From v1.1.0 of the library, the platform ID is stored in PMEM and, for this example, should be 0x01234567 51 | 52 | const unsigned long repetitionPeriod = 50000; // Define the repetition period in milliseconds 53 | 54 | const uint32_t tcxoWarmupTime = 10; // Define the TCXO warmup time 55 | 56 | #include 57 | 58 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 59 | ARTIC_R2 myARTIC; 60 | 61 | // Pin assignments for the SparkFun Thing Plus - Artemis 62 | // (Change these if required) 63 | int CS_Pin = 24; 64 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 65 | int BOOT_Pin = 4; 66 | int INT1_Pin = 5; 67 | int INT2_Pin = 6; 68 | int RESET_Pin = 7; 69 | #ifdef IOTA 70 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 71 | #else 72 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 73 | int RF_PWR_EN_Pin = 9; 74 | #endif 75 | 76 | // Loop Steps - these are used by the switch/case in the main loop 77 | // This structure makes it easy to jump between any of the steps 78 | enum { 79 | configure_ARTIC, // Configure the ARTIC (set the satellite detection timeout and TX mode) 80 | ARTIC_TX, // Start the ARTIC TX 81 | wait_for_ARTIC_TX, // Wait for the ARTIC to transmit 82 | } loop_steps; 83 | int loop_step = configure_ARTIC; // Make sure loop_step is set to configure_ARTIC 84 | 85 | // AS3-SP-516-274-CNES specifies a ±10% 'jitter' on the repetition period to reduce the risk of transmission collisions 86 | unsigned long nextTransmitTime; // Time of the next satellite transmission (before jitter is added) 87 | unsigned long nextTransmitTimeActual; // Actual time of the next satellite transmission (including jitter) 88 | 89 | void setup() 90 | { 91 | Serial.begin(115200); 92 | Serial.println(); 93 | Serial.println(F("ARGOS ARTIC R2 Example")); 94 | Serial.println(); 95 | 96 | SPI.begin(); 97 | 98 | // Uncomment the next line to enable the helpful debug messages 99 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 100 | 101 | Serial.println(F("Starting the ARTIC R2...")); 102 | Serial.println(); 103 | 104 | // Begin the ARTIC: enable power and upload firmware or boot from flash 105 | #ifdef IOTA 106 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 107 | #else 108 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 109 | #endif 110 | { 111 | Serial.println("ARTIC R2 not detected. Freezing..."); 112 | while (1) 113 | ; // Do nothing more 114 | } 115 | 116 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 117 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 118 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 119 | // earlier versions of the board will need to use version 1.0.9 of the library. 120 | uint32_t platformID = myARTIC.readPlatformID(); 121 | if (platformID == 0) 122 | { 123 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 124 | Serial.println(F("Please use the Library Manager to select version 1.0.9 of this library.")); 125 | Serial.println(F("Freezing...")); 126 | while (1) 127 | ; // Do nothing more 128 | } 129 | else 130 | { 131 | Serial.print(F("Your Platform ID is: 0x")); 132 | Serial.println(platformID, HEX); 133 | } 134 | 135 | // Define the time of the first transmit 136 | nextTransmitTime = repetitionPeriod; 137 | nextTransmitTimeActual = nextTransmitTime - tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 138 | } 139 | 140 | void loop() 141 | { 142 | // loop is one large switch/case that controls the sequencing of the code 143 | switch (loop_step) { 144 | 145 | // ************************************************************************************************ 146 | // Configure the ARTIC 147 | case configure_ARTIC: 148 | { 149 | // Set the TCXO voltage to 1.8V and autoDisable to 1 150 | if (myARTIC.setTCXOControl(1.8, true) == false) 151 | { 152 | Serial.println("setTCXOControl failed. Freezing..."); 153 | while (1) 154 | ; // Do nothing more 155 | } 156 | 157 | // Set the TCXO warm-up time 158 | if (myARTIC.setTCXOWarmupTime(tcxoWarmupTime) == false) 159 | { 160 | Serial.println("setTCXOWarmupTime failed. Freezing..."); 161 | while (1) 162 | ; // Do nothing more 163 | } 164 | 165 | // Set the satellite detection timeout to 60 seconds 166 | if (myARTIC.setSatelliteDetectionTimeout(60) == false) 167 | { 168 | Serial.println("setSatelliteDetectionTimeout failed. Freezing..."); 169 | while (1) 170 | ; // Do nothing more 171 | } 172 | 173 | // Set the TX mode to ARGOS 3 PTT-ZE 174 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_PTT_ZE_TX_MODE); 175 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 176 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 177 | { 178 | Serial.println("sendConfigurationCommand failed. Freezing..."); 179 | while (1) 180 | ; // Do nothing more 181 | } 182 | 183 | // Read and print the ARGOS configuration 184 | ARGOS_Configuration_Register configuration; 185 | myARTIC.readARGOSconfiguration(&configuration); 186 | myARTIC.printARGOSconfiguration(configuration); 187 | 188 | // Set the ARGOS 3 TX frequency to 401.630 MHz 189 | if (myARTIC.setARGOS23TxFrequency(401.630) == false) 190 | { 191 | Serial.println("setARGOS23TxFrequency failed. Freezing..."); 192 | while (1) 193 | ; // Do nothing more 194 | } 195 | 196 | // Print the TX frequency 197 | float tx23freq = myARTIC.getARGOS23TxFrequency(); 198 | Serial.print(F("The ARGOS 2/3 TX Frequency is ")); 199 | Serial.print(tx23freq, 3); 200 | Serial.println(F(" MHz.")); 201 | 202 | loop_step = ARTIC_TX; // Move on 203 | } 204 | break; 205 | 206 | // ************************************************************************************************ 207 | // Start the ARTIC in Transmit One Package And Go Idle mode 208 | case ARTIC_TX: 209 | { 210 | // Configure the Tx payload for ARGOS 3 PTT-ZE (AS3-SP-516-274-CNES) using our platform ID and 0 bits of user data 211 | // If the Platform ID has been set to 0x01234567, the complete over-air data stream, including sync pattern and length, should be: 212 | // 0xAFBBBAFC0F4C29B4BB3AA09CC followed by 0b00 213 | if (myARTIC.setPayloadARGOS3ZE() == false) 214 | { 215 | Serial.println(F("setPayloadARGOS3ZE failed!")); 216 | Serial.println(); 217 | // Read the payload back again and print it 218 | myARTIC.readTxPayload(); 219 | myARTIC.printTxPayload(); 220 | Serial.println(); 221 | Serial.println(F("Freezing...")); 222 | while (1) 223 | ; // Do nothing more 224 | } 225 | 226 | /* 227 | // Read the payload back again and print it 228 | myARTIC.readTxPayload(); 229 | myARTIC.printTxPayload(); 230 | Serial.println(); 231 | */ 232 | 233 | // Wait for the next repetition period 234 | while (nextTransmitTimeActual > millis()) 235 | { 236 | if ((millis() % 1000) < 50) // Print how long it is until the next transmit 237 | { 238 | Serial.print(F("The next transmit will take place in ")); 239 | unsigned long remaining = (nextTransmitTimeActual - millis()) / 1000; 240 | Serial.print(remaining); 241 | Serial.println(F(" seconds")); 242 | } 243 | delay(50); 244 | } 245 | nextTransmitTime += repetitionPeriod; 246 | nextTransmitTimeActual = nextTransmitTime + random((-0.1 * repetitionPeriod), (0.1 * repetitionPeriod)); 247 | nextTransmitTimeActual -= tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 248 | 249 | // Tell the ARTIC to do its thing! 250 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE); 251 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 252 | { 253 | Serial.println("sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE) failed!"); 254 | Serial.println(); 255 | ARTIC_R2_Firmware_Status status; 256 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 257 | Serial.println(F("ARTIC R2 Firmware Status:")); 258 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 259 | Serial.println(); 260 | Serial.println(F("ARTIC_R2_MCU_Command_Result:")); 261 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 262 | Serial.println(); 263 | Serial.println("Freezing..."); 264 | while (1) 265 | ; // Do nothing more 266 | } 267 | 268 | loop_step = wait_for_ARTIC_TX; // Move on 269 | } 270 | break; 271 | 272 | // ************************************************************************************************ 273 | // Start the ARTIC in Transmit One Package And Go Idle mode 274 | case wait_for_ARTIC_TX: 275 | { 276 | delay(1000); // Check the status every second 277 | 278 | // Read and print the ARTIC R2 status register 279 | ARTIC_R2_Firmware_Status status; 280 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 281 | Serial.println(F("ARTIC R2 Firmware Status:")); 282 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 283 | 284 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when TX is finished 285 | { 286 | Serial.println(F("INT1 pin is high. TX is finished (or MCU is in IDLE_STATE)!")); 287 | } 288 | 289 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT2) // Check the interrupt 2 flag. This will go high when if the message was invalid 290 | { 291 | Serial.println(F("INT2 pin is high. TX message was invalid! (Something really bad must have happened...)")); 292 | } 293 | 294 | Serial.println(); 295 | 296 | // Read and print the instruction progress 297 | ARTIC_R2_MCU_Instruction_Progress progress; 298 | // checkMCUinstructionProgress will return true if the instruction is complete 299 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 300 | Serial.println(F("ARTIC R2 instruction progress:")); 301 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 302 | 303 | Serial.println(); 304 | 305 | if (instructionComplete) 306 | { 307 | Serial.println(F("Transmission is complete!")); 308 | Serial.println(); 309 | 310 | Serial.println(F("Clearing INT1.")); 311 | Serial.println(); 312 | 313 | // Clear INT1 314 | if (myARTIC.clearInterrupts(1) == false) 315 | { 316 | Serial.println("clearInterrupts failed! Freezing..."); 317 | while (1) 318 | ; // Do nothing more 319 | } 320 | 321 | loop_step = ARTIC_TX; // Do over... 322 | } 323 | } 324 | break; 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /examples/Example17_TransmitARGOS2Example/Example17_TransmitARGOS2Example.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the TCXO voltage; 12 | sets the TCXO warmup time; 13 | sets the satellite detection timeout to 60 seconds; 14 | sets the TX mode to ARGOS PTT A2; 15 | sets the TX frequency; 16 | instructs the ARTIC to Transmit One Package And Go Idle; 17 | keeps checking the MCU status until transmit is complete; 18 | repeats. 19 | 20 | The transmit power can be reduced by 8dB by uncommenting the line: myARTIC.attenuateTXgain(true); 21 | 22 | License: please see the license file at: 23 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 24 | 25 | Feel like supporting our work? Buy a board from SparkFun! 26 | https://www.sparkfun.com/products/17236 27 | 28 | Hardware Connections: 29 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 30 | https://www.sparkfun.com/products/15574 31 | CS_Pin = A5 (D24) 32 | GAIN8_Pin = D3 33 | BOOT_Pin = D4 34 | INT1_Pin = D5 35 | INT2_Pin = D6 36 | RESET_Pin = D7 37 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 38 | RF_PWR_EN_Pin = D9 39 | (SPI COPI = D11) 40 | (SPI CIPO = D12) 41 | (SPI SCK = D13) 42 | 43 | If you are using IOTA, uncomment the #define IOTA below. 44 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 45 | 46 | */ 47 | 48 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 49 | 50 | // From v1.1.0 of the library, the platform ID is stored in PMEM and, for this example, should be 0x01234567 51 | 52 | const uint8_t Nx32_bits = 8; // In this example, transmit the maximum amount of data 53 | 54 | // The user data. Note: only the least-significant 24 bits of userData[0] are transmitted. 55 | const uint32_t userData[Nx32_bits] = {0x00111213, 0x21222324, 0x31323334, 0x41424344, 0x51525354, 0x61626364, 0x71727374, 0x81828384}; 56 | 57 | // The complete over-air data pattern (after the sync pattern) will be 0xF123456711121321222324313233344142434451525354616263647172737481828384 58 | 59 | const unsigned long repetitionPeriod = 50000; // Define the repetition period in milliseconds 60 | 61 | const uint32_t tcxoWarmupTime = 10; // Define the TCXO warmup time 62 | 63 | #include 64 | 65 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 66 | ARTIC_R2 myARTIC; 67 | 68 | // Pin assignments for the SparkFun Thing Plus - Artemis 69 | // (Change these if required) 70 | int CS_Pin = 24; 71 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 72 | int BOOT_Pin = 4; 73 | int INT1_Pin = 5; 74 | int INT2_Pin = 6; 75 | int RESET_Pin = 7; 76 | #ifdef IOTA 77 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 78 | #else 79 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 80 | int RF_PWR_EN_Pin = 9; 81 | #endif 82 | 83 | // Loop Steps - these are used by the switch/case in the main loop 84 | // This structure makes it easy to jump between any of the steps 85 | enum { 86 | configure_ARTIC, // Configure the ARTIC (set the satellite detection timeout and TX mode) 87 | ARTIC_TX, // Start the ARTIC TX 88 | wait_for_ARTIC_TX, // Wait for the ARTIC to transmit 89 | } loop_steps; 90 | int loop_step = configure_ARTIC; // Make sure loop_step is set to configure_ARTIC 91 | 92 | // AS3-SP-516-2098-CNES specifies a ±10% 'jitter' on the repetition period to reduce the risk of transmission collisions 93 | unsigned long nextTransmitTime; // Time of the next satellite transmission (before jitter is added) 94 | unsigned long nextTransmitTimeActual; // Actual time of the next satellite transmission (including jitter) 95 | 96 | void setup() 97 | { 98 | Serial.begin(115200); 99 | Serial.println(); 100 | Serial.println(F("ARGOS ARTIC R2 Example")); 101 | Serial.println(); 102 | 103 | SPI.begin(); 104 | 105 | // Uncomment the next line to enable the helpful debug messages 106 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 107 | 108 | Serial.println(F("Starting the ARTIC R2...")); 109 | Serial.println(); 110 | 111 | // Begin the ARTIC: enable power and upload firmware or boot from flash 112 | #ifdef IOTA 113 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 114 | #else 115 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 116 | #endif 117 | { 118 | Serial.println("ARTIC R2 not detected. Freezing..."); 119 | while (1) 120 | ; // Do nothing more 121 | } 122 | 123 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 124 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 125 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 126 | // earlier versions of the board will need to use version 1.0.9 of the library. 127 | uint32_t platformID = myARTIC.readPlatformID(); 128 | if (platformID == 0) 129 | { 130 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 131 | Serial.println(F("Please use the Library Manager to select version 1.0.9 of this library.")); 132 | Serial.println(F("Freezing...")); 133 | while (1) 134 | ; // Do nothing more 135 | } 136 | else 137 | { 138 | Serial.print(F("Your Platform ID is: 0x")); 139 | Serial.println(platformID, HEX); 140 | } 141 | 142 | // Define the time of the first transmit 143 | nextTransmitTime = repetitionPeriod; 144 | nextTransmitTimeActual = nextTransmitTime - tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 145 | } 146 | 147 | void loop() 148 | { 149 | // loop is one large switch/case that controls the sequencing of the code 150 | switch (loop_step) { 151 | 152 | // ************************************************************************************************ 153 | // Configure the ARTIC 154 | case configure_ARTIC: 155 | { 156 | // Set the TCXO voltage to 1.8V and autoDisable to 1 157 | if (myARTIC.setTCXOControl(1.8, true) == false) 158 | { 159 | Serial.println("setTCXOControl failed. Freezing..."); 160 | while (1) 161 | ; // Do nothing more 162 | } 163 | 164 | // Set the TCXO warm-up time 165 | if (myARTIC.setTCXOWarmupTime(tcxoWarmupTime) == false) 166 | { 167 | Serial.println("setTCXOWarmupTime failed. Freezing..."); 168 | while (1) 169 | ; // Do nothing more 170 | } 171 | 172 | // Set the satellite detection timeout to 60 seconds 173 | if (myARTIC.setSatelliteDetectionTimeout(60) == false) 174 | { 175 | Serial.println("setSatelliteDetectionTimeout failed. Freezing..."); 176 | while (1) 177 | ; // Do nothing more 178 | } 179 | 180 | // Set the TX mode to ARGOS PTT A2 181 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_PTT_A2_TX_MODE); 182 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 183 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 184 | { 185 | Serial.println("sendConfigurationCommand failed. Freezing..."); 186 | while (1) 187 | ; // Do nothing more 188 | } 189 | 190 | // Read and print the ARGOS configuration 191 | ARGOS_Configuration_Register configuration; 192 | myARTIC.readARGOSconfiguration(&configuration); 193 | myARTIC.printARGOSconfiguration(configuration); 194 | 195 | // Set the ARGOS PTT A2 frequency to 401.630 MHz 196 | // From AS3-SP-516-2098-CNES: 197 | // The transmission frequency for PTT/PMT-A2 platforms shall be set between 399.91 MHz to 401.68 MHz. 198 | // Due to frequency regulations, the frequency ranges [400.05 MHz to 401.0 MHz] and [401.2 MHz to 401.3 MHz] are forbidden for A2 transmissions. 199 | if (myARTIC.setARGOS23TxFrequency(401.630) == false) 200 | { 201 | Serial.println("setARGOS23TxFrequency failed. Freezing..."); 202 | while (1) 203 | ; // Do nothing more 204 | } 205 | 206 | // Print the TX frequency 207 | float tx2freq = myARTIC.getARGOS23TxFrequency(); 208 | Serial.print(F("The ARGOS PTT A2 TX Frequency is ")); 209 | Serial.print(tx2freq, 3); 210 | Serial.println(F(" MHz.")); 211 | 212 | // Uncomment the next line if you want to attenuate the transmit power by 8dB 213 | //myARTIC.attenuateTXgain(true); 214 | 215 | loop_step = ARTIC_TX; // Move on 216 | } 217 | break; 218 | 219 | // ************************************************************************************************ 220 | // Start the ARTIC in Transmit One Package And Go Idle mode 221 | case ARTIC_TX: 222 | { 223 | // Configure the Tx payload for ARGOS PTT A2 using the platform ID and the defined user data 224 | // From v1.1.0 of the library, the platform ID is stored in PMEM 225 | if (myARTIC.setPayloadARGOS2(Nx32_bits, (uint32_t *)&userData) == false) 226 | { 227 | Serial.println(F("setPayloadARGOS2 failed!")); 228 | Serial.println(); 229 | // Read the payload back again and print it 230 | myARTIC.readTxPayload(); 231 | myARTIC.printTxPayload(); 232 | Serial.println(); 233 | Serial.println(F("Freezing...")); 234 | while (1) 235 | ; // Do nothing more 236 | } 237 | 238 | /* 239 | // Read the payload back again and print it 240 | myARTIC.readTxPayload(); 241 | myARTIC.printTxPayload(); 242 | Serial.println(); 243 | */ 244 | 245 | // Wait for the next repetition period 246 | while (nextTransmitTimeActual > millis()) 247 | { 248 | if ((millis() % 1000) < 50) // Print how long it is until the next transmit 249 | { 250 | Serial.print(F("The next transmit will take place in ")); 251 | unsigned long remaining = (nextTransmitTimeActual - millis()) / 1000; 252 | Serial.print(remaining); 253 | Serial.println(F(" seconds")); 254 | } 255 | delay(50); 256 | } 257 | nextTransmitTime += repetitionPeriod; 258 | nextTransmitTimeActual = nextTransmitTime + random((-0.1 * repetitionPeriod), (0.1 * repetitionPeriod)); 259 | nextTransmitTimeActual -= tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 260 | 261 | // Tell the ARTIC to do its thing! 262 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE); 263 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 264 | { 265 | Serial.println("sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE) failed!"); 266 | Serial.println(); 267 | ARTIC_R2_Firmware_Status status; 268 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 269 | Serial.println(F("ARTIC R2 Firmware Status:")); 270 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 271 | Serial.println(); 272 | Serial.println(F("ARTIC_R2_MCU_Command_Result:")); 273 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 274 | Serial.println(); 275 | Serial.println("Freezing..."); 276 | while (1) 277 | ; // Do nothing more 278 | } 279 | 280 | loop_step = wait_for_ARTIC_TX; // Move on 281 | } 282 | break; 283 | 284 | // ************************************************************************************************ 285 | // Start the ARTIC in Transmit One Package And Go Idle mode 286 | case wait_for_ARTIC_TX: 287 | { 288 | delay(1000); // Check the status every second 289 | 290 | // Read and print the ARTIC R2 status register 291 | ARTIC_R2_Firmware_Status status; 292 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 293 | Serial.println(F("ARTIC R2 Firmware Status:")); 294 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 295 | 296 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when TX is finished 297 | { 298 | Serial.println(F("INT1 pin is high. TX is finished (or MCU is in IDLE_STATE)!")); 299 | } 300 | 301 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT2) // Check the interrupt 2 flag. This will go high when if the message was invalid 302 | { 303 | Serial.println(F("INT2 pin is high. TX message was invalid! (Something really bad must have happened...)")); 304 | } 305 | 306 | Serial.println(); 307 | 308 | // Read and print the instruction progress 309 | ARTIC_R2_MCU_Instruction_Progress progress; 310 | // checkMCUinstructionProgress will return true if the instruction is complete 311 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 312 | Serial.println(F("ARTIC R2 instruction progress:")); 313 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 314 | 315 | Serial.println(); 316 | 317 | if (instructionComplete) 318 | { 319 | Serial.println(F("Transmission is complete!")); 320 | Serial.println(); 321 | 322 | Serial.println(F("Clearing INT1.")); 323 | Serial.println(); 324 | 325 | // Clear INT1 326 | if (myARTIC.clearInterrupts(1) == false) 327 | { 328 | Serial.println("clearInterrupts failed! Freezing..."); 329 | while (1) 330 | ; // Do nothing more 331 | } 332 | 333 | loop_step = ARTIC_TX; // Do over... 334 | } 335 | } 336 | break; 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /examples/Example18_TransmitARGOS3Example/Example18_TransmitARGOS3Example.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the TCXO voltage; 12 | sets the TCXO warmup time; 13 | sets the satellite detection timeout to 60 seconds; 14 | sets the TX mode to ARGOS PTT A3; 15 | sets the TX frequency; 16 | instructs the ARTIC to Transmit One Package And Go Idle; 17 | keeps checking the MCU status until transmit is complete; 18 | repeats. 19 | 20 | License: please see the license file at: 21 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 22 | 23 | Feel like supporting our work? Buy a board from SparkFun! 24 | https://www.sparkfun.com/products/17236 25 | 26 | Hardware Connections: 27 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 28 | https://www.sparkfun.com/products/15574 29 | CS_Pin = A5 (D24) 30 | GAIN8_Pin = D3 31 | BOOT_Pin = D4 32 | INT1_Pin = D5 33 | INT2_Pin = D6 34 | RESET_Pin = D7 35 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 36 | RF_PWR_EN_Pin = D9 37 | (SPI COPI = D11) 38 | (SPI CIPO = D12) 39 | (SPI SCK = D13) 40 | 41 | If you are using IOTA, uncomment the #define IOTA below. 42 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 43 | 44 | */ 45 | 46 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 47 | 48 | // From v1.1.0 of the library, the platform ID is stored in PMEM and, for this example, should be 0x01234567 49 | 50 | const uint8_t Nx32_bits = 8; // In this example, transmit the maximum amount of data 51 | 52 | // The user data. Note: only the least-significant 24 bits of userData[0] are transmitted. 53 | const uint32_t userData[Nx32_bits] = {0x00111213, 0x21222324, 0x31323334, 0x41424344, 0x51525354, 0x61626364, 0x71727374, 0x81828384}; 54 | 55 | const unsigned long repetitionPeriod = 50000; // Define the repetition period in milliseconds 56 | 57 | const uint32_t tcxoWarmupTime = 10; // Define the TCXO warmup time 58 | 59 | #include 60 | 61 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 62 | ARTIC_R2 myARTIC; 63 | 64 | // Pin assignments for the SparkFun Thing Plus - Artemis 65 | // (Change these if required) 66 | int CS_Pin = 24; 67 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 68 | int BOOT_Pin = 4; 69 | int INT1_Pin = 5; 70 | int INT2_Pin = 6; 71 | int RESET_Pin = 7; 72 | #ifdef IOTA 73 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 74 | #else 75 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 76 | int RF_PWR_EN_Pin = 9; 77 | #endif 78 | 79 | // Loop Steps - these are used by the switch/case in the main loop 80 | // This structure makes it easy to jump between any of the steps 81 | enum { 82 | configure_ARTIC, // Configure the ARTIC (set the satellite detection timeout and TX mode) 83 | ARTIC_TX, // Start the ARTIC TX 84 | wait_for_ARTIC_TX, // Wait for the ARTIC to transmit 85 | } loop_steps; 86 | int loop_step = configure_ARTIC; // Make sure loop_step is set to configure_ARTIC 87 | 88 | // AS3-SP-516-274-CNES specifies a ±10% 'jitter' on the repetition period to reduce the risk of transmission collisions 89 | unsigned long nextTransmitTime; // Time of the next satellite transmission (before jitter is added) 90 | unsigned long nextTransmitTimeActual; // Actual time of the next satellite transmission (including jitter) 91 | 92 | void setup() 93 | { 94 | Serial.begin(115200); 95 | Serial.println(); 96 | Serial.println(F("ARGOS ARTIC R2 Example")); 97 | Serial.println(); 98 | 99 | SPI.begin(); 100 | 101 | // Uncomment the next line to enable the helpful debug messages 102 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 103 | 104 | Serial.println(F("Starting the ARTIC R2...")); 105 | Serial.println(); 106 | 107 | // Begin the ARTIC: enable power and upload firmware or boot from flash 108 | #ifdef IOTA 109 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 110 | #else 111 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 112 | #endif 113 | { 114 | Serial.println("ARTIC R2 not detected. Freezing..."); 115 | while (1) 116 | ; // Do nothing more 117 | } 118 | 119 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 120 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 121 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 122 | // earlier versions of the board will need to use version 1.0.9 of the library. 123 | uint32_t platformID = myARTIC.readPlatformID(); 124 | if (platformID == 0) 125 | { 126 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 127 | Serial.println(F("Please use the Library Manager to select version 1.0.9 of this library.")); 128 | Serial.println(F("Freezing...")); 129 | while (1) 130 | ; // Do nothing more 131 | } 132 | else 133 | { 134 | Serial.print(F("Your Platform ID is: 0x")); 135 | Serial.println(platformID, HEX); 136 | } 137 | 138 | // Define the time of the first transmit 139 | nextTransmitTime = repetitionPeriod; 140 | nextTransmitTimeActual = nextTransmitTime - tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 141 | } 142 | 143 | void loop() 144 | { 145 | // loop is one large switch/case that controls the sequencing of the code 146 | switch (loop_step) { 147 | 148 | // ************************************************************************************************ 149 | // Configure the ARTIC 150 | case configure_ARTIC: 151 | { 152 | // Set the TCXO voltage to 1.8V and autoDisable to 1 153 | if (myARTIC.setTCXOControl(1.8, true) == false) 154 | { 155 | Serial.println("setTCXOControl failed. Freezing..."); 156 | while (1) 157 | ; // Do nothing more 158 | } 159 | 160 | // Set the TCXO warm-up time 161 | if (myARTIC.setTCXOWarmupTime(tcxoWarmupTime) == false) 162 | { 163 | Serial.println("setTCXOWarmupTime failed. Freezing..."); 164 | while (1) 165 | ; // Do nothing more 166 | } 167 | 168 | // Set the satellite detection timeout to 60 seconds 169 | if (myARTIC.setSatelliteDetectionTimeout(60) == false) 170 | { 171 | Serial.println("setSatelliteDetectionTimeout failed. Freezing..."); 172 | while (1) 173 | ; // Do nothing more 174 | } 175 | 176 | // Set the TX mode to ARGOS 3 PTT-A3 177 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_PTT_A3_TX_MODE); 178 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 179 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 180 | { 181 | Serial.println("sendConfigurationCommand failed. Freezing..."); 182 | while (1) 183 | ; // Do nothing more 184 | } 185 | 186 | // Read and print the ARGOS configuration 187 | ARGOS_Configuration_Register configuration; 188 | myARTIC.readARGOSconfiguration(&configuration); 189 | myARTIC.printARGOSconfiguration(configuration); 190 | 191 | // Set the ARGOS PTT A3 frequency to 401.630 MHz 192 | // From AS3-SP-516-274-CNES: 193 | // The transmitted frequency for PTT/PMT-A3 in the ARGOS 4 system is set between 399.90 MHz to 401.69 MHz 194 | // Due to frequency regulations, the frequency ranges [400.05 MHz to 401.0 MHz] and [401.2 MHz to 401.3 MHz] are forbidden for VLD-A4 transmissions. 195 | if (myARTIC.setARGOS23TxFrequency(401.630) == false) 196 | { 197 | Serial.println("setARGOS23TxFrequency failed. Freezing..."); 198 | while (1) 199 | ; // Do nothing more 200 | } 201 | 202 | // Print the TX frequency 203 | float tx23freq = myARTIC.getARGOS23TxFrequency(); 204 | Serial.print(F("The ARGOS 2/3 TX Frequency is ")); 205 | Serial.print(tx23freq, 3); 206 | Serial.println(F(" MHz.")); 207 | 208 | loop_step = ARTIC_TX; // Move on 209 | } 210 | break; 211 | 212 | // ************************************************************************************************ 213 | // Start the ARTIC in Transmit One Package And Go Idle mode 214 | case ARTIC_TX: 215 | { 216 | // Configure the Tx payload for ARGOS PTT A3 using the platform ID and the defined user data 217 | // From v1.1.0 of the library, the platform ID is stored in PMEM and, for this example, should be 0x01234567 218 | if (myARTIC.setPayloadARGOS3(Nx32_bits, (uint32_t *)&userData) == false) 219 | { 220 | Serial.println(F("setPayloadARGOS3 failed!")); 221 | Serial.println(); 222 | // Read the payload back again and print it 223 | myARTIC.readTxPayload(); 224 | myARTIC.printTxPayload(); 225 | Serial.println(); 226 | Serial.println(F("Freezing...")); 227 | while (1) 228 | ; // Do nothing more 229 | } 230 | 231 | /* 232 | // Read the payload back again and print it 233 | myARTIC.readTxPayload(); 234 | myARTIC.printTxPayload(); 235 | Serial.println(); 236 | */ 237 | 238 | // Wait for the next repetition period 239 | while (nextTransmitTimeActual > millis()) 240 | { 241 | if ((millis() % 1000) < 50) // Print how long it is until the next transmit 242 | { 243 | Serial.print(F("The next transmit will take place in ")); 244 | unsigned long remaining = (nextTransmitTimeActual - millis()) / 1000; 245 | Serial.print(remaining); 246 | Serial.println(F(" seconds")); 247 | } 248 | delay(50); 249 | } 250 | nextTransmitTime += repetitionPeriod; 251 | nextTransmitTimeActual = nextTransmitTime + random((-0.1 * repetitionPeriod), (0.1 * repetitionPeriod)); 252 | nextTransmitTimeActual -= tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 253 | 254 | // Tell the ARTIC to do its thing! 255 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE); 256 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 257 | { 258 | Serial.println("sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE) failed!"); 259 | Serial.println(); 260 | ARTIC_R2_Firmware_Status status; 261 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 262 | Serial.println(F("ARTIC R2 Firmware Status:")); 263 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 264 | Serial.println(); 265 | Serial.println(F("ARTIC_R2_MCU_Command_Result:")); 266 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 267 | Serial.println(); 268 | Serial.println("Freezing..."); 269 | while (1) 270 | ; // Do nothing more 271 | } 272 | 273 | loop_step = wait_for_ARTIC_TX; // Move on 274 | } 275 | break; 276 | 277 | // ************************************************************************************************ 278 | // Start the ARTIC in Transmit One Package And Go Idle mode 279 | case wait_for_ARTIC_TX: 280 | { 281 | delay(1000); // Check the status every second 282 | 283 | // Read and print the ARTIC R2 status register 284 | ARTIC_R2_Firmware_Status status; 285 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 286 | Serial.println(F("ARTIC R2 Firmware Status:")); 287 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 288 | 289 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when TX is finished 290 | { 291 | Serial.println(F("INT1 pin is high. TX is finished (or MCU is in IDLE_STATE)!")); 292 | } 293 | 294 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT2) // Check the interrupt 2 flag. This will go high when if the message was invalid 295 | { 296 | Serial.println(F("INT2 pin is high. TX message was invalid! (Something really bad must have happened...)")); 297 | } 298 | 299 | Serial.println(); 300 | 301 | // Read and print the instruction progress 302 | ARTIC_R2_MCU_Instruction_Progress progress; 303 | // checkMCUinstructionProgress will return true if the instruction is complete 304 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 305 | Serial.println(F("ARTIC R2 instruction progress:")); 306 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 307 | 308 | Serial.println(); 309 | 310 | if (instructionComplete) 311 | { 312 | Serial.println(F("Transmission is complete!")); 313 | Serial.println(); 314 | 315 | Serial.println(F("Clearing INT1.")); 316 | Serial.println(); 317 | 318 | // Clear INT1 319 | if (myARTIC.clearInterrupts(1) == false) 320 | { 321 | Serial.println("clearInterrupts failed! Freezing..."); 322 | while (1) 323 | ; // Do nothing more 324 | } 325 | 326 | loop_step = ARTIC_TX; // Do over... 327 | } 328 | } 329 | break; 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /examples/Example1_FirmwareVersion/Example1_FirmwareVersion.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example begins (initializes) the ARTIC breakout or IOTA. The pin numbers are passed to begin. 8 | Begin takes care of setting the PWR_EN pins to enable power for the ARTIC and the RF Amp. 9 | Begin also controls the BOOT pin and downloads the firmware to the ARTIC. 10 | Begin returns true if the firmware checksum is valid. 11 | 12 | The ARTIC firmware version is read and printed to Serial. 13 | 14 | License: please see the license file at: 15 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 16 | 17 | Feel like supporting our work? Buy a board from SparkFun! 18 | https://www.sparkfun.com/products/17236 19 | 20 | Hardware Connections: 21 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 22 | https://www.sparkfun.com/products/15574 23 | CS_Pin = A5 (D24) 24 | GAIN8_Pin = D3 25 | BOOT_Pin = D4 26 | INT1_Pin = D5 27 | INT2_Pin = D6 28 | RESET_Pin = D7 29 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 30 | RF_PWR_EN_Pin = D9 31 | (SPI COPI = D11) 32 | (SPI CIPO = D12) 33 | (SPI SCK = D13) 34 | 35 | If you are using the SparkFun ESP32 Thing Plus, the pins are different: 36 | https://www.sparkfun.com/products/15663 37 | CS_Pin = A5 (D4) 38 | GAIN8_Pin = D14 39 | BOOT_Pin = D32 40 | INT1_Pin = D15 41 | INT2_Pin = D33 42 | RESET_Pin = D27 43 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D12 44 | RF_PWR_EN_Pin = D13 ** Please note: D13 on the ESP32 Thing Plus is LED_BUILTIN ** 45 | (SPI COPI = D18) 46 | (SPI CIPO = D19) 47 | (SPI SCK = D5) 48 | 49 | 50 | If you are using IOTA, uncomment the #define IOTA below. 51 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 52 | 53 | */ 54 | 55 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 56 | 57 | #include 58 | 59 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 60 | ARTIC_R2 myARTIC; 61 | 62 | 63 | // Pin assignments for the SparkFun Thing Plus - Artemis 64 | // (Change these if required) 65 | int CS_Pin = 24; 66 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 67 | int BOOT_Pin = 4; 68 | int INT1_Pin = 5; 69 | int INT2_Pin = 6; 70 | int RESET_Pin = 7; 71 | #ifdef IOTA 72 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 73 | #else 74 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 75 | int RF_PWR_EN_Pin = 9; 76 | #endif 77 | 78 | 79 | /* 80 | // Pin assignments for the SparkFun ESP32 Thing Plus 81 | // (Change these if required) 82 | int CS_Pin = 4; 83 | int GAIN8_Pin = 14; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 84 | int BOOT_Pin = 32; 85 | int INT1_Pin = 15; 86 | int INT2_Pin = 33; 87 | int RESET_Pin = 27; 88 | #ifdef IOTA 89 | int IOTA_PWR_EN_Pin = 12; // IOTA has a single power enable pin 90 | #else 91 | int ARTIC_PWR_EN_Pin = 12; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 92 | int RF_PWR_EN_Pin = 13; // ** Please note: D13 on the ESP32 Thing Plus is LED_BUILTIN ** 93 | #endif 94 | */ 95 | 96 | void setup() 97 | { 98 | Serial.begin(115200); 99 | Serial.println(); 100 | Serial.println(F("ARGOS ARTIC R2 Example")); 101 | Serial.println(); 102 | 103 | SPI.begin(); 104 | 105 | Serial.println(F("ARTIC R2 is booting...")); 106 | Serial.println(); 107 | 108 | //myARTIC.enableDebugging(); // Uncomment this line to enable debug messages on Serial 109 | 110 | //myARTIC.enableDebugging(Serial1); // E.g. enable debug messages on Serial1 instead 111 | 112 | // Begin (initialize) the ARTIC 113 | #ifdef IOTA 114 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 115 | #else 116 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 117 | #endif 118 | { 119 | Serial.println(F("ARTIC R2 not detected. Freezing...")); 120 | while (1) 121 | ; // Do nothing more 122 | } 123 | 124 | Serial.println(F("ARTIC R2 boot was successful.")); 125 | 126 | char buffer[9]; // Buffer to store the firmware version (8 bytes + NULL) 127 | 128 | myARTIC.readFirmwareVersion(&buffer[0]); // Read the firmware version from PMEM 129 | 130 | Serial.print(F("ARTIC R2 firmware version is: ")); 131 | Serial.println(buffer); 132 | 133 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 134 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 135 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 136 | // earlier versions of the board will need to use version 1.0.9 of the library. 137 | uint32_t platformID = myARTIC.readPlatformID(); 138 | if (platformID == 0) 139 | { 140 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 141 | Serial.println(F("For the transmit examples, you will need to use the Library Manager to select version 1.0.9 of this library.")); 142 | } 143 | else 144 | { 145 | Serial.print(F("Your Platform ID is: 0x")); 146 | Serial.println(platformID, HEX); 147 | } 148 | } 149 | 150 | void loop() 151 | { 152 | // Nothing to do here... 153 | } 154 | -------------------------------------------------------------------------------- /examples/Example2_FirmwareStatus/Example2_FirmwareStatus.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example begins (initializes) the ARTIC breakout or IOTA. The pin numbers are passed to begin. 8 | Begin takes care of setting the PWR_EN pins to enable power for the ARTIC and the RF Amp. 9 | Begin also controls the BOOT pin and downloads the firmware to the ARTIC. 10 | Begin returns true if the firmware checksum is valid. 11 | 12 | The firmware status is read and printed to Serial. 13 | 14 | License: please see the license file at: 15 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 16 | 17 | Feel like supporting our work? Buy a board from SparkFun! 18 | https://www.sparkfun.com/products/17236 19 | 20 | Hardware Connections: 21 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 22 | https://www.sparkfun.com/products/15574 23 | CS_Pin = A5 (D24) 24 | GAIN8_Pin = D3 25 | BOOT_Pin = D4 26 | INT1_Pin = D5 27 | INT2_Pin = D6 28 | RESET_Pin = D7 29 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 30 | RF_PWR_EN_Pin = D9 31 | (SPI COPI = D11) 32 | (SPI CIPO = D12) 33 | (SPI SCK = D13) 34 | 35 | If you are using IOTA, uncomment the #define IOTA below. 36 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 37 | 38 | */ 39 | 40 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 41 | 42 | #include 43 | 44 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 45 | ARTIC_R2 myARTIC; 46 | 47 | // Pin assignments for the SparkFun Thing Plus - Artemis 48 | // (Change these if required) 49 | int CS_Pin = 24; 50 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 51 | int BOOT_Pin = 4; 52 | int INT1_Pin = 5; 53 | int INT2_Pin = 6; 54 | int RESET_Pin = 7; 55 | #ifdef IOTA 56 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 57 | #else 58 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 59 | int RF_PWR_EN_Pin = 9; 60 | #endif 61 | 62 | void setup() 63 | { 64 | Serial.begin(115200); 65 | Serial.println(); 66 | Serial.println(F("ARGOS ARTIC R2 Example")); 67 | Serial.println(); 68 | 69 | SPI.begin(); 70 | 71 | Serial.println(F("ARTIC R2 is booting...")); 72 | Serial.println(); 73 | 74 | //myARTIC.enableDebugging(); // Uncomment this line to enable debug messages on Serial 75 | 76 | //myARTIC.enableDebugging(Serial1); // E.g. enable debug messages on Serial1 instead 77 | 78 | // Begin (initialize) the ARTIC 79 | #ifdef IOTA 80 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 81 | #else 82 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 83 | #endif 84 | { 85 | Serial.println(F("ARTIC R2 not detected. Freezing...")); 86 | while (1) 87 | ; // Do nothing more 88 | } 89 | 90 | Serial.println(F("ARTIC R2 boot was successful.")); 91 | 92 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 93 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 94 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 95 | // earlier versions of the board will need to use version 1.0.9 of the library. 96 | uint32_t platformID = myARTIC.readPlatformID(); 97 | if (platformID == 0) 98 | { 99 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 100 | Serial.println(F("For the transmit examples, you will need to use the Library Manager to select version 1.0.9 of this library.")); 101 | } 102 | else 103 | { 104 | Serial.print(F("Your Platform ID is: 0x")); 105 | Serial.println(platformID, HEX); 106 | } 107 | 108 | ARTIC_R2_Firmware_Status status; 109 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 110 | 111 | Serial.println(F("ARTIC R2 Firmware Status:")); 112 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 113 | 114 | //myARTIC.printFirmwareStatus(status, Serial1); // E.g.: pretty-print the firmware status to Serial1 instead 115 | 116 | } 117 | 118 | void loop() 119 | { 120 | // Nothing to do here... 121 | } 122 | -------------------------------------------------------------------------------- /examples/Example3_ReadSettings/Example3_ReadSettings.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example begins (initializes) the ARTIC breakout or IOTA and then reads and prints a bunch of settings. 8 | 9 | License: please see the license file at: 10 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 11 | 12 | Feel like supporting our work? Buy a board from SparkFun! 13 | https://www.sparkfun.com/products/17236 14 | 15 | Hardware Connections: 16 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 17 | https://www.sparkfun.com/products/15574 18 | CS_Pin = A5 (D24) 19 | GAIN8_Pin = D3 20 | BOOT_Pin = D4 21 | INT1_Pin = D5 22 | INT2_Pin = D6 23 | RESET_Pin = D7 24 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 25 | RF_PWR_EN_Pin = D9 26 | (SPI COPI = D11) 27 | (SPI CIPO = D12) 28 | (SPI SCK = D13) 29 | 30 | If you are using IOTA, uncomment the #define IOTA below. 31 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 32 | 33 | */ 34 | 35 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 36 | 37 | #include 38 | 39 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 40 | ARTIC_R2 myARTIC; 41 | 42 | // Pin assignments for the SparkFun Thing Plus - Artemis 43 | // (Change these if required) 44 | int CS_Pin = 24; 45 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 46 | int BOOT_Pin = 4; 47 | int INT1_Pin = 5; 48 | int INT2_Pin = 6; 49 | int RESET_Pin = 7; 50 | #ifdef IOTA 51 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 52 | #else 53 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 54 | int RF_PWR_EN_Pin = 9; 55 | #endif 56 | 57 | void setup() 58 | { 59 | Serial.begin(115200); 60 | Serial.println(); 61 | Serial.println(F("ARGOS ARTIC R2 Example")); 62 | Serial.println(); 63 | 64 | Serial.println(F("ARTIC R2 is booting...")); 65 | Serial.println(); 66 | 67 | SPI.begin(); 68 | 69 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 70 | //myARTIC.enableDebugging(Serial1); // E.g. enable debug messages to Serial1 instead 71 | 72 | // Begin (initialize) the ARTIC 73 | #ifdef IOTA 74 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 75 | #else 76 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 77 | #endif 78 | { 79 | Serial.println(F("ARTIC R2 not detected. Freezing...")); 80 | while (1) 81 | ; // Do nothing more 82 | } 83 | 84 | Serial.println(F("ARTIC R2 boot was successful.")); 85 | Serial.println(); 86 | 87 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 88 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 89 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 90 | // earlier versions of the board will need to use version 1.0.9 of the library. 91 | uint32_t platformID = myARTIC.readPlatformID(); 92 | if (platformID == 0) 93 | { 94 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 95 | Serial.println(F("For the transmit examples, you will need to use the Library Manager to select version 1.0.9 of this library.")); 96 | } 97 | else 98 | { 99 | Serial.print(F("Your Platform ID is: 0x")); 100 | Serial.println(platformID, HEX); 101 | } 102 | 103 | // Read and print the ARGOS configuration 104 | ARGOS_Configuration_Register configuration; 105 | myARTIC.readARGOSconfiguration(&configuration); 106 | myARTIC.printARGOSconfiguration(configuration); // Pretty-print the TX and RX configuration to Serial 107 | 108 | uint32_t rxTimeout = myARTIC.readRxTimeout(); 109 | Serial.print(F("The RX Timeout is ")); 110 | Serial.print(rxTimeout); 111 | Serial.println(F(" seconds.")); 112 | 113 | uint32_t detectionTimeout = myARTIC.readSatelliteDetectionTimeout(); 114 | Serial.print(F("The Satellite Detection Timeout is ")); 115 | Serial.print(detectionTimeout); 116 | Serial.println(F(" seconds.")); 117 | 118 | uint32_t warmupTime = myARTIC.readTCXOWarmupTime(); 119 | Serial.print(F("The TCXO Warmup Time is ")); 120 | Serial.print(warmupTime); 121 | Serial.println(F(" seconds.")); 122 | 123 | uint32_t certificationInterval = myARTIC.readTxCertificationInterval(); 124 | Serial.print(F("The TX Certification Interval is ")); 125 | Serial.print(certificationInterval); 126 | Serial.println(F(" seconds.")); 127 | 128 | float controlVoltage = myARTIC.readTCXOControlVoltage(); 129 | Serial.print(F("The TCXO Control Voltage is ")); 130 | Serial.print(controlVoltage, 2); 131 | Serial.println(F(" Volts.")); 132 | 133 | boolean autoDisable = myARTIC.readTCXOAutoDisable(); 134 | Serial.print(F("TCXO Auto Disable is ")); 135 | if (autoDisable == false) Serial.print(F("not ")); 136 | Serial.println(F("enabled.")); 137 | 138 | float tx23freq = myARTIC.getARGOS23TxFrequency(); 139 | Serial.print(F("The ARGOS 2/3 TX Frequency is ")); 140 | Serial.print(tx23freq, 3); 141 | Serial.println(F(" MHz.")); 142 | 143 | float tx4freq = myARTIC.getARGOS4TxFrequency(); 144 | Serial.print(F("The ARGOS 4 TX Frequency is ")); 145 | Serial.print(tx4freq, 3); 146 | Serial.println(F(" MHz.")); 147 | 148 | boolean rxCRCenabled = myARTIC.isRXCRCenabled(); 149 | Serial.print(F("The RX CRC is ")); 150 | if (rxCRCenabled == false) Serial.print(F("not ")); 151 | Serial.println(F("enabled.")); 152 | 153 | int lutLength = myARTIC.getAddressLUTlength(); 154 | Serial.print(F("The Address-Filtering Look-Up-Table length is ")); 155 | Serial.print(lutLength); 156 | Serial.println(F(".")); 157 | 158 | boolean rxTransparentMode = myARTIC.isRXTransparentModeEnabled(); 159 | Serial.print(F("RX Transparent Mode is ")); 160 | if (rxTransparentMode == false) Serial.print(F("not ")); 161 | Serial.println(F("enabled.")); 162 | } 163 | 164 | void loop() 165 | { 166 | // Nothing to do here... 167 | } 168 | -------------------------------------------------------------------------------- /examples/Example4_SatelliteDetection/Example4_SatelliteDetection.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the TCXO voltage; 12 | sets the satellite detection timeout to 600 seconds; 13 | starts satellite detection; 14 | keeps checking the MCU status until a satellite is detected or the detection times out. 15 | 16 | License: please see the license file at: 17 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 18 | 19 | Feel like supporting our work? Buy a board from SparkFun! 20 | https://www.sparkfun.com/products/17236 21 | 22 | Hardware Connections: 23 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 24 | https://www.sparkfun.com/products/15574 25 | CS_Pin = A5 (D24) 26 | GAIN8_Pin = D3 27 | BOOT_Pin = D4 28 | INT1_Pin = D5 29 | INT2_Pin = D6 30 | RESET_Pin = D7 31 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 32 | RF_PWR_EN_Pin = D9 33 | (SPI COPI = D11) 34 | (SPI CIPO = D12) 35 | (SPI SCK = D13) 36 | 37 | If you are using IOTA, uncomment the #define IOTA below. 38 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 39 | 40 | */ 41 | 42 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 43 | 44 | #include 45 | 46 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 47 | ARTIC_R2 myARTIC; 48 | 49 | // Pin assignments for the SparkFun Thing Plus - Artemis 50 | // (Change these if required) 51 | int CS_Pin = 24; 52 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 53 | int BOOT_Pin = 4; 54 | int INT1_Pin = 5; 55 | int INT2_Pin = 6; 56 | int RESET_Pin = 7; 57 | #ifdef IOTA 58 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 59 | #else 60 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 61 | int RF_PWR_EN_Pin = 9; 62 | #endif 63 | 64 | void setup() 65 | { 66 | Serial.begin(115200); 67 | Serial.println(); 68 | Serial.println(F("ARGOS ARTIC R2 Example")); 69 | Serial.println(); 70 | 71 | Serial.println(F("ARTIC R2 is booting...")); 72 | Serial.println(); 73 | 74 | SPI.begin(); 75 | 76 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 77 | 78 | // Begin the ARTIC: enable power and upload firmware or boot from flash 79 | #ifdef IOTA 80 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 81 | #else 82 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 83 | #endif 84 | { 85 | Serial.println("ARTIC R2 not detected. Freezing..."); 86 | while (1) 87 | ; // Do nothing more 88 | } 89 | 90 | Serial.println(F("ARTIC R2 boot was successful.")); 91 | Serial.println(); 92 | 93 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 94 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 95 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 96 | // earlier versions of the board will need to use version 1.0.9 of the library. 97 | uint32_t platformID = myARTIC.readPlatformID(); 98 | if (platformID == 0) 99 | { 100 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 101 | Serial.println(F("For the transmit examples, you will need to use the Library Manager to select version 1.0.9 of this library.")); 102 | } 103 | else 104 | { 105 | Serial.print(F("Your Platform ID is: 0x")); 106 | Serial.println(platformID, HEX); 107 | } 108 | 109 | // Read and print the ARTIC R2 firmware status 110 | ARTIC_R2_Firmware_Status status; 111 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 112 | Serial.println(F("ARTIC R2 Firmware Status:")); 113 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 114 | Serial.println(); 115 | 116 | // Read and print the ARGOS configuration 117 | ARGOS_Configuration_Register configuration; 118 | myARTIC.readARGOSconfiguration(&configuration); 119 | myARTIC.printARGOSconfiguration(configuration); // Pretty-print the TX and RX configuration to Serial 120 | 121 | // Set the TCXO voltage to 1.8V and autoDisable to 1 122 | if (myARTIC.setTCXOControl(1.8, true) == false) 123 | { 124 | Serial.println("setTCXOControl failed. Freezing..."); 125 | while (1) 126 | ; // Do nothing more 127 | } 128 | 129 | // Set the satellite detection timeout to 600 seconds 130 | if (myARTIC.setSatelliteDetectionTimeout(600) == false) 131 | { 132 | Serial.println("setSatelliteDetectionTimeout failed. Freezing..."); 133 | while (1) 134 | ; // Do nothing more 135 | } 136 | 137 | // Get the satellite detection timeout 138 | uint32_t detectionTimeout = myARTIC.readSatelliteDetectionTimeout(); 139 | Serial.print(F("The Satellite Detection Timeout is ")); 140 | Serial.print(detectionTimeout); 141 | Serial.println(F(" seconds.")); 142 | 143 | Serial.println(); 144 | Serial.println(F("Starting satellite detection...")); 145 | Serial.println(); 146 | 147 | // Start satellite detection 148 | // The ARTIC will start looking for a satellite for the specified amount of time. 149 | // If no satellite is detected, INT 2 will be set with the ‘SATELLITE_TIMEOUT’ flag. 150 | // If a satellite was detected, by receiving 5 consecutive 0x7E flags, INT 1 will be set with the ‘RX_SATELLITE_DETECTED’ flag. 151 | // sendMCUinstruction returns an ARTIC_R2_MCU_Command_Result 152 | // sendMCUinstruction will return ARTIC_R2_MCU_COMMAND_ACCEPTED if the instruction was accepted 153 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendMCUinstruction(INST_SATELLITE_DETECTION); 154 | 155 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 156 | Serial.println(F("ARTIC R2 Firmware Status:")); 157 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 158 | Serial.println(); 159 | Serial.println(F("ARTIC R2 MCU instruction result:")); 160 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 161 | Serial.println(); 162 | 163 | if ((result == ARTIC_R2_MCU_COMMAND_REJECTED) || (result == ARTIC_R2_MCU_COMMAND_OVERFLOW)) 164 | { 165 | Serial.println("MCU Command failed! Freezing..."); 166 | while (1) 167 | ; // Do nothing more 168 | } 169 | } 170 | 171 | void loop() 172 | { 173 | delay(1000); 174 | 175 | Serial.println(); 176 | 177 | // Read and print the ARTIC R2 status register 178 | ARTIC_R2_Firmware_Status status; 179 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 180 | Serial.println(F("ARTIC R2 Firmware Status:")); 181 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 182 | 183 | // Note: satellite detection does not time out once a satellite has been detected. The firmware goes IDLE instead. 184 | 185 | // Note: With ARTIC006 firmware: when satellite detection times out and INT2 goes high, INT1 goes high too! Confusing... 186 | // We should only believe INT1 if INT2 is low. 187 | 188 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT2) // Check the interrupt 2 flag. This will go high if satellite detection times out 189 | { 190 | Serial.println(F("INT2 pin is high. Satellite detection has timed out!")); 191 | } 192 | else if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when a satellite is detected 193 | { 194 | Serial.println(F("INT1 pin is high. Satellite detected!")); 195 | } 196 | 197 | Serial.println(); 198 | 199 | // Read and print the instruction progress 200 | ARTIC_R2_MCU_Instruction_Progress progress; 201 | // checkMCUinstructionProgress will return true if the instruction is complete 202 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 203 | Serial.println(F("ARTIC R2 instruction progress:")); 204 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 205 | 206 | if (instructionComplete) 207 | { 208 | Serial.println(); 209 | Serial.println(F("Satellite detection is complete! Freezing...")); 210 | while (1) 211 | ; // Do nothing more 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /examples/Example5_ReceiveOneMessage/Example5_ReceiveOneMessage.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the RX mode to ARGOS 3; 12 | sets the TCXO voltage; 13 | enables RX transparent mode (so we will receive the first valid message even if it is not addressed to us); 14 | instructs the ARTIC to Receive One Message (for an unlimited time); 15 | keeps checking the MCU status until a message is received. 16 | 17 | License: please see the license file at: 18 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 19 | 20 | Feel like supporting our work? Buy a board from SparkFun! 21 | https://www.sparkfun.com/products/17236 22 | 23 | Hardware Connections: 24 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 25 | https://www.sparkfun.com/products/15574 26 | CS_Pin = A5 (D24) 27 | GAIN8_Pin = D3 28 | BOOT_Pin = D4 29 | INT1_Pin = D5 30 | INT2_Pin = D6 31 | RESET_Pin = D7 32 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 33 | RF_PWR_EN_Pin = D9 34 | (SPI COPI = D11) 35 | (SPI CIPO = D12) 36 | (SPI SCK = D13) 37 | 38 | If you are using IOTA, uncomment the #define IOTA below. 39 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 40 | 41 | */ 42 | 43 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 44 | 45 | #include 46 | 47 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 48 | ARTIC_R2 myARTIC; 49 | 50 | // Pin assignments for the SparkFun Thing Plus - Artemis 51 | // (Change these if required) 52 | int CS_Pin = 24; 53 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 54 | int BOOT_Pin = 4; 55 | int INT1_Pin = 5; 56 | int INT2_Pin = 6; 57 | int RESET_Pin = 7; 58 | #ifdef IOTA 59 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 60 | #else 61 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 62 | int RF_PWR_EN_Pin = 9; 63 | #endif 64 | 65 | void setup() 66 | { 67 | Serial.begin(115200); 68 | Serial.println(); 69 | Serial.println(F("ARGOS ARTIC R2 Example")); 70 | Serial.println(); 71 | 72 | Serial.println(F("ARTIC R2 is booting...")); 73 | Serial.println(); 74 | 75 | SPI.begin(); 76 | 77 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 78 | 79 | // Begin the ARTIC: enable power and upload firmware or boot from flash 80 | #ifdef IOTA 81 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 82 | #else 83 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 84 | #endif 85 | { 86 | Serial.println("ARTIC R2 not detected. Freezing..."); 87 | while (1) 88 | ; // Do nothing more 89 | } 90 | 91 | Serial.println(F("ARTIC R2 boot was successful.")); 92 | Serial.println(); 93 | 94 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 95 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 96 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 97 | // earlier versions of the board will need to use version 1.0.9 of the library. 98 | uint32_t platformID = myARTIC.readPlatformID(); 99 | if (platformID == 0) 100 | { 101 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 102 | Serial.println(F("For the transmit examples, you will need to use the Library Manager to select version 1.0.9 of this library.")); 103 | } 104 | else 105 | { 106 | Serial.print(F("Your Platform ID is: 0x")); 107 | Serial.println(platformID, HEX); 108 | } 109 | 110 | // Read and print the ARTIC R2 status register 111 | ARTIC_R2_Firmware_Status status; 112 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 113 | Serial.println(F("ARTIC R2 Firmware Status:")); 114 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 115 | Serial.println(); 116 | 117 | // Read and print the ARGOS configuration 118 | ARGOS_Configuration_Register configuration; 119 | myARTIC.readARGOSconfiguration(&configuration); 120 | myARTIC.printARGOSconfiguration(configuration); // Pretty-print the TX and RX configuration to Serial 121 | 122 | Serial.println(F("Setting the RX mode to ARGOS 3...")); 123 | 124 | // Set the RX mode to ARGOS 3 125 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_ARGOS_3_RX_MODE); 126 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 127 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 128 | { 129 | Serial.println("sendConfigurationCommand failed. Freezing..."); 130 | while (1) 131 | ; // Do nothing more 132 | } 133 | 134 | // Read and print the ARGOS configuration 135 | myARTIC.readARGOSconfiguration(&configuration); 136 | myARTIC.printARGOSconfiguration(configuration); 137 | 138 | // Set the TCXO voltage to 1.8V and autoDisable to 1 139 | if (myARTIC.setTCXOControl(1.8, true) == false) 140 | { 141 | Serial.println("setTCXOControl failed. Freezing..."); 142 | while (1) 143 | ; // Do nothing more 144 | } 145 | 146 | // Enable RX transparent mode so we will receive the first valid message even if it is not addressed to us 147 | if (myARTIC.enableRXTransparentMode() == false) 148 | { 149 | Serial.println(F("enableRXTransparentMode failed! Freezing...")); 150 | while (1) 151 | ; // Do nothing more 152 | } 153 | 154 | Serial.println(); 155 | Serial.println(F("Starting message reception...")); 156 | Serial.println(); 157 | 158 | // Start the ARTIC in receiving mode for an unlimited time until 1 message has been received. 159 | // If the message is received the Artic will go to IDLE. The user can abort the reception using the ‘Go to idle’ command. 160 | result = myARTIC.sendMCUinstruction(INST_START_RECEIVING_1_MESSAGE); 161 | 162 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 163 | Serial.println(F("ARTIC R2 Firmware Status:")); 164 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 165 | Serial.println(); 166 | Serial.println(F("ARTIC R2 MCU instruction result:")); 167 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 168 | Serial.println(); 169 | 170 | if ((result == ARTIC_R2_MCU_COMMAND_REJECTED) || (result == ARTIC_R2_MCU_COMMAND_OVERFLOW)) 171 | { 172 | Serial.println("MCU Command failed! Freezing..."); 173 | while (1) 174 | ; // Do nothing more 175 | } 176 | } 177 | 178 | void loop() 179 | { 180 | delay(1000); 181 | 182 | Serial.println(); 183 | 184 | // Read and print the ARTIC R2 status register 185 | ARTIC_R2_Firmware_Status status; 186 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 187 | Serial.println(F("ARTIC R2 Firmware Status:")); 188 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 189 | 190 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when a satellite is detected 191 | { 192 | Serial.println(F("INT1 pin is high. Valid message received!")); 193 | } 194 | 195 | Serial.println(); 196 | 197 | // Read and print the instruction progress 198 | ARTIC_R2_MCU_Instruction_Progress progress; 199 | // checkMCUinstructionProgress will return true if the instruction is complete 200 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 201 | Serial.println(F("ARTIC R2 instruction progress:")); 202 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 203 | 204 | if (instructionComplete) 205 | { 206 | Serial.println(); 207 | Serial.println(F("Message reception is complete!")); 208 | Serial.println(); 209 | 210 | if (progress == ARTIC_R2_MCU_PROGRESS_RECEIVE_ONE_MESSAGE_RX_VALID_MESSAGE) // If a message was received, read it. 211 | { 212 | // Read a downlink message from the RX payload buffer 213 | Downlink_Message downlinkMessage; 214 | if (myARTIC.readDownlinkMessage(&downlinkMessage)) 215 | { 216 | Serial.println(F("Message received:")); 217 | Serial.printf("Payload length: %d\n", downlinkMessage.payloadLength); 218 | Serial.printf("Addressee ID: 0x%07X\n", downlinkMessage.addresseeIdentification); 219 | Serial.printf("ADCS: 0x%X\n", downlinkMessage.ADCS); 220 | Serial.printf("Service: 0x%02X\n", downlinkMessage.service); 221 | Serial.printf("FCS: 0x%04X\n", downlinkMessage.FCS); 222 | Serial.print(F("Payload buffer: 0x")); 223 | for (int i = 0; i < ((downlinkMessage.payloadLength / 8) - 7); i++) 224 | { 225 | Serial.printf("%02X", downlinkMessage.payload[i]); 226 | } 227 | Serial.println(); 228 | } 229 | else 230 | { 231 | Serial.println(F("readDownlinkMessage failed!")); 232 | } 233 | } 234 | 235 | Serial.println(); 236 | Serial.println(F("We are done. Freezing...")); 237 | while (1) 238 | ; // Do nothing more 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /examples/Example6_ReceiveOneMessageWithFiltering/Example6_ReceiveOneMessageWithFiltering.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the RX mode to ARGOS 3; 12 | sets the TCXO voltage; 13 | adds the platform ID to the address Look Up Table (LUT); 14 | disables RX transparent mode; 15 | enables the RX CRC check (even though this is enabled by default); 16 | instructs the ARTIC to Receive One Message (for an unlimited time); 17 | keeps checking the MCU status until a message is received. 18 | 19 | License: please see the license file at: 20 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 21 | 22 | Feel like supporting our work? Buy a board from SparkFun! 23 | https://www.sparkfun.com/products/17236 24 | 25 | This example requires a Platform ID. Copy and paste your 28-bit Platform ID into ADDRESS_LS_BITS and ADDRESS_MS_BITS. (See below) 26 | 27 | Hardware Connections: 28 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 29 | https://www.sparkfun.com/products/15574 30 | CS_Pin = A5 (D24) 31 | GAIN8_Pin = D3 32 | BOOT_Pin = D4 33 | INT1_Pin = D5 34 | INT2_Pin = D6 35 | RESET_Pin = D7 36 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 37 | RF_PWR_EN_Pin = D9 38 | (SPI COPI = D11) 39 | (SPI CIPO = D12) 40 | (SPI SCK = D13) 41 | 42 | If you are using IOTA, uncomment the #define IOTA below. 43 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 44 | 45 | */ 46 | 47 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 48 | 49 | // CLS will have provided you with a Platform ID for your ARGOS R2. Copy and paste it into PLATFORM_ID below to filter out all other messages. 50 | // E.g.: if your Platform ID is 01:23:AB:CD then set PLATFORM_ID to 0x0123ABCD 51 | const uint32_t PLATFORM_ID = 0x00000000; // Update this with your Platform ID 52 | 53 | #include 54 | 55 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 56 | ARTIC_R2 myARTIC; 57 | 58 | // Pin assignments for the SparkFun Thing Plus - Artemis 59 | // (Change these if required) 60 | int CS_Pin = 24; 61 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 62 | int BOOT_Pin = 4; 63 | int INT1_Pin = 5; 64 | int INT2_Pin = 6; 65 | int RESET_Pin = 7; 66 | #ifdef IOTA 67 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 68 | #else 69 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 70 | int RF_PWR_EN_Pin = 9; 71 | #endif 72 | 73 | void setup() 74 | { 75 | Serial.begin(115200); 76 | Serial.println(); 77 | Serial.println(F("ARGOS ARTIC R2 Example")); 78 | Serial.println(); 79 | 80 | Serial.println(F("ARTIC R2 is booting...")); 81 | Serial.println(); 82 | 83 | SPI.begin(); 84 | 85 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 86 | 87 | // Begin the ARTIC: enable power and upload firmware or boot from flash 88 | #ifdef IOTA 89 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 90 | #else 91 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 92 | #endif 93 | { 94 | Serial.println("ARTIC R2 not detected. Freezing..."); 95 | while (1) 96 | ; // Do nothing more 97 | } 98 | 99 | Serial.println(F("ARTIC R2 boot was successful.")); 100 | Serial.println(); 101 | 102 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 103 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 104 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 105 | // earlier versions of the board will need to use version 1.0.9 of the library. 106 | uint32_t platformID = myARTIC.readPlatformID(); 107 | if (platformID == 0) 108 | { 109 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 110 | Serial.println(F("For the transmit examples, you will need to use the Library Manager to select version 1.0.9 of this library.")); 111 | } 112 | else 113 | { 114 | Serial.print(F("Your Platform ID is: 0x")); 115 | Serial.println(platformID, HEX); 116 | } 117 | 118 | // Read and print the ARTIC R2 status register 119 | ARTIC_R2_Firmware_Status status; 120 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 121 | Serial.println(F("ARTIC R2 Firmware Status:")); 122 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 123 | Serial.println(); 124 | 125 | // Read and print the ARGOS configuration 126 | ARGOS_Configuration_Register configuration; 127 | myARTIC.readARGOSconfiguration(&configuration); 128 | myARTIC.printARGOSconfiguration(configuration); // Pretty-print the TX and RX configuration to Serial 129 | 130 | Serial.println(F("Setting the RX mode to ARGOS 3...")); 131 | 132 | // Set the RX mode to ARGOS 3 133 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_ARGOS_3_RX_MODE); 134 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 135 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 136 | { 137 | Serial.println("sendConfigurationCommand failed. Freezing..."); 138 | while (1) 139 | ; // Do nothing more 140 | } 141 | 142 | // Read and print the ARGOS configuration 143 | myARTIC.readARGOSconfiguration(&configuration); 144 | myARTIC.printARGOSconfiguration(configuration); 145 | Serial.println(); 146 | 147 | // Set the TCXO voltage to 1.8V and autoDisable to 1 148 | if (myARTIC.setTCXOControl(1.8, true) == false) 149 | { 150 | Serial.println("setTCXOControl failed. Freezing..."); 151 | while (1) 152 | ; // Do nothing more 153 | } 154 | 155 | // Add our address (platform ID) to the LUT. 156 | // You can add multiple addresses if required, up to a maximum of 50. 157 | // Add an additional address by calling addAddressToLUT again. 158 | // addAddressToLUT will return false if the LUT is full. 159 | // You can clear the LUT by calling clearAddressLUT. 160 | if (myARTIC.addAddressToLUT(PLATFORM_ID) == false) 161 | { 162 | Serial.println(F("addAddressToLUT failed! Freezing...")); 163 | while (1) 164 | ; // Do nothing more 165 | } 166 | 167 | // Check that our platform ID was added correctly 168 | uint32_t tableEntry; 169 | if (myARTIC.readAddressLUTentry(0, &tableEntry) == false) 170 | { 171 | Serial.println(F("readAddressLUTentry failed! Freezing...")); 172 | while (1) 173 | ; // Do nothing more 174 | } 175 | Serial.print(F("Address Look Up Table entry 0 is 0x")); 176 | Serial.println(tableEntry, HEX); 177 | Serial.println(); 178 | if (tableEntry != PLATFORM_ID) 179 | { 180 | Serial.println(F("Platform ID mismatch! Freezing...")); 181 | while (1) 182 | ; // Do nothing more 183 | } 184 | 185 | // Disable RX transparent mode so we will only receive messages addressed to us 186 | // (transparent mode is disabled by default) 187 | if (myARTIC.disableRXTransparentMode() == false) 188 | { 189 | Serial.println(F("disableRXTransparentMode failed! Freezing...")); 190 | while (1) 191 | ; // Do nothing more 192 | } 193 | 194 | // Enable the RX CRC check (even though this is enabled by default) 195 | if (myARTIC.enableRXCRC() == false) 196 | { 197 | Serial.println(F("enableRXCRC failed! Freezing...")); 198 | while (1) 199 | ; // Do nothing more 200 | } 201 | 202 | Serial.println(F("Starting message reception...")); 203 | Serial.println(); 204 | 205 | // Start the ARTIC in receiving mode for an unlimited time until 1 message has been received. 206 | // If the message is received the Artic will go to IDLE. The user can abort the reception using the ‘Go to idle’ command. 207 | result = myARTIC.sendMCUinstruction(INST_START_RECEIVING_1_MESSAGE); 208 | 209 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 210 | Serial.println(F("ARTIC R2 Firmware Status:")); 211 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 212 | Serial.println(); 213 | Serial.println(F("ARTIC R2 MCU instruction result:")); 214 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 215 | 216 | if ((result == ARTIC_R2_MCU_COMMAND_REJECTED) || (result == ARTIC_R2_MCU_COMMAND_OVERFLOW)) 217 | { 218 | Serial.println("MCU Command failed! Freezing..."); 219 | while (1) 220 | ; // Do nothing more 221 | } 222 | } 223 | 224 | void loop() 225 | { 226 | delay(1000); 227 | 228 | Serial.println(); 229 | 230 | // Read and print the ARTIC R2 status register 231 | ARTIC_R2_Firmware_Status status; 232 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 233 | Serial.println(F("ARTIC R2 Firmware Status:")); 234 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 235 | 236 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when a satellite is detected 237 | { 238 | Serial.println(F("INT1 pin is high. Valid message received!")); 239 | } 240 | 241 | Serial.println(); 242 | 243 | // Read and print the instruction progress 244 | ARTIC_R2_MCU_Instruction_Progress progress; 245 | // checkMCUinstructionProgress will return true if the instruction is complete 246 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 247 | Serial.println(F("ARTIC R2 instruction progress:")); 248 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 249 | 250 | if (instructionComplete) 251 | { 252 | Serial.println(); 253 | Serial.println(F("Message reception is complete!")); 254 | Serial.println(); 255 | 256 | if (progress == ARTIC_R2_MCU_PROGRESS_RECEIVE_ONE_MESSAGE_RX_VALID_MESSAGE) // If a message was received, read it. 257 | { 258 | // Read a downlink message from the RX payload buffer 259 | Downlink_Message downlinkMessage; 260 | if (myARTIC.readDownlinkMessage(&downlinkMessage)) 261 | { 262 | Serial.println(F("Message received:")); 263 | Serial.printf("Payload length: %d\n", downlinkMessage.payloadLength); 264 | Serial.printf("Addressee ID: 0x%07X\n", downlinkMessage.addresseeIdentification); 265 | Serial.printf("ADCS: 0x%X\n", downlinkMessage.ADCS); 266 | Serial.printf("Service: 0x%02X\n", downlinkMessage.service); 267 | Serial.printf("FCS: 0x%04X\n", downlinkMessage.FCS); 268 | Serial.print(F("Payload buffer: 0x")); 269 | for (int i = 0; i < ((downlinkMessage.payloadLength / 8) - 7); i++) 270 | { 271 | Serial.printf("%02X", downlinkMessage.payload[i]); 272 | } 273 | Serial.println(); 274 | } 275 | else 276 | { 277 | Serial.println(F("readDownlinkMessage failed!")); 278 | } 279 | } 280 | 281 | Serial.println(); 282 | Serial.println(F("We are done. Freezing...")); 283 | while (1) 284 | ; // Do nothing more 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /examples/Example7_ContinuousReceiveWithAOPParsing/Example7_ContinuousReceiveWithAOPParsing.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the RX mode to ARGOS 3; 12 | sets the TCXO voltage; 13 | enables RX transparent mode (so we will receive all valid messages even if they are not addressed to us); 14 | instructs the ARTIC to Start Continuous Reception; 15 | keeps checking the MCU status; 16 | downloads messages as they are received; 17 | clears INT1 each time a message is downloaded. 18 | LED_BUILTIN will illuminate when a satellite is detected. 19 | Messages are parsed for UTC time and AOP data. 20 | 21 | License: please see the license file at: 22 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 23 | 24 | Feel like supporting our work? Buy a board from SparkFun! 25 | https://www.sparkfun.com/products/17236 26 | 27 | Hardware Connections: 28 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 29 | https://www.sparkfun.com/products/15574 30 | CS_Pin = A5 (D24) 31 | GAIN8_Pin = D3 32 | BOOT_Pin = D4 33 | INT1_Pin = D5 34 | INT2_Pin = D6 35 | RESET_Pin = D7 36 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 37 | RF_PWR_EN_Pin = D9 38 | (SPI COPI = D11) 39 | (SPI CIPO = D12) 40 | (SPI SCK = D13) 41 | 42 | If you are using IOTA, uncomment the #define IOTA below. 43 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 44 | 45 | */ 46 | 47 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 48 | 49 | #include 50 | 51 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 52 | ARTIC_R2 myARTIC; 53 | 54 | // Pin assignments for the SparkFun Thing Plus - Artemis 55 | // (Change these if required) 56 | int CS_Pin = 24; 57 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 58 | int BOOT_Pin = 4; 59 | int INT1_Pin = 5; 60 | int INT2_Pin = 6; 61 | int RESET_Pin = 7; 62 | #ifdef IOTA 63 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 64 | #else 65 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 66 | int RF_PWR_EN_Pin = 9; 67 | #endif 68 | 69 | void setup() 70 | { 71 | pinMode(LED_BUILTIN, OUTPUT); // Turn the LED off 72 | digitalWrite(LED_BUILTIN, LOW); 73 | 74 | Serial.begin(115200); 75 | Serial.println(); 76 | Serial.println(F("ARGOS ARTIC R2 Example")); 77 | Serial.println(); 78 | 79 | Serial.println(F("ARTIC R2 is booting...")); 80 | Serial.println(); 81 | 82 | SPI.begin(); 83 | 84 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 85 | 86 | // Begin the ARTIC: enable power and upload firmware or boot from flash 87 | #ifdef IOTA 88 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 89 | #else 90 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 91 | #endif 92 | { 93 | Serial.println("ARTIC R2 not detected. Freezing..."); 94 | while (1) 95 | ; // Do nothing more 96 | } 97 | 98 | Serial.println(F("ARTIC R2 boot was successful.")); 99 | Serial.println(); 100 | 101 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 102 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 103 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 104 | // earlier versions of the board will need to use version 1.0.9 of the library. 105 | uint32_t platformID = myARTIC.readPlatformID(); 106 | if (platformID == 0) 107 | { 108 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 109 | Serial.println(F("For the transmit examples, you will need to use the Library Manager to select version 1.0.9 of this library.")); 110 | } 111 | else 112 | { 113 | Serial.print(F("Your Platform ID is: 0x")); 114 | Serial.println(platformID, HEX); 115 | } 116 | 117 | // Read the ARTIC R2 status register 118 | ARTIC_R2_Firmware_Status status; 119 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 120 | Serial.println(F("ARTIC R2 Firmware Status:")); 121 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 122 | Serial.println(); 123 | 124 | // Read and print the ARGOS configuration 125 | ARGOS_Configuration_Register configuration; 126 | myARTIC.readARGOSconfiguration(&configuration); 127 | myARTIC.printARGOSconfiguration(configuration); // Pretty-print the TX and RX configuration to Serial 128 | 129 | Serial.println(F("Setting the RX mode to ARGOS 3...")); 130 | 131 | // Set the RX mode to ARGOS 3 132 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_ARGOS_3_RX_MODE); 133 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 134 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 135 | { 136 | Serial.println("sendConfigurationCommand failed. Freezing..."); 137 | while (1) 138 | ; // Do nothing more 139 | } 140 | 141 | // Read and print the ARGOS configuration 142 | myARTIC.readARGOSconfiguration(&configuration); 143 | myARTIC.printARGOSconfiguration(configuration); 144 | 145 | // Set the TCXO voltage to 1.8V and autoDisable to 1 146 | if (myARTIC.setTCXOControl(1.8, true) == false) 147 | { 148 | Serial.println("setTCXOControl failed. Freezing..."); 149 | while (1) 150 | ; // Do nothing more 151 | } 152 | 153 | // Enable RX transparent mode so we will receive all valid messages even if they are not addressed to us 154 | if (myARTIC.enableRXTransparentMode() == false) 155 | { 156 | Serial.println(F("enableRXTransparentMode failed! Freezing...")); 157 | while (1) 158 | ; // Do nothing more 159 | } 160 | 161 | Serial.println(); 162 | Serial.println(F("Starting message reception...")); 163 | Serial.println(); 164 | 165 | // Start the ARTIC in receiving mode for an unlimited time and unlimited number of messages. 166 | // The user has to use the 'Go To Idle' command to stop the receiver. 167 | result = myARTIC.sendMCUinstruction(INST_START_CONTINUOUS_RECEPTION); 168 | 169 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 170 | Serial.println(F("ARTIC R2 Firmware Status:")); 171 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 172 | Serial.println(); 173 | Serial.println(F("ARTIC R2 MCU instruction result:")); 174 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 175 | Serial.println(); 176 | 177 | if ((result == ARTIC_R2_MCU_COMMAND_REJECTED) || (result == ARTIC_R2_MCU_COMMAND_OVERFLOW)) 178 | { 179 | Serial.println("MCU Command failed! Freezing..."); 180 | while (1) 181 | ; // Do nothing more 182 | } 183 | } 184 | 185 | void loop() 186 | { 187 | delay(1000); 188 | 189 | // Read the ARTIC R2 status register 190 | ARTIC_R2_Firmware_Status status; 191 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 192 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when a satellite is detected 193 | { 194 | Serial.println(); 195 | Serial.println(F("Firmware status: INT1 flag is high. Valid message received!")); 196 | } 197 | 198 | // Illuminate the LED if a satellite is detected 199 | digitalWrite(LED_BUILTIN, status.STATUS_REGISTER_BITS.RX_SATELLITE_DETECTED); 200 | 201 | // Read the instruction progress 202 | ARTIC_R2_MCU_Instruction_Progress progress; 203 | myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 204 | 205 | // Check if there is a valid message waiting to be downloaded 206 | if (progress == ARTIC_R2_MCU_PROGRESS_CONTINUOUS_RECEPTION_RX_VALID_MESSAGE) 207 | { 208 | Serial.println(); 209 | Serial.println(F("Valid message received! Downloading...")); 210 | Serial.println(); 211 | 212 | // Read a downlink message from the RX payload buffer 213 | Downlink_Message downlinkMessage; 214 | if (myARTIC.readDownlinkMessage(&downlinkMessage)) 215 | { 216 | Serial.println(F("Message received:")); 217 | Serial.printf("Payload length: %d\n", downlinkMessage.payloadLength); 218 | Serial.printf("Addressee ID: 0x%07X\n", downlinkMessage.addresseeIdentification); 219 | Serial.printf("ADCS: 0x%X\n", downlinkMessage.ADCS); 220 | Serial.printf("Service: 0x%02X\n", downlinkMessage.service); 221 | Serial.printf("FCS: 0x%04X\n", downlinkMessage.FCS); 222 | Serial.print(F("Payload buffer: 0x")); 223 | for (int i = 0; i < ((downlinkMessage.payloadLength / 8) - 7); i++) 224 | { 225 | Serial.printf("%02X", downlinkMessage.payload[i]); 226 | } 227 | Serial.println(); 228 | 229 | // Parse for UTC allcast 230 | // Taken from KINEIS-MU-2019-0094 and AS3-SP-516-2095-CNES 231 | if ((downlinkMessage.addresseeIdentification == 0x00000E1) && (downlinkMessage.service == 0x08)) 232 | { 233 | Serial.print(F("UTC allcast received: Year=")); 234 | Serial.print(downlinkMessage.payload[0] >> 4); Serial.print(downlinkMessage.payload[0] & 0x0F); 235 | Serial.print(downlinkMessage.payload[1] >> 4); Serial.print(downlinkMessage.payload[1] & 0x0F); 236 | Serial.print(F(" Day of year=")); 237 | Serial.print(downlinkMessage.payload[2] >> 4); Serial.print(downlinkMessage.payload[2] & 0x0F); 238 | Serial.print(downlinkMessage.payload[3] >> 4); 239 | Serial.print(F(" Time=")); 240 | Serial.print(downlinkMessage.payload[3] & 0x0F); Serial.print(downlinkMessage.payload[4] >> 4); 241 | Serial.print(F(":")); 242 | Serial.print(downlinkMessage.payload[4] & 0x0F); Serial.print(downlinkMessage.payload[5] >> 4); 243 | Serial.print(F(":")); 244 | Serial.print(downlinkMessage.payload[5] & 0x0F); Serial.print(downlinkMessage.payload[6] >> 4); 245 | Serial.print(F(".")); 246 | Serial.print(downlinkMessage.payload[6] & 0x0F); Serial.print(downlinkMessage.payload[7] >> 4); 247 | Serial.println(downlinkMessage.payload[7] & 0x0F); 248 | } 249 | 250 | // Parse for AOP data 251 | // Taken from KINEIS-MU-2019-0094 and AS3-SP-516-2095-CNES 252 | if ((downlinkMessage.addresseeIdentification == 0x00000BE) && (downlinkMessage.service == 0x00)) 253 | { 254 | bulletin_data_t bulletin; // Assemble the data as a bulletin_data_t which could then be used for satellite pass prediction (see the later examples) 255 | 256 | Serial.print(F("Satellite orbit parameters received: Satellite ID=")); 257 | switch (downlinkMessage.payload[0] >> 4) 258 | { 259 | // The full list from KINEIS-MU-2019-0094 is as follows: 260 | // 0x1 CDARS 261 | // 0x2 OCEANSAT-3 262 | // 0x3 METOP-SG1B 263 | // 0x4 METOP-SG2B 264 | // 0x5 NOAA K 265 | // 0x6 ANGELS 266 | // 0x8 NOAA N 267 | // 0x9 METOP B 268 | // 0xA METOP A 269 | // 0xB METOP C 270 | // 0xC NOAA N' ( = NP) 271 | // 0xD SARAL 272 | 273 | // Process the 'known' satellites 274 | // The two character satellite identifiers are: 275 | // A1 : ANGELS 276 | // MA : METOP-A 277 | // MB : METOP-B 278 | // MC : METOP-C 279 | // NK : NOAA-15 (appears as 15 in the AOP) 280 | // NN : NOAA-18 (appears as 18 in the AOP) 281 | // NP : NOAA-19 (appears as 19 in the AOP) 282 | // SR : SARAL 283 | 284 | case 0x6: 285 | Serial.println(F("ANGELS")); 286 | bulletin.sat[0] = 'A'; bulletin.sat[1] = '1'; 287 | break; 288 | case 0xA: 289 | Serial.println(F("METOP-A")); 290 | bulletin.sat[0] = 'M'; bulletin.sat[1] = 'A'; 291 | break; 292 | case 0x9: 293 | Serial.println(F("METOP-B")); 294 | bulletin.sat[0] = 'M'; bulletin.sat[1] = 'B'; 295 | break; 296 | case 0xB: 297 | Serial.println(F("METOP-C")); 298 | bulletin.sat[0] = 'M'; bulletin.sat[1] = 'C'; 299 | break; 300 | case 0x5: 301 | Serial.println(F("NOAA K")); 302 | bulletin.sat[0] = '1'; bulletin.sat[1] = '5'; 303 | break; 304 | case 0x8: 305 | Serial.println(F("NOAA N")); 306 | bulletin.sat[0] = '1'; bulletin.sat[1] = '8'; 307 | break; 308 | case 0xC: 309 | Serial.println(F("NOAA N\'")); 310 | bulletin.sat[0] = '1'; bulletin.sat[1] = '9'; 311 | break; 312 | case 0xD: 313 | Serial.println(F("SARAL")); 314 | bulletin.sat[0] = 'S'; bulletin.sat[1] = 'R'; 315 | break; 316 | default: // We don't know the two character ID for the other satellites! 317 | Serial.print(F("0x")); 318 | Serial.println((downlinkMessage.payload[0] >> 4), HEX); 319 | bulletin.sat[0] = '?'; bulletin.sat[1] = '?'; 320 | break; 321 | } 322 | 323 | // Extract the date and time of the bulletin 324 | uint16_t year = 2000; 325 | year += (((downlinkMessage.payload[0] & 0x03) << 2) | (downlinkMessage.payload[1] >> 6)) * 10; 326 | year += ((downlinkMessage.payload[1] & 0x3C) >> 2); 327 | uint16_t day_of_year = (((downlinkMessage.payload[1] & 0x03) << 2) | (downlinkMessage.payload[2] >> 6)) * 100; 328 | day_of_year += ((downlinkMessage.payload[2] & 0x3C) >> 2) * 10; 329 | day_of_year += (((downlinkMessage.payload[2] & 0x03) << 2) | (downlinkMessage.payload[3] >> 6)); 330 | uint8_t hour = ((downlinkMessage.payload[3] & 0x3C) >> 2) * 10; 331 | hour += (((downlinkMessage.payload[3] & 0x03) << 2) | (downlinkMessage.payload[4] >> 6)); 332 | uint8_t minute = ((downlinkMessage.payload[4] & 0x3C) >> 2) * 10; 333 | minute += (((downlinkMessage.payload[4] & 0x03) << 2) | (downlinkMessage.payload[5] >> 6)); 334 | uint8_t second = ((downlinkMessage.payload[5] & 0x3C) >> 2) * 10; 335 | second += (((downlinkMessage.payload[5] & 0x03) << 2) | (downlinkMessage.payload[6] >> 6)); 336 | // Convert to seconds from the epoch - using Jan 1st 337 | uint32_t time_bulletin = myARTIC.convertGPSTimeToEpoch(year, 1, 1, hour, minute, second); 338 | time_bulletin += ((uint32_t)day_of_year - 1) * 24 * 60 * 60; // Now add the day of year (remembering that Jan 1st is day 1, not day 0) 339 | bulletin.time_bulletin = time_bulletin; // Store it 340 | 341 | // Extract the 19-bit ascending node longitude (deg) 342 | // Longitude of the ascending node : the ascending node (terrestrial ascending node) is the 343 | // point where the satellite ground track intersects the equatorial plane on the northbound crossing. 344 | uint32_t anl = (((uint32_t)(downlinkMessage.payload[6] & 0x3F)) << 13); 345 | anl |= ((uint32_t)downlinkMessage.payload[7]) << 5; 346 | anl |= ((uint32_t)downlinkMessage.payload[8]) >> 3; 347 | float anl_f = ((float)anl) / 1000; // Defined in AS3-SP-516-2095-CNES 348 | bulletin.params[2] = anl_f; // Store it 349 | 350 | // Extract the 10-bit ascending node longitude drift (deg) 351 | // Angular separation between two successive ascending nodes 352 | uint32_t anld = (((uint32_t)(downlinkMessage.payload[8] & 0x07)) << 7); 353 | anld |= ((uint32_t)downlinkMessage.payload[9]) >> 1; 354 | float anld_f = (((float)anld) / 1000) - 26; // Defined in AS3-SP-516-2095-CNES 355 | bulletin.params[3] = anld_f; // Store it 356 | 357 | // Extract the 14-bit orbital period (min) 358 | // Nodal period : elapsed time between two successive ascending node passes 359 | uint32_t op = (((uint32_t)(downlinkMessage.payload[9] & 0x01)) << 13); 360 | op |= ((uint32_t)downlinkMessage.payload[10]) << 5; 361 | op |= ((uint32_t)downlinkMessage.payload[11]) >> 3; 362 | float op_f = (((float)op) / 1000) + 95; // Defined in AS3-SP-516-2095-CNES 363 | bulletin.params[4] = op_f; // Store it 364 | 365 | // Extract the 19-bit semi-major axis (km) 366 | // Semi-major axis : distance from the apogee (point farthest from the earth) to the center of 367 | // the earth. 368 | // (ANGELS A1's orbit is less than 7000km! I guess ANGELS will need a new definition?) 369 | uint32_t sma = (((uint32_t)(downlinkMessage.payload[11] & 0x07)) << 16); 370 | sma |= ((uint32_t)downlinkMessage.payload[12]) << 8; 371 | sma |= ((uint32_t)downlinkMessage.payload[13]); 372 | float sma_f = (((float)sma) / 1000) + 7000; // Defined in AS3-SP-516-2095-CNES 373 | bulletin.params[0] = sma_f; // Store it 374 | 375 | // Extract the 8-bit semi-major axis drift (m/day) 376 | // Semi-major axis decay : semi-major axis first derivative 377 | uint32_t smad = ((uint32_t)(downlinkMessage.payload[14])); 378 | float smad_f = 0 - (((float)smad) / 10); // Defined in AS3-SP-516-2095-CNES 379 | bulletin.params[5] = smad_f; // Store it 380 | 381 | // Extract the 16-bit orbit inclination (deg) 382 | // Inclination : angle between the plane of the satellite orbit and the earth's equatorial plane 383 | uint32_t oi = (((uint32_t)(downlinkMessage.payload[15])) << 8); 384 | oi |= ((uint32_t)downlinkMessage.payload[16]); 385 | float oi_f = (((float)oi) / 10000) + 97; // Defined in AS3-SP-516-2095-CNES 386 | bulletin.params[1] = oi_f; // Store it 387 | 388 | // Pretty-print the bulletin to Serial 389 | myARTIC.printAOPbulletin(bulletin); 390 | } 391 | } 392 | else 393 | { 394 | Serial.println(F("readDownlinkMessage failed!")); 395 | } 396 | 397 | // Manually clear INT1 now that the message has been downloaded. This will clear the RX_VALID_MESSAGE flag too. 398 | // *** INT1 will go high again after 100us if there is another message to be read (which could cause clearInterrupts to return false) *** 399 | Serial.println(); 400 | Serial.println(F("Clearing INT1.")); 401 | if (myARTIC.clearInterrupts(1) == false) 402 | { 403 | Serial.println("clearInterrupts may have failed!"); 404 | } 405 | } 406 | } 407 | -------------------------------------------------------------------------------- /examples/Example8_ContinuousReceiveWithAbort/Example8_ContinuousReceiveWithAbort.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun ARGOS ARTIC R2 Breakout & IOTA 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: June 8th 2021 6 | 7 | This example: 8 | begins (initializes) the ARTIC; 9 | reads and prints the ARTIC TX and RX configuration; 10 | reads and prints the firmware status; 11 | sets the RX mode to ARGOS 3; 12 | sets the TCXO voltage; 13 | enables RX transparent mode (so we will receive all valid messages even if they are not addressed to us); 14 | instructs the ARTIC to Start Continuous Reception; 15 | keeps checking the MCU status; 16 | downloads messages as they are received; 17 | clears INT1 each time a message is downloaded; 18 | after GO_IDLE_AFTER milliseconds, the ARTIC is instructed to Go To Idle (which aborts continuous reception). 19 | 20 | License: please see the license file at: 21 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 22 | 23 | Feel like supporting our work? Buy a board from SparkFun! 24 | https://www.sparkfun.com/products/17236 25 | 26 | Hardware Connections: 27 | This example assumes the ARTIC Breakout has been mounted on a SparkFun Thing Plus - Artemis: 28 | https://www.sparkfun.com/products/15574 29 | CS_Pin = A5 (D24) 30 | GAIN8_Pin = D3 31 | BOOT_Pin = D4 32 | INT1_Pin = D5 33 | INT2_Pin = D6 34 | RESET_Pin = D7 35 | ARTIC_PWR_EN_Pin = IOTA_PWR_EN_Pin = D8 36 | RF_PWR_EN_Pin = D9 37 | (SPI COPI = D11) 38 | (SPI CIPO = D12) 39 | (SPI SCK = D13) 40 | 41 | If you are using IOTA, uncomment the #define IOTA below. 42 | IOTA only has one power enable pin. Uncommenting the #define IOTA will let the code run correctly on IOTA. 43 | 44 | */ 45 | 46 | //#define IOTA // Uncomment this line if you are using IOTA (not the ARTIC R2 Breakout) 47 | 48 | #define GO_IDLE_AFTER 120000 // Abort receive (go idle) after this many milliseconds (120000 = 2 mins) 49 | 50 | boolean goToIdleSent = false; // Use this flag to make sure we only send Go To Idle once 51 | 52 | #include 53 | 54 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 55 | ARTIC_R2 myARTIC; 56 | 57 | // Pin assignments for the SparkFun Thing Plus - Artemis 58 | // (Change these if required) 59 | int CS_Pin = 24; 60 | int GAIN8_Pin = 3; // Optional. Set to -1 if you don't want to control the gain. The library defaults to maximum power. 61 | int BOOT_Pin = 4; 62 | int INT1_Pin = 5; 63 | int INT2_Pin = 6; 64 | int RESET_Pin = 7; 65 | #ifdef IOTA 66 | int IOTA_PWR_EN_Pin = 8; // IOTA has a single power enable pin 67 | #else 68 | int ARTIC_PWR_EN_Pin = 8; // The ARTIC R2 Breakout has separate enables for the ARTIC and the RF Amplifier 69 | int RF_PWR_EN_Pin = 9; 70 | #endif 71 | 72 | void setup() 73 | { 74 | Serial.begin(115200); 75 | Serial.println(); 76 | Serial.println(F("ARGOS ARTIC R2 Example")); 77 | Serial.println(); 78 | 79 | Serial.println(F("ARTIC R2 is booting...")); 80 | Serial.println(); 81 | 82 | SPI.begin(); 83 | 84 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 85 | 86 | // Begin the ARTIC: enable power and upload firmware or boot from flash 87 | #ifdef IOTA 88 | if (myARTIC.beginIOTA(CS_Pin, RESET_Pin, BOOT_Pin, IOTA_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 89 | #else 90 | if (myARTIC.begin(CS_Pin, RESET_Pin, BOOT_Pin, ARTIC_PWR_EN_Pin, RF_PWR_EN_Pin, INT1_Pin, INT2_Pin, GAIN8_Pin) == false) 91 | #endif 92 | { 93 | Serial.println("ARTIC R2 not detected. Freezing..."); 94 | while (1) 95 | ; // Do nothing more 96 | } 97 | 98 | Serial.println(F("ARTIC R2 boot was successful.")); 99 | Serial.println(); 100 | 101 | // From v1.1.0: we were instructed by Kineis to ensure the Platform ID was written into each module 102 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 103 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 104 | // earlier versions of the board will need to use version 1.0.9 of the library. 105 | uint32_t platformID = myARTIC.readPlatformID(); 106 | if (platformID == 0) 107 | { 108 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 109 | Serial.println(F("For the transmit examples, you will need to use the Library Manager to select version 1.0.9 of this library.")); 110 | } 111 | else 112 | { 113 | Serial.print(F("Your Platform ID is: 0x")); 114 | Serial.println(platformID, HEX); 115 | } 116 | 117 | // Read and print the ARTIC R2 status register 118 | ARTIC_R2_Firmware_Status status; 119 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 120 | Serial.println(F("ARTIC R2 Firmware Status:")); 121 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 122 | Serial.println(); 123 | 124 | // Read and print the ARGOS configuration 125 | ARGOS_Configuration_Register configuration; 126 | myARTIC.readARGOSconfiguration(&configuration); 127 | myARTIC.printARGOSconfiguration(configuration); // Pretty-print the TX and RX configuration to Serial 128 | 129 | Serial.println(F("Setting the RX mode to ARGOS 3...")); 130 | 131 | // Set the RX mode to ARGOS 3 132 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_ARGOS_3_RX_MODE); 133 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 134 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 135 | { 136 | Serial.println("sendConfigurationCommand failed. Freezing..."); 137 | while (1) 138 | ; // Do nothing more 139 | } 140 | 141 | // Read and print the ARGOS configuration 142 | myARTIC.readARGOSconfiguration(&configuration); 143 | myARTIC.printARGOSconfiguration(configuration); 144 | 145 | // Set the TCXO voltage to 1.8V and autoDisable to 1 146 | if (myARTIC.setTCXOControl(1.8, true) == false) 147 | { 148 | Serial.println("setTCXOControl failed. Freezing..."); 149 | while (1) 150 | ; // Do nothing more 151 | } 152 | 153 | // Enable RX transparent mode so we will receive all valid messages even if they are not addressed to us 154 | if (myARTIC.enableRXTransparentMode() == false) 155 | { 156 | Serial.println(F("enableRXTransparentMode failed! Freezing...")); 157 | while (1) 158 | ; // Do nothing more 159 | } 160 | 161 | Serial.println(); 162 | Serial.println(F("Starting message reception...")); 163 | Serial.println(); 164 | 165 | // Start the ARTIC in receiving mode for an unlimited time and unlimited number of messages. 166 | // The user has to use the 'Go To Idle' command to stop the receiver. 167 | result = myARTIC.sendMCUinstruction(INST_START_CONTINUOUS_RECEPTION); 168 | 169 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 170 | Serial.println(F("ARTIC R2 Firmware Status:")); 171 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 172 | Serial.println(); 173 | Serial.println(F("ARTIC R2 MCU instruction result:")); 174 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 175 | Serial.println(); 176 | 177 | if ((result == ARTIC_R2_MCU_COMMAND_REJECTED) || (result == ARTIC_R2_MCU_COMMAND_OVERFLOW)) 178 | { 179 | Serial.println("MCU Command failed! Freezing..."); 180 | while (1) 181 | ; // Do nothing more 182 | } 183 | 184 | goToIdleSent = false; // Make sure goToIdleSent is false (redundant!) 185 | } 186 | 187 | void loop() 188 | { 189 | delay(5000); 190 | 191 | Serial.println(); 192 | 193 | // Read and print the ARTIC R2 status register 194 | ARTIC_R2_Firmware_Status status; 195 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 196 | Serial.println(F("ARTIC R2 Firmware Status:")); 197 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 198 | 199 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when a message is received - or Go To Idle is complete. 200 | { 201 | Serial.println(F("INT1 pin is high.")); 202 | } 203 | 204 | Serial.println(); 205 | 206 | // Read and print the instruction progress 207 | ARTIC_R2_MCU_Instruction_Progress progress; 208 | // checkMCUinstructionProgress will return true if the instruction is complete 209 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 210 | Serial.println(F("ARTIC R2 instruction progress:")); 211 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 212 | 213 | // Check if there is a valid message waiting to be downloaded 214 | if (progress == ARTIC_R2_MCU_PROGRESS_CONTINUOUS_RECEPTION_RX_VALID_MESSAGE) 215 | { 216 | Serial.println(); 217 | Serial.println(F("Valid message received! Downloading...")); 218 | Serial.println(); 219 | 220 | // Read a downlink message from the RX payload buffer 221 | Downlink_Message downlinkMessage; 222 | if (myARTIC.readDownlinkMessage(&downlinkMessage)) 223 | { 224 | Serial.println(F("Message received:")); 225 | Serial.printf("Payload length: %d\n", downlinkMessage.payloadLength); 226 | Serial.printf("Addressee ID: 0x%07X\n", downlinkMessage.addresseeIdentification); 227 | Serial.printf("ADCS: 0x%X\n", downlinkMessage.ADCS); 228 | Serial.printf("Service: 0x%02X\n", downlinkMessage.service); 229 | Serial.printf("FCS: 0x%04X\n", downlinkMessage.FCS); 230 | Serial.print(F("Payload buffer: 0x")); 231 | for (int i = 0; i < ((downlinkMessage.payloadLength / 8) - 7); i++) 232 | { 233 | Serial.printf("%02X", downlinkMessage.payload[i]); 234 | } 235 | Serial.println(); 236 | } 237 | else 238 | { 239 | Serial.println(F("readDownlinkMessage failed!")); 240 | } 241 | 242 | // Manually clear INT1 now that the message has been downloaded. This will clear the RX_VALID_MESSAGE flag too. 243 | // *** INT1 will go high again after 100us if there is another message to be read (which could cause clearInterrupts to return false) *** 244 | Serial.println(F("Clearing INT1.")); 245 | Serial.println(); 246 | if (myARTIC.clearInterrupts(1) == false) 247 | { 248 | Serial.println("clearInterrupts may have failed!"); 249 | } 250 | } 251 | 252 | // Check if it is time to abort reception and Go To Idle 253 | if ((goToIdleSent == false) and (millis() > GO_IDLE_AFTER)) 254 | { 255 | Serial.println(); 256 | Serial.println(F("Time to stop receiving! Sending Go To Idle...")); 257 | Serial.println(); 258 | 259 | // Tell the ARTIC to return to idle mode. 260 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendMCUinstruction(INST_GO_TO_IDLE); 261 | 262 | if ((result == ARTIC_R2_MCU_COMMAND_REJECTED) || (result == ARTIC_R2_MCU_COMMAND_OVERFLOW)) 263 | { 264 | Serial.println("MCU Command failed!"); 265 | Serial.println(); 266 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 267 | Serial.println(F("ARTIC R2 Firmware Status:")); 268 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 269 | Serial.println(); 270 | Serial.println(F("ARTIC R2 MCU Command Result:")); 271 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 272 | Serial.println(); 273 | Serial.println("Freezing..."); 274 | while (1) 275 | ; // Do nothing more 276 | } 277 | 278 | Serial.println(F("Go To Idle sent.")); 279 | Serial.println(); 280 | 281 | goToIdleSent = true; // Set goToIdleSent to true so we only Go To Idle once 282 | } 283 | 284 | // Check if Go To Idle is complete 285 | // (Continuous Reception never goes idle, so Go To Idle must have caused this) 286 | if (instructionComplete) 287 | { 288 | Serial.println(); 289 | Serial.println(F("Instruction (Go To Idle) is complete! Freezing...")); 290 | Serial.println(); 291 | 292 | while (1) 293 | ; // Do nothing more 294 | } 295 | } 296 | -------------------------------------------------------------------------------- /examples/Example9_TestJSONSatellitePassPredictor/ARTIC_R2_Allcast_Converter.py: -------------------------------------------------------------------------------- 1 | # This code converts the Satellite Allcast Info .txt file 2 | # into the correct format for ArduinoJson 3 | 4 | # All CR and LF characters are removed 5 | # All spaces are removed unless between quotes 6 | # All quotes (") are replaced with \" 7 | # A quote is added at the beginning and end of the file 8 | 9 | # Written by Paul Clark, March 6th 2021 10 | 11 | # License: please see the license file at: 12 | # https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 13 | 14 | import sys 15 | 16 | with open(sys.argv[1], "r") as reader: 17 | with open(sys.argv[2], "w") as writer: 18 | char = '"' 19 | writer.write(char) # Add " at the start of the file 20 | in_quotes = False 21 | while (char != ''): 22 | char = reader.read(1) # Read a single character 23 | if (char == ''): # Check for NULL (End Of File) 24 | break 25 | if (char == '"'): # Check for a quote 26 | in_quotes = not in_quotes # Toggle in_quotes 27 | writer.write('\\') # Always convert " into \" 28 | skip = False 29 | if ((char == ' ') and not in_quotes): # Skip spaces but not if in_quotes 30 | skip = True 31 | if ((char == '\r') or (char == '\n')): # Skip CR and LF 32 | skip = True 33 | if (not skip): 34 | writer.write(char) # Write the character if not skipping 35 | writer.write('"') # Add " at the end of the file 36 | -------------------------------------------------------------------------------- /examples/Example9_TestJSONSatellitePassPredictor/Example9_TestJSONSatellitePassPredictor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the ARGOS ARTIC R2 Breakout 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: March 6th 2021 6 | 7 | This example tests the satellite pass predictor using JSON-format Satellite Allcast Info. 8 | The predictor was originally written by CLS. 9 | This code is gratefully based on the version in Arribada Horizon. 10 | 11 | License: please see the license file at: 12 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 13 | 14 | Feel like supporting our work? Buy a board from SparkFun! 15 | https://www.sparkfun.com/products/17236 16 | 17 | You can download the Satellite Allcast Info from https://argos-system.cls.fr/argos-cwi2/login.html 18 | Select System \ Satellite Allcast Info and then click "Download Allcast" to download the orbit parameters etc. in JSON format. 19 | Use ARTIC_R2_Allcast_Converter.py to convert the format of the .txt file into a .h file which Arduino can compile: 20 | 21 | python ARTIC_R2_Allcast_Converter.py allcast_2021_03_06_13_27_618.txt allcast_2021_03_06_13_27_618.h 22 | 23 | Update the #include below with the name of your .h file. 24 | 25 | The JSON file is parsed (deserialized) by Benoit Blanchon's ArduinoJson library. Thank you Benoit. 26 | 27 | */ 28 | 29 | // Include the Allcast JSON Info. Update the filename as required: 30 | char allcast_JSON[] = { 31 | #include "allcast_2021_03_06_13_27_618.h" 32 | }; 33 | 34 | #include // Click here to get the library: http://librarymanager/All#ArduinoJson_deserialization 35 | 36 | StaticJsonDocument<3100> allcast; // Increase this if you see DeserializationError::NoMemory errors 37 | 38 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 39 | ARTIC_R2 myARTIC; 40 | 41 | void setup() 42 | { 43 | Serial.begin(115200); 44 | Serial.println(); 45 | Serial.println(F("ARGOS ARTIC R2 Example")); 46 | 47 | myARTIC.enableDebugging(); // Enable debug messages to Serial 48 | 49 | // Deserialize the JSON data 50 | DeserializationError error = deserializeJson(allcast, allcast_JSON); 51 | 52 | // Test if parsing succeeds. 53 | if (error) { 54 | Serial.print(F("deserializeJson() failed! Error: ")); 55 | Serial.print(error.f_str()); 56 | Serial.println(F(". Freezing...")); 57 | while (1) 58 | ; // Do nothing more 59 | } 60 | 61 | int numARGOSsatellites = extractNumSatellitesFromAllcast(); // Extract the number of satellites from the Allcast Info 62 | if (numARGOSsatellites == 0) // Check that the number of satellites is > 0 63 | { 64 | Serial.println("numARGOSsatellites is zero! Freezing..."); 65 | while (1) 66 | ; // Do nothing more 67 | } 68 | Serial.print(F("allcast_JSON contains data for ")); 69 | Serial.print(numARGOSsatellites); 70 | Serial.println(F(" satellites")); 71 | 72 | // Extract the satellite orbit parameters from the Allcast Info 73 | bulletin_data_t satelliteParameters[numARGOSsatellites]; // Create an array of bulletin_data_t to hold the parameters for all satellites 74 | extractOrbitParametersFromAllcast(numARGOSsatellites, satelliteParameters); // Extract the orbit parameters from the Allcast Info 75 | 76 | // Epoch timestamp for the prediction 77 | // E.g. 2021/03/06 14:00:00 UTC/GMT should be 1615039200 78 | // https://www.epochconverter.com/ 79 | // https://www.epochconverter.com/programming/c 80 | 81 | uint32_t current_time = myARTIC.convertGPSTimeToEpoch(2021, 3, 6, 14, 0, 0); 82 | 83 | Serial.print(F("The time of the prediction in seconds since the epoch is ")); 84 | Serial.println(current_time); 85 | Serial.print(F("The date and time of the prediction is ")); 86 | Serial.println(myARTIC.convertEpochToDateTime(current_time)); 87 | 88 | // Prediction parameters 89 | float min_elevation = 45.0; // Minimum satellite elevation (above the horizon) 90 | float lat = 48.8548; // Site latitude (C'est La Tour Eiffel naturellement!) 91 | float lon = 2.2945; // Site longitude 92 | 93 | // Calculate the prediction 94 | // For this example, using allcast_2021_03_06_13_27_618.h, the answer should be: 95 | // Satellite | Start date/time | Middle date/time | End date/time | Duration | Middle elevation | Start azimuth | Middle azimuth | End azimuth 96 | // A1 | 06/03/2021 18:19:52 | 06/03/2021 18:20:49 | 06/03/2021 18:21:45 | 00:01:53 | 67.37 | 350.46 | 284.87 | 221.39 97 | uint32_t predicted_time = myARTIC.predictNextSatellitePass(satelliteParameters, min_elevation, numARGOSsatellites, lon, lat, current_time); 98 | Serial.print(F("Predicted next pass will take place at ")); 99 | Serial.print(predicted_time); 100 | Serial.print(F(" = ")); 101 | Serial.print(myARTIC.convertEpochToDateTime(predicted_time)); 102 | Serial.println(); 103 | } 104 | 105 | void loop() 106 | { 107 | // Nothing to do here... 108 | } 109 | 110 | // Extract the number of satellites from the Allcast Info 111 | int extractNumSatellitesFromAllcast() 112 | { 113 | return(allcast["satellitesInformation"].size()); // Get the size of "satellitesInformation" 114 | } 115 | 116 | // Extract the satellite orbit parameters from the Allcast Info 117 | void extractOrbitParametersFromAllcast(int numARGOSsatellites, bulletin_data_t* satelliteParameters) 118 | { 119 | // For each satellite, extract the orbit parameters 120 | for (int i = 0; i < numARGOSsatellites; i++) 121 | { 122 | satelliteParameters[i].sat[0] = *((const char *)(allcast["satellitesInformation"][i]["satellite"])); // Two-character satellite ID 123 | satelliteParameters[i].sat[1] = *((const char *)(allcast["satellitesInformation"][i]["satellite"]) + 1); 124 | satelliteParameters[i].time_bulletin = myARTIC.convertAllcastDateTimeToEpoch((const char *)allcast["satellitesInformation"][i]["aop"]["date"]); // DateTime of the parameters 125 | satelliteParameters[i].params[0] = (float)allcast["satellitesInformation"][i]["aop"]["semiMajorAxis"]; // Orbit parameters 126 | satelliteParameters[i].params[1] = (float)allcast["satellitesInformation"][i]["aop"]["inclination"]; 127 | satelliteParameters[i].params[2] = (float)allcast["satellitesInformation"][i]["aop"]["ascendantNodeLongitude"]; 128 | satelliteParameters[i].params[3] = (float)allcast["satellitesInformation"][i]["aop"]["ascendantNodeDrift"]; 129 | satelliteParameters[i].params[4] = (float)allcast["satellitesInformation"][i]["aop"]["orbitalPeriod"]; 130 | satelliteParameters[i].params[5] = (float)allcast["satellitesInformation"][i]["aop"]["semiMajorAxisDrift"]; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /examples/Example9_TestJSONSatellitePassPredictor/allcast_2021_03_06_13_27_618.h: -------------------------------------------------------------------------------- 1 | "{\"creationDate\":\"2021-03-06_13:27:51.610000000\",\"satellitesInformation\":[{\"satellite\":\"A1\",\"instrumentGeneration\":\"ARGOS-NEO\",\"aop\":{\"date\":\"2021-03-05_22:46:21\",\"semiMajorAxis\":6891.243,\"semiMajorAxisDrift\":-3.11,\"inclination\":97.4624,\"ascendantNodeLongitude\":104.6,\"ascendantNodeDrift\":-23.752,\"orbitalPeriod\":95.0101},\"broadcastedStatus\":{\"allcastIdent\":\"6\",\"operatingStatus\":\"OUT OF SERVICE\",\"downlinkStatus\":\"Downlink transmitter OFF\"}},{\"satellite\":\"MA\",\"instrumentGeneration\":\"ARGOS-3\",\"addressADCS\":\"5\",\"aop\":{\"date\":\"2021-03-05_22:00:40\",\"semiMajorAxis\":7195.534,\"semiMajorAxisDrift\":0.0,\"inclination\":98.4874,\"ascendantNodeLongitude\":334.209,\"ascendantNodeDrift\":-25.341,\"orbitalPeriod\":101.3585},\"broadcastedStatus\":{\"allcastIdent\":\"A\",\"operatingStatus\":\"ARGOS-3 payload\",\"downlinkStatus\":\"ARGOS-3 TX ON\"}},{\"satellite\":\"MB\",\"instrumentGeneration\":\"ARGOS-3\",\"addressADCS\":\"3\",\"aop\":{\"date\":\"2021-03-05_23:15:31\",\"semiMajorAxis\":7195.643,\"semiMajorAxisDrift\":0.0,\"inclination\":98.6932,\"ascendantNodeLongitude\":333.69,\"ascendantNodeDrift\":-25.34,\"orbitalPeriod\":101.3603},\"broadcastedStatus\":{\"allcastIdent\":\"9\",\"operatingStatus\":\"ARGOS-3 payload\",\"downlinkStatus\":\"Downlink transmitter OFF\"}},{\"satellite\":\"MC\",\"instrumentGeneration\":\"ARGOS-3\",\"addressADCS\":\"7\",\"aop\":{\"date\":\"2021-03-05_22:28:17\",\"semiMajorAxis\":7195.574,\"semiMajorAxisDrift\":0.0,\"inclination\":98.7009,\"ascendantNodeLongitude\":345.928,\"ascendantNodeDrift\":-25.34,\"orbitalPeriod\":101.3588},\"broadcastedStatus\":{\"allcastIdent\":\"B\",\"operatingStatus\":\"ARGOS-3 payload\",\"downlinkStatus\":\"ARGOS-3 TX ON\"}},{\"satellite\":\"NK\",\"instrumentGeneration\":\"ARGOS-2\",\"aop\":{\"date\":\"2021-03-05_22:38:47\",\"semiMajorAxis\":7180.409,\"semiMajorAxisDrift\":-0.33,\"inclination\":98.6934,\"ascendantNodeLongitude\":310.746,\"ascendantNodeDrift\":-25.259,\"orbitalPeriod\":101.0391},\"broadcastedStatus\":{\"allcastIdent\":\"5\",\"operatingStatus\":\"ARGOS-3 payload\",\"downlinkStatus\":\"Downlink transmitter OFF\"}},{\"satellite\":\"NN\",\"instrumentGeneration\":\"ARGOS-2\",\"aop\":{\"date\":\"2021-03-05_23:05:48\",\"semiMajorAxis\":7225.936,\"semiMajorAxisDrift\":-0.95,\"inclination\":99.0076,\"ascendantNodeLongitude\":338.997,\"ascendantNodeDrift\":-25.498,\"orbitalPeriod\":101.9992},\"broadcastedStatus\":{\"allcastIdent\":\"8\",\"operatingStatus\":\"ARGOS-3 payload\",\"downlinkStatus\":\"Downlink transmitter OFF\"}},{\"satellite\":\"NP\",\"instrumentGeneration\":\"ARGOS-3\",\"addressADCS\":\"6\",\"aop\":{\"date\":\"2021-03-05_21:58:48\",\"semiMajorAxis\":7226.283,\"semiMajorAxisDrift\":-0.43,\"inclination\":99.1912,\"ascendantNodeLongitude\":309.447,\"ascendantNodeDrift\":-25.499,\"orbitalPeriod\":102.006},\"broadcastedStatus\":{\"allcastIdent\":\"C\",\"operatingStatus\":\"ARGOS-3 payload\",\"downlinkStatus\":\"Downlink transmitter OFF\"}},{\"satellite\":\"SR\",\"instrumentGeneration\":\"ARGOS-3\",\"addressADCS\":\"4\",\"aop\":{\"date\":\"2021-03-05_21:54:20\",\"semiMajorAxis\":7160.239,\"semiMajorAxisDrift\":-0.29,\"inclination\":98.5421,\"ascendantNodeLongitude\":120.062,\"ascendantNodeDrift\":-25.154,\"orbitalPeriod\":100.6147},\"broadcastedStatus\":{\"allcastIdent\":\"D\",\"operatingStatus\":\"ARGOS-3 payload\",\"downlinkStatus\":\"ARGOS-3 TX ON\"}}],\"allcastFormats\":[{\"from\":\"MA\",\"adaptedOrbitParametersBurst\":{\"NN\":\"00000BE50084841908C1522961ABECDABB7290094E6C96A1\",\"NP\":\"00000BE500C4841908561225C63BEADAF373EB045598A75E\",\"MA\":\"00000BE500A4841908801028CC0D26C6B2FBCE003A193F1B\",\"MB\":\"00000BE50094841908C54C68BBD528C6C2FC3B0042241FF1\",\"MC\":\"00000BE500B48419088A05EA3A4528C6B2FBF600427191F2\",\"NK\":\"00000BE500548419088E11E5EED5CABCBAC0B90342267EF4\",\"SR\":\"00000BE500D484190855080EA7F69CAF7271EF023C3D8242\"},\"constellationStatusBurst\":{\"A\":\"00000C75008603A5C900B7C500800C00D4CE845\",\"B\":\"000005F5006607A58900B78C00D484741\"},\"timeDiffusionSampleBurst\":\"00000E150820210651327516169A45\"},{\"from\":\"MC\",\"adaptedOrbitParametersBurst\":{\"NN\":\"00000BE70084841908C1522961ABECDABB7290094E6C3ABE\",\"NP\":\"00000BE700C4841908561225C63BEADAF373EB0455980B41\",\"MA\":\"00000BE700A4841908801028CC0D26C6B2FBCE003A199304\",\"MB\":\"00000BE70094841908C54C68BBD528C6C2FC3B004224B3EE\",\"MC\":\"00000BE700B48419088A05EA3A4528C6B2FBF60042713DED\",\"NK\":\"00000BE700548419088E11E5EED5CABCBAC0B9034226D2EB\",\"SR\":\"00000BE700D484190855080EA7F69CAF7271EF023C3D2E5D\"},\"constellationStatusBurst\":{\"A\":\"00000C77008603A5C900B7C500800C00D4C758A\",\"B\":\"000005F7006607A58900B78C00D48ED3B\"},\"timeDiffusionSampleBurst\":\"00000E1708202106513275161644CF\"},{\"from\":\"SR\",\"adaptedOrbitParametersBurst\":{\"NN\":\"00000BE40084841908C1522961ABECDABB7290094E6C48BE\",\"NP\":\"00000BE400C4841908561225C63BEADAF373EB0455987941\",\"MA\":\"00000BE400A4841908801028CC0D26C6B2FBCE003A19E104\",\"MB\":\"00000BE40094841908C54C68BBD528C6C2FC3B004224C1EE\",\"MC\":\"00000BE400B48419088A05EA3A4528C6B2FBF60042714FED\",\"NK\":\"00000BE400548419088E11E5EED5CABCBAC0B9034226A0EB\",\"SR\":\"00000BE400D484190855080EA7F69CAF7271EF023C3D5C5D\"},\"constellationStatusBurst\":{\"A\":\"00000C74008603A5C900B7C500800C00D4C2EB2\",\"B\":\"000005F4006607A58900B78C00D48127C\"},\"timeDiffusionSampleBurst\":\"00000E14082021065132751617E521\"}]}" -------------------------------------------------------------------------------- /examples/Example9_TestJSONSatellitePassPredictor/allcast_2021_03_06_13_27_618.txt: -------------------------------------------------------------------------------- 1 | { 2 | "creationDate" : "2021-03-06_13:27:51.610000000", 3 | "satellitesInformation" : [ { 4 | "satellite" : "A1", 5 | "instrumentGeneration" : "ARGOS-NEO", 6 | "aop" : { 7 | "date" : "2021-03-05_22:46:21", 8 | "semiMajorAxis" : 6891.243, 9 | "semiMajorAxisDrift" : -3.11, 10 | "inclination" : 97.4624, 11 | "ascendantNodeLongitude" : 104.6, 12 | "ascendantNodeDrift" : -23.752, 13 | "orbitalPeriod" : 95.0101 14 | }, 15 | "broadcastedStatus" : { 16 | "allcastIdent" : "6", 17 | "operatingStatus" : "OUT OF SERVICE", 18 | "downlinkStatus" : "Downlink transmitter OFF" 19 | } 20 | }, { 21 | "satellite" : "MA", 22 | "instrumentGeneration" : "ARGOS-3", 23 | "addressADCS" : "5", 24 | "aop" : { 25 | "date" : "2021-03-05_22:00:40", 26 | "semiMajorAxis" : 7195.534, 27 | "semiMajorAxisDrift" : 0.0, 28 | "inclination" : 98.4874, 29 | "ascendantNodeLongitude" : 334.209, 30 | "ascendantNodeDrift" : -25.341, 31 | "orbitalPeriod" : 101.3585 32 | }, 33 | "broadcastedStatus" : { 34 | "allcastIdent" : "A", 35 | "operatingStatus" : "ARGOS-3 payload", 36 | "downlinkStatus" : "ARGOS-3 TX ON" 37 | } 38 | }, { 39 | "satellite" : "MB", 40 | "instrumentGeneration" : "ARGOS-3", 41 | "addressADCS" : "3", 42 | "aop" : { 43 | "date" : "2021-03-05_23:15:31", 44 | "semiMajorAxis" : 7195.643, 45 | "semiMajorAxisDrift" : 0.0, 46 | "inclination" : 98.6932, 47 | "ascendantNodeLongitude" : 333.69, 48 | "ascendantNodeDrift" : -25.34, 49 | "orbitalPeriod" : 101.3603 50 | }, 51 | "broadcastedStatus" : { 52 | "allcastIdent" : "9", 53 | "operatingStatus" : "ARGOS-3 payload", 54 | "downlinkStatus" : "Downlink transmitter OFF" 55 | } 56 | }, { 57 | "satellite" : "MC", 58 | "instrumentGeneration" : "ARGOS-3", 59 | "addressADCS" : "7", 60 | "aop" : { 61 | "date" : "2021-03-05_22:28:17", 62 | "semiMajorAxis" : 7195.574, 63 | "semiMajorAxisDrift" : 0.0, 64 | "inclination" : 98.7009, 65 | "ascendantNodeLongitude" : 345.928, 66 | "ascendantNodeDrift" : -25.34, 67 | "orbitalPeriod" : 101.3588 68 | }, 69 | "broadcastedStatus" : { 70 | "allcastIdent" : "B", 71 | "operatingStatus" : "ARGOS-3 payload", 72 | "downlinkStatus" : "ARGOS-3 TX ON" 73 | } 74 | }, { 75 | "satellite" : "NK", 76 | "instrumentGeneration" : "ARGOS-2", 77 | "aop" : { 78 | "date" : "2021-03-05_22:38:47", 79 | "semiMajorAxis" : 7180.409, 80 | "semiMajorAxisDrift" : -0.33, 81 | "inclination" : 98.6934, 82 | "ascendantNodeLongitude" : 310.746, 83 | "ascendantNodeDrift" : -25.259, 84 | "orbitalPeriod" : 101.0391 85 | }, 86 | "broadcastedStatus" : { 87 | "allcastIdent" : "5", 88 | "operatingStatus" : "ARGOS-3 payload", 89 | "downlinkStatus" : "Downlink transmitter OFF" 90 | } 91 | }, { 92 | "satellite" : "NN", 93 | "instrumentGeneration" : "ARGOS-2", 94 | "aop" : { 95 | "date" : "2021-03-05_23:05:48", 96 | "semiMajorAxis" : 7225.936, 97 | "semiMajorAxisDrift" : -0.95, 98 | "inclination" : 99.0076, 99 | "ascendantNodeLongitude" : 338.997, 100 | "ascendantNodeDrift" : -25.498, 101 | "orbitalPeriod" : 101.9992 102 | }, 103 | "broadcastedStatus" : { 104 | "allcastIdent" : "8", 105 | "operatingStatus" : "ARGOS-3 payload", 106 | "downlinkStatus" : "Downlink transmitter OFF" 107 | } 108 | }, { 109 | "satellite" : "NP", 110 | "instrumentGeneration" : "ARGOS-3", 111 | "addressADCS" : "6", 112 | "aop" : { 113 | "date" : "2021-03-05_21:58:48", 114 | "semiMajorAxis" : 7226.283, 115 | "semiMajorAxisDrift" : -0.43, 116 | "inclination" : 99.1912, 117 | "ascendantNodeLongitude" : 309.447, 118 | "ascendantNodeDrift" : -25.499, 119 | "orbitalPeriod" : 102.006 120 | }, 121 | "broadcastedStatus" : { 122 | "allcastIdent" : "C", 123 | "operatingStatus" : "ARGOS-3 payload", 124 | "downlinkStatus" : "Downlink transmitter OFF" 125 | } 126 | }, { 127 | "satellite" : "SR", 128 | "instrumentGeneration" : "ARGOS-3", 129 | "addressADCS" : "4", 130 | "aop" : { 131 | "date" : "2021-03-05_21:54:20", 132 | "semiMajorAxis" : 7160.239, 133 | "semiMajorAxisDrift" : -0.29, 134 | "inclination" : 98.5421, 135 | "ascendantNodeLongitude" : 120.062, 136 | "ascendantNodeDrift" : -25.154, 137 | "orbitalPeriod" : 100.6147 138 | }, 139 | "broadcastedStatus" : { 140 | "allcastIdent" : "D", 141 | "operatingStatus" : "ARGOS-3 payload", 142 | "downlinkStatus" : "ARGOS-3 TX ON" 143 | } 144 | } ], 145 | "allcastFormats" : [ { 146 | "from" : "MA", 147 | "adaptedOrbitParametersBurst" : { 148 | "NN" : "00000BE50084841908C1522961ABECDABB7290094E6C96A1", 149 | "NP" : "00000BE500C4841908561225C63BEADAF373EB045598A75E", 150 | "MA" : "00000BE500A4841908801028CC0D26C6B2FBCE003A193F1B", 151 | "MB" : "00000BE50094841908C54C68BBD528C6C2FC3B0042241FF1", 152 | "MC" : "00000BE500B48419088A05EA3A4528C6B2FBF600427191F2", 153 | "NK" : "00000BE500548419088E11E5EED5CABCBAC0B90342267EF4", 154 | "SR" : "00000BE500D484190855080EA7F69CAF7271EF023C3D8242" 155 | }, 156 | "constellationStatusBurst" : { 157 | "A" : "00000C75008603A5C900B7C500800C00D4CE845", 158 | "B" : "000005F5006607A58900B78C00D484741" 159 | }, 160 | "timeDiffusionSampleBurst" : "00000E150820210651327516169A45" 161 | }, { 162 | "from" : "MC", 163 | "adaptedOrbitParametersBurst" : { 164 | "NN" : "00000BE70084841908C1522961ABECDABB7290094E6C3ABE", 165 | "NP" : "00000BE700C4841908561225C63BEADAF373EB0455980B41", 166 | "MA" : "00000BE700A4841908801028CC0D26C6B2FBCE003A199304", 167 | "MB" : "00000BE70094841908C54C68BBD528C6C2FC3B004224B3EE", 168 | "MC" : "00000BE700B48419088A05EA3A4528C6B2FBF60042713DED", 169 | "NK" : "00000BE700548419088E11E5EED5CABCBAC0B9034226D2EB", 170 | "SR" : "00000BE700D484190855080EA7F69CAF7271EF023C3D2E5D" 171 | }, 172 | "constellationStatusBurst" : { 173 | "A" : "00000C77008603A5C900B7C500800C00D4C758A", 174 | "B" : "000005F7006607A58900B78C00D48ED3B" 175 | }, 176 | "timeDiffusionSampleBurst" : "00000E1708202106513275161644CF" 177 | }, { 178 | "from" : "SR", 179 | "adaptedOrbitParametersBurst" : { 180 | "NN" : "00000BE40084841908C1522961ABECDABB7290094E6C48BE", 181 | "NP" : "00000BE400C4841908561225C63BEADAF373EB0455987941", 182 | "MA" : "00000BE400A4841908801028CC0D26C6B2FBCE003A19E104", 183 | "MB" : "00000BE40094841908C54C68BBD528C6C2FC3B004224C1EE", 184 | "MC" : "00000BE400B48419088A05EA3A4528C6B2FBF60042714FED", 185 | "NK" : "00000BE400548419088E11E5EED5CABCBAC0B9034226A0EB", 186 | "SR" : "00000BE400D484190855080EA7F69CAF7271EF023C3D5C5D" 187 | }, 188 | "constellationStatusBurst" : { 189 | "A" : "00000C74008603A5C900B7C500800C00D4C2EB2", 190 | "B" : "000005F4006607A58900B78C00D48127C" 191 | }, 192 | "timeDiffusionSampleBurst" : "00000E14082021065132751617E521" 193 | } ] 194 | } -------------------------------------------------------------------------------- /examples/Example9_TestSatellitePassPredictor/Example9_TestSatellitePassPredictor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the ARGOS ARTIC R2 Breakout 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: November 12th 2020 6 | 7 | This example tests the satellite pass predictor. 8 | The predictor was originally written by CLS. 9 | This code is gratefully based on the version in Arribada Horizon. 10 | 11 | License: please see the license file at: 12 | https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library/LICENSE.md 13 | 14 | Feel like supporting our work? Buy a board from SparkFun! 15 | https://www.sparkfun.com/products/17236 16 | 17 | 18 | You can download the Satellite AOP (Adapted Orbit Parameters) from https://argos-system.cls.fr/argos-cwi2/login.html 19 | 20 | The AOP file contains the following fields separated with spaces : 21 | Satellite identifier (number for NOAA spacecraft) 22 | Satellite identifier into the downlink allcast data 23 | First digit of downlink identifier of the first instrument associated to satellite. (0 if no downlink) 24 | Downlink operating status 25 | 0=OFF 26 | 1=ON 27 | 3=ON (ARGOS-3) 28 | 4=ON (ARGOS-4) 29 | Argos Instrument Operating status 30 | 0= OPERATIONAL ARGOS-2/3 31 | 1= OPERATIONAL ARGOS-NEO 32 | 2= OPERATIONAL ARGOS-4 33 | 3= OUTOFSERVICE or OTHER 34 | Date : YYYY MM DD HH mm ss (Y = year, M = month, d = day, H = hours, m = minutes, s = seconds) 35 | Semi-major axis (km) 36 | Orbit inclination (deg) 37 | Ascending node longitude (deg) 38 | Ascending node longitudinal drift (deg) 39 | Orbital period (min) 40 | Semi-major axis drift (m/day) 41 | 42 | Example data for METOP-A for October 2nd 2020 is: 43 | 44 | MA A 5 3 0 2020 10 1 22 7 29 7195.569 98.5114 336.036 -25.341 101.3592 0.00 45 | 46 | The two character satellite identifiers are: 47 | 48 | MA : METOP-A 49 | MB : METOP-B 50 | MC : METOP-C 51 | NK : NOAA-15 (appears as 15 in the AOP) 52 | NN : NOAA-18 (appears as 18 in the AOP) 53 | NP : NOAA-19 (appears as 19 in the AOP) 54 | SR : SARAL 55 | 56 | */ 57 | 58 | const uint8_t numARGOSsatellites = 7; // Change this if required to match the number of satellites in the AOP 59 | 60 | // Copy and paste the latest AOP from ARGOS Web between the quotes and then carefully delete the line feeds 61 | // Check the alignment afterwards - make sure that the satellite identifiers line up correctly (or convertAOPtoParameters will go horribly wrong!) 62 | // Check the alignment: " MA A 5 3 0 2020 10 1 22 7 29 7195.569 98.5114 336.036 -25.341 101.3592 0.00 MB 9 3 0 0 2020 10 1 23 21 58 7195.654 98.7194 331.991 -25.340 101.3604 0.00 MC B 7 3 0 2020 10 1 22 34 23 7195.569 98.6883 344.217 -25.340 101.3587 0.00 15 5 0 0 0 2020 10 1 22 44 11 7180.495 98.7089 308.255 -25.259 101.0408 0.00 18 8 0 0 0 2020 10 1 21 50 32 7225.981 99.0331 354.556 -25.498 102.0000 -0.79 19 C 6 0 0 2020 10 1 22 7 6 7226.365 99.1946 301.174 -25.499 102.0077 -0.54 SR D 4 3 0 2020 10 1 22 33 38 7160.233 98.5416 110.362 -25.154 100.6146 -0.12"; 63 | const char AOP[] = " MA A 5 3 0 2020 10 1 22 7 29 7195.569 98.5114 336.036 -25.341 101.3592 0.00 MB 9 3 0 0 2020 10 1 23 21 58 7195.654 98.7194 331.991 -25.340 101.3604 0.00 MC B 7 3 0 2020 10 1 22 34 23 7195.569 98.6883 344.217 -25.340 101.3587 0.00 15 5 0 0 0 2020 10 1 22 44 11 7180.495 98.7089 308.255 -25.259 101.0408 0.00 18 8 0 0 0 2020 10 1 21 50 32 7225.981 99.0331 354.556 -25.498 102.0000 -0.79 19 C 6 0 0 2020 10 1 22 7 6 7226.365 99.1946 301.174 -25.499 102.0077 -0.54 SR D 4 3 0 2020 10 1 22 33 38 7160.233 98.5416 110.362 -25.154 100.6146 -0.12"; 64 | 65 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 66 | ARTIC_R2 myARTIC; 67 | 68 | void setup() 69 | { 70 | Serial.begin(115200); 71 | Serial.println(); 72 | Serial.println(F("ARGOS ARTIC R2 Example")); 73 | 74 | myARTIC.enableDebugging(); // Enable debug messages to Serial 75 | 76 | // Read the AOP, convert into bulletin_data_t 77 | bulletin_data_t satelliteParameters[numARGOSsatellites]; // Create an array of bulletin_data_t to hold the parameters for all satellites 78 | if (myARTIC.convertAOPtoParameters(AOP, satelliteParameters, numARGOSsatellites) == false) 79 | { 80 | Serial.println("convertAOPtoParameters failed! Freezing..."); 81 | while (1) 82 | ; // Do nothing more 83 | } 84 | 85 | // Epoch timestamp for the prediction 86 | // E.g. 2020/10/2 08:00:00 UTC/GMT should be 1601625600 87 | // https://www.epochconverter.com/ 88 | // https://www.epochconverter.com/programming/c 89 | 90 | uint32_t current_time = myARTIC.convertGPSTimeToEpoch(2020, 10, 2, 8, 0, 0); 91 | 92 | Serial.print(F("The time of the prediction in seconds since the epoch is ")); 93 | Serial.println(current_time); 94 | Serial.print(F("The date and time of the prediction is ")); 95 | Serial.println(myARTIC.convertEpochToDateTime(current_time)); 96 | 97 | // Prediction parameters 98 | float min_elevation = 45.0; // Minimum satellite elevation (above the horizon) 99 | float lat = 48.8548; // Site latitude (C'est La Tour Eiffel naturellement!) 100 | float lon = 2.2945; // Site longitude 101 | 102 | // Calculate the prediction 103 | // For this example, the answer should be: 104 | // Satellite | Start date/time | Middle date/time | End date/time | Duration | Middle elevation | Start azimuth | Middle azimuth | End azimuth 105 | // MA | 02/10/2020 08:48:04 | 02/10/2020 08:52:28 | 02/10/2020 08:56:51 | 00:08:47 | 76.69 | 18.28 | 104.36 | 189.26 106 | uint32_t predicted_time = myARTIC.predictNextSatellitePass(satelliteParameters, min_elevation, numARGOSsatellites, lon, lat, current_time); 107 | Serial.print(F("Predicted next pass will take place at ")); 108 | Serial.print(predicted_time); 109 | Serial.print(F(" = ")); 110 | Serial.print(myARTIC.convertEpochToDateTime(predicted_time)); 111 | Serial.println(); 112 | } 113 | 114 | void loop() 115 | { 116 | // Nothing to do here... 117 | } 118 | -------------------------------------------------------------------------------- /examples/smol_ARTIC_R2/Example3_SatelliteDetection/Example3_SatelliteDetection.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun smôl ARGOS ARTIC R2 Board 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: August 30th 2021 6 | 7 | This example shows how to use the smôl ARTIC R2 for ARGOS satellite communication. 8 | The smôl ESP32 is the board which runs this example. 9 | Power can be provided by: 10 | The ESP32 board USB-C connection 11 | The smôl Power Board AAA 12 | The smôl Power Board LiPo 13 | 14 | Feel like supporting our work? Buy a board from SparkFun! 15 | 16 | The smôl stack-up for this example is: 17 | smôl ARTIC R2: https://www.sparkfun.com/products/18363 18 | smôl ESP32: https://www.sparkfun.com/products/18362 19 | 20 | smôl Power Board LiPo: https://www.sparkfun.com/products/18359 (Optional) 21 | smôl Power Board AAA: https://www.sparkfun.com/products/18360 (Optional) 22 | 23 | The way the boards are stacked is important: 24 | 25 | OUT ---smôl ARTIC R2--- IN 26 | | 27 | ________________________/ 28 | / 29 | | 30 | OUT --- smôl ESP32 --- IN 31 | 32 | Arranged like this: 33 | The ESP32 GPIO0 (Digital Pin 27) controls the power for the ARTIC R2 34 | ARTIC R2 uses SPI Chip Select 0 (ESP32 Digital Pin 5) 35 | 36 | This example: 37 | begins (initializes) the ARTIC; 38 | reads and prints the ARTIC TX and RX configuration; 39 | reads and prints the firmware status; 40 | sets the TCXO voltage; 41 | sets the satellite detection timeout to 600 seconds; 42 | starts satellite detection; 43 | keeps checking the MCU status until a satellite is detected or the detection times out. 44 | 45 | */ 46 | 47 | #include //Needed for I2C to ARTIC R2 GPIO and GNSS 48 | 49 | #include 50 | 51 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 52 | ARTIC_R2 myARTIC; 53 | 54 | // Pin assignments for the smôl stack-up described above 55 | int CS_Pin = 5; // smôl CS0 = ESP32 Pin 5 56 | int ARTIC_PWR_EN_Pin = 27; // smôl GPIO0 = ESP32 Pin 27 57 | 58 | // The ARTIC RESETB, INT1, BOOT and G8 signals are accessed through a PCA9536 I2C-GPIO chip on the smôl ARTIC R2 59 | 60 | void setup() 61 | { 62 | Serial.begin(115200); 63 | Serial.println(); 64 | Serial.println(F("ARGOS smôl ARTIC R2 Example")); 65 | Serial.println(); 66 | 67 | Serial.println(F("ARTIC R2 is booting...")); 68 | Serial.println(); 69 | 70 | Wire.begin(); // Needed to communicate with the I2C GPIO chip on the smôl ARTIC R2 71 | SPI.begin(); 72 | 73 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 74 | 75 | // Begin the ARTIC: enable power and upload firmware or boot from flash 76 | if (myARTIC.beginSmol(CS_Pin, ARTIC_PWR_EN_Pin) == false) // Default to using Wire to communicate with the PCA9536 I2C-GPIO chip on the smôl ARTIC R2 77 | { 78 | Serial.println("ARTIC R2 not detected. Please check the smôl stack-up and flexible circuits. Freezing..."); 79 | while (1) 80 | ; // Do nothing more 81 | } 82 | 83 | Serial.println(F("ARTIC R2 boot was successful.")); 84 | Serial.println(); 85 | 86 | // Read and print the ARTIC R2 firmware status 87 | ARTIC_R2_Firmware_Status status; 88 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 89 | Serial.println(F("ARTIC R2 Firmware Status:")); 90 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 91 | Serial.println(); 92 | 93 | // Read and print the ARGOS configuration 94 | ARGOS_Configuration_Register configuration; 95 | myARTIC.readARGOSconfiguration(&configuration); 96 | myARTIC.printARGOSconfiguration(configuration); // Pretty-print the TX and RX configuration to Serial 97 | 98 | // Set the TCXO voltage to 1.8V and autoDisable to 1 99 | if (myARTIC.setTCXOControl(1.8, true) == false) 100 | { 101 | Serial.println("setTCXOControl failed. Freezing..."); 102 | while (1) 103 | ; // Do nothing more 104 | } 105 | 106 | // Set the satellite detection timeout to 600 seconds 107 | if (myARTIC.setSatelliteDetectionTimeout(600) == false) 108 | { 109 | Serial.println("setSatelliteDetectionTimeout failed. Freezing..."); 110 | while (1) 111 | ; // Do nothing more 112 | } 113 | 114 | // Get the satellite detection timeout 115 | uint32_t detectionTimeout = myARTIC.readSatelliteDetectionTimeout(); 116 | Serial.print(F("The Satellite Detection Timeout is ")); 117 | Serial.print(detectionTimeout); 118 | Serial.println(F(" seconds.")); 119 | 120 | Serial.println(); 121 | Serial.println(F("Starting satellite detection...")); 122 | Serial.println(); 123 | 124 | // Start satellite detection 125 | // The ARTIC will start looking for a satellite for the specified amount of time. 126 | // If no satellite is detected, INT 2 will be set with the ‘SATELLITE_TIMEOUT’ flag. 127 | // If a satellite was detected, by receiving 5 consecutive 0x7E flags, INT 1 will be set with the ‘RX_SATELLITE_DETECTED’ flag. 128 | // sendMCUinstruction returns an ARTIC_R2_MCU_Command_Result 129 | // sendMCUinstruction will return ARTIC_R2_MCU_COMMAND_ACCEPTED if the instruction was accepted 130 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendMCUinstruction(INST_SATELLITE_DETECTION); 131 | 132 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 133 | Serial.println(F("ARTIC R2 Firmware Status:")); 134 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 135 | Serial.println(); 136 | Serial.println(F("ARTIC R2 MCU instruction result:")); 137 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 138 | Serial.println(); 139 | 140 | if ((result == ARTIC_R2_MCU_COMMAND_REJECTED) || (result == ARTIC_R2_MCU_COMMAND_OVERFLOW)) 141 | { 142 | Serial.println("MCU Command failed! Freezing..."); 143 | while (1) 144 | ; // Do nothing more 145 | } 146 | } 147 | 148 | void loop() 149 | { 150 | delay(1000); 151 | 152 | Serial.println(); 153 | 154 | // Read and print the ARTIC R2 status register 155 | ARTIC_R2_Firmware_Status status; 156 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 157 | Serial.println(F("ARTIC R2 Firmware Status:")); 158 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 159 | 160 | // Note: satellite detection does not time out once a satellite has been detected. The firmware goes IDLE instead. 161 | 162 | // Note: With ARTIC006 firmware: when satellite detection times out and INT2 goes high, INT1 goes high too! Confusing... 163 | // We should only believe INT1 if INT2 is low. 164 | 165 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT2) // Check the interrupt 2 flag. This will go high if satellite detection times out 166 | { 167 | Serial.println(F("INT2 pin is high. Satellite detection has timed out!")); 168 | } 169 | else if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when a satellite is detected 170 | { 171 | Serial.println(F("INT1 pin is high. Satellite detected!")); 172 | } 173 | 174 | Serial.println(); 175 | 176 | // Read and print the instruction progress 177 | ARTIC_R2_MCU_Instruction_Progress progress; 178 | // checkMCUinstructionProgress will return true if the instruction is complete 179 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 180 | Serial.println(F("ARTIC R2 instruction progress:")); 181 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 182 | 183 | if (instructionComplete) 184 | { 185 | Serial.println(); 186 | Serial.println(F("Satellite detection is complete! Freezing...")); 187 | while (1) 188 | ; // Do nothing more 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /examples/smol_ARTIC_R2/Example4_TransmitARGOS4VLDLongExample/Example4_TransmitARGOS4VLDLongExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Using the SparkFun smôl ARGOS ARTIC R2 Board 3 | By: Paul Clark 4 | SparkFun Electronics 5 | Date: August 30th 2021 6 | 7 | This example shows how to use the smôl ARTIC R2 for ARGOS satellite communication. 8 | The smôl ESP32 is the board which runs this example. 9 | 10 | Feel like supporting our work? Buy a board from SparkFun! 11 | 12 | The smôl stack-up for this example is: 13 | smôl ZOE-M8Q: https://www.sparkfun.com/products/18358 14 | smôl ARTIC R2: https://www.sparkfun.com/products/18363 15 | 16 | The way the boards are stacked is important: 17 | 18 | OUT ---smôl ARTIC R2--- IN 19 | | 20 | ________________________/ 21 | / 22 | | 23 | OUT --- smôl ESP32 --- IN 24 | 25 | Arranged like this: 26 | The ESP32 GPIO0 (Digital Pin 27) controls the power for the ARTIC R2 27 | ARTIC R2 uses SPI Chip Select 0 (ESP32 Digital Pin 5) 28 | 29 | This example: 30 | begins (initializes) the ARTIC; 31 | reads and prints the ARTIC TX and RX configuration; 32 | reads and prints the firmware status; 33 | sets the TCXO voltage; 34 | sets the TCXO warmup time; 35 | sets the satellite detection timeout to 60 seconds; 36 | sets the TX mode to ARGOS A4 VLD; 37 | sets the TX frequency; 38 | instructs the ARTIC to Transmit One Package And Go Idle; 39 | keeps checking the MCU status until transmit is complete; 40 | repeats. 41 | 42 | The transmit power can be reduced by 8dB by uncommenting the line: myARTIC.attenuateTXgain(true); 43 | 44 | The messages are ARGOS 4 VLD (Long) and contain the example used in A4-SS-TER-SP-0079-CNES. 45 | 46 | */ 47 | 48 | // From v1.1.0 of the library, the platform ID is stored in PMEM and, for this example, should be 0x01234567 49 | 50 | const unsigned long repetitionPeriod = 50000; // Define the repetition period in milliseconds 51 | 52 | const uint32_t tcxoWarmupTime = 10; // Define the TCXO warmup time (in seconds) 53 | 54 | #include 55 | 56 | #include "SparkFun_ARGOS_ARTIC_R2_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_ARGOS_ARTIC_R2 57 | ARTIC_R2 myARTIC; 58 | 59 | #include //Needed for I2C to ARTIC R2 GPIO and GNSS 60 | 61 | #include "SparkFun_u-blox_GNSS_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_u-blox_GNSS 62 | SFE_UBLOX_GNSS myGNSS; 63 | 64 | // Pin assignments for the smôl stack-up described above 65 | int CS_Pin = 5; // smôl CS0 = ESP32 Pin 5 66 | int ARTIC_PWR_EN_Pin = 27; // smôl GPIO0 = ESP32 Pin 27 67 | 68 | // The ARTIC RESETB, INT1, BOOT and G8 signals are accessed through a PCA9536 I2C-GPIO chip on the smôl ARTIC R2 69 | 70 | // Loop Steps - these are used by the switch/case in the main loop 71 | // This structure makes it easy to jump between any of the steps 72 | typedef enum { 73 | configure_ARTIC, // Configure the ARTIC (set the satellite detection timeout and TX mode) 74 | ARTIC_TX, // Start the ARTIC TX 75 | wait_for_ARTIC_TX // Wait for the ARTIC to transmit 76 | } loop_steps; 77 | loop_steps loop_step = configure_ARTIC; // Make sure loop_step is set to configure_ARTIC 78 | 79 | // AS3-SP-516-2098-CNES specifies a ±10% 'jitter' on the repetition period to reduce the risk of transmission collisions 80 | uint32_t nextTransmitTime; // Time of the next satellite transmission (before jitter is added) 81 | uint32_t nextTransmitTimeActual; // Actual time of the next satellite transmission (including jitter) 82 | 83 | void setup() 84 | { 85 | delay(1000); 86 | 87 | Serial.begin(115200); 88 | Serial.println(); 89 | Serial.println(F("SparkFun smôl ARTIC R2 Example")); 90 | Serial.println(); 91 | 92 | Wire.begin(); 93 | 94 | SPI.begin(); 95 | 96 | // Uncomment the next line to enable the helpful debug messages 97 | //myARTIC.enableDebugging(); // Enable debug messages to Serial 98 | 99 | Serial.println(F("Starting the ARTIC R2...")); 100 | Serial.println(); 101 | 102 | // Begin the ARTIC: enable power and upload firmware or boot from flash 103 | if (myARTIC.beginSmol(CS_Pin, ARTIC_PWR_EN_Pin) == false) // Default to using Wire to communicate with the PCA9536 I2C-GPIO chip on the smôl ARTIC R2 104 | { 105 | Serial.println("ARTIC R2 not detected. Please check the smôl stack-up and flexible circuits. Freezing..."); 106 | while (1) 107 | ; // Do nothing more 108 | } 109 | 110 | // From v1.1.0 of the ARTIC R2 library: we were instructed by Kineis to ensure the Platform ID was written into each module 111 | // and not stored in a configuration file accessible to standard users. To comply with this, SparkFun 112 | // ARTIC R2 boards are now shipped with the Platform ID programmed into PMEM. Customers who have 113 | // earlier versions of the board will need to use version 1.0.9 of the library. 114 | uint32_t platformID = myARTIC.readPlatformID(); 115 | if (platformID == 0) 116 | { 117 | Serial.println(F("You appear to have an early version of the SparkFun board.")); 118 | Serial.println(F("Please use the Library Manager to select version 1.0.9 of this library.")); 119 | Serial.println(F("Freezing...")); 120 | while (1) 121 | ; // Do nothing more 122 | } 123 | else 124 | { 125 | Serial.print(F("Your Platform ID is: 0x")); 126 | Serial.println(platformID, HEX); 127 | } 128 | 129 | // Define the time of the first transmit 130 | nextTransmitTime = repetitionPeriod; 131 | nextTransmitTimeActual = nextTransmitTime - tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 132 | } 133 | 134 | void loop() 135 | { 136 | // loop is one large switch/case that controls the sequencing of the code 137 | switch (loop_step) { 138 | 139 | // ************************************************************************************************ 140 | // Configure the ARTIC 141 | case configure_ARTIC: 142 | { 143 | // Set the TCXO voltage to 1.8V and autoDisable to 1 144 | if (myARTIC.setTCXOControl(1.8, true) == false) 145 | { 146 | Serial.println("setTCXOControl failed. Freezing..."); 147 | while (1) 148 | ; // Do nothing more 149 | } 150 | 151 | // Set the TCXO warm-up time 152 | if (myARTIC.setTCXOWarmupTime(tcxoWarmupTime) == false) 153 | { 154 | Serial.println("setTCXOWarmupTime failed. Freezing..."); 155 | while (1) 156 | ; // Do nothing more 157 | } 158 | 159 | // Set the satellite detection timeout to 60 seconds 160 | if (myARTIC.setSatelliteDetectionTimeout(60) == false) 161 | { 162 | Serial.println("setSatelliteDetectionTimeout failed. Freezing..."); 163 | while (1) 164 | ; // Do nothing more 165 | } 166 | 167 | // Set the TX mode to ARGOS 4 VLD 168 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendConfigurationCommand(CONFIG_CMD_SET_ARGOS_4_PTT_VLD_TX_MODE); 169 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 170 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 171 | { 172 | Serial.println("sendConfigurationCommand failed. Freezing..."); 173 | while (1) 174 | ; // Do nothing more 175 | } 176 | 177 | // Read and print the ARGOS configuration 178 | ARGOS_Configuration_Register configuration; 179 | myARTIC.readARGOSconfiguration(&configuration); 180 | myARTIC.printARGOSconfiguration(configuration); 181 | 182 | // Set the ARGOS 4 TX frequency to 401.630 MHz 183 | // From A4-SS-TER-SP-0079-CNES: 184 | // The transmission frequency for PTT-VLD-A4 platforms shall be set between 399.91 MHz to 401.68 MHz. 185 | // Due to frequency regulations, the frequency ranges [400.05 MHz to 401.0 MHz] and [401.2 MHz to 401.3 MHz] are forbidden for VLD-A4 transmissions. 186 | if (myARTIC.setARGOS4TxFrequency(401.630) == false) 187 | { 188 | Serial.println("setARGOS4TxFrequency failed. Freezing..."); 189 | while (1) 190 | ; // Do nothing more 191 | } 192 | 193 | // Print the TX frequency 194 | float tx4freq = myARTIC.getARGOS4TxFrequency(); 195 | Serial.print(F("The ARGOS 4 TX Frequency is ")); 196 | Serial.print(tx4freq, 3); 197 | Serial.println(F(" MHz.")); 198 | 199 | // Uncomment the next line if you want to attenuate the transmit power by 8dB 200 | //myARTIC.attenuateTXgain(true); 201 | 202 | // Configure the Tx payload for ARGOS 4 VLD (A4-SS-TER-SP-0079-CNES) 203 | // If the Platform ID has also been set to 0x01234567, the complete over-air data stream, including sync pattern and length, should be: 204 | // 0xAC5353DC651CECA2F6E328E76517B719473B28BD followed by 0b1 205 | if (myARTIC.setPayloadARGOS4VLDLong(0x01234567, 0x01234567) == false) 206 | { 207 | Serial.println(F("setPayloadARGOS4VLDLatLon failed!")); 208 | Serial.println(); 209 | // Read the payload back again and print it 210 | myARTIC.readTxPayload(); 211 | myARTIC.printTxPayload(); 212 | Serial.println(); 213 | Serial.println(F("Freezing...")); 214 | while (1) 215 | ; // Do nothing more 216 | } 217 | 218 | /* 219 | // Read the payload back again and print it 220 | myARTIC.readTxPayload(); 221 | myARTIC.printTxPayload(); 222 | Serial.println(); 223 | */ 224 | 225 | loop_step = ARTIC_TX; // Move on 226 | } 227 | break; 228 | 229 | // ************************************************************************************************ 230 | // Start the ARTIC in Transmit One Package And Go Idle mode 231 | case ARTIC_TX: 232 | { 233 | // Wait for the next repetition period 234 | while (nextTransmitTimeActual > millis()) 235 | { 236 | if ((millis() % 1000) < 50) // Print how long it is until the next transmit 237 | { 238 | Serial.print(F("The next transmit will take place in ")); 239 | unsigned long remaining = (nextTransmitTimeActual - millis()) / 1000; 240 | Serial.print(remaining); 241 | Serial.println(F(" seconds")); 242 | } 243 | delay(50); 244 | } 245 | nextTransmitTime += repetitionPeriod; 246 | nextTransmitTimeActual = nextTransmitTime + random((-0.1 * repetitionPeriod), (0.1 * repetitionPeriod)); 247 | nextTransmitTimeActual -= tcxoWarmupTime; // Start the transmit early to compensate for the TCXO warmup time 248 | 249 | // Tell the ARTIC to do its thing! 250 | ARTIC_R2_MCU_Command_Result result = myARTIC.sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE); 251 | if (result != ARTIC_R2_MCU_COMMAND_ACCEPTED) 252 | { 253 | Serial.println("sendMCUinstruction(INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE) failed!"); 254 | Serial.println(); 255 | ARTIC_R2_Firmware_Status status; 256 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 257 | Serial.println(F("ARTIC R2 Firmware Status:")); 258 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 259 | Serial.println(); 260 | Serial.println(F("ARTIC_R2_MCU_Command_Result:")); 261 | myARTIC.printCommandResult(result); // Pretty-print the command result to Serial 262 | Serial.println(); 263 | Serial.println("Freezing..."); 264 | while (1) 265 | ; // Do nothing more 266 | } 267 | 268 | loop_step = wait_for_ARTIC_TX; // Move on 269 | } 270 | break; 271 | 272 | // ************************************************************************************************ 273 | // Start the ARTIC in Transmit One Package And Go Idle mode 274 | case wait_for_ARTIC_TX: 275 | { 276 | delay(1000); // Check the status every second 277 | 278 | // Read and print the ARTIC R2 status register 279 | ARTIC_R2_Firmware_Status status; 280 | myARTIC.readStatusRegister(&status); // Read the ARTIC R2 status register 281 | Serial.println(F("ARTIC R2 Firmware Status:")); 282 | myARTIC.printFirmwareStatus(status); // Pretty-print the firmware status to Serial 283 | 284 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT1) // Check the interrupt 1 flag. This will go high when TX is finished 285 | { 286 | Serial.println(F("INT1 pin is high. TX is finished (or MCU is in IDLE_STATE)!")); 287 | } 288 | 289 | if (status.STATUS_REGISTER_BITS.DSP2MCU_INT2) // Check the interrupt 2 flag. This will go high when if the message was invalid 290 | { 291 | Serial.println(F("INT2 pin is high. TX message was invalid! (Something really bad must have happened...)")); 292 | } 293 | 294 | Serial.println(); 295 | 296 | // Read and print the instruction progress 297 | ARTIC_R2_MCU_Instruction_Progress progress; 298 | // checkMCUinstructionProgress will return true if the instruction is complete 299 | boolean instructionComplete = myARTIC.checkMCUinstructionProgress(&progress); // Check the instruction progress 300 | Serial.println(F("ARTIC R2 instruction progress:")); 301 | myARTIC.printInstructionProgress(progress); // Pretty-print the progress to Serial 302 | 303 | Serial.println(); 304 | 305 | if (instructionComplete) 306 | { 307 | Serial.println(F("Transmission is complete!")); 308 | Serial.println(); 309 | 310 | Serial.println(F("Clearing INT1.")); 311 | Serial.println(); 312 | 313 | // Clear INT1 314 | if (myARTIC.clearInterrupts(1) == false) 315 | { 316 | Serial.println("clearInterrupts failed! Freezing..."); 317 | while (1) 318 | ; // Do nothing more 319 | } 320 | 321 | loop_step = ARTIC_TX; // Do over... 322 | } 323 | } 324 | break; 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | ARTIC_R2 KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | beginIOTA KEYWORD2 17 | beginSmol KEYWORD2 18 | enableDebugging KEYWORD2 19 | attenuateTXgain KEYWORD2 20 | enableARTICpower KEYWORD2 21 | disableARTICpower KEYWORD2 22 | enableRFpower KEYWORD2 23 | disableRFpower KEYWORD2 24 | readStatusRegister KEYWORD2 25 | printFirmwareStatus KEYWORD2 26 | sendConfigurationCommand KEYWORD2 27 | sendMCUinstruction KEYWORD2 28 | sendHousekeepingCommand KEYWORD2 29 | printCommandResult KEYWORD2 30 | checkMCUinstructionProgress KEYWORD2 31 | printInstructionProgress KEYWORD2 32 | clearInterrupts KEYWORD2 33 | readFirmwareVersion KEYWORD2 34 | readPlatformID KEYWORD2 35 | readMemoryCRC KEYWORD2 36 | setRxTimeout KEYWORD2 37 | setSatelliteDetectionTimeout KEYWORD2 38 | setTCXOWarmupTime KEYWORD2 39 | setTxCertificationInterval KEYWORD2 40 | readARGOSconfiguration KEYWORD2 41 | printARGOSconfiguration KEYWORD2 42 | txConfigurationString KEYWORD2 43 | rxConfigurationString KEYWORD2 44 | readRxTimeout KEYWORD2 45 | readSatelliteDetectionTimeout KEYWORD2 46 | readTCXOWarmupTime KEYWORD2 47 | readTxCertificationInterval KEYWORD2 48 | setTCXOControl KEYWORD2 49 | readTCXOControlVoltage KEYWORD2 50 | readTCXOAutoDisable KEYWORD2 51 | setARGOS23TxFrequency KEYWORD2 52 | setARGOS4TxFrequency KEYWORD2 53 | getARGOS23TxFrequency KEYWORD2 54 | getARGOS4TxFrequency KEYWORD2 55 | enableRXCRC KEYWORD2 56 | disableRXCRC KEYWORD2 57 | isRXCRCenabled KEYWORD2 58 | enableRXTransparentMode KEYWORD2 59 | disableRXTransparentMode KEYWORD2 60 | isRXTransparentModeEnabled KEYWORD2 61 | clearAddressLUT KEYWORD2 62 | addAddressToLUT KEYWORD2 63 | getAddressLUTlength KEYWORD2 64 | readAddressLUTentry KEYWORD2 65 | readDownlinkMessage KEYWORD2 66 | setPayloadARGOS3ZE KEYWORD2 67 | setPayloadARGOS3LatLon KEYWORD2 68 | setPayloadARGOS3 KEYWORD2 69 | setPayloadARGOS2LatLon KEYWORD2 70 | setPayloadARGOS2 KEYWORD2 71 | setPayloadARGOS4VLDshort KEYWORD2 72 | setPayloadARGOS4VLDLatLon KEYWORD2 73 | setPayloadARGOS4VLDLong KEYWORD2 74 | setTxPayload KEYWORD2 75 | readTxPayload KEYWORD2 76 | printTxPayload KEYWORD2 77 | invertPWNENpin KEYWORD2 78 | predictNextSatellitePass KEYWORD2 79 | convertAOPtoParameters KEYWORD2 80 | convertEpochToDateTime KEYWORD2 81 | convertEpochToDateTimeAOP KEYWORD2 82 | convertGPSTimeToEpoch KEYWORD2 83 | printAOPbulletin KEYWORD2 84 | getINT1 KEYWORD2 85 | 86 | ####################################### 87 | # Constants (LITERAL1) 88 | ####################################### 89 | 90 | ARTIC_R2_SPI_MODE SPI_MODE1 LITERAL1 91 | ARTIC_R2_TX_POWER_ON_DELAY_MS LITERAL1 92 | ARTIC_R2_POWER_ON_DELAY_MS LITERAL1 93 | ARTIC_R2_FLASH_BOOT_TIMEOUT_MS LITERAL1 94 | ARTIC_R2_BOOT_TIMEOUT_MS LITERAL1 95 | ARTIC_R2_BOOT_DELAY_MS LITERAL1 96 | ARTIC_R2_BOOT_MAX_RETRIES LITERAL1 97 | ARTIC_R2_BURST_INTER_WORD_DELAY_US LITERAL1 98 | ARTIC_R2_BURST_BLOCK_SIZE LITERAL1 99 | ARTIC_R2_BURST_INTER_BLOCK_DELAY_MS LITERAL1 100 | ARTIC_R2_BURST_FINISH_DELAY_MS LITERAL1 101 | ARTIC_R2_INSTRUCTION_DELAY_MS LITERAL1 102 | ARTIC_R2_CONFIGURATION_DELAY_MS LITERAL1 103 | ARTIC_R2_HOUSEKEEPING_DELAY_MS LITERAL1 104 | ARTIC_R2_MAX_ADDRESS_LUT_LENGTH LITERAL1 105 | ARTIC_R2_TX_MAX_PAYLOAD_LENGTH_BYTES LITERAL1 106 | ARTIC_R2_TX_MAX_PAYLOAD_LENGTH_WORDS LITERAL1 107 | 108 | ARTIC_R2_Firmware_Status LITERAL1 109 | STATUS_REGISTER LITERAL1 110 | STATUS_REGISTER_BITS LITERAL1 111 | IDLE LITERAL1 112 | RX_IN_PROGRESS LITERAL1 113 | TX_IN_PROGRESS LITERAL1 114 | BUSY LITERAL1 115 | RX_VALID_MESSAGE LITERAL1 116 | RX_SATELLITE_DETECTED LITERAL1 117 | TX_FINISHED LITERAL1 118 | MCU_COMMAND_ACCEPTED LITERAL1 119 | CRC_CALCULATED LITERAL1 120 | IDLE_STATE LITERAL1 121 | RX_CALIBRATION_FINISHED LITERAL1 122 | RX_TIMEOUT LITERAL1 123 | SATELLITE_TIMEOUT LITERAL1 124 | RX_BUFFER_OVERFLOW LITERAL1 125 | TX_INVALID_MESSAGE LITERAL1 126 | MCU_COMMAND_REJECTED LITERAL1 127 | MCU_COMMAND_OVERFLOW LITERAL1 128 | INTERNAL_ERROR LITERAL1 129 | DSP2MCU_INT1 LITERAL1 130 | DSP2MCU_INT2 LITERAL1 131 | 132 | ARTIC_R2_Burstmode_Register LITERAL1 133 | BURSTMODE_REGISTER LITERAL1 134 | BURSTMODE_REGISTER_BITS LITERAL1 135 | BURSTMODE_START_ADDR LITERAL1 136 | BURST_R_RW_MODE LITERAL1 137 | BURST_MEM_SEL LITERAL1 138 | BURST_MODE_ON LITERAL1 139 | BURSTMODE_REG_SPI_ADDR LITERAL1 140 | 141 | ARTIC_R2_P_MEMORY LITERAL1 142 | ARTIC_R2_X_MEMORY LITERAL1 143 | ARTIC_R2_Y_MEMORY LITERAL1 144 | ARTIC_R2_IO_MEMORY LITERAL1 145 | 146 | ARTIC_R2_WRITE_BURST LITERAL1 147 | ARTIC_R2_READ_BURST LITERAL1 148 | 149 | ARTIC_R2_PLATFORM_ID_BITS LITERAL1 150 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_BITS LITERAL1 151 | 152 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_24 LITERAL1 153 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_56 LITERAL1 154 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_88 LITERAL1 155 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_120 LITERAL1 156 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_152 LITERAL1 157 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_184 LITERAL1 158 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_216 LITERAL1 159 | ARTIC_R2_PTT_A2_MESSAGE_LENGTH_248 LITERAL1 160 | 161 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_BITS 162 | 163 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_24 LITERAL1 164 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_56 LITERAL1 165 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_88 LITERAL1 166 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_120 LITERAL1 167 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_152 LITERAL1 168 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_184 LITERAL1 169 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_216 LITERAL1 170 | ARTIC_R2_PTT_A3_MESSAGE_LENGTH_248 LITERAL1 171 | 172 | ARTIC_R2_PTT_A3_NUM_TAIL_BITS_24 LITERAL1 173 | ARTIC_R2_PTT_A3_NUM_TAIL_BITS_56 LITERAL1 174 | ARTIC_R2_PTT_A3_NUM_TAIL_BITS_88 LITERAL1 175 | ARTIC_R2_PTT_A3_NUM_TAIL_BITS_120 LITERAL1 176 | ARTIC_R2_PTT_A3_NUM_TAIL_BITS_152 LITERAL1 177 | ARTIC_R2_PTT_A3_NUM_TAIL_BITS_184 LITERAL1 178 | ARTIC_R2_PTT_A3_NUM_TAIL_BITS_216 LITERAL1 179 | ARTIC_R2_PTT_A3_NUM_TAIL_BITS_248 LITERAL1 180 | 181 | ARTIC_R2_PTT_ZE_NUM_TAIL_BITS LITERAL1 182 | 183 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_BITS LITERAL1 184 | 185 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_32 LITERAL1 186 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_512 LITERAL1 187 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_1024 LITERAL1 188 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_1536 LITERAL1 189 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_2048 LITERAL1 190 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_2560 LITERAL1 191 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_3072 LITERAL1 192 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_3584 LITERAL1 193 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_4096 LITERAL1 194 | ARTIC_R2_PTT_A3_HD_MESSAGE_LENGTH_4608 LITERAL1 195 | 196 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_32 LITERAL1 197 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_512 LITERAL1 198 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_1024 LITERAL1 199 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_1536 LITERAL1 200 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_2048 LITERAL1 201 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_2560 LITERAL1 202 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_3072 LITERAL1 203 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_3584 LITERAL1 204 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_4096 LITERAL1 205 | ARTIC_R2_PTT_A3_HD_NUM_TAIL_BITS_4608 LITERAL1 206 | 207 | ARTIC_R2_PTT_A4_VLD_NUM_TAIL_BITS LITERAL1 208 | 209 | ARTIC_R2_PTT_A4_VLD_SHORT_NUM_MESSAGE_BITS LITERAL1 210 | ARTIC_R2_PTT_A4_VLD_LONG_NUM_MESSAGE_BITS LITERAL1 211 | 212 | CONFIG_CMD_SET_ARGOS_4_RX_MODE LITERAL1 213 | CONFIG_CMD_SET_ARGOS_3_RX_MODE LITERAL1 214 | CONFIG_CMD_SET_ARGOS_3_RX_BACKUP_MODE LITERAL1 215 | CONFIG_CMD_SET_PTT_A2_TX_MODE LITERAL1 216 | CONFIG_CMD_SET_PTT_A3_TX_MODE LITERAL1 217 | CONFIG_CMD_SET_PTT_ZE_TX_MODE LITERAL1 218 | CONFIG_CMD_SET_ARGOS_3_PTT_HD_TX_MODE LITERAL1 219 | CONFIG_CMD_SET_ARGOS_4_PTT_HD_TX_MODE LITERAL1 220 | CONFIG_CMD_SET_ARGOS_4_PTT_MD_TX_MODE LITERAL1 221 | CONFIG_CMD_SET_ARGOS_4_PTT_VLD_TX_MODE LITERAL1 222 | 223 | ARTIC_R2_MCU_COMMAND_ACCEPTED LITERAL1 224 | ARTIC_R2_MCU_COMMAND_REJECTED LITERAL1 225 | ARTIC_R2_MCU_COMMAND_OVERFLOW LITERAL1 226 | ARTIC_R2_MCU_COMMAND_UNCERTAIN LITERAL1 227 | ARTIC_R2_MCU_COMMAND_INVALID LITERAL1 228 | ARTIC_R2_MCU_INSTRUCTION_IN_PROGRESS LITERAL1 229 | ARTIC_R2_MCU_COMMAND_VALID LITERAL1 230 | 231 | ARGOS_Configuration_Register LITERAL1 232 | CONFIGURATION_REGISTER LITERAL1 233 | CONFIGURATION_REGISTER_BITS LITERAL1 234 | TX_CONFIGURATION LITERAL1 235 | RX_CONFIGURATION LITERAL1 236 | 237 | RX_CONFIG_ARGOS_3_RX_MODE LITERAL1 238 | RX_CONFIG_ARGOS_3_RX_BACKUP_MODE LITERAL1 239 | RX_CONFIG_ARGOS_4_RX_MODE LITERAL1 240 | 241 | TX_CONFIG_ARGOS_PTT_A2_MODE LITERAL1 242 | TX_CONFIG_ARGOS_PTT_A3_MODE LITERAL1 243 | TX_CONFIG_ARGOS_PTT_ZE_MODE LITERAL1 244 | TX_CONFIG_ARGOS_PTT_HD_MODE LITERAL1 245 | TX_CONFIG_ARGOS_PTT_A4_MD_MODE LITERAL1 246 | TX_CONFIG_ARGOS_PTT_A4_HD_MODE LITERAL1 247 | TX_CONFIG_ARGOS_PTT_A4_VLD_MODE LITERAL1 248 | 249 | INST_START_CONTINUOUS_RECEPTION LITERAL1 250 | INST_START_RECEIVING_1_MESSAGE LITERAL1 251 | INST_START_RECEIVING_2_MESSAGES LITERAL1 252 | INST_START_RECEPTION_FOR_FIXED_TIME LITERAL1 253 | INST_TRANSMIT_ONE_PACKAGE_AND_GO_IDLE LITERAL1 254 | INST_TRANSMIT_ONE_PACKAGE_AND_START_RX LITERAL1 255 | INST_GO_TO_IDLE LITERAL1 256 | INST_SATELLITE_DETECTION LITERAL1 257 | 258 | ARTIC_R2_MCU_Instruction_Progress LITERAL1 259 | ARTIC_R2_MCU_PROGRESS_NONE_IN_PROGRESS LITERAL1 260 | ARTIC_R2_MCU_PROGRESS_CONTINUOUS_RECEPTION LITERAL1 261 | ARTIC_R2_MCU_PROGRESS_CONTINUOUS_RECEPTION_RX_SATELLITE_DETECTED LITERAL1 262 | ARTIC_R2_MCU_PROGRESS_CONTINUOUS_RECEPTION_RX_VALID_MESSAGE LITERAL1 263 | ARTIC_R2_MCU_PROGRESS_CONTINUOUS_RECEPTION_RX_BUFFER_OVERFLOW LITERAL1 264 | ARTIC_R2_MCU_PROGRESS_RECEIVE_ONE_MESSAGE LITERAL1 265 | ARTIC_R2_MCU_PROGRESS_RECEIVE_ONE_MESSAGE_RX_SATELLITE_DETECTED LITERAL1 266 | ARTIC_R2_MCU_PROGRESS_RECEIVE_ONE_MESSAGE_RX_VALID_MESSAGE LITERAL1 267 | ARTIC_R2_MCU_PROGRESS_RECEIVE_TWO_MESSAGES LITERAL1 268 | ARTIC_R2_MCU_PROGRESS_RECEIVE_TWO_MESSAGES_RX_SATELLITE_DETECTED LITERAL1 269 | ARTIC_R2_MCU_PROGRESS_RECEIVE_TWO_MESSAGES_RX_VALID_MESSAGE LITERAL1 270 | ARTIC_R2_MCU_PROGRESS_RECEIVE_FIXED_TIME LITERAL1 271 | ARTIC_R2_MCU_PROGRESS_RECEIVE_FIXED_TIME_RX_SATELLITE_DETECTED LITERAL1 272 | ARTIC_R2_MCU_PROGRESS_RECEIVE_FIXED_TIME_RX_VALID_MESSAGE LITERAL1 273 | ARTIC_R2_MCU_PROGRESS_RECEIVE_FIXED_TIME_RX_BUFFER_OVERFLOW LITERAL1 274 | ARTIC_R2_MCU_PROGRESS_RECEIVE_FIXED_TIME_RX_TIMEOUT LITERAL1 275 | ARTIC_R2_MCU_PROGRESS_RECEIVE_FIXED_TIME_RX_TIMEOUT_WITH_VALID_MESSAGE LITERAL1 276 | ARTIC_R2_MCU_PROGRESS_RECEIVE_FIXED_TIME_RX_TIMEOUT_WITH_BUFFER_OVERFLOW LITERAL1 277 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_GO_IDLE LITERAL1 278 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_GO_IDLE_IDLE_STATE LITERAL1 279 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_GO_IDLE_TX_FINISHED LITERAL1 280 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_GO_IDLE_TX_INVALID_MESSAGE LITERAL1 281 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX LITERAL1 282 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX_TX_FINISHED LITERAL1 283 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX_TX_INVALID_MESSAGE LITERAL1 284 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX_RX_SATELLITE_DETECTED LITERAL1 285 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX_RX_VALID_MESSAGE LITERAL1 286 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX_RX_BUFFER_OVERFLOW LITERAL1 287 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX_RX_TIMEOUT LITERAL1 288 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX_RX_TIMEOUT_WITH_VALID_MESSAGE LITERAL1 289 | ARTIC_R2_MCU_PROGRESS_TRANSMIT_ONE_FIXED_RX_RX_TIMEOUT_WITH_BUFFER_OVERFLOW LITERAL1 290 | ARTIC_R2_MCU_PROGRESS_GO_TO_IDLE LITERAL1 291 | ARTIC_R2_MCU_PROGRESS_GO_TO_IDLE_IDLE_STATE LITERAL1 292 | ARTIC_R2_MCU_PROGRESS_SATELLITE_DETECTION LITERAL1 293 | ARTIC_R2_MCU_PROGRESS_SATELLITE_DETECTION_RX_SATELLITE_DETECTED LITERAL1 294 | ARTIC_R2_MCU_PROGRESS_SATELLITE_DETECTION_SATELLITE_TIMEOUT LITERAL1 295 | ARTIC_R2_MCU_PROGRESS_INTERNAL_ERROR LITERAL1 296 | ARTIC_R2_MCU_PROGRESS_UNKNOWN_INSTRUCTION LITERAL1 297 | 298 | CMD_CLEAR_INT_1 LITERAL1 299 | CMD_CLEAR_INT_2 LITERAL1 300 | 301 | ARTIC_R2_BURSTMODE_REG_WRITE LITERAL1 302 | ARTIC_R2_DSP_CRTL_REG_WRITE LITERAL1 303 | ARTIC_R2_DSP_CRTL_REG_READ LITERAL1 304 | ARTIC_R2_DSP_CRTL_REG_MAGIC_NUMBER LITERAL1 305 | 306 | ARTIC_R2_FIRMWARE_VERSION LITERAL1 307 | MEM_LOC_FIRMWARE_VERSION LITERAL1 308 | 309 | MEM_LOC_ARGOS_CONFIGURATION LITERAL1 310 | MEM_LOC_RX_PAYLOAD LITERAL1 311 | MEM_LOC_RX_FILTERING_CONFIGURATION LITERAL1 312 | MEM_LOC_RX_FILTERING_ENABLE_CRC LITERAL1 313 | MEM_LOC_RX_FILTERING_TRANSPARENT_MODE LITERAL1 314 | MEM_LOC_RX_FILTERING_LUT_LENGTH LITERAL1 315 | MEM_LOC_RX_FILTERING_LUT_FIRST_ADDRESS LITERAL1 316 | MEM_LOC_RX_TIMEOUT LITERAL1 317 | MEM_LOC_SATELLITE_DETECTION_TIMEOUT LITERAL1 318 | MEM_LOC_TX_PAYLOAD LITERAL1 319 | MEM_LOC_TX_FREQ_ARGOS_2_3 LITERAL1 320 | MEM_LOC_TX_FREQ_ARGOS_4 LITERAL1 321 | MEM_LOC_TCXO_WARMUP_TIME LITERAL1 322 | MEM_LOC_TCXO_CONTROL LITERAL1 323 | MEM_LOC_CRC_RESULTS LITERAL1 324 | MEM_LOC_TX_CERTIFICATION_INTERVAL LITERAL1 325 | MEM_LOC_FLASH_PROG_BUFFER LITERAL1 326 | 327 | MEM_LOC_FIRMWARE_STATUS_REGISTER LITERAL1 328 | 329 | TCXO_Control_Register LITERAL1 330 | TCXO_CONTROL_REGISTER LITERAL1 331 | CONTROL_REGISTER_BITS LITERAL1 332 | AUTO_DISABLE LITERAL1 333 | SELECT_1V3_TO_2V7 LITERAL1 334 | SELECT_1V8 LITERAL1 335 | SELECT_3V3 LITERAL1 336 | 337 | Downlink_Message LITERAL1 338 | payloadLength LITERAL1 339 | addresseeIdentification LITERAL1 340 | ADCS LITERAL1 341 | service LITERAL1 342 | payload LITERAL1 343 | FCS LITERAL1 344 | 345 | bulletin_data_t LITERAL1 346 | ARTIC_R2_AOP_ENTRY_WIDTH LITERAL1 347 | 348 | _txPayloadBytes LITERAL1 349 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=SparkFun ARGOS ARTIC R2 Arduino Library 2 | version=1.1.2 3 | author=SparkFun Electronics 4 | maintainer=SparkFun Electronics 5 | sentence=Library for the ARGOS ARTIC R2 chipset found on the SparkFun ARTIC R2 Breakout 6 | paragraph=An Arduino Library for the ARGOS ARTIC R2 chipset found on the SparkFun ARTIC R2 Breakout. This library allows you to send and receive short data messages via the ARGOS satellite system. 7 | category=Communication 8 | url=https://github.com/sparkfun/SparkFun_ARGOS_ARTIC_R2_Arduino_Library 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/ARTIC_R2_Firmware.h: -------------------------------------------------------------------------------- 1 | // These are the firmware parameter memory locations for the ARTIC006 firmware 2 | // They are defined in the Release_README.txt for ARTIC006 3 | // The locations for ARTIC004 are very different! 4 | 5 | #ifndef ARTIC_R2_MEM_LOC_H 6 | #define ARTIC_R2_MEM_LOC_H 7 | 8 | const uint8_t ARTIC_R2_FIRMWARE_VERSION = 6; // Make it clear that we are using ARTIC006 9 | 10 | const uint32_t ARTIC_R2_PMEM_LEN = 10240; // PMEM Length in 32-Bit Words 11 | const uint32_t ARTIC_R2_XMEM_LEN = 21845; // XMEM Length in 24-Bit Words 12 | const uint32_t ARTIC_R2_YMEM_LEN = 6826; // YMEM Length in 24-Bit Words 13 | 14 | const uint32_t ARTIC_R2_PMEM_CHECKSUM = 0x4DC69E; // ARTIC006 15 | const uint32_t ARTIC_R2_XMEM_CHECKSUM = 0x4A51F6; // ARTIC006 16 | const uint32_t ARTIC_R2_YMEM_CHECKSUM = 0x65CC81; // ARTIC006 17 | 18 | // P Memory Locations 19 | const uint16_t MEM_LOC_FIRMWARE_VERSION = 0x0010; // 2 * 32-bit words = 8 bytes: 'ARTICnnn' 20 | const uint16_t MEM_LOC_PLATFORM_ID = 10239; // Platform ID is stored in the 28 least significant bits of the final PMEM location 21 | 22 | // X Memory locations 23 | const uint16_t MEM_LOC_ARGOS_CONFIGURATION = 0x137E; // Size 1. Read only (Was 0x0384 in ARTIC004) 24 | const uint16_t MEM_LOC_RX_PAYLOAD = 0x1204; // Size 9. Read only (Was 0x0200 in ARTIC004) 25 | const uint16_t MEM_LOC_RX_FILTERING_CONFIGURATION = 0x120D; // Size 104. Read/Write (Was 0x0209 in ARTIC004) 26 | const uint16_t MEM_LOC_RX_FILTERING_ENABLE_CRC = 0x120D; // Size 1. Read/Write 27 | const uint16_t MEM_LOC_RX_FILTERING_TRANSPARENT_MODE = 0x120E; // Size 1. Read/Write 28 | const uint16_t MEM_LOC_RX_FILTERING_LUT_LENGTH = 0x120F; // Size 1. Read/Write 29 | const uint16_t MEM_LOC_RX_FILTERING_LUT_FIRST_ADDRESS = 0x1210; // Read/Write 30 | const uint16_t MEM_LOC_RX_TIMEOUT = 0x1275; // Size 1. Read/Write (Was 0x0271 in ARTIC004) 31 | const uint16_t MEM_LOC_SATELLITE_DETECTION_TIMEOUT = 0x1276; // Size 1. Read/Write (Was 0x0272 in ARTIC004) 32 | const uint16_t MEM_LOC_TX_PAYLOAD = 0x1277; // Size 220. Write only. (Was 0x0273 in ARTIC004) 33 | const uint16_t MEM_LOC_TX_FREQ_ARGOS_2_3 = 0x1353; // Size 1. Read/Write (Was 0x034F in ARTIC004) 34 | const uint16_t MEM_LOC_TX_FREQ_ARGOS_4 = 0x1363; // Size 1. Read/Write (Was 0x035F in ARTIC004) 35 | const uint16_t MEM_LOC_TCXO_WARMUP_TIME = 0x1373; // Sizde 1. Read/Write (Was 0x036F in ARTIC004) 36 | const uint16_t MEM_LOC_TCXO_CONTROL = 0x1374; // Size 1. Read/Write (Was 0x0370 in ARTIC004) 37 | const uint16_t MEM_LOC_CRC_RESULTS = 0x1375; // Size 3. Read only. (Was 0x0371 in ARTIC004) 38 | const uint16_t MEM_LOC_TX_CERTIFICATION_INTERVAL = 0x137D; // Size 1. Read/Write (Was 0x0379 in ARTIC004) 39 | const uint16_t MEM_LOC_FLASH_PROG_BUFFER = 0x137F; // Flash Programming Buffer (New in ARTIC006) 40 | 41 | // IO Memory locations 42 | const uint16_t MEM_LOC_FIRMWARE_STATUS_REGISTER = 0x8018; 43 | 44 | // Include the firmware for SPI upload - if desired 45 | #ifdef ARTIC_R2_UPLOAD_FIRMWARE 46 | 47 | // Include firmware binary data 48 | // P 32-bit 10240 DSP Program memory 49 | const uint32_t ARTIC_R2_PMEM[ARTIC_R2_PMEM_LEN] = { 50 | #include "ARTIC_R2_Firmware_PMEM.h" 51 | }; 52 | 53 | // X 24-bit 21845 DSP X memory 54 | const uint32_t ARTIC_R2_XMEM[ARTIC_R2_XMEM_LEN] = { 55 | #include "ARTIC_R2_Firmware_XMEM.h" 56 | }; 57 | 58 | // Y 24-bit 6826 DSP Y memory 59 | const uint32_t ARTIC_R2_YMEM[ARTIC_R2_YMEM_LEN] = { 60 | #include "ARTIC_R2_Firmware_YMEM.h" 61 | }; 62 | 63 | #endif 64 | 65 | #endif 66 | --------------------------------------------------------------------------------