first commit
This commit is contained in:
3
extra_script.py
Normal file
3
extra_script.py
Normal file
@ -0,0 +1,3 @@
|
||||
Import("env")
|
||||
|
||||
env.Replace(PROGNAME="firmware_%s" % env.GetProjectOption("custom_prog_version"))
|
39
include/README
Normal file
39
include/README
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
46
lib/README
Normal file
46
lib/README
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
52
platformio.ini
Normal file
52
platformio.ini
Normal file
@ -0,0 +1,52 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
; [env:esp32dev]
|
||||
; platform = espressif32
|
||||
; board = esp32dev
|
||||
; framework = arduino
|
||||
; monitor_speed = 115200
|
||||
; ;upload_speed=115200
|
||||
; ; upload_port = COM31
|
||||
; ;monitor_port = com5
|
||||
; lib_deps =
|
||||
; vshymanskyy/TinyGSM@^0.11.5
|
||||
; knolleary/PubSubClient@^2.8
|
||||
; plerup/EspSoftwareSerial@^6.15.2
|
||||
; arduino-libraries/ArduinoHttpClient@^0.4.0
|
||||
; janelia-arduino/Vector@^1.2.2
|
||||
; build_flags:
|
||||
; -DVERSION=${this.custom_prog_version}
|
||||
; extra_scripts = pre:extra_script.py
|
||||
; custom_prog_version = V2.6
|
||||
|
||||
|
||||
[env:esp32-s3-devkitc-1]
|
||||
; platformio/espressif32@^6.4.0
|
||||
platform = espressif32 @ ^4.4.0
|
||||
board = esp32-s3-devkitc-1
|
||||
framework = arduino
|
||||
platform_packages =
|
||||
toolchain-riscv32-esp @ 8.4.0+2021r2-patch5
|
||||
; framework-arduinoespressif32 @ 2.0.6+sha.099b432
|
||||
board_upload.flash_size=4MB
|
||||
board_upload.psram_size =2MB
|
||||
lib_deps =
|
||||
vshymanskyy/TinyGSM@^0.11.5
|
||||
knolleary/PubSubClient@^2.8
|
||||
plerup/EspSoftwareSerial@^6.15.2
|
||||
arduino-libraries/ArduinoHttpClient@^0.4.0
|
||||
janelia-arduino/Vector@^1.2.2
|
||||
paulstoffregen/OneWire@^2.3.7
|
||||
milesburton/DallasTemperature@^3.11.0
|
||||
adafruit/Adafruit MLX90614 Library@^2.1.3
|
||||
sparkfun/SparkFun u-blox Arduino Library@^1.8.11
|
||||
|
||||
|
13
smartweatherstation.code-workspace
Normal file
13
smartweatherstation.code-workspace
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"name": "smartweatherstation",
|
||||
"path": "smartweatherstation"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"files.associations": {
|
||||
"*.tpp": "cpp"
|
||||
}
|
||||
}
|
||||
}
|
10
src/Define.h
Normal file
10
src/Define.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef Define_h
|
||||
#define Define_h
|
||||
//#define DebugCalibration
|
||||
//#define DINBIAO
|
||||
//#define Curentvsion "V2.4b"\
|
||||
#define Curentvsion "V2.5b"
|
||||
#define Curentvsion "V2.3"
|
||||
#define TINY_GSM_DEBUG Serial
|
||||
|
||||
#endif
|
136
src/GSMMannager.cpp
Normal file
136
src/GSMMannager.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include "GSMMannager.h"
|
||||
HardwareSerial *MySerial;
|
||||
GSMMannger::GSMMannger(int serialnumber, int rx, int tx)
|
||||
{
|
||||
MySerial=new HardwareSerial(serialnumber);
|
||||
modem = new TinyGsm(*MySerial);
|
||||
MySerial->begin(115200, SERIAL_8N1, rx, tx);
|
||||
client = new TinyGsmClient(*modem);
|
||||
// !!!!!!!!!!! <20>ϵ<EFBFBD>
|
||||
Serial.println("Wait...");
|
||||
pinMode(37, OUTPUT); //pin32控制sim800C电源 高电平上电 低电平断电
|
||||
digitalWrite(37, HIGH);
|
||||
delay(100);
|
||||
digitalWrite(37, LOW);
|
||||
Serial.println("Wait...1");
|
||||
delay(1800);
|
||||
// Set your reset, enable, power pins here
|
||||
// !!!!!!!!!!!
|
||||
|
||||
delay(5000);
|
||||
// Set GSM module baud rate
|
||||
// MySerial->readString();
|
||||
int banddd=TinyGsmAutoBaud(*MySerial, rx, tx, 9600,460800);
|
||||
if (banddd==0)
|
||||
{
|
||||
Serial.println("fail to connect sim800 reboot");
|
||||
esp_restart();
|
||||
/* code */
|
||||
}
|
||||
|
||||
Serial.println("band is" + String(banddd));
|
||||
delay(6000);
|
||||
modem->init();
|
||||
|
||||
String modemInfo = modem->getModemInfo();
|
||||
if (modemInfo=="")
|
||||
{
|
||||
Serial.println("fail to getmode reboot");
|
||||
esp_restart();
|
||||
/* code */
|
||||
}
|
||||
Serial.print("Modem Info: ");
|
||||
|
||||
SerialMon.println(modemInfo);
|
||||
if (GSM_PIN && modem->getSimStatus() != 3)
|
||||
{
|
||||
modem->simUnlock(GSM_PIN);
|
||||
}
|
||||
SerialMon.print("Waiting for network...");
|
||||
if (!modem->waitForNetwork())
|
||||
{
|
||||
SerialMon.println(" fail");
|
||||
delay(10000);
|
||||
return;
|
||||
}
|
||||
SerialMon.println(" success");
|
||||
|
||||
if (modem->isNetworkConnected())
|
||||
{
|
||||
SerialMon.println("Network connected");
|
||||
}
|
||||
SerialMon.print(F("Connecting to "));
|
||||
SerialMon.print(apn);
|
||||
if (!modem->gprsConnect(apn, gprsUser, gprsPass))
|
||||
{
|
||||
SerialMon.println(" fail");
|
||||
delay(10000);
|
||||
return;
|
||||
}
|
||||
SerialMon.println(" success");
|
||||
|
||||
if (modem->isGprsConnected())
|
||||
{
|
||||
SerialMon.println("GPRS connected");
|
||||
}
|
||||
modem->NTPServerSync();
|
||||
}
|
||||
String GSMMannger::I2toS(int n)
|
||||
{
|
||||
if (n>=10)
|
||||
{
|
||||
return String(n);
|
||||
} else{
|
||||
return "0"+ String(n);
|
||||
}
|
||||
}
|
||||
String GSMMannger::GetDataAndTime() {
|
||||
//String str=modem->getGSMDateTime(DATE_FULL);
|
||||
if(modem->getNetworkTime(&year,&month,&day,&hour,&minute, &second,&timezone))
|
||||
{
|
||||
String date=String(year)+"-"+I2toS(month)+"-"+I2toS(day)+" "+I2toS(hour)+":"+I2toS(minute)+":"+I2toS(second);
|
||||
return date;}
|
||||
return "2000-01-01 00:00:00";
|
||||
}
|
||||
|
||||
void GSMMannger::loop()
|
||||
{
|
||||
|
||||
if (!modem->isNetworkConnected())
|
||||
{
|
||||
|
||||
SerialMon.println("Network disconnected");
|
||||
if (!modem->waitForNetwork(20000L, true))
|
||||
{
|
||||
SerialMon.println(" re wait For Network fail");
|
||||
esp_restart();
|
||||
delay(10000);
|
||||
return;
|
||||
}
|
||||
if (modem->isNetworkConnected())
|
||||
{
|
||||
SerialMon.println("Network re-connected");
|
||||
}
|
||||
|
||||
// and make sure GPRS/EPS is still connected
|
||||
if (!modem->isGprsConnected())
|
||||
{
|
||||
SerialMon.println("GPRS disconnected!");
|
||||
SerialMon.print(F("Connecting to "));
|
||||
SerialMon.print(apn);
|
||||
if (!modem->gprsConnect(apn, gprsUser, gprsPass))
|
||||
{
|
||||
SerialMon.println(" set apn gprsuser gprspass fail");
|
||||
esp_restart();
|
||||
delay(10000);
|
||||
return;
|
||||
}
|
||||
if (modem->isGprsConnected())
|
||||
{
|
||||
SerialMon.println("GPRS reconnected");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
33
src/GSMMannager.h
Normal file
33
src/GSMMannager.h
Normal file
@ -0,0 +1,33 @@
|
||||
#define TINY_GSM_MODEM_SIM800
|
||||
#define SerialMon Serial
|
||||
#include <TinyGsmClient.h>
|
||||
#include <PubSubClient.h>
|
||||
|
||||
|
||||
//#define TINY_GSM_DEBUG SerialMon
|
||||
#define GSM_AUTOBAUD_MIN 9600
|
||||
#define GSM_AUTOBAUD_MAX 115200
|
||||
#define TINY_GSM_USE_GPRS true
|
||||
#define TINY_GSM_USE_WIFI false
|
||||
|
||||
#define GSM_PIN ""
|
||||
|
||||
const char apn[] = "CMNET";
|
||||
const char gprsUser[] = "";
|
||||
const char gprsPass[] = "";
|
||||
|
||||
class GSMMannger
|
||||
{
|
||||
public:
|
||||
GSMMannger(int serialnumber,int rx,int tx); // <20><><EFBFBD>ǹ<EFBFBD><C7B9>캯<EFBFBD><ECBAAF>
|
||||
TinyGsm *modem;
|
||||
TinyGsmClient *client;
|
||||
String GetDataAndTime();
|
||||
void loop();
|
||||
String I2toS(int n);
|
||||
int year,month, day, hour,minute, second;
|
||||
float timezone;
|
||||
|
||||
};
|
||||
|
||||
|
5
src/MyEsp8266.cpp
Normal file
5
src/MyEsp8266.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
//
|
||||
// Created by xin on 2022/4/28.
|
||||
//
|
||||
|
||||
#include "MyEsp8266.h"
|
14
src/MyEsp8266.h
Normal file
14
src/MyEsp8266.h
Normal file
@ -0,0 +1,14 @@
|
||||
//
|
||||
// Created by xin on 2022/4/28.
|
||||
//
|
||||
|
||||
#ifndef ESP32MAINBOARD_MYESP8266_H
|
||||
#define ESP32MAINBOARD_MYESP8266_H
|
||||
|
||||
|
||||
class MyEsp8266 {
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //ESP32MAINBOARD_MYESP8266_H
|
138
src/MyWebServer.cpp
Normal file
138
src/MyWebServer.cpp
Normal file
@ -0,0 +1,138 @@
|
||||
#include "MyWebServer.h"
|
||||
|
||||
ESPWebServer *ESPStaticServer;
|
||||
void webserver::printn(String str)
|
||||
{
|
||||
if (serialmy != nullptr)
|
||||
{
|
||||
serialmy->print(str);
|
||||
}
|
||||
}
|
||||
void webserver::initme()
|
||||
{
|
||||
|
||||
printn("webserver begain\n");
|
||||
|
||||
// wifiMulti.addAP("IRIS", "irishk*******"); // 将需要连接的一系列WiFi ID和密码输入这里
|
||||
// wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
|
||||
// wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
|
||||
// printn("Connecting ..."); // 则尝试使用此处存储的密码进行连接。
|
||||
|
||||
// int i = 0;
|
||||
// while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
|
||||
// delay(1000);
|
||||
// printn("retry to connect wifi");
|
||||
// }
|
||||
|
||||
// WiFi连接成功后将通过串口监视器输出连接成功信息
|
||||
|
||||
printn("Connected to \n");
|
||||
printn(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
|
||||
printn("IP address:\t");
|
||||
printn(WiFi.localIP().toString()); // 通过串口监视器输出ESP8266-NodeMCU的IP
|
||||
printn("\n");
|
||||
if (SPIFFS.begin())
|
||||
{ // 启动闪存文件系统
|
||||
printn("SPIFFS Started.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printn("SPIFFS Failed to Start.\n");
|
||||
}
|
||||
|
||||
server->onNotFound(handleUserRequet); // 告知系统如何处理用户请求
|
||||
|
||||
server->begin(); // 启动网站服务
|
||||
printn("HTTP server started\n");
|
||||
}
|
||||
webserver::webserver(HardwareSerial *serial)
|
||||
{
|
||||
serialmy = serial;
|
||||
server=new ESPWebServer(80);
|
||||
ESPStaticServer=server;
|
||||
initme();
|
||||
}
|
||||
webserver::webserver()
|
||||
{
|
||||
serialmy = nullptr;
|
||||
server=new ESPWebServer(80);
|
||||
ESPStaticServer=server;
|
||||
initme();
|
||||
}
|
||||
|
||||
webserver::~webserver()
|
||||
{
|
||||
}
|
||||
|
||||
void webserver::handleUserRequet()
|
||||
{
|
||||
Serial.println("some one come\n");
|
||||
|
||||
// 获取用户请求网址信息
|
||||
String webAddress = ESPStaticServer->uri();
|
||||
|
||||
// 通过handleFileRead函数处处理用户访问
|
||||
bool fileReadOK = handleFileRead(webAddress);
|
||||
|
||||
// 如果在SPIFFS无法找到用户访问的资源,则回复404 (Not Found)
|
||||
if (!fileReadOK)
|
||||
{
|
||||
ESPStaticServer->send(404, "text/plain", "404 Not Found");
|
||||
}
|
||||
}
|
||||
|
||||
bool webserver::handleFileRead(String path)
|
||||
{ //处理浏览器HTTP访问
|
||||
|
||||
if (path.endsWith("/"))
|
||||
{ // 如果访问地址以"/"为结尾
|
||||
path = "/index.html"; // 则将访问地址修改为/index.html便于SPIFFS访问
|
||||
}
|
||||
|
||||
String contentType = getContentType(path); // 获取文件类型
|
||||
|
||||
if (SPIFFS.exists(path))
|
||||
{ // 如果访问的文件可以在SPIFFS中找到
|
||||
File file = SPIFFS.open(path, "r"); // 则尝试打开该文件
|
||||
ESPStaticServer->streamFile(file, contentType); // 并且将该文件返回给浏览器
|
||||
file.close(); // 并且关闭文件
|
||||
return true; // 返回true
|
||||
}
|
||||
return false; // 如果文件未找到,则返回false
|
||||
}
|
||||
|
||||
// 获取文件类型
|
||||
String webserver::getContentType(String filename)
|
||||
{
|
||||
if (filename.endsWith(".htm"))
|
||||
return "text/html";
|
||||
else if (filename.endsWith(".html"))
|
||||
return "text/html";
|
||||
else if (filename.endsWith(".css"))
|
||||
return "text/css";
|
||||
else if (filename.endsWith(".js"))
|
||||
return "application/javascript";
|
||||
else if (filename.endsWith(".png"))
|
||||
return "image/png";
|
||||
else if (filename.endsWith(".gif"))
|
||||
return "image/gif";
|
||||
else if (filename.endsWith(".jpg"))
|
||||
return "image/jpeg";
|
||||
else if (filename.endsWith(".ico"))
|
||||
return "image/x-icon";
|
||||
else if (filename.endsWith(".xml"))
|
||||
return "text/xml";
|
||||
else if (filename.endsWith(".pdf"))
|
||||
return "application/x-pdf";
|
||||
else if (filename.endsWith(".zip"))
|
||||
return "application/x-zip";
|
||||
else if (filename.endsWith(".gz"))
|
||||
return "application/x-gzip";
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
void webserver::loop()
|
||||
{
|
||||
ESPStaticServer->handleClient();
|
||||
// printn("...");
|
||||
}
|
38
src/MyWebServer.h
Normal file
38
src/MyWebServer.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef wenserver_H
|
||||
#define wenserver_H
|
||||
#define ESP32
|
||||
#ifdef ESP32
|
||||
|
||||
#include "WebServer.h"
|
||||
#include "WiFi.h"
|
||||
#include "Arduino.h"
|
||||
#include "SPIFFS.h"
|
||||
#define ESPWebServer WebServer
|
||||
#elif
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#define ESPWebServer ESP8266WebServer
|
||||
#endif
|
||||
#include <FS.h>
|
||||
|
||||
class webserver
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
webserver(HardwareSerial *serial);
|
||||
webserver();
|
||||
void initme();
|
||||
HardwareSerial *serialmy;
|
||||
~webserver();
|
||||
static void handleUserRequet();
|
||||
static bool handleFileRead(String path);
|
||||
static String getContentType(String filename);
|
||||
void loop();
|
||||
void printn(String str);
|
||||
ESPWebServer *server;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
287
src/SDmanger.cpp
Normal file
287
src/SDmanger.cpp
Normal file
@ -0,0 +1,287 @@
|
||||
#include"SDmanger.h"
|
||||
File Comenfile;
|
||||
|
||||
int sdcard::init_sdcard()
|
||||
{
|
||||
SD_MMC.setPins(9,10,11,12,13,14);
|
||||
int succ = SD_MMC.begin("/sdcard", true,true,150);
|
||||
if (succ) {
|
||||
Serial.printf("SD_MMC Begin: %d\n", succ);
|
||||
uint8_t cardType = SD_MMC.cardType();
|
||||
Serial.print("SD_MMC Card Type: ");
|
||||
if (cardType == CARD_MMC) {
|
||||
Serial.println("MMC");
|
||||
} else if (cardType == CARD_SD) {
|
||||
Serial.println("SDSC");
|
||||
} else if (cardType == CARD_SDHC) {
|
||||
Serial.println("SDHC");
|
||||
} else {
|
||||
Serial.println("UNKNOWN");
|
||||
}
|
||||
|
||||
uint64_t cardSize = SD_MMC.cardSize() / (1024 * 1024);
|
||||
Serial.printf("SD_MMC Card Size: %lluMB\n", cardSize);
|
||||
|
||||
} else {
|
||||
Serial.printf("Failed to mount SD card VFAT filesystem. \n");
|
||||
Serial.println("Do you have an SD Card installed?");
|
||||
Serial.println("Check pin 12 and 13, not grounded, or grounded with 10k resistors!\n\n");
|
||||
// major_fail();
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void sdcard::mylistDir( const char * dirname, uint8_t levels) {
|
||||
|
||||
Serial.printf("Listing directory: %s\n", "/");
|
||||
String dir(dirname);
|
||||
File root = SD_MMC.open(dirname);
|
||||
if (!root) {
|
||||
Serial.println("Failed to open directory");
|
||||
return;
|
||||
}
|
||||
if (!root.isDirectory()) {
|
||||
Serial.println("Not a directory");
|
||||
return;
|
||||
}
|
||||
|
||||
File filex = root.openNextFile();
|
||||
while (filex) {
|
||||
if (filex.isDirectory())
|
||||
{
|
||||
Serial.print(" DIR : ");
|
||||
Serial.println(filex.name());
|
||||
if (levels) {
|
||||
String filename=dir+"/"+String(filex.name());
|
||||
mylistDir( filename.c_str(), levels - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(" FILE: ");
|
||||
Serial.print(filex.name());
|
||||
Serial.print(" SIZE: ");
|
||||
Serial.println(filex.size());
|
||||
}
|
||||
filex = root.openNextFile();
|
||||
}
|
||||
}
|
||||
bool sdcard::ListDir(const char * dirname,Vector <String> &stringlist)
|
||||
{
|
||||
stringlist.clear();
|
||||
Serial.printf("Listing directory: %s\n", dirname);
|
||||
String dir(dirname);
|
||||
File root = SD_MMC.open(dirname);
|
||||
if (!root) {
|
||||
Serial.println("Failed to open directory");
|
||||
return true;
|
||||
}
|
||||
if (!root.isDirectory()) {
|
||||
Serial.println("Not a directory");
|
||||
return true;
|
||||
}
|
||||
|
||||
File filex = root.openNextFile();
|
||||
while (filex)
|
||||
{
|
||||
if (filex.isDirectory()) {
|
||||
|
||||
} else {
|
||||
String filename=dir+"/"+String(filex.name());
|
||||
stringlist.push_back(filename);
|
||||
|
||||
if (stringlist.size()==stringlist.max_size())
|
||||
{
|
||||
return false;
|
||||
/* code */
|
||||
}
|
||||
|
||||
}
|
||||
filex = root.openNextFile();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void sdcard::delete_old_stuff() {
|
||||
|
||||
Serial.printf("Total space: %lluMB\n", SD_MMC.totalBytes() / (1024 * 1024));
|
||||
Serial.printf("Used space: %lluMB\n", SD_MMC.usedBytes() / (1024 * 1024));
|
||||
|
||||
//listDir( "/", 0);
|
||||
|
||||
float full = 1.0 * SD_MMC.usedBytes() / SD_MMC.totalBytes();;
|
||||
if (full < 0.8) {
|
||||
Serial.printf("Nothing deleted, %.1f%% disk full\n", 100.0 * full);
|
||||
} else {
|
||||
Serial.printf("Disk is %.1f%% full ... deleting oldest file\n", 100.0 * full);
|
||||
while (full > 0.8) {
|
||||
|
||||
double del_number = 999999999;
|
||||
char del_numbername[50];
|
||||
|
||||
File f = SD_MMC.open("/");
|
||||
|
||||
File file = f.openNextFile();
|
||||
|
||||
while (file) {
|
||||
//Serial.println(file.name());
|
||||
if (!file.isDirectory()) {
|
||||
|
||||
char foldname[50];
|
||||
strcpy(foldname, file.name());
|
||||
for ( int x = 0; x < 50; x++) {
|
||||
if ( (foldname[x] >= 0x30 && foldname[x] <= 0x39) || foldname[x] == 0x2E) {
|
||||
} else {
|
||||
if (foldname[x] != 0) foldname[x] = 0x20;
|
||||
}
|
||||
}
|
||||
|
||||
double i = atof(foldname);
|
||||
if ( i > 0 && i < del_number) {
|
||||
strcpy (del_numbername, file.name());
|
||||
del_number = i;
|
||||
}
|
||||
//Serial.printf("Name is %s, number is %f\n", foldname, i);
|
||||
}
|
||||
file = f.openNextFile();
|
||||
|
||||
}
|
||||
Serial.printf("lowest is Name is %s, number is %f\n", del_numbername, del_number);
|
||||
if (del_number < 999999999) {
|
||||
deleteFolderOrFile(del_numbername);
|
||||
}
|
||||
full = 1.0 * SD_MMC.usedBytes() / SD_MMC.totalBytes();
|
||||
Serial.printf("Disk is %.1f%% full ... \n", 100.0 * full);
|
||||
f.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sdcard::deleteFolderOrFile(const char * val) {
|
||||
// Function provided by user @gemi254
|
||||
Serial.printf("Deleting : %s\n", val);
|
||||
File f = SD_MMC.open(val);
|
||||
if (!f) {
|
||||
Serial.printf("Failed to open %s\n", val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (f.isDirectory()) {
|
||||
File file = f.openNextFile();
|
||||
while (file) {
|
||||
if (file.isDirectory()) {
|
||||
Serial.print(" DIR : ");
|
||||
Serial.println(file.name());
|
||||
} else {
|
||||
Serial.print(" FILE: ");
|
||||
Serial.print(file.name());
|
||||
Serial.print(" SIZE: ");
|
||||
Serial.print(file.size());
|
||||
if (SD_MMC.remove(file.name())) {
|
||||
Serial.println(" deleted.");
|
||||
} else {
|
||||
Serial.println(" FAILED.");
|
||||
}
|
||||
}
|
||||
file = f.openNextFile();
|
||||
}
|
||||
f.close();
|
||||
//Remove the dir
|
||||
if (SD_MMC.rmdir(val)) {
|
||||
Serial.printf("Dir %s removed\n", val);
|
||||
} else {
|
||||
Serial.println("Remove dir failed");
|
||||
}
|
||||
|
||||
} else {
|
||||
//Remove the file
|
||||
if (SD_MMC.remove(val)) {
|
||||
Serial.printf("File %s deleted\n", val);
|
||||
} else {
|
||||
Serial.println("Delete failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sdcard:: testwriet()
|
||||
{
|
||||
File file;
|
||||
file = SD_MMC.open("/gps/try.txt", "wb");
|
||||
file.println("hello world");
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sdcard::WriteStringToFile(String name,String Str)
|
||||
{
|
||||
File file;
|
||||
|
||||
file = SD_MMC.open(name, "w+");
|
||||
file.println(Str);
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
void sdcard::WriteStringToFile(String name,char *data,size_t lenth)
|
||||
{
|
||||
File file;
|
||||
|
||||
file = SD_MMC.open(name, "wb");
|
||||
file.write((const byte *)data,lenth);
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
bool sdcard::Mkdir(String path)
|
||||
{
|
||||
return SD_MMC.mkdir(path);
|
||||
}
|
||||
|
||||
namespace sdcard
|
||||
{
|
||||
void openFileformWirte(String Path)
|
||||
{
|
||||
if (Comenfile.available())
|
||||
{
|
||||
Comenfile.close();
|
||||
/* code */
|
||||
}
|
||||
Comenfile = SD_MMC.open(Path, "w+");
|
||||
|
||||
}
|
||||
|
||||
void WritetoFileCommen(String Str)
|
||||
{
|
||||
if (Comenfile.available())
|
||||
{
|
||||
Comenfile.print(Str);
|
||||
Comenfile.flush();
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
|
||||
void WritetoFileCommen(char *data,size_t lenth)
|
||||
{
|
||||
if (Comenfile.available())
|
||||
{
|
||||
Comenfile.write((const byte *)data,lenth);
|
||||
Comenfile.flush();
|
||||
/* code */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void closeCommenFile()
|
||||
{
|
||||
if (Comenfile.available())
|
||||
{
|
||||
Comenfile.close();
|
||||
/* code */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
28
src/SDmanger.h
Normal file
28
src/SDmanger.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef SDMANGER_H
|
||||
#define SDMANGER_H
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "driver/sdmmc_defs.h"
|
||||
#include "sdmmc_cmd.h"
|
||||
#include "esp_vfs_fat.h"
|
||||
#include "FS.h"
|
||||
#include <SD_MMC.h>
|
||||
#include "Vector.h"
|
||||
namespace sdcard{
|
||||
int init_sdcard();
|
||||
|
||||
void mylistDir( const char * dirname, uint8_t levels);
|
||||
bool ListDir(const char * dirname,Vector <String> &stringlist);
|
||||
void delete_old_stuff();
|
||||
void deleteFolderOrFile(const char * val) ;
|
||||
void testwriet();
|
||||
void WriteStringToFile(String name,String Str);
|
||||
void WriteStringToFile(String name,char *data,size_t lenth);
|
||||
bool Mkdir(String path);
|
||||
void openFileformWirte(String Path);
|
||||
void WritetoFileCommen(String Str);
|
||||
void WritetoFileCommen(char *data,size_t lenth);
|
||||
void closeCommenFile();
|
||||
|
||||
}
|
||||
#endif
|
||||
|
281
src/SensorOptoSky.cpp
Normal file
281
src/SensorOptoSky.cpp
Normal file
@ -0,0 +1,281 @@
|
||||
//
|
||||
// Created by xin on 2022/4/24.
|
||||
//
|
||||
|
||||
#include "wifidebug.h"
|
||||
|
||||
|
||||
#include "SensorOptoSky.h"
|
||||
bool SensorOptoSky::initSensor(int id )
|
||||
{
|
||||
IS1Sensor.SetPortName(id);
|
||||
SensorInfo=GetSensorInfo();
|
||||
pinMode(5,OUTPUT);
|
||||
pinMode(6,OUTPUT);
|
||||
// Serial.println("i am here12312312312312312");
|
||||
return true;
|
||||
}
|
||||
|
||||
STRSensorInfo SensorOptoSky::GetSensorInfo() {
|
||||
STRSensorInfo setem;
|
||||
|
||||
if (!IS1Sensor.isSensorInit())
|
||||
{
|
||||
Serial.println("sensor is 123123");
|
||||
return setem;
|
||||
}
|
||||
int lenthretrunl;
|
||||
char *result;
|
||||
|
||||
IS1Sensor.SendComment(GET_PN_NUMBER);
|
||||
IS1Sensor.GetReturn(GET_PN_NUMBER, lenthretrunl,1000);
|
||||
result=new char[lenthretrunl+1]();
|
||||
memcpy(result,IS1Sensor.result,lenthretrunl);
|
||||
result[lenthretrunl]='\0';
|
||||
|
||||
String str(result);
|
||||
Serial.println(str);
|
||||
delete[] result;
|
||||
str.remove(str.indexOf("00")+1,str.length()-(str.indexOf("00")+1));
|
||||
setem.SensorName=str;
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
IS1Sensor.SendComment(GET_SN_NUMBER);
|
||||
IS1Sensor.GetReturn(GET_SN_NUMBER, lenthretrunl,1000);
|
||||
result=new char[lenthretrunl+1]();
|
||||
memcpy(result,IS1Sensor.result,lenthretrunl);
|
||||
result[lenthretrunl]='\0';
|
||||
String SNNUMBER(result);
|
||||
Serial.println(SNNUMBER);
|
||||
delete[] result;//
|
||||
SNNUMBER.remove(SNNUMBER.indexOf('X'),SNNUMBER.length()-SNNUMBER.indexOf('X'));
|
||||
setem.serialnumber=SNNUMBER;
|
||||
/*
|
||||
Serial.write("IS1Sensor.result+10,lenthretrunl");
|
||||
Serial.write(IS1Sensor.result+3,lenthretrunl-3);
|
||||
Serial.println("SNNUMBER");
|
||||
Serial.println(SNNUMBER);
|
||||
|
||||
*/
|
||||
////////////////////////
|
||||
|
||||
|
||||
u_char *shutter=new u_char[2]();
|
||||
int msc=10;
|
||||
shutter[0] = (int)msc / 256;
|
||||
shutter[1] = (int)msc % 256;
|
||||
IS1Sensor.SendComment(SYNCHRONIZATION_GET_DATA,shutter,2);
|
||||
IS1Sensor.GetReturn(SYNCHRONIZATION_GET_DATA, lenthretrunl,10);
|
||||
setem.BandNum = (lenthretrunl-1)/2;
|
||||
Serial.println("band lenth:" );
|
||||
Serial.println( setem.BandNum );
|
||||
DATABUFF=new unsigned short[setem.BandNum] ;
|
||||
DownData=new unsigned short[setem.BandNum] ;
|
||||
UpData=new unsigned short[setem.BandNum] ;
|
||||
////////////////////////////////////////////////////////
|
||||
shutter[0] = 0x00;
|
||||
shutter[1] = 0x01;
|
||||
IS1Sensor.SendComment(GET_WAVELENGTH_CALIBRATION_COFF,shutter,2);
|
||||
IS1Sensor.GetReturn(GET_WAVELENGTH_CALIBRATION_COFF, lenthretrunl);
|
||||
float a[4];
|
||||
memcpy(a, IS1Sensor.result + 16, 4 * 4);
|
||||
|
||||
int bandsss= setem.BandNum;
|
||||
setem.wavelenthlist=new float[setem.BandNum]();
|
||||
Serial.print("a0:");
|
||||
Serial.print(a[0]);
|
||||
Serial.print(" a1:");
|
||||
Serial.print(a[1]);
|
||||
Serial.print(" a2:");
|
||||
Serial.print(a[2]);
|
||||
Serial.print(" a3:");
|
||||
Serial.println(a[3]);
|
||||
setem.a1=a[0];
|
||||
setem.a2=a[1];
|
||||
setem.a3=a[2];
|
||||
setem.a4=a[3];
|
||||
for ( int i = 1; i <=bandsss ; i++)
|
||||
{
|
||||
setem.wavelenthlist[i-1] = a[0] * i*i*i + a[1] * i*i + a[2] * i + a[3];
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////
|
||||
shutter[0] = 0x00;
|
||||
shutter[1] = 0x01;
|
||||
|
||||
IS1Sensor.SendComment(SET_AVERAGE_NUMBER, shutter,2);
|
||||
IS1Sensor.GetReturn(SET_AVERAGE_NUMBER, lenthretrunl);
|
||||
setem.maxValue=65535;
|
||||
delete[] shutter;
|
||||
|
||||
return setem;
|
||||
/* 非线性校正
|
||||
IS1Sensor.SendComment(0x53, shutter,2);
|
||||
IS1Sensor. GetReturn(0x53, lenthretrunl);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
void SensorOptoSky::SetShutter(int id) {
|
||||
switch (id) {
|
||||
case 0:
|
||||
{
|
||||
digitalWrite(5,LOW);
|
||||
digitalWrite(6,LOW);
|
||||
delay(200);
|
||||
break;
|
||||
}
|
||||
case 1:{
|
||||
digitalWrite(6,HIGH);
|
||||
digitalWrite(5,LOW);
|
||||
delay(200);
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
digitalWrite(5,HIGH);
|
||||
digitalWrite(6,LOW);
|
||||
delay(200);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SensorOptoSky::GetOneDate(int msc) {
|
||||
u_char *shutter=new u_char[2]();
|
||||
shutter[0] = (int)msc / 256;
|
||||
shutter[1] = (int)msc % 256;
|
||||
int lenthretrunl;
|
||||
IS1Sensor.SendComment(SYNCHRONIZATION_GET_DATA,shutter,2);
|
||||
IS1Sensor.GetReturn(SYNCHRONIZATION_GET_DATA, lenthretrunl,msc);
|
||||
memcpy(DATABUFF, IS1Sensor.result + 1, SensorInfo.BandNum * 2);
|
||||
shortLittletoBiG(DATABUFF, SensorInfo.BandNum);
|
||||
}
|
||||
|
||||
void SensorOptoSky::shortLittletoBiG(unsigned short *data, int lenth) {
|
||||
char *chardata=(char *)data;
|
||||
char temp;
|
||||
for (int i = 0; i <lenth ; ++i) {
|
||||
temp=chardata[2*i+1];
|
||||
chardata[2*i+1]=chardata[2*i];
|
||||
chardata[2*i]=temp;
|
||||
}
|
||||
}
|
||||
|
||||
int SensorOptoSky::OptSnenser(int persent) {
|
||||
long maxtime = 20000;
|
||||
int maxvalue=SensorInfo.maxValue*1.0*persent / 100;
|
||||
int maxvaluenow = 0;
|
||||
float shutternow = 10;
|
||||
GetOneDate(shutternow);
|
||||
maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
|
||||
Serial.print("now Shutter is :");
|
||||
Serial.print(shutternow);
|
||||
Serial.print(" maxvalue is :");
|
||||
Serial.println(maxvaluenow);
|
||||
int numberoftry = 0;
|
||||
while (maxvaluenow<maxvalue*0.95 || maxvaluenow>maxvalue) {
|
||||
if (maxvaluenow > maxvalue)
|
||||
{
|
||||
shutternow = shutternow *0.7;
|
||||
}
|
||||
else
|
||||
{
|
||||
shutternow = maxvalue * 0.98 / (maxvaluenow * 1.0)*shutternow + 1;
|
||||
}
|
||||
if (shutternow > maxtime)
|
||||
{
|
||||
shutternow = maxtime;
|
||||
break;
|
||||
}
|
||||
GetOneDate(shutternow);
|
||||
maxvaluenow= Getmaxvalue(DATABUFF, SensorInfo.BandNum);
|
||||
Serial.print("now Shutter is :");
|
||||
Serial.print(shutternow);
|
||||
Serial.print(" maxvalue is :");
|
||||
Serial.println(maxvaluenow);
|
||||
numberoftry++;
|
||||
if (numberoftry > 200)
|
||||
{
|
||||
|
||||
return maxtime;
|
||||
|
||||
}
|
||||
if (shutternow == maxtime)
|
||||
{
|
||||
|
||||
return maxtime;
|
||||
}
|
||||
}
|
||||
Serial.print("zi dong value:");
|
||||
Serial.println(shutternow);
|
||||
if (shutternow<0)
|
||||
{
|
||||
shutternow=maxtime;
|
||||
/* code */
|
||||
}
|
||||
|
||||
return shutternow;
|
||||
}
|
||||
|
||||
int SensorOptoSky::Getmaxvalue(unsigned short *data, int lenth) {
|
||||
int ret=-1;
|
||||
for (int i = 0; i < lenth; ++i) {
|
||||
if (data[i]>ret){
|
||||
ret=data[i];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SensorOptoSky::TakeOneJob() {
|
||||
SetShutter(1);
|
||||
int shutter=OptSnenser(90);
|
||||
shutterup=shutter;
|
||||
GetOneDate(shutter);
|
||||
memcpy(UpData,DATABUFF,SensorInfo.BandNum*2);
|
||||
SetShutter(0);
|
||||
GetOneDate(shutter);
|
||||
for (int i = 0; i < SensorInfo.BandNum; ++i) {
|
||||
UpData[i]=UpData[i]-DATABUFF[i];
|
||||
}
|
||||
shutterup=shutter;
|
||||
Serial.println("Finish Up ------Green");
|
||||
bool dingbing=false;
|
||||
#ifdef DINBIAO
|
||||
|
||||
String strout="1 shutteruo is "+String(shutterup)+" Finish Up ------Green ";
|
||||
printbytcpserver(strout);
|
||||
PrintFunc(strout );
|
||||
digitalWrite(21, LOW);
|
||||
printbytcpserver("please change the fiber in 1 min");
|
||||
delay(90000);
|
||||
SensorInfo.SensorName=SensorInfo.SensorName+"cali";
|
||||
Serial.println("begindown");
|
||||
digitalWrite(21, HIGH);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
SetShutter(2);
|
||||
shutter=OptSnenser(90);
|
||||
shutterdown=shutter;
|
||||
GetOneDate(shutter);
|
||||
memcpy(DownData,DATABUFF,SensorInfo.BandNum*2);
|
||||
SetShutter(0);
|
||||
GetOneDate(shutter);
|
||||
for (int i = 0; i < SensorInfo.BandNum; ++i) {
|
||||
DownData[i]=DownData[i]-DATABUFF[i];
|
||||
}
|
||||
shutterdown=shutter;
|
||||
Serial.println("Down Finish ------Blue");
|
||||
#ifdef DINBIAO
|
||||
String strout1="2 shutterdown is "+String(shutterdown)+" Down Finish ------Blue";
|
||||
PrintFunc(strout1 );
|
||||
printbytcpserver(strout1);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
32
src/SensorOptoSky.h
Normal file
32
src/SensorOptoSky.h
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by xin on 2022/4/24.
|
||||
//
|
||||
|
||||
#ifndef ESP32MAINBOARD_SENSOROPTOSKY_H
|
||||
#define ESP32MAINBOARD_SENSOROPTOSKY_H
|
||||
;
|
||||
#include "optoskybase.h"
|
||||
typedef void (*PRINTFUNC)(String );
|
||||
class SensorOptoSky {
|
||||
public:
|
||||
STRSensorInfo SensorInfo;
|
||||
OptoSky IS1Sensor;
|
||||
bool initSensor(int id = 2);
|
||||
STRSensorInfo GetSensorInfo();
|
||||
void SetShutter(int id);// 0 dark 1 green 2 blue
|
||||
void GetOneDate(int msc);
|
||||
unsigned short *DATABUFF;
|
||||
int shutterup,shutterdown;
|
||||
unsigned short *DownData;
|
||||
unsigned short *UpData;
|
||||
void shortLittletoBiG( unsigned short *data,int lenth);
|
||||
int OptSnenser(int percent);
|
||||
int Getmaxvalue(unsigned short *data,int lenth);
|
||||
void TakeOneJob();
|
||||
PRINTFUNC PrintFunc;
|
||||
//int shutterup,shutterdown;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //ESP32MAINBOARD_SENSOROPTOSKY_H
|
206
src/TCPserver.cpp
Normal file
206
src/TCPserver.cpp
Normal file
@ -0,0 +1,206 @@
|
||||
#include "TCPserver.h"
|
||||
bool fenge(String &zifuchuan, String &outstring, String fengefu)
|
||||
{
|
||||
int weizhi = 0; //找查的位置
|
||||
|
||||
if (zifuchuan == "")
|
||||
{
|
||||
// Serial.print("commanesdafasdf");
|
||||
return false;
|
||||
|
||||
/* code */
|
||||
}
|
||||
|
||||
weizhi = zifuchuan.indexOf(fengefu); //找到位置
|
||||
if (weizhi != -1) //如果位置不为空
|
||||
{
|
||||
// Serial.println(zifuchuan);
|
||||
outstring = zifuchuan.substring(0, weizhi); //打印取第一个字符
|
||||
zifuchuan = zifuchuan.substring(weizhi + fengefu.length(), zifuchuan.length());
|
||||
return true;
|
||||
//分隔后只取后面一段内容 以方便后面找查
|
||||
}
|
||||
else
|
||||
{
|
||||
// Serial.print(zifuchuan);
|
||||
outstring = zifuchuan;
|
||||
zifuchuan = "";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
TCPserver::TCPserver(int port)
|
||||
{
|
||||
server = new WiFiServer(port);
|
||||
myserial = nullptr;
|
||||
isPortOutInit = false;
|
||||
|
||||
}
|
||||
#if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE
|
||||
TCPserver::TCPserver(USBCDC *serial,int port)
|
||||
{
|
||||
server = new WiFiServer(port);
|
||||
myserial = serial;
|
||||
isPortOutInit = true;
|
||||
|
||||
}
|
||||
#elif ARDUINO_USB_CDC_ON_BOOT && ARDUINO_USB_MODE
|
||||
TCPserver::TCPserver(HWCDC *serial,int port)
|
||||
{
|
||||
server = new WiFiServer(port);
|
||||
myserial = serial;
|
||||
isPortOutInit = true;
|
||||
|
||||
}
|
||||
#else
|
||||
TCPserver::TCPserver(HardwareSerial *serial, int port /* args */)
|
||||
{
|
||||
server = new WiFiServer(port);
|
||||
myserial = serial;
|
||||
isPortOutInit = true;
|
||||
|
||||
}
|
||||
#endif
|
||||
void TCPserver::initme()
|
||||
{
|
||||
server->begin();
|
||||
//关闭小包合并包功能,不会延时发送数据
|
||||
server->setNoDelay(true);
|
||||
}
|
||||
void TCPserver::loop()
|
||||
{
|
||||
uint8_t i;
|
||||
//检测是否有新的client请求进来
|
||||
// myserial->print("asdffsd");
|
||||
if (server->hasClient())
|
||||
{
|
||||
for (i = 0; i < MAX_SRV_CLIENTS; i++)
|
||||
{
|
||||
//释放旧无效或者断开的client
|
||||
if (!serverClients[i] || !serverClients[i].connected())
|
||||
{
|
||||
if (serverClients[i])
|
||||
{
|
||||
serverClients[i].stop();
|
||||
}
|
||||
//分配最新的client
|
||||
serverClients[i] = server->available();
|
||||
if (isPortOutInit)
|
||||
{
|
||||
myserial->print("New client: ");
|
||||
myserial->print(i);
|
||||
/* code */
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
//当达到最大连接数 无法释放无效的client,需要拒绝连接
|
||||
if (i == MAX_SRV_CLIENTS)
|
||||
{
|
||||
WiFiClient serverClient = server->available();
|
||||
serverClient.stop();
|
||||
if (isPortOutInit)
|
||||
{
|
||||
myserial->print("Connection rejected ");
|
||||
}
|
||||
}
|
||||
}
|
||||
//检测client发过来的数据
|
||||
for (i = 0; i < MAX_SRV_CLIENTS; i++)
|
||||
{
|
||||
if (serverClients[i] && serverClients[i].connected())
|
||||
{
|
||||
if (serverClients[i].available())
|
||||
{
|
||||
// get data from the telnet client and push it to the UART
|
||||
String str = "";
|
||||
while (serverClients[i].available())
|
||||
{
|
||||
//发送到串口调试器
|
||||
if (isPortOutInit)
|
||||
{
|
||||
str = str + String((char)serverClients[i].read());
|
||||
// myserial->write(serverClients[i].read());
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isPortOutInit)
|
||||
{
|
||||
|
||||
if (myserial->available())
|
||||
{
|
||||
//把串口调试器发过来的数据 发送给client
|
||||
size_t len = myserial->available();
|
||||
uint8_t sbuf[len];
|
||||
myserial->readBytes(sbuf, len);
|
||||
// push UART data to all connected telnet clients
|
||||
for (i = 0; i < MAX_SRV_CLIENTS; i++)
|
||||
{
|
||||
if (serverClients[i] && serverClients[i].connected())
|
||||
{
|
||||
serverClients[i].write(sbuf, len);
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void TCPserver::SendDataToClinet(String str, int clinetid)
|
||||
{
|
||||
|
||||
// myserial->print("Connection rejected ");
|
||||
if (clinetid == -1)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_SRV_CLIENTS; i++)
|
||||
{
|
||||
if (serverClients[i] && serverClients[i].connected())
|
||||
{
|
||||
serverClients[i].println(str);
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
/* code */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (serverClients[clinetid] && serverClients[clinetid].connected())
|
||||
{
|
||||
serverClients[clinetid].println(str);
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
void TCPserver::SendDataToClinet(char *str, int clinetid)
|
||||
{
|
||||
// push UART data to all connected telnet clients
|
||||
myserial->print("Connection rejected ");
|
||||
if (clinetid == -1)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_SRV_CLIENTS; i++)
|
||||
{
|
||||
if (serverClients[i] && serverClients[i].connected())
|
||||
{
|
||||
serverClients[i].write(str);
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
/* code */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (serverClients[clinetid] && serverClients[clinetid].connected())
|
||||
{
|
||||
serverClients[clinetid].write(str);
|
||||
delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
TCPserver::~TCPserver()
|
||||
{
|
||||
delete server;
|
||||
}
|
54
src/TCPserver.h
Normal file
54
src/TCPserver.h
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef TCPSERVER_H
|
||||
#define TCPSERVER_H
|
||||
|
||||
#include<HardwareSerial.h>
|
||||
#ifdef ESP8266
|
||||
#include <ESP8266WiFi.h>
|
||||
#else
|
||||
#include<WiFi.h>
|
||||
#endif
|
||||
|
||||
#define MAX_SRV_CLIENTS 2
|
||||
class TCPserver
|
||||
{
|
||||
private:
|
||||
/* data */
|
||||
//创建server 端口号是23
|
||||
WiFiServer *server;
|
||||
//管理clients
|
||||
WiFiClient serverClients[MAX_SRV_CLIENTS];
|
||||
|
||||
bool isPortOutInit;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
#if ARDUINO_USB_CDC_ON_BOOT && !ARDUINO_USB_MODE //Serial used for USB CDC
|
||||
USBCDC *myserial;
|
||||
TCPserver(USBCDC *serial,int port);
|
||||
#elif ARDUINO_USB_CDC_ON_BOOT && ARDUINO_USB_MODE
|
||||
HWCDC *myserial;
|
||||
TCPserver(HWCDC *serial,int port);
|
||||
#else
|
||||
HardwareSerial *myserial;
|
||||
TCPserver(HardwareSerial *serial,int port);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
TCPserver(int port);
|
||||
void initme();
|
||||
~TCPserver();
|
||||
void SendDataToClinet(String str,int clinetid=-1);
|
||||
void SendDataToClinet(char *str,int clinetid=-1);
|
||||
void loop();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
46
src/log.cpp
Normal file
46
src/log.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "log.h"
|
||||
/*
|
||||
|
||||
w+以纯文本方式读写,而wb+是以二进制方式进行读写。
|
||||
|
||||
mode说明:
|
||||
|
||||
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
|
||||
|
||||
w+ 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
|
||||
|
||||
wb 只写方式打开或新建一个二进制文件,只允许写数据。
|
||||
|
||||
wb+ 读写方式打开或建立一个二进制文件,允许读和写。
|
||||
|
||||
r 打开只读文件,该文件必须存在,否则报错。
|
||||
|
||||
r+ 打开可读写的文件,该文件必须存在,否则报错。
|
||||
|
||||
rb+ 读写方式打开一个二进制文件,只允许读写数据。
|
||||
|
||||
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
|
||||
|
||||
a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
|
||||
|
||||
ab+ 读写打开一个二进制文件,允许读或在文件末追加数据。
|
||||
|
||||
加入b 字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。
|
||||
*/
|
||||
|
||||
void write_log(String path,unsigned char level,String write_data)
|
||||
{
|
||||
#ifdef ceshi
|
||||
Serial.println(write_data);
|
||||
#endif
|
||||
|
||||
if(level > 10) {
|
||||
//保存本地,和同时上传云端,小于10只保存本地
|
||||
}
|
||||
|
||||
File file;
|
||||
file = SD_MMC.open(path,"a+");
|
||||
file.println(write_data);
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
12
src/log.h
Normal file
12
src/log.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _LOG_H_
|
||||
#define _LOG_H_
|
||||
|
||||
|
||||
#define ceshi 1
|
||||
#include "SDmanger.h"
|
||||
void write_log(String path,unsigned char level,String write_data);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
759
src/main.cpp
Normal file
759
src/main.cpp
Normal file
@ -0,0 +1,759 @@
|
||||
#include"Define.h"
|
||||
#include <GSMMannager.h>
|
||||
#include <HTTPClient.h>
|
||||
#include <ArduinoHttpClient.h>
|
||||
#include<driver/periph_ctrl.h>
|
||||
#include "SensorOptoSky.h"
|
||||
#include <SoftwareSerial.h>
|
||||
#include <Ticker.h>
|
||||
#include <updatebyme.h>
|
||||
//#include "MyWebServer.h"
|
||||
#include "SDmanger.h"
|
||||
//#include "HttpsOTAUpdate.h"
|
||||
#include "slave.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <wifidebug.h>
|
||||
|
||||
#define LOGGING
|
||||
//myPort将原来ESP8266对内通讯改为,485对内的通讯
|
||||
// #define MYPORT_TX 45
|
||||
// #define MYPORT_RX 46
|
||||
int hassend = 0;
|
||||
GSMMannger *gsmmanger;
|
||||
UpDateClassByme *ProgrameUper;
|
||||
HttpClient *http;
|
||||
bool ishttpbusy = false;
|
||||
SensorOptoSky IS1Sensor;
|
||||
// SoftwareSerial myPort(MYPORT_RX, MYPORT_TX, false);
|
||||
// HardwareSerial myPort(1);
|
||||
// swSer(14, 12, false, 256);
|
||||
// u_char a[]={0x01,0x04,0x00,0x00,0x00,0x06,0x70,0x08};
|
||||
u_char ret[17];
|
||||
u_char windret[17];
|
||||
Ticker ticker;
|
||||
slave myslave;
|
||||
|
||||
String getnetData()
|
||||
{
|
||||
int err = http->get("/weather/php/Date.php");
|
||||
if (err != 0)
|
||||
{
|
||||
SerialMon.println(F("Date failed to connect"));
|
||||
delay(10000);
|
||||
return "";
|
||||
}
|
||||
int status = http->responseStatusCode();
|
||||
if (!status)
|
||||
{
|
||||
delay(10000);
|
||||
return "";
|
||||
}
|
||||
|
||||
// SerialMon.println(F("Response Headers:"));
|
||||
while (http->headerAvailable())
|
||||
{
|
||||
String headerName = http->readHeaderName();
|
||||
String headerValue = http->readHeaderValue();
|
||||
// SerialMon.println("Date: " + headerName + " : " + headerValue);
|
||||
}
|
||||
if (http->isResponseChunked())
|
||||
{
|
||||
// SerialMon.println(F("Date The response is chunked"));
|
||||
}
|
||||
|
||||
String body = http->responseBody();
|
||||
http->stop();
|
||||
return body;
|
||||
}
|
||||
bool UpdateData(String path, char *str, size_t lenth, String Contenttype = "")
|
||||
{
|
||||
|
||||
http->beginRequest();
|
||||
http->post(path);
|
||||
if (Contenttype != "")
|
||||
{
|
||||
http->sendHeader(HTTP_HEADER_CONTENT_TYPE, Contenttype);
|
||||
|
||||
/* code */
|
||||
}
|
||||
|
||||
http->sendHeader(HTTP_HEADER_CONTENT_LENGTH, lenth);
|
||||
http->endRequest();
|
||||
int err = http->write((const byte *)str, lenth);
|
||||
delay(1000);
|
||||
Serial.print("send date size");
|
||||
Serial.println(err);
|
||||
|
||||
/*
|
||||
for (size_t i = 0; i < lenth; i++)
|
||||
{
|
||||
Serial.print("0x");
|
||||
Serial.print(str[i],HEX);
|
||||
Serial.print(" ");
|
||||
if (i%20==0)
|
||||
{
|
||||
Serial.println(" ");
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
// http->write((const byte*)IS1Sensor.UpData, IS1Sensor.SensorInfo.BandNum*2);
|
||||
// http->stop();
|
||||
Serial.println("hear1");
|
||||
if (err == 0)
|
||||
{
|
||||
|
||||
http->stop();
|
||||
return false;
|
||||
}
|
||||
int status = http->responseStatusCode();
|
||||
Serial.println("hear3");
|
||||
if (!status)
|
||||
{
|
||||
http->stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
int length = http->contentLength();
|
||||
Serial.println("hear4");
|
||||
if (length == 0)
|
||||
{
|
||||
http->stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
String body = http->responseBody();
|
||||
Serial.println("body:"+body);
|
||||
if (body != "ok")
|
||||
{
|
||||
http->stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
http->stop();
|
||||
return true;
|
||||
}
|
||||
void ReuploadData(String path, String webpath, String content = "")
|
||||
{
|
||||
vTaskDelay(1);
|
||||
Vector<String> files;
|
||||
String vec[20]; //每次处理20个
|
||||
files.setStorage(vec);
|
||||
while (!sdcard::ListDir(path.c_str(), files))
|
||||
{
|
||||
if (files.size() != 0)
|
||||
{
|
||||
Serial.println("find " + String(files.size()) + "file");
|
||||
for (size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
File nowfile = SD_MMC.open(files.at(i).c_str(), "rb");
|
||||
size_t size = nowfile.size();
|
||||
char *arr = new char[size];
|
||||
nowfile.readBytes(arr, size);
|
||||
bool flagsucc = UpdateData(webpath, arr, size, content);
|
||||
if (!flagsucc)
|
||||
{
|
||||
return;
|
||||
/* code */
|
||||
}
|
||||
delete[] arr;
|
||||
sdcard::deleteFolderOrFile(files.at(i).c_str());
|
||||
vTaskDelay(1);
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
if (files.size() != 0)
|
||||
{
|
||||
Serial.println("find " + String(files.size()) + "file not enough 20");
|
||||
for (size_t i = 0; i < files.size(); i++)
|
||||
{
|
||||
vTaskDelay(1);
|
||||
File nowfile = SD_MMC.open(files.at(i).c_str(), "rb");
|
||||
size_t size = nowfile.size();
|
||||
char *arr = new char[size];
|
||||
nowfile.readBytes(arr, size);
|
||||
Serial.println("run here now");
|
||||
bool flagsucc = UpdateData(webpath, arr, size, content);
|
||||
if (!flagsucc)
|
||||
{
|
||||
return;
|
||||
/* code */
|
||||
}
|
||||
|
||||
delete[] arr;
|
||||
sdcard::deleteFolderOrFile(files.at(i).c_str());
|
||||
/* code */
|
||||
}
|
||||
}
|
||||
vTaskDelay(1);
|
||||
}
|
||||
String fenge(String str, String fen, int index)
|
||||
{
|
||||
int weizhi;
|
||||
String temps[str.length()];
|
||||
int i = 0;
|
||||
do
|
||||
{
|
||||
weizhi = str.indexOf(fen);
|
||||
if (weizhi != -1)
|
||||
{
|
||||
temps[i] = str.substring(0, weizhi);
|
||||
str = str.substring(weizhi + fen.length(), str.length());
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (str.length() > 0)
|
||||
temps[i] = str;
|
||||
}
|
||||
} while (weizhi >= 0);
|
||||
|
||||
if (index > i)
|
||||
return "-1";
|
||||
return temps[index];
|
||||
}
|
||||
void Reuploaddata(void *) //重新上传数据
|
||||
{
|
||||
ReuploadData("/down", "/weather/php/SpectralDataUp.php");
|
||||
ReuploadData("/up", "/weather/php/SpectralDataUp.php");
|
||||
ReuploadData("/other", "/weather/php/WindsensorUp.php", "application/json");
|
||||
}
|
||||
void Reuploaddata() //重新上传数据
|
||||
{
|
||||
ReuploadData("/down", "/weather/php/SpectralDataUp.php");
|
||||
ReuploadData("/up", "/weather/php/SpectralDataUp.php");
|
||||
ReuploadData("/other", "/weather/php/WindsensorUp.php", "application/json");
|
||||
|
||||
}
|
||||
|
||||
String Datenow="";
|
||||
void printbytcp(String str)
|
||||
{
|
||||
//tcpserver.SendDataToClinet(str);
|
||||
Serial.println(str);
|
||||
str=Datenow+"#######"+str;
|
||||
int lennn=str.length();
|
||||
char *temp = new char[lennn];
|
||||
memcpy(temp, str.c_str(), str.length());
|
||||
bool flagsucc = UpdateData("/weather/php/log.php", temp, lennn);
|
||||
vTaskDelay(3000);
|
||||
delete[] temp;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void esp8266_readmeichaung()
|
||||
{
|
||||
//读取美创模块
|
||||
// while (myPort.read() != -1)
|
||||
// ;
|
||||
// delay(1000); //等待1s 防止下位机反应不过来
|
||||
// myPort.println("MLX#");
|
||||
// delay(10);
|
||||
// for (int j = 0; j < 8; ++j)
|
||||
// {
|
||||
// ret[j] = myPort.read();
|
||||
// }
|
||||
// double temprature;
|
||||
// memcpy(&temprature, ret, 8);
|
||||
// Serial.println("wendu");
|
||||
// Serial.println(temprature);
|
||||
// Serial.println("hello word");
|
||||
|
||||
///////////////now///////////////////////////
|
||||
double temprature = myslave.getMLX();
|
||||
Serial.println("wendu");
|
||||
Serial.println(temprature);
|
||||
Serial.println("hello word");
|
||||
|
||||
|
||||
|
||||
/////////////////////////////初始化windsensor并测评1<E8AF84>71ᅣ1<EFBF84>77/////////////////////////////////////////////////////////////
|
||||
// while (myPort.read() != -1)
|
||||
// ;
|
||||
// sleep(1);
|
||||
// myPort.println("WindSensor#");
|
||||
// delay(210);
|
||||
// for (int j = 0; j < 17; ++j)
|
||||
// {
|
||||
// windret[j] = myPort.read();
|
||||
// }
|
||||
// float VV = (windret[3] * 256 + windret[4]) * 1.0 / 100;
|
||||
// float DD = (windret[5] * 256 + windret[6]) * 1.0 / 10;
|
||||
// float TT = (windret[7] * 256 + windret[8]) * 1.0 / 100;
|
||||
// float HH = (windret[9] * 256 + windret[10]) * 1.0 / 100;
|
||||
// long PP = (windret[13] * 256 + windret[14]) * 256 * 256 + (windret[11] * 256 + windret[12]);
|
||||
// Serial.println("VV:" + String(VV) + "DD:" + String(DD) + "TT:" + String(TT) + "HH:" + String(HH) + "PP:" + String(PP));
|
||||
|
||||
|
||||
////////////////////////////////now////////////////////////////
|
||||
myslave.getWehter();
|
||||
memcpy(windret,myslave.ret,17);
|
||||
float VV = (windret[3] * 256 + windret[4]) * 1.0 / 100;
|
||||
float DD = (windret[5] * 256 + windret[6]) * 1.0 / 10;
|
||||
float TT = (windret[7] * 256 + windret[8]) * 1.0 / 100;
|
||||
float HH = (windret[9] * 256 + windret[10]) * 1.0 / 100;
|
||||
long PP = (windret[13] * 256 + windret[14]) * 256 * 256 + (windret[11] * 256 + windret[12]);
|
||||
Serial.println("VV:" + String(VV) + "DD:" + String(DD) + "TT:" + String(TT) + "HH:" + String(HH) + "PP:" + String(PP));
|
||||
}
|
||||
|
||||
|
||||
String get_GPS(void)
|
||||
{
|
||||
Serial.println("check GPS...");
|
||||
gsmmanger->modem->sendAT(GF("+CGNSPWR?"));
|
||||
gsmmanger->modem->waitResponse("OK");
|
||||
|
||||
Serial.println("Open GPS...");
|
||||
gsmmanger->modem->sendAT(GF("+CGNSPWR=1"));
|
||||
gsmmanger->modem->waitResponse("OK");
|
||||
|
||||
gsmmanger->modem->sendAT(GF("+CGNSAID=31,1,1,1"));
|
||||
gsmmanger->modem->waitResponse("OK");
|
||||
|
||||
Serial.println("get GNSS...");
|
||||
gsmmanger->modem->sendAT(GF("+CGNSINF"));
|
||||
|
||||
String gps;
|
||||
gsmmanger->modem->waitResponse(5000,gps);
|
||||
// Serial.println(gps);
|
||||
|
||||
return gps;
|
||||
}
|
||||
|
||||
|
||||
String log_path;
|
||||
String log_data;
|
||||
void setup()
|
||||
{
|
||||
Serial2.begin(115200);
|
||||
|
||||
Serial.begin(115200);
|
||||
sdcard::init_sdcard();
|
||||
sdcard::testwriet();
|
||||
sdcard::Mkdir("/up");
|
||||
sdcard::Mkdir("/down");
|
||||
sdcard::Mkdir("/other");
|
||||
sdcard::Mkdir("/gps");
|
||||
sdcard::Mkdir("/log");
|
||||
beginWIFI();
|
||||
// sdcard::mylistDir("/",2);
|
||||
{
|
||||
}
|
||||
// pinMode(21, OUTPUT);
|
||||
// digitalWrite(21, HIGH);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// return;
|
||||
//重启esp8266现在不用
|
||||
// pinMode(5, OUTPUT);
|
||||
// digitalWrite(5, LOW);
|
||||
// delay(500);
|
||||
// digitalWrite(5, HIGH);
|
||||
|
||||
|
||||
// pinMode(22,OUTPUT);
|
||||
// digitalWrite(22,HIGH);
|
||||
// pinMode(23,OUTPUT);
|
||||
// digitalWrite(23,HIGH);
|
||||
|
||||
|
||||
//将原来通过esp8266读取美创写成函数esp8266_readmeichaung(),方便调试。
|
||||
|
||||
// myPort.begin(38400, SWSERIAL_8N1, MYPORT_RX, MYPORT_TX, false);
|
||||
myslave.init(46,45);
|
||||
sleep(3);
|
||||
// esp8266_readmeichaung();
|
||||
//原来的SIM800,改为现在的AIR780E4G模块,使用的是串口2。
|
||||
gsmmanger = new GSMMannger(2, 19, 20);
|
||||
|
||||
http = new HttpClient(*gsmmanger->client, "82.156.1.111");
|
||||
|
||||
String Date = getnetData();
|
||||
Serial.println("date is :"+Date);
|
||||
String tem = fenge(Date," ",0);
|
||||
log_path = "/log/"+tem+".txt";
|
||||
log_data = Date+"\r\nSystem starts working.";
|
||||
write_log(log_path,10,"");
|
||||
write_log(log_path,10,log_data);
|
||||
write_log(log_path,10,"AIR780E Init Success.");
|
||||
vTaskDelay(1000);
|
||||
|
||||
|
||||
gsmmanger->modem->sendAT(GF("+CGPIO=1,11,1")); //点灯
|
||||
gsmmanger->modem->waitResponse("OK");
|
||||
String gpsbac = get_GPS();
|
||||
Serial.println(gpsbac);
|
||||
write_log(log_path,10,"GPS Init Success.");
|
||||
vTaskDelay(1000);
|
||||
//////////////////////////////初始化http模块//////////////////////////////////////////////
|
||||
// http = new HttpClient(*gsmmanger->client, "82.156.1.111");
|
||||
ProgrameUper = new UpDateClassByme(http);
|
||||
|
||||
IS1Sensor.initSensor();
|
||||
String StationID = IS1Sensor.SensorInfo.serialnumber;
|
||||
String SensorID = IS1Sensor.SensorInfo.SensorName;
|
||||
|
||||
|
||||
ProgrameUper->initme(Curentvsion);
|
||||
ProgrameUper->StationID=StationID;
|
||||
ProgrameUper->CheckAndUpdate();
|
||||
write_log(log_path,10,"Http Init Success.");
|
||||
// ProgrameUper->DownloadFirmwareForurl("");
|
||||
////////////////////////////上传IS1设备信息//////////////////////////////////////////////
|
||||
|
||||
//////////////////////////////初始化IS1///////////////////////////////////////////////////
|
||||
|
||||
// String Date=getnetData();
|
||||
String Upheader = StationID + "##" + SensorID + "##" + String(IS1Sensor.SensorInfo.BandNum) + "##"
|
||||
+ String(IS1Sensor.SensorInfo.a1,9) + ":" + String(IS1Sensor.SensorInfo.a2,9) + ":" + String(IS1Sensor.SensorInfo.a3,9) + ":" + String(IS1Sensor.SensorInfo.a4,9)+"##"+ProgrameUper->CurrentVersion;
|
||||
http->beginRequest();
|
||||
http->post("/weather/php/SensorInfoUp.php");
|
||||
http->sendHeader(HTTP_HEADER_CONTENT_LENGTH, Upheader.length());
|
||||
http->endRequest();
|
||||
http->write((const byte *)Upheader.c_str(), Upheader.length());
|
||||
http->stop();
|
||||
ticker.attach(60 * 60, Reuploaddata);
|
||||
write_log(log_path,10,"IS1 Init Success.");
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
log_data = "System Init Success";
|
||||
write_log(log_path,10,log_data);
|
||||
// Serial.println(gsmmanger->GetDataAndTime());
|
||||
}
|
||||
String lastdate="";
|
||||
void loop()
|
||||
{
|
||||
String Date = getnetData();
|
||||
String tem = fenge(Date," ",0);
|
||||
log_path = "/log/"+tem+".txt";
|
||||
// //擦除myport缓存
|
||||
// while (myPort.read() != -1)
|
||||
// ;
|
||||
// myPort.println("YULIANG#");
|
||||
// delay(510); //等待500ms
|
||||
// String yuliang=myPort.readStringUntil('#');
|
||||
// delay(1010);
|
||||
// Serial.println("yuliang "+yuliang);
|
||||
|
||||
/////////////////NOW/////////////////////
|
||||
write_log(log_path,10,"");
|
||||
write_log(log_path,10,Date);
|
||||
|
||||
String yuliang = String(myslave.getYuliang());
|
||||
delay(1010);
|
||||
Serial.println("yuliang "+yuliang);
|
||||
write_log(log_path,10,"getYuliang :"+yuliang);
|
||||
|
||||
// //擦除myport缓存
|
||||
// while (myPort.read() != -1)
|
||||
// ;
|
||||
// myPort.println("YLFZ#");
|
||||
// delay(510); //等待500ms
|
||||
// String yuliangfz=myPort.readStringUntil('#');
|
||||
// delay(1010);
|
||||
// Serial.println("fuzhao "+yuliangfz);
|
||||
|
||||
/////////////////NOW/////////////////////
|
||||
String yuliangfz = String(myslave.getYuliang());
|
||||
delay(1010);
|
||||
Serial.println("fuzhao " + yuliangfz);
|
||||
log_data ="fuzhao :"+yuliangfz;
|
||||
write_log(log_path,10,log_data);
|
||||
// while (myPort.read() != -1)
|
||||
// ;
|
||||
// myPort.println("WindSensor#"); //发送指令给无参数
|
||||
// delay(510); //等待500ms
|
||||
// for (int j = 0; j < 17; ++j)
|
||||
// {
|
||||
// windret[j] = myPort.read(); //读取返回倄1<E58084>71ᅣ1<EFBF84>77
|
||||
// // Serial.println(ret[j],HEX);
|
||||
// }
|
||||
// float VV = (windret[3] * 256 + windret[4]) * 1.0 / 100;
|
||||
// float DD = (windret[5] * 256 + windret[6]) * 1.0 / 10;
|
||||
// float TT = (windret[7] * 256 + windret[8]) * 1.0 / 100;
|
||||
// float HH = (windret[9] * 256 + windret[10]) * 1.0 / 100;
|
||||
// long PP = (windret[13] * 256 + windret[14]) * 256 * 256 + (windret[11] * 256 + windret[12]);
|
||||
// Serial.println("VV:" + String(VV) + "DD:" + String(DD) + "TT:" + String(TT) + "HH:" + String(HH) + "PP:" + String(PP));
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////NOW///////////////////////////
|
||||
myslave.getWehter();
|
||||
memcpy(windret,myslave.ret,17);
|
||||
float VV = (windret[3] * 256 + windret[4]) * 1.0 / 100;
|
||||
float DD = (windret[5] * 256 + windret[6]) * 1.0 / 10;
|
||||
float TT = (windret[7] * 256 + windret[8]) * 1.0 / 100;
|
||||
float HH = (windret[9] * 256 + windret[10]) * 1.0 / 100;
|
||||
long PP = (windret[13] * 256 + windret[14]) * 256 * 256 + (windret[11] * 256 + windret[12]);
|
||||
Serial.println("VV:" + String(VV) + "DD:" + String(DD) + "TT:" + String(TT) + "HH:" + String(HH) + "PP:" + String(PP));
|
||||
write_log(log_path,10,"VV:" + String(VV) + "DD:" + String(DD) + "TT:" + String(TT) + "HH:" + String(HH) + "PP:" + String(PP));
|
||||
|
||||
// //读取美创模块
|
||||
// delay(1010);
|
||||
// while (myPort.read() != -1)
|
||||
// ;
|
||||
// delay(1000); //等待1s 防止下位机反应不过来
|
||||
// myPort.println("MLX#");
|
||||
// delay(10);
|
||||
// for (int j = 0; j < 8; ++j)
|
||||
// {
|
||||
// ret[j] = myPort.read();
|
||||
// }
|
||||
// double temprature;
|
||||
// memcpy(&temprature, ret, 8);
|
||||
// Serial.println("wendu");
|
||||
// Serial.println(temprature);
|
||||
// delay(1000);
|
||||
|
||||
////////////////////////////NOW///////////////////////////
|
||||
String temprature =String(myslave.getMLX());
|
||||
Serial.println("wendu");
|
||||
Serial.println(temprature);
|
||||
log_data ="wendu :"+temprature;
|
||||
write_log(log_path,10,log_data);
|
||||
|
||||
////sim 循环
|
||||
|
||||
write_log(log_path,10,"start gsmmanger->loop()");
|
||||
gsmmanger->loop();
|
||||
#ifdef DINBIAO
|
||||
String Datenow1=getnetData();
|
||||
Datenow =fenge(Datenow1, " ", 0) + "_" + fenge(fenge(Datenow1, " ", 1), ":", 0) + "_" + fenge(fenge(Datenow1, " ", 1), ":", 1) + "_" + fenge(fenge(Datenow1, " ", 1), ":", 2);
|
||||
IS1Sensor.PrintFunc=printbytcp;
|
||||
#endif
|
||||
write_log(log_path,10,"start TakeOneJob()");
|
||||
IS1Sensor.TakeOneJob(); ////IS1采集一次
|
||||
String StationID = IS1Sensor.SensorInfo.serialnumber;
|
||||
String SensorID = IS1Sensor.SensorInfo.SensorName;
|
||||
|
||||
///////////////获取时间
|
||||
// while (myPort.read() != -1)
|
||||
// ;
|
||||
// myPort.println("GETGPS#");
|
||||
// String gpsbac = myPort.readStringUntil('\n');
|
||||
// Serial.println(gpsbac);
|
||||
|
||||
// String statnumberstr = fenge(gpsbac, "#", 1);
|
||||
// String statnumber = fenge(statnumberstr, "_", 1);
|
||||
// Serial.println(statnumber);
|
||||
// String Date;
|
||||
// if (statnumber.toInt() < 3)
|
||||
// {
|
||||
// Date = getnetData();
|
||||
// }
|
||||
|
||||
write_log(log_path,10,"start get_GPS()");
|
||||
String gpsbac = get_GPS();
|
||||
|
||||
Serial.println(gpsbac);
|
||||
// if (index < 28)
|
||||
// {
|
||||
write_log(log_path,10,"start getnetData()");
|
||||
Date = getnetData();
|
||||
// }
|
||||
|
||||
|
||||
// String Date;
|
||||
// Date = getnetData();
|
||||
|
||||
// str.substring(0, weizhi);
|
||||
// else
|
||||
// {
|
||||
// String datastr = fenge(gpsbac, "#", 0);
|
||||
// Date = fenge(datastr, "_", 1);
|
||||
// if (hassend == 0)
|
||||
// {
|
||||
// gpsbac = StationID+"#"+gpsbac;
|
||||
// int lennn = gpsbac.length();
|
||||
// char *temp = new char[lennn];
|
||||
// memcpy(temp, gpsbac.c_str(), gpsbac.length());
|
||||
// String nameoffile = "/gps/" + fenge(Date, " ", 0) + "_" + fenge(fenge(Date, " ", 1), ":", 0) + "_" + fenge(fenge(Date, " ", 1), ":", 1) + "_" + fenge(fenge(Date, " ", 1), ":", 2) + ".gps";
|
||||
// bool flagsucc = UpdateData("/weather/php/StationGPSinfo.php", temp, lennn);
|
||||
|
||||
// if (!flagsucc)
|
||||
// {
|
||||
// // sdcard::WriteStringToFile(nameoffile, temp, lennn);
|
||||
// }
|
||||
// else{
|
||||
// Serial.println("Finish Put StationGPSinfo Data");
|
||||
// }
|
||||
// delete[] temp;
|
||||
|
||||
// }
|
||||
// if (hassend >= 0)
|
||||
// {
|
||||
// hassend--;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// delay(15000);
|
||||
// if (fenge(Date, " ", 0)!=lastdate)
|
||||
// {
|
||||
// lastdate=fenge(Date, " ", 0);
|
||||
// while (myPort.read() != -1)
|
||||
// ;
|
||||
// myPort.println("ClearYL#");
|
||||
// ProgrameUper->CheckAndUpdate();
|
||||
|
||||
// /* code */
|
||||
// }
|
||||
// String Date;
|
||||
// double temprature;
|
||||
// String yuliang;
|
||||
// String yuliangfz;
|
||||
|
||||
|
||||
/////////*获取相关信息*//////////////////////////
|
||||
String datestring=fenge(Date, " ", 0) + "_" + fenge(fenge(Date, " ", 1), ":", 0) + "_" + fenge(fenge(Date, " ", 1), ":", 1) + "_" + fenge(fenge(Date, " ", 1), ":", 2);
|
||||
String Upheader = Date + "##" + StationID + "##" + SensorID + "##" + "UP" + "##"+String(IS1Sensor.shutterup)+"##";
|
||||
String Upname = "/up/" +datestring+ "_" + StationID + "_" + SensorID + "_" + "UP";
|
||||
String Downheader = Date + "##" + StationID + "##" + SensorID + "##" + "DOWN" + "##"+String(IS1Sensor.shutterdown)+"##";
|
||||
String Downname = "/down/" + datestring + "_" + StationID + "_" + SensorID + "_" + "DOWN";
|
||||
String senderID = Date + "##" + StationID + "##" + SensorID + "##" + String(temprature) + "##"+yuliang+"##"+yuliangfz+"##";
|
||||
String othername = "/other/" +datestring + "_" + StationID + "_" + SensorID + "_" + String(temprature);
|
||||
// Serial.println(senderID);
|
||||
// Serial.println( Upheader);
|
||||
// Serial.println(Upheader.length());
|
||||
|
||||
//////////////////////上传up数据//////////////////
|
||||
write_log(log_path,10,"put up data");
|
||||
size_t lennn = IS1Sensor.SensorInfo.BandNum * 2 + Upheader.length();
|
||||
char *temp = new char[IS1Sensor.SensorInfo.BandNum * 2 + Upheader.length()];
|
||||
memcpy(temp, Upheader.c_str(), Upheader.length());
|
||||
char *str=(char *)IS1Sensor.UpData;
|
||||
int lenofis=IS1Sensor.SensorInfo.BandNum * 2 ;
|
||||
for (size_t i = 0; i < IS1Sensor.SensorInfo.BandNum * 2; i++)
|
||||
{
|
||||
//temp[Upheader.length()+i]=str[i];
|
||||
}
|
||||
memcpy(temp + Upheader.length(), IS1Sensor.UpData,IS1Sensor.SensorInfo.BandNum * 2);
|
||||
bool flagsucc = UpdateData("/weather/php/SpectralDataUp.php", temp, lennn);
|
||||
vTaskDelay(3000);
|
||||
if (!flagsucc)
|
||||
{
|
||||
sdcard::WriteStringToFile(Upname, temp, lennn);
|
||||
log_data ="Up_data upload failed,save to SD.";
|
||||
write_log(log_path,10,log_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("finish Put Up Data");
|
||||
log_data ="finish Put Up Data.";
|
||||
write_log(log_path,10,log_data);
|
||||
}
|
||||
delete[] temp;
|
||||
|
||||
|
||||
|
||||
//////////////////////上传Down数据//////////////////
|
||||
write_log(log_path,10,"put dowm data");
|
||||
lennn = IS1Sensor.SensorInfo.BandNum * 2 + Downheader.length();
|
||||
temp = new char[lennn];
|
||||
memcpy(temp, Downheader.c_str(), Downheader.length());
|
||||
str=(char *)IS1Sensor.DownData;
|
||||
lenofis=IS1Sensor.SensorInfo.BandNum * 2 ;
|
||||
for (size_t i = 0; i < IS1Sensor.SensorInfo.BandNum * 2; i++)
|
||||
{
|
||||
// temp[Downheader.length()+i]=str[i];
|
||||
}
|
||||
memcpy(temp + Downheader.length(), IS1Sensor.DownData,IS1Sensor.SensorInfo.BandNum * 2);
|
||||
flagsucc = UpdateData("/weather/php/SpectralDataUp.php", temp, lennn);
|
||||
vTaskDelay(3000);
|
||||
|
||||
if (!flagsucc)
|
||||
{
|
||||
sdcard::WriteStringToFile(Downname, temp, lennn);
|
||||
log_data ="Down_data upload failed,save to SD.";
|
||||
write_log(log_path,10,log_data);
|
||||
}else{
|
||||
Serial.println("finish Put Down Data");
|
||||
log_data ="finish Put Down Data.";
|
||||
write_log(log_path,10,log_data);
|
||||
}
|
||||
delete[] temp;
|
||||
|
||||
//////////////////////上传其他数据//////////////////
|
||||
lennn = 12 + senderID.length();
|
||||
temp = new char[lennn];
|
||||
memcpy(temp, senderID.c_str(), senderID.length());
|
||||
memcpy(temp + senderID.length(), windret + 3, 12);
|
||||
flagsucc = UpdateData("/weather/php/WindsensorUp.php", temp, lennn, "application/json");
|
||||
vTaskDelay(3000);
|
||||
if (!flagsucc)
|
||||
{
|
||||
sdcard::WriteStringToFile(othername, temp, lennn);
|
||||
log_data ="put Other Data failed,save to SD.";
|
||||
write_log(log_path,10,log_data);
|
||||
}else{
|
||||
Serial.println("finish Put Other Data");
|
||||
log_data ="finish Put Other Data.";
|
||||
write_log(log_path,10,log_data);
|
||||
}
|
||||
delete[] temp;
|
||||
|
||||
|
||||
//结束并等待一定时间
|
||||
// http->stop(); delay(100);return;
|
||||
|
||||
delay(120000);
|
||||
#ifdef DINBIAO
|
||||
abort();
|
||||
ESP.restart();
|
||||
#endif
|
||||
return;
|
||||
|
||||
// //////以下位测试代砄1<E7A084>71ᅣ1<EFBF84>77
|
||||
|
||||
// delay(3000);
|
||||
// // int err = http->get("/weather/php/WindsensorUp.php");
|
||||
// // if (err == 0)
|
||||
// {
|
||||
// SerialMon.println(F("failed to connect"));
|
||||
// delay(10000);
|
||||
// return;
|
||||
// }
|
||||
// int status = http->responseStatusCode();
|
||||
// SerialMon.print(F("Response status code: "));
|
||||
// SerialMon.println(status);
|
||||
// if (!status)
|
||||
// {
|
||||
// delay(10000);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// SerialMon.println(F("Response Headers:"));
|
||||
// while (http->headerAvailable())
|
||||
// {
|
||||
// String headerName = http->readHeaderName();
|
||||
// String headerValue = http->readHeaderValue();
|
||||
// SerialMon.println(" " + headerName + " : " + headerValue);
|
||||
// }
|
||||
|
||||
// int length = http->contentLength();
|
||||
// if (length >= 0)
|
||||
// {
|
||||
// SerialMon.print(F("Content length is: "));
|
||||
// SerialMon.println(length);
|
||||
// }
|
||||
// if (http->isResponseChunked())
|
||||
// {
|
||||
// SerialMon.println(F("The response is chunked"));
|
||||
// }
|
||||
|
||||
// String body = http->responseBody();
|
||||
// SerialMon.println(F("Response:"));
|
||||
// SerialMon.println(body);
|
||||
|
||||
// SerialMon.print(F("Body length is: "));
|
||||
// SerialMon.println(body.length());
|
||||
// delay(5000);
|
||||
// // Shutdown
|
||||
|
||||
// // http->stop();
|
||||
}
|
294
src/main.cpp1
Normal file
294
src/main.cpp1
Normal file
@ -0,0 +1,294 @@
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* For this example, you need to install PubSubClient library:
|
||||
* https://github.com/knolleary/pubsubclient
|
||||
* or from http://librarymanager/all#PubSubClient
|
||||
*
|
||||
* TinyGSM Getting Started guide:
|
||||
* https://tiny.cc/tinygsm-readme
|
||||
*
|
||||
* For more MQTT examples, see PubSubClient library
|
||||
*
|
||||
**************************************************************
|
||||
* This example connects to HiveMQ's showcase broker.
|
||||
*
|
||||
* You can quickly test sending and receiving messages from the HiveMQ webclient
|
||||
* available at http://www.hivemq.com/demos/websocket-client/.
|
||||
*
|
||||
* Subscribe to the topic GsmClientTest/ledStatus
|
||||
* Publish "toggle" to the topic GsmClientTest/led and the LED on your board
|
||||
* should toggle and you should see a new message published to
|
||||
* GsmClientTest/ledStatus with the newest LED status.
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
// Select your modem:
|
||||
#define TINY_GSM_MODEM_SIM800
|
||||
// #define TINY_GSM_MODEM_SIM808
|
||||
// #define TINY_GSM_MODEM_SIM868
|
||||
// #define TINY_GSM_MODEM_SIM900
|
||||
// #define TINY_GSM_MODEM_SIM7000
|
||||
// #define TINY_GSM_MODEM_SIM7000SSL
|
||||
// #define TINY_GSM_MODEM_SIM7080
|
||||
// #define TINY_GSM_MODEM_SIM5360
|
||||
// #define TINY_GSM_MODEM_SIM7600
|
||||
// #define TINY_GSM_MODEM_UBLOX
|
||||
// #define TINY_GSM_MODEM_SARAR4
|
||||
// #define TINY_GSM_MODEM_M95
|
||||
// #define TINY_GSM_MODEM_BG96
|
||||
// #define TINY_GSM_MODEM_A6
|
||||
// #define TINY_GSM_MODEM_A7
|
||||
// #define TINY_GSM_MODEM_M590
|
||||
// #define TINY_GSM_MODEM_MC60
|
||||
// #define TINY_GSM_MODEM_MC60E
|
||||
// #define TINY_GSM_MODEM_ESP8266
|
||||
// #define TINY_GSM_MODEM_XBEE
|
||||
// #define TINY_GSM_MODEM_SEQUANS_MONARCH
|
||||
|
||||
// Set serial for debug console (to the Serial Monitor, default speed 115200)
|
||||
#define SerialMon Serial
|
||||
|
||||
// Set serial for AT commands (to the module)
|
||||
// Use Hardware Serial on Mega, Leonardo, Micro
|
||||
#include <TinyGsmClient.h>
|
||||
#include <PubSubClient.h>
|
||||
#ifndef __AVR_ATmega328P__
|
||||
HardwareSerial MySerial(1);
|
||||
#define SerialAT MySerial
|
||||
|
||||
// or Software Serial on Uno, Nano
|
||||
#else
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial SerialAT(2, 3); // RX, TX
|
||||
#endif
|
||||
|
||||
// See all AT commands, if wanted
|
||||
// #define DUMP_AT_COMMANDS
|
||||
|
||||
// Define the serial console for debug prints, if needed
|
||||
#define TINY_GSM_DEBUG SerialMon
|
||||
|
||||
// Range to attempt to autobaud
|
||||
// NOTE: DO NOT AUTOBAUD in production code. Once you've established
|
||||
// communication, set a fixed baud rate using modem.setBaud(#).
|
||||
#define GSM_AUTOBAUD_MIN 9600
|
||||
#define GSM_AUTOBAUD_MAX 115200
|
||||
|
||||
// Add a reception delay, if needed.
|
||||
// This may be needed for a fast processor at a slow baud rate.
|
||||
// #define TINY_GSM_YIELD() { delay(2); }
|
||||
|
||||
// Define how you're planning to connect to the internet.
|
||||
// This is only needed for this example, not in other code.
|
||||
#define TINY_GSM_USE_GPRS true
|
||||
#define TINY_GSM_USE_WIFI false
|
||||
|
||||
// set GSM PIN, if any
|
||||
#define GSM_PIN ""
|
||||
|
||||
// Your GPRS credentials, if any
|
||||
const char apn[] = "CMNET";
|
||||
const char gprsUser[] = "";
|
||||
const char gprsPass[] = "";
|
||||
|
||||
// Your WiFi connection credentials, if applicable
|
||||
const char wifiSSID[] = "YourSSID";
|
||||
const char wifiPass[] = "YourWiFiPass";
|
||||
|
||||
// MQTT details
|
||||
const char* broker = "broker.hivemq.com";
|
||||
|
||||
const char* topicLed = "GsmClientTest/led";
|
||||
const char* topicInit = "GsmClientTest/init";
|
||||
const char* topicLedStatus = "GsmClientTest/ledStatus";
|
||||
|
||||
|
||||
|
||||
// Just in case someone defined the wrong thing..
|
||||
#if TINY_GSM_USE_GPRS && not defined TINY_GSM_MODEM_HAS_GPRS
|
||||
#undef TINY_GSM_USE_GPRS
|
||||
#undef TINY_GSM_USE_WIFI
|
||||
#define TINY_GSM_USE_GPRS false
|
||||
#define TINY_GSM_USE_WIFI true
|
||||
#endif
|
||||
#if TINY_GSM_USE_WIFI && not defined TINY_GSM_MODEM_HAS_WIFI
|
||||
#undef TINY_GSM_USE_GPRS
|
||||
#undef TINY_GSM_USE_WIFI
|
||||
#define TINY_GSM_USE_GPRS true
|
||||
#define TINY_GSM_USE_WIFI false
|
||||
#endif
|
||||
|
||||
#ifdef DUMP_AT_COMMANDS
|
||||
#include <StreamDebugger.h>
|
||||
StreamDebugger debugger(SerialAT, SerialMon);
|
||||
TinyGsm modem(debugger);
|
||||
#else
|
||||
TinyGsm modem(SerialAT);
|
||||
#endif
|
||||
TinyGsmClient client(modem);
|
||||
PubSubClient mqtt(client);
|
||||
|
||||
#define LED_PIN 13
|
||||
int ledStatus = LOW;
|
||||
|
||||
uint32_t lastReconnectAttempt = 0;
|
||||
|
||||
void mqttCallback(char* topic, byte* payload, unsigned int len) {
|
||||
SerialMon.print("Message arrived [");
|
||||
SerialMon.print(topic);
|
||||
SerialMon.print("]: ");
|
||||
SerialMon.write(payload, len);
|
||||
SerialMon.println();
|
||||
|
||||
// Only proceed if incoming message's topic matches
|
||||
if (String(topic) == topicLed) {
|
||||
ledStatus = !ledStatus;
|
||||
digitalWrite(LED_PIN, ledStatus);
|
||||
mqtt.publish(topicLedStatus, ledStatus ? "1" : "0");
|
||||
}
|
||||
}
|
||||
|
||||
boolean mqttConnect() {
|
||||
SerialMon.print("Connecting to ");
|
||||
SerialMon.print(broker);
|
||||
|
||||
// Connect to MQTT Broker
|
||||
boolean status = mqtt.connect("GsmClientTest");
|
||||
|
||||
// Or, if you want to authenticate MQTT:
|
||||
// boolean status = mqtt.connect("GsmClientName", "mqtt_user", "mqtt_pass");
|
||||
|
||||
if (status == false) {
|
||||
SerialMon.println(" fail");
|
||||
return false;
|
||||
}
|
||||
SerialMon.println(" success");
|
||||
mqtt.publish(topicInit, "GsmClientTest started");
|
||||
mqtt.subscribe(topicLed);
|
||||
return mqtt.connected();
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
MySerial.begin(9600, SERIAL_8N1, 26, 14);
|
||||
// Set console baud rate
|
||||
SerialMon.begin(115200);
|
||||
delay(1010);
|
||||
|
||||
pinMode(LED_PIN, OUTPUT);
|
||||
|
||||
// !!!!!!!!!!!
|
||||
|
||||
pinMode(32, OUTPUT);
|
||||
digitalWrite(32, HIGH);
|
||||
Serial.println("Wait..."); pinMode(25, OUTPUT);
|
||||
pinMode(33, OUTPUT);
|
||||
digitalWrite(33, LOW);
|
||||
delay(1800);
|
||||
Serial.println("Wait...1");
|
||||
|
||||
digitalWrite(33, HIGH);
|
||||
// Set your reset, enable, power pins here
|
||||
// !!!!!!!!!!!
|
||||
Serial2.begin(9600);
|
||||
Serial.println("Wait...");
|
||||
// MySerial.begin(115200);
|
||||
delay(5000);
|
||||
MySerial.print("AT\r\n");
|
||||
MySerial.print("AT\r\n");
|
||||
MySerial.print("AT\r\n");
|
||||
MySerial.print("AT\r\n");
|
||||
String input = MySerial.readString();
|
||||
Serial.println(input);
|
||||
Serial.println("Wait..asdfasdf.");
|
||||
while (1)
|
||||
{
|
||||
input =MySerial.readString();
|
||||
Serial.println(input);
|
||||
MySerial.print("AT\r\n");
|
||||
delay(10);
|
||||
}
|
||||
|
||||
|
||||
delay(5000);
|
||||
|
||||
|
||||
//Serial2.begin(9600);
|
||||
//Serial2.print("AT\r\n");
|
||||
//delay(1000);
|
||||
|
||||
//input = Serial2.readString();
|
||||
//Serial.println(input);
|
||||
|
||||
delay(16000);
|
||||
// Set GSM module baud rate
|
||||
TinyGsmAutoBaud(SerialAT, 9600, 460800);
|
||||
// SerialAT.begin(9600);
|
||||
delay(6000);
|
||||
|
||||
// Restart takes quite some time
|
||||
// To skip it, call init() instead of restart()
|
||||
SerialMon.println("Initializing modem...");
|
||||
// modem.restart();
|
||||
modem.init();
|
||||
|
||||
String modemInfo = modem.getModemInfo();
|
||||
SerialMon.print("Modem Info: ");
|
||||
SerialMon.println(modemInfo);
|
||||
|
||||
#if TINY_GSM_USE_GPRS
|
||||
// Unlock your SIM card with a PIN if needed
|
||||
if (GSM_PIN && modem.getSimStatus() != 3) { modem.simUnlock(GSM_PIN); }
|
||||
#endif
|
||||
|
||||
#if TINY_GSM_USE_WIFI
|
||||
// Wifi connection parameters must be set before waiting for the network
|
||||
SerialMon.print(F("Setting SSID/password..."));
|
||||
if (!modem.networkConnect(wifiSSID, wifiPass)) {
|
||||
SerialMon.println(" fail");
|
||||
delay(10000);
|
||||
return;
|
||||
}
|
||||
SerialMon.println(" success");
|
||||
#endif
|
||||
|
||||
#if TINY_GSM_USE_GPRS && defined TINY_GSM_MODEM_XBEE
|
||||
// The XBee must run the gprsConnect function BEFORE waiting for network!
|
||||
modem.gprsConnect(apn, gprsUser, gprsPass);
|
||||
#endif
|
||||
|
||||
SerialMon.print("Waiting for network...");
|
||||
if (!modem.waitForNetwork()) {
|
||||
SerialMon.println(" fail");
|
||||
delay(10000);
|
||||
return;
|
||||
}
|
||||
SerialMon.println(" success");
|
||||
|
||||
if (modem.isNetworkConnected()) { SerialMon.println("Network connected"); }
|
||||
|
||||
#if TINY_GSM_USE_GPRS
|
||||
// GPRS connection parameters are usually set after network registration
|
||||
SerialMon.print(F("Connecting to "));
|
||||
SerialMon.print(apn);
|
||||
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
|
||||
SerialMon.println(" fail");
|
||||
delay(10000);
|
||||
return;
|
||||
}
|
||||
SerialMon.println(" success");
|
||||
|
||||
if (modem.isGprsConnected()) { SerialMon.println("GPRS connected"); }
|
||||
#endif
|
||||
|
||||
// MQTT Broker setup
|
||||
mqtt.setServer(broker, 1883);
|
||||
mqtt.setCallback(mqttCallback);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Make sure we're still registered on the network
|
||||
|
||||
}
|
215
src/optoskybase.cpp
Normal file
215
src/optoskybase.cpp
Normal file
@ -0,0 +1,215 @@
|
||||
#include"optoskybase.h"
|
||||
static byte datatoget[10000];
|
||||
byte echtimedata[1000];
|
||||
OptoSky::OptoSky()
|
||||
{
|
||||
IsOptoskyinit=false;
|
||||
result=datatoget;
|
||||
}
|
||||
void OptoSky::SetPortName(int serial)
|
||||
{
|
||||
ISserial=new HardwareSerial(1);
|
||||
ISserial->begin(115200,SERIAL_8N1,17,18);
|
||||
// ISserial->println("sadfasdfsadfasdf");
|
||||
IsOptoskyinit=true;
|
||||
}
|
||||
void OptoSky::SendComment(byte *commend,int lenth)
|
||||
{
|
||||
unsigned short lenthsend = lenth + 5;
|
||||
byte *senddata=new byte[lenthsend]();
|
||||
|
||||
|
||||
senddata[0] = 0xaa;
|
||||
senddata[1] = 0x55;
|
||||
senddata[2] = (lenth+3) / 256;
|
||||
senddata[3] = (lenth+3) % 256;
|
||||
for (size_t i = 0; i < lenth; i++)
|
||||
{
|
||||
senddata[i+4]=commend[i];
|
||||
|
||||
/* code */
|
||||
}
|
||||
|
||||
int sum = 0;
|
||||
for (int i = 0; i < lenth+2; i++)
|
||||
{
|
||||
sum = sum+senddata[i+2];
|
||||
}
|
||||
senddata[lenthsend-1]=sum;
|
||||
if (IsOptoskyinit)
|
||||
{
|
||||
while (ISserial->read()!=-1)
|
||||
{
|
||||
/* code */
|
||||
|
||||
}
|
||||
//Serial.write(senddata,lenthsend);
|
||||
ISserial->write(senddata,lenthsend);
|
||||
delay(10);
|
||||
|
||||
}
|
||||
delete[] senddata;
|
||||
}
|
||||
|
||||
void OptoSky::SendComment(byte comid)
|
||||
{
|
||||
SendComment(&comid,1);
|
||||
}
|
||||
|
||||
void OptoSky::SendComment(byte *Comment,int commentlenth, byte *data,int lenth)
|
||||
{
|
||||
byte *commnetdsend=new byte[commentlenth+lenth]();
|
||||
memcpy(commnetdsend,Comment,commentlenth);
|
||||
memcpy(commnetdsend+commentlenth,data,lenth);
|
||||
SendComment(commnetdsend,commentlenth+lenth);
|
||||
delete[] commnetdsend;
|
||||
|
||||
}
|
||||
|
||||
void OptoSky::SendComment(byte comid, byte *data,int lenth)
|
||||
{
|
||||
byte *commnetdsend=new byte[lenth+1]();
|
||||
memcpy(commnetdsend,&comid,1);
|
||||
memcpy(commnetdsend+1,data,lenth);
|
||||
SendComment(commnetdsend,1+lenth);
|
||||
delete[] commnetdsend;
|
||||
}
|
||||
|
||||
bool OptoSky::GetReturn(byte id,int &lenth,int timewaitbefor)
|
||||
{
|
||||
if (!GetReturn(lenth,timewaitbefor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (datatoget[4]!=id)
|
||||
{
|
||||
Serial.println("retrun is not correct with ComId:" );
|
||||
|
||||
return false;//<2F>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>0<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>0<EFBFBD>8<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>5<EFBFBD>3<EFBFBD>1<EFBFBD>2<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7<EFBFBD>1<EFBFBD>7
|
||||
}
|
||||
memcpy(datatoget,datatoget+5,lenth-1);
|
||||
lenth=lenth-6;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OptoSky::GetReturn(int &lenth,int timewaitbefor)
|
||||
{
|
||||
lenth=0;
|
||||
delay(timewaitbefor);
|
||||
while (ISserial->available())
|
||||
{
|
||||
int dataget=ISserial->readBytes(echtimedata,1000);
|
||||
|
||||
for (long i = 0; i < dataget; i++)
|
||||
{
|
||||
datatoget[i+lenth]=echtimedata[i];
|
||||
/* code */
|
||||
}
|
||||
lenth=lenth+dataget;
|
||||
|
||||
|
||||
|
||||
delay(40);
|
||||
|
||||
|
||||
/* code */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tiemstry=0;
|
||||
lable1:
|
||||
while (lenth < 5)
|
||||
{
|
||||
delay(20);
|
||||
if (ISserial->available())
|
||||
{
|
||||
/* code */
|
||||
int dataget=ISserial->readBytes(echtimedata,1000);
|
||||
|
||||
for (long i = 0; i < dataget; i++)
|
||||
{
|
||||
datatoget[i+lenth]=echtimedata[i];
|
||||
/* code */
|
||||
}
|
||||
lenth=lenth+dataget;
|
||||
}
|
||||
|
||||
if (tiemstry> 2000)
|
||||
{
|
||||
Serial.println("long time no data retrun");
|
||||
Serial.print("size now:");
|
||||
Serial.println(lenth);
|
||||
return false;
|
||||
|
||||
}
|
||||
tiemstry++;
|
||||
}
|
||||
if (datatoget[0] != 0xaa || datatoget[1] != 0x55)
|
||||
{
|
||||
memcpy(datatoget,datatoget+1,lenth-1);
|
||||
lenth--;
|
||||
|
||||
goto lable1;
|
||||
}
|
||||
|
||||
int datalenth = datatoget[2] * 256 + datatoget[3] + 2;
|
||||
tiemstry=0;
|
||||
while (lenth < datalenth)
|
||||
{
|
||||
delay(20);
|
||||
if (ISserial->available())
|
||||
{
|
||||
/* code */
|
||||
int dataget=ISserial->readBytes(echtimedata,1000);
|
||||
|
||||
for (long i = 0; i < dataget; i++)
|
||||
{
|
||||
datatoget[i+lenth]=echtimedata[i];
|
||||
/* code */
|
||||
}
|
||||
lenth=lenth+dataget;
|
||||
}
|
||||
if (tiemstry> 500)
|
||||
{
|
||||
Serial.println("not enouth data retrun");
|
||||
Serial.print("size now:");
|
||||
Serial.println(lenth);
|
||||
return false;
|
||||
|
||||
}
|
||||
tiemstry++;
|
||||
|
||||
}
|
||||
|
||||
if (lenth > datalenth)
|
||||
{
|
||||
lenth=datalenth;
|
||||
}
|
||||
int checkleth = datalenth - 3;
|
||||
unsigned int checknum = 0;
|
||||
for (size_t i = 0; i < checkleth; i++)
|
||||
{
|
||||
|
||||
checknum = checknum + datatoget[i + 2];
|
||||
}
|
||||
checknum = checknum % 256;
|
||||
if (checknum != datatoget[lenth-1])
|
||||
{
|
||||
Serial.println("checkerro " );
|
||||
//data.clear();
|
||||
//return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool OptoSky::isSensorInit()
|
||||
{
|
||||
return IsOptoskyinit;
|
||||
}
|
77
src/optoskybase.h
Normal file
77
src/optoskybase.h
Normal file
@ -0,0 +1,77 @@
|
||||
|
||||
|
||||
#ifndef __OPTOSKYBASE_H__
|
||||
#define __OPTOSKYBASE_H__
|
||||
#include"HardwareSerial.h"
|
||||
|
||||
struct STRSensorInfo
|
||||
{
|
||||
String SensorName;
|
||||
long maxValue;
|
||||
long BandNum;
|
||||
String WavelenthStr;
|
||||
float *wavelenthlist;
|
||||
//double *wavelenth;
|
||||
bool isSensorInit;
|
||||
String serialnumber;
|
||||
float a1,a2,a3,a4;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define GET_MODEBOARD_TEMP 0x01
|
||||
#define GET_PN_NUMBER 0x03
|
||||
#define GET_SN_NUMBER 0x04
|
||||
#define GET_MANUFACTURE_DATA 0x06
|
||||
#define GET_MANUFACTOR_INFO 0x09
|
||||
#define GET_PIXEL_LENGTH 0x0a
|
||||
#define GET_TEC_TEMP 0x13
|
||||
#define SET_TEC_TEMP 0x12
|
||||
#define GET_OPTICFLAT_TEMP 0x35
|
||||
#define GET_CIRCUIT_BOARD_TEMP 0x36
|
||||
#define SET_INTEGRAL_TIME 0x14
|
||||
#define GET_INTEGRAL_TIME 0x41
|
||||
#define GET_MAX_INTEGRAL_TIME 0x42
|
||||
#define GET_MIN_INTEGRAL_TIME 0x43
|
||||
#define ASYNCHRONOUS_COLLECT_DARK 0x23
|
||||
#define ASYNCHRONOUS_START_COLLECTION 0x16
|
||||
#define ASYNCHRONOUS_READ_DATA 0x17
|
||||
#define SET_AVERAGE_NUMBER 0x28
|
||||
#define SYNCHRONIZATION_GET_DATA 0x1e
|
||||
#define SYNCHRONIZATION_GET_DARK 0x2f
|
||||
//#define SYNCHRONIZATION_GET_DARK 0x23
|
||||
#define EXTERNAL_TRIGGER_ENABLE 0x1f
|
||||
#define SET_XENON_LAMP_DELAY_TIME 0x24
|
||||
#define GET_WAVELENGTH_CALIBRATION_COFF 0x55
|
||||
#define GET_STAT_OF_LAMPOUT 0x60
|
||||
#define SET_GPIO 0x61
|
||||
#define byte u_char
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class OptoSky
|
||||
{
|
||||
public:
|
||||
OptoSky();
|
||||
byte *result;
|
||||
HardwareSerial *ISserial;
|
||||
bool IsOptoskyinit;
|
||||
void SetPortName(int serial);
|
||||
void SendComment(byte *commend,int lenth);
|
||||
void SendComment(byte comid);
|
||||
void SendComment(byte *Comment,int commentlenth, byte *data,int lenth);
|
||||
void SendComment(byte comid, byte *data,int lenth);
|
||||
bool GetReturn(byte id,int &lenth,int timewaitbefor=20);
|
||||
bool GetReturn(int &lenth,int timewaitbefor);
|
||||
|
||||
bool isSensorInit();
|
||||
void RemoveHeaderandEnd(byte *data,int lenth);
|
||||
|
||||
};
|
||||
#endif // __OPTOSKYBASE_H__
|
120
src/slave.cpp
Normal file
120
src/slave.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
#include "slave.h"
|
||||
|
||||
double new_emissivity =0.95;
|
||||
|
||||
|
||||
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
|
||||
TwoWire wireme(0);
|
||||
|
||||
u_char a[]={0x01,0x04,0x00,0x00,0x00 ,0x06,0x70,0x08};
|
||||
u_char yuliang[]={0x02, 0x03, 0x00, 0x00 ,0x00, 0x01, 0x84, 0x39};
|
||||
u_char ClearYL[]={0x02,0x06,0x00, 0x00 ,0x00 ,0x5A ,0X09 ,0Xc2};
|
||||
u_char yuliangfuliangdu[]={0x02,0x03,0x00,0x02,0x00,0x02,0x65,0xf8};
|
||||
|
||||
u_char openGNRMC[]={0xF1,0xD9,0x06,0x01,0x03,0x00,0xF0,0x05,0x01,0x00,0x1A};
|
||||
u_char gpsSaveConfig[]={0xF1,0xD9,0x06,0x09,0x08,0x00,0x00,0x00,0x00,0x00,0x2F,0x00,0x00,0x00,0x46,0xB7};
|
||||
|
||||
|
||||
|
||||
SoftwareSerial *my485Port;
|
||||
void slave::init(int8_t MY485PORT_RX,int8_t MY485PORT_TX){
|
||||
// put your setup code here, to run once:
|
||||
//Wire.begin(4,5);
|
||||
|
||||
Serial.println("slave init ...");
|
||||
my485Port = new SoftwareSerial(MY485PORT_RX ,MY485PORT_TX,false);
|
||||
my485Port->begin(9600, SWSERIAL_8N1, MY485PORT_RX, MY485PORT_TX, false);
|
||||
|
||||
///////////// 光谱电源控制,重启
|
||||
pinMode(36,OUTPUT);
|
||||
digitalWrite(36,LOW);
|
||||
delay(2000);
|
||||
digitalWrite(36,HIGH);
|
||||
|
||||
|
||||
// GPSSeiral.begin(115200, SWSERIAL_8N1, 2, 12, false);
|
||||
wireme.setPins(7,8);
|
||||
|
||||
if (!mlx.begin(MLX90614_I2CADDR,&wireme)) {
|
||||
Serial.println("Error connecting to MLX sensor. Check wiring.");
|
||||
//while (1);
|
||||
};
|
||||
mlx.writeEmissivity(new_emissivity); // this does the 0x0000 erase write
|
||||
Serial.println(sizeof(openGNRMC));
|
||||
|
||||
}
|
||||
|
||||
double slave::getMLX(){
|
||||
double a =mlx.readObjectTempC();
|
||||
return a;
|
||||
// Serial.write((char*) &a,8);
|
||||
}
|
||||
|
||||
void slave::getWehter(){
|
||||
while (my485Port->read()!=-1);
|
||||
my485Port->write(a,8);
|
||||
delay(90);
|
||||
for (int j = 0; j <17 ; ++j) {
|
||||
ret[j]=my485Port->read();
|
||||
}
|
||||
float VV=(ret[3]*256+ret[4])*1.0/100;
|
||||
float DD=(ret[5]*256+ret[6])*1.0/10;
|
||||
float TT=(ret[7]*256+ret[8])*1.0/100;
|
||||
float HH=(ret[9]*256+ret[10])*1.0/100;
|
||||
long PP=(ret[13]*256+ret[14])*256*256+(ret[11]*256+ret[12]);
|
||||
#ifdef DEBG
|
||||
String str_getWehter = "VV:"+String(VV)+" DD:"+String(DD)+" TT:"+String(TT)+" HH:"+String(HH)+" PP:"+String(PP);
|
||||
// return str;
|
||||
// Serial.println("VV:"+String(VV)+" DD:"+String(DD)+" TT:"+String(TT)+" HH:"+String(HH)+" PP:"+String(PP));
|
||||
#endif
|
||||
// Serial.write(ret,17);
|
||||
}
|
||||
|
||||
float slave::getYuliang(){
|
||||
while (my485Port->read()!=-1);
|
||||
my485Port->write(yuliang,8);
|
||||
delay(90);
|
||||
|
||||
for (int j = 0; j <7; ++j) {
|
||||
ret[j]=my485Port->read();
|
||||
}
|
||||
float Value=ret[3]*256+ret[4];
|
||||
Value=Value/10;
|
||||
// Serial.write(ret,7);
|
||||
// Serial.print(Value);
|
||||
// Serial.print("#");
|
||||
|
||||
return Value;
|
||||
|
||||
}
|
||||
|
||||
int32_t slave::getYuliangfuliang(){
|
||||
while (my485Port->read()!=-1);
|
||||
my485Port->write(yuliangfuliangdu,8);
|
||||
delay(90);
|
||||
|
||||
for (int j = 0; j <7; ++j) {
|
||||
ret[j]=my485Port->read();
|
||||
}
|
||||
int32_t Value=(ret[3]*256+ret[4])*256*256+ret[5]*256+ret[6];
|
||||
// Value=Value/10;
|
||||
// Serial.write(ret,7);
|
||||
// Serial.print(Value);
|
||||
// Serial.print("#");
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
/// 返回1,表示ok
|
||||
uint8_t slave::claeryuliang(){
|
||||
while (my485Port->read()!=-1);
|
||||
my485Port->write(ClearYL,8);
|
||||
delay(90);
|
||||
for (int j = 0; j <8; ++j) {
|
||||
ret[j]=my485Port->read();
|
||||
}
|
||||
// Serial.print("OK");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
30
src/slave.h
Normal file
30
src/slave.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef _SLAVE_H_
|
||||
#define _SLAVE_H_
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "SoftwareSerial.h"
|
||||
#include "Wire.h"
|
||||
#include <Adafruit_MLX90614.h>
|
||||
//#define DEBUG_SERIAL Serial
|
||||
#include <SPI.h>
|
||||
#include "SparkFun_Ublox_Arduino_Library.h"
|
||||
|
||||
|
||||
class slave
|
||||
{
|
||||
public:
|
||||
u_char ret[17];
|
||||
String str_getWehter;
|
||||
|
||||
void init(int8_t MYPORT_RX,int8_t MYPORT_TX);
|
||||
double getMLX();
|
||||
void getWehter();
|
||||
float getYuliang();
|
||||
int32_t getYuliangfuliang();
|
||||
uint8_t claeryuliang();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
233
src/updatebyme.cpp
Normal file
233
src/updatebyme.cpp
Normal file
@ -0,0 +1,233 @@
|
||||
#include "updatebyme.h"
|
||||
#include "SDmanger.h"
|
||||
void UpDateClassByme::performUpdate(Stream &updateSource, size_t updateSize)
|
||||
{
|
||||
if (Update.begin(updateSize))
|
||||
{
|
||||
Serial.println("Writes : ");
|
||||
size_t written = Update.writeStream(updateSource);
|
||||
if (written == updateSize)
|
||||
{
|
||||
Serial.println("Writes : " + String(written) + " successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Written only : " + String(written) + "/" + String(updateSize) + ". Retry?");
|
||||
}
|
||||
if (Update.end())
|
||||
{
|
||||
Serial.println("OTA finished!");
|
||||
if (Update.isFinished())
|
||||
{
|
||||
Serial.println("Restart ESP device!");
|
||||
abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("OTA not fiished");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Error occured #: " + String(Update.getError()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Cannot beggin update");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t UpDateClassByme::DownloadFirmwareForurl(String version)
|
||||
{
|
||||
String url="/weather/firmware/esp32/firmware_"+version+".bin";
|
||||
int err = http->get(url.c_str());
|
||||
if (err != 0)
|
||||
{
|
||||
Serial.println(F("Date failed to connect"));
|
||||
delay(10000);
|
||||
return 0;
|
||||
}
|
||||
int status = http->responseStatusCode();
|
||||
if (!status)
|
||||
{
|
||||
delay(10000);
|
||||
return 0;
|
||||
}
|
||||
Serial.print(F("Response status code: "));
|
||||
Serial.println(status);
|
||||
// SerialMon.println(F("Response Headers:"));
|
||||
size_t count=0;
|
||||
while (http->headerAvailable())
|
||||
{
|
||||
String headerName = http->readHeaderName();
|
||||
String headerValue = http->readHeaderValue();
|
||||
Serial.println("Date: " + headerName + " : " + headerValue);
|
||||
if (headerName=="Content-Length")
|
||||
{
|
||||
count=headerValue.toInt();
|
||||
/* code */
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Serial.println("lenth is "+String(count));
|
||||
if (http->isResponseChunked())
|
||||
{
|
||||
Serial.println(F("Date The response is chunked"));
|
||||
}
|
||||
char *str=new char[1000];
|
||||
int lent=count/1000;
|
||||
File file;
|
||||
|
||||
file = SD_MMC.open("/update.bin", "wb");
|
||||
|
||||
for (size_t i = 0; i < lent; i++)
|
||||
{
|
||||
http->readBytes(str,1000);
|
||||
file.write((const byte *)str,1000);
|
||||
Serial.print("download ");
|
||||
Serial.println(String(i*100/lent));
|
||||
/* code */
|
||||
}
|
||||
http->readBytes(str,count%1000);
|
||||
file.write((const byte *)str,count%1000);
|
||||
file.flush();
|
||||
file.close();
|
||||
//performUpdate(*http,cout);
|
||||
|
||||
|
||||
// http->readBytes
|
||||
Serial.println("adfasdfsadfsdfsd");
|
||||
//Serial.write(str,cout);
|
||||
//Serial.println(body.length());
|
||||
http->stop();
|
||||
return count;
|
||||
// return body;
|
||||
}
|
||||
|
||||
void UpDateClassByme::initme(String Version)
|
||||
{
|
||||
CurrentVersion=Version;
|
||||
|
||||
}
|
||||
void UpDateClassByme::updateversion()
|
||||
{
|
||||
String Targetversion=GetValueFromNet("/weather/php/upVserion.php",StationID+":"+CurrentVersion);
|
||||
}
|
||||
bool UpDateClassByme::CheckAndUpdate()
|
||||
{
|
||||
|
||||
|
||||
String Targetversion=GetValueFromNet("/weather/php/GetVserion.php",StationID);
|
||||
if ( Targetversion=="0"||Targetversion==CurrentVersion||Targetversion=="")
|
||||
{
|
||||
return true;
|
||||
|
||||
}
|
||||
Serial.println("targetvesion is:"+Targetversion);
|
||||
|
||||
//size_t countdownload1=375584;
|
||||
size_t countdownload1=DownloadFirmwareForurl(Targetversion);
|
||||
if (countdownload1<10000)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Serial.println("count download is:"+String(countdownload1));
|
||||
|
||||
String MD5=GetValueFromNet("/weather/php/GetMD5Value.php",Targetversion);
|
||||
|
||||
if (MD5=="0")
|
||||
{
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
// updater.setMD5(MD5);
|
||||
MD5Builder md5my;
|
||||
|
||||
|
||||
File file;
|
||||
|
||||
file = SD_MMC.open("/update.bin", "rb");
|
||||
md5my.begin();
|
||||
md5my.addStream(file,countdownload1);
|
||||
md5my.calculate();
|
||||
String md5com=md5my.toString();
|
||||
Serial.println("md5 comput is:"+md5my.toString());
|
||||
Serial.println("md5 should is:"+MD5);
|
||||
file.close();
|
||||
if (MD5==md5com)
|
||||
{
|
||||
file = SD_MMC.open("/update.bin", "rb");
|
||||
performUpdate(file,countdownload1);
|
||||
return true;
|
||||
/* code */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UpDateClassByme::UpDateClassByme(HttpClient *httptm)
|
||||
{
|
||||
http=httptm;
|
||||
StationID="000";
|
||||
}
|
||||
String UpDateClassByme::GetValueFromNet(String url,String Key)
|
||||
{
|
||||
|
||||
http->beginRequest();
|
||||
http->post(url.c_str());
|
||||
|
||||
|
||||
http->sendHeader(HTTP_HEADER_CONTENT_LENGTH, Key.length());
|
||||
http->endRequest();
|
||||
int err = http->write((const byte *)Key.c_str(), Key.length());
|
||||
Serial.print("send date size");
|
||||
Serial.println(err);
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
|
||||
http->stop();
|
||||
return "-1";
|
||||
}
|
||||
int status = http->responseStatusCode();
|
||||
if (!status)
|
||||
{
|
||||
http->stop();
|
||||
return "-1";
|
||||
}
|
||||
|
||||
int length = http->contentLength();
|
||||
if (length == 0)
|
||||
{
|
||||
http->stop();
|
||||
return "-1";
|
||||
}
|
||||
|
||||
String body = http->responseBody();
|
||||
Serial.println("body:"+body);
|
||||
|
||||
http->stop();
|
||||
return body;
|
||||
}
|
23
src/updatebyme.h
Normal file
23
src/updatebyme.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef UPDATEBYME_H
|
||||
#define UPDATEBYME_H
|
||||
#include<Update.h>
|
||||
#include <HTTPClient.h>
|
||||
class UpDateClassByme{
|
||||
public:
|
||||
UpdateClass updater;
|
||||
UpDateClassByme(HttpClient *httptm);
|
||||
void performUpdate(Stream &updateSource, size_t updateSize);
|
||||
HttpClient *http;
|
||||
size_t DownloadFirmwareForurl(String version);
|
||||
String CurrentVersion;
|
||||
void initme(String Version);
|
||||
bool CheckAndUpdate();
|
||||
String StationID;
|
||||
String GetValueFromNet(String url,String Key);
|
||||
void updateversion();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
41
src/wifidebug.cpp
Normal file
41
src/wifidebug.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include <wifidebug.h>
|
||||
#include<TCPserver.h>
|
||||
|
||||
|
||||
|
||||
#ifdef DebugCalibration
|
||||
const char *ssid = "SmartForCalibration";
|
||||
const char *password = "123456789";
|
||||
IPAddress local_IP(192, 168, 1,2);
|
||||
IPAddress gateway(192, 168, 1, 2);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
TCPserver *tcpserver;
|
||||
void beginWIFI(){
|
||||
tcpserver=new TCPserver(23);
|
||||
WiFi.mode( WIFI_MODE_AP );
|
||||
Serial.println("init webserver ok 33333");
|
||||
WiFi.softAPConfig(local_IP, gateway, subnet);
|
||||
boolean result = WiFi.softAP(ssid, password);
|
||||
|
||||
tcpserver->loop();
|
||||
|
||||
}
|
||||
void tcploop(){
|
||||
tcpserver->loop();
|
||||
}
|
||||
|
||||
|
||||
void printbytcpserver(String str)
|
||||
{
|
||||
tcpserver->SendDataToClinet(str);
|
||||
tcpserver->loop();
|
||||
// Serial.println(str);
|
||||
|
||||
}
|
||||
#endif
|
||||
#ifndef DebugCalibration
|
||||
void beginWIFI(){}
|
||||
void printbytcpserver(String str){}
|
||||
void tcploop(){}
|
||||
#endif
|
||||
|
16
src/wifidebug.h
Normal file
16
src/wifidebug.h
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
#include"Arduino.h"
|
||||
#include"Define.h"
|
||||
#ifdef DebugCalibration
|
||||
#include"WiFi.h"
|
||||
#endif
|
||||
|
||||
void beginWIFI();
|
||||
void printbytcpserver(String str);
|
||||
void tcploop();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
7
weatherslave/.gitignore
vendored
Normal file
7
weatherslave/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
.pio/build
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
/test/
|
||||
/.vscode/
|
46
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit BusIO/.github/ISSUE_TEMPLATE.md
vendored
Normal file
46
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit BusIO/.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
26
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit BusIO/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
26
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit BusIO/.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
32
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit BusIO/.github/workflows/githubci.yml
vendored
Normal file
32
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit BusIO/.github/workflows/githubci.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: Arduino Library CI
|
||||
|
||||
on: [pull_request, push, repository_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: adafruit/ci-arduino
|
||||
path: ci
|
||||
|
||||
- name: pre-install
|
||||
run: bash ci/actions_install.sh
|
||||
|
||||
- name: test platforms
|
||||
run: python3 ci/build_platform.py main_platforms zero feather32u4
|
||||
|
||||
- name: clang
|
||||
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
|
||||
|
||||
- name: doxygen
|
||||
env:
|
||||
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
|
||||
PRETTYNAME : "Adafruit Bus IO Library"
|
||||
run: bash ci/doxy_gen_and_deploy.sh
|
@ -0,0 +1 @@
|
||||
{"type": "library", "name": "Adafruit BusIO", "version": "1.11.4", "spec": {"owner": "adafruit", "id": 6214, "name": "Adafruit BusIO", "requirements": null, "url": null}}
|
@ -0,0 +1,365 @@
|
||||
#include <Adafruit_BusIO_Register.h>
|
||||
|
||||
#if !defined(SPI_INTERFACES_COUNT) || \
|
||||
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
|
||||
|
||||
/*!
|
||||
* @brief Create a register we access over an I2C Device (which defines the
|
||||
* bus and address)
|
||||
* @param i2cdevice The I2CDevice to use for underlying I2C access
|
||||
* @param reg_addr The address pointer value for the I2C/SMBus register, can
|
||||
* be 8 or 16 bits
|
||||
* @param width The width of the register data itself, defaults to 1 byte
|
||||
* @param byteorder The byte order of the register (used when width is > 1),
|
||||
* defaults to LSBFIRST
|
||||
* @param address_width The width of the register address itself, defaults
|
||||
* to 1 byte
|
||||
*/
|
||||
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
|
||||
uint16_t reg_addr,
|
||||
uint8_t width,
|
||||
uint8_t byteorder,
|
||||
uint8_t address_width) {
|
||||
_i2cdevice = i2cdevice;
|
||||
_spidevice = nullptr;
|
||||
_addrwidth = address_width;
|
||||
_address = reg_addr;
|
||||
_byteorder = byteorder;
|
||||
_width = width;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Create a register we access over an SPI Device (which defines the
|
||||
* bus and CS pin)
|
||||
* @param spidevice The SPIDevice to use for underlying SPI access
|
||||
* @param reg_addr The address pointer value for the SPI register, can
|
||||
* be 8 or 16 bits
|
||||
* @param type The method we use to read/write data to SPI (which is not
|
||||
* as well defined as I2C)
|
||||
* @param width The width of the register data itself, defaults to 1 byte
|
||||
* @param byteorder The byte order of the register (used when width is > 1),
|
||||
* defaults to LSBFIRST
|
||||
* @param address_width The width of the register address itself, defaults
|
||||
* to 1 byte
|
||||
*/
|
||||
Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice,
|
||||
uint16_t reg_addr,
|
||||
Adafruit_BusIO_SPIRegType type,
|
||||
uint8_t width,
|
||||
uint8_t byteorder,
|
||||
uint8_t address_width) {
|
||||
_spidevice = spidevice;
|
||||
_spiregtype = type;
|
||||
_i2cdevice = nullptr;
|
||||
_addrwidth = address_width;
|
||||
_address = reg_addr;
|
||||
_byteorder = byteorder;
|
||||
_width = width;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Create a register we access over an I2C or SPI Device. This is a
|
||||
* handy function because we can pass in nullptr for the unused interface,
|
||||
* allowing libraries to mass-define all the registers
|
||||
* @param i2cdevice The I2CDevice to use for underlying I2C access, if
|
||||
* nullptr we use SPI
|
||||
* @param spidevice The SPIDevice to use for underlying SPI access, if
|
||||
* nullptr we use I2C
|
||||
* @param reg_addr The address pointer value for the I2C/SMBus/SPI register,
|
||||
* can be 8 or 16 bits
|
||||
* @param type The method we use to read/write data to SPI (which is not
|
||||
* as well defined as I2C)
|
||||
* @param width The width of the register data itself, defaults to 1 byte
|
||||
* @param byteorder The byte order of the register (used when width is > 1),
|
||||
* defaults to LSBFIRST
|
||||
* @param address_width The width of the register address itself, defaults
|
||||
* to 1 byte
|
||||
*/
|
||||
Adafruit_BusIO_Register::Adafruit_BusIO_Register(
|
||||
Adafruit_I2CDevice *i2cdevice, Adafruit_SPIDevice *spidevice,
|
||||
Adafruit_BusIO_SPIRegType type, uint16_t reg_addr, uint8_t width,
|
||||
uint8_t byteorder, uint8_t address_width) {
|
||||
_spidevice = spidevice;
|
||||
_i2cdevice = i2cdevice;
|
||||
_spiregtype = type;
|
||||
_addrwidth = address_width;
|
||||
_address = reg_addr;
|
||||
_byteorder = byteorder;
|
||||
_width = width;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Write a buffer of data to the register location
|
||||
* @param buffer Pointer to data to write
|
||||
* @param len Number of bytes to write
|
||||
* @return True on successful write (only really useful for I2C as SPI is
|
||||
* uncheckable)
|
||||
*/
|
||||
bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
|
||||
|
||||
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
|
||||
(uint8_t)(_address >> 8)};
|
||||
|
||||
if (_i2cdevice) {
|
||||
return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth);
|
||||
}
|
||||
if (_spidevice) {
|
||||
if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
|
||||
// very special case!
|
||||
|
||||
// pass the special opcode address which we set as the high byte of the
|
||||
// regaddr
|
||||
addrbuffer[0] =
|
||||
(uint8_t)(_address >> 8) & ~0x01; // set bottom bit low to write
|
||||
// the 'actual' reg addr is the second byte then
|
||||
addrbuffer[1] = (uint8_t)(_address & 0xFF);
|
||||
// the address appears to be a byte longer
|
||||
return _spidevice->write(buffer, len, addrbuffer, _addrwidth + 1);
|
||||
}
|
||||
|
||||
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
|
||||
addrbuffer[0] &= ~0x80;
|
||||
}
|
||||
if (_spiregtype == ADDRBIT8_HIGH_TOWRITE) {
|
||||
addrbuffer[0] |= 0x80;
|
||||
}
|
||||
if (_spiregtype == AD8_HIGH_TOREAD_AD7_HIGH_TOINC) {
|
||||
addrbuffer[0] &= ~0x80;
|
||||
addrbuffer[0] |= 0x40;
|
||||
}
|
||||
return _spidevice->write(buffer, len, addrbuffer, _addrwidth);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Write up to 4 bytes of data to the register location
|
||||
* @param value Data to write
|
||||
* @param numbytes How many bytes from 'value' to write
|
||||
* @return True on successful write (only really useful for I2C as SPI is
|
||||
* uncheckable)
|
||||
*/
|
||||
bool Adafruit_BusIO_Register::write(uint32_t value, uint8_t numbytes) {
|
||||
if (numbytes == 0) {
|
||||
numbytes = _width;
|
||||
}
|
||||
if (numbytes > 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// store a copy
|
||||
_cached = value;
|
||||
|
||||
for (int i = 0; i < numbytes; i++) {
|
||||
if (_byteorder == LSBFIRST) {
|
||||
_buffer[i] = value & 0xFF;
|
||||
} else {
|
||||
_buffer[numbytes - i - 1] = value & 0xFF;
|
||||
}
|
||||
value >>= 8;
|
||||
}
|
||||
return write(_buffer, numbytes);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read data from the register location. This does not do any error
|
||||
* checking!
|
||||
* @return Returns 0xFFFFFFFF on failure, value otherwise
|
||||
*/
|
||||
uint32_t Adafruit_BusIO_Register::read(void) {
|
||||
if (!read(_buffer, _width)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t value = 0;
|
||||
|
||||
for (int i = 0; i < _width; i++) {
|
||||
value <<= 8;
|
||||
if (_byteorder == LSBFIRST) {
|
||||
value |= _buffer[_width - i - 1];
|
||||
} else {
|
||||
value |= _buffer[i];
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read cached data from last time we wrote to this register
|
||||
* @return Returns 0xFFFFFFFF on failure, value otherwise
|
||||
*/
|
||||
uint32_t Adafruit_BusIO_Register::readCached(void) { return _cached; }
|
||||
|
||||
/*!
|
||||
* @brief Read a buffer of data from the register location
|
||||
* @param buffer Pointer to data to read into
|
||||
* @param len Number of bytes to read
|
||||
* @return True on successful write (only really useful for I2C as SPI is
|
||||
* uncheckable)
|
||||
*/
|
||||
bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
|
||||
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
|
||||
(uint8_t)(_address >> 8)};
|
||||
|
||||
if (_i2cdevice) {
|
||||
return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
|
||||
}
|
||||
if (_spidevice) {
|
||||
if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
|
||||
// very special case!
|
||||
|
||||
// pass the special opcode address which we set as the high byte of the
|
||||
// regaddr
|
||||
addrbuffer[0] =
|
||||
(uint8_t)(_address >> 8) | 0x01; // set bottom bit high to read
|
||||
// the 'actual' reg addr is the second byte then
|
||||
addrbuffer[1] = (uint8_t)(_address & 0xFF);
|
||||
// the address appears to be a byte longer
|
||||
return _spidevice->write_then_read(addrbuffer, _addrwidth + 1, buffer,
|
||||
len);
|
||||
}
|
||||
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
|
||||
addrbuffer[0] |= 0x80;
|
||||
}
|
||||
if (_spiregtype == ADDRBIT8_HIGH_TOWRITE) {
|
||||
addrbuffer[0] &= ~0x80;
|
||||
}
|
||||
if (_spiregtype == AD8_HIGH_TOREAD_AD7_HIGH_TOINC) {
|
||||
addrbuffer[0] |= 0x80 | 0x40;
|
||||
}
|
||||
return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read 2 bytes of data from the register location
|
||||
* @param value Pointer to uint16_t variable to read into
|
||||
* @return True on successful write (only really useful for I2C as SPI is
|
||||
* uncheckable)
|
||||
*/
|
||||
bool Adafruit_BusIO_Register::read(uint16_t *value) {
|
||||
if (!read(_buffer, 2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_byteorder == LSBFIRST) {
|
||||
*value = _buffer[1];
|
||||
*value <<= 8;
|
||||
*value |= _buffer[0];
|
||||
} else {
|
||||
*value = _buffer[0];
|
||||
*value <<= 8;
|
||||
*value |= _buffer[1];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read 1 byte of data from the register location
|
||||
* @param value Pointer to uint8_t variable to read into
|
||||
* @return True on successful write (only really useful for I2C as SPI is
|
||||
* uncheckable)
|
||||
*/
|
||||
bool Adafruit_BusIO_Register::read(uint8_t *value) {
|
||||
if (!read(_buffer, 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*value = _buffer[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Pretty printer for this register
|
||||
* @param s The Stream to print to, defaults to &Serial
|
||||
*/
|
||||
void Adafruit_BusIO_Register::print(Stream *s) {
|
||||
uint32_t val = read();
|
||||
s->print("0x");
|
||||
s->print(val, HEX);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Pretty printer for this register
|
||||
* @param s The Stream to print to, defaults to &Serial
|
||||
*/
|
||||
void Adafruit_BusIO_Register::println(Stream *s) {
|
||||
print(s);
|
||||
s->println();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Create a slice of the register that we can address without
|
||||
* touching other bits
|
||||
* @param reg The Adafruit_BusIO_Register which defines the bus/register
|
||||
* @param bits The number of bits wide we are slicing
|
||||
* @param shift The number of bits that our bit-slice is shifted from LSB
|
||||
*/
|
||||
Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(
|
||||
Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift) {
|
||||
_register = reg;
|
||||
_bits = bits;
|
||||
_shift = shift;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read 4 bytes of data from the register
|
||||
* @return data The 4 bytes to read
|
||||
*/
|
||||
uint32_t Adafruit_BusIO_RegisterBits::read(void) {
|
||||
uint32_t val = _register->read();
|
||||
val >>= _shift;
|
||||
return val & ((1 << (_bits)) - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Write 4 bytes of data to the register
|
||||
* @param data The 4 bytes to write
|
||||
* @return True on successful write (only really useful for I2C as SPI is
|
||||
* uncheckable)
|
||||
*/
|
||||
bool Adafruit_BusIO_RegisterBits::write(uint32_t data) {
|
||||
uint32_t val = _register->read();
|
||||
|
||||
// mask off the data before writing
|
||||
uint32_t mask = (1 << (_bits)) - 1;
|
||||
data &= mask;
|
||||
|
||||
mask <<= _shift;
|
||||
val &= ~mask; // remove the current data at that spot
|
||||
val |= data << _shift; // and add in the new data
|
||||
|
||||
return _register->write(val, _register->width());
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief The width of the register data, helpful for doing calculations
|
||||
* @returns The data width used when initializing the register
|
||||
*/
|
||||
uint8_t Adafruit_BusIO_Register::width(void) { return _width; }
|
||||
|
||||
/*!
|
||||
* @brief Set the default width of data
|
||||
* @param width the default width of data read from register
|
||||
*/
|
||||
void Adafruit_BusIO_Register::setWidth(uint8_t width) { _width = width; }
|
||||
|
||||
/*!
|
||||
* @brief Set register address
|
||||
* @param address the address from register
|
||||
*/
|
||||
void Adafruit_BusIO_Register::setAddress(uint16_t address) {
|
||||
_address = address;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Set the width of register address
|
||||
* @param address_width the width for register address
|
||||
*/
|
||||
void Adafruit_BusIO_Register::setAddressWidth(uint16_t address_width) {
|
||||
_addrwidth = address_width;
|
||||
}
|
||||
|
||||
#endif // SPI exists
|
@ -0,0 +1,105 @@
|
||||
#ifndef Adafruit_BusIO_Register_h
|
||||
#define Adafruit_BusIO_Register_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#if !defined(SPI_INTERFACES_COUNT) || \
|
||||
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
|
||||
|
||||
#include <Adafruit_I2CDevice.h>
|
||||
#include <Adafruit_SPIDevice.h>
|
||||
|
||||
typedef enum _Adafruit_BusIO_SPIRegType {
|
||||
ADDRBIT8_HIGH_TOREAD = 0,
|
||||
/*!<
|
||||
* ADDRBIT8_HIGH_TOREAD
|
||||
* When reading a register you must actually send the value 0x80 + register
|
||||
* address to the device. e.g. To read the register 0x0B the register value
|
||||
* 0x8B is sent and to write 0x0B is sent.
|
||||
*/
|
||||
AD8_HIGH_TOREAD_AD7_HIGH_TOINC = 1,
|
||||
|
||||
/*!<
|
||||
* ADDRBIT8_HIGH_TOWRITE
|
||||
* When writing to a register you must actually send the value 0x80 +
|
||||
* the register address to the device. e.g. To write to the register 0x19 the
|
||||
* register value 0x99 is sent and to read 0x19 is sent.
|
||||
*/
|
||||
ADDRBIT8_HIGH_TOWRITE = 2,
|
||||
|
||||
/*!<
|
||||
* ADDRESSED_OPCODE_LOWBIT_TO_WRITE
|
||||
* Used by the MCP23S series, we send 0x40 |'rd with the opcode
|
||||
* Then set the lowest bit to write
|
||||
*/
|
||||
ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE = 3,
|
||||
|
||||
} Adafruit_BusIO_SPIRegType;
|
||||
|
||||
/*!
|
||||
* @brief The class which defines a device register (a location to read/write
|
||||
* data from)
|
||||
*/
|
||||
class Adafruit_BusIO_Register {
|
||||
public:
|
||||
Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr,
|
||||
uint8_t width = 1, uint8_t byteorder = LSBFIRST,
|
||||
uint8_t address_width = 1);
|
||||
|
||||
Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr,
|
||||
Adafruit_BusIO_SPIRegType type, uint8_t width = 1,
|
||||
uint8_t byteorder = LSBFIRST,
|
||||
uint8_t address_width = 1);
|
||||
|
||||
Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
|
||||
Adafruit_SPIDevice *spidevice,
|
||||
Adafruit_BusIO_SPIRegType type, uint16_t reg_addr,
|
||||
uint8_t width = 1, uint8_t byteorder = LSBFIRST,
|
||||
uint8_t address_width = 1);
|
||||
|
||||
bool read(uint8_t *buffer, uint8_t len);
|
||||
bool read(uint8_t *value);
|
||||
bool read(uint16_t *value);
|
||||
uint32_t read(void);
|
||||
uint32_t readCached(void);
|
||||
bool write(uint8_t *buffer, uint8_t len);
|
||||
bool write(uint32_t value, uint8_t numbytes = 0);
|
||||
|
||||
uint8_t width(void);
|
||||
|
||||
void setWidth(uint8_t width);
|
||||
void setAddress(uint16_t address);
|
||||
void setAddressWidth(uint16_t address_width);
|
||||
|
||||
void print(Stream *s = &Serial);
|
||||
void println(Stream *s = &Serial);
|
||||
|
||||
private:
|
||||
Adafruit_I2CDevice *_i2cdevice;
|
||||
Adafruit_SPIDevice *_spidevice;
|
||||
Adafruit_BusIO_SPIRegType _spiregtype;
|
||||
uint16_t _address;
|
||||
uint8_t _width, _addrwidth, _byteorder;
|
||||
uint8_t _buffer[4]; // we won't support anything larger than uint32 for
|
||||
// non-buffered read
|
||||
uint32_t _cached = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
* @brief The class which defines a slice of bits from within a device register
|
||||
* (a location to read/write data from)
|
||||
*/
|
||||
class Adafruit_BusIO_RegisterBits {
|
||||
public:
|
||||
Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits,
|
||||
uint8_t shift);
|
||||
bool write(uint32_t value);
|
||||
uint32_t read(void);
|
||||
|
||||
private:
|
||||
Adafruit_BusIO_Register *_register;
|
||||
uint8_t _bits, _shift;
|
||||
};
|
||||
|
||||
#endif // SPI exists
|
||||
#endif // BusIO_Register_h
|
@ -0,0 +1,270 @@
|
||||
#include "Adafruit_I2CDevice.h"
|
||||
|
||||
//#define DEBUG_SERIAL Serial
|
||||
|
||||
/*!
|
||||
* @brief Create an I2C device at a given address
|
||||
* @param addr The 7-bit I2C address for the device
|
||||
* @param theWire The I2C bus to use, defaults to &Wire
|
||||
*/
|
||||
Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
|
||||
_addr = addr;
|
||||
_wire = theWire;
|
||||
_begun = false;
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
_maxBufferSize = 250; // as defined in Wire.h's RingBuffer
|
||||
#else
|
||||
_maxBufferSize = 32;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Initializes and does basic address detection
|
||||
* @param addr_detect Whether we should attempt to detect the I2C address
|
||||
* with a scan. 99% of sensors/devices don't mind but once in a while, they spaz
|
||||
* on a scan!
|
||||
* @return True if I2C initialized and a device with the addr found
|
||||
*/
|
||||
bool Adafruit_I2CDevice::begin(bool addr_detect) {
|
||||
_wire->begin();
|
||||
_begun = true;
|
||||
//Serial.println(addr_detect);
|
||||
if (addr_detect) {
|
||||
return detected();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief De-initialize device, turn off the Wire interface
|
||||
*/
|
||||
void Adafruit_I2CDevice::end(void) {
|
||||
// Not all port implement Wire::end(), such as
|
||||
// - ESP8266
|
||||
// - AVR core without WIRE_HAS_END
|
||||
// - ESP32: end() is implemented since 2.0.1 which is latest at the moment.
|
||||
// Temporarily disable for now to give time for user to update.
|
||||
#if !(defined(ESP8266) || \
|
||||
(defined(ARDUINO_ARCH_AVR) && !defined(WIRE_HAS_END)) || \
|
||||
defined(ARDUINO_ARCH_ESP32))
|
||||
_wire->end();
|
||||
_begun = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Scans I2C for the address - note will give a false-positive
|
||||
* if there's no pullups on I2C
|
||||
* @return True if I2C initialized and a device with the addr found
|
||||
*/
|
||||
bool Adafruit_I2CDevice::detected(void) {
|
||||
// Init I2C if not done yet
|
||||
// Serial.println("sadfasdfasdfsdf");
|
||||
if (!_begun && !begin()) {
|
||||
//Serial.println("sadfasdfasdfsdf");
|
||||
return false;
|
||||
}
|
||||
|
||||
// A basic scanner, see if it ACK's
|
||||
_wire->beginTransmission(_addr);
|
||||
if (_wire->endTransmission() == 0) {
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println(F("Detected"));
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println(F("Not detected"));
|
||||
#endif
|
||||
Serial.println("22222222222222");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Write a buffer or two to the I2C device. Cannot be more than
|
||||
* maxBufferSize() bytes.
|
||||
* @param buffer Pointer to buffer of data to write. This is const to
|
||||
* ensure the content of this buffer doesn't change.
|
||||
* @param len Number of bytes from buffer to write
|
||||
* @param prefix_buffer Pointer to optional array of data to write before
|
||||
* buffer. Cannot be more than maxBufferSize() bytes. This is const to
|
||||
* ensure the content of this buffer doesn't change.
|
||||
* @param prefix_len Number of bytes from prefix buffer to write
|
||||
* @param stop Whether to send an I2C STOP signal on write
|
||||
* @return True if write was successful, otherwise false.
|
||||
*/
|
||||
bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
|
||||
const uint8_t *prefix_buffer,
|
||||
size_t prefix_len) {
|
||||
if ((len + prefix_len) > maxBufferSize()) {
|
||||
// currently not guaranteed to work if more than 32 bytes!
|
||||
// we will need to find out if some platforms have larger
|
||||
// I2C buffer sizes :/
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
_wire->beginTransmission(_addr);
|
||||
|
||||
// Write the prefix data (usually an address)
|
||||
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
|
||||
if (_wire->write(prefix_buffer, prefix_len) != prefix_len) {
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the data itself
|
||||
if (_wire->write(buffer, len) != len) {
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
|
||||
DEBUG_SERIAL.print(F("\tI2CWRITE @ 0x"));
|
||||
DEBUG_SERIAL.print(_addr, HEX);
|
||||
DEBUG_SERIAL.print(F(" :: "));
|
||||
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
|
||||
for (uint16_t i = 0; i < prefix_len; i++) {
|
||||
DEBUG_SERIAL.print(F("0x"));
|
||||
DEBUG_SERIAL.print(prefix_buffer[i], HEX);
|
||||
DEBUG_SERIAL.print(F(", "));
|
||||
}
|
||||
}
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
DEBUG_SERIAL.print(F("0x"));
|
||||
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||
DEBUG_SERIAL.print(F(", "));
|
||||
if (i % 32 == 31) {
|
||||
DEBUG_SERIAL.println();
|
||||
}
|
||||
}
|
||||
|
||||
if (stop) {
|
||||
DEBUG_SERIAL.print("\tSTOP");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (_wire->endTransmission(stop) == 0) {
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println();
|
||||
// DEBUG_SERIAL.println("Sent!");
|
||||
#endif
|
||||
return true;
|
||||
} else {
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.println("\tFailed to send!");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read from I2C into a buffer from the I2C device.
|
||||
* Cannot be more than maxBufferSize() bytes.
|
||||
* @param buffer Pointer to buffer of data to read into
|
||||
* @param len Number of bytes from buffer to read.
|
||||
* @param stop Whether to send an I2C STOP signal on read
|
||||
* @return True if read was successful, otherwise false.
|
||||
*/
|
||||
bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
|
||||
size_t pos = 0;
|
||||
while (pos < len) {
|
||||
size_t read_len =
|
||||
((len - pos) > maxBufferSize()) ? maxBufferSize() : (len - pos);
|
||||
bool read_stop = (pos < (len - read_len)) ? false : stop;
|
||||
if (!_read(buffer + pos, read_len, read_stop))
|
||||
return false;
|
||||
pos += read_len;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Adafruit_I2CDevice::_read(uint8_t *buffer, size_t len, bool stop) {
|
||||
#if defined(TinyWireM_h)
|
||||
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len);
|
||||
#else
|
||||
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
|
||||
#endif
|
||||
|
||||
if (recv != len) {
|
||||
// Not enough data available to fulfill our obligation!
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: "));
|
||||
DEBUG_SERIAL.println(recv);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
buffer[i] = _wire->read();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.print(F("\tI2CREAD @ 0x"));
|
||||
DEBUG_SERIAL.print(_addr, HEX);
|
||||
DEBUG_SERIAL.print(F(" :: "));
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
DEBUG_SERIAL.print(F("0x"));
|
||||
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||
DEBUG_SERIAL.print(F(", "));
|
||||
if (len % 32 == 31) {
|
||||
DEBUG_SERIAL.println();
|
||||
}
|
||||
}
|
||||
DEBUG_SERIAL.println();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Write some data, then read some data from I2C into another buffer.
|
||||
* Cannot be more than maxBufferSize() bytes. The buffers can point to
|
||||
* same/overlapping locations.
|
||||
* @param write_buffer Pointer to buffer of data to write from
|
||||
* @param write_len Number of bytes from buffer to write.
|
||||
* @param read_buffer Pointer to buffer of data to read into.
|
||||
* @param read_len Number of bytes from buffer to read.
|
||||
* @param stop Whether to send an I2C STOP signal between the write and read
|
||||
* @return True if write & read was successful, otherwise false.
|
||||
*/
|
||||
bool Adafruit_I2CDevice::write_then_read(const uint8_t *write_buffer,
|
||||
size_t write_len, uint8_t *read_buffer,
|
||||
size_t read_len, bool stop) {
|
||||
if (!write(write_buffer, write_len, stop)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return read(read_buffer, read_len);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Returns the 7-bit address of this device
|
||||
* @return The 7-bit address of this device
|
||||
*/
|
||||
uint8_t Adafruit_I2CDevice::address(void) { return _addr; }
|
||||
|
||||
/*!
|
||||
* @brief Change the I2C clock speed to desired (relies on
|
||||
* underlying Wire support!
|
||||
* @param desiredclk The desired I2C SCL frequency
|
||||
* @return True if this platform supports changing I2C speed.
|
||||
* Not necessarily that the speed was achieved!
|
||||
*/
|
||||
bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) {
|
||||
#if (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) && !defined(TinyWireM_h)
|
||||
_wire->setClock(desiredclk);
|
||||
return true;
|
||||
#else
|
||||
(void)desiredclk;
|
||||
return false;
|
||||
#endif
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
#ifndef Adafruit_I2CDevice_h
|
||||
#define Adafruit_I2CDevice_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
///< The class which defines how we will talk to this device over I2C
|
||||
class Adafruit_I2CDevice {
|
||||
public:
|
||||
Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire = &Wire);
|
||||
uint8_t address(void);
|
||||
bool begin(bool addr_detect = true);
|
||||
void end(void);
|
||||
bool detected(void);
|
||||
|
||||
bool read(uint8_t *buffer, size_t len, bool stop = true);
|
||||
bool write(const uint8_t *buffer, size_t len, bool stop = true,
|
||||
const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
|
||||
bool write_then_read(const uint8_t *write_buffer, size_t write_len,
|
||||
uint8_t *read_buffer, size_t read_len,
|
||||
bool stop = false);
|
||||
bool setSpeed(uint32_t desiredclk);
|
||||
|
||||
/*! @brief How many bytes we can read in a transaction
|
||||
* @return The size of the Wire receive/transmit buffer */
|
||||
size_t maxBufferSize() { return _maxBufferSize; }
|
||||
|
||||
private:
|
||||
uint8_t _addr;
|
||||
TwoWire *_wire;
|
||||
bool _begun;
|
||||
size_t _maxBufferSize;
|
||||
bool _read(uint8_t *buffer, size_t len, bool stop);
|
||||
};
|
||||
|
||||
#endif // Adafruit_I2CDevice_h
|
@ -0,0 +1,10 @@
|
||||
#ifndef _ADAFRUIT_I2C_REGISTER_H_
|
||||
#define _ADAFRUIT_I2C_REGISTER_H_
|
||||
|
||||
#include <Adafruit_BusIO_Register.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
typedef Adafruit_BusIO_Register Adafruit_I2CRegister;
|
||||
typedef Adafruit_BusIO_RegisterBits Adafruit_I2CRegisterBits;
|
||||
|
||||
#endif
|
@ -0,0 +1,495 @@
|
||||
#include "Adafruit_SPIDevice.h"
|
||||
|
||||
#if !defined(SPI_INTERFACES_COUNT) || \
|
||||
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
|
||||
|
||||
//#define DEBUG_SERIAL Serial
|
||||
|
||||
/*!
|
||||
* @brief Create an SPI device with the given CS pin and settings
|
||||
* @param cspin The arduino pin number to use for chip select
|
||||
* @param freq The SPI clock frequency to use, defaults to 1MHz
|
||||
* @param dataOrder The SPI data order to use for bits within each byte,
|
||||
* defaults to SPI_BITORDER_MSBFIRST
|
||||
* @param dataMode The SPI mode to use, defaults to SPI_MODE0
|
||||
* @param theSPI The SPI bus to use, defaults to &theSPI
|
||||
*/
|
||||
Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq,
|
||||
BusIOBitOrder dataOrder,
|
||||
uint8_t dataMode, SPIClass *theSPI) {
|
||||
_cs = cspin;
|
||||
_sck = _mosi = _miso = -1;
|
||||
_spi = theSPI;
|
||||
_begun = false;
|
||||
_spiSetting = new SPISettings(freq, dataOrder, dataMode);
|
||||
_freq = freq;
|
||||
_dataOrder = dataOrder;
|
||||
_dataMode = dataMode;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Create an SPI device with the given CS pin and settings
|
||||
* @param cspin The arduino pin number to use for chip select
|
||||
* @param sckpin The arduino pin number to use for SCK
|
||||
* @param misopin The arduino pin number to use for MISO, set to -1 if not
|
||||
* used
|
||||
* @param mosipin The arduino pin number to use for MOSI, set to -1 if not
|
||||
* used
|
||||
* @param freq The SPI clock frequency to use, defaults to 1MHz
|
||||
* @param dataOrder The SPI data order to use for bits within each byte,
|
||||
* defaults to SPI_BITORDER_MSBFIRST
|
||||
* @param dataMode The SPI mode to use, defaults to SPI_MODE0
|
||||
*/
|
||||
Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin,
|
||||
int8_t misopin, int8_t mosipin,
|
||||
uint32_t freq, BusIOBitOrder dataOrder,
|
||||
uint8_t dataMode) {
|
||||
_cs = cspin;
|
||||
_sck = sckpin;
|
||||
_miso = misopin;
|
||||
_mosi = mosipin;
|
||||
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
csPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(cspin));
|
||||
csPinMask = digitalPinToBitMask(cspin);
|
||||
if (mosipin != -1) {
|
||||
mosiPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(mosipin));
|
||||
mosiPinMask = digitalPinToBitMask(mosipin);
|
||||
}
|
||||
if (misopin != -1) {
|
||||
misoPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(misopin));
|
||||
misoPinMask = digitalPinToBitMask(misopin);
|
||||
}
|
||||
clkPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(sckpin));
|
||||
clkPinMask = digitalPinToBitMask(sckpin);
|
||||
#endif
|
||||
|
||||
_freq = freq;
|
||||
_dataOrder = dataOrder;
|
||||
_dataMode = dataMode;
|
||||
_begun = false;
|
||||
_spiSetting = new SPISettings(freq, dataOrder, dataMode);
|
||||
_spi = nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Release memory allocated in constructors
|
||||
*/
|
||||
Adafruit_SPIDevice::~Adafruit_SPIDevice() { delete _spiSetting; }
|
||||
|
||||
/*!
|
||||
* @brief Initializes SPI bus and sets CS pin high
|
||||
* @return Always returns true because there's no way to test success of SPI
|
||||
* init
|
||||
*/
|
||||
bool Adafruit_SPIDevice::begin(void) {
|
||||
if (_cs != -1) {
|
||||
pinMode(_cs, OUTPUT);
|
||||
digitalWrite(_cs, HIGH);
|
||||
}
|
||||
|
||||
if (_spi) { // hardware SPI
|
||||
_spi->begin();
|
||||
} else {
|
||||
pinMode(_sck, OUTPUT);
|
||||
|
||||
if ((_dataMode == SPI_MODE0) || (_dataMode == SPI_MODE1)) {
|
||||
// idle low on mode 0 and 1
|
||||
digitalWrite(_sck, LOW);
|
||||
} else {
|
||||
// idle high on mode 2 or 3
|
||||
digitalWrite(_sck, HIGH);
|
||||
}
|
||||
if (_mosi != -1) {
|
||||
pinMode(_mosi, OUTPUT);
|
||||
digitalWrite(_mosi, HIGH);
|
||||
}
|
||||
if (_miso != -1) {
|
||||
pinMode(_miso, INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
_begun = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Transfer (send/receive) one byte over hard/soft SPI
|
||||
* @param buffer The buffer to send and receive at the same time
|
||||
* @param len The number of bytes to transfer
|
||||
*/
|
||||
void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
|
||||
if (_spi) {
|
||||
// hardware SPI is easy
|
||||
|
||||
#if defined(SPARK)
|
||||
_spi->transfer(buffer, buffer, len, nullptr);
|
||||
#elif defined(STM32)
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
_spi->transfer(buffer[i]);
|
||||
}
|
||||
#else
|
||||
_spi->transfer(buffer, len);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t startbit;
|
||||
if (_dataOrder == SPI_BITORDER_LSBFIRST) {
|
||||
startbit = 0x1;
|
||||
} else {
|
||||
startbit = 0x80;
|
||||
}
|
||||
|
||||
bool towrite, lastmosi = !(buffer[0] & startbit);
|
||||
uint8_t bitdelay_us = (1000000 / _freq) / 2;
|
||||
|
||||
// for softSPI we'll do it by hand
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
// software SPI
|
||||
uint8_t reply = 0;
|
||||
uint8_t send = buffer[i];
|
||||
|
||||
/*
|
||||
Serial.print("\tSending software SPI byte 0x");
|
||||
Serial.print(send, HEX);
|
||||
Serial.print(" -> 0x");
|
||||
*/
|
||||
|
||||
// Serial.print(send, HEX);
|
||||
for (uint8_t b = startbit; b != 0;
|
||||
b = (_dataOrder == SPI_BITORDER_LSBFIRST) ? b << 1 : b >> 1) {
|
||||
|
||||
if (bitdelay_us) {
|
||||
delayMicroseconds(bitdelay_us);
|
||||
}
|
||||
|
||||
if (_dataMode == SPI_MODE0 || _dataMode == SPI_MODE2) {
|
||||
towrite = send & b;
|
||||
if ((_mosi != -1) && (lastmosi != towrite)) {
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
if (towrite)
|
||||
*mosiPort |= mosiPinMask;
|
||||
else
|
||||
*mosiPort &= ~mosiPinMask;
|
||||
#else
|
||||
digitalWrite(_mosi, towrite);
|
||||
#endif
|
||||
lastmosi = towrite;
|
||||
}
|
||||
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
*clkPort |= clkPinMask; // Clock high
|
||||
#else
|
||||
digitalWrite(_sck, HIGH);
|
||||
#endif
|
||||
|
||||
if (bitdelay_us) {
|
||||
delayMicroseconds(bitdelay_us);
|
||||
}
|
||||
|
||||
if (_miso != -1) {
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
if (*misoPort & misoPinMask) {
|
||||
#else
|
||||
if (digitalRead(_miso)) {
|
||||
#endif
|
||||
reply |= b;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
*clkPort &= ~clkPinMask; // Clock low
|
||||
#else
|
||||
digitalWrite(_sck, LOW);
|
||||
#endif
|
||||
} else { // if (_dataMode == SPI_MODE1 || _dataMode == SPI_MODE3)
|
||||
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
*clkPort |= clkPinMask; // Clock high
|
||||
#else
|
||||
digitalWrite(_sck, HIGH);
|
||||
#endif
|
||||
|
||||
if (bitdelay_us) {
|
||||
delayMicroseconds(bitdelay_us);
|
||||
}
|
||||
|
||||
if (_mosi != -1) {
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
if (send & b)
|
||||
*mosiPort |= mosiPinMask;
|
||||
else
|
||||
*mosiPort &= ~mosiPinMask;
|
||||
#else
|
||||
digitalWrite(_mosi, send & b);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
*clkPort &= ~clkPinMask; // Clock low
|
||||
#else
|
||||
digitalWrite(_sck, LOW);
|
||||
#endif
|
||||
|
||||
if (_miso != -1) {
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
if (*misoPort & misoPinMask) {
|
||||
#else
|
||||
if (digitalRead(_miso)) {
|
||||
#endif
|
||||
reply |= b;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_miso != -1) {
|
||||
buffer[i] = reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Transfer (send/receive) one byte over hard/soft SPI
|
||||
* @param send The byte to send
|
||||
* @return The byte received while transmitting
|
||||
*/
|
||||
uint8_t Adafruit_SPIDevice::transfer(uint8_t send) {
|
||||
uint8_t data = send;
|
||||
transfer(&data, 1);
|
||||
return data;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Manually begin a transaction (calls beginTransaction if hardware
|
||||
* SPI)
|
||||
*/
|
||||
void Adafruit_SPIDevice::beginTransaction(void) {
|
||||
if (_spi) {
|
||||
_spi->beginTransaction(*_spiSetting);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Manually end a transaction (calls endTransaction if hardware SPI)
|
||||
*/
|
||||
void Adafruit_SPIDevice::endTransaction(void) {
|
||||
if (_spi) {
|
||||
_spi->endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Write a buffer or two to the SPI device.
|
||||
* @param buffer Pointer to buffer of data to write
|
||||
* @param len Number of bytes from buffer to write
|
||||
* @param prefix_buffer Pointer to optional array of data to write before
|
||||
* buffer.
|
||||
* @param prefix_len Number of bytes from prefix buffer to write
|
||||
* @return Always returns true because there's no way to test success of SPI
|
||||
* writes
|
||||
*/
|
||||
bool Adafruit_SPIDevice::write(const uint8_t *buffer, size_t len,
|
||||
const uint8_t *prefix_buffer,
|
||||
size_t prefix_len) {
|
||||
if (_spi) {
|
||||
_spi->beginTransaction(*_spiSetting);
|
||||
}
|
||||
|
||||
setChipSelect(LOW);
|
||||
// do the writing
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (_spi) {
|
||||
if (prefix_len > 0) {
|
||||
_spi->transferBytes(prefix_buffer, nullptr, prefix_len);
|
||||
}
|
||||
if (len > 0) {
|
||||
_spi->transferBytes(buffer, nullptr, len);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
for (size_t i = 0; i < prefix_len; i++) {
|
||||
transfer(prefix_buffer[i]);
|
||||
}
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
transfer(buffer[i]);
|
||||
}
|
||||
}
|
||||
setChipSelect(HIGH);
|
||||
|
||||
if (_spi) {
|
||||
_spi->endTransaction();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
|
||||
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
|
||||
for (uint16_t i = 0; i < prefix_len; i++) {
|
||||
DEBUG_SERIAL.print(F("0x"));
|
||||
DEBUG_SERIAL.print(prefix_buffer[i], HEX);
|
||||
DEBUG_SERIAL.print(F(", "));
|
||||
}
|
||||
}
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
DEBUG_SERIAL.print(F("0x"));
|
||||
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||
DEBUG_SERIAL.print(F(", "));
|
||||
if (i % 32 == 31) {
|
||||
DEBUG_SERIAL.println();
|
||||
}
|
||||
}
|
||||
DEBUG_SERIAL.println();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Read from SPI into a buffer from the SPI device.
|
||||
* @param buffer Pointer to buffer of data to read into
|
||||
* @param len Number of bytes from buffer to read.
|
||||
* @param sendvalue The 8-bits of data to write when doing the data read,
|
||||
* defaults to 0xFF
|
||||
* @return Always returns true because there's no way to test success of SPI
|
||||
* writes
|
||||
*/
|
||||
bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
|
||||
memset(buffer, sendvalue, len); // clear out existing buffer
|
||||
if (_spi) {
|
||||
_spi->beginTransaction(*_spiSetting);
|
||||
}
|
||||
|
||||
setChipSelect(LOW);
|
||||
transfer(buffer, len);
|
||||
setChipSelect(HIGH);
|
||||
|
||||
if (_spi) {
|
||||
_spi->endTransaction();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
DEBUG_SERIAL.print(F("0x"));
|
||||
DEBUG_SERIAL.print(buffer[i], HEX);
|
||||
DEBUG_SERIAL.print(F(", "));
|
||||
if (len % 32 == 31) {
|
||||
DEBUG_SERIAL.println();
|
||||
}
|
||||
}
|
||||
DEBUG_SERIAL.println();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Write some data, then read some data from SPI into another buffer.
|
||||
* The buffers can point to same/overlapping locations. This does not
|
||||
* transmit-receive at the same time!
|
||||
* @param write_buffer Pointer to buffer of data to write from
|
||||
* @param write_len Number of bytes from buffer to write.
|
||||
* @param read_buffer Pointer to buffer of data to read into.
|
||||
* @param read_len Number of bytes from buffer to read.
|
||||
* @param sendvalue The 8-bits of data to write when doing the data read,
|
||||
* defaults to 0xFF
|
||||
* @return Always returns true because there's no way to test success of SPI
|
||||
* writes
|
||||
*/
|
||||
bool Adafruit_SPIDevice::write_then_read(const uint8_t *write_buffer,
|
||||
size_t write_len, uint8_t *read_buffer,
|
||||
size_t read_len, uint8_t sendvalue) {
|
||||
if (_spi) {
|
||||
_spi->beginTransaction(*_spiSetting);
|
||||
}
|
||||
|
||||
setChipSelect(LOW);
|
||||
// do the writing
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (_spi) {
|
||||
if (write_len > 0) {
|
||||
_spi->transferBytes(write_buffer, nullptr, write_len);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
for (size_t i = 0; i < write_len; i++) {
|
||||
transfer(write_buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
|
||||
for (uint16_t i = 0; i < write_len; i++) {
|
||||
DEBUG_SERIAL.print(F("0x"));
|
||||
DEBUG_SERIAL.print(write_buffer[i], HEX);
|
||||
DEBUG_SERIAL.print(F(", "));
|
||||
if (write_len % 32 == 31) {
|
||||
DEBUG_SERIAL.println();
|
||||
}
|
||||
}
|
||||
DEBUG_SERIAL.println();
|
||||
#endif
|
||||
|
||||
// do the reading
|
||||
for (size_t i = 0; i < read_len; i++) {
|
||||
read_buffer[i] = transfer(sendvalue);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
|
||||
for (uint16_t i = 0; i < read_len; i++) {
|
||||
DEBUG_SERIAL.print(F("0x"));
|
||||
DEBUG_SERIAL.print(read_buffer[i], HEX);
|
||||
DEBUG_SERIAL.print(F(", "));
|
||||
if (read_len % 32 == 31) {
|
||||
DEBUG_SERIAL.println();
|
||||
}
|
||||
}
|
||||
DEBUG_SERIAL.println();
|
||||
#endif
|
||||
|
||||
setChipSelect(HIGH);
|
||||
|
||||
if (_spi) {
|
||||
_spi->endTransaction();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Write some data and read some data at the same time from SPI
|
||||
* into the same buffer. This is basicaly a wrapper for transfer() with
|
||||
* CS-pin and transaction management.
|
||||
* This /does/ transmit-receive at the same time!
|
||||
* @param buffer Pointer to buffer of data to write/read to/from
|
||||
* @param len Number of bytes from buffer to write/read.
|
||||
* @return Always returns true because there's no way to test success of SPI
|
||||
* writes
|
||||
*/
|
||||
bool Adafruit_SPIDevice::write_and_read(uint8_t *buffer, size_t len) {
|
||||
if (_spi) {
|
||||
_spi->beginTransaction(*_spiSetting);
|
||||
}
|
||||
|
||||
setChipSelect(LOW);
|
||||
transfer(buffer, len);
|
||||
setChipSelect(HIGH);
|
||||
|
||||
if (_spi) {
|
||||
_spi->endTransaction();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Adafruit_SPIDevice::setChipSelect(int value) {
|
||||
if (_cs == -1)
|
||||
return;
|
||||
digitalWrite(_cs, value);
|
||||
}
|
||||
|
||||
#endif // SPI exists
|
@ -0,0 +1,109 @@
|
||||
#ifndef Adafruit_SPIDevice_h
|
||||
#define Adafruit_SPIDevice_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#if !defined(SPI_INTERFACES_COUNT) || \
|
||||
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
// some modern SPI definitions don't have BitOrder enum
|
||||
#if (defined(__AVR__) && !defined(ARDUINO_ARCH_MEGAAVR)) || \
|
||||
defined(ESP8266) || defined(TEENSYDUINO) || defined(SPARK) || \
|
||||
defined(ARDUINO_ARCH_SPRESENSE) || defined(MEGATINYCORE) || \
|
||||
defined(DXCORE) || defined(ARDUINO_AVR_ATmega4809) || \
|
||||
defined(ARDUINO_AVR_ATmega4808) || defined(ARDUINO_AVR_ATmega3209) || \
|
||||
defined(ARDUINO_AVR_ATmega3208) || defined(ARDUINO_AVR_ATmega1609) || \
|
||||
defined(ARDUINO_AVR_ATmega1608) || defined(ARDUINO_AVR_ATmega809) || \
|
||||
defined(ARDUINO_AVR_ATmega808) || defined(ARDUINO_ARCH_ARC32)
|
||||
|
||||
typedef enum _BitOrder {
|
||||
SPI_BITORDER_MSBFIRST = MSBFIRST,
|
||||
SPI_BITORDER_LSBFIRST = LSBFIRST,
|
||||
} BusIOBitOrder;
|
||||
|
||||
#elif defined(ESP32) || defined(__ASR6501__) || defined(__ASR6502__)
|
||||
|
||||
// some modern SPI definitions don't have BitOrder enum and have different SPI
|
||||
// mode defines
|
||||
typedef enum _BitOrder {
|
||||
SPI_BITORDER_MSBFIRST = SPI_MSBFIRST,
|
||||
SPI_BITORDER_LSBFIRST = SPI_LSBFIRST,
|
||||
} BusIOBitOrder;
|
||||
|
||||
#else
|
||||
// Some platforms have a BitOrder enum but its named MSBFIRST/LSBFIRST
|
||||
#define SPI_BITORDER_MSBFIRST MSBFIRST
|
||||
#define SPI_BITORDER_LSBFIRST LSBFIRST
|
||||
typedef BitOrder BusIOBitOrder;
|
||||
#endif
|
||||
|
||||
#if defined(__AVR__) || defined(TEENSYDUINO)
|
||||
typedef volatile uint8_t BusIO_PortReg;
|
||||
typedef uint8_t BusIO_PortMask;
|
||||
#define BUSIO_USE_FAST_PINIO
|
||||
|
||||
#elif defined(ESP8266) || defined(ESP32) || defined(__SAM3X8E__) || \
|
||||
defined(ARDUINO_ARCH_SAMD)
|
||||
typedef volatile uint32_t BusIO_PortReg;
|
||||
typedef uint32_t BusIO_PortMask;
|
||||
#define BUSIO_USE_FAST_PINIO
|
||||
|
||||
#elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) && \
|
||||
!defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_RP2040)
|
||||
typedef volatile uint32_t BusIO_PortReg;
|
||||
typedef uint32_t BusIO_PortMask;
|
||||
#if !defined(__ASR6501__) && !defined(__ASR6502__)
|
||||
#define BUSIO_USE_FAST_PINIO
|
||||
#endif
|
||||
|
||||
#else
|
||||
#undef BUSIO_USE_FAST_PINIO
|
||||
#endif
|
||||
|
||||
/**! The class which defines how we will talk to this device over SPI **/
|
||||
class Adafruit_SPIDevice {
|
||||
public:
|
||||
Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
|
||||
BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
|
||||
uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = &SPI);
|
||||
|
||||
Adafruit_SPIDevice(int8_t cspin, int8_t sck, int8_t miso, int8_t mosi,
|
||||
uint32_t freq = 1000000,
|
||||
BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
|
||||
uint8_t dataMode = SPI_MODE0);
|
||||
~Adafruit_SPIDevice();
|
||||
|
||||
bool begin(void);
|
||||
bool read(uint8_t *buffer, size_t len, uint8_t sendvalue = 0xFF);
|
||||
bool write(const uint8_t *buffer, size_t len,
|
||||
const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
|
||||
bool write_then_read(const uint8_t *write_buffer, size_t write_len,
|
||||
uint8_t *read_buffer, size_t read_len,
|
||||
uint8_t sendvalue = 0xFF);
|
||||
bool write_and_read(uint8_t *buffer, size_t len);
|
||||
|
||||
uint8_t transfer(uint8_t send);
|
||||
void transfer(uint8_t *buffer, size_t len);
|
||||
void beginTransaction(void);
|
||||
void endTransaction(void);
|
||||
|
||||
private:
|
||||
SPIClass *_spi;
|
||||
SPISettings *_spiSetting;
|
||||
uint32_t _freq;
|
||||
BusIOBitOrder _dataOrder;
|
||||
uint8_t _dataMode;
|
||||
void setChipSelect(int value);
|
||||
|
||||
int8_t _cs, _sck, _mosi, _miso;
|
||||
#ifdef BUSIO_USE_FAST_PINIO
|
||||
BusIO_PortReg *mosiPort, *clkPort, *misoPort, *csPort;
|
||||
BusIO_PortMask mosiPinMask, misoPinMask, clkPinMask, csPinMask;
|
||||
#endif
|
||||
bool _begun;
|
||||
};
|
||||
|
||||
#endif // has SPI defined
|
||||
#endif // Adafruit_SPIDevice_h
|
@ -0,0 +1,11 @@
|
||||
# Adafruit Bus IO Library
|
||||
# https://github.com/adafruit/Adafruit_BusIO
|
||||
# MIT License
|
||||
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
idf_component_register(SRCS "Adafruit_I2CDevice.cpp" "Adafruit_BusIO_Register.cpp" "Adafruit_SPIDevice.cpp"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES arduino)
|
||||
|
||||
project(Adafruit_BusIO)
|
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Adafruit Industries
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -0,0 +1,8 @@
|
||||
# Adafruit Bus IO Library [](https://github.com/adafruit/Adafruit_BusIO/actions)
|
||||
|
||||
|
||||
This is a helper library to abstract away I2C & SPI transactions and registers
|
||||
|
||||
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
|
||||
|
||||
MIT license, all text above must be included in any redistribution
|
@ -0,0 +1 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS = .
|
@ -0,0 +1,21 @@
|
||||
#include <Adafruit_I2CDevice.h>
|
||||
|
||||
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(0x10);
|
||||
|
||||
void setup() {
|
||||
while (!Serial) { delay(10); }
|
||||
Serial.begin(115200);
|
||||
Serial.println("I2C address detection test");
|
||||
|
||||
if (!i2c_dev.begin()) {
|
||||
Serial.print("Did not find device at 0x");
|
||||
Serial.println(i2c_dev.address(), HEX);
|
||||
while (1);
|
||||
}
|
||||
Serial.print("Device found on address 0x");
|
||||
Serial.println(i2c_dev.address(), HEX);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
#include <Adafruit_I2CDevice.h>
|
||||
|
||||
#define I2C_ADDRESS 0x60
|
||||
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
|
||||
|
||||
|
||||
void setup() {
|
||||
while (!Serial) { delay(10); }
|
||||
Serial.begin(115200);
|
||||
Serial.println("I2C device read and write test");
|
||||
|
||||
if (!i2c_dev.begin()) {
|
||||
Serial.print("Did not find device at 0x");
|
||||
Serial.println(i2c_dev.address(), HEX);
|
||||
while (1);
|
||||
}
|
||||
Serial.print("Device found on address 0x");
|
||||
Serial.println(i2c_dev.address(), HEX);
|
||||
|
||||
uint8_t buffer[32];
|
||||
// Try to read 32 bytes
|
||||
i2c_dev.read(buffer, 32);
|
||||
Serial.print("Read: ");
|
||||
for (uint8_t i=0; i<32; i++) {
|
||||
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// read a register by writing first, then reading
|
||||
buffer[0] = 0x0C; // we'll reuse the same buffer
|
||||
i2c_dev.write_then_read(buffer, 1, buffer, 2, false);
|
||||
Serial.print("Write then Read: ");
|
||||
for (uint8_t i=0; i<2; i++) {
|
||||
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#include <Adafruit_I2CDevice.h>
|
||||
#include <Adafruit_BusIO_Register.h>
|
||||
|
||||
#define I2C_ADDRESS 0x60
|
||||
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
|
||||
|
||||
|
||||
void setup() {
|
||||
while (!Serial) { delay(10); }
|
||||
Serial.begin(115200);
|
||||
Serial.println("I2C device register test");
|
||||
|
||||
if (!i2c_dev.begin()) {
|
||||
Serial.print("Did not find device at 0x");
|
||||
Serial.println(i2c_dev.address(), HEX);
|
||||
while (1);
|
||||
}
|
||||
Serial.print("Device found on address 0x");
|
||||
Serial.println(i2c_dev.address(), HEX);
|
||||
|
||||
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST);
|
||||
uint16_t id;
|
||||
id_reg.read(&id);
|
||||
Serial.print("ID register = 0x"); Serial.println(id, HEX);
|
||||
|
||||
Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST);
|
||||
uint16_t thresh;
|
||||
thresh_reg.read(&thresh);
|
||||
Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX);
|
||||
|
||||
thresh_reg.write(~thresh);
|
||||
|
||||
Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#include <Adafruit_BusIO_Register.h>
|
||||
|
||||
// Define which interface to use by setting the unused interface to NULL!
|
||||
|
||||
#define SPIDEVICE_CS 10
|
||||
Adafruit_SPIDevice *spi_dev = NULL; // new Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||
|
||||
#define I2C_ADDRESS 0x5D
|
||||
Adafruit_I2CDevice *i2c_dev = new Adafruit_I2CDevice(I2C_ADDRESS);
|
||||
|
||||
void setup() {
|
||||
while (!Serial) { delay(10); }
|
||||
Serial.begin(115200);
|
||||
Serial.println("I2C or SPI device register test");
|
||||
|
||||
if (spi_dev && !spi_dev->begin()) {
|
||||
Serial.println("Could not initialize SPI device");
|
||||
}
|
||||
|
||||
if (i2c_dev) {
|
||||
if (i2c_dev->begin()) {
|
||||
Serial.print("Device found on I2C address 0x");
|
||||
Serial.println(i2c_dev->address(), HEX);
|
||||
} else {
|
||||
Serial.print("Did not find I2C device at 0x");
|
||||
Serial.println(i2c_dev->address(), HEX);
|
||||
}
|
||||
}
|
||||
|
||||
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F);
|
||||
uint8_t id=0;
|
||||
id_reg.read(&id);
|
||||
Serial.print("ID register = 0x"); Serial.println(id, HEX);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
#include <Adafruit_SPIDevice.h>
|
||||
|
||||
#define SPIDEVICE_CS 10
|
||||
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
|
||||
//Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
|
||||
|
||||
|
||||
void setup() {
|
||||
while (!Serial) { delay(10); }
|
||||
Serial.begin(115200);
|
||||
Serial.println("SPI device mode test");
|
||||
|
||||
if (!spi_dev.begin()) {
|
||||
Serial.println("Could not initialize SPI device");
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.println("\n\nTransfer test");
|
||||
for (uint16_t x=0; x<=0xFF; x++) {
|
||||
uint8_t i = x;
|
||||
Serial.print("0x"); Serial.print(i, HEX);
|
||||
spi_dev.read(&i, 1, i);
|
||||
Serial.print("/"); Serial.print(i, HEX);
|
||||
Serial.print(", ");
|
||||
delay(25);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
#include <Adafruit_SPIDevice.h>
|
||||
|
||||
#define SPIDEVICE_CS 10
|
||||
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||
|
||||
|
||||
void setup() {
|
||||
while (!Serial) { delay(10); }
|
||||
Serial.begin(115200);
|
||||
Serial.println("SPI device read and write test");
|
||||
|
||||
if (!spi_dev.begin()) {
|
||||
Serial.println("Could not initialize SPI device");
|
||||
while (1);
|
||||
}
|
||||
|
||||
uint8_t buffer[32];
|
||||
|
||||
// Try to read 32 bytes
|
||||
spi_dev.read(buffer, 32);
|
||||
Serial.print("Read: ");
|
||||
for (uint8_t i=0; i<32; i++) {
|
||||
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// read a register by writing first, then reading
|
||||
buffer[0] = 0x8F; // we'll reuse the same buffer
|
||||
spi_dev.write_then_read(buffer, 1, buffer, 2, false);
|
||||
Serial.print("Write then Read: ");
|
||||
for (uint8_t i=0; i<2; i++) {
|
||||
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
@ -0,0 +1,192 @@
|
||||
/***************************************************
|
||||
|
||||
This is an example for how to use Adafruit_BusIO_RegisterBits from Adafruit_BusIO library.
|
||||
|
||||
Designed specifically to work with the Adafruit RTD Sensor
|
||||
----> https://www.adafruit.com/products/3328
|
||||
uisng a MAX31865 RTD-to-Digital Converter
|
||||
----> https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf
|
||||
|
||||
This sensor uses SPI to communicate, 4 pins are required to
|
||||
interface.
|
||||
A fifth pin helps to detect when a new conversion is ready.
|
||||
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Example written (2020/3) by Andreas Hardtung/AnHard.
|
||||
BSD license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#include <Adafruit_BusIO_Register.h>
|
||||
#include <Adafruit_SPIDevice.h>
|
||||
|
||||
#define MAX31865_SPI_SPEED (5000000)
|
||||
#define MAX31865_SPI_BITORDER (SPI_BITORDER_MSBFIRST)
|
||||
#define MAX31865_SPI_MODE (SPI_MODE1)
|
||||
|
||||
#define MAX31865_SPI_CS (10)
|
||||
#define MAX31865_READY_PIN (2)
|
||||
|
||||
|
||||
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE, &SPI); // Hardware SPI
|
||||
// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software SPI
|
||||
|
||||
// MAX31865 chip related *********************************************************************************************
|
||||
Adafruit_BusIO_Register config_reg = Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
|
||||
Adafruit_BusIO_RegisterBits bias_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 7);
|
||||
Adafruit_BusIO_RegisterBits auto_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 6);
|
||||
Adafruit_BusIO_RegisterBits oneS_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 5);
|
||||
Adafruit_BusIO_RegisterBits wire_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 4);
|
||||
Adafruit_BusIO_RegisterBits faultT_bits = Adafruit_BusIO_RegisterBits(&config_reg, 2, 2);
|
||||
Adafruit_BusIO_RegisterBits faultR_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 1);
|
||||
Adafruit_BusIO_RegisterBits fi50hz_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 0);
|
||||
|
||||
Adafruit_BusIO_Register rRatio_reg = Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
|
||||
Adafruit_BusIO_RegisterBits rRatio_bits = Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1);
|
||||
Adafruit_BusIO_RegisterBits fault_bit = Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0);
|
||||
|
||||
Adafruit_BusIO_Register maxRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
|
||||
Adafruit_BusIO_RegisterBits maxRratio_bits = Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1);
|
||||
|
||||
Adafruit_BusIO_Register minRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
|
||||
Adafruit_BusIO_RegisterBits minRratio_bits = Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1);
|
||||
|
||||
Adafruit_BusIO_Register fault_reg = Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
|
||||
Adafruit_BusIO_RegisterBits range_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7);
|
||||
Adafruit_BusIO_RegisterBits range_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6);
|
||||
Adafruit_BusIO_RegisterBits refin_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5);
|
||||
Adafruit_BusIO_RegisterBits refin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4);
|
||||
Adafruit_BusIO_RegisterBits rtdin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3);
|
||||
Adafruit_BusIO_RegisterBits voltage_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2);
|
||||
|
||||
// Print the details of the configuration register.
|
||||
void printConfig( void ) {
|
||||
Serial.print("BIAS: "); if (bias_bit.read() ) Serial.print("ON"); else Serial.print("OFF");
|
||||
Serial.print(", AUTO: "); if (auto_bit.read() ) Serial.print("ON"); else Serial.print("OFF");
|
||||
Serial.print(", ONES: "); if (oneS_bit.read() ) Serial.print("ON"); else Serial.print("OFF");
|
||||
Serial.print(", WIRE: "); if (wire_bit.read() ) Serial.print("3"); else Serial.print("2/4");
|
||||
Serial.print(", FAULTCLEAR: "); if (faultR_bit.read() ) Serial.print("ON"); else Serial.print("OFF");
|
||||
Serial.print(", "); if (fi50hz_bit.read() ) Serial.print("50HZ"); else Serial.print("60HZ");
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
// Check and print faults. Then clear them.
|
||||
void checkFaults( void ) {
|
||||
if (fault_bit.read()) {
|
||||
Serial.print("MAX: "); Serial.println(maxRratio_bits.read());
|
||||
Serial.print("VAL: "); Serial.println( rRatio_bits.read());
|
||||
Serial.print("MIN: "); Serial.println(minRratio_bits.read());
|
||||
|
||||
if (range_high_fault_bit.read() ) Serial.println("Range high fault");
|
||||
if ( range_low_fault_bit.read() ) Serial.println("Range low fault");
|
||||
if (refin_high_fault_bit.read() ) Serial.println("REFIN high fault");
|
||||
if ( refin_low_fault_bit.read() ) Serial.println("REFIN low fault");
|
||||
if ( rtdin_low_fault_bit.read() ) Serial.println("RTDIN low fault");
|
||||
if ( voltage_fault_bit.read() ) Serial.println("Voltage fault");
|
||||
|
||||
faultR_bit.write(1); // clear fault
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
#if (MAX31865_1_READY_PIN != -1)
|
||||
pinMode(MAX31865_READY_PIN ,INPUT_PULLUP);
|
||||
#endif
|
||||
|
||||
while (!Serial) { delay(10); }
|
||||
Serial.begin(115200);
|
||||
Serial.println("SPI Adafruit_BusIO_RegisterBits test on MAX31865");
|
||||
|
||||
if (!spi_dev.begin()) {
|
||||
Serial.println("Could not initialize SPI device");
|
||||
while (1);
|
||||
}
|
||||
|
||||
// Set up for automode 50Hz. We don't care about selfheating. We want the highest possible sampling rate.
|
||||
auto_bit.write(0); // Don't switch filtermode while auto_mode is on.
|
||||
fi50hz_bit.write(1); // Set filter to 50Hz mode.
|
||||
faultR_bit.write(1); // Clear faults.
|
||||
bias_bit.write(1); // In automode we want to have the bias current always on.
|
||||
delay(5); // Wait until bias current settles down.
|
||||
// 10.5 time constants of the input RC network is required.
|
||||
// 10ms worst case for 10kω reference resistor and a 0.1µF capacitor across the RTD inputs.
|
||||
// Adafruit Module has 0.1µF and only 430/4300ω So here 0.43/4.3ms
|
||||
auto_bit.write(1); // Now we can set automode. Automatically starting first conversion.
|
||||
|
||||
// Test the READY_PIN
|
||||
#if (defined( MAX31865_READY_PIN ) && (MAX31865_READY_PIN != -1))
|
||||
int i = 0;
|
||||
while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) { delay(1); }
|
||||
if (i >= 100) {
|
||||
Serial.print("ERROR: Max31865 Pin detection does not work. PIN:");
|
||||
Serial.println(MAX31865_READY_PIN);
|
||||
}
|
||||
#else
|
||||
delay(100);
|
||||
#endif
|
||||
|
||||
// Set ratio range.
|
||||
// Setting the temperatures would need some more calculation - not related to Adafruit_BusIO_RegisterBits.
|
||||
uint16_t ratio = rRatio_bits.read();
|
||||
maxRratio_bits.write( (ratio < 0x8fffu-1000u) ? ratio + 1000u : 0x8fffu );
|
||||
minRratio_bits.write( (ratio > 1000u) ? ratio - 1000u : 0u );
|
||||
|
||||
printConfig();
|
||||
checkFaults();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
#if (defined( MAX31865_READY_PIN ) && (MAX31865_1_READY_PIN != -1))
|
||||
// Is conversion ready?
|
||||
if (!digitalRead(MAX31865_READY_PIN))
|
||||
#else
|
||||
// Warant conversion is ready.
|
||||
delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode.
|
||||
#endif
|
||||
{
|
||||
// Read ratio, calculate temperature, scale, filter and print.
|
||||
Serial.println( rRatio2C( rRatio_bits.read() ) * 100.0f, 0); // Temperature scaled by 100
|
||||
// Check, print, clear faults.
|
||||
checkFaults();
|
||||
}
|
||||
|
||||
// Do something else.
|
||||
//delay(15000);
|
||||
}
|
||||
|
||||
|
||||
// Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C *****************************
|
||||
float rRatio2C(uint16_t ratio) {
|
||||
// A simple linear conversion.
|
||||
const float R0 = 100.0f;
|
||||
const float Rref = 430.0f;
|
||||
const float alphaPT = 0.003850f;
|
||||
const float ADCmax = (1u << 15) - 1.0f;
|
||||
const float rscale = Rref / ADCmax;
|
||||
// Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C.
|
||||
// Measured temperature in ice/water bath 0.76°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C.
|
||||
//const float a = 1.0f / (alphaPT * R0);
|
||||
const float a = (100.0f/101.08f) / (alphaPT * R0);
|
||||
//const float b = 0.0f; // 101.08
|
||||
const float b = -0.76f; // 100.32 > 101.08
|
||||
|
||||
return filterRing( ((ratio * rscale) - R0) * a + b );
|
||||
}
|
||||
|
||||
// General purpose *********************************************************************************************
|
||||
#define RINGLENGTH 250
|
||||
float filterRing( float newVal ) {
|
||||
static float ring[RINGLENGTH] = { 0.0 };
|
||||
static uint8_t ringIndex = 0;
|
||||
static bool ringFull = false;
|
||||
|
||||
if ( ringIndex == RINGLENGTH ) { ringFull = true; ringIndex = 0; }
|
||||
ring[ringIndex] = newVal;
|
||||
uint8_t loopEnd = (ringFull) ? RINGLENGTH : ringIndex + 1;
|
||||
float ringSum = 0.0f;
|
||||
for (uint8_t i = 0; i < loopEnd; i++) ringSum += ring[i];
|
||||
ringIndex++;
|
||||
return ringSum / loopEnd;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
#include <Adafruit_BusIO_Register.h>
|
||||
#include <Adafruit_SPIDevice.h>
|
||||
|
||||
#define SPIDEVICE_CS 10
|
||||
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
|
||||
|
||||
void setup() {
|
||||
while (!Serial) { delay(10); }
|
||||
Serial.begin(115200);
|
||||
Serial.println("SPI device register test");
|
||||
|
||||
if (!spi_dev.begin()) {
|
||||
Serial.println("Could not initialize SPI device");
|
||||
while (1);
|
||||
}
|
||||
|
||||
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD);
|
||||
uint8_t id = 0;
|
||||
id_reg.read(&id);
|
||||
Serial.print("ID register = 0x"); Serial.println(id, HEX);
|
||||
|
||||
Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST);
|
||||
uint16_t thresh = 0;
|
||||
thresh_reg.read(&thresh);
|
||||
Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX);
|
||||
|
||||
thresh_reg.write(~thresh);
|
||||
|
||||
Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
name=Adafruit BusIO
|
||||
version=1.11.4
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=This is a library for abstracting away UART, I2C and SPI interfacing
|
||||
paragraph=This is a library for abstracting away UART, I2C and SPI interfacing
|
||||
category=Signal Input/Output
|
||||
url=https://github.com/adafruit/Adafruit_BusIO
|
||||
architectures=*
|
46
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit MLX90614 Library/.github/ISSUE_TEMPLATE.md
vendored
Normal file
46
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit MLX90614 Library/.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
Thank you for opening an issue on an Adafruit Arduino library repository. To
|
||||
improve the speed of resolution please review the following guidelines and
|
||||
common troubleshooting steps below before creating the issue:
|
||||
|
||||
- **Do not use GitHub issues for troubleshooting projects and issues.** Instead use
|
||||
the forums at http://forums.adafruit.com to ask questions and troubleshoot why
|
||||
something isn't working as expected. In many cases the problem is a common issue
|
||||
that you will more quickly receive help from the forum community. GitHub issues
|
||||
are meant for known defects in the code. If you don't know if there is a defect
|
||||
in the code then start with troubleshooting on the forum first.
|
||||
|
||||
- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
|
||||
check all of the steps and commands to run have been followed. Consult the
|
||||
forum if you're unsure or have questions about steps in a guide/tutorial.
|
||||
|
||||
- **For Arduino projects check these very common issues to ensure they don't apply**:
|
||||
|
||||
- For uploading sketches or communicating with the board make sure you're using
|
||||
a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes
|
||||
very hard to tell the difference between a data and charge cable! Try using the
|
||||
cable with other devices or swapping to another cable to confirm it is not
|
||||
the problem.
|
||||
|
||||
- **Be sure you are supplying adequate power to the board.** Check the specs of
|
||||
your board and plug in an external power supply. In many cases just
|
||||
plugging a board into your computer is not enough to power it and other
|
||||
peripherals.
|
||||
|
||||
- **Double check all soldering joints and connections.** Flakey connections
|
||||
cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
|
||||
|
||||
- **Ensure you are using an official Arduino or Adafruit board.** We can't
|
||||
guarantee a clone board will have the same functionality and work as expected
|
||||
with this code and don't support them.
|
||||
|
||||
If you're sure this issue is a defect in the code and checked the steps above
|
||||
please fill in the following fields to provide enough troubleshooting information.
|
||||
You may delete the guideline and text above to just leave the following details:
|
||||
|
||||
- Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE**
|
||||
|
||||
- Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO
|
||||
VERSION HERE**
|
||||
|
||||
- List the steps to reproduce the problem below (if possible attach a sketch or
|
||||
copy the sketch code in too): **LIST REPRO STEPS BELOW**
|
@ -0,0 +1,26 @@
|
||||
Thank you for creating a pull request to contribute to Adafruit's GitHub code!
|
||||
Before you open the request please review the following guidelines and tips to
|
||||
help it be more easily integrated:
|
||||
|
||||
- **Describe the scope of your change--i.e. what the change does and what parts
|
||||
of the code were modified.** This will help us understand any risks of integrating
|
||||
the code.
|
||||
|
||||
- **Describe any known limitations with your change.** For example if the change
|
||||
doesn't apply to a supported platform of the library please mention it.
|
||||
|
||||
- **Please run any tests or examples that can exercise your modified code.** We
|
||||
strive to not break users of the code and running tests/examples helps with this
|
||||
process.
|
||||
|
||||
Thank you again for contributing! We will try to test and integrate the change
|
||||
as soon as we can, but be aware we have many GitHub repositories to manage and
|
||||
can't immediately respond to every request. There is no need to bump or check in
|
||||
on a pull request (it will clutter the discussion of the request).
|
||||
|
||||
Also don't be worried if the request is closed or not integrated--sometimes the
|
||||
priorities of Adafruit's GitHub code (education, ease of use) might not match the
|
||||
priorities of the pull request. Don't fret, the open source community thrives on
|
||||
forks and GitHub makes it easy to keep your changes in a forked repo.
|
||||
|
||||
After reviewing the guidelines above you can delete this text from the pull request.
|
32
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit MLX90614 Library/.github/workflows/githubci.yml
vendored
Normal file
32
weatherslave/.pio/libdeps/esp_wroom_02/Adafruit MLX90614 Library/.github/workflows/githubci.yml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: Arduino Library CI
|
||||
|
||||
on: [pull_request, push, repository_dispatch]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: adafruit/ci-arduino
|
||||
path: ci
|
||||
|
||||
- name: pre-install
|
||||
run: bash ci/actions_install.sh
|
||||
|
||||
- name: test platforms
|
||||
run: python3 ci/build_platform.py main_platforms
|
||||
|
||||
- name: clang
|
||||
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
|
||||
|
||||
- name: doxygen
|
||||
env:
|
||||
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
|
||||
PRETTYNAME : "Adafruit MLX90614 Arduino Library"
|
||||
run: bash ci/doxy_gen_and_deploy.sh
|
@ -0,0 +1 @@
|
||||
{"type": "library", "name": "Adafruit MLX90614 Library", "version": "2.1.3", "spec": {"owner": "adafruit", "id": 782, "name": "Adafruit MLX90614 Library", "requirements": null, "url": null}}
|
@ -0,0 +1,175 @@
|
||||
/***************************************************
|
||||
This is a library for the MLX90614 Temp Sensor
|
||||
|
||||
Designed specifically to work with the MLX90614 sensors in the
|
||||
adafruit shop
|
||||
----> https://www.adafruit.com/products/1747 (3V)
|
||||
----> https://www.adafruit.com/products/1748 (5V)
|
||||
|
||||
These sensors use I2C to communicate, 2 pins are required to
|
||||
interface
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#include "Adafruit_MLX90614.h"
|
||||
|
||||
Adafruit_MLX90614::~Adafruit_MLX90614() {
|
||||
if (i2c_dev)
|
||||
delete i2c_dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Begin the I2C connection
|
||||
* @param addr I2C address for the device.
|
||||
* @param wire Pointer to Wire instance
|
||||
* @return True if the device was successfully initialized, otherwise false.
|
||||
*/
|
||||
bool Adafruit_MLX90614::begin(uint8_t addr, TwoWire *wire) {
|
||||
_addr = addr; // needed for CRC
|
||||
if (i2c_dev)
|
||||
delete i2c_dev;
|
||||
i2c_dev = new Adafruit_I2CDevice(addr, wire);
|
||||
return i2c_dev->begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the raw value from the emissivity register
|
||||
*
|
||||
* @return uint16_t The unscaled emissivity value or '0' if reading failed
|
||||
*/
|
||||
uint16_t Adafruit_MLX90614::readEmissivityReg(void) {
|
||||
return read16(MLX90614_EMISS);
|
||||
}
|
||||
/**
|
||||
* @brief Write the raw unscaled emissivity value to the emissivity register
|
||||
*
|
||||
* @param ereg The unscaled emissivity value
|
||||
*/
|
||||
void Adafruit_MLX90614::writeEmissivityReg(uint16_t ereg) {
|
||||
write16(MLX90614_EMISS, 0); // erase
|
||||
delay(10);
|
||||
write16(MLX90614_EMISS, ereg);
|
||||
delay(10);
|
||||
}
|
||||
/**
|
||||
* @brief Read the emissivity value from the sensor's register and scale
|
||||
*
|
||||
* @return double The emissivity value, ranging from 0.1 - 1.0 or NAN if reading
|
||||
* failed
|
||||
*/
|
||||
double Adafruit_MLX90614::readEmissivity(void) {
|
||||
uint16_t ereg = read16(MLX90614_EMISS);
|
||||
if (ereg == 0)
|
||||
return NAN;
|
||||
return ((double)ereg) / 65535.0;
|
||||
}
|
||||
/**
|
||||
* @brief Set the emissivity value
|
||||
*
|
||||
* @param emissivity The emissivity value to use, between 0.1 and 1.0
|
||||
*/
|
||||
void Adafruit_MLX90614::writeEmissivity(double emissivity) {
|
||||
uint16_t ereg = (uint16_t)(0xffff * emissivity);
|
||||
|
||||
writeEmissivityReg(ereg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current temperature of an object in degrees Farenheit
|
||||
*
|
||||
* @return double The temperature in degrees Farenheit or NAN if reading failed
|
||||
*/
|
||||
double Adafruit_MLX90614::readObjectTempF(void) {
|
||||
return (readTemp(MLX90614_TOBJ1) * 9 / 5) + 32;
|
||||
}
|
||||
/**
|
||||
* @brief Get the current ambient temperature in degrees Farenheit
|
||||
*
|
||||
* @return double The temperature in degrees Farenheit or NAN if reading failed
|
||||
*/
|
||||
double Adafruit_MLX90614::readAmbientTempF(void) {
|
||||
return (readTemp(MLX90614_TA) * 9 / 5) + 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current temperature of an object in degrees Celcius
|
||||
*
|
||||
* @return double The temperature in degrees Celcius or NAN if reading failed
|
||||
*/
|
||||
double Adafruit_MLX90614::readObjectTempC(void) {
|
||||
return readTemp(MLX90614_TOBJ1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the current ambient temperature in degrees Celcius
|
||||
*
|
||||
* @return double The temperature in degrees Celcius or NAN if reading failed
|
||||
*/
|
||||
double Adafruit_MLX90614::readAmbientTempC(void) {
|
||||
return readTemp(MLX90614_TA);
|
||||
}
|
||||
|
||||
float Adafruit_MLX90614::readTemp(uint8_t reg) {
|
||||
float temp;
|
||||
|
||||
temp = read16(reg);
|
||||
if (temp == 0)
|
||||
return NAN;
|
||||
temp *= .02;
|
||||
temp -= 273.15;
|
||||
return temp;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
uint16_t Adafruit_MLX90614::read16(uint8_t a) {
|
||||
uint8_t buffer[3];
|
||||
buffer[0] = a;
|
||||
// read two bytes of data + pec
|
||||
bool status = i2c_dev->write_then_read(buffer, 1, buffer, 3);
|
||||
if (!status)
|
||||
return 0;
|
||||
// return data, ignore pec
|
||||
return uint16_t(buffer[0]) | (uint16_t(buffer[1]) << 8);
|
||||
}
|
||||
|
||||
byte Adafruit_MLX90614::crc8(byte *addr, byte len)
|
||||
// The PEC calculation includes all bits except the START, REPEATED START, STOP,
|
||||
// ACK, and NACK bits. The PEC is a CRC-8 with polynomial X8+X2+X1+1.
|
||||
{
|
||||
byte crc = 0;
|
||||
while (len--) {
|
||||
byte inbyte = *addr++;
|
||||
for (byte i = 8; i; i--) {
|
||||
byte carry = (crc ^ inbyte) & 0x80;
|
||||
crc <<= 1;
|
||||
if (carry)
|
||||
crc ^= 0x7;
|
||||
inbyte <<= 1;
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
void Adafruit_MLX90614::write16(uint8_t a, uint16_t v) {
|
||||
uint8_t buffer[4];
|
||||
|
||||
buffer[0] = _addr << 1;
|
||||
buffer[1] = a;
|
||||
buffer[2] = v & 0xff;
|
||||
buffer[3] = v >> 8;
|
||||
|
||||
uint8_t pec = crc8(buffer, 4);
|
||||
|
||||
buffer[0] = buffer[1];
|
||||
buffer[1] = buffer[2];
|
||||
buffer[2] = buffer[3];
|
||||
buffer[3] = pec;
|
||||
|
||||
i2c_dev->write(buffer, 4);
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/***************************************************
|
||||
This is a library for the MLX90614 Temp Sensor
|
||||
|
||||
Designed specifically to work with the MLX90614 sensors in the
|
||||
adafruit shop
|
||||
----> https://www.adafruit.com/products/1747 (3V)
|
||||
----> https://www.adafruit.com/products/1748 (5V)
|
||||
|
||||
These sensors use I2C to communicate, 2 pins are required to
|
||||
interface
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#include <Adafruit_I2CDevice.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#define MLX90614_I2CADDR 0x5A
|
||||
|
||||
// RAM
|
||||
#define MLX90614_RAWIR1 0x04
|
||||
#define MLX90614_RAWIR2 0x05
|
||||
#define MLX90614_TA 0x06
|
||||
#define MLX90614_TOBJ1 0x07
|
||||
#define MLX90614_TOBJ2 0x08
|
||||
// EEPROM
|
||||
#define MLX90614_TOMAX 0x20
|
||||
#define MLX90614_TOMIN 0x21
|
||||
#define MLX90614_PWMCTRL 0x22
|
||||
#define MLX90614_TARANGE 0x23
|
||||
#define MLX90614_EMISS 0x24
|
||||
#define MLX90614_CONFIG 0x25
|
||||
#define MLX90614_ADDR 0x2E
|
||||
#define MLX90614_ID1 0x3C
|
||||
#define MLX90614_ID2 0x3D
|
||||
#define MLX90614_ID3 0x3E
|
||||
#define MLX90614_ID4 0x3F
|
||||
|
||||
/**
|
||||
* @brief Class to read from and control a MLX90614 Temp Sensor
|
||||
*
|
||||
*/
|
||||
class Adafruit_MLX90614 {
|
||||
public:
|
||||
~Adafruit_MLX90614();
|
||||
bool begin(uint8_t addr = MLX90614_I2CADDR, TwoWire *wire = &Wire);
|
||||
|
||||
double readObjectTempC(void);
|
||||
double readAmbientTempC(void);
|
||||
double readObjectTempF(void);
|
||||
double readAmbientTempF(void);
|
||||
uint16_t readEmissivityReg(void);
|
||||
void writeEmissivityReg(uint16_t ereg);
|
||||
double readEmissivity(void);
|
||||
void writeEmissivity(double emissivity);
|
||||
|
||||
private:
|
||||
Adafruit_I2CDevice *i2c_dev = NULL; ///< Pointer to I2C bus interface
|
||||
float readTemp(uint8_t reg);
|
||||
|
||||
uint16_t read16(uint8_t addr);
|
||||
void write16(uint8_t addr, uint16_t data);
|
||||
byte crc8(byte *addr, byte len);
|
||||
uint8_t _addr;
|
||||
};
|
@ -0,0 +1,51 @@
|
||||
# Adafruit-MLX90614-Library [](https://github.com/adafruit/Adafruit-MLX90614-Library/actions)[](http://adafruit.github.io/Adafruit-MLX90614-Library/html/index.html)
|
||||
|
||||
This is a library for the MLX90614 temperature sensor
|
||||
|
||||
<a href="https://www.adafruit.com/products/1747"><img src="https://cdn-shop.adafruit.com/970x728/1747-00.jpg" width="500px"></a>
|
||||
|
||||
Designed and tested to work with the MLX90614 sensors in the adafruit shop
|
||||
* https://www.adafruit.com/products/1747 3V version
|
||||
* https://www.adafruit.com/products/1748 5V version
|
||||
|
||||
Check out the links above for our tutorials and wiring diagrams
|
||||
|
||||
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
|
||||
|
||||
# Installation
|
||||
To install, use the Arduino Library Manager and search for "Adafruit-MLX90614-Library" and install the library.
|
||||
|
||||
# Contributing
|
||||
|
||||
Contributions are welcome! Please read our [Code of Conduct](https://github.com/adafruit/Adafruit-MLX90614-Library/blob/master/CODE_OF_CONDUCT.md>)
|
||||
before contributing to help this project stay welcoming.
|
||||
|
||||
## Documentation and doxygen
|
||||
Documentation is produced by doxygen. Contributions should include documentation for any new code added.
|
||||
|
||||
Some examples of how to use doxygen can be found in these guide pages:
|
||||
|
||||
https://learn.adafruit.com/the-well-automated-arduino-library/doxygen
|
||||
|
||||
https://learn.adafruit.com/the-well-automated-arduino-library/doxygen-tips
|
||||
|
||||
## Formatting and clang-format
|
||||
This library uses [`clang-format`](https://releases.llvm.org/download.html) to standardize the formatting of `.cpp` and `.h` files.
|
||||
Contributions should be formatted using `clang-format`:
|
||||
|
||||
The `-i` flag will make the changes to the file.
|
||||
```bash
|
||||
clang-format -i *.cpp *.h
|
||||
```
|
||||
If you prefer to make the changes yourself, running `clang-format` without the `-i` flag will print out a formatted version of the file. You can save this to a file and diff it against the original to see the changes.
|
||||
|
||||
Note that the formatting output by `clang-format` is what the automated formatting checker will expect. Any diffs from this formatting will result in a failed build until they are addressed. Using the `-i` flag is highly recommended.
|
||||
|
||||
### clang-format resources
|
||||
* [Binary builds and source available on the LLVM downloads page](https://releases.llvm.org/download.html)
|
||||
* [Documentation and IDE integration](https://clang.llvm.org/docs/ClangFormat.html)
|
||||
|
||||
## About this Driver
|
||||
Written by Limor Fried for Adafruit Industries.
|
||||
BSD license, check license.txt for more information
|
||||
All text above must be included in any redistribution
|
@ -0,0 +1,127 @@
|
||||
# Adafruit Community Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and leaders pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, gender identity and expression, level or type of
|
||||
experience, education, socio-economic status, nationality, personal appearance,
|
||||
race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
We are committed to providing a friendly, safe and welcoming environment for
|
||||
all.
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Be kind and courteous to others
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Collaborating with other community members
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and sexual attention or advances
|
||||
* The use of inappropriate images, including in a community member's avatar
|
||||
* The use of inappropriate language, including in a community member's nickname
|
||||
* Any spamming, flaming, baiting or other attention-stealing behavior
|
||||
* Excessive or unwelcome helping; answering outside the scope of the question
|
||||
asked
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate
|
||||
|
||||
The goal of the standards and moderation guidelines outlined here is to build
|
||||
and maintain a respectful community. We ask that you don’t just aim to be
|
||||
"technically unimpeachable", but rather try to be your best self.
|
||||
|
||||
We value many things beyond technical expertise, including collaboration and
|
||||
supporting others within our community. Providing a positive experience for
|
||||
other community members can have a much more significant impact than simply
|
||||
providing the correct answer.
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project leaders are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project leaders have the right and responsibility to remove, edit, or
|
||||
reject messages, comments, commits, code, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any community member for other behaviors that they deem
|
||||
inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Moderation
|
||||
|
||||
Instances of behaviors that violate the Adafruit Community Code of Conduct
|
||||
may be reported by any member of the community. Community members are
|
||||
encouraged to report these situations, including situations they witness
|
||||
involving other community members.
|
||||
|
||||
You may report in the following ways:
|
||||
|
||||
In any situation, you may send an email to <support@adafruit.com>.
|
||||
|
||||
On the Adafruit Discord, you may send an open message from any channel
|
||||
to all Community Helpers by tagging @community helpers. You may also send an
|
||||
open message from any channel, or a direct message to @kattni#1507,
|
||||
@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or
|
||||
@Andon#8175.
|
||||
|
||||
Email and direct message reports will be kept confidential.
|
||||
|
||||
In situations on Discord where the issue is particularly egregious, possibly
|
||||
illegal, requires immediate action, or violates the Discord terms of service,
|
||||
you should also report the message directly to Discord.
|
||||
|
||||
These are the steps for upholding our community’s standards of conduct.
|
||||
|
||||
1. Any member of the community may report any situation that violates the
|
||||
Adafruit Community Code of Conduct. All reports will be reviewed and
|
||||
investigated.
|
||||
2. If the behavior is an egregious violation, the community member who
|
||||
committed the violation may be banned immediately, without warning.
|
||||
3. Otherwise, moderators will first respond to such behavior with a warning.
|
||||
4. Moderators follow a soft "three strikes" policy - the community member may
|
||||
be given another chance, if they are receptive to the warning and change their
|
||||
behavior.
|
||||
5. If the community member is unreceptive or unreasonable when warned by a
|
||||
moderator, or the warning goes unheeded, they may be banned for a first or
|
||||
second offense. Repeated offenses will result in the community member being
|
||||
banned.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct and the enforcement policies listed above apply to all
|
||||
Adafruit Community venues. This includes but is not limited to any community
|
||||
spaces (both public and private), the entire Adafruit Discord server, and
|
||||
Adafruit GitHub repositories. Examples of Adafruit Community spaces include
|
||||
but are not limited to meet-ups, audio chats on the Adafruit Discord, or
|
||||
interaction at a conference.
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. As a community
|
||||
member, you are representing our community, and are expected to behave
|
||||
accordingly.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 1.4, available at
|
||||
<https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>,
|
||||
and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html).
|
||||
|
||||
For other projects adopting the Adafruit Community Code of
|
||||
Conduct, please contact the maintainers of those projects for enforcement.
|
||||
If you wish to use this code of conduct for your own project, consider
|
||||
explicitly mentioning your moderation policy or making a copy with your
|
||||
own moderation policy so as to avoid confusion.
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* See app note:
|
||||
* https://www.melexis.com/en/documents/documentation/application-notes/application-note-mlx90614-changing-emissivity-setting
|
||||
*
|
||||
* 1. Write 0x0000 to address 0x04 (erase the EEPROM cell)
|
||||
* 2. Write the new value to address 0x04
|
||||
* 3. Read the value in address 0x04 in order to check that the correct value is stored
|
||||
* 4. Restart the module
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Adafruit_MLX90614.h>
|
||||
|
||||
//== CHANGE THIS ============
|
||||
double new_emissivity = 0.95;
|
||||
//===========================
|
||||
|
||||
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while (!Serial);
|
||||
|
||||
Serial.println("Adafruit MLX90614 Emissivity Setter.\n");
|
||||
|
||||
// init sensor
|
||||
if (!mlx.begin()) {
|
||||
Serial.println("Error connecting to MLX sensor. Check wiring.");
|
||||
while (1);
|
||||
};
|
||||
|
||||
// read current emissivity
|
||||
Serial.print("Current emissivity = "); Serial.println(mlx.readEmissivity());
|
||||
|
||||
// set new emissivity
|
||||
Serial.print("Setting emissivity = "); Serial.println(new_emissivity);
|
||||
mlx.writeEmissivity(new_emissivity); // this does the 0x0000 erase write
|
||||
|
||||
// read back
|
||||
Serial.print("New emissivity = "); Serial.println(mlx.readEmissivity());
|
||||
|
||||
// done
|
||||
Serial.print("DONE. Restart the module.");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/***************************************************
|
||||
This is a library example for the MLX90614 Temp Sensor
|
||||
|
||||
Designed specifically to work with the MLX90614 sensors in the
|
||||
adafruit shop
|
||||
----> https://www.adafruit.com/products/1747 3V version
|
||||
----> https://www.adafruit.com/products/1748 5V version
|
||||
|
||||
These sensors use I2C to communicate, 2 pins are required to
|
||||
interface
|
||||
Adafruit invests time and resources providing this open source code,
|
||||
please support Adafruit and open-source hardware by purchasing
|
||||
products from Adafruit!
|
||||
|
||||
Written by Limor Fried/Ladyada for Adafruit Industries.
|
||||
BSD license, all text above must be included in any redistribution
|
||||
****************************************************/
|
||||
|
||||
#include <Adafruit_MLX90614.h>
|
||||
|
||||
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while (!Serial);
|
||||
|
||||
Serial.println("Adafruit MLX90614 test");
|
||||
|
||||
if (!mlx.begin()) {
|
||||
Serial.println("Error connecting to MLX sensor. Check wiring.");
|
||||
while (1);
|
||||
};
|
||||
|
||||
Serial.print("Emissivity = "); Serial.println(mlx.readEmissivity());
|
||||
Serial.println("================================================");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempC());
|
||||
Serial.print("*C\tObject = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C");
|
||||
Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempF());
|
||||
Serial.print("*F\tObject = "); Serial.print(mlx.readObjectTempF()); Serial.println("*F");
|
||||
|
||||
Serial.println();
|
||||
delay(500);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
name=Adafruit MLX90614 Library
|
||||
version=2.1.3
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <info@adafruit.com>
|
||||
sentence=Arduino library for the MLX90614 sensors in the Adafruit shop
|
||||
paragraph=Arduino library for the MLX90614 sensors in the Adafruit shop
|
||||
category=Sensors
|
||||
url=https://github.com/adafruit/Adafruit-MLX90614-Library
|
||||
architectures=*
|
||||
depends=Adafruit BusIO
|
@ -0,0 +1,26 @@
|
||||
Software License Agreement (BSD License)
|
||||
|
||||
Copyright (c) 2020 Limor Fried for Adafruit Industries
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holders nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2
weatherslave/.pio/libdeps/esp_wroom_02/SparkFun u-blox Arduino Library/.gitattributes
vendored
Normal file
2
weatherslave/.pio/libdeps/esp_wroom_02/SparkFun u-blox Arduino Library/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
58
weatherslave/.pio/libdeps/esp_wroom_02/SparkFun u-blox Arduino Library/.gitignore
vendored
Normal file
58
weatherslave/.pio/libdeps/esp_wroom_02/SparkFun u-blox Arduino Library/.gitignore
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
# Visual Studio Code files
|
||||
.vscode
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# =========================
|
||||
# Operating System Files
|
||||
# =========================
|
||||
|
||||
# OSX
|
||||
# =========================
|
||||
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# VIM backup files
|
||||
*~
|
||||
[._]*.un~
|
||||
*.swp
|
||||
|
||||
# Zephyr build files
|
||||
examples/Zephyr/*/build/*
|
@ -0,0 +1 @@
|
||||
{"type": "library", "name": "SparkFun u-blox Arduino Library", "version": "1.8.11", "spec": {"owner": "sparkfun", "id": 5746, "name": "SparkFun u-blox Arduino Library", "requirements": null, "uri": null}}
|
@ -0,0 +1,20 @@
|
||||
# How to Contribute
|
||||
|
||||
Thank you so *much* for offering to help out. We truly appreciate it.
|
||||
|
||||
If you'd like to contribute, start by searching through the [issues](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/issues) and [pull requests](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/pulls) to see whether someone else has raised a similar idea or question.
|
||||
Please check the [closed issues](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/issues?q=is%3Aissue+is%3Aclosed)
|
||||
and [closed pull requests](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/pulls?q=is%3Apr+is%3Aclosed) too - you may find that your issue or feature has already been discussed.
|
||||
|
||||
If you decide to add a feature to this library, please create a PR and follow these best practices:
|
||||
|
||||
* Change as little as possible. Do not submit a PR that changes 100 lines of whitespace. Break up into multiple PRs if necessary.
|
||||
* If you've added a new feature document it with a simple example sketch. This serves both as a test of your PR and as a quick way for users to quickly learn how to use your new feature.
|
||||
* If you add new functions also add them to _keywords.txt_ so that they are properly highlighted in Arduino. [Read more](https://www.arduino.cc/en/Hacking/libraryTutorial).
|
||||
* **Important:** Please submit your PR using the [release_candidate branch](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/tree/release_candidate). That way, we can merge and test your PR quickly without changing the _master_ branch
|
||||
|
||||

|
||||
|
||||
## Style guide
|
||||
|
||||
Please read and follow the [Arduino API style guide](https://www.arduino.cc/en/Reference/APIStyleGuide). Also read and consider the [Arduino style guide](https://www.arduino.cc/en/Reference/StyleGuide).
|
@ -0,0 +1,18 @@
|
||||
### Subject of the issue
|
||||
Describe your issue here. If you reference a datasheet please specify which one and in which section (ie, the protocol manual, section 5.1.2). Additionally, screenshots are easy to paste into github.
|
||||
|
||||
### Your workbench
|
||||
* What development board or microcontroller are you using?
|
||||
* What version of hardware or breakout board are you using?
|
||||
* How is the breakout board wired to your microcontroller?
|
||||
* How is everything being powered?
|
||||
* Are there any additional details that may help us help you?
|
||||
|
||||
### Steps to reproduce
|
||||
Tell us how to reproduce this issue. Please post stripped down example code demonstrating your issue.
|
||||
|
||||
### Expected behavior
|
||||
Tell us what should happen
|
||||
|
||||
### Actual behavior
|
||||
Tell us what happens instead
|
@ -0,0 +1,55 @@
|
||||
SparkFun License Information
|
||||
============================
|
||||
|
||||
SparkFun uses two different licenses for our files — one for hardware and one for code.
|
||||
|
||||
Hardware
|
||||
---------
|
||||
|
||||
**SparkFun hardware is released under [Creative Commons Share-alike 4.0 International](http://creativecommons.org/licenses/by-sa/4.0/).**
|
||||
|
||||
Note: This is a human-readable summary of (and not a substitute for) the [license](http://creativecommons.org/licenses/by-sa/4.0/legalcode).
|
||||
|
||||
You are free to:
|
||||
|
||||
Share — copy and redistribute the material in any medium or format
|
||||
Adapt — remix, transform, and build upon the material
|
||||
for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
|
||||
No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits.
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary for your intended use. For example, other rights such as publicity, privacy, or moral rights may limit how you use the material.
|
||||
|
||||
|
||||
Code
|
||||
--------
|
||||
|
||||
**SparkFun code, firmware, and software is released under the MIT License(http://opensource.org/licenses/MIT).**
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 SparkFun Electronics
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -0,0 +1,163 @@
|
||||
SparkFun u-blox Arduino Library
|
||||
===========================================================
|
||||
|
||||
**Please note: this library is now deprecated. Please migrate to the new [SparkFun u-blox GNSS Arduino Library](https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library).**
|
||||
|
||||
**You can find details on how to migrate to v2.0 [here](https://github.com/sparkfun/SparkFun_u-blox_GNSS_Arduino_Library#migrating-to-v20).**
|
||||
|
||||
You can install v2.0 via the Arduino Library Manager. Search for **SparkFun u-blox GNSS**.
|
||||
|
||||
<table class="table table-hover table-striped table-bordered">
|
||||
<tr align="center">
|
||||
<td><a href="https://www.sparkfun.com/products/15136"><img src="https://cdn.sparkfun.com//assets/parts/1/3/5/1/4/15136-SparkFun_GPS-RTK2_Board_-_ZED-F9P__Qwiic_-03.jpg"></a></td>
|
||||
<td><a href="https://www.sparkfun.com/products/15005"><img src="https://cdn.sparkfun.com//assets/parts/1/3/3/2/0/15005-SparkFun_GPS-RTK__Qwiic__-_NEO-M8P-2-00.jpg"></a></td>
|
||||
<td><a href="https://www.sparkfun.com/products/15193"><img src="https://cdn.sparkfun.com//assets/parts/1/3/6/1/4/15193-SparkFun_GPS_Breakout_-_U.FL__ZOE-M8__Qwiic_-01.jpg"></a></td>
|
||||
<td><a href="https://www.sparkfun.com/products/15210"><img src="https://cdn.sparkfun.com//assets/parts/1/3/6/4/8/15210-SparkFun_GPS_Breakout_-_Chip_Antenna__SAM-M8Q__Qwiic_-01.jpg"></a></td>
|
||||
<td><a href="https://www.sparkfun.com/products/15733"><img src="https://cdn.sparkfun.com//assets/parts/1/4/3/2/2/15733-SparkFun_GPS_Breakout_-_NEO-M9N__Chip_Antenna__Qwiic_-01.jpg"></a></td>
|
||||
</tr>
|
||||
<tr align="center">
|
||||
<td><a href="https://www.sparkfun.com/products/15136">SparkFun GPS-RTK2 - ZED-F9P (GPS-15136)</a></td>
|
||||
<td><a href="https://www.sparkfun.com/products/15005">SparkFun GPS-RTK - NEO-M8P-2 (GPS-15005)</a></td>
|
||||
<td><a href="https://www.sparkfun.com/products/15193">SparkFun ZOE-M8Q Breakout (GPS-15193)</a></td>
|
||||
<td><a href="https://www.sparkfun.com/products/15210">SparkFun SAM-M8Q Breakout (GPS-15210)</a></td>
|
||||
<td><a href="https://www.sparkfun.com/products/15733">SparkFun NEO-M9N Breakout (GPS-15733)</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
U-blox makes some incredible GPS receivers covering everything from low-cost, highly configurable modules such as the SAM-M8Q all the way up to the surveyor grade ZED-F9P with precision of the diameter of a dime. This library focuses on configuration and control of u-blox devices over I2C (called DDC by u-blox) and Serial. The UBX protocol is supported over both I2C and serial, and is a much easier and lighterweight interface to a GPS module. Stop parsing NMEA data! And simply ask for the datums you need.
|
||||
|
||||
This library can be installed via the Arduino Library manager. Search for **SparkFun u-blox GNSS**.
|
||||
|
||||
Although not an integrated part of the library, you will find an example of how to communicate with the older series 6 and 7 modules in the [examples folder](./examples/Series_6_7).
|
||||
|
||||
Max (400kHz) I2C Support
|
||||
-------------------
|
||||
|
||||
To achieve 400kHz I2C speed please be sure to remove all pull-ups on the I2C bus. Most, if not all, u-blox modules include pull ups on the I2C lines (sometimes called DDC in their manuals). Cut all I2C pull up jumpers and/or remove them from peripheral boards. Otherwise, various data glitches can occur. See issues [38](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/issues/38) and [40](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/issues/40) for more information. If possible, run the I2C bus at 100kHz.
|
||||
|
||||
-------------------
|
||||
|
||||
Want to help? Please do! We are always looking for ways to improve and build out features of this library.
|
||||
|
||||
* We are always interested in adding SPI support with a checkUbloxSPI() function
|
||||
|
||||
Thanks to:
|
||||
|
||||
* [trycoon](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/pull/7) for fixing the lack of I2C buffer length defines.
|
||||
* [tve](https://github.com/tve) for building out serial additions and examples.
|
||||
* [Redstoned](https://github.com/Redstoned) and [davidallenmann](https://github.com/davidallenmann) for adding PVT date and time.
|
||||
* [wittend](https://forum.sparkfun.com/viewtopic.php?t=49874) for pointing out the RTCM print bug.
|
||||
* Big thanks to [PaulZC](https://github.com/PaulZC) for implementing the combined key ValSet method, geofence functions, better saveConfig handling, as well as a bunch of small fixes.
|
||||
* [RollieRowland](https://github.com/RollieRowland) for adding HPPOSLLH (High Precision Geodetic Position).
|
||||
* [tedder](https://github.com/tedder) for moving iTOW to PVT instead of HPPOS and comment cleanup.
|
||||
* [grexjmo](https://github.com/grexjmo) for pushing for a better NMEA sentence configuration method.
|
||||
* [averywallis](https://github.com/averywallis) for adding good comments to the various constants.
|
||||
* [blazczak](https://github.com/blazczak) and [geeksville](https://github.com/geeksville) for adding support for the series 6 and 7 modules.
|
||||
* [bjorn@unsurv](https://github.com/unsurv) for adding powerOff and powerOffWithInterrupt.
|
||||
* [dotMorten](https://github.com/dotMorten) for the MSGOUT keys, autoHPPOSLLH, autoDOP and upgrades to autoPVT.
|
||||
* [markuckermann](https://github.com/markuckermann) for spotting the config layer gremlins
|
||||
* [vid553](https://github.com/vid553) for the Zephyr port
|
||||
* [balamuruganky](https://github.com/balamuruganky) for the NAV-PVT velocity parameters, getSpeedAccEst, getHeadingAccEst, getInvalidLlh, getHeadVeh, getMagDec and getMagAcc
|
||||
* [nelarsen](https://github.com/nelarsen) for the buffer overrun improvements
|
||||
* [mstranne](https://github.com/mstranne) and [shaneperera](https://github.com/shaneperera) for the pushRawData suggestion
|
||||
* [rubienr](https://github.com/rubienr) for spotting the logical AND issues
|
||||
|
||||
Need a Python version for Raspberry Pi? Checkout the [Qwiic Ublox GPS Py module](https://github.com/sparkfun/Qwiic_Ublox_Gps_Py).
|
||||
|
||||
Need a library for the u-blox and Particle? Checkout the [Particle library](https://github.com/aseelye/SparkFun_Ublox_Particle_Library) fork.
|
||||
|
||||
Need a C++ version which runs on Linux? Checkout the [Ublox_Linux_Library](https://github.com/balamuruganky/Ublox_Linux_Library).
|
||||
|
||||
Contributing
|
||||
--------------
|
||||
|
||||
If you would like to contribute to this library: please do, we truly appreciate it, but please follow [these guidelines](./CONTRIBUTING.md). Thanks!
|
||||
|
||||
Repository Contents
|
||||
-------------------
|
||||
|
||||
* **/examples** - Example sketches for the library (.ino). Run these from the Arduino IDE.
|
||||
* **/src** - Source files for the library (.cpp, .h).
|
||||
* **[keywords.txt](./keywords.txt)** - Keywords from this library that will be highlighted in the Arduino IDE.
|
||||
* **[library.properties](./library.properties)** - General library properties for the Arduino package manager.
|
||||
* **[CONTRIBUTING.md](./CONTRIBUTING.md)** - Guidelines on how to contribute to this library.
|
||||
* **[Theory.md](./Theory.md)** - provides detail on how data is processed by the library.
|
||||
|
||||
Documentation
|
||||
--------------
|
||||
|
||||
* **[Installing an Arduino Library Guide](https://learn.sparkfun.com/tutorials/installing-an-arduino-library)** - Basic information on how to install an Arduino library.
|
||||
|
||||
Polling vs. Auto-Reporting
|
||||
--------------------------
|
||||
|
||||
This library supports two modes of operation for getting navigation information with the `getPVT`
|
||||
function (based on the `UBX_NAV_PVT` protocol packet): polling and auto-reporting.
|
||||
|
||||
The standard method is for the sketch to call `getPVT` (or one of the `getLatitude`, `getLongitude`,
|
||||
etc. methods) when it needs a fresh navigation solution. At that point the library sends a request
|
||||
to the GPS to produce a fresh solution. The GPS then waits until the next measurement occurs (e.g.
|
||||
once per second or as set using `setNavigationFrequency`) and then sends the fresh data.
|
||||
The advantage of this method is that the data received is always fresh, the downside is that getPVT
|
||||
can block until the next measurement is made by the GPS, e.g. up to 1 second if the nav frequency is
|
||||
set to one second.
|
||||
|
||||
An alternate method can be chosen using `setAutoPVT(true)` which instructs the GPS to send the
|
||||
navigation information (`UBX_NAV_PVT` packet) as soon as it is produced. This is the way the older
|
||||
NMEA navigation data has been used for years. The sketch continues to call `getPVT` as before but
|
||||
under the hood the library returns the data of the last solution received from the GPS, which may be
|
||||
a bit out of date (how much depends on the `setNavigationFrequency` value).
|
||||
|
||||
The advantage of this method is that getPVT does not block: it returns true if new data is available
|
||||
and false otherwise. The disadvantages are that the data may be a bit old and that buffering for
|
||||
these spontaneus `UBX_NAV_PVT` packets is required (100 bytes each). When using Serial the buffering
|
||||
is an issue because the std serial buffer is 32 or 64 bytes long depending on Arduino version. When
|
||||
using I2C the buffering is not an issue because the GPS device has at least 1KB of internal buffering
|
||||
(possibly as large as 4KB).
|
||||
|
||||
As an example, assume that the GPS is set to produce 5 navigation
|
||||
solutions per second and that the sketch only calls getPVT once a second, then the GPS will queue 5
|
||||
packets in its internal buffer (about 500 bytes) and the library will read those when getPVT is
|
||||
called, update its internal copy of the nav data 5 times, and return `true` to the sketch. The
|
||||
sketch calls `getLatitude`, etc. and retrieve the data of the most recent of those 5 packets.
|
||||
|
||||
The library also supports:
|
||||
* `autoHPPOSLLH`
|
||||
* `autoDOP`
|
||||
* `autoHNRAtt`
|
||||
* `autoHNRDyn`
|
||||
* `autoHNRPVT`
|
||||
|
||||
Memory Usage
|
||||
---------------------------------
|
||||
|
||||
Version 1.8.9 introduced support for `autoHNR` on the NEO-M8U, and that tipped the balance in terms of RAM use on the ATmega328.
|
||||
The library does still run on the ATmega328 but you will see _**Low memory available, stability problems may occur**_ warnings
|
||||
as the global variables now occupy 1540 bytes of RAM. If you do want to run this library on the ATmega328, you may need to regress
|
||||
to Version 1.8.8 via the Library Manager.
|
||||
|
||||
Products That Use This Library
|
||||
---------------------------------
|
||||
* [GPS-16481](https://www.sparkfun.com/products/16481) - SparkFun GPS-RTK-SMA Breakout - ZED-F9P (Qwiic)
|
||||
* [GPS-15136](https://www.sparkfun.com/products/15136) - SparkFun GPS-RTK2 Board - ZED-F9P (Qwiic)
|
||||
* [GPS-15005](https://www.sparkfun.com/products/15005) - SparkFun GPS-RTK Board - NEO-M8P-2 (Qwiic)
|
||||
* [GPS-15210](https://www.sparkfun.com/products/15210) - SparkFun GPS Breakout - Chip Antenna, SAM-M8Q (Qwiic)
|
||||
* [GPS-15193](https://www.sparkfun.com/products/15193) - SparkFun GPS Breakout - Chip Antenna, ZOE-M8Q (Qwiic)
|
||||
* [GPS-15733](https://www.sparkfun.com/products/15733) - SparkFun GPS Breakout - NEO-M9N, Chip Antenna (Qwiic)
|
||||
* [GPS-15712](https://www.sparkfun.com/products/15712) - SparkFun GPS Breakout - NEO-M9N, U.FL (Qwiic)
|
||||
* [GPS-16329](https://www.sparkfun.com/products/16329) - SparkFun GPS Dead Reckoning Breakout - NEO-M8U (Qwiic)
|
||||
* [SPX-14980](https://www.sparkfun.com/products/14980) - SparkX GPS-RTK Black
|
||||
* [SPX-15106](https://www.sparkfun.com/products/15106) - SparkX SAM-M8Q
|
||||
|
||||
License Information
|
||||
-------------------
|
||||
|
||||
This product is _**open source**_!
|
||||
|
||||
Various bits of the code have different licenses applied. Anything SparkFun wrote is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round!
|
||||
|
||||
Please use, reuse, and modify these files as you see fit. Please maintain attribution to SparkFun Electronics and release anything derivative under the same license.
|
||||
|
||||
Distributed as-is; no warranty is given.
|
||||
|
||||
- Your friends at SparkFun.
|
@ -0,0 +1,39 @@
|
||||
How I2C (aka DDC) communication works with a u-blox module
|
||||
===========================================================
|
||||
|
||||
When the user calls one of the methods the library will poll the u-blox module for new data.
|
||||
|
||||
* Wait for a minimum of 25 ms between polls (configured dynamically when update rate is set)
|
||||
* Write 0xFD to module
|
||||
* Read two bytes (0xFD and 0xFE) for bytes available
|
||||
* If 0x7F or 0xFF then no bytes are available
|
||||
* Otherwise, read number of bytes and process into NMEA, UBX, or RTCM frame.
|
||||
* If checksum is valid, flag frame as complete.
|
||||
|
||||
This library was originally written to use the I2C interface but Serial has been implemented as well.
|
||||
|
||||
How data is processed by this library
|
||||
===========================================================
|
||||
|
||||
A method will call **sendCommand()**. This will begin waiting for a response with either **waitForACKResponse()** or **waitForNoACKResponse()** depending on the command we have sent (CFG commands generate an ACK where others like PVT do not).
|
||||
|
||||
Once **waitForACKResponse()** or **waitForNoACKResponse()** is called the library will start checking the u-blox module for new bytes. These bytes may be part of a NMEA sentence, an RTCM sentence, or a UBX packet. The library will file each byte into the appropriate container. Once a given sentence or packet is complete, the appropriate processUBX(), processNMEA() will be called. These functions deal with specific processing for each type.
|
||||
|
||||
Note: When interfacing to a u-blox module over I2C **checkUbloxI2C()** will read all bytes currently sitting in the I2C buffer. This may pick up multiple UBX packets. For example, an ACK for a VALSET may be mixed in with an **AutoPVT** response. We cannot tell **checkUbloxI2C()** to stop once a given ACK is found because we run the risk of leaving unprocessed bytes in the I2C buffer and losing them. We don't have this issue with **checkUbloxSerial()**.
|
||||
|
||||
**processUBX()** will check the CRC of the UBX packet. If validated, the packet will be marked as valid. Once a packet is marked as valid then **processUBXpacket()** is called to extract the contents. This is most commonly used to get the position, velocity, and time (PVT) out of the packet but is also used to check the nature of an ACK packet.
|
||||
|
||||
Once a packet has been processed, **waitForACKResponse()/waitForNoACKResponse()** makes the appropriate decision what to do with it. If a packet satisfies the CLS/ID and characteristics of what **waitForACKResponse()/waitForNoACKResponse()** is waiting for, then it returns back to **sendCommand()**. If the packet didn't match or was invalid then **waitForACKResponse()/waitForNoACKResponse()** will continue to wait until the correct packet is received or we time out. **sendCommand()** then returns with a value from the **sfe_ublox_status_e** enum depending on the success of **waitForACKResponse()/waitForNoACKResponse()**.
|
||||
|
||||
If we are getting / polling data from the module, **sendCommand()** will return **SFE_UBLOX_STATUS_DATA_RECEIVED** if the get was successful.
|
||||
|
||||
If we are setting / writing data to the module, **sendCommand()** will return **SFE_UBLOX_STATUS_DATA_SENT** if the set was successful.
|
||||
|
||||
We are proud that this library still compiles and runs on the original RedBoard (ATmega328P). We achieve that by being very careful about how much RAM we allocate to packet storage. We use only three buffers or containers to store the incoming data:
|
||||
- **packetBuf** (packetBuffer) - is small and is used to store only the head (and tail) of incoming UBX packets until we know they are. If the packet is _expected_ (i.e. it matches the Class and ID in the packet passed in **sendCommand()**) then the incoming bytes are diverted into **packetCfg** or **packetAck**. Unexpected packets are ignored.
|
||||
- **packetCfg** (packetConfiguration) - is used to store an _expected_ incoming UBX packet of up to 256 bytes. E.g. **getProtocolVersion()** returns about 220 bytes. Message data requested by a higher function is returned in packetCfg.
|
||||
- **packetAck** (packetAcknowledge) - is small and is used to store the ACK or NACK accompanying any _expected_ packetCfg.
|
||||
|
||||
**AutoPVT**, **AutoHPPOSLLH** and **AutoDOP** packets can arrive at any time. They too _have_ to be stored and processed in **packetCfg**. This means there are circumstances where the library can get the data it is expecting from the module, but it is overwritten (e.g. by an **AutoPVT** packet) before **sendCommand()** is able to return. In this case, **sendCommand()** will return the error **SFE_UBLOX_STATUS_DATA_OVERWRITTEN**. We should simply call the library function again, but we will need to reset the packet contents first as they will indeed have been overwritten as the error implies.
|
||||
|
||||
Need a command that is not currently "built-in" to the library? You can do that using a Custom Command. Check out [Example20_SendCustomCommand](https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library/blob/master/examples/Example20_SendCustomCommand/Example20_SendCustomCommand.ino) for further details. Note: this will of course increase your RAM use.
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
By: Elias Santistevan
|
||||
SparkFun Electronics
|
||||
Date: May, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
ZED-F9R: https://www.sparkfun.com/products/16344
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a Redboard Qwiic
|
||||
If you don't have a platform with a Qwiic connection use the
|
||||
SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
|
||||
To take advantage of the internal IMU of either the Dead Reckoning GPS
|
||||
boards (ZED-F9R, NEO-M8U), you must first calibrate it. This includes securing the GPS module
|
||||
to your vehicle so that it is stable within 2 degrees and that the frame of
|
||||
reference of the board is consistent with the picture outlined in the
|
||||
Receiver-Description-Prot-Spec Datasheet under Automotive/Untethered Dead
|
||||
Reckoning. You may also check either the ZED-F9R or NEO-M8U Hookup Guide for
|
||||
more information. After the board is secure, you'll need to put the module
|
||||
through certain conditions for proper calibration: acceleration, turning,
|
||||
stopping for a few minutes, getting to a speed over 30km/h all under a clear sky
|
||||
with good GNSS signal. This example simply looks at the
|
||||
"fusionMode" status which indicates whether the SparkFun Dead Reckoning is
|
||||
not-calibrated - 0, or calibrated - 1.
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (myGPS.getEsfInfo()){
|
||||
Serial.print(F("Fusion Mode: "));
|
||||
Serial.println(myGPS.imuMeas.fusionMode);
|
||||
if (myGPS.imuMeas.fusionMode == 1)
|
||||
Serial.println(F("Sensor is calibrated!"));
|
||||
}
|
||||
|
||||
delay(250);
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
By: Elias Santistevan
|
||||
SparkFun Electronics
|
||||
Date: May, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
ZED-F9R: https://www.sparkfun.com/products/16344
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a Redboard Qwiic
|
||||
If you don't have a platform with a Qwiic connection use the
|
||||
SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
|
||||
After calibrating the module, also known as "Fusion Mode", you can get
|
||||
data directly from the IMU. This data is integrated directly into the GNSS
|
||||
output, but is provided by the module as well.
|
||||
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
|
||||
if (myGPS.getEsfInfo()){
|
||||
|
||||
Serial.print(F("Fusion Mode: "));
|
||||
Serial.println(myGPS.imuMeas.fusionMode);
|
||||
|
||||
if (myGPS.imuMeas.fusionMode == 1){
|
||||
Serial.println(F("Fusion Mode is Initialized!"));
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Fusion Mode is either disabled or not initialized - Freezing!"));
|
||||
Serial.println(F("Please see Example 1 description at top for more information."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
if (myGPS.getEsfIns())
|
||||
{
|
||||
Serial.print(F("X: "));
|
||||
Serial.println(myGPS.imuMeas.xAngRate);
|
||||
Serial.print(F("Y: "));
|
||||
Serial.println(myGPS.imuMeas.yAngRate);
|
||||
Serial.print(F("Z: "));
|
||||
Serial.println(myGPS.imuMeas.zAngRate);
|
||||
Serial.print(F("X Acceleration: "));
|
||||
Serial.println(myGPS.imuMeas.xAccel);
|
||||
Serial.print(F("Y Acceleration: "));
|
||||
Serial.println(myGPS.imuMeas.yAccel);
|
||||
Serial.print(F("Z Acceleration: "));
|
||||
Serial.println(myGPS.imuMeas.zAccel);
|
||||
// These values also have "validity checks" that can be provided by the
|
||||
// ublox library, add "Vald" to values: e.g. xAngRateVald or xAccelVald.
|
||||
}
|
||||
|
||||
delay(250);
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
By: Elias Santistevan
|
||||
SparkFun Electronics
|
||||
Date: May, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
ZED-F9R: https://www.sparkfun.com/products/16344
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a Redboard Qwiic
|
||||
If you don't have a platform with a Qwiic connection use the
|
||||
SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
|
||||
After calibrating the module, also known as "Fusion Mode", you can get
|
||||
data directly from the IMU. This example code walks you through trouble
|
||||
shooting or identifying the different states of any individual
|
||||
"external" (which include internal) sensors you've hooked up (vehicle speed
|
||||
sensor) or the internal IMU used by the modules. You can see if the sensor is
|
||||
being used, if it's calibrated, ready, what data type it returns, the state
|
||||
of the measurement etc.
|
||||
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
|
||||
// GetEsfInfo also gets the number of sensors used by the ublox module, this
|
||||
// includes (in the case of the ZED-F9R) wheel tick input from the vehicle
|
||||
// speed sensor attached to the module.
|
||||
if (myGPS.getEsfInfo()){
|
||||
|
||||
Serial.print(F("Fusion Mode: "));
|
||||
Serial.println(myGPS.imuMeas.fusionMode);
|
||||
|
||||
if (myGPS.imuMeas.fusionMode == 1){
|
||||
Serial.println(F("Fusion Mode is Initialized!"));
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Fusion Mode is either disabled or not initialized - Freezing!"));
|
||||
Serial.println(F("Please see Example 1 description at top for more information."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
for(int i=1; i<=myGPS.ubloxSen.numSens; i++){
|
||||
myGPS.getSensState(i); // Give the sensor you want to check on.
|
||||
Serial.print(F("Sensor Data Type: ")); //See ublox receiver description
|
||||
//or our hookup guide for information on the
|
||||
//return value.
|
||||
Serial.println(myGPS.ubloxSen.senType);
|
||||
Serial.print(F("Being Used: "));
|
||||
Serial.println(myGPS.ubloxSen.isUsed);
|
||||
Serial.print(F("Is Ready: "));
|
||||
Serial.println(myGPS.ubloxSen.isReady);
|
||||
Serial.print(F("Calibration Status: "));
|
||||
Serial.println(myGPS.ubloxSen.calibStatus);
|
||||
Serial.print(F("Time Status: "));
|
||||
Serial.println(myGPS.ubloxSen.timeStatus);
|
||||
Serial.print(F("Bad Measure: "));
|
||||
Serial.println(myGPS.ubloxSen.timeStatus);
|
||||
Serial.print(F("Bad Time Tag: "));
|
||||
Serial.println(myGPS.ubloxSen.badTag);
|
||||
Serial.print(F("Missed Measure : "));
|
||||
Serial.println(myGPS.ubloxSen.missMeas);
|
||||
Serial.print(F("Noisy Measure: "));
|
||||
Serial.println(myGPS.ubloxSen.noisyMeas);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
By: Elias Santistevan
|
||||
SparkFun Electronics
|
||||
Date: May, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
ZED-F9R: https://www.sparkfun.com/products/16344
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a Redboard Qwiic
|
||||
If you don't have a platform with a Qwiic connection use the
|
||||
SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
|
||||
After calibrating the module and securing it to your vehicle such that it's
|
||||
stable within 2 degrees, and the board is oriented correctly with regards to
|
||||
the vehicle's frame, you can now read the vehicle's "attitude". The attitude
|
||||
includes the vehicle's heading, pitch, and roll. You can also check the
|
||||
accuracy of those readings.
|
||||
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
|
||||
if (myGPS.getEsfInfo()){
|
||||
|
||||
Serial.print(F("Fusion Mode: "));
|
||||
Serial.println(myGPS.imuMeas.fusionMode);
|
||||
|
||||
if (myGPS.imuMeas.fusionMode == 1){
|
||||
Serial.println(F("Fusion Mode is Initialized!"));
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Fusion Mode is either disabled or not initialized - Freezing!"));
|
||||
Serial.println(F("Please see Example 1 description at top for more information."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.getVehAtt(); // Give the sensor you want to check on.
|
||||
Serial.print(F("Roll: "));
|
||||
Serial.println(myGPS.vehAtt.roll);
|
||||
Serial.print(F("Pitch: "));
|
||||
Serial.println(myGPS.vehAtt.pitch);
|
||||
Serial.print(F("Heading: "));
|
||||
Serial.println(myGPS.vehAtt.heading);
|
||||
Serial.print(F("Roll Accuracy: "));
|
||||
Serial.println(myGPS.vehAtt.accRoll);
|
||||
Serial.print(F("Pitch Accuracy: "));
|
||||
Serial.println(myGPS.vehAtt.accPitch);
|
||||
Serial.print(F("Heading Accuracy: "));
|
||||
Serial.println(myGPS.vehAtt.accHeading);
|
||||
|
||||
delay(250);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
By: Paul Clark
|
||||
SparkFun Electronics
|
||||
Date: December, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example configures the High Navigation Rate on the NEO-M8U and then
|
||||
polls and displays the attitude solution, vehicle dynamics information
|
||||
and high rate position, velocity and time.
|
||||
|
||||
This example polls the high rate data.
|
||||
(The next example uses "autoHNR" to receive the HNR data automatically.)
|
||||
|
||||
Please make sure your NEO-M8U is running UDR firmware >= 1.31. Please update using u-center if necessary:
|
||||
https://www.u-blox.com/en/product/neo-m8u-module#tab-documentation-resources
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a Redboard Qwiic
|
||||
If you don't have a platform with a Qwiic connection use the
|
||||
SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun u-blox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages on Serial
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Warning! u-blox GPS did not begin correctly."));
|
||||
Serial.println(F("(This may be because the I2C port is busy with HNR messages.)"));
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save (only) the communications port settings to flash and BBR
|
||||
|
||||
if (myGPS.setHNRNavigationRate(10) == true) //Set the High Navigation Rate to 10Hz
|
||||
Serial.println(F("setHNRNavigationRate was successful"));
|
||||
else
|
||||
Serial.println(F("setHNRNavigationRate was NOT successful"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Poll and print selected HNR data
|
||||
if (myGPS.getHNRAtt(125) == true) // Request HNR Att data using a 125ms timeout
|
||||
{
|
||||
Serial.print(F("Roll: "));
|
||||
Serial.print(myGPS.hnrAtt.roll);
|
||||
Serial.print(F(" Pitch: "));
|
||||
Serial.print(myGPS.hnrAtt.pitch);
|
||||
Serial.print(F(" Heading: "));
|
||||
Serial.println(myGPS.hnrAtt.heading);
|
||||
}
|
||||
if (myGPS.getHNRDyn(125) == true) // Request HNR Dyn data using a 125ms timeout
|
||||
{
|
||||
Serial.print(F("xAccel: "));
|
||||
Serial.print(myGPS.hnrVehDyn.xAccel);
|
||||
Serial.print(F(" yAccel: "));
|
||||
Serial.print(myGPS.hnrVehDyn.yAccel);
|
||||
Serial.print(F(" zAccel: "));
|
||||
Serial.println(myGPS.hnrVehDyn.zAccel);
|
||||
}
|
||||
if (myGPS.getHNRPVT(125) == true) // Request HNR PVT data using a 125ms timeout
|
||||
{
|
||||
Serial.print(F("ns: "));
|
||||
Serial.print(myGPS.hnrPVT.nano);
|
||||
Serial.print(F(" Lat: "));
|
||||
Serial.print(myGPS.hnrPVT.lat);
|
||||
Serial.print(F(" Lon: "));
|
||||
Serial.println(myGPS.hnrPVT.lon);
|
||||
}
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
By: Paul Clark
|
||||
SparkFun Electronics
|
||||
Date: December, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example configures the High Navigation Rate on the NEO-M8U and then
|
||||
reads and displays the attitude solution, vehicle dynamics information
|
||||
and high rate position, velocity and time.
|
||||
|
||||
This example uses "autoHNR" to receive the HNR data automatically.
|
||||
|
||||
Please make sure your NEO-M8U is running UDR firmware >= 1.31. Please update using u-center if necessary:
|
||||
https://www.u-blox.com/en/product/neo-m8u-module#tab-documentation-resources
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
NEO-M8U: https://www.sparkfun.com/products/16329
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a Redboard Qwiic
|
||||
If you don't have a platform with a Qwiic connection use the
|
||||
SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
boolean usingAutoHNRAtt = false;
|
||||
boolean usingAutoHNRDyn = false;
|
||||
boolean usingAutoHNRPVT = false;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun u-blox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages on Serial
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Warning! u-blox GPS did not begin correctly."));
|
||||
Serial.println(F("(This may be because the I2C port is busy with HNR messages.)"));
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT); //Save (only) the communications port settings to flash and BBR
|
||||
|
||||
if (myGPS.setHNRNavigationRate(10) == true) //Set the High Navigation Rate to 10Hz
|
||||
Serial.println(F("setHNRNavigationRate was successful"));
|
||||
else
|
||||
Serial.println(F("setHNRNavigationRate was NOT successful"));
|
||||
|
||||
usingAutoHNRAtt = myGPS.setAutoHNRAtt(true); //Attempt to enable auto HNR attitude messages
|
||||
usingAutoHNRDyn = myGPS.setAutoHNRDyn(true); //Attempt to enable auto HNR vehicle dynamics messages
|
||||
usingAutoHNRPVT = myGPS.setAutoHNRPVT(true); //Attempt to enable auto HNR PVT messages
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (usingAutoHNRAtt && (myGPS.getHNRAtt() == true)) // If setAutoHNRAtt was successful and new data is available
|
||||
{
|
||||
Serial.print(F("Roll: ")); // Print selected data
|
||||
Serial.print(myGPS.hnrAtt.roll);
|
||||
Serial.print(F(" Pitch: "));
|
||||
Serial.print(myGPS.hnrAtt.pitch);
|
||||
Serial.print(F(" Heading: "));
|
||||
Serial.println(myGPS.hnrAtt.heading);
|
||||
}
|
||||
if (usingAutoHNRDyn && (myGPS.getHNRDyn() == true)) // If setAutoHNRDyn was successful and new data is available
|
||||
{
|
||||
Serial.print(F("xAccel: ")); // Print selected data
|
||||
Serial.print(myGPS.hnrVehDyn.xAccel);
|
||||
Serial.print(F(" yAccel: "));
|
||||
Serial.print(myGPS.hnrVehDyn.yAccel);
|
||||
Serial.print(F(" zAccel: "));
|
||||
Serial.println(myGPS.hnrVehDyn.zAccel);
|
||||
}
|
||||
if (usingAutoHNRPVT && (myGPS.getHNRPVT() == true)) // If setAutoHNRPVT was successful and new data is available
|
||||
{
|
||||
Serial.print(F("ns: ")); // Print selected data
|
||||
Serial.print(myGPS.hnrPVT.nano);
|
||||
Serial.print(F(" Lat: "));
|
||||
Serial.print(myGPS.hnrPVT.lat);
|
||||
Serial.print(F(" Lon: "));
|
||||
Serial.println(myGPS.hnrPVT.lon);
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
Reading two altitudes - Mean Sea Level and Ellipsode
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for its lat/long/altitude.
|
||||
|
||||
getAltitude() reports mm above ellipsode model of the globe. There are some
|
||||
instances where altitude above Mean Sea Level is better. This example shows how
|
||||
to use getAltitudeMSL(). The difference varies but is ~20m.
|
||||
Ellipsoid model: https://www.esri.com/news/arcuser/0703/geoid1of3.html
|
||||
Difference between Ellipsoid Model and Mean Sea Level: https://eos-gnss.com/elevation-for-beginners/
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Tracks the passing of 2000ms (2 seconds)
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
long altitudeMSL = myGPS.getAltitudeMSL();
|
||||
Serial.print(F(" AltMSL: "));
|
||||
Serial.print(altitudeMSL);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Send command to reset module over I2C
|
||||
By: Nathan Seidle
|
||||
Date: January 29rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to reset the U-Blox module to factory defaults over I2C.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GNSS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
while (Serial.available()) Serial.read(); //Trash any incoming chars
|
||||
Serial.println("Press a key to reset module to factory defaults");
|
||||
while (Serial.available() == false) ; //Wait for user to send character
|
||||
|
||||
myGPS.factoryReset(); //Reset everything: baud rate, I2C address, update rate, everything.
|
||||
|
||||
if (myGPS.begin() == false) //Attempt to re-connect
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
Serial.println("Unit has now been factory reset. Freezing...");
|
||||
while(1);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
Test baud rate changes on serial, factory reset, and hard reset.
|
||||
By: Thorsten von Eicken
|
||||
Date: January 29rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to reset the U-Blox module to factory defaults over serial.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Connect the U-Blox serial port to Serial1
|
||||
If you're using an Uno or don't have a 2nd serial port (Serial1), consider using software serial
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
int state = 0; // steps through auto-baud, reset, etc states
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
Serial.print("===== STATE ");
|
||||
Serial.println(state);
|
||||
switch (state) {
|
||||
case 0: // auto-baud connection, then switch to 38400 and save config
|
||||
do {
|
||||
Serial.println("GPS: trying 38400 baud");
|
||||
Serial1.begin(38400);
|
||||
if (myGPS.begin(Serial1)) break;
|
||||
|
||||
delay(100);
|
||||
Serial.println("GPS: trying 9600 baud");
|
||||
Serial1.begin(9600);
|
||||
if (myGPS.begin(Serial1)) {
|
||||
Serial.println("GPS: connected at 9600 baud, switching to 38400");
|
||||
myGPS.setSerialRate(38400);
|
||||
delay(100);
|
||||
} else {
|
||||
delay(2000); //Wait a bit before trying again to limit the Serial output flood
|
||||
}
|
||||
} while(1);
|
||||
myGPS.setUART1Output(COM_TYPE_UBX); //Set the UART port to output UBX only
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
Serial.println("GPS serial connected, saved config");
|
||||
state++;
|
||||
break;
|
||||
case 1: // hardReset, expect to see GPS back at 38400 baud
|
||||
Serial.println("Issuing hardReset (cold start)");
|
||||
myGPS.hardReset();
|
||||
delay(1000);
|
||||
Serial1.begin(38400);
|
||||
if (myGPS.begin(Serial1)) {
|
||||
Serial.println("Success.");
|
||||
state++;
|
||||
} else {
|
||||
Serial.println("*** GPS did not respond at 38400 baud, starting over.");
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 2: // factoryReset, expect to see GPS back at 9600 baud
|
||||
Serial.println("Issuing factoryReset");
|
||||
myGPS.factoryReset();
|
||||
delay(2000); // takes more than one second... a loop to resync would be best
|
||||
Serial1.begin(9600);
|
||||
if (myGPS.begin(Serial1)) {
|
||||
Serial.println("Success.");
|
||||
state++;
|
||||
} else {
|
||||
Serial.println("*** GPS did not come back at 9600 baud, starting over.");
|
||||
state = 0;
|
||||
}
|
||||
break;
|
||||
case 3: // print version info
|
||||
Serial.print("GPS protocol version: ");
|
||||
Serial.print(myGPS.getProtocolVersionHigh());
|
||||
Serial.print('.');
|
||||
Serial.print(myGPS.getProtocolVersionLow());
|
||||
state = 0;
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
Reading lat and long via UBX binary commands using UART @38400 baud - free from I2C
|
||||
By: Nathan Seidle, Adapted from Example3_GetPosition by Thorsten von Eicken
|
||||
SparkFun Electronics
|
||||
Date: January 28rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the library and U-Blox for serial port use as well as
|
||||
switching the module from the default 9600 baud to 38400.
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 10,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Connect the U-Blox serial TX pin to Uno pin 10
|
||||
Connect the U-Blox serial RX pin to Uno pin 11
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
#include <SoftwareSerial.h>
|
||||
SoftwareSerial mySerial(10, 11); // RX, TX. Pin 10 on Uno goes to TX pin on GPS module.
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount of I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
//Assume that the U-Blox GPS is running at 9600 baud (the default) or at 38400 baud.
|
||||
//Loop until we're in sync and then ensure it's at 38400 baud.
|
||||
do {
|
||||
Serial.println("GPS: trying 38400 baud");
|
||||
mySerial.begin(38400);
|
||||
if (myGPS.begin(mySerial) == true) break;
|
||||
|
||||
delay(100);
|
||||
Serial.println("GPS: trying 9600 baud");
|
||||
mySerial.begin(9600);
|
||||
if (myGPS.begin(mySerial) == true) {
|
||||
Serial.println("GPS: connected at 9600 baud, switching to 38400");
|
||||
myGPS.setSerialRate(38400);
|
||||
delay(100);
|
||||
} else {
|
||||
//myGPS.factoryReset();
|
||||
delay(2000); //Wait a bit before trying again to limit the Serial output
|
||||
}
|
||||
} while(1);
|
||||
Serial.println("GPS serial connected");
|
||||
|
||||
myGPS.setUART1Output(COM_TYPE_UBX); //Set the UART port to output UBX only
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
Configuring the GPS to automatically send position reports over I2C
|
||||
By: Nathan Seidle and Thorsten von Eicken
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the U-Blox GPS the send navigation reports automatically
|
||||
and retrieving the latest one via getPVT. This eliminates the blocking in getPVT while the GPS
|
||||
produces a fresh navigation solution at the expense of returning a slighly old solution.
|
||||
|
||||
This can be used over serial or over I2C, this example shows the I2C use. With serial the GPS
|
||||
simply outputs the UBX_NAV_PVT packet. With I2C it queues it into its internal I2C buffer (4KB in
|
||||
size?) where it can be retrieved in the next I2C poll.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.setNavigationFrequency(2); //Produce two solutions per second
|
||||
myGPS.setAutoPVT(true); //Tell the GPS to "send" each solution
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Calling getPVT returns true if there actually is a fresh navigation solution available.
|
||||
// Start the reading only when valid LLH is available
|
||||
if (myGPS.getPVT() && (myGPS.getInvalidLlh() == false))
|
||||
{
|
||||
Serial.println();
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
int PDOP = myGPS.getPDOP();
|
||||
Serial.print(F(" PDOP: "));
|
||||
Serial.print(PDOP);
|
||||
Serial.print(F(" (10^-2)"));
|
||||
|
||||
int nedNorthVel = myGPS.getNedNorthVel();
|
||||
Serial.print(F(" VelN: "));
|
||||
Serial.print(nedNorthVel);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
int nedEastVel = myGPS.getNedEastVel();
|
||||
Serial.print(F(" VelE: "));
|
||||
Serial.print(nedEastVel);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
int nedDownVel = myGPS.getNedDownVel();
|
||||
Serial.print(F(" VelD: "));
|
||||
Serial.print(nedDownVel);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
int verticalAccEst = myGPS.getVerticalAccEst();
|
||||
Serial.print(F(" VAccEst: "));
|
||||
Serial.print(verticalAccEst);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
int horizontalAccEst = myGPS.getHorizontalAccEst();
|
||||
Serial.print(F(" HAccEst: "));
|
||||
Serial.print(horizontalAccEst);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
int speedAccEst = myGPS.getSpeedAccEst();
|
||||
Serial.print(F(" SpeedAccEst: "));
|
||||
Serial.print(speedAccEst);
|
||||
Serial.print(F(" (mm/s)"));
|
||||
|
||||
int headAccEst = myGPS.getHeadingAccEst();
|
||||
Serial.print(F(" HeadAccEst: "));
|
||||
Serial.print(headAccEst);
|
||||
Serial.print(F(" (degrees * 10^-5)"));
|
||||
|
||||
if (myGPS.getHeadVehValid() == true) {
|
||||
int headVeh = myGPS.getHeadVeh();
|
||||
Serial.print(F(" HeadVeh: "));
|
||||
Serial.print(headVeh);
|
||||
Serial.print(F(" (degrees * 10^-5)"));
|
||||
|
||||
int magDec = myGPS.getMagDec();
|
||||
Serial.print(F(" MagDec: "));
|
||||
Serial.print(magDec);
|
||||
Serial.print(F(" (degrees * 10^-2)"));
|
||||
|
||||
int magAcc = myGPS.getMagAcc();
|
||||
Serial.print(F(" MagAcc: "));
|
||||
Serial.print(magAcc);
|
||||
Serial.print(F(" (degrees * 10^-2)"));
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
} else {
|
||||
Serial.print(".");
|
||||
delay(50);
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
Configuring the GPS to automatically send position reports over I2C, with explicit data parsing calls
|
||||
By: Nathan Seidle Thorsten von Eicken and Felix Jirka
|
||||
SparkFun Electronics
|
||||
Date: July 1st, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the U-Blox GPS the send navigation reports automatically
|
||||
and retrieving the latest one via checkUblox when available.
|
||||
This eliminates the implicit update in getPVT when accessing data fields twice.
|
||||
Also this reduces the memory overhead of a separate buffer while introducing a slight error by inconsistencies because of the unsynchronized updates (on a multi core system).
|
||||
|
||||
This can be used over serial or over I2C, this example shows the I2C use. With serial the GPS
|
||||
simply outputs the UBX_NAV_PVT packet. With I2C it queues it into its internal I2C buffer (4KB in
|
||||
size?) where it can be retrieved in the next I2C poll.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include <SparkFun_Ublox_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.setNavigationFrequency(2); //Produce two solutions per second
|
||||
myGPS.setAutoPVT(true, false); //Tell the GPS to "send" each solution and the lib not to update stale data implicitly
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
/*
|
||||
Calling getPVT would return false now (compare to previous example where it would return true), so we just use the data provided
|
||||
If you are using a threaded OS eg. FreeRTOS on an ESP32, the explicit mode of autoPVT allows you to use the data provided on both cores and inside multiple threads
|
||||
The data update in background creates an inconsistent state, but that should not cause issues for most applications as they usually won't change the GPS location significantly within a 2Hz - 5Hz update rate.
|
||||
Also you could oversample (10Hz - 20Hz) the data to smooth out such issues...
|
||||
*/
|
||||
void loop()
|
||||
{
|
||||
static uint16_t counter = 0;
|
||||
|
||||
if (counter % 10 == 0)
|
||||
{
|
||||
// update your AHRS filter here for a ~100Hz update rate
|
||||
// GPS data will be quasi static but data from your IMU will be changing
|
||||
}
|
||||
// debug output each half second
|
||||
if (counter % 500 == 0)
|
||||
{
|
||||
Serial.println();
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
// call checkUblox all 50ms to capture the gps data
|
||||
if (counter % 50 == 0)
|
||||
{
|
||||
myGPS.checkUblox();
|
||||
}
|
||||
delay(1);
|
||||
counter++;
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
Reading lat and long via UBX binary commands using an RX-only UART
|
||||
By: Nathan Seidle, Adapted from Example11 by Felix Jirka
|
||||
SparkFun Electronics
|
||||
Date: July 2nd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the library for serial port use with a single wire connection using the assumeAutoPVT method.
|
||||
Saving your pins for other stuff :-)
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Preconditions:
|
||||
U-Blox module is configured to send cyclical PVT message
|
||||
Hardware Connections:
|
||||
Connect the U-Blox serial TX pin to Rx of Serial2 (default: GPIO16) on your ESP32
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example 17");
|
||||
|
||||
//Use any Serial port with at least a Rx Pin connected or a receive only version of SoftwareSerial here
|
||||
//Assume that the U-Blox GPS is running at 9600 baud (the default)
|
||||
Serial2.begin(9600);
|
||||
// no need to check return value as internal call to isConnected() will not succeed
|
||||
myGPS.begin(Serial2);
|
||||
|
||||
// tell lib, we are expecting the module to send PVT messages by itself to our Rx pin
|
||||
// you can set second parameter to "false" if you want to control the parsing and eviction of the data (need to call checkUblox cyclically)
|
||||
myGPS.assumeAutoPVT(true, true);
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// if implicit updates are allowed, this will trigger parsing the incoming messages
|
||||
// and be true once a PVT message has been parsed
|
||||
// In case you want to use explicit updates, wrap this in a timer and call checkUblox as often as needed, not to overflow your UART buffers
|
||||
if (myGPS.getPVT())
|
||||
{
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
else {
|
||||
Serial.println(F("Wait for GPS data"));
|
||||
delay(500);
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
Reading lat and long via UBX binary commands using UART @38400 baud - free from I2C
|
||||
By: Nathan Seidle, Adapted from Example3_GetPosition by Thorsten von Eicken
|
||||
SparkFun Electronics
|
||||
Date: January 28rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to configure the debug output from the library.
|
||||
Debug shows various packet and status outputs. These prints can be directed
|
||||
towards Serial (as in Serial.print) or any other port (Serial1, SerialUSB, etc).
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Connect the U-Blox serial TX pin to Uno pin 10
|
||||
Connect the U-Blox serial RX pin to Uno pin 11
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
myGPS.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
//myGPS.enableDebugging(SerialUSB); //Enable debug messages over Serial USB
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
Serial.print(myGPS.getYear());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getMonth());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getDay());
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getHour());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getMinute());
|
||||
Serial.print(":");
|
||||
Serial.println(myGPS.getSecond());
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
/*
|
||||
Getting time and date using Ublox commands
|
||||
By: davidallenmann
|
||||
SparkFun Electronics
|
||||
Date: April 16th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for the current time and date. We also
|
||||
turn off the NMEA output on the I2C port. This decreases the amount of I2C traffic
|
||||
dramatically.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.println();
|
||||
Serial.print(myGPS.getYear());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getMonth());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getDay());
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getHour());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getMinute());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getSecond());
|
||||
|
||||
Serial.print(" Time is ");
|
||||
if (myGPS.getTimeValid() == false)
|
||||
{
|
||||
Serial.print("not ");
|
||||
}
|
||||
Serial.print("valid Date is ");
|
||||
if (myGPS.getDateValid() == false)
|
||||
{
|
||||
Serial.print("not ");
|
||||
}
|
||||
Serial.print("valid");
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Getting time and date using Ublox commands
|
||||
By: davidallenmann
|
||||
SparkFun Electronics
|
||||
Date: April 16th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to query a Ublox module for the current time and date. We also
|
||||
turn off the NMEA output on the I2C port. This decreases the amount of I2C traffic
|
||||
dramatically.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(500000); //Increase serial speed to maximize
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000);
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
//myGPS.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
|
||||
myGPS.setNavigationFrequency(10); //Set output to 10 times a second
|
||||
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
|
||||
Serial.print("Current update rate:");
|
||||
Serial.println(rate);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Calling getPVT returns true if there actually is a fresh navigation solution available.
|
||||
if (myGPS.getPVT())
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getYear());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getMonth());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getDay());
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getHour());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getMinute());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getSecond());
|
||||
Serial.print(".");
|
||||
Serial.print(myGPS.getNanosecond());
|
||||
|
||||
myGPS.flushPVT();
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
/*
|
||||
Getting time and date using Ublox commands
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: April 16th, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to use the Millisecond and Nanosecond output as well as increase the
|
||||
I2C speed (100 to 400kHz), and serial output (115200 to 500kbps).
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(500000); //Increase serial speed to maximize
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
Wire.setClock(400000);
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
|
||||
//myGPS.enableDebugging(); //Enable debug messages over Serial (default)
|
||||
|
||||
myGPS.setNavigationFrequency(10); //Set output to 10 times a second
|
||||
byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module
|
||||
Serial.print("Current update rate:");
|
||||
Serial.println(rate);
|
||||
|
||||
myGPS.saveConfiguration(); //Save the current settings to flash and BBR
|
||||
|
||||
pinMode(2, OUTPUT); //For debug capture
|
||||
digitalWrite(2, HIGH);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Calling getPVT returns true if there actually is a fresh navigation solution available.
|
||||
if (myGPS.getPVT())
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
byte SIV = myGPS.getSIV();
|
||||
Serial.print(F(" SIV: "));
|
||||
Serial.print(SIV);
|
||||
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getYear());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getMonth());
|
||||
Serial.print("-");
|
||||
Serial.print(myGPS.getDay());
|
||||
Serial.print(" ");
|
||||
Serial.print(myGPS.getHour());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getMinute());
|
||||
Serial.print(":");
|
||||
Serial.print(myGPS.getSecond());
|
||||
Serial.print(".");
|
||||
//Pretty print leading zeros
|
||||
int mseconds = myGPS.getMillisecond();
|
||||
if (mseconds < 100)
|
||||
Serial.print("0");
|
||||
if (mseconds < 10)
|
||||
Serial.print("0");
|
||||
Serial.print(mseconds);
|
||||
|
||||
Serial.print(" nanoSeconds: ");
|
||||
Serial.print(myGPS.getNanosecond());
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
/*
|
||||
u-blox M8 geofence example
|
||||
|
||||
Written by Paul Clark (PaulZC)
|
||||
10th December 2019
|
||||
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example demonstrates how to use the addGeofence and getGeofenceState functions
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15210
|
||||
ZOE-M8Q: https://www.sparkfun.com/products/15193
|
||||
|
||||
This example powers up the GPS and reads the fix.
|
||||
Once a valid 3D fix has been found, the code reads the latitude and longitude.
|
||||
The code then sets four geofences around that position with a radii of 5m, 10m, 15m and 20m with 95% confidence.
|
||||
The code then monitors the geofence status.
|
||||
The LED will be illuminated if you are inside the _combined_ geofence (i.e. within the 20m radius).
|
||||
|
||||
This code has been tested on the ZOE-M8Q.
|
||||
*/
|
||||
|
||||
#define LED LED_BUILTIN // Change this if your LED is on a different pin
|
||||
|
||||
#include <Wire.h> // Needed for I2C
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
pinMode(LED, OUTPUT);
|
||||
|
||||
// Set up the I2C pins
|
||||
Wire.begin();
|
||||
|
||||
// Start the console serial port
|
||||
Serial.begin(115200);
|
||||
while (!Serial); // Wait for the user to open the serial monitor
|
||||
delay(100);
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println(F("u-blox M8 geofence example"));
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
delay(1000); // Let the GPS power up
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
//myGPS.enableDebugging(); // Enable debug messages
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); // Limit I2C output to UBX (disable the NMEA noise)
|
||||
|
||||
Serial.println(F("Waiting for a 3D fix..."));
|
||||
|
||||
byte fixType = 0;
|
||||
|
||||
while (fixType < 3)
|
||||
{
|
||||
fixType = myGPS.getFixType(); // Get the fix type
|
||||
Serial.print(F("Fix: ")); // Print it
|
||||
Serial.print(fixType);
|
||||
if(fixType == 0) Serial.print(F(" = No fix"));
|
||||
else if(fixType == 1) Serial.print(F(" = Dead reckoning"));
|
||||
else if(fixType == 2) Serial.print(F(" = 2D"));
|
||||
else if(fixType == 3) Serial.print(F(" = 3D"));
|
||||
else if(fixType == 4) Serial.print(F(" = GNSS + Dead reckoning"));
|
||||
else if(fixType == 5) Serial.print(F(" = Time only"));
|
||||
Serial.println();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
Serial.println(F("3D fix found!"));
|
||||
|
||||
long latitude = myGPS.getLatitude(); // Get the latitude in degrees * 10^-7
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude(); // Get the longitude in degrees * 10^-7
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.println(longitude);
|
||||
|
||||
uint32_t radius = 500; // Set the radius to 5m (radius is in m * 10^-2 i.e. cm)
|
||||
|
||||
byte confidence = 2; // Set the confidence level: 0=none, 1=68%, 2=95%, 3=99.7%, 4=99.99%
|
||||
|
||||
// Call clearGeofences() to clear all existing geofences.
|
||||
Serial.print(F("Clearing any existing geofences. clearGeofences returned: "));
|
||||
Serial.println(myGPS.clearGeofences());
|
||||
|
||||
// It is possible to define up to four geofences.
|
||||
// Call addGeofence up to four times to define them.
|
||||
Serial.println(F("Setting the geofences:"));
|
||||
|
||||
Serial.print(F("addGeofence for geofence 1 returned: "));
|
||||
Serial.println(myGPS.addGeofence(latitude, longitude, radius, confidence));
|
||||
|
||||
radius = 1000; // 10m
|
||||
Serial.print(F("addGeofence for geofence 2 returned: "));
|
||||
Serial.println(myGPS.addGeofence(latitude, longitude, radius, confidence));
|
||||
|
||||
radius = 1500; // 15m
|
||||
Serial.print(F("addGeofence for geofence 3 returned: "));
|
||||
Serial.println(myGPS.addGeofence(latitude, longitude, radius, confidence));
|
||||
|
||||
radius = 2000; // 20m
|
||||
Serial.print(F("addGeofence for geofence 4 returned: "));
|
||||
Serial.println(myGPS.addGeofence(latitude, longitude, radius, confidence));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
geofenceState currentGeofenceState; // Create storage for the geofence state
|
||||
|
||||
boolean result = myGPS.getGeofenceState(currentGeofenceState);
|
||||
|
||||
Serial.print(F("getGeofenceState returned: ")); // Print the combined state
|
||||
Serial.print(result); // Get the geofence state
|
||||
|
||||
if (!result) // If getGeofenceState did not return true
|
||||
{
|
||||
Serial.println(F(".")); // Tidy up
|
||||
return; // and go round the loop again
|
||||
}
|
||||
|
||||
Serial.print(F(". status is: ")); // Print the status
|
||||
Serial.print(currentGeofenceState.status);
|
||||
|
||||
Serial.print(F(". numFences is: ")); // Print the numFences
|
||||
Serial.print(currentGeofenceState.numFences);
|
||||
|
||||
Serial.print(F(". combState is: ")); // Print the combined state
|
||||
Serial.print(currentGeofenceState.combState);
|
||||
|
||||
if (currentGeofenceState.combState == 0)
|
||||
{
|
||||
Serial.print(F(" = Unknown"));
|
||||
digitalWrite(LED, LOW);
|
||||
}
|
||||
if (currentGeofenceState.combState == 1)
|
||||
{
|
||||
Serial.print(F(" = Inside"));
|
||||
digitalWrite(LED, HIGH);
|
||||
}
|
||||
else if (currentGeofenceState.combState == 2)
|
||||
{
|
||||
Serial.print(F(" = Outside"));
|
||||
digitalWrite(LED, LOW);
|
||||
}
|
||||
|
||||
Serial.print(F(". The individual states are: ")); // Print the state of each geofence
|
||||
for(int i = 0; i < currentGeofenceState.numFences; i++)
|
||||
{
|
||||
if (i > 0) Serial.print(F(","));
|
||||
Serial.print(currentGeofenceState.states[i]);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
/*
|
||||
Power Save Mode
|
||||
By: Paul Clark (PaulZC)
|
||||
Date: April 22nd, 2020
|
||||
|
||||
Based extensively on Example3_GetPosition
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to put the Ublox module into power save mode and then
|
||||
query its lat/long/altitude. We also turn off the NMEA output on the I2C port.
|
||||
This decreases the amount of I2C traffic dramatically.
|
||||
|
||||
** When it is able to ** the module will reduce its current draw.
|
||||
For the ZOE-M8Q with a passive antenna, you should see the current drop
|
||||
from (approx.) 25-28mA to (approx.) 9mA when power save mode kicks in.
|
||||
|
||||
Note: this will fail on the ZED (protocol version >= 27) as UBX-CFG-RXM is not supported
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 10,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
//myGPS.saveConfiguration(); //Uncomment this line to save the current settings to flash and BBR
|
||||
|
||||
Serial.println("Power save example.");
|
||||
Serial.println("1) Enable power saving");
|
||||
Serial.println("2) Disable power saving");
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (Serial.available())
|
||||
{
|
||||
byte incoming = Serial.read();
|
||||
|
||||
if (incoming == '1')
|
||||
{
|
||||
// Put the GNSS into power save mode
|
||||
// (If you want to disable power save mode, call myGPS.powerSaveMode(false) instead)
|
||||
// This will fail on the ZED (protocol version >= 27) as UBX-CFG-RXM is not supported
|
||||
if (myGPS.powerSaveMode()) // Defaults to true
|
||||
Serial.println(F("Power Save Mode enabled."));
|
||||
else
|
||||
Serial.println(F("***!!! Power Save Mode FAILED !!!***"));
|
||||
}
|
||||
else if (incoming == '2')
|
||||
{
|
||||
//Go to normal power mode (not power saving mode)
|
||||
if (myGPS.powerSaveMode(false))
|
||||
Serial.println(F("Power Save Mode disabled."));
|
||||
else
|
||||
Serial.println(F("***!!! Power Save Disable FAILED !!!***"));
|
||||
}
|
||||
|
||||
// Read and print the new low power mode
|
||||
uint8_t lowPowerMode = myGPS.getPowerSaveMode();
|
||||
if (lowPowerMode == 255)
|
||||
{
|
||||
Serial.println(F("***!!! getPowerSaveMode FAILED !!!***"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("The low power mode is: "));
|
||||
Serial.print(lowPowerMode);
|
||||
if (lowPowerMode == 0)
|
||||
{
|
||||
Serial.println(F(" (Continuous)"));
|
||||
}
|
||||
else if (lowPowerMode == 1)
|
||||
{
|
||||
Serial.println(F(" (Power Save)"));
|
||||
}
|
||||
else if (lowPowerMode == 4)
|
||||
{
|
||||
Serial.println(F(" (Continuous)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F(" (Unknown!)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Query module every 10 seconds so it is easier to monitor the current draw
|
||||
if (millis() - lastTime > 10000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
byte fixType = myGPS.getFixType(); // Get the fix type
|
||||
Serial.print(F("Fix: "));
|
||||
Serial.print(fixType);
|
||||
if (fixType == 0)
|
||||
Serial.print(F("(No fix)"));
|
||||
else if (fixType == 1)
|
||||
Serial.print(F("(Dead reckoning)"));
|
||||
else if (fixType == 2)
|
||||
Serial.print(F("(2D)"));
|
||||
else if (fixType == 3)
|
||||
Serial.print(F("(3D)"));
|
||||
else if (fixType == 4)
|
||||
Serial.print(F("(GNSS + Dead reckoning)"));
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F(" Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
Set Dynamic Model
|
||||
By: Paul Clark (PaulZC)
|
||||
Date: April 22nd, 2020
|
||||
|
||||
Based extensively on Example3_GetPosition
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: January 3rd, 2019
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how to change the Ublox module's dynamic platform model and then
|
||||
query its lat/long/altitude. We also turn off the NMEA output on the I2C port.
|
||||
This decreases the amount of I2C traffic dramatically.
|
||||
|
||||
Possible values for the dynamic model are: PORTABLE, STATIONARY, PEDESTRIAN, AUTOMOTIVE,
|
||||
SEA, AIRBORNE1g, AIRBORNE2g, AIRBORNE4g, WRIST, BIKE
|
||||
|
||||
Note: Long/lat are large numbers because they are * 10^7. To convert lat/long
|
||||
to something google maps understands simply divide the numbers by 10,000,000. We
|
||||
do this so that we don't have to use floating point numbers.
|
||||
|
||||
Leave NMEA parsing behind. Now you can simply ask the module for the datums you want!
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module.
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
|
||||
// If we are going to change the dynamic platform model, let's do it here.
|
||||
// Possible values are:
|
||||
// PORTABLE, STATIONARY, PEDESTRIAN, AUTOMOTIVE, SEA, AIRBORNE1g, AIRBORNE2g, AIRBORNE4g, WRIST, BIKE
|
||||
|
||||
if (myGPS.setDynamicModel(DYN_MODEL_PORTABLE) == false) // Set the dynamic model to PORTABLE
|
||||
{
|
||||
Serial.println(F("***!!! Warning: setDynamicModel failed !!!***"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Dynamic platform model changed successfully!"));
|
||||
}
|
||||
|
||||
// Let's read the new dynamic model to see if it worked
|
||||
uint8_t newDynamicModel = myGPS.getDynamicModel();
|
||||
if (newDynamicModel == 255)
|
||||
{
|
||||
Serial.println(F("***!!! Warning: getDynamicModel failed !!!***"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(F("The new dynamic model is: "));
|
||||
Serial.println(newDynamicModel);
|
||||
}
|
||||
|
||||
//myGPS.saveConfigSelective(VAL_CFG_SUBSEC_NAVCONF); //Uncomment this line to save only the NAV settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query module only every second. Doing it more often will just cause I2C traffic.
|
||||
//The module only responds when a new position is available
|
||||
if (millis() - lastTime > 1000)
|
||||
{
|
||||
lastTime = millis(); //Update the timer
|
||||
|
||||
long latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
long longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Long: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
long altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.print(F(" (mm)"));
|
||||
|
||||
Serial.println();
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
Read NMEA sentences over I2C using Ublox module SAM-M8Q, NEO-M8P, ZED-F9P, etc
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: August 22nd, 2018
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example reads the NMEA setences from the Ublox module over I2c and outputs
|
||||
them to the serial port
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false)
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
//This will pipe all NMEA sentences to the serial port so we can see them
|
||||
myGPS.setNMEAOutputPort(Serial);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
@ -0,0 +1,161 @@
|
||||
/*
|
||||
Send Custom Command
|
||||
By: Paul Clark (PaulZC)
|
||||
Date: April 20th, 2020
|
||||
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows how you can create and send a custom UBX packet
|
||||
using the SparkFun u-blox library.
|
||||
|
||||
Previously it was possible to create and send a custom packet
|
||||
through the library but it would always appear to timeout as
|
||||
some of the internal functions referred to the internal private
|
||||
struct packetCfg.
|
||||
The most recent version of the library allows sendCommand to
|
||||
use a custom packet as if it were packetCfg and so:
|
||||
- sendCommand will return a sfe_ublox_status_e enum as if
|
||||
it had been called from within the library
|
||||
- the custom packet will be updated with data returned by the module
|
||||
(previously this was not possible from outside the library)
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#define NAV_RATE 20 // The new navigation rate in Hz (measurements per second)
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); // You may need to increase this for high navigation rates!
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
|
||||
// Let's configure the module's navigation rate as if we were using setNavigationFrequency
|
||||
|
||||
// Let's create our custom packet
|
||||
uint8_t customPayload[MAX_PAYLOAD_SIZE]; // This array holds the payload data bytes
|
||||
// The next line creates and initialises the packet information which wraps around the payload
|
||||
ubxPacket customCfg = {0, 0, 0, 0, 0, customPayload, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
|
||||
|
||||
// The structure of ubxPacket is:
|
||||
// uint8_t cls : The message Class
|
||||
// uint8_t id : The message ID
|
||||
// uint16_t len : Length of the payload. Does not include cls, id, or checksum bytes
|
||||
// uint16_t counter : Keeps track of number of overall bytes received. Some responses are larger than 255 bytes.
|
||||
// uint16_t startingSpot : The counter value needed to go past before we begin recording into payload array
|
||||
// uint8_t *payload : The payload
|
||||
// uint8_t checksumA : Given to us by the module. Checked against the rolling calculated A/B checksums.
|
||||
// uint8_t checksumB
|
||||
// sfe_ublox_packet_validity_e valid : Goes from NOT_DEFINED to VALID or NOT_VALID when checksum is checked
|
||||
// sfe_ublox_packet_validity_e classAndIDmatch : Goes from NOT_DEFINED to VALID or NOT_VALID when the Class and ID match the requestedClass and requestedID
|
||||
|
||||
// sendCommand will return:
|
||||
// SFE_UBLOX_STATUS_DATA_RECEIVED if the data we requested was read / polled successfully
|
||||
// SFE_UBLOX_STATUS_DATA_SENT if the data we sent was writted successfully (ACK'd)
|
||||
// Other values indicate errors. Please see the sfe_ublox_status_e enum for further details.
|
||||
|
||||
// Referring to the u-blox M8 Receiver Description and Protocol Specification we see that
|
||||
// the navigation rate is configured using the UBX-CFG-RATE message. So let's load our
|
||||
// custom packet with the correct information so we can read (poll / get) the current settings.
|
||||
|
||||
customCfg.cls = UBX_CLASS_CFG; // This is the message Class
|
||||
customCfg.id = UBX_CFG_RATE; // This is the message ID
|
||||
customCfg.len = 0; // Setting the len (length) to zero let's us poll the current settings
|
||||
customCfg.startingSpot = 0; // Always set the startingSpot to zero (unless you really know what you are doing)
|
||||
|
||||
// We also need to tell sendCommand how long it should wait for a reply
|
||||
uint16_t maxWait = 250; // Wait for up to 250ms (Serial may need a lot longer e.g. 1100)
|
||||
|
||||
// Now let's read the current navigation rate. The results will be loaded into customCfg.
|
||||
if (myGPS.sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED) // We are expecting data and an ACK
|
||||
{
|
||||
Serial.println(F("sendCommand (poll / get) failed! Freezing..."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
// Referring to the message definition for UBX-CFG-RATE we see that the measurement rate
|
||||
// is stored in payload bytes 0 and 1 as a uint16_t in LSB-first (little endian) format
|
||||
|
||||
uint16_t rate = (customPayload[1] << 8) | customPayload[0]; // Extract the current rate (ms)
|
||||
float f_rate = 1000.0 / ((float)rate); // Convert the navigation rate to Hz (measurements per second)
|
||||
|
||||
// Print the current measurement rate
|
||||
Serial.print(F("The current measurement rate is: "));
|
||||
Serial.println(f_rate, 1);
|
||||
|
||||
// Let's change it
|
||||
rate = 1000 / NAV_RATE; // Load the new value into rate
|
||||
customPayload[0] = rate & 0xFF; // Store it in the payload
|
||||
customPayload[1] = rate >> 8;
|
||||
|
||||
// Print the new measurement rate
|
||||
Serial.print(F("The new measurement rate will be: "));
|
||||
Serial.println(NAV_RATE);
|
||||
|
||||
// We don't need to update customCfg.len as it will have been set to 6
|
||||
// when sendCommand read the data
|
||||
|
||||
// Now we write the custom packet back again to change the setting
|
||||
if (myGPS.sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_SENT) // This time we are only expecting an ACK
|
||||
{
|
||||
Serial.println(F("sendCommand (set) failed! Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println(F("Navigation rate updated. Here we go..."));
|
||||
}
|
||||
|
||||
myGPS.setAutoPVT(true); // Enable AutoPVT. The module will generate measurements automatically without being polled.
|
||||
|
||||
//myGPS.saveConfigSelective(VAL_CFG_SUBSEC_NAVCONF); //Uncomment this line to save only the NAV settings to flash and BBR
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
//Query the module as fast as possible
|
||||
int32_t latitude = myGPS.getLatitude();
|
||||
Serial.print(F("Lat: "));
|
||||
Serial.print(latitude);
|
||||
|
||||
int32_t longitude = myGPS.getLongitude();
|
||||
Serial.print(F(" Lon: "));
|
||||
Serial.print(longitude);
|
||||
Serial.print(F(" (degrees * 10^-7)"));
|
||||
|
||||
int32_t altitude = myGPS.getAltitude();
|
||||
Serial.print(F(" Alt: "));
|
||||
Serial.print(altitude);
|
||||
Serial.println(F(" (mm)"));
|
||||
}
|
@ -0,0 +1,183 @@
|
||||
/*
|
||||
Module Info - extracts and prints the full module information from UBX_MON_VER
|
||||
using a custom command.
|
||||
By: @mayopan
|
||||
Date: May 9th, 2020
|
||||
|
||||
Based on:
|
||||
Send Custom Command
|
||||
By: Paul Clark (PaulZC)
|
||||
Date: April 20th, 2020
|
||||
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
Previously it was possible to create and send a custom packet
|
||||
through the library but it would always appear to timeout as
|
||||
some of the internal functions referred to the internal private
|
||||
struct packetCfg.
|
||||
The most recent version of the library allows sendCommand to
|
||||
use a custom packet as if it were packetCfg and so:
|
||||
- sendCommand will return a sfe_ublox_status_e enum as if
|
||||
it had been called from within the library
|
||||
- the custom packet will be updated with data returned by the module
|
||||
(previously this was not possible from outside the library)
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#define MAX_PAYLOAD_SIZE 384 // Override MAX_PAYLOAD_SIZE for getModuleInfo which can return up to 348 bytes
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
|
||||
// Extend the class for getModuleInfo
|
||||
class SFE_UBLOX_GPS_ADD : public SFE_UBLOX_GPS
|
||||
{
|
||||
public:
|
||||
boolean getModuleInfo(uint16_t maxWait = 1100); //Queries module, texts
|
||||
|
||||
struct minfoStructure // Structure to hold the module info (uses 341 bytes of RAM)
|
||||
{
|
||||
char swVersion[30];
|
||||
char hwVersion[10];
|
||||
uint8_t extensionNo = 0;
|
||||
char extension[10][30];
|
||||
} minfo;
|
||||
};
|
||||
|
||||
SFE_UBLOX_GPS_ADD myGPS;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200); // You may need to increase this for high navigation rates!
|
||||
while (!Serial)
|
||||
; //Wait for user to open terminal
|
||||
Serial.println(F("SparkFun Ublox Example"));
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Uncomment this line to enable debug messages
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
|
||||
|
||||
Serial.print(F("Polling module info"));
|
||||
if (myGPS.getModuleInfo(1100) == false) // Try to get the module info
|
||||
{
|
||||
Serial.print(F("getModuleInfo failed! Freezing..."));
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println(F("Module Info : "));
|
||||
Serial.print(F("Soft version: "));
|
||||
Serial.println(myGPS.minfo.swVersion);
|
||||
Serial.print(F("Hard version: "));
|
||||
Serial.println(myGPS.minfo.hwVersion);
|
||||
Serial.print(F("Extensions:"));
|
||||
Serial.println(myGPS.minfo.extensionNo);
|
||||
for (int i = 0; i < myGPS.minfo.extensionNo; i++)
|
||||
{
|
||||
Serial.print(" ");
|
||||
Serial.println(myGPS.minfo.extension[i]);
|
||||
}
|
||||
Serial.println();
|
||||
Serial.println(F("Done!"));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
boolean SFE_UBLOX_GPS_ADD::getModuleInfo(uint16_t maxWait)
|
||||
{
|
||||
myGPS.minfo.hwVersion[0] = 0;
|
||||
myGPS.minfo.swVersion[0] = 0;
|
||||
for (int i = 0; i < 10; i++)
|
||||
myGPS.minfo.extension[i][0] = 0;
|
||||
myGPS.minfo.extensionNo = 0;
|
||||
|
||||
// Let's create our custom packet
|
||||
uint8_t customPayload[MAX_PAYLOAD_SIZE]; // This array holds the payload data bytes
|
||||
|
||||
// The next line creates and initialises the packet information which wraps around the payload
|
||||
ubxPacket customCfg = {0, 0, 0, 0, 0, customPayload, 0, 0, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED, SFE_UBLOX_PACKET_VALIDITY_NOT_DEFINED};
|
||||
|
||||
// The structure of ubxPacket is:
|
||||
// uint8_t cls : The message Class
|
||||
// uint8_t id : The message ID
|
||||
// uint16_t len : Length of the payload. Does not include cls, id, or checksum bytes
|
||||
// uint16_t counter : Keeps track of number of overall bytes received. Some responses are larger than 255 bytes.
|
||||
// uint16_t startingSpot : The counter value needed to go past before we begin recording into payload array
|
||||
// uint8_t *payload : The payload
|
||||
// uint8_t checksumA : Given to us by the module. Checked against the rolling calculated A/B checksums.
|
||||
// uint8_t checksumB
|
||||
// sfe_ublox_packet_validity_e valid : Goes from NOT_DEFINED to VALID or NOT_VALID when checksum is checked
|
||||
// sfe_ublox_packet_validity_e classAndIDmatch : Goes from NOT_DEFINED to VALID or NOT_VALID when the Class and ID match the requestedClass and requestedID
|
||||
|
||||
// sendCommand will return:
|
||||
// SFE_UBLOX_STATUS_DATA_RECEIVED if the data we requested was read / polled successfully
|
||||
// SFE_UBLOX_STATUS_DATA_SENT if the data we sent was writted successfully (ACK'd)
|
||||
// Other values indicate errors. Please see the sfe_ublox_status_e enum for further details.
|
||||
|
||||
// Referring to the u-blox M8 Receiver Description and Protocol Specification we see that
|
||||
// the module information can be read using the UBX-MON-VER message. So let's load our
|
||||
// custom packet with the correct information so we can read (poll / get) the module information.
|
||||
|
||||
customCfg.cls = UBX_CLASS_MON; // This is the message Class
|
||||
customCfg.id = UBX_MON_VER; // This is the message ID
|
||||
customCfg.len = 0; // Setting the len (length) to zero let's us poll the current settings
|
||||
customCfg.startingSpot = 0; // Always set the startingSpot to zero (unless you really know what you are doing)
|
||||
|
||||
// Now let's send the command. The module info is returned in customPayload
|
||||
|
||||
if (sendCommand(&customCfg, maxWait) != SFE_UBLOX_STATUS_DATA_RECEIVED)
|
||||
return (false); //If command send fails then bail
|
||||
|
||||
// Now let's extract the module info from customPayload
|
||||
|
||||
uint16_t position = 0;
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
minfo.swVersion[i] = customPayload[position];
|
||||
position++;
|
||||
}
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
minfo.hwVersion[i] = customPayload[position];
|
||||
position++;
|
||||
}
|
||||
|
||||
while (customCfg.len >= position + 30)
|
||||
{
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
minfo.extension[minfo.extensionNo][i] = customPayload[position];
|
||||
position++;
|
||||
}
|
||||
minfo.extensionNo++;
|
||||
if (minfo.extensionNo > 9)
|
||||
break;
|
||||
}
|
||||
|
||||
return (true); //Success!
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
Powering off a ublox GPS module
|
||||
By: bjorn
|
||||
unsurv.org
|
||||
Date: July 20th, 2020
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example shows you how to turn off the ublox module to lower the power consumption.
|
||||
There are two functions: one just specifies a duration in milliseconds the other also specifies a pin on the GPS device to wake it up with.
|
||||
By driving a voltage from LOW to HIGH or HIGH to LOW on the chosen module pin you wake the device back up.
|
||||
Note: Doing so on the INT0 pin when using the regular powerOff(durationInMs) function will wake the device anyway. (tested on SAM-M8Q)
|
||||
Note: While powered off, you should not query the device for data or it might wake up. This can be used to wake the device but is not recommended.
|
||||
Works best when also putting your microcontroller to sleep.
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard.
|
||||
To force the device to wake up you need to connect to a pin (for example INT0) seperately on the module.
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
*/
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
|
||||
// define a digital pin capable of driving HIGH and LOW
|
||||
#define WAKEUP_PIN 5
|
||||
|
||||
// Possible GNSS interrupt pins for powerOffWithInterrupt are:
|
||||
// VAL_RXM_PMREQ_WAKEUPSOURCE_UARTRX = uartrx
|
||||
// VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0 = extint0 (default)
|
||||
// VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT1 = extint1
|
||||
// VAL_RXM_PMREQ_WAKEUPSOURCE_SPICS = spics
|
||||
// These values can be or'd (|) together to enable interrupts on multiple pins
|
||||
|
||||
void wakeUp() {
|
||||
|
||||
Serial.print("-- waking up module via pin " + String(WAKEUP_PIN));
|
||||
Serial.println(" on your microcontroller --");
|
||||
|
||||
digitalWrite(WAKEUP_PIN, LOW);
|
||||
delay(1000);
|
||||
digitalWrite(WAKEUP_PIN, HIGH);
|
||||
delay(1000);
|
||||
digitalWrite(WAKEUP_PIN, LOW);
|
||||
}
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
pinMode(WAKEUP_PIN, OUTPUT);
|
||||
digitalWrite(WAKEUP_PIN, LOW);
|
||||
|
||||
Serial.begin(115200);
|
||||
while (!Serial); //Wait for user to open terminal
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
//myGPS.enableDebugging(); // Enable debug messages
|
||||
|
||||
if (myGPS.begin() == false) //Connect to the Ublox module using Wire port
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
|
||||
// Powering off for 20s, you should see the power consumption drop.
|
||||
Serial.println("-- Powering off module for 20s --");
|
||||
|
||||
myGPS.powerOff(20000);
|
||||
//myGPS.powerOffWithInterrupt(20000, VAL_RXM_PMREQ_WAKEUPSOURCE_EXTINT0);
|
||||
|
||||
delay(10000);
|
||||
|
||||
// After 10 seconds wake the device via the specified pin on your microcontroller and module.
|
||||
wakeUp();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//Do nothing
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
Read NMEA sentences over I2C using Ublox module SAM-M8Q, NEO-M8P, etc
|
||||
By: Nathan Seidle
|
||||
SparkFun Electronics
|
||||
Date: August 22nd, 2018
|
||||
License: MIT. See license file for more information but you can
|
||||
basically do whatever you want with this code.
|
||||
|
||||
This example reads the NMEA characters over I2C and pipes them to MicroNMEA
|
||||
This example will output your current long/lat and satellites in view
|
||||
|
||||
Feel like supporting open source hardware?
|
||||
Buy a board from SparkFun!
|
||||
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
|
||||
NEO-M8P RTK: https://www.sparkfun.com/products/15005
|
||||
SAM-M8Q: https://www.sparkfun.com/products/15106
|
||||
|
||||
For more MicroNMEA info see https://github.com/stevemarple/MicroNMEA
|
||||
|
||||
Hardware Connections:
|
||||
Plug a Qwiic cable into the GPS and a BlackBoard
|
||||
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
|
||||
Open the serial monitor at 115200 baud to see the output
|
||||
Go outside! Wait ~25 seconds and you should see your lat/long
|
||||
*/
|
||||
|
||||
#include <Wire.h> //Needed for I2C to GPS
|
||||
|
||||
#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_u-blox_GNSS
|
||||
SFE_UBLOX_GPS myGPS;
|
||||
|
||||
#include <MicroNMEA.h> //http://librarymanager/All#MicroNMEA
|
||||
char nmeaBuffer[100];
|
||||
MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer));
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("SparkFun Ublox Example");
|
||||
|
||||
Wire.begin();
|
||||
|
||||
if (myGPS.begin() == false)
|
||||
{
|
||||
Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing."));
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
myGPS.checkUblox(); //See if new data is available. Process bytes as they come in.
|
||||
|
||||
if(nmea.isValid() == true)
|
||||
{
|
||||
long latitude_mdeg = nmea.getLatitude();
|
||||
long longitude_mdeg = nmea.getLongitude();
|
||||
|
||||
Serial.print("Latitude (deg): ");
|
||||
Serial.println(latitude_mdeg / 1000000., 6);
|
||||
Serial.print("Longitude (deg): ");
|
||||
Serial.println(longitude_mdeg / 1000000., 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print("No Fix - ");
|
||||
Serial.print("Num. satellites: ");
|
||||
Serial.println(nmea.getNumSatellites());
|
||||
}
|
||||
|
||||
delay(250); //Don't pound too hard on the I2C bus
|
||||
}
|
||||
|
||||
//This function gets called from the SparkFun Ublox Arduino Library
|
||||
//As each NMEA character comes in you can specify what to do with it
|
||||
//Useful for passing to other libraries like tinyGPS, MicroNMEA, or even
|
||||
//a buffer, radio, etc.
|
||||
void SFE_UBLOX_GPS::processNMEA(char incoming)
|
||||
{
|
||||
//Take the incoming char from the Ublox I2C port and pass it on to the MicroNMEA lib
|
||||
//for sentence cracking
|
||||
nmea.process(incoming);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user