Skip to content

Instantly share code, notes, and snippets.

@sayacom
Last active December 24, 2021 00:47
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save sayacom/7c20cf766db7476b1c8ba4950e748e0f to your computer and use it in GitHub Desktop.
#include <Wire.h>
#include <MsgPack.h>
#include "DHT.h"
#include "Seeed_BMP280.h"
#include "LIS3DHTR.h"
// Pin assignments for digital/analog input
char led = 4;
char buzzer = 5;
char button = 6;
char rotary = A0;
char light = A6;
char sound = A2;
// Temperature and Humidity sensor
DHT dht(3,DHT11);
// Air pressure sensor
BMP280 bmp280;
// Accelemeter Sensor
LIS3DHTR<TwoWire> accelemeter;
/**
* if you want to parse this structure by binary-parser, use this definition below (by one-line):
* button::int:16:little-endian rotaryEncoder::int:16:little-endian light::int:16:little-endian temperature::int:16:little-endian humidity::int:16:little-endian
* pressure::float:32:little-endian acceleratorX::float:32:little-endian acceleratorY::float:32:little-endian acceleratorZ::float:32:little-endian
*/
typedef struct {
bool button;
int rotaryEncoder;
int light;
int temperature;
int humidity;
float pressure;
float acceleratorX;
float acceleratorY;
float acceleratorZ;
} GroveBeginnerInputValues;
#define CONSOLE Serial
// Definition for LTE-M Shield(BG96) Pins
#define BG96_TX 11
#define BG96_RX 10
#define BG96_RST 15
#define BG96_BAUDRATE 9600
#define TINY_GSM_MODEM_BG96
#include <TinyGsmClient.h>
#include <SoftwareSerial.h>
SoftwareSerial LTEModemUART(BG96_RX, BG96_TX);
//#define USE_DEBUG_OUTPUT
#ifdef USE_DEBUG_OUTPUT
#include <StreamDebugger.h>
StreamDebugger debugger(LTEModemUART, CONSOLE);
TinyGsm LTEModem(debugger);
TinyGsmClient LTEClient(LTEModem);
#else
TinyGsm LTEModem(LTEModemUART);
TinyGsmClient LTEClient(LTEModem);
#endif
void initializeBG96() {
// Send RESET
pinMode(BG96_RST, OUTPUT);
digitalWrite(BG96_RST, LOW);
delay(300);
digitalWrite(BG96_RST, HIGH);
delay(300);
digitalWrite(BG96_RST, LOW);
// Start LTE Modem Software Serial
LTEModemUART.begin(BG96_BAUDRATE);
CONSOLE.println(F("Restarting modem..."));
LTEModem.restart();
CONSOLE.println(F("--- Modem Info ---"));
String info = LTEModem.getModemInfo();
CONSOLE.println(info);
CONSOLE.println(F("--- End Info ---"));
// Wait for catch cellular wireless
CONSOLE.print("Waiting network...");
while(!LTEModem.waitForNetwork()) CONSOLE.print(".");
CONSOLE.println(F("OK!"));
// Connect SORACOM network
CONSOLE.print("Connecting SORACOM...");
LTEModem.gprsConnect("soracom.io", "sora", "sora");
while(!LTEModem.isNetworkConnected()) CONSOLE.print(".");
CONSOLE.println(F("OK!"));
// Show device IP address
CONSOLE.print("Device IP Address: ");
IPAddress ipaddr = LTEModem.localIP();
CONSOLE.println(ipaddr);
}
void initializeGroveBeginnerKitModules() {
// Initialize BMP280 (air pressure sensor)
if(!bmp280.init()){
CONSOLE.println(F("Failed to initialize BMP280!"));
while(1);
}
CONSOLE.print(".");
// Initialize LIS3DHTR (accelemeter sensor)
accelemeter.begin(Wire, LIS3DHTR_ADDRESS_UPDATED);
delay(100);
accelemeter.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
if (!accelemeter) {
CONSOLE.println(F("Failed to initialize LIS3DHTR"));
}
CONSOLE.print(".");
// Setup pin mode for modules
pinMode(rotary, INPUT);
pinMode(button, INPUT);
pinMode(light, INPUT);
pinMode(sound, INPUT);
pinMode(led, OUTPUT);
pinMode(buzzer, OUTPUT);
digitalWrite(buzzer, LOW);
CONSOLE.print(".");
}
void setup() {
CONSOLE.begin(115200);
CONSOLE.print("Initializing Sensors...");
initializeGroveBeginnerKitModules();
CONSOLE.println(F("OK!"));
CONSOLE.println(F("Initializing LTE-M Modem..."));
initializeBG96();
CONSOLE.println(F("OK!"));
}
char *toFloatString(float value) {
static char str[20] = { 0 };
dtostrf((float)value, 10, 2, str);
return str;
}
int connect() {
static bool INITIAL_CONNECTED = false;
if (LTEClient.connected()) {
CONSOLE.println(F("Already connected"));
return 0;
}
if (!INITIAL_CONNECTED && !LTEClient.connected()) {
CONSOLE.print("Initial Connecting...");
}
else if (INITIAL_CONNECTED && !LTEClient.connected()) {
CONSOLE.print("Reconnecting...");
}
// Connect Unified Endpoint (TCP)
if (!LTEClient.connect("uni.soracom.io", 23080)) {
CONSOLE.println(F("Failed to connect unified endpoint."));
return -1;
}
CONSOLE.println(F("OK."));
if (!INITIAL_CONNECTED) {
INITIAL_CONNECTED = true;
}
return 0;
}
void close() {
CONSOLE.print("Stopping...");
LTEClient.stop(1000);
CONSOLE.println(F("OK."));
}
void sendBinary(GroveBeginnerInputValues v) {
// Generate MsgPack Structure
MsgPack::Packer packer;
packer.serialize(MsgPack::map_size_t(8),
"merry", "christmas!",
"button", v.button,
"rotaryEncoder", v.rotaryEncoder,
"light", v.light,
"temp", v.temperature,
"humid", v.humidity,
"pressure", v.pressure,
"accel", MsgPack::map_size_t(3),
"x", v.acceleratorX,
"y", v.acceleratorY,
"z", v.acceleratorZ);
// Debug output
char buf[5] = { 0 };
CONSOLE.print("MsgPack-ed hex value: ");
for (int i=0; i<packer.size(); i++) {
sprintf(buf, "%02x ", packer.data()[i]);
CONSOLE.print(buf);
}
CONSOLE.println();
// Send binaries
LTEClient.write(packer.data(), packer.size());
// Receive response
while(LTEClient.connected()) {
String line = LTEClient.readString();
CONSOLE.println(line);
if (line == "\r" || line == "\n" || line.length() <= 0) {
CONSOLE.println(F("[END]"));
break;
}
}
}
void loop() {
char stdoutBuf[64] = { 0 };
GroveBeginnerInputValues inputValues, *v;
v = &inputValues;
while(1) {
memset(stdoutBuf, 0, sizeof(stdoutBuf));
memset(&inputValues, 0, sizeof(GroveBeginnerInputValues));
// Wait while button to be pushed
CONSOLE.println(F("Push button to send data, waiting..."));
int buttonStatus = LOW;
while(buttonStatus == LOW) {
buttonStatus = digitalRead(button);
}
// Connect Unified Endpoint (TCP)
if (connect() < 0) return;
// Read sensor values
v -> button = digitalRead(button);
v -> rotaryEncoder = analogRead(rotary);
v -> light = analogRead(light);
v -> temperature = dht.readTemperature();
v -> humidity = dht.readHumidity();
v -> pressure = (bmp280.getPressure() / 100.0);
v -> acceleratorX = accelemeter.getAccelerationX();
v -> acceleratorY = -accelemeter.getAccelerationY();
v -> acceleratorZ = accelemeter.getAccelerationZ();
// Output values to console
CONSOLE.println();
CONSOLE.println(F("--- VALUES ---"));
sprintf(stdoutBuf, "Rotary: %d\n", v -> rotaryEncoder);
CONSOLE.print(stdoutBuf);
memset(stdoutBuf, 0, sizeof(stdoutBuf));
sprintf(stdoutBuf, "Light: %d\n", v -> light);
CONSOLE.print(stdoutBuf);
memset(stdoutBuf, 0, sizeof(stdoutBuf));
sprintf(stdoutBuf, "Temp: %d\n", v -> temperature);
CONSOLE.print(stdoutBuf);
memset(stdoutBuf, 0, sizeof(stdoutBuf));
sprintf(stdoutBuf, "Humid: %d\n", v -> humidity);
CONSOLE.print(stdoutBuf);
memset(stdoutBuf, 0, sizeof(stdoutBuf));
sprintf(stdoutBuf, "Pressure: %s\n", toFloatString(v -> pressure));
CONSOLE.print(stdoutBuf);
memset(stdoutBuf, 0, sizeof(stdoutBuf));
CONSOLE.println(F("Accel:"));
sprintf(stdoutBuf, " X: %s\n", toFloatString(v -> acceleratorX));
CONSOLE.print(stdoutBuf);
memset(stdoutBuf, 0, sizeof(stdoutBuf));
sprintf(stdoutBuf, " Y: %s\n", toFloatString(v -> acceleratorY));
CONSOLE.print(stdoutBuf);
memset(stdoutBuf, 0, sizeof(stdoutBuf));
sprintf(stdoutBuf, " Z: %s\n", toFloatString(v -> acceleratorZ));
CONSOLE.print(stdoutBuf);
memset(stdoutBuf, 0, sizeof(stdoutBuf));
CONSOLE.println(F("--- END ---"));
CONSOLE.println();
// Send via TCP
sendBinary(*v);
close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment