Created
May 31, 2024 17:23
-
-
Save rdlauer/81d222b5a47e63e14f63f77f34793950 to your computer and use it in GitHub Desktop.
Inbound and Outbound Messaging over Satellite IoT with Blues Starnote
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Arduino.h> | |
#include <Adafruit_GFX.h> | |
#include <SPI.h> | |
#include <Wire.h> | |
#include <Adafruit_ILI9341.h> | |
#include <Fonts/FreeSans9pt7b.h> | |
#include <Adafruit_NeoPixel.h> | |
#include <BBQ10Keyboard.h> | |
#include <Notecard.h> | |
#include "base64.hpp" | |
#define TFT_CS 9 | |
#define TFT_DC 10 | |
#define NEOPIXEL_PIN 11 | |
#define productUID "your-product-uid" | |
#define serialDebug Serial | |
HardwareSerial stlinkSerial(PIN_VCP_RX, PIN_VCP_TX); // using optional STLINK | |
Adafruit_ILI9341 tft(TFT_CS, TFT_DC); | |
Adafruit_NeoPixel pixels(1, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); | |
BBQ10Keyboard keyboard; | |
Notecard notecard; | |
String msg = ""; | |
unsigned long time_now = 0; | |
unsigned long last_inbound_check = 0; | |
void setup() | |
{ | |
#ifdef serialDebug | |
stlinkSerial.begin(115200); | |
const size_t usb_timeout_ms = 3000; | |
for (const size_t start_ms = millis(); !stlinkSerial && (millis() - start_ms) < usb_timeout_ms;) | |
; | |
notecard.setDebugOutputStream(stlinkSerial); | |
#endif | |
Wire.begin(); | |
// Initialize Notecard | |
notecard.begin(); | |
// Connect Notecard to your Notehub account (the Product UID) | |
J *req = notecard.newRequest("hub.set"); | |
if (req != NULL) | |
{ | |
JAddStringToObject(req, "product", productUID); | |
JAddStringToObject(req, "mode", "minimum"); | |
notecard.sendRequestWithRetry(req, 5); | |
} | |
// Put the Notecard in the relevant NTN mode | |
req = notecard.newRequest("card.transport"); | |
if (req != NULL) | |
{ | |
JAddStringToObject(req, "method", "wifi-cell-ntn"); | |
notecard.sendRequestWithRetry(req, 5); | |
} | |
// Create a Note template for **OUTBOUND** messages to Notehub/Twilio | |
req = notecard.newRequest("note.template"); | |
if (req != NULL) | |
{ | |
JAddStringToObject(req, "file", "outbound_msg.qo"); | |
JAddStringToObject(req, "format", "compact"); | |
JAddNumberToObject(req, "port", 45); | |
J *body = JCreateObject(); | |
if (body != NULL) | |
{ | |
JAddStringToObject(body, "message", "x"); | |
JAddItemToObject(req, "body", body); | |
} | |
notecard.sendRequestWithRetry(req, 5); | |
} | |
// Create a Note template for **INBOUND** messages from Notehub/Twilio | |
req = notecard.newRequest("note.template"); | |
if (req != NULL) | |
{ | |
JAddStringToObject(req, "file", "inbound_msg.qi"); | |
JAddStringToObject(req, "format", "compact"); | |
JAddNumberToObject(req, "port", 46); | |
J *body = JCreateObject(); | |
if (body != NULL) | |
{ | |
JAddStringToObject(body, "message", "x"); | |
JAddItemToObject(req, "body", body); | |
} | |
notecard.sendRequestWithRetry(req, 5); | |
} | |
// OPTIONAL: Set a fixed GPS location | |
req = notecard.newRequest("card.location.mode"); | |
if (req != NULL) | |
{ | |
JAddStringToObject(req, "mode", "fixed"); | |
JAddNumberToObject(req, "lat", 0); // add your lat/lon! | |
JAddNumberToObject(req, "lon", 0); | |
} | |
notecard.sendRequestWithRetry(req, 5); | |
// Force a sync between the Notecard and Notehub | |
req = notecard.newRequest("hub.sync"); | |
if (req != NULL) | |
{ | |
notecard.sendRequestWithRetry(req, 5); | |
} | |
tft.begin(); | |
pixels.begin(); | |
pixels.setBrightness(30); | |
keyboard.begin(); | |
keyboard.setBacklight(0.5f); | |
tft.setRotation(1); | |
tft.fillScreen(ILI9341_BLACK); | |
tft.setTextSize(1); | |
tft.setFont(&FreeSans9pt7b); | |
tft.print("\nWi-Fi/Cell/Satellite SMS with Blues!\n"); | |
} | |
void theaterChase(uint32_t color, int wait) | |
{ | |
for (int a = 0; a < 20; a++) | |
{ | |
for (int b = 0; b < 3; b++) | |
{ | |
pixels.clear(); | |
for (int c = b; c < pixels.numPixels(); c += 3) | |
{ | |
pixels.setPixelColor(c, color); | |
} | |
pixels.show(); | |
delay(wait); | |
} | |
} | |
} | |
void loop() | |
{ | |
if (keyboard.keyCount()) | |
{ | |
const BBQ10Keyboard::KeyEvent key = keyboard.keyEvent(); | |
if (key.state == BBQ10Keyboard::StateRelease) | |
{ | |
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); | |
pixels.show(); | |
tft.print(key.key); | |
if (key.key == '\6') | |
{ | |
// this is the top left "custom" button on the keyboard | |
J *req = notecard.newRequest("hub.sync"); | |
if (req != NULL) | |
{ | |
notecard.sendRequestWithRetry(req, 5); | |
} | |
tft.print("Manually check for inbound message!\n"); | |
} | |
else if ((int)key.key == 8) | |
{ | |
// erase previous character | |
if (msg.length() > 0) | |
{ | |
msg = msg.substring(0, msg.length() - 1); | |
tft.fillScreen(ILI9341_BLACK); | |
tft.setCursor(0, 10); | |
tft.print(msg); | |
} | |
} | |
else if ((int)key.key == 10) | |
{ | |
// carriage return | |
serialDebug.println("return!"); | |
if (msg.length() > 0) | |
{ | |
theaterChase(pixels.Color(0, 0, 127), 50); // Blue | |
// add a note | |
J *req = notecard.newRequest("note.add"); | |
if (req != NULL) | |
{ | |
JAddStringToObject(req, "file", "outbound_msg.qo"); | |
J *body = JCreateObject(); | |
if (body != NULL) | |
{ | |
JAddStringToObject(body, "message", msg.c_str()); | |
JAddItemToObject(req, "body", body); | |
} | |
notecard.sendRequestWithRetry(req, 5); | |
} | |
req = notecard.newRequest("hub.sync"); | |
if (req != NULL) | |
{ | |
notecard.sendRequestWithRetry(req, 5); | |
} | |
tft.print("Message sent!\n"); | |
msg = ""; | |
} | |
} | |
else | |
{ | |
// any other character | |
msg += key.key; | |
} | |
pixels.clear(); | |
pixels.show(); | |
} | |
} | |
// Check to see if there are any inbound messages (Notes) needing processing | |
time_now = millis(); | |
if (time_now > last_inbound_check + 5000) // every 5 secs | |
{ | |
last_inbound_check = millis(); | |
J *req = NoteNewRequest("note.get"); | |
if (req != NULL) | |
{ | |
JAddStringToObject(req, "file", "inbound_msg.qi"); | |
JAddBoolToObject(req, "delete", true); | |
J *rsp = notecard.requestAndResponse(req); | |
if (rsp && JGetObject(rsp, "body")) | |
{ | |
theaterChase(pixels.Color(255, 0, 0), 50); // red notification for inbound msg | |
J *body = JGetObject(rsp, "body"); | |
String inbound_msg = JGetString(body, "message"); | |
tft.print("New inbound message:\n"); | |
tft.print(inbound_msg); | |
tft.print("\n"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment