master
iotcat 5 years ago
parent 6e87f91e84
commit eebca9b33a
  1. 235
      opt/gateway/LoRa_GateWay_esp32/LoRa_GateWay_esp32.ino
  2. 62
      opt/gateway/LoRa_GateWay_esp32/lora-mqtt.h
  3. 246
      opt/gateway/LoRa_GateWay_esp32/lora-socket.h
  4. 77
      opt/gateway/LoRa_GateWay_esp32/stringVec.h
  5. 269
      opt/gateway/LoRa_GateWay_esp32/vector.h
  6. BIN
      opt/station.zip
  7. 7
      opt/station/.vscode/arduino.json
  8. 10
      opt/station/.vscode/bin/build.options.json
  9. 13
      opt/station/.vscode/bin/core/CDC.cpp.d
  10. BIN
      opt/station/.vscode/bin/core/CDC.cpp.o
  11. 15
      opt/station/.vscode/bin/core/HardwareSerial.cpp.d
  12. BIN
      opt/station/.vscode/bin/core/HardwareSerial.cpp.o
  13. 15
      opt/station/.vscode/bin/core/HardwareSerial0.cpp.d
  14. BIN
      opt/station/.vscode/bin/core/HardwareSerial0.cpp.o
  15. 15
      opt/station/.vscode/bin/core/HardwareSerial1.cpp.d
  16. BIN
      opt/station/.vscode/bin/core/HardwareSerial1.cpp.o
  17. 15
      opt/station/.vscode/bin/core/HardwareSerial2.cpp.d
  18. BIN
      opt/station/.vscode/bin/core/HardwareSerial2.cpp.o
  19. 15
      opt/station/.vscode/bin/core/HardwareSerial3.cpp.d
  20. BIN
      opt/station/.vscode/bin/core/HardwareSerial3.cpp.o
  21. 15
      opt/station/.vscode/bin/core/IPAddress.cpp.d
  22. BIN
      opt/station/.vscode/bin/core/IPAddress.cpp.o
  23. 14
      opt/station/.vscode/bin/core/PluggableUSB.cpp.d
  24. BIN
      opt/station/.vscode/bin/core/PluggableUSB.cpp.o
  25. 13
      opt/station/.vscode/bin/core/Print.cpp.d
  26. BIN
      opt/station/.vscode/bin/core/Print.cpp.o
  27. 13
      opt/station/.vscode/bin/core/Stream.cpp.d
  28. BIN
      opt/station/.vscode/bin/core/Stream.cpp.o
  29. 13
      opt/station/.vscode/bin/core/Tone.cpp.d
  30. BIN
      opt/station/.vscode/bin/core/Tone.cpp.o
  31. 14
      opt/station/.vscode/bin/core/USBCore.cpp.d
  32. BIN
      opt/station/.vscode/bin/core/USBCore.cpp.o
  33. 7
      opt/station/.vscode/bin/core/WInterrupts.c.d
  34. BIN
      opt/station/.vscode/bin/core/WInterrupts.c.o
  35. 2
      opt/station/.vscode/bin/core/WMath.cpp.d
  36. BIN
      opt/station/.vscode/bin/core/WMath.cpp.o
  37. 3
      opt/station/.vscode/bin/core/WString.cpp.d
  38. BIN
      opt/station/.vscode/bin/core/WString.cpp.o
  39. 2
      opt/station/.vscode/bin/core/abi.cpp.d
  40. BIN
      opt/station/.vscode/bin/core/abi.cpp.o
  41. BIN
      opt/station/.vscode/bin/core/core.a
  42. 2
      opt/station/.vscode/bin/core/hooks.c.d
  43. BIN
      opt/station/.vscode/bin/core/hooks.c.o
  44. 14
      opt/station/.vscode/bin/core/main.cpp.d
  45. BIN
      opt/station/.vscode/bin/core/main.cpp.o
  46. 2
      opt/station/.vscode/bin/core/new.cpp.d
  47. BIN
      opt/station/.vscode/bin/core/new.cpp.o
  48. 7
      opt/station/.vscode/bin/core/wiring.c.d
  49. BIN
      opt/station/.vscode/bin/core/wiring.c.o
  50. 7
      opt/station/.vscode/bin/core/wiring_analog.c.d
  51. BIN
      opt/station/.vscode/bin/core/wiring_analog.c.o
  52. 7
      opt/station/.vscode/bin/core/wiring_digital.c.d
  53. BIN
      opt/station/.vscode/bin/core/wiring_digital.c.o
  54. 2
      opt/station/.vscode/bin/core/wiring_pulse.S.d
  55. BIN
      opt/station/.vscode/bin/core/wiring_pulse.S.o
  56. 7
      opt/station/.vscode/bin/core/wiring_pulse.c.d
  57. BIN
      opt/station/.vscode/bin/core/wiring_pulse.c.o
  58. 7
      opt/station/.vscode/bin/core/wiring_shift.c.d
  59. BIN
      opt/station/.vscode/bin/core/wiring_shift.c.o
  60. 62
      opt/station/.vscode/bin/includes.cache
  61. 16
      opt/station/.vscode/bin/libraries/LoRa/LoRa.cpp.d
  62. BIN
      opt/station/.vscode/bin/libraries/LoRa/LoRa.cpp.o
  63. 15
      opt/station/.vscode/bin/libraries/SPI/SPI.cpp.d
  64. BIN
      opt/station/.vscode/bin/libraries/SPI/SPI.cpp.o
  65. 8
      opt/station/.vscode/bin/libraries/Wire/Wire.cpp.d
  66. BIN
      opt/station/.vscode/bin/libraries/Wire/Wire.cpp.o
  67. 7
      opt/station/.vscode/bin/libraries/Wire/utility/twi.c.d
  68. BIN
      opt/station/.vscode/bin/libraries/Wire/utility/twi.c.o
  69. 151
      opt/station/.vscode/bin/preproc/ctags_target_for_gcc_minus_e.cpp
  70. 211
      opt/station/.vscode/bin/sketch/BME280.cpp
  71. 17
      opt/station/.vscode/bin/sketch/BME280.cpp.d
  72. BIN
      opt/station/.vscode/bin/sketch/BME280.cpp.o
  73. 54
      opt/station/.vscode/bin/sketch/BME280.h
  74. 28
      opt/station/.vscode/bin/sketch/GY30.cpp
  75. 17
      opt/station/.vscode/bin/sketch/GY30.cpp.d
  76. BIN
      opt/station/.vscode/bin/sketch/GY30.cpp.o
  77. 17
      opt/station/.vscode/bin/sketch/GY30.h
  78. 87
      opt/station/.vscode/bin/sketch/lora-mqtt.h
  79. 289
      opt/station/.vscode/bin/sketch/lora-socket.h
  80. 160
      opt/station/.vscode/bin/sketch/station.ino.cpp
  81. 24
      opt/station/.vscode/bin/sketch/station.ino.cpp.d
  82. BIN
      opt/station/.vscode/bin/sketch/station.ino.cpp.o
  83. 77
      opt/station/.vscode/bin/sketch/stringVec.h
  84. 269
      opt/station/.vscode/bin/sketch/vector.h
  85. 1
      opt/station/.vscode/bin/station.ino.eep
  86. BIN
      opt/station/.vscode/bin/station.ino.elf
  87. 1162
      opt/station/.vscode/bin/station.ino.hex
  88. 1286
      opt/station/.vscode/bin/station.ino.with_bootloader.hex
  89. 19
      opt/station/.vscode/c_cpp_properties.json
  90. 10
      opt/station/.vscode/settings.json
  91. 211
      opt/station/BME280.cpp
  92. 54
      opt/station/BME280.h
  93. 28
      opt/station/GY30.cpp
  94. 17
      opt/station/GY30.h
  95. 87
      opt/station/lora-mqtt.h
  96. 289
      opt/station/lora-socket.h
  97. 149
      opt/station/station.ino
  98. 77
      opt/station/stringVec.h
  99. 269
      opt/station/vector.h

@ -2,13 +2,17 @@
#include <LoRa.h>
#include <WiFi.h>
#define LORA_SOCKET_IP "1.0.0.1"
#include "lora-mqtt.h"
#define MQTT_MAX_TRANSFER_SIZE 99999
#include <PubSubClient.h>
#include <U8x8lib.h>
#include "ovo.h"
#include<ArduinoJson.h>
// WIFI_LoRa_32 ports
// GPIO5 -- SX1278's SCK
@ -27,7 +31,7 @@
//============================
//CHANGE THIS FOR EACH ARDUINO
String nodeId ="Gateway22";
String nodeId ="Gateway";
//============================
const char* ssid = "yimian-iot";
@ -36,14 +40,14 @@ const char* mqtt_server = "192.168.1.102";//change this to the mqtt server
char* topicIn="qos/sync";//change this to the outgoing messages
String cache_mqtt_publish = "";
char* jsonData;
String cache_mqtt_subject = "";
const int capacity = JSON_OBJECT_SIZE(14);//station has 14 objects, its the max amount
StaticJsonDocument<capacity> jb;
WiFiClient espClient;
PubSubClient client(espClient);
LoRaMQTT mqtt;
char outMsg[200];
long lastMsg = 0;
@ -81,14 +85,10 @@ Serial.println("LoRa Receiver");
u8x8.drawString(0, 6, "LoRa failure");
}
mqtt.ini();
mqtt.subscribe("#");
mqtt.onReceived(mqttRes);
LoRa.onReceive(gotMessage);// set the interrupt function
//LoRa_rxMode(); LoRa.receive();// put LoRa in Receive mode
//sendToNode();
//delay(500);
//sendToNode();
//delay(500);
//sendToNode();
Serial.println("Lora Started...\n");
Serial.print("Connecting to ");
Serial.println(ssid);
@ -98,217 +98,26 @@ Serial.println("LoRa Receiver");
void gotMessage(int packetSize)
{
if(packetSize==0)
return;
int i=0;
String msg;
//String buff;
//DynamicJsonBuffer jBuffer;
//JsonObject& root = jBuffer.createObject();
while(LoRa.available())
{
msg+=(char)LoRa.read();
i++;
}
Serial.println(msg);
delay(200);
//sendToNode();
cache_mqtt_publish = msg;
/*deserializeJson(jb, msg);
//5.13.1
DeserializationError err = deserializeJson(jb,msg);
if(err)
{
u8x8.drawString(0, 6, "parse_err");// parse error
return;
}
const char* type=jb["type"];
String topicOut;
//change to string if it doesnt work
u8x8.drawString(0, 6, "from:");// who are we getting messages from?
u8x8.drawString(0, 8, type); //show on LCD
if(type == "node" )
{
int nodeId=jb["id"];
String stat=jb["status"];
String batLev=jb["batteryLevel"];
String watTemp=jb["temperature"];
String qos = jb["qos"];
String switchState=jb["waterSwitch"];
String humid=jb["humidity"];
switch(nodeId)
{
case 0:
topicOut="res/node0/status";
client.publish(topicOut.c_str(), stat.c_str());
topicOut="res/node0/batteryLevel";
client.publish(topicOut.c_str(), batLev.c_str());
topicOut="res/node0/waterSwitch";
client.publish(topicOut.c_str(),switchState.c_str());
topicOut="res/node0/temperature";
client.publish(topicOut.c_str(), watTemp.c_str());
topicOut="res/node0/humidity";
client.publish(topicOut.c_str(),humid.c_str());
topicOut="qos/node0";
client.publish(topicOut.c_str(),qos.c_str());
break;
case 1:
topicOut="res/node1/status";
client.publish(topicOut.c_str(), stat.c_str());
topicOut="res/node1/batteryLevel";
client.publish(topicOut.c_str(), batLev.c_str());
topicOut="res/node1/waterSwitch";
client.publish(topicOut.c_str(),switchState.c_str());
topicOut="res/node1/temperature";
client.publish(topicOut.c_str(), watTemp.c_str());
topicOut="res/node1/humidity";
client.publish(topicOut.c_str(), humid.c_str());
topicOut="qos/node1";
client.publish(topicOut.c_str(),qos.c_str());
break;
default:
u8x8.drawString(0, 8, "no ID =("); //show on LCD
break;
}
}
else if(type =="station")
{
String stat =jb["status"];
String batLev=jb["batterylevel"];
String light =jb["light"];
String temp=jb["temperature"];
String humid =jb["humidity"];
String rainF=jb["rainfall"];
String co =jb["co"];
String nh3 =jb["nh3"];
String airP =jb["airpressure"];
String qos=jb["qos"];
topicOut="res/station/status";
client.publish(topicOut.c_str(), stat.c_str());
topicOut="res/station/batteryLevel";
client.publish(topicOut.c_str(), batLev.c_str());
topicOut="res/station/light";
client.publish(topicOut.c_str(),light.c_str() );
topicOut="res/station/temperature";
client.publish(topicOut.c_str(),temp.c_str() );
topicOut="res/station/humidity";
client.publish(topicOut.c_str(), humid.c_str());
topicOut="res/station/rainfall";
client.publish(topicOut.c_str(), rainF.c_str() );
topicOut="res/station/CO";
client.publish(topicOut.c_str(), co.c_str());
topicOut="res/station/NH3";
client.publish(topicOut.c_str(), nh3.c_str());
topicOut="res/station/airPressure";
client.publish(topicOut.c_str(), airP.c_str());
topicOut="qos/station";
client.publish(topicOut.c_str(), qos.c_str());
}
else
{
u8x8.drawString(0, 8, "JSON ERR"); //show on LCD
}
//send to MQTT here...
//client.publish(topicOut, msg);
msg[0]='\0';
jb.clear();//clear memory for next message
*/
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
String s = String(topic) + String("|");
String s = "";
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
s += (char)payload[i];
}
Serial.println("");
sendToNode(s);
mqtt.publish(String(topic), s);
//send to LoRa nodes..
//sendToNode();
}
void LoRa_rxMode(){
//LoRa.disableInvertIQ(); // normal mode
LoRa.receive(); // set receive mode
}
void LoRa_txMode(){
LoRa.idle(); // set standby mode
//LoRa.enableInvertIQ(); // active invert I and Q signals
}
void sendToNode(String s)
{
LoRa_txMode(); // set tx mode
delay(200);
LoRa.beginPacket(); // start packet
LoRa.print(s); // add payload
LoRa.endPacket(); // finish packet and send it
delay(200);
LoRa_rxMode();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
@ -337,13 +146,22 @@ void reconnect() {
void f(){
if(cache_mqtt_publish != "") {Serial.println("haha"+cache_mqtt_publish);
if(cache_mqtt_publish != "") {
client.publish("res/json", cache_mqtt_publish.c_str(), cache_mqtt_publish.length());
client.publish(cache_mqtt_subject.c_str(), cache_mqtt_publish.c_str(), cache_mqtt_publish.length());
cache_mqtt_publish = "";
cache_mqtt_subject = "";
}
}
void mqttRes(String subject, String content){
Serial.println("LoRaMQTT::"+subject+"::"+content);
cache_mqtt_subject = subject;
cache_mqtt_publish = content;
}
void loop() {
if (!client.connected())
@ -351,6 +169,7 @@ void loop() {
reconnect();
}
client.loop();
mqtt.core();
f();
}

@ -0,0 +1,62 @@
#ifndef __LORA_MATT_H__
#define __LORA_MATT_H__
#define MAX_STRINGVEC_SIZE 20
#include "lora-socket.h"
class LoRaMQTT{
public:
inline void ini(){
socket.ini();
socket.onReceived(_onReceived);
}
inline void core(){
socket.core();
}
inline void publish(const String& subject, const String& content){
String s = subject + "$" + content;
socket.udp(s);
}
inline void subscribe(const String& subject){
this->_subjects.PushBack(subject);
}
inline static void onReceived(void (*f)(String, String)){
_f = f;
}
private:
static LoRaSocket socket;
static StringVec _subjects;
static void (*_f)(String, String);
inline static void _onReceived(String msg, String from, String to, String type){
if(msg.indexOf('$') == -1) return;
String subject = msg.substring(0, msg.indexOf('$'));
String content = msg.substring(msg.indexOf('$') + 1, msg.length());
if(_subjects.Find("#") != -1 || _subjects.Find(subject) != -1){
_f(subject, content);
}
};
};
LoRaSocket LoRaMQTT::socket;
StringVec LoRaMQTT::_subjects;
void (*LoRaMQTT::_f)(String, String);
#endif //__LORA_MATT_H__

@ -0,0 +1,246 @@
#ifndef __LORA_SOCKET_H__
#define __LORA_SOCKET_H__
#include <LoRa.h>
#include "vector.h"
#include "stringVec.h"
#ifndef LORA_SOCKET_IP
#define LORA_SOCKET_IP "0.0.0.0"
#endif
#ifndef MAX_RECEIVE_STACK_SIZE
#define MAX_RECEIVE_STACK_SIZE 5
#endif
#ifndef MAX_SEND_STACK_SIZE
#define MAX_SEND_STACK_SIZE 5
#endif
#ifndef MAX_TCP_TRY_TIMES
#define MAX_TCP_TRY_TIMES 8
#endif
class LoRaSocket {
public:
LoRaSocket(){}
static void core();
static void ini();
static void udp(const String& msg, const String& to = "0.0.0.0");
static void tcp(const String& msg, const String& to);
static void rtcp(const String& msg);
inline static void onReceived(void (*f)(String, String, String, String)){
_f = f;
};
private:
static StringVec tcp_sendingStack, tcp_receiveStack;
static Vector<unsigned int> tcp_sendingTryTimes;
static void(*_f)(String, String, String, String);
inline static void _onReceived(const String& msg, const String& from, const String& to, const String& type){
(*_f)(msg, from, to, type);
};
/* LoRa Functions */
static void LoRa_tx_mode();
static void LoRa_rx_mode();
static void send(const String& s);
static const String receiveMsg();
/* Package Functions */
inline static const String getIPHeader(const String& to = "0.0.0.0"){
return to + "|" + LORA_SOCKET_IP + "|";
};
inline static bool isGoodPackage(const String& s){
String body = s.substring(0, s.length() - 1);
if(s.substring(s.length() - 1, s.length()) != hash(body)){
return false;
}
return true;
};
inline static const String getToIP(const String& s){
unsigned short left = s.indexOf('|');
unsigned short right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
inline static const String getFromIP(const String& s){
unsigned short left = s.indexOf('|', s.indexOf('|') + 1);
unsigned short right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
inline static const String getType(const String& s){
return s.substring(0, s.indexOf('|'));
};
inline static const String getContent(const String& s){
unsigned short left = s.indexOf('|', s.indexOf('|', s.indexOf('|') + 1) + 1);
unsigned short right = s.indexOf('|', left + 1);
return decode(s.substring(left + 1, right));
};
inline static const String getTcpKey(const String& s){
int left = s.indexOf('|', s.indexOf('|', s.indexOf('|', s.indexOf('|') + 1) + 1) + 1);
int right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
/* receive Functions */
static void getMsg(const String& msg);
/* tcp stack functions */
static void checkSendStack(){
for(unsigned int i = 0; i < tcp_sendingStack.Size(); i ++){
send("tc"+tcp_sendingStack[i]);
tcp_sendingTryTimes[i] += 1;
if(tcp_sendingTryTimes[i] >= MAX_TCP_TRY_TIMES){
tcp_sendingStack.Erase(i);
tcp_sendingTryTimes.Erase(i);
}
}
};
inline static void receiveStackClassify(){
if(tcp_receiveStack.Size() > MAX_RECEIVE_STACK_SIZE) tcp_receiveStack.Erase(0);
};
inline static void sendStackClassify(){
if(tcp_sendingStack.Size() > MAX_SEND_STACK_SIZE) {
tcp_sendingStack.Erase(0);
tcp_sendingTryTimes.Erase(0);
}
};
static void removeByKey(const String& key);
/* tools */
static const String hash(const String& s);
static const String encode(const String& s){
return s;
};
static const String decode(const String& s){
return s;
}
static const String generateRandomKey(){
String o = "";
for(unsigned short i = 0; i < 4; i ++){
o += char(random(26) + 97);
}
return o;
}
/* timer */
static void setInterval(void (*function)(void), const int delay){
static unsigned long startTime = millis();
if(millis() - startTime > delay){
(*function)();
startTime = millis();
}
}
};
void LoRaSocket::getMsg(const String& msg){
if(!isGoodPackage(msg)) return;
if(getToIP(msg) != LORA_SOCKET_IP && getToIP(msg) != "0.0.0.0") return;
if(getType(msg) == "udp") _onReceived(getContent(msg), getFromIP(msg), getToIP(msg), "udp");
if(getType(msg) == "tcp"){
rtcp(msg);
if(tcp_receiveStack.Find(msg) != -1) return;
_onReceived(getContent(msg), getFromIP(msg), getToIP(msg), "tcp");
receiveStackClassify();
}
if(getType(msg) == "rtcp"){
removeByKey(getContent(msg));
}
}
void LoRaSocket::udp(const String& msg, const String& to){
String fin = "udp|"+ getIPHeader(to) + encode(msg) + "|";
fin += hash(fin);
send(fin);
};
void LoRaSocket::tcp(const String& msg, const String& to){
String fin = "tcp|" + getIPHeader(to) + encode(msg) + "|" + generateRandomKey() + "|";
fin += hash(fin);
tcp_sendingStack.PushBack(fin);
tcp_sendingTryTimes.PushBack(0);
sendStackClassify();
send(fin);
};
void LoRaSocket::rtcp(const String& msg){
tcp_receiveStack.PushBack(msg);
String fin = "rtcp|" + getIPHeader(getFromIP(msg)) + getTcpKey(msg) + "|";
fin += hash(fin);
send(fin);
}
StringVec LoRaSocket::tcp_sendingStack, LoRaSocket::tcp_receiveStack;
Vector<unsigned int> LoRaSocket::tcp_sendingTryTimes;
void (*LoRaSocket::_f)(String, String, String, String);
void LoRaSocket::ini() {
LoRa_rx_mode();
}
void LoRaSocket::core() {
/* Listen Msg */
if(LoRa.parsePacket()){
getMsg(receiveMsg());
}
/* check tcp stack */
setInterval(checkSendStack, 1000);
}
void LoRaSocket::LoRa_tx_mode(){
LoRa.idle();
}
void LoRaSocket::LoRa_rx_mode(){
LoRa.receive();
}
void LoRaSocket::send(const String& s){
LoRa_tx_mode();
delay(200);
LoRa.beginPacket();
LoRa.print(s);
LoRa.endPacket();
delay(200);
LoRa_rx_mode();
}
const String LoRaSocket::receiveMsg(){
String s = "";
while (LoRa.available()) {
s += (char)LoRa.read();
}
return s;
}
const String LoRaSocket::hash(const String& s){
unsigned char hashVal = 'k';
for(unsigned short i = 0; i < s.length(); i ++){
hashVal ^= s.charAt(i);
}
hashVal = hashVal % 26 + 97;
return String((char)hashVal);
}
void LoRaSocket::removeByKey(const String& key){
for(unsigned int i = 0; i < tcp_sendingStack.Size(); i++){
if(getTcpKey(tcp_sendingStack[i]) == key) {
tcp_sendingStack.Erase(i);
return;
}
}
}
#endif //__LORA_SOCKET_H__

@ -0,0 +1,77 @@
#ifndef __STRINGVEC__
#define __STRINGVEC__
#ifndef MAX_STRINGVEC_SIZE
#define MAX_STRINGVEC_SIZE 10
#endif
class StringVec{
public:
StringVec():_size(0){
this->clear();
};
inline void PushBack(const String& ss){
if(this->Size() == MAX_STRINGVEC_SIZE){
this->shift();
}
this->_s[this->Size()] = ss;
this->_size ++;
}
const int Find(const String& ss){
for(unsigned i = 0; i < this->Size(); i ++){
if(this->_s[i] == ss){
return i;
}
}
return -1;
}
void Erase(const int& pos){
if(pos < 0 || pos >= this->Size()) return;
for(unsigned int i = pos+1; i < this->Size(); i ++){
this->_s[i-1] = this->_s[i];
}
this->_size --;
}
const String shift(){
String s = this->_s[0];
if(this->Size() != 0){
for(unsigned int i = 1; i < this->Size(); i ++){
this->_s[i-1] = this->_s[i];
}
this->_size --;
}
return s;
}
void clear(){
for(unsigned int i = 0; i < this->Size(); i ++){
this->_s[i] = "";
}
}
inline const int Size(){
return this->_size;
}
String& operator[](int i){
if(i < 0 || i >= this->Size()) return this->_s[0];
return this->_s[i];
}
private:
String _s[MAX_STRINGVEC_SIZE];
int _size;
};
#endif //__STRINGVEC__

@ -0,0 +1,269 @@
/*
* Vector.h
*
* Created on: 05/04/2012
* Author: tom
* Purpose: To play the part of a mutable array in the absence of the STL.
*/
#ifndef VECTOR_H
#define VECTOR_H
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#define SWAP(type, a, b) type tmp ## a = a; a = b; b = tmp ## a;
template <class ParameterType> class Predicate
{
public:
virtual void operator() (ParameterType &param) = 0;
};
template <class VectorType> class Vector
{
// The address of the first element of the vector
VectorType *begin;
// The address one after the last allocated entry in the underlying array
VectorType *storage;
// The index of the most recent element put in the underlying array - the head
int head;
public:
// The value that is returned when the caller asks for an element that is out of the bounds of the vector
VectorType OB;
// We can save a few re-sizings if we know how large the array is likely to grow to be
Vector(int initialSize = 0)
{
begin = new VectorType[initialSize]; //points to the beginning of the new array
head = initialSize - 1;
storage = begin + initialSize; //points to the element one outside of the array (such that end - begin = capacity)
}
Vector(Vector &obj)
{
begin = new VectorType[0]; // Points to the beginning of the new array, it's zero but this line keeps malloc from seg faulting should we delete begin before resizing it
head = -1;
storage = begin; //points to the element one outside of the array (such that end - begin = capacity)
*this = obj;
}
// If there's anything in the vector then delete the array, if there's no array then doing will will cause seg faults
virtual ~Vector() { delete[] begin; }
Vector &operator=(Vector &obj)
{
// Reallocate the underlying buffer to the same size as the
Resize(obj.Size());
for(int i = 0; i < obj.Size(); i++)
(*this)[i] = obj[i];
head = obj.head;
return *this;
}
void ForEach(Predicate<VectorType> &functor)
{
for(int i = 0; i < Size(); i++)
functor(begin[i]);
}
// Swaps the underlying array and characteristics of this vector with another of the same type, very quickly
void Swap(Vector &obj)
{
SWAP(int, head, obj.head);
SWAP(VectorType*, begin, obj.begin);
SWAP(VectorType*, storage, obj.storage);
}
// Checks the entire Vector to see whether a matching item exists. Bear in mind that the VectorType might need to implement
// equality operator (operator==) for this to work properly.
bool Contains(VectorType element)
{
for(int i = 0; i < Size(); i++)
if(operator [](i) == element)
return true;
return false;
}
int Find(VectorType element)
{
for(int i = 0; i < Size(); i++)
if(operator [](i) == element)
return i;
return -1;
}
void PushBack(VectorType element) { PushBack(&element, 1); }
void PushBack(const VectorType *elements, int len)
{
// If the length plus this's size is greater than the capacity, reallocate to that size.
if(len + Size() > Capacity())
ReAllocate(MAX(Size() + len, Size() * 2));
int append = MIN(storage - begin - head - 1, len), prepend = len - append;
// memcpy the data starting at the head all the way up to the last element *(storage - 1)
memcpy((begin + head + 1), elements, sizeof(VectorType) * append);
// If there's still data to copy memcpy whatever remains, starting at the first element *(begin) until the end of data. The first step will have ensured
// that we don't crash into the tail during this process.
memcpy(begin,(elements + append), sizeof(VectorType) * prepend);
// Re-recalculate head and size.
head += len;
}
void Erase(unsigned int position) { Erase(position, position + 1); }
// Erase an arbitrary section of the vector from first up to last minus one. Like the stl counterpart, this is pretty labour intensive so go easy on it.
void Erase(int first, int last)
{
// For this we'll set the value of the array at first to the value of the array at last plus one. We'll do that all the way up to toIndex
for(int i = 0; i < (Size() - first); i++)
{
// If by trying to fill in the next element with the ones ahead of it we'll be running off the end of the vector, stop.
if((i + last) > (Size() - 1))
break;
begin[first + i] = begin[last + i];
}
// Adjust the head to reflect the new size
head -= last - first;
}
// Remove the most recent element in the array
void PopBack()
{
if(Size() > 0)
head--;
}
// Empty the vector, or to be precise - forget the fact that there was ever anything in there.
void Clear() { head = -1; }
// Returns a bool indicating whether or not there are any elements in the array
bool Empty() { return head == -1; }
// Returns the oldest element in the array (the one added before any other)
VectorType const &Back() { return *begin; }
// Returns the newest element in the array (the one added after every other)
VectorType const &Front() { return begin[head]; }
// Returns the nth element in the vector
VectorType &operator[](int n)
{
if(n < Size())
return begin[n];
else
return OB;
}
// Returns a pointer such that the vector's data is laid out between ret to ret + size
VectorType *Data() { return begin; }
// Recreates the vector to hold len elements, all being copies of val
void Assign(int len, const VectorType &val)
{
delete[] begin;
// Allocate an array the same size as the one passed in
begin = new VectorType[len];
storage = begin + len;
// Refresh the head and tail, assuming the array is in order, which it really has to be
head = len - 1;
for(int i = 0 ; i < Size(); i++)
begin[i] = val;
}
// Recreates the vector using an external array
void Assign(VectorType *array, int len)
{
delete[] begin;
// Allocate an array the same size as the one passed in
begin = new VectorType[len];
storage = begin + len;
// Refresh the head and tail, assuming the array is in order, which it really has to be
head = len - 1;
// Copy over the memory
memcpy(begin, array, sizeof(VectorType) * len);
}
// Returns the number of elements that the vector will support before needing resizing
int Capacity() { return (storage - begin); }
// Returns the number of elements in vector
int Size() { return head + 1; }
// Requests that the capacity of the allocated storage space for the elements
// of the vector be at least enough to hold size elements.
void Reserve(unsigned int size)
{
if(size > Capacity())
ReAllocate(size);
}
// Resizes the vector
void Resize(unsigned int size)
{
// If necessary, resize the underlying array to fit the new size
if(size > Capacity())
ReAllocate(size);
// Now revise the head and size (tail needn't change) to reflect the new size
head = size - 1;
}
private:
void ReAllocate(unsigned int size)
{
// Just in case we're re-allocating less room than we had before, make sure that we don't overrun the buffer by trying to write more elements than
// are now possible for this vector to hold.
if(Size() > (int)size)
head = size - 1;
// Allocate an array twice the size of that of the old
VectorType *_begin = new VectorType[size];
VectorType *_storage = _begin + size;
int _head = Size() - 1;
// Copy across all the old array's data and rearrange it!
for(int i = 0; i < Size(); i++)
_begin[i] = (*this)[i];
// Free the old memory
delete[] begin;
// Redirect the old array to point to the new one
begin = _begin;
storage = _storage;
head = _head;
}
};
#endif // VECTOR_H

Binary file not shown.

@ -0,0 +1,7 @@
{
"board": "arduino:avr:nano",
"configuration": "cpu=atmega328",
"port": "COM4",
"sketch": "station.ino",
"output": "./.vscode/bin"
}

@ -0,0 +1,10 @@
{
"builtInLibrariesFolders": "C:\\Program Files (x86)\\Arduino\\libraries",
"customBuildProperties": "build.path=e:\\git\\smart-farming\\opt\\station\\.vscode\\bin,build.warn_data_percentage=75,runtime.tools.arduinoOTA.path=C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr,runtime.tools.avrdude.path=C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr,runtime.tools.avr-gcc.path=C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr",
"fqbn": "arduino:avr:nano:cpu=atmega328",
"hardwareFolders": "C:\\Program Files (x86)\\Arduino\\hardware,C:\\Users\\i\\AppData\\Local\\Arduino15\\packages",
"otherLibrariesFolders": "E:\\OneDrive\\pc\\document\\Arduino\\libraries",
"runtime.ide.version": "10805",
"sketchLocation": "e:\\git\\smart-farming\\opt\\station\\station.ino",
"toolsFolders": "C:\\Program Files (x86)\\Arduino\\tools-builder,C:\\Program Files (x86)\\Arduino\\hardware\\tools\\avr,C:\\Users\\i\\AppData\\Local\\Arduino15\\packages"
}

@ -0,0 +1,13 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\CDC.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\CDC.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,15 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\HardwareSerial.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h

@ -0,0 +1,15 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\HardwareSerial0.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial0.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h

@ -0,0 +1,15 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\HardwareSerial1.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial1.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h

@ -0,0 +1,15 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\HardwareSerial2.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial2.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h

@ -0,0 +1,15 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\HardwareSerial3.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial3.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h

@ -0,0 +1,15 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\IPAddress.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\IPAddress.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/IPAddress.h

Binary file not shown.

@ -0,0 +1,14 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\PluggableUSB.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\PluggableUSB.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\PluggableUSB.h

Binary file not shown.

@ -0,0 +1,13 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\Print.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,13 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\Stream.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,13 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\Tone.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Tone.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,14 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\USBCore.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBCore.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\PluggableUSB.h

Binary file not shown.

@ -0,0 +1,7 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\WInterrupts.c.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WInterrupts.c \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,2 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\WMath.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WMath.cpp

Binary file not shown.

@ -0,0 +1,3 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\WString.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\WString.h

Binary file not shown.

@ -0,0 +1,2 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\abi.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\abi.cpp

Binary file not shown.

Binary file not shown.

@ -0,0 +1,2 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\hooks.c.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\hooks.c

Binary file not shown.

@ -0,0 +1,14 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\main.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\main.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,2 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\new.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\new.cpp

Binary file not shown.

@ -0,0 +1,7 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\wiring.c.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring.c \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,7 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\wiring_analog.c.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_analog.c \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,7 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\wiring_digital.c.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_digital.c \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,2 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\wiring_pulse.S.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_pulse.S

Binary file not shown.

@ -0,0 +1,7 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\wiring_pulse.c.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_pulse.c \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,7 @@
e:\git\smart-farming\opt\station\.vscode\bin\core\wiring_shift.c.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_shift.c \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_private.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino\binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,62 @@
[
{
"Sourcefile": "",
"Include": "",
"Includepath": "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino"
},
{
"Sourcefile": "",
"Include": "",
"Includepath": "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\variants\\eightanaloginputs"
},
{
"Sourcefile": "e:\\git\\smart-farming\\opt\\station\\.vscode\\bin\\sketch\\station.ino.cpp",
"Include": "SPI.h",
"Includepath": "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\libraries\\SPI\\src"
},
{
"Sourcefile": "e:\\git\\smart-farming\\opt\\station\\.vscode\\bin\\sketch\\station.ino.cpp",
"Include": "LoRa.h",
"Includepath": "E:\\OneDrive\\pc\\document\\Arduino\\libraries\\LoRa\\src"
},
{
"Sourcefile": "e:\\git\\smart-farming\\opt\\station\\.vscode\\bin\\sketch\\station.ino.cpp",
"Include": "Wire.h",
"Includepath": "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\libraries\\Wire\\src"
},
{
"Sourcefile": "e:\\git\\smart-farming\\opt\\station\\.vscode\\bin\\sketch\\station.ino.cpp",
"Include": "",
"Includepath": ""
},
{
"Sourcefile": "e:\\git\\smart-farming\\opt\\station\\.vscode\\bin\\sketch\\BME280.cpp",
"Include": "",
"Includepath": ""
},
{
"Sourcefile": "e:\\git\\smart-farming\\opt\\station\\.vscode\\bin\\sketch\\GY30.cpp",
"Include": "",
"Includepath": ""
},
{
"Sourcefile": "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\libraries\\SPI\\src\\SPI.cpp",
"Include": "",
"Includepath": ""
},
{
"Sourcefile": "E:\\OneDrive\\pc\\document\\Arduino\\libraries\\LoRa\\src\\LoRa.cpp",
"Include": "",
"Includepath": ""
},
{
"Sourcefile": "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\libraries\\Wire\\src\\Wire.cpp",
"Include": "",
"Includepath": ""
},
{
"Sourcefile": "C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\libraries\\Wire\\src\\utility\\twi.c",
"Include": "",
"Includepath": ""
}
]

@ -0,0 +1,16 @@
e:\git\smart-farming\opt\station\.vscode\bin\libraries\LoRa\LoRa.cpp.o: \
E:\OneDrive\pc\document\Arduino\libraries\LoRa\src\LoRa.cpp \
E:\OneDrive\pc\document\Arduino\libraries\LoRa\src/LoRa.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src/SPI.h

@ -0,0 +1,15 @@
e:\git\smart-farming\opt\station\.vscode\bin\libraries\SPI\SPI.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src\SPI.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src\SPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,8 @@
e:\git\smart-farming\opt\station\.vscode\bin\libraries\Wire\Wire.cpp.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\Wire.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility/twi.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\Wire.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h

@ -0,0 +1,7 @@
e:\git\smart-farming\opt\station\.vscode\bin\libraries\Wire\utility\twi.c.o: \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.c \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\utility\twi.h

@ -0,0 +1,151 @@
# 1 "e:\\git\\smart-farming\\opt\\station\\station.ino"
# 1 "e:\\git\\smart-farming\\opt\\station\\station.ino"
//#include <ArduinoJson.h>
# 3 "e:\\git\\smart-farming\\opt\\station\\station.ino" 2
# 4 "e:\\git\\smart-farming\\opt\\station\\station.ino" 2
# 5 "e:\\git\\smart-farming\\opt\\station\\station.ino" 2
# 6 "e:\\git\\smart-farming\\opt\\station\\station.ino" 2
# 7 "e:\\git\\smart-farming\\opt\\station\\station.ino" 2
//const size_t capacity = JSON_OBJECT_SIZE(15);
//DynamicJsonDocument data(capacity);
# 13 "e:\\git\\smart-farming\\opt\\station\\station.ino" 2
LoRaMQTT mqtt;
BME280 bme;
GY30 gy;
void setup() {
uint8_t osrs_t = 1; //Temperature oversampling x 1
uint8_t osrs_p = 1; //Pressure oversampling x 1
uint8_t osrs_h = 1; //Humidity oversampling x 1
uint8_t mode = 3; //Normal mode
uint8_t t_sb = 5; //Tstandby 1000ms
uint8_t filter = 0; //Filter off
uint8_t spi3w_en = 0; //3-wire SPI Disable
uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;
Serial.begin(115200);
pinMode(A0, 0x0);
pinMode(A1, 0x0);
pinMode(A3, 0x0);
pinMode(A7, 0x0);
Wire.begin();
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
mqtt.ini();
mqtt.subscribe("#");
mqtt.onReceived(mqttRes);
bme.writeReg(0xF2,ctrl_hum_reg);
bme.writeReg(0xF4,ctrl_meas_reg);
bme.writeReg(0xF5,config_reg);
bme.readTrim();
}
void loop() {
mqtt.core();
}
void mqttRes(String subject, String content){
if(subject == "qos/sync"){
String s;
getData(s, content);
//data = getJson();
//data["qos"] = content;
//data["type"] = "station";
//serializeJson(data, dataStr);
Serial.println(s);
mqtt.publish("res/json", s);
}
}
void getData(String& s, const String& content){
s = "{\"t\":\"station\",\"l\": ";
s += gy.getLight();
s += ",\"T\":";
s += bme.getTemp();
s += ",\"h\":";
s += bme.getHum();
s += ",\"a\":";
s += bme.getPress()/100;
s += ",\"C\":";
s += analogRead(A0);
s += ",\"N\":";
s += analogRead(A1);
s += ",\"r\":";
s += analogRead(A2);
s += ",\"b\":";
s += (unsigned int)analogRead(A6)*100/1024;
s += ",\"s\":";
s += 0;
s += ",\"q\":";
s += content;
s += "}";
}
/*
//DynamicJsonDocument createJson(const size_t capacity, int Light, long int batteryLevel, double Temp, double Hum, double Press, int CO, int NH3, int Rain)
DynamicJsonDocument getJson()
{
DynamicJsonDocument json(capacity);
int Light = gy.getLight();
double Temp = bme.getTemp();
double Hum = bme.getHum();
double Press = bme.getPress()/100;
int CO = analogRead(A0);
int NH3 = analogRead(A1);
int Rain = analogRead(A2);
long int batteryLevel = analogRead(A6);
batteryLevel = (batteryLevel * 100)/1024;
Serial.print("Light: ");
Serial.println(Light);
Serial.print("batteryLevel: ");
Serial.println(batteryLevel);
Serial.print("Temperature: ");
Serial.println(Temp);
Serial.print("Humidity: ");
Serial.println(Hum);
Serial.print("Press: ");
Serial.println(Press);
Serial.print("Rain: ");
Serial.println(Rain);
Serial.print("CO: ");
Serial.println(CO);
Serial.print("NH3: ");
Serial.println(NH3);
Serial.println();
json["status"] = "0";
json["batterylevel"] = batteryLevel;
json["light"] = Light;
json["temperature"] = Temp;
json["humidity"] = Hum;
json["rainfall"] = Rain;
json["co"] = CO;
json["nh3"] = NH3;
json["airpressure"] = Press;
return json;
}
*/

@ -0,0 +1,211 @@
#include"BME280.h"
#include<Arduino.h>
#include<Wire.h>
void BME280::readTrim()
{
uint8_t data[32],i=0;
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,24);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xA1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,1);
data[i] = Wire.read();
i++;
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xE1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,7);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
dig_T1 = (data[1] << 8) | data[0];
dig_T2 = (data[3] << 8) | data[2];
dig_T3 = (data[5] << 8) | data[4];
dig_P1 = (data[7] << 8) | data[6];
dig_P2 = (data[9] << 8) | data[8];
dig_P3 = (data[11]<< 8) | data[10];
dig_P4 = (data[13]<< 8) | data[12];
dig_P5 = (data[15]<< 8) | data[14];
dig_P6 = (data[17]<< 8) | data[16];
dig_P7 = (data[19]<< 8) | data[18];
dig_P8 = (data[21]<< 8) | data[20];
dig_P9 = (data[23]<< 8) | data[22];
dig_H1 = data[24];
dig_H2 = (data[26]<< 8) | data[25];
dig_H3 = data[27];
dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
dig_H6 = data[31];
}
void BME280::writeReg(uint8_t reg_address, uint8_t data)
{
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(reg_address);
Wire.write(data);
Wire.endTransmission();
}
void BME280::readData()
{
int i = 0;
uint32_t data[8];
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xF7);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,8);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
hum_raw = (data[6] << 8) | data[7];
}
double BME280::getTemp()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
/* Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");*/
//delay(1000);
return temp_act;
}
double BME280::getPress()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
/* Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");*/
//delay(1000);
return press_cal;
}
double BME280::getHum()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
/* Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");*/
//delay(1000);
return hum_act;
}
signed long int BME280::calibration_T(signed long int adc_T)
{
signed long int var1, var2, T;
var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
unsigned long int BME280::calibration_P(signed long int adc_P)
{
signed long int var1, var2;
unsigned long int P;
var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
if (var1 == 0)
{
return 0;
}
P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
if(P<0x80000000)
{
P = (P << 1) / ((unsigned long int) var1);
}
else
{
P = (P / (unsigned long int)var1) * 2;
}
var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
return P;
}
unsigned long int BME280::calibration_H(signed long int adc_H)
{
signed long int v_x1;
v_x1 = (t_fine - ((signed long int)76800));
v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) +
((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *
(((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *
((signed long int) dig_H2) + 8192) >> 14));
v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));
v_x1 = (v_x1 < 0 ? 0 : v_x1);
v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
return (unsigned long int)(v_x1 >> 12);
}

@ -0,0 +1,17 @@
e:\git\smart-farming\opt\station\.vscode\bin\sketch\BME280.cpp.o: \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\BME280.cpp \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\BME280.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,54 @@
#ifndef BME280_H_
#define BME280_H_
#include <Wire.h>
#include <Arduino.h>
class BME280
{
#define BME280_ADDRESS 0x76
private:
signed long int t_fine;
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int8_t dig_H1;
int16_t dig_H2;
int8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
public:
unsigned long int hum_raw,temp_raw,pres_raw;
void readTrim();
void writeReg(uint8_t reg_address, uint8_t data);
void readData();
double getTemp();
double getPress();
double getHum();
signed long int calibration_T(signed long int adc_T);
unsigned long int calibration_P(signed long int adc_P);
unsigned long int calibration_H(signed long int adc_H);
};
#endif

@ -0,0 +1,28 @@
#include<Wire.h>
#include"GY30.h"
#include <Arduino.h>
int GY30::getLight()
{
// put your main code here, to run repeatedly:
int val = 0;
// reset
Wire.beginTransmission(ADDR);
Wire.write(0b00000111);
Wire.endTransmission();
Wire.beginTransmission(ADDR);
Wire.write(0b00100000);
Wire.endTransmission();
// typical read delay 120ms
delay(120);
Wire.requestFrom(ADDR, 2); // 2byte every time
for (val = 0; Wire.available() >= 1; ) {
char c = Wire.read();
//Serial.println(c, HEX);
val = (val << 8) + (c & 0xFF);
}
val = val / 1.2;
return val;
}

@ -0,0 +1,17 @@
e:\git\smart-farming\opt\station\.vscode\bin\sketch\GY30.cpp.o: \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\GY30.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\GY30.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h

Binary file not shown.

@ -0,0 +1,17 @@
#ifndef GY30_H_
#define GY30_H_
#include <Wire.h>
#include <Arduino.h>
class GY30
{
#define ADDR 0b0100011
private:
public:
int getLight();
};
#endif

@ -0,0 +1,87 @@
#ifndef __LORA_MATT_H__
#define __LORA_MATT_H__
#define MAX_STRINGVEC_SIZE 2
#include "lora-socket.h"
class LoRaMQTT{
public:
inline void ini(){
socket.ini();
socket.onReceived(_onReceived);
}
inline void core(){
if(isLoopMode){
if(socket.isNewMsg()){
String msg = "", from = "", to = "", type = "";
socket.getNewMsg(msg, from, to, type);
_onReceived(msg, from, to, type);
}
}
socket.core();
}
inline void publish(const String& subject, const String& content){
String s = subject + "$" + content;
socket.udp(s);
}
inline void subscribe(const String& subject){
this->_subjects.PushBack(subject);
}
inline static void onReceived(void (*f)(String, String)){
_f = f;
}
inline bool isNewMsg(){
isLoopMode = true;
return (newSubject == "") ? false : true;
};
inline void getNewMsg(String& subject, String& content){
subject = newSubject;
content = newContent;
clearNewMsg();
}
private:
static LoRaSocket socket;
static StringVec _subjects;
static void (*_f)(String, String);
static String newSubject, newContent;
static bool isLoopMode;
inline void clearNewMsg(){
newSubject = "";
newContent = "";
};
inline static void _onReceived(String msg, String from, String to, String type){
if(msg.indexOf('$') == -1) return;
String subject = msg.substring(0, msg.indexOf('$'));
String content = msg.substring(msg.indexOf('$') + 1, msg.length());
if(_subjects.Find("#") != -1 || _subjects.Find(subject) != -1){
newSubject = subject;
newContent = content;
if(!isLoopMode) _f(subject, content);
}
};
};
LoRaSocket LoRaMQTT::socket;
StringVec LoRaMQTT::_subjects;
void (*LoRaMQTT::_f)(String, String);
String LoRaMQTT::newSubject = "", LoRaMQTT::newContent = "";
bool LoRaMQTT::isLoopMode = false;
#endif //__LORA_MATT_H__

@ -0,0 +1,289 @@
#ifndef __LORA_SOCKET_H__
#define __LORA_SOCKET_H__
#include <LoRa.h>
#include "vector.h"
#include "stringVec.h"
#ifndef LORA_SOCKET_IP
#define LORA_SOCKET_IP "0.0.0.0"
#endif
#ifndef MAX_RECEIVE_STACK_SIZE
#define MAX_RECEIVE_STACK_SIZE 5
#endif
#ifndef MAX_SEND_STACK_SIZE
#define MAX_SEND_STACK_SIZE 5
#endif
#ifndef MAX_TCP_TRY_TIMES
#define MAX_TCP_TRY_TIMES 8
#endif
class LoRaSocket {
public:
LoRaSocket(){}
static void core();
static void ini();
static void udp(const String& msg, const String& to = "0.0.0.0");
static void tcp(const String& msg, const String& to);
static void rtcp(const String& msg);
inline static void onReceived(void (*f)(String, String, String, String)){
_f = f;
};
inline bool isNewMsg(){
isLoopMode = true;
return (newType == "") ? false : true;
};
inline const String getNewMsg(){
String msg = newMsg;
clearNewMsg();
return msg;
};
inline void getNewMsg(String& msg, String& from, String& to, String& type){
msg = newMsg;
from = newFrom;
to = newTo;
type = newType;
clearNewMsg();
};
private:
static StringVec tcp_sendingStack, tcp_receiveStack;
static Vector<unsigned int> tcp_sendingTryTimes;
static void(*_f)(String, String, String, String);
static String newMsg, newFrom, newTo, newType;
static bool isLoopMode;
inline void clearNewMsg(){
newMsg = "";
newFrom = "";
newTo = "";
newType = "";
};
inline static void _onReceived(const String& msg, const String& from, const String& to, const String& type){
newMsg = msg;
newFrom = from;
newTo = to;
newType = type;
if(!isLoopMode) (*_f)(msg, from, to, type);
};
/* LoRa Functions */
static void LoRa_tx_mode();
static void LoRa_rx_mode();
static void send(const String& s);
static void send(const char *s);
static const String receiveMsg();
/* Package Functions */
inline static const String getIPHeader(const String& to = "0.0.0.0"){
return to + "|" + LORA_SOCKET_IP + "|";
};
inline static bool isGoodPackage(const String& s){
String body = s.substring(0, s.length() - 1);
if(s.substring(s.length() - 1, s.length()) != hash(body)){
return false;
}
return true;
};
inline static const String getToIP(const String& s){
unsigned short left = s.indexOf('|');
unsigned short right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
inline static const String getFromIP(const String& s){
unsigned short left = s.indexOf('|', s.indexOf('|') + 1);
unsigned short right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
inline static const String getType(const String& s){
return s.substring(0, s.indexOf('|'));
};
inline static const String getContent(const String& s){
unsigned short left = s.indexOf('|', s.indexOf('|', s.indexOf('|') + 1) + 1);
unsigned short right = s.indexOf('|', left + 1);
return decode(s.substring(left + 1, right));
};
inline static const String getTcpKey(const String& s){
int left = s.indexOf('|', s.indexOf('|', s.indexOf('|', s.indexOf('|') + 1) + 1) + 1);
int right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
/* receive Functions */
static void getMsg(const String& msg);
/* tcp stack functions */
static void checkSendStack(){
for(unsigned int i = 0; i < tcp_sendingStack.Size(); i ++){
send("tc"+tcp_sendingStack[i]);
tcp_sendingTryTimes[i] += 1;
if(tcp_sendingTryTimes[i] >= MAX_TCP_TRY_TIMES){
tcp_sendingStack.Erase(i);
tcp_sendingTryTimes.Erase(i);
}
}
};
inline static void receiveStackClassify(){
if(tcp_receiveStack.Size() > MAX_RECEIVE_STACK_SIZE) tcp_receiveStack.Erase(0);
};
inline static void sendStackClassify(){
if(tcp_sendingStack.Size() > MAX_SEND_STACK_SIZE) {
tcp_sendingStack.Erase(0);
tcp_sendingTryTimes.Erase(0);
}
};
static void removeByKey(const String& key);
/* tools */
static const String hash(const String& s);
static const String encode(const String& s){
return s;
};
static const String decode(const String& s){
return s;
}
static const String generateRandomKey(){
String o = "";
for(unsigned short i = 0; i < 4; i ++){
o += char(random(26) + 97);
}
return o;
}
/* timer */
static void setInterval(void (*function)(void), const int delay){
static unsigned long startTime = millis();
if(millis() - startTime > delay){
(*function)();
startTime = millis();
}
}
};
void LoRaSocket::getMsg(const String& msg){
if(!isGoodPackage(msg)) return;
if(getToIP(msg) != LORA_SOCKET_IP && getToIP(msg) != "0.0.0.0") return;
if(getType(msg) == "udp") _onReceived(getContent(msg), getFromIP(msg), getToIP(msg), "udp");
if(getType(msg) == "tcp"){
rtcp(msg);
if(tcp_receiveStack.Find(msg) != -1) return;
_onReceived(getContent(msg), getFromIP(msg), getToIP(msg), "tcp");
receiveStackClassify();
}
if(getType(msg) == "rtcp"){
removeByKey(getContent(msg));
}
}
void LoRaSocket::udp(const String& msg, const String& to){
char *c;
c = (char*)malloc((msg.length()+39)*sizeof(char));
sprintf(c, "udp|%s%s|", getIPHeader(to).c_str(), encode(msg).c_str());
sprintf(c, "%s%s", c, hash(c).c_str());
send(c);
free(c);
};
void LoRaSocket::tcp(const String& msg, const String& to){
String fin = "tcp|" + getIPHeader(to) + encode(msg) + "|" + generateRandomKey() + "|";
fin += hash(fin);
tcp_sendingStack.PushBack(fin);
tcp_sendingTryTimes.PushBack(0);
sendStackClassify();
send(fin);
};
void LoRaSocket::rtcp(const String& msg){
tcp_receiveStack.PushBack(msg);
String fin = "rtcp|" + getIPHeader(getFromIP(msg)) + getTcpKey(msg) + "|";
fin += hash(fin);
send(fin);
}
StringVec LoRaSocket::tcp_sendingStack, LoRaSocket::tcp_receiveStack;
Vector<unsigned int> LoRaSocket::tcp_sendingTryTimes;
void (*LoRaSocket::_f)(String, String, String, String);
String LoRaSocket::newMsg = "", LoRaSocket::newFrom = "", LoRaSocket::newTo = "", LoRaSocket::newType = "";
bool LoRaSocket::isLoopMode = false;
void LoRaSocket::ini() {
LoRa_rx_mode();
}
void LoRaSocket::core() {
/* Listen Msg */
if(LoRa.parsePacket()){
getMsg(receiveMsg());
}
/* check tcp stack */
setInterval(checkSendStack, 1000);
}
void LoRaSocket::LoRa_tx_mode(){
LoRa.idle();
}
void LoRaSocket::LoRa_rx_mode(){
LoRa.receive();
}
void LoRaSocket::send(const char *s){
LoRa_tx_mode();
delay(200);
LoRa.beginPacket();Serial.println(s);
LoRa.print(s);
LoRa.endPacket();
delay(200);
LoRa_rx_mode();
}
void LoRaSocket::send(const String& s){
LoRa_tx_mode();
delay(200);
LoRa.beginPacket();Serial.println(s);
LoRa.print(s);
LoRa.endPacket();
delay(200);
LoRa_rx_mode();
}
const String LoRaSocket::receiveMsg(){
String s = "";
while (LoRa.available()) {
s += (char)LoRa.read();
}
return s;
}
const String LoRaSocket::hash(const String& s){
unsigned char hashVal = 'k';
for(unsigned short i = 0; i < s.length(); i ++){
hashVal ^= s.charAt(i);
}
hashVal = hashVal % 26 + 97;
return String((char)hashVal);
}
void LoRaSocket::removeByKey(const String& key){
for(unsigned int i = 0; i < tcp_sendingStack.Size(); i++){
if(getTcpKey(tcp_sendingStack[i]) == key) {
tcp_sendingStack.Erase(i);
return;
}
}
}
#endif //__LORA_SOCKET_H__

@ -0,0 +1,160 @@
#line 1 "e:\\git\\smart-farming\\opt\\station\\station.ino"
#line 1 "e:\\git\\smart-farming\\opt\\station\\station.ino"
//#include <ArduinoJson.h>
#include <SPI.h>
#include <LoRa.h>
#include <Arduino.h>
#include "BME280.h"
#include "GY30.h"
//const size_t capacity = JSON_OBJECT_SIZE(15);
//DynamicJsonDocument data(capacity);
#define LORA_SOCKET_IP "1.0.0.2"
#include "lora-mqtt.h"
LoRaMQTT mqtt;
BME280 bme;
GY30 gy;
#line 21 "e:\\git\\smart-farming\\opt\\station\\station.ino"
void setup();
#line 55 "e:\\git\\smart-farming\\opt\\station\\station.ino"
void loop();
#line 61 "e:\\git\\smart-farming\\opt\\station\\station.ino"
void mqttRes(String subject, String content);
#line 76 "e:\\git\\smart-farming\\opt\\station\\station.ino"
void getData(String& s, const String& content);
#line 21 "e:\\git\\smart-farming\\opt\\station\\station.ino"
void setup() {
uint8_t osrs_t = 1; //Temperature oversampling x 1
uint8_t osrs_p = 1; //Pressure oversampling x 1
uint8_t osrs_h = 1; //Humidity oversampling x 1
uint8_t mode = 3; //Normal mode
uint8_t t_sb = 5; //Tstandby 1000ms
uint8_t filter = 0; //Filter off
uint8_t spi3w_en = 0; //3-wire SPI Disable
uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;
Serial.begin(115200);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A3, INPUT);
pinMode(A7, INPUT);
Wire.begin();
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
mqtt.ini();
mqtt.subscribe("#");
mqtt.onReceived(mqttRes);
bme.writeReg(0xF2,ctrl_hum_reg);
bme.writeReg(0xF4,ctrl_meas_reg);
bme.writeReg(0xF5,config_reg);
bme.readTrim();
}
void loop() {
mqtt.core();
}
void mqttRes(String subject, String content){
if(subject == "qos/sync"){
String s;
getData(s, content);
//data = getJson();
//data["qos"] = content;
//data["type"] = "station";
//serializeJson(data, dataStr);
Serial.println(s);
mqtt.publish("res/json", s);
}
}
void getData(String& s, const String& content){
s = "{\"t\":\"station\",\"l\": ";
s += gy.getLight();
s += ",\"T\":";
s += bme.getTemp();
s += ",\"h\":";
s += bme.getHum();
s += ",\"a\":";
s += bme.getPress()/100;
s += ",\"C\":";
s += analogRead(A0);
s += ",\"N\":";
s += analogRead(A1);
s += ",\"r\":";
s += analogRead(A2);
s += ",\"b\":";
s += (unsigned int)analogRead(A6)*100/1024;
s += ",\"s\":";
s += 0;
s += ",\"q\":";
s += content;
s += "}";
}
/*
//DynamicJsonDocument createJson(const size_t capacity, int Light, long int batteryLevel, double Temp, double Hum, double Press, int CO, int NH3, int Rain)
DynamicJsonDocument getJson()
{
DynamicJsonDocument json(capacity);
int Light = gy.getLight();
double Temp = bme.getTemp();
double Hum = bme.getHum();
double Press = bme.getPress()/100;
int CO = analogRead(A0);
int NH3 = analogRead(A1);
int Rain = analogRead(A2);
long int batteryLevel = analogRead(A6);
batteryLevel = (batteryLevel * 100)/1024;
Serial.print("Light: ");
Serial.println(Light);
Serial.print("batteryLevel: ");
Serial.println(batteryLevel);
Serial.print("Temperature: ");
Serial.println(Temp);
Serial.print("Humidity: ");
Serial.println(Hum);
Serial.print("Press: ");
Serial.println(Press);
Serial.print("Rain: ");
Serial.println(Rain);
Serial.print("CO: ");
Serial.println(CO);
Serial.print("NH3: ");
Serial.println(NH3);
Serial.println();
json["status"] = "0";
json["batterylevel"] = batteryLevel;
json["light"] = Light;
json["temperature"] = Temp;
json["humidity"] = Hum;
json["rainfall"] = Rain;
json["co"] = CO;
json["nh3"] = NH3;
json["airpressure"] = Press;
return json;
}
*/

@ -0,0 +1,24 @@
e:\git\smart-farming\opt\station\.vscode\bin\sketch\station.ino.cpp.o: \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\station.ino.cpp \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\SPI\src/SPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/binary.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WCharacter.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Print.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Printable.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/USBAPI.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/pins_arduino.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\variants\eightanaloginputs/../standard/pins_arduino.h \
E:\OneDrive\pc\document\Arduino\libraries\LoRa\src/LoRa.h \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\BME280.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src/Wire.h \
C:\Program\ Files\ (x86)\Arduino\hardware\arduino\avr\cores\arduino/Stream.h \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\GY30.h \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\lora-mqtt.h \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\lora-socket.h \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\vector.h \
e:\git\smart-farming\opt\station\.vscode\bin\sketch\stringVec.h

@ -0,0 +1,77 @@
#ifndef __STRINGVEC__
#define __STRINGVEC__
#ifndef MAX_STRINGVEC_SIZE
#define MAX_STRINGVEC_SIZE 2
#endif
class StringVec{
public:
StringVec():_size(0){
this->clear();
};
inline void PushBack(const String& ss){
if(this->Size() == MAX_STRINGVEC_SIZE){
this->shift();
}
this->_s[this->Size()] = ss;
this->_size ++;
}
const int Find(const String& ss){
for(unsigned i = 0; i < this->Size(); i ++){
if(this->_s[i] == ss){
return i;
}
}
return -1;
}
void Erase(const int& pos){
if(pos < 0 || pos >= this->Size()) return;
for(unsigned int i = pos+1; i < this->Size(); i ++){
this->_s[i-1] = this->_s[i];
}
this->_size --;
}
const String shift(){
String s = this->_s[0];
if(this->Size() != 0){
for(unsigned int i = 1; i < this->Size(); i ++){
this->_s[i-1] = this->_s[i];
}
this->_size --;
}
return s;
}
void clear(){
for(unsigned int i = 0; i < this->Size(); i ++){
this->_s[i] = "";
}
}
inline const int Size(){
return this->_size;
}
String& operator[](int i){
if(i < 0 || i >= this->Size()) return this->_s[0];
return this->_s[i];
}
private:
String _s[MAX_STRINGVEC_SIZE];
int _size;
};
#endif //__STRINGVEC__

@ -0,0 +1,269 @@
/*
* Vector.h
*
* Created on: 05/04/2012
* Author: tom
* Purpose: To play the part of a mutable array in the absence of the STL.
*/
#ifndef VECTOR_H
#define VECTOR_H
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#define SWAP(type, a, b) type tmp ## a = a; a = b; b = tmp ## a;
template <class ParameterType> class Predicate
{
public:
virtual void operator() (ParameterType &param) = 0;
};
template <class VectorType> class Vector
{
// The address of the first element of the vector
VectorType *begin;
// The address one after the last allocated entry in the underlying array
VectorType *storage;
// The index of the most recent element put in the underlying array - the head
int head;
public:
// The value that is returned when the caller asks for an element that is out of the bounds of the vector
VectorType OB;
// We can save a few re-sizings if we know how large the array is likely to grow to be
Vector(int initialSize = 0)
{
begin = new VectorType[initialSize]; //points to the beginning of the new array
head = initialSize - 1;
storage = begin + initialSize; //points to the element one outside of the array (such that end - begin = capacity)
}
Vector(Vector &obj)
{
begin = new VectorType[0]; // Points to the beginning of the new array, it's zero but this line keeps malloc from seg faulting should we delete begin before resizing it
head = -1;
storage = begin; //points to the element one outside of the array (such that end - begin = capacity)
*this = obj;
}
// If there's anything in the vector then delete the array, if there's no array then doing will will cause seg faults
virtual ~Vector() { delete[] begin; }
Vector &operator=(Vector &obj)
{
// Reallocate the underlying buffer to the same size as the
Resize(obj.Size());
for(int i = 0; i < obj.Size(); i++)
(*this)[i] = obj[i];
head = obj.head;
return *this;
}
void ForEach(Predicate<VectorType> &functor)
{
for(int i = 0; i < Size(); i++)
functor(begin[i]);
}
// Swaps the underlying array and characteristics of this vector with another of the same type, very quickly
void Swap(Vector &obj)
{
SWAP(int, head, obj.head);
SWAP(VectorType*, begin, obj.begin);
SWAP(VectorType*, storage, obj.storage);
}
// Checks the entire Vector to see whether a matching item exists. Bear in mind that the VectorType might need to implement
// equality operator (operator==) for this to work properly.
bool Contains(VectorType element)
{
for(int i = 0; i < Size(); i++)
if(operator [](i) == element)
return true;
return false;
}
int Find(VectorType element)
{
for(int i = 0; i < Size(); i++)
if(operator [](i) == element)
return i;
return -1;
}
void PushBack(VectorType element) { PushBack(&element, 1); }
void PushBack(const VectorType *elements, int len)
{
// If the length plus this's size is greater than the capacity, reallocate to that size.
if(len + Size() > Capacity())
ReAllocate(MAX(Size() + len, Size() * 2));
int append = MIN(storage - begin - head - 1, len), prepend = len - append;
// memcpy the data starting at the head all the way up to the last element *(storage - 1)
memcpy((begin + head + 1), elements, sizeof(VectorType) * append);
// If there's still data to copy memcpy whatever remains, starting at the first element *(begin) until the end of data. The first step will have ensured
// that we don't crash into the tail during this process.
memcpy(begin,(elements + append), sizeof(VectorType) * prepend);
// Re-recalculate head and size.
head += len;
}
void Erase(unsigned int position) { Erase(position, position + 1); }
// Erase an arbitrary section of the vector from first up to last minus one. Like the stl counterpart, this is pretty labour intensive so go easy on it.
void Erase(int first, int last)
{
// For this we'll set the value of the array at first to the value of the array at last plus one. We'll do that all the way up to toIndex
for(int i = 0; i < (Size() - first); i++)
{
// If by trying to fill in the next element with the ones ahead of it we'll be running off the end of the vector, stop.
if((i + last) > (Size() - 1))
break;
begin[first + i] = begin[last + i];
}
// Adjust the head to reflect the new size
head -= last - first;
}
// Remove the most recent element in the array
void PopBack()
{
if(Size() > 0)
head--;
}
// Empty the vector, or to be precise - forget the fact that there was ever anything in there.
void Clear() { head = -1; }
// Returns a bool indicating whether or not there are any elements in the array
bool Empty() { return head == -1; }
// Returns the oldest element in the array (the one added before any other)
VectorType const &Back() { return *begin; }
// Returns the newest element in the array (the one added after every other)
VectorType const &Front() { return begin[head]; }
// Returns the nth element in the vector
VectorType &operator[](int n)
{
if(n < Size())
return begin[n];
else
return OB;
}
// Returns a pointer such that the vector's data is laid out between ret to ret + size
VectorType *Data() { return begin; }
// Recreates the vector to hold len elements, all being copies of val
void Assign(int len, const VectorType &val)
{
delete[] begin;
// Allocate an array the same size as the one passed in
begin = new VectorType[len];
storage = begin + len;
// Refresh the head and tail, assuming the array is in order, which it really has to be
head = len - 1;
for(int i = 0 ; i < Size(); i++)
begin[i] = val;
}
// Recreates the vector using an external array
void Assign(VectorType *array, int len)
{
delete[] begin;
// Allocate an array the same size as the one passed in
begin = new VectorType[len];
storage = begin + len;
// Refresh the head and tail, assuming the array is in order, which it really has to be
head = len - 1;
// Copy over the memory
memcpy(begin, array, sizeof(VectorType) * len);
}
// Returns the number of elements that the vector will support before needing resizing
int Capacity() { return (storage - begin); }
// Returns the number of elements in vector
int Size() { return head + 1; }
// Requests that the capacity of the allocated storage space for the elements
// of the vector be at least enough to hold size elements.
void Reserve(unsigned int size)
{
if(size > Capacity())
ReAllocate(size);
}
// Resizes the vector
void Resize(unsigned int size)
{
// If necessary, resize the underlying array to fit the new size
if(size > Capacity())
ReAllocate(size);
// Now revise the head and size (tail needn't change) to reflect the new size
head = size - 1;
}
private:
void ReAllocate(unsigned int size)
{
// Just in case we're re-allocating less room than we had before, make sure that we don't overrun the buffer by trying to write more elements than
// are now possible for this vector to hold.
if(Size() > (int)size)
head = size - 1;
// Allocate an array twice the size of that of the old
VectorType *_begin = new VectorType[size];
VectorType *_storage = _begin + size;
int _head = Size() - 1;
// Copy across all the old array's data and rearrange it!
for(int i = 0; i < Size(); i++)
_begin[i] = (*this)[i];
// Free the old memory
delete[] begin;
// Redirect the old array to point to the new one
begin = _begin;
storage = _storage;
head = _head;
}
};
#endif // VECTOR_H

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,19 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"C:\\Program Files (x86)\\Arduino\\tools\\**",
"C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\**",
"C:\\Users\\i\\AppData\\Local\\Arduino15\\packages\\esp8266\\tools\\**",
"C:\\Users\\i\\AppData\\Local\\Arduino15\\packages\\esp8266\\hardware\\esp8266\\2.5.2\\**"
],
"forcedInclude": [
"C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino\\Arduino.h"
],
"intelliSenseMode": "msvc-x64",
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe"
}
],
"version": 4
}

@ -0,0 +1,10 @@
{
"files.associations": {
"initializer_list": "cpp",
"list": "cpp",
"vector": "cpp",
"xhash": "cpp",
"xstring": "cpp",
"xutility": "cpp"
}
}

@ -0,0 +1,211 @@
#include"BME280.h"
#include<Arduino.h>
#include<Wire.h>
void BME280::readTrim()
{
uint8_t data[32],i=0;
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0x88);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,24);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xA1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,1);
data[i] = Wire.read();
i++;
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xE1);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,7);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
dig_T1 = (data[1] << 8) | data[0];
dig_T2 = (data[3] << 8) | data[2];
dig_T3 = (data[5] << 8) | data[4];
dig_P1 = (data[7] << 8) | data[6];
dig_P2 = (data[9] << 8) | data[8];
dig_P3 = (data[11]<< 8) | data[10];
dig_P4 = (data[13]<< 8) | data[12];
dig_P5 = (data[15]<< 8) | data[14];
dig_P6 = (data[17]<< 8) | data[16];
dig_P7 = (data[19]<< 8) | data[18];
dig_P8 = (data[21]<< 8) | data[20];
dig_P9 = (data[23]<< 8) | data[22];
dig_H1 = data[24];
dig_H2 = (data[26]<< 8) | data[25];
dig_H3 = data[27];
dig_H4 = (data[28]<< 4) | (0x0F & data[29]);
dig_H5 = (data[30] << 4) | ((data[29] >> 4) & 0x0F);
dig_H6 = data[31];
}
void BME280::writeReg(uint8_t reg_address, uint8_t data)
{
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(reg_address);
Wire.write(data);
Wire.endTransmission();
}
void BME280::readData()
{
int i = 0;
uint32_t data[8];
Wire.beginTransmission(BME280_ADDRESS);
Wire.write(0xF7);
Wire.endTransmission();
Wire.requestFrom(BME280_ADDRESS,8);
while(Wire.available()){
data[i] = Wire.read();
i++;
}
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4);
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4);
hum_raw = (data[6] << 8) | data[7];
}
double BME280::getTemp()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
/* Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");*/
//delay(1000);
return temp_act;
}
double BME280::getPress()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
/* Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");*/
//delay(1000);
return press_cal;
}
double BME280::getHum()
{
double temp_act = 0.0, press_act = 0.0,hum_act=0.0;
signed long int temp_cal;
unsigned long int press_cal,hum_cal;
readData();
temp_cal = calibration_T(temp_raw);
press_cal = calibration_P(pres_raw);
hum_cal = calibration_H(hum_raw);
temp_act = (double)temp_cal / 100.0;
press_act = (double)press_cal / 100.0;
hum_act = (double)hum_cal / 1024.0;
/* Serial.print("TEMP : ");
Serial.print(temp_act);
Serial.print(" DegC PRESS : ");
Serial.print(press_act);
Serial.print(" hPa HUM : ");
Serial.print(hum_act);
Serial.println(" %");*/
//delay(1000);
return hum_act;
}
signed long int BME280::calibration_T(signed long int adc_T)
{
signed long int var1, var2, T;
var1 = ((((adc_T >> 3) - ((signed long int)dig_T1<<1))) * ((signed long int)dig_T2)) >> 11;
var2 = (((((adc_T >> 4) - ((signed long int)dig_T1)) * ((adc_T>>4) - ((signed long int)dig_T1))) >> 12) * ((signed long int)dig_T3)) >> 14;
t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}
unsigned long int BME280::calibration_P(signed long int adc_P)
{
signed long int var1, var2;
unsigned long int P;
var1 = (((signed long int)t_fine)>>1) - (signed long int)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)dig_P6);
var2 = var2 + ((var1*((signed long int)dig_P5))<<1);
var2 = (var2>>2)+(((signed long int)dig_P4)<<16);
var1 = (((dig_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)dig_P2) * var1)>>1))>>18;
var1 = ((((32768+var1))*((signed long int)dig_P1))>>15);
if (var1 == 0)
{
return 0;
}
P = (((unsigned long int)(((signed long int)1048576)-adc_P)-(var2>>12)))*3125;
if(P<0x80000000)
{
P = (P << 1) / ((unsigned long int) var1);
}
else
{
P = (P / (unsigned long int)var1) * 2;
}
var1 = (((signed long int)dig_P9) * ((signed long int)(((P>>3) * (P>>3))>>13)))>>12;
var2 = (((signed long int)(P>>2)) * ((signed long int)dig_P8))>>13;
P = (unsigned long int)((signed long int)P + ((var1 + var2 + dig_P7) >> 4));
return P;
}
unsigned long int BME280::calibration_H(signed long int adc_H)
{
signed long int v_x1;
v_x1 = (t_fine - ((signed long int)76800));
v_x1 = (((((adc_H << 14) -(((signed long int)dig_H4) << 20) - (((signed long int)dig_H5) * v_x1)) +
((signed long int)16384)) >> 15) * (((((((v_x1 * ((signed long int)dig_H6)) >> 10) *
(((v_x1 * ((signed long int)dig_H3)) >> 11) + ((signed long int) 32768))) >> 10) + (( signed long int)2097152)) *
((signed long int) dig_H2) + 8192) >> 14));
v_x1 = (v_x1 - (((((v_x1 >> 15) * (v_x1 >> 15)) >> 7) * ((signed long int)dig_H1)) >> 4));
v_x1 = (v_x1 < 0 ? 0 : v_x1);
v_x1 = (v_x1 > 419430400 ? 419430400 : v_x1);
return (unsigned long int)(v_x1 >> 12);
}

@ -0,0 +1,54 @@
#ifndef BME280_H_
#define BME280_H_
#include <Wire.h>
#include <Arduino.h>
class BME280
{
#define BME280_ADDRESS 0x76
private:
signed long int t_fine;
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
int8_t dig_H1;
int16_t dig_H2;
int8_t dig_H3;
int16_t dig_H4;
int16_t dig_H5;
int8_t dig_H6;
public:
unsigned long int hum_raw,temp_raw,pres_raw;
void readTrim();
void writeReg(uint8_t reg_address, uint8_t data);
void readData();
double getTemp();
double getPress();
double getHum();
signed long int calibration_T(signed long int adc_T);
unsigned long int calibration_P(signed long int adc_P);
unsigned long int calibration_H(signed long int adc_H);
};
#endif

@ -0,0 +1,28 @@
#include<Wire.h>
#include"GY30.h"
#include <Arduino.h>
int GY30::getLight()
{
// put your main code here, to run repeatedly:
int val = 0;
// reset
Wire.beginTransmission(ADDR);
Wire.write(0b00000111);
Wire.endTransmission();
Wire.beginTransmission(ADDR);
Wire.write(0b00100000);
Wire.endTransmission();
// typical read delay 120ms
delay(120);
Wire.requestFrom(ADDR, 2); // 2byte every time
for (val = 0; Wire.available() >= 1; ) {
char c = Wire.read();
//Serial.println(c, HEX);
val = (val << 8) + (c & 0xFF);
}
val = val / 1.2;
return val;
}

@ -0,0 +1,17 @@
#ifndef GY30_H_
#define GY30_H_
#include <Wire.h>
#include <Arduino.h>
class GY30
{
#define ADDR 0b0100011
private:
public:
int getLight();
};
#endif

@ -0,0 +1,87 @@
#ifndef __LORA_MATT_H__
#define __LORA_MATT_H__
#define MAX_STRINGVEC_SIZE 2
#include "lora-socket.h"
class LoRaMQTT{
public:
inline void ini(){
socket.ini();
socket.onReceived(_onReceived);
}
inline void core(){
if(isLoopMode){
if(socket.isNewMsg()){
String msg = "", from = "", to = "", type = "";
socket.getNewMsg(msg, from, to, type);
_onReceived(msg, from, to, type);
}
}
socket.core();
}
inline void publish(const String& subject, const String& content){
String s = subject + "$" + content;
socket.udp(s);
}
inline void subscribe(const String& subject){
this->_subjects.PushBack(subject);
}
inline static void onReceived(void (*f)(String, String)){
_f = f;
}
inline bool isNewMsg(){
isLoopMode = true;
return (newSubject == "") ? false : true;
};
inline void getNewMsg(String& subject, String& content){
subject = newSubject;
content = newContent;
clearNewMsg();
}
private:
static LoRaSocket socket;
static StringVec _subjects;
static void (*_f)(String, String);
static String newSubject, newContent;
static bool isLoopMode;
inline void clearNewMsg(){
newSubject = "";
newContent = "";
};
inline static void _onReceived(String msg, String from, String to, String type){
if(msg.indexOf('$') == -1) return;
String subject = msg.substring(0, msg.indexOf('$'));
String content = msg.substring(msg.indexOf('$') + 1, msg.length());
if(_subjects.Find("#") != -1 || _subjects.Find(subject) != -1){
newSubject = subject;
newContent = content;
if(!isLoopMode) _f(subject, content);
}
};
};
LoRaSocket LoRaMQTT::socket;
StringVec LoRaMQTT::_subjects;
void (*LoRaMQTT::_f)(String, String);
String LoRaMQTT::newSubject = "", LoRaMQTT::newContent = "";
bool LoRaMQTT::isLoopMode = false;
#endif //__LORA_MATT_H__

@ -0,0 +1,289 @@
#ifndef __LORA_SOCKET_H__
#define __LORA_SOCKET_H__
#include <LoRa.h>
#include "vector.h"
#include "stringVec.h"
#ifndef LORA_SOCKET_IP
#define LORA_SOCKET_IP "0.0.0.0"
#endif
#ifndef MAX_RECEIVE_STACK_SIZE
#define MAX_RECEIVE_STACK_SIZE 5
#endif
#ifndef MAX_SEND_STACK_SIZE
#define MAX_SEND_STACK_SIZE 5
#endif
#ifndef MAX_TCP_TRY_TIMES
#define MAX_TCP_TRY_TIMES 8
#endif
class LoRaSocket {
public:
LoRaSocket(){}
static void core();
static void ini();
static void udp(const String& msg, const String& to = "0.0.0.0");
static void tcp(const String& msg, const String& to);
static void rtcp(const String& msg);
inline static void onReceived(void (*f)(String, String, String, String)){
_f = f;
};
inline bool isNewMsg(){
isLoopMode = true;
return (newType == "") ? false : true;
};
inline const String getNewMsg(){
String msg = newMsg;
clearNewMsg();
return msg;
};
inline void getNewMsg(String& msg, String& from, String& to, String& type){
msg = newMsg;
from = newFrom;
to = newTo;
type = newType;
clearNewMsg();
};
private:
static StringVec tcp_sendingStack, tcp_receiveStack;
static Vector<unsigned int> tcp_sendingTryTimes;
static void(*_f)(String, String, String, String);
static String newMsg, newFrom, newTo, newType;
static bool isLoopMode;
inline void clearNewMsg(){
newMsg = "";
newFrom = "";
newTo = "";
newType = "";
};
inline static void _onReceived(const String& msg, const String& from, const String& to, const String& type){
newMsg = msg;
newFrom = from;
newTo = to;
newType = type;
if(!isLoopMode) (*_f)(msg, from, to, type);
};
/* LoRa Functions */
static void LoRa_tx_mode();
static void LoRa_rx_mode();
static void send(const String& s);
static void send(const char *s);
static const String receiveMsg();
/* Package Functions */
inline static const String getIPHeader(const String& to = "0.0.0.0"){
return to + "|" + LORA_SOCKET_IP + "|";
};
inline static bool isGoodPackage(const String& s){
String body = s.substring(0, s.length() - 1);
if(s.substring(s.length() - 1, s.length()) != hash(body)){
return false;
}
return true;
};
inline static const String getToIP(const String& s){
unsigned short left = s.indexOf('|');
unsigned short right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
inline static const String getFromIP(const String& s){
unsigned short left = s.indexOf('|', s.indexOf('|') + 1);
unsigned short right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
inline static const String getType(const String& s){
return s.substring(0, s.indexOf('|'));
};
inline static const String getContent(const String& s){
unsigned short left = s.indexOf('|', s.indexOf('|', s.indexOf('|') + 1) + 1);
unsigned short right = s.indexOf('|', left + 1);
return decode(s.substring(left + 1, right));
};
inline static const String getTcpKey(const String& s){
int left = s.indexOf('|', s.indexOf('|', s.indexOf('|', s.indexOf('|') + 1) + 1) + 1);
int right = s.indexOf('|', left + 1);
return s.substring(left + 1, right);
};
/* receive Functions */
static void getMsg(const String& msg);
/* tcp stack functions */
static void checkSendStack(){
for(unsigned int i = 0; i < tcp_sendingStack.Size(); i ++){
send("tc"+tcp_sendingStack[i]);
tcp_sendingTryTimes[i] += 1;
if(tcp_sendingTryTimes[i] >= MAX_TCP_TRY_TIMES){
tcp_sendingStack.Erase(i);
tcp_sendingTryTimes.Erase(i);
}
}
};
inline static void receiveStackClassify(){
if(tcp_receiveStack.Size() > MAX_RECEIVE_STACK_SIZE) tcp_receiveStack.Erase(0);
};
inline static void sendStackClassify(){
if(tcp_sendingStack.Size() > MAX_SEND_STACK_SIZE) {
tcp_sendingStack.Erase(0);
tcp_sendingTryTimes.Erase(0);
}
};
static void removeByKey(const String& key);
/* tools */
static const String hash(const String& s);
static const String encode(const String& s){
return s;
};
static const String decode(const String& s){
return s;
}
static const String generateRandomKey(){
String o = "";
for(unsigned short i = 0; i < 4; i ++){
o += char(random(26) + 97);
}
return o;
}
/* timer */
static void setInterval(void (*function)(void), const int delay){
static unsigned long startTime = millis();
if(millis() - startTime > delay){
(*function)();
startTime = millis();
}
}
};
void LoRaSocket::getMsg(const String& msg){
if(!isGoodPackage(msg)) return;
if(getToIP(msg) != LORA_SOCKET_IP && getToIP(msg) != "0.0.0.0") return;
if(getType(msg) == "udp") _onReceived(getContent(msg), getFromIP(msg), getToIP(msg), "udp");
if(getType(msg) == "tcp"){
rtcp(msg);
if(tcp_receiveStack.Find(msg) != -1) return;
_onReceived(getContent(msg), getFromIP(msg), getToIP(msg), "tcp");
receiveStackClassify();
}
if(getType(msg) == "rtcp"){
removeByKey(getContent(msg));
}
}
void LoRaSocket::udp(const String& msg, const String& to){
char *c;
c = (char*)malloc((msg.length()+39)*sizeof(char));
sprintf(c, "udp|%s%s|", getIPHeader(to).c_str(), encode(msg).c_str());
sprintf(c, "%s%s", c, hash(c).c_str());
send(c);
free(c);
};
void LoRaSocket::tcp(const String& msg, const String& to){
String fin = "tcp|" + getIPHeader(to) + encode(msg) + "|" + generateRandomKey() + "|";
fin += hash(fin);
tcp_sendingStack.PushBack(fin);
tcp_sendingTryTimes.PushBack(0);
sendStackClassify();
send(fin);
};
void LoRaSocket::rtcp(const String& msg){
tcp_receiveStack.PushBack(msg);
String fin = "rtcp|" + getIPHeader(getFromIP(msg)) + getTcpKey(msg) + "|";
fin += hash(fin);
send(fin);
}
StringVec LoRaSocket::tcp_sendingStack, LoRaSocket::tcp_receiveStack;
Vector<unsigned int> LoRaSocket::tcp_sendingTryTimes;
void (*LoRaSocket::_f)(String, String, String, String);
String LoRaSocket::newMsg = "", LoRaSocket::newFrom = "", LoRaSocket::newTo = "", LoRaSocket::newType = "";
bool LoRaSocket::isLoopMode = false;
void LoRaSocket::ini() {
LoRa_rx_mode();
}
void LoRaSocket::core() {
/* Listen Msg */
if(LoRa.parsePacket()){
getMsg(receiveMsg());
}
/* check tcp stack */
setInterval(checkSendStack, 1000);
}
void LoRaSocket::LoRa_tx_mode(){
LoRa.idle();
}
void LoRaSocket::LoRa_rx_mode(){
LoRa.receive();
}
void LoRaSocket::send(const char *s){
LoRa_tx_mode();
delay(200);
LoRa.beginPacket();Serial.println(s);
LoRa.print(s);
LoRa.endPacket();
delay(200);
LoRa_rx_mode();
}
void LoRaSocket::send(const String& s){
LoRa_tx_mode();
delay(200);
LoRa.beginPacket();Serial.println(s);
LoRa.print(s);
LoRa.endPacket();
delay(200);
LoRa_rx_mode();
}
const String LoRaSocket::receiveMsg(){
String s = "";
while (LoRa.available()) {
s += (char)LoRa.read();
}
return s;
}
const String LoRaSocket::hash(const String& s){
unsigned char hashVal = 'k';
for(unsigned short i = 0; i < s.length(); i ++){
hashVal ^= s.charAt(i);
}
hashVal = hashVal % 26 + 97;
return String((char)hashVal);
}
void LoRaSocket::removeByKey(const String& key){
for(unsigned int i = 0; i < tcp_sendingStack.Size(); i++){
if(getTcpKey(tcp_sendingStack[i]) == key) {
tcp_sendingStack.Erase(i);
return;
}
}
}
#endif //__LORA_SOCKET_H__

@ -0,0 +1,149 @@
//#include <ArduinoJson.h>
#include <SPI.h>
#include <LoRa.h>
#include <Arduino.h>
#include "BME280.h"
#include "GY30.h"
//const size_t capacity = JSON_OBJECT_SIZE(15);
//DynamicJsonDocument data(capacity);
#define LORA_SOCKET_IP "1.0.0.2"
#include "lora-mqtt.h"
LoRaMQTT mqtt;
BME280 bme;
GY30 gy;
void setup() {
uint8_t osrs_t = 1; //Temperature oversampling x 1
uint8_t osrs_p = 1; //Pressure oversampling x 1
uint8_t osrs_h = 1; //Humidity oversampling x 1
uint8_t mode = 3; //Normal mode
uint8_t t_sb = 5; //Tstandby 1000ms
uint8_t filter = 0; //Filter off
uint8_t spi3w_en = 0; //3-wire SPI Disable
uint8_t ctrl_meas_reg = (osrs_t << 5) | (osrs_p << 2) | mode;
uint8_t config_reg = (t_sb << 5) | (filter << 2) | spi3w_en;
uint8_t ctrl_hum_reg = osrs_h;
Serial.begin(115200);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A3, INPUT);
pinMode(A7, INPUT);
Wire.begin();
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
mqtt.ini();
mqtt.subscribe("#");
mqtt.onReceived(mqttRes);
bme.writeReg(0xF2,ctrl_hum_reg);
bme.writeReg(0xF4,ctrl_meas_reg);
bme.writeReg(0xF5,config_reg);
bme.readTrim();
}
void loop() {
mqtt.core();
}
void mqttRes(String subject, String content){
if(subject == "qos/sync"){
String s;
getData(s, content);
//data = getJson();
//data["qos"] = content;
//data["type"] = "station";
//serializeJson(data, dataStr);
Serial.println(s);
mqtt.publish("res/json", s);
}
}
void getData(String& s, const String& content){
s = "{\"t\":\"station\",\"l\": ";
s += gy.getLight();
s += ",\"T\":";
s += bme.getTemp();
s += ",\"h\":";
s += bme.getHum();
s += ",\"a\":";
s += bme.getPress()/100;
s += ",\"C\":";
s += analogRead(A0);
s += ",\"N\":";
s += analogRead(A1);
s += ",\"r\":";
s += analogRead(A2);
s += ",\"b\":";
s += (unsigned int)analogRead(A6)*100/1024;
s += ",\"s\":";
s += 0;
s += ",\"q\":";
s += content;
s += "}";
}
/*
//DynamicJsonDocument createJson(const size_t capacity, int Light, long int batteryLevel, double Temp, double Hum, double Press, int CO, int NH3, int Rain)
DynamicJsonDocument getJson()
{
DynamicJsonDocument json(capacity);
int Light = gy.getLight();
double Temp = bme.getTemp();
double Hum = bme.getHum();
double Press = bme.getPress()/100;
int CO = analogRead(A0);
int NH3 = analogRead(A1);
int Rain = analogRead(A2);
long int batteryLevel = analogRead(A6);
batteryLevel = (batteryLevel * 100)/1024;
Serial.print("Light: ");
Serial.println(Light);
Serial.print("batteryLevel: ");
Serial.println(batteryLevel);
Serial.print("Temperature: ");
Serial.println(Temp);
Serial.print("Humidity: ");
Serial.println(Hum);
Serial.print("Press: ");
Serial.println(Press);
Serial.print("Rain: ");
Serial.println(Rain);
Serial.print("CO: ");
Serial.println(CO);
Serial.print("NH3: ");
Serial.println(NH3);
Serial.println();
json["status"] = "0";
json["batterylevel"] = batteryLevel;
json["light"] = Light;
json["temperature"] = Temp;
json["humidity"] = Hum;
json["rainfall"] = Rain;
json["co"] = CO;
json["nh3"] = NH3;
json["airpressure"] = Press;
return json;
}
*/

@ -0,0 +1,77 @@
#ifndef __STRINGVEC__
#define __STRINGVEC__
#ifndef MAX_STRINGVEC_SIZE
#define MAX_STRINGVEC_SIZE 2
#endif
class StringVec{
public:
StringVec():_size(0){
this->clear();
};
inline void PushBack(const String& ss){
if(this->Size() == MAX_STRINGVEC_SIZE){
this->shift();
}
this->_s[this->Size()] = ss;
this->_size ++;
}
const int Find(const String& ss){
for(unsigned i = 0; i < this->Size(); i ++){
if(this->_s[i] == ss){
return i;
}
}
return -1;
}
void Erase(const int& pos){
if(pos < 0 || pos >= this->Size()) return;
for(unsigned int i = pos+1; i < this->Size(); i ++){
this->_s[i-1] = this->_s[i];
}
this->_size --;
}
const String shift(){
String s = this->_s[0];
if(this->Size() != 0){
for(unsigned int i = 1; i < this->Size(); i ++){
this->_s[i-1] = this->_s[i];
}
this->_size --;
}
return s;
}
void clear(){
for(unsigned int i = 0; i < this->Size(); i ++){
this->_s[i] = "";
}
}
inline const int Size(){
return this->_size;
}
String& operator[](int i){
if(i < 0 || i >= this->Size()) return this->_s[0];
return this->_s[i];
}
private:
String _s[MAX_STRINGVEC_SIZE];
int _size;
};
#endif //__STRINGVEC__

@ -0,0 +1,269 @@
/*
* Vector.h
*
* Created on: 05/04/2012
* Author: tom
* Purpose: To play the part of a mutable array in the absence of the STL.
*/
#ifndef VECTOR_H
#define VECTOR_H
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#define SWAP(type, a, b) type tmp ## a = a; a = b; b = tmp ## a;
template <class ParameterType> class Predicate
{
public:
virtual void operator() (ParameterType &param) = 0;
};
template <class VectorType> class Vector
{
// The address of the first element of the vector
VectorType *begin;
// The address one after the last allocated entry in the underlying array
VectorType *storage;
// The index of the most recent element put in the underlying array - the head
int head;
public:
// The value that is returned when the caller asks for an element that is out of the bounds of the vector
VectorType OB;
// We can save a few re-sizings if we know how large the array is likely to grow to be
Vector(int initialSize = 0)
{
begin = new VectorType[initialSize]; //points to the beginning of the new array
head = initialSize - 1;
storage = begin + initialSize; //points to the element one outside of the array (such that end - begin = capacity)
}
Vector(Vector &obj)
{
begin = new VectorType[0]; // Points to the beginning of the new array, it's zero but this line keeps malloc from seg faulting should we delete begin before resizing it
head = -1;
storage = begin; //points to the element one outside of the array (such that end - begin = capacity)
*this = obj;
}
// If there's anything in the vector then delete the array, if there's no array then doing will will cause seg faults
virtual ~Vector() { delete[] begin; }
Vector &operator=(Vector &obj)
{
// Reallocate the underlying buffer to the same size as the
Resize(obj.Size());
for(int i = 0; i < obj.Size(); i++)
(*this)[i] = obj[i];
head = obj.head;
return *this;
}
void ForEach(Predicate<VectorType> &functor)
{
for(int i = 0; i < Size(); i++)
functor(begin[i]);
}
// Swaps the underlying array and characteristics of this vector with another of the same type, very quickly
void Swap(Vector &obj)
{
SWAP(int, head, obj.head);
SWAP(VectorType*, begin, obj.begin);
SWAP(VectorType*, storage, obj.storage);
}
// Checks the entire Vector to see whether a matching item exists. Bear in mind that the VectorType might need to implement
// equality operator (operator==) for this to work properly.
bool Contains(VectorType element)
{
for(int i = 0; i < Size(); i++)
if(operator [](i) == element)
return true;
return false;
}
int Find(VectorType element)
{
for(int i = 0; i < Size(); i++)
if(operator [](i) == element)
return i;
return -1;
}
void PushBack(VectorType element) { PushBack(&element, 1); }
void PushBack(const VectorType *elements, int len)
{
// If the length plus this's size is greater than the capacity, reallocate to that size.
if(len + Size() > Capacity())
ReAllocate(MAX(Size() + len, Size() * 2));
int append = MIN(storage - begin - head - 1, len), prepend = len - append;
// memcpy the data starting at the head all the way up to the last element *(storage - 1)
memcpy((begin + head + 1), elements, sizeof(VectorType) * append);
// If there's still data to copy memcpy whatever remains, starting at the first element *(begin) until the end of data. The first step will have ensured
// that we don't crash into the tail during this process.
memcpy(begin,(elements + append), sizeof(VectorType) * prepend);
// Re-recalculate head and size.
head += len;
}
void Erase(unsigned int position) { Erase(position, position + 1); }
// Erase an arbitrary section of the vector from first up to last minus one. Like the stl counterpart, this is pretty labour intensive so go easy on it.
void Erase(int first, int last)
{
// For this we'll set the value of the array at first to the value of the array at last plus one. We'll do that all the way up to toIndex
for(int i = 0; i < (Size() - first); i++)
{
// If by trying to fill in the next element with the ones ahead of it we'll be running off the end of the vector, stop.
if((i + last) > (Size() - 1))
break;
begin[first + i] = begin[last + i];
}
// Adjust the head to reflect the new size
head -= last - first;
}
// Remove the most recent element in the array
void PopBack()
{
if(Size() > 0)
head--;
}
// Empty the vector, or to be precise - forget the fact that there was ever anything in there.
void Clear() { head = -1; }
// Returns a bool indicating whether or not there are any elements in the array
bool Empty() { return head == -1; }
// Returns the oldest element in the array (the one added before any other)
VectorType const &Back() { return *begin; }
// Returns the newest element in the array (the one added after every other)
VectorType const &Front() { return begin[head]; }
// Returns the nth element in the vector
VectorType &operator[](int n)
{
if(n < Size())
return begin[n];
else
return OB;
}
// Returns a pointer such that the vector's data is laid out between ret to ret + size
VectorType *Data() { return begin; }
// Recreates the vector to hold len elements, all being copies of val
void Assign(int len, const VectorType &val)
{
delete[] begin;
// Allocate an array the same size as the one passed in
begin = new VectorType[len];
storage = begin + len;
// Refresh the head and tail, assuming the array is in order, which it really has to be
head = len - 1;
for(int i = 0 ; i < Size(); i++)
begin[i] = val;
}
// Recreates the vector using an external array
void Assign(VectorType *array, int len)
{
delete[] begin;
// Allocate an array the same size as the one passed in
begin = new VectorType[len];
storage = begin + len;
// Refresh the head and tail, assuming the array is in order, which it really has to be
head = len - 1;
// Copy over the memory
memcpy(begin, array, sizeof(VectorType) * len);
}
// Returns the number of elements that the vector will support before needing resizing
int Capacity() { return (storage - begin); }
// Returns the number of elements in vector
int Size() { return head + 1; }
// Requests that the capacity of the allocated storage space for the elements
// of the vector be at least enough to hold size elements.
void Reserve(unsigned int size)
{
if(size > Capacity())
ReAllocate(size);
}
// Resizes the vector
void Resize(unsigned int size)
{
// If necessary, resize the underlying array to fit the new size
if(size > Capacity())
ReAllocate(size);
// Now revise the head and size (tail needn't change) to reflect the new size
head = size - 1;
}
private:
void ReAllocate(unsigned int size)
{
// Just in case we're re-allocating less room than we had before, make sure that we don't overrun the buffer by trying to write more elements than
// are now possible for this vector to hold.
if(Size() > (int)size)
head = size - 1;
// Allocate an array twice the size of that of the old
VectorType *_begin = new VectorType[size];
VectorType *_storage = _begin + size;
int _head = Size() - 1;
// Copy across all the old array's data and rearrange it!
for(int i = 0; i < Size(); i++)
_begin[i] = (*this)[i];
// Free the old memory
delete[] begin;
// Redirect the old array to point to the new one
begin = _begin;
storage = _storage;
head = _head;
}
};
#endif // VECTOR_H
Loading…
Cancel
Save