# 航電元件程式碼
###### tags: `Avionics`
[toc]
## 財產表
麵包版短×2
麵包版長×1
Arduino UNO版×3
Lora 通訊元件×4 (損壞×1)
3dbi 天線×4
35dbi 天線×2
## 元件狀況註記列表
UNO 1:
UNO 2, 3: UCI電子材料行
UNO 4: 墾億電子
UNO 2b + Lora 3a:不明原因經常 Lora 啟動 failed,持續時間也不長(約2-3分鐘)
5/11 無法連接com
## BMP180
### 獨立使用
```
#include <SFE_BMP180.h>
#include <Wire.h>
SFE_BMP180 pressure; // 建立一個物件名為 pressure
#define ALTITUDE 25 // 台灣西部海岸大約的海平面高度
void setup()
{
Serial.begin(9600);
Serial.println("REBOOT");
// 初始設定
if (pressure.begin())
Serial.println("BMP180 init success");
else
{
// 初始化錯誤,一般是連接問題
Serial.println("BMP180 init fail\n\n");
while(1); // 永久停在這裡
}
}
void loop()
{
char status;
double T,P,p0,a;
Serial.println();
status = pressure.startTemperature();
if (status != 0)
{
// 等待感測完成
delay(status);
// 取得完整溫度測量,感測值存在變數T,函數回傳 1表示成功,0表示失敗
status = pressure.getTemperature(T);
if (status != 0)
{
// 顯示感測值
Serial.print("temperature: ");
Serial.print(T,2);
Serial.print(" .C, ");
// 量測壓力
// 參數設定從 0 到 3 (最高的解析度,等待較久)
// 感測成功會傳回等待多少 ms,如果不成功會傳回 0
status = pressure.startPressure(3);
if (status != 0)
{
// 等待感測完成
delay(status);
// 取得完整的壓力感測值,感測值存在變數 P,這個函數需要先前取得的溫度 T
// 假使溫度變化不大,可以只取得一次的值即可,函數執行成功會傳回 1,失敗傳回 0
status = pressure.getPressure(P,T);
if (status != 0)
{
// 列出感測值
Serial.print("absolute pressure: ");
Serial.print(P,2);
Serial.print(" mb, ");
// 壓力感測值傳回絕對壓力,會隨著高度而變化,要移除高度的影響,需使用 sealevel 函數在目前的高度,
// 這個數字常被用在氣象報告中,參數 P = 絕對壓力(毫巴), 高度 = 目前高度(公尺/米).
// 傳回值 p0 = sealevel函數的補償壓力(毫巴)
p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)
Serial.print("relative (sea-level) pressure: ");
Serial.print(p0,2);
Serial.print(" mb, ");
// 如果要從壓力感測值得知高度,需使用高度函數 altitude,以及先言算出的基準壓力.
// 參數 P = 絕對壓力(毫巴), p0 = 基準壓力(毫巴). 傳回值 a = 高度(公尺/米)
a = pressure.altitude(P,p0);
Serial.print("computed altitude: ");
Serial.print(a,0);
Serial.print(" meters, ");
}
else Serial.println("error retrieving pressure measurement\n");
}
else Serial.println("error starting pressure measurement\n");
}
else Serial.println("error retrieving temperature measurement\n");
}
else Serial.println("error starting temperature measurement\n");
delay(2000); // 暫停5秒
}
```
### with Lora Sender
```
#include <SFE_BMP180.h>
#include <Wire.h>
#include <SPI.h>
#include <LoRa.h>
SFE_BMP180 pressure; // 建立一個物件名為 pressure
#define ALTITUDE 25 // 台灣西部海岸大約的海平面高度
void setup()
{
Serial.begin(9600);
Serial.println("LoRa Sender");
if (!LoRa.begin(433E6))
{
Serial.println("Starting LoRa failed!");
while(1);
}
while (pressure.begin() != true) {
Serial.println(F("BMP180 not connected..."));
delay(5000);
}
Serial.println(F("BMP180 initial OK"));
}
void loop()
{
char status;
double T,P,p0,a;
Serial.println();
status = pressure.startTemperature();
if (status != 0)
{
// 等待感測完成
delay(status);
// 取得完整溫度測量,感測值存在變數T,函數回傳 1表示成功,0表示失敗
status = pressure.getTemperature(T);
if (status != 0)
{
// 顯示感測值
Serial.print("temperature: ");
Serial.print(T,2);
Serial.print(" .C, ");
// 量測壓力
// 參數設定從 0 到 3 (最高的解析度,等待較久)
// 感測成功會傳回等待多少 ms,如果不成功會傳回 0
status = pressure.startPressure(3);
if (status != 0)
{
// 等待感測完成
delay(status);
// 取得完整的壓力感測值,感測值存在變數 P,這個函數需要先前取得的溫度 T
// 假使溫度變化不大,可以只取得一次的值即可,函數執行成功會傳回 1,失敗傳回 0
status = pressure.getPressure(P,T);
if (status != 0)
{
// 列出感測值
Serial.print("absolute pressure: ");
Serial.print(P,2);
Serial.print(" mb, ");
// 壓力感測值傳回絕對壓力,會隨著高度而變化,要移除高度的影響,需使用 sealevel 函數在目前的高度,
// 這個數字常被用在氣象報告中,參數 P = 絕對壓力(毫巴), 高度 = 目前高度(公尺/米).
// 傳回值 p0 = sealevel函數的補償壓力(毫巴)
p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)
Serial.print("relative (sea-level) pressure: ");
Serial.print(p0,2);
Serial.print(" mb, ");
// 如果要從壓力感測值得知高度,需使用高度函數 altitude,以及先言算出的基準壓力.
// 參數 P = 絕對壓力(毫巴), p0 = 基準壓力(毫巴). 傳回值 a = 高度(公尺/米)
a = pressure.altitude(P,p0);
Serial.print("computed altitude: ");
Serial.print(a,0);
Serial.print(" meters, ");
}
else Serial.println("error retrieving pressure measurement\n");
}
else Serial.println("error starting pressure measurement\n");
}
else Serial.println("error retrieving temperature measurement\n");
}
else Serial.println("error starting temperature measurement\n");
String msg = String(T,2)+" "+String(P,2)+" "+String(p0,2)+" "+String(a,0);
Serial.println();
Serial.print(msg);
LoRa.beginPacket();
LoRa.print(msg);
LoRa.endPacket();
delay(1000);
}
```
### with Lora Receiver
```
#include <SPI.h>
#include <LoRa.h>
#include <string.h>
void setup() {
Serial.begin(9600);
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
String str="";
String t="";
String P="";
String p0="";
String a="";
int packetSize = LoRa.parsePacket();
if (packetSize) {
Serial.print("Received packet: ");
// 讀取封包
while (LoRa.available()) {
str=str+((char)LoRa.read());
}
t = str.substring(0,5);
P = str.substring(6,13);
p0 = str.substring(14,21);
a = str.substring(22,24);
Serial.print("temperature:");
Serial.print(t);
Serial.print(" .C, ");
Serial.print("absolute pressure:");
Serial.print(P);
Serial.print(" mb, ");
Serial.print("relative (sea-level) pressure: ");
Serial.print(p0);
Serial.print(" mb, ");
Serial.print("computed altitude: ");
Serial.print(a);
Serial.print(" meters, ");
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
}
// delay(1000);
}
```


### 獨立使用 with PLXDAQ
```
#include <SFE_BMP180.h>
#include <Wire.h>
SFE_BMP180 pressure; // 建立一個物件名為 pressure
#define ALTITUDE 25 // 台灣西部海岸大約的海平面高度
void setup()
{
Serial.begin(9600);
Serial.println("REBOOT");
// 初始設定
if (pressure.begin())
Serial.println("BMP180 init success");
else
{
// 初始化錯誤,一般是連接問題
Serial.println("BMP180 init fail\n\n");
while(1); // 永久停在這裡
}
Serial.println("CLEARSHEET");
Serial.println("LABEL, Time,Timer, Temperature (C), Absolute Pressure (mb), Relative Pressure (mb), Altitude (m)");
}
void loop()
{
char status;
double T,P,p0,a;
status = pressure.startTemperature();
if (status != 0)
{
delay(status);
status = pressure.getTemperature(T);
if (status != 0)
{
// Serial.print("temperature: ");
// Serial.print(T,2);
// Serial.print(" .C, ");
status = pressure.startPressure(3);
if (status != 0)
{
// 等待感測完成
delay(status);
status = pressure.getPressure(P,T);
if (status != 0)
{
// 列出感測值
// Serial.print("absolute pressure: ");
// Serial.print(P,2);
// Serial.print(" mb, ");
p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)
// Serial.print("relative (sea-level) pressure: ");
// Serial.print(p0,2);
// Serial.print(" mb, ");
a = pressure.altitude(P,p0);
// Serial.print("computed altitude: ");
// Serial.print(a,0);
// Serial.print(" meters, ");
}
else; //Serial.println("error retrieving pressure measurement\n");
}
else; //Serial.println("error starting pressure measurement\n");
}
else; //Serial.println("error retrieving temperature measurement\n");
}
else; //Serial.println("error starting temperature measurement\n");
Serial.print("DATA, TIME, TIMER,");
Serial.print(T);
Serial.print(",");
Serial.print(P);
Serial.print(",");
Serial.print(p0);
Serial.print(",");
Serial.println(a);
delay(2000); // 暫停5秒
}
```
### Lora Receiver with PLXDAQ
```
#include <SPI.h>
#include <LoRa.h>
#include <string.h>
void setup() {
Serial.begin(9600);
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println("CLEARSHEET");
Serial.println("LABEL, Time,Timer, Temperature (C), Absolute Pressure (mb), Relative Pressure (mb), Altitude (m), RSSI");
}
void loop() {
String str="";
String T="";
String P="";
String p0="";
String a="";
int packetSize = LoRa.parsePacket();
if (packetSize) {
Serial.print("Received packet: ");
// 讀取封包
while (LoRa.available()) {
str=str+((char)LoRa.read());
}
T = str.substring(0,5);
P = str.substring(6,13);
p0 = str.substring(14,21);
a = str.substring(22,24);
Serial.print("DATA, TIME, TIMER,");
Serial.print(T);
Serial.print(",");
Serial.print(P);
Serial.print(",");
Serial.print(p0);
Serial.print(",");
Serial.print(a);
Serial.print(",");
// Serial.print("temperature:");
// Serial.print(t);
// Serial.print(" .C, ");
// Serial.print("absolute pressure:");
// Serial.print(P);
// Serial.print(" mb, ");
// Serial.print("relative (sea-level) pressure: ");
// Serial.print(p0);
// Serial.print(" mb, ");
// Serial.print("computed altitude: ");
// Serial.print(a);
// Serial.print(" meters, ");
//Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
}
delay(1000);
}
```
## LoRa傳送空封包
### Sender
```
#include <SPI.h>
#include <LoRa.h>
//define the pins used by the transceiver module
#define ss 5
#define rst 14
#include <SPI.h>
#include <LoRa.h>
int counter=0; //傳送次數計數器
void setup() {
Serial.begin(9600);
while (!Serial); //等待序列埠起始完畢
Serial.println("LoRa Sender");
if (!LoRa.begin(433E6)) { //起始 433MHz LoRa
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
Serial.print("Sending packet: ");
Serial.println(counter);
LoRa.beginPacket(); //封包傳送開始
LoRa.print("hello "); //封包內容
LoRa.print(counter); //封包內容
LoRa.endPacket(); //封包傳送結束
counter++; //計數器增量 1
delay(1000);
}
```
### Receiver
```
#include <SPI.h>
#include <LoRa.h>
#include <string.h>
void setup() {
Serial.begin(9600);
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
String str="";
String t="";
String P="";
String p0="";
String a="";
int packetSize = LoRa.parsePacket();
if (packetSize) {
Serial.print("Received packet: ");
// 讀取封包
while (LoRa.available()) {
str=str+((char)LoRa.read());
}
t = str.substring(0,5);
P = str.substring(6,13);
p0 = str.substring(14,21);
a = str.substring(22,24);
Serial.print("temperature:");
Serial.print(t);
Serial.print(" .C, ");
Serial.print("absolute pressure:");
Serial.print(P);
Serial.print(" mb, ");
Serial.print("relative (sea-level) pressure: ");
Serial.print(p0);
Serial.print(" mb, ");
Serial.print("computed altitude: ");
Serial.print(a);
Serial.print(" meters, ");
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
}
// delay(1000);
}
```
## CJMCU-8128
### 獨立使用
```
#include "Adafruit_CCS811.h"
#include <BMx280_EnvCalc.h>
#include <sSense-BMx280I2C.h>
#include <Wire.h>
#define SERIAL_SPEED 9600
Adafruit_CCS811 ccs;
BMx280I2C ssenseBMx280;
void setup() {
Serial.begin(9600); // initialize the serial monitor
Serial.begin(SERIAL_SPEED);
ccs.begin();
DebugPort.begin(SERIAL_SPEED);
while(!DebugPort) {} // Wait
Wire.begin();
while(!ssenseBMx280.begin())
{
DebugPort.println("Could not find BME280 sensor!");
delay(50);
}
/*switch(ssenseBMx280.chipModel())
{
case BME280::ChipModel_BME280:
DebugPort.println("Found BME280 sensor! Humidity available.");
break;
case BME280::ChipModel_BMP280:
DebugPort.println("Found BMP280 sensor! No Humidity available.");
break;
default:
DebugPort.println("Found UNKNOWN sensor! Error!");
}*/
Serial.println("CO2(ppm),Temp(C),Pressure(Pa),Altitude(m)");
}
void loop() {
if(ccs.available()){
if(!ccs.readData()){
Serial.print(ccs.geteCO2());
Serial.print(",");
}
else{
Serial.println("ERROR!,ERROR!,");
}
}
printBMx280Data(&DebugPort);
delay(2000);
}
void printBMx280Data( Stream* client )
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
ssenseBMx280.read(pres, temp, hum, tempUnit, presUnit);
client->print(temp);
client->print(",");
client->print(pres);
client->print(",");
BMx280_EnvCalc::AltitudeUnit envAltUnit = BMx280_EnvCalc::AltitudeUnit_Meters;
BMx280_EnvCalc::TempUnit envTempUnit = BMx280_EnvCalc::TempUnit_Celsius;
float altitude = BMx280_EnvCalc::Altitude(pres, envAltUnit);
// float dewPoint = BMx280_EnvCalc::DewPoint(temp, hum, envTempUnit);
//float seaLevel = BMx280_EnvCalc::EquivalentSeaLevelPressure(altitude, temp, pres);
client->print(altitude);
Serial.println(" ");
//delay(1000);
}
```
### With Lora Sender
```
#include <SPI.h>
#include <LoRa.h>
#include "Adafruit_CCS811.h"
#include <BMx280_EnvCalc.h>
#include <sSense-BMx280I2C.h>
#include <Wire.h>
#define SERIAL_SPEED 9600
Adafruit_CCS811 ccs;
BMx280I2C ssenseBMx280;
void setup()
{
Serial.begin(9600);
Serial.println("LoRa Sender");
if (!LoRa.begin(433E6))
{
Serial.println("Starting LoRa failed!");
while(1);
}
Serial.begin(SERIAL_SPEED);
ccs.begin();
DebugPort.begin(SERIAL_SPEED);
while(!DebugPort) {} // Wait
Wire.begin();
while(!ssenseBMx280.begin())
{
DebugPort.println("Could not find BME280 sensor!");
delay(50);
}
}
void loop() {
Serial.println();
Serial.println("CO2(ppm),Temp(C),Pressure(Pa),Altitude(m)");
if(ccs.available())
{
if(!ccs.readData()){
Serial.print("CO2(ppm):");
Serial.print(ccs.geteCO2());
//Serial.print(",");
}
else{
Serial.println("ERROR!,ERROR!,");
}
}
printBMx280Data(&DebugPort);
delay(2000);
}
void printBMx280Data( Stream* client )
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
ssenseBMx280.read(pres, temp, hum, tempUnit, presUnit);
//client->print(temp);
//client->print(",");
//client->print(pres);
//client->print(",");
BMx280_EnvCalc::AltitudeUnit envAltUnit = BMx280_EnvCalc::AltitudeUnit_Meters;
BMx280_EnvCalc::TempUnit envTempUnit = BMx280_EnvCalc::TempUnit_Celsius;
float altitude = BMx280_EnvCalc::Altitude(pres, envAltUnit);
//client->print(altitude);
//Serial.println(" ");
//delay(1000);
String msg = String(ccs.geteCO2())+" "+String(temp)+" "+String(pres)+" "+String(altitude);
Serial.println();
Serial.print(msg);
LoRa.beginPacket();
LoRa.print(msg);
LoRa.endPacket();
delay(1000); // 每1秒鐘送一次資料
}
```
### With Lora Receiver
```
#include <SPI.h>
#include <LoRa.h>
#include <string.h>
void setup() {
Serial.begin(9600);
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
String str="";
String ccsgeteCO2="";
String temp="";
String pres="";
String altitude="";
int packetSize = LoRa.parsePacket();
if (packetSize) {
Serial.print("Received packet: ");
// 讀取封包
while (LoRa.available()) {
str=str+((char)LoRa.read());
}
ccsgeteCO2 = str.substring(0,5);
temp = str.substring(5,11);
pres = str.substring(11,21);
altitude = str.substring(21,27);
Serial.print("Co2:");
Serial.print(ccsgeteCO2);
Serial.print("ppm, ");
Serial.print("Temperature:");
Serial.print(temp);
Serial.print("C, ");
Serial.print("Pressure: ");
Serial.print(pres);
Serial.print("Pa, ");
Serial.print("Altitude: ");
Serial.print(altitude);
Serial.print(" m, ");
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
}
// delay(1000);
}
```
## MPU9250
### 獨立使用
```
#include "Wire.h"
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"
#include "MPU6050.h"
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
I2Cdev I2C_M;
uint8_t buffer_m[6];
int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t mx, my, mz;
float heading;
float tiltheading;
float Axyz[3];
float Gxyz[3];
float Mxyz[3];
#define sample_num_mdate 5000
volatile float mx_sample[3];
volatile float my_sample[3];
volatile float mz_sample[3];
static float mx_centre = 0;
static float my_centre = 0;
static float mz_centre = 0;
volatile int mx_max = 0;
volatile int my_max = 0;
volatile int mz_max = 0;
volatile int mx_min = 0;
volatile int my_min = 0;
volatile int mz_min = 0;
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin();
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it's really up to you depending on your project)
Serial.begin(38400);
// initialize device
while(!Serial);
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
delay(1000);
Serial.println(" ");
Mxyz_init_calibrated();
}
void loop() {
getAccel_Data();
getGyro_Data();
getCompassDate_calibrated(); // compass data has been calibrated here
getHeading(); //before we use this function we should run 'getCompassDate_calibrated()' frist, so that we can get calibrated data ,then we can get correct angle .
getTiltHeading();
Serial.println("calibration parameter: ");
Serial.print(mx_centre);
Serial.print(" ");
Serial.print(my_centre);
Serial.print(" ");
Serial.println(mz_centre);
Serial.println(" ");
Serial.println("Acceleration(g) of X,Y,Z:");
Serial.print(Axyz[0]);
Serial.print(",");
Serial.print(Axyz[1]);
Serial.print(",");
Serial.println(Axyz[2]);
Serial.println("Gyro(degress/s) of X,Y,Z:");
Serial.print(Gxyz[0]);
Serial.print(",");
Serial.print(Gxyz[1]);
Serial.print(",");
Serial.println(Gxyz[2]);
Serial.println("Compass Value of X,Y,Z:");
Serial.print(Mxyz[0]);
Serial.print(",");
Serial.print(Mxyz[1]);
Serial.print(",");
Serial.println(Mxyz[2]);
Serial.println("The clockwise angle between the magnetic north and X-Axis:");
Serial.print(heading);
Serial.println(" ");
Serial.println("The clockwise angle between the magnetic north and the projection of the positive X-Axis in the horizontal plane:");
Serial.println(tiltheading);
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
delay(1000);
}
void getHeading(void) {
heading = 180 * atan2(Mxyz[1], Mxyz[0]) / PI;
if (heading < 0) {
heading += 360;
}
}
void getTiltHeading(void) {
float pitch = asin(-Axyz[0]);
float roll = asin(Axyz[1] / cos(pitch));
float xh = Mxyz[0] * cos(pitch) + Mxyz[2] * sin(pitch);
float yh = Mxyz[0] * sin(roll) * sin(pitch) + Mxyz[1] * cos(roll) - Mxyz[2] * sin(roll) * cos(pitch);
float zh = -Mxyz[0] * cos(roll) * sin(pitch) + Mxyz[1] * sin(roll) + Mxyz[2] * cos(roll) * cos(pitch);
tiltheading = 180 * atan2(yh, xh) / PI;
if (yh < 0) {
tiltheading += 360;
}
}
void Mxyz_init_calibrated() {
Serial.println(F("Before using 9DOF,we need to calibrate the compass frist,It will takes about 2 minutes."));
Serial.print(" ");
Serial.println(F("During calibratting ,you should rotate and turn the 9DOF all the time within 2 minutes."));
Serial.print(" ");
Serial.println(F("If you are ready ,please sent a command data 'ready' to start sample and calibrate."));
while (!Serial.find("ready"));
Serial.println(" ");
Serial.println("ready");
Serial.println("Sample starting......");
Serial.println("waiting ......");
get_calibration_Data();
Serial.println(" ");
Serial.println("compass calibration parameter ");
Serial.print(mx_centre);
Serial.print(" ");
Serial.print(my_centre);
Serial.print(" ");
Serial.println(mz_centre);
Serial.println(" ");
}
void get_calibration_Data() {
for (int i = 0; i < sample_num_mdate; i++) {
get_one_sample_date_mxyz();
/*
Serial.print(mx_sample[2]);
Serial.print(" ");
Serial.print(my_sample[2]); //you can see the sample data here .
Serial.print(" ");
Serial.println(mz_sample[2]);
*/
if (mx_sample[2] >= mx_sample[1]) {
mx_sample[1] = mx_sample[2];
}
if (my_sample[2] >= my_sample[1]) {
my_sample[1] = my_sample[2]; //find max value
}
if (mz_sample[2] >= mz_sample[1]) {
mz_sample[1] = mz_sample[2];
}
if (mx_sample[2] <= mx_sample[0]) {
mx_sample[0] = mx_sample[2];
}
if (my_sample[2] <= my_sample[0]) {
my_sample[0] = my_sample[2]; //find min value
}
if (mz_sample[2] <= mz_sample[0]) {
mz_sample[0] = mz_sample[2];
}
}
mx_max = mx_sample[1];
my_max = my_sample[1];
mz_max = mz_sample[1];
mx_min = mx_sample[0];
my_min = my_sample[0];
mz_min = mz_sample[0];
mx_centre = (mx_max + mx_min) / 2;
my_centre = (my_max + my_min) / 2;
mz_centre = (mz_max + mz_min) / 2;
}
void get_one_sample_date_mxyz() {
getCompass_Data();
mx_sample[2] = Mxyz[0];
my_sample[2] = Mxyz[1];
mz_sample[2] = Mxyz[2];
}
void getAccel_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Axyz[0] = (double) ax / 16384;
Axyz[1] = (double) ay / 16384;
Axyz[2] = (double) az / 16384;
}
void getGyro_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Gxyz[0] = (double) gx * 250 / 32768;
Gxyz[1] = (double) gy * 250 / 32768;
Gxyz[2] = (double) gz * 250 / 32768;
}
void getCompass_Data(void) {
I2C_M.writeByte(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x01); //enable the magnetometer
delay(10);
I2C_M.readBytes(MPU9150_RA_MAG_ADDRESS, MPU9150_RA_MAG_XOUT_L, 6, buffer_m);
mx = ((int16_t)(buffer_m[1]) << 8) | buffer_m[0] ;
my = ((int16_t)(buffer_m[3]) << 8) | buffer_m[2] ;
mz = ((int16_t)(buffer_m[5]) << 8) | buffer_m[4] ;
Mxyz[0] = (double) mx * 1200 / 4096;
Mxyz[1] = (double) my * 1200 / 4096;
Mxyz[2] = (double) mz * 1200 / 4096;
}
void getCompassDate_calibrated() {
getCompass_Data();
Mxyz[0] = Mxyz[0] - mx_centre;
Mxyz[1] = Mxyz[1] - my_centre;
Mxyz[2] = Mxyz[2] - mz_centre;
}
```
### 用9600(可)
```
#include "Wire.h"
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"
#include "MPU6050.h"
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for InvenSense evaluation board)
// AD0 high = 0x69
MPU6050 accelgyro;
I2Cdev I2C_M;
uint8_t buffer_m[6];
int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t mx, my, mz;
float heading;
float tiltheading;
float Axyz[3];
float Gxyz[3];
float Mxyz[3];
#define sample_num_mdate 5000
volatile float mx_sample[3];
volatile float my_sample[3];
volatile float mz_sample[3];
static float mx_centre = 0;
static float my_centre = 0;
static float mz_centre = 0;
volatile int mx_max = 0;
volatile int my_max = 0;
volatile int mz_max = 0;
volatile int mx_min = 0;
volatile int my_min = 0;
volatile int mz_min = 0;
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin();
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it's really up to you depending on your project)
Serial.begin(9600);
// initialize device
while(!Serial);
//Serial.println("Initializing I2C devices...");
accelgyro.initialize();
// verify connection
//Serial.println("Testing device connections...");
//Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
delay(1000);
//Serial.println(" ");
Mxyz_init_calibrated();
}
void loop() {
getAccel_Data();
getGyro_Data();
getCompassDate_calibrated(); // compass data has been calibrated here
getHeading(); //before we use this function we should run 'getCompassDate_calibrated()' frist, so that we can get calibrated data ,then we can get correct angle .
getTiltHeading();
/*Serial.println("calibration parameter: ");
Serial.print(mx_centre);
Serial.print(" ");
Serial.print(my_centre);
Serial.print(" ");
Serial.println(mz_centre);
Serial.println(" ");*/
Serial.println("Acceleration(g) of X,Y,Z:");
Serial.print(Axyz[0]);
Serial.print(",");
Serial.print(Axyz[1]);
Serial.print(",");
Serial.println(Axyz[2]);
Serial.println("Gyro(degress/s) of X,Y,Z:");
Serial.print(Gxyz[0]);
Serial.print(",");
Serial.print(Gxyz[1]);
Serial.print(",");
Serial.println(Gxyz[2]);
Serial.println("Compass Value of X,Y,Z:");
Serial.print(Mxyz[0]);
Serial.print(",");
Serial.print(Mxyz[1]);
Serial.print(",");
Serial.println(Mxyz[2]);
/*Serial.println("The clockwise angle between the magnetic north and X-Axis:");
Serial.print(heading);
Serial.println(" ");
Serial.println("The clockwise angle between the magnetic north and the projection of the positive X-Axis in the horizontal plane:");
Serial.println(tiltheading);
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");*/
//delay(1000);
}
void getHeading(void) {
heading = 180 * atan2(Mxyz[1], Mxyz[0]) / PI;
if (heading < 0) {
heading += 360;
}
}
void getTiltHeading(void) {
float pitch = asin(-Axyz[0]);
float roll = asin(Axyz[1] / cos(pitch));
float xh = Mxyz[0] * cos(pitch) + Mxyz[2] * sin(pitch);
float yh = Mxyz[0] * sin(roll) * sin(pitch) + Mxyz[1] * cos(roll) - Mxyz[2] * sin(roll) * cos(pitch);
float zh = -Mxyz[0] * cos(roll) * sin(pitch) + Mxyz[1] * sin(roll) + Mxyz[2] * cos(roll) * cos(pitch);
tiltheading = 180 * atan2(yh, xh) / PI;
if (yh < 0) {
tiltheading += 360;
}
}
void Mxyz_init_calibrated() {
/*Serial.println(F("Before using 9DOF,we need to calibrate the compass frist,It will takes about 2 minutes."));
Serial.print(" ");
Serial.println(F("During calibratting ,you should rotate and turn the 9DOF all the time within 2 minutes."));
Serial.print(" ");
Serial.println(F("If you are ready ,please sent a command data 'ready' to start sample and calibrate."));
while (!Serial.find("ready"));
Serial.println(" ");
Serial.println("ready");
Serial.println("Sample starting......");
Serial.println("waiting ......");*/
get_calibration_Data();
Serial.println(" ");
Serial.println("compass calibration parameter ");
Serial.print(mx_centre);
Serial.print(" ");
Serial.print(my_centre);
Serial.print(" ");
Serial.println(mz_centre);
Serial.println(" ");
}
void get_calibration_Data() {
for (int i = 0; i < sample_num_mdate; i++) {
get_one_sample_date_mxyz();
/*
Serial.print(mx_sample[2]);
Serial.print(" ");
Serial.print(my_sample[2]); //you can see the sample data here .
Serial.print(" ");
Serial.println(mz_sample[2]);
*/
if (mx_sample[2] >= mx_sample[1]) {
mx_sample[1] = mx_sample[2];
}
if (my_sample[2] >= my_sample[1]) {
my_sample[1] = my_sample[2]; //find max value
}
if (mz_sample[2] >= mz_sample[1]) {
mz_sample[1] = mz_sample[2];
}
if (mx_sample[2] <= mx_sample[0]) {
mx_sample[0] = mx_sample[2];
}
if (my_sample[2] <= my_sample[0]) {
my_sample[0] = my_sample[2]; //find min value
}
if (mz_sample[2] <= mz_sample[0]) {
mz_sample[0] = mz_sample[2];
}
}
mx_max = mx_sample[1];
my_max = my_sample[1];
mz_max = mz_sample[1];
mx_min = mx_sample[0];
my_min = my_sample[0];
mz_min = mz_sample[0];
mx_centre = (mx_max + mx_min) / 2;
my_centre = (my_max + my_min) / 2;
mz_centre = (mz_max + mz_min) / 2;
}
void get_one_sample_date_mxyz() {
getCompass_Data();
mx_sample[2] = Mxyz[0];
my_sample[2] = Mxyz[1];
mz_sample[2] = Mxyz[2];
}
void getAccel_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Axyz[0] = (double) ax / 16384;
Axyz[1] = (double) ay / 16384;
Axyz[2] = (double) az / 16384;
}
void getGyro_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Gxyz[0] = (double) gx * 250 / 32768;
Gxyz[1] = (double) gy * 250 / 32768;
Gxyz[2] = (double) gz * 250 / 32768;
}
void getCompass_Data(void) {
I2C_M.writeByte(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x01); //enable the magnetometer
delay(10);
I2C_M.readBytes(MPU9150_RA_MAG_ADDRESS, MPU9150_RA_MAG_XOUT_L, 6, buffer_m);
mx = ((int16_t)(buffer_m[1]) << 8) | buffer_m[0] ;
my = ((int16_t)(buffer_m[3]) << 8) | buffer_m[2] ;
mz = ((int16_t)(buffer_m[5]) << 8) | buffer_m[4] ;
Mxyz[0] = (double) mx * 1200 / 4096;
Mxyz[1] = (double) my * 1200 / 4096;
Mxyz[2] = (double) mz * 1200 / 4096;
}
void getCompassDate_calibrated() {
getCompass_Data();
Mxyz[0] = Mxyz[0] - mx_centre;
Mxyz[1] = Mxyz[1] - my_centre;
Mxyz[2] = Mxyz[2] - mz_centre;
}
```
### Sender
```
#include "I2Cdev.h"
#include "MPU6050.h"
#include <Wire.h>
#include <SPI.h>
#include <LoRa.h>
MPU6050 accelgyro;
I2Cdev I2C_M;
uint8_t buffer_m[6];
int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t mx, my, mz;
float heading;
float tiltheading;
float Axyz[3];
float Gxyz[3];
float Mxyz[3];
#define sample_num_mdate 5000
volatile float mx_sample[3];
volatile float my_sample[3];
volatile float mz_sample[3];
static float mx_centre = 0;
static float my_centre = 0;
static float mz_centre = 0;
volatile int mx_max = 0;
volatile int my_max = 0;
volatile int mz_max = 0;
volatile int mx_min = 0;
volatile int my_min = 0;
volatile int mz_min = 0;
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("LoRa Sender");
if (!LoRa.begin(433E6))
{
Serial.println("Starting LoRa failed!");
while(1);
}
// initialize device
while(!Serial);
//Serial.println("Initializing I2C devices...");
accelgyro.initialize();
// verify connection
//Serial.println("Testing device connections...");
//Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
delay(3000);
//Serial.println(" ");
Mxyz_init_calibrated();
}
void loop()
{
getAccel_Data();
getGyro_Data();
getCompassDate_calibrated(); // compass data has been calibrated here
getHeading(); //before we use this function we should run 'getCompassDate_calibrated()' frist, so that we can get calibrated data ,then we can get correct angle .
getTiltHeading();
/*Serial.println("calibration parameter: ");
Serial.print(mx_centre);
Serial.print(" ");
Serial.print(my_centre);
Serial.print(" ");
Serial.println(mz_centre);
Serial.println(" ");*/
Serial.println("Acceleration(g) of X,Y,Z:");
Serial.print(Axyz[0]);
Serial.print(",");
Serial.print(Axyz[1]);
Serial.print(",");
Serial.println(Axyz[2]);
Serial.println("Gyro(degress/s) of X,Y,Z:");
Serial.print(Gxyz[0]);
Serial.print(",");
Serial.print(Gxyz[1]);
Serial.print(",");
Serial.println(Gxyz[2]);
Serial.println("Compass Value of X,Y,Z:");
Serial.print(Mxyz[0]);
Serial.print(",");
Serial.print(Mxyz[1]);
Serial.print(",");
Serial.println(Mxyz[2]);
/*Serial.println("The clockwise angle between the magnetic north and X-Axis:");
Serial.print(heading);
Serial.println(" ");
Serial.println("The clockwise angle between the magnetic north and the projection of the positive X-Axis in the horizontal plane:");
Serial.println(tiltheading);
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");*/
//delay(1000);
}
void getHeading(void) {
heading = 180 * atan2(Mxyz[1], Mxyz[0]) / PI;
if (heading < 0) {
heading += 360;
}
}
void getTiltHeading(void) {
float pitch = asin(-Axyz[0]);
float roll = asin(Axyz[1] / cos(pitch));
float xh = Mxyz[0] * cos(pitch) + Mxyz[2] * sin(pitch);
float yh = Mxyz[0] * sin(roll) * sin(pitch) + Mxyz[1] * cos(roll) - Mxyz[2] * sin(roll) * cos(pitch);
float zh = -Mxyz[0] * cos(roll) * sin(pitch) + Mxyz[1] * sin(roll) + Mxyz[2] * cos(roll) * cos(pitch);
tiltheading = 180 * atan2(yh, xh) / PI;
if (yh < 0) {
tiltheading += 360;
}
}
void Mxyz_init_calibrated() {
/*Serial.println(F("Before using 9DOF,we need to calibrate the compass frist,It will takes about 2 minutes."));
Serial.print(" ");
Serial.println(F("During calibratting ,you should rotate and turn the 9DOF all the time within 2 minutes."));
Serial.print(" ");
Serial.println(F("If you are ready ,please sent a command data 'ready' to start sample and calibrate."));
while (!Serial.find("ready"));
Serial.println(" ");
Serial.println("ready");
Serial.println("Sample starting......");
Serial.println("waiting ......");*/
get_calibration_Data();
Serial.println(" ");
Serial.println("compass calibration parameter ");
Serial.print(mx_centre);
Serial.print(" ");
Serial.print(my_centre);
Serial.print(" ");
Serial.println(mz_centre);
Serial.println(" ");
}
void get_calibration_Data() {
for (int i = 0; i < sample_num_mdate; i++) {
get_one_sample_date_mxyz();
/*
Serial.print(mx_sample[2]);
Serial.print(" ");
Serial.print(my_sample[2]); //you can see the sample data here .
Serial.print(" ");
Serial.println(mz_sample[2]);
*/
if (mx_sample[2] >= mx_sample[1]) {
mx_sample[1] = mx_sample[2];
}
if (my_sample[2] >= my_sample[1]) {
my_sample[1] = my_sample[2]; //find max value
}
if (mz_sample[2] >= mz_sample[1]) {
mz_sample[1] = mz_sample[2];
}
if (mx_sample[2] <= mx_sample[0]) {
mx_sample[0] = mx_sample[2];
}
if (my_sample[2] <= my_sample[0]) {
my_sample[0] = my_sample[2]; //find min value
}
if (mz_sample[2] <= mz_sample[0]) {
mz_sample[0] = mz_sample[2];
}
}
mx_max = mx_sample[1];
my_max = my_sample[1];
mz_max = mz_sample[1];
mx_min = mx_sample[0];
my_min = my_sample[0];
mz_min = mz_sample[0];
mx_centre = (mx_max + mx_min) / 2;
my_centre = (my_max + my_min) / 2;
mz_centre = (mz_max + mz_min) / 2;
}
void get_one_sample_date_mxyz() {
getCompass_Data();
mx_sample[2] = Mxyz[0];
my_sample[2] = Mxyz[1];
mz_sample[2] = Mxyz[2];
}
void getAccel_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Axyz[0] = (double) ax / 16384;
Axyz[1] = (double) ay / 16384;
Axyz[2] = (double) az / 16384;
}
void getGyro_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Gxyz[0] = (double) gx * 250 / 32768;
Gxyz[1] = (double) gy * 250 / 32768;
Gxyz[2] = (double) gz * 250 / 32768;
}
void getCompass_Data(void) {
I2C_M.writeByte(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x01); //enable the magnetometer
delay(10);
I2C_M.readBytes(MPU9150_RA_MAG_ADDRESS, MPU9150_RA_MAG_XOUT_L, 6, buffer_m);
mx = ((int16_t)(buffer_m[1]) << 8) | buffer_m[0] ;
my = ((int16_t)(buffer_m[3]) << 8) | buffer_m[2] ;
mz = ((int16_t)(buffer_m[5]) << 8) | buffer_m[4] ;
Mxyz[0] = (double) mx * 1200 / 4096;
Mxyz[1] = (double) my * 1200 / 4096;
Mxyz[2] = (double) mz * 1200 / 4096;
}
void getCompassDate_calibrated() {
getCompass_Data();
Mxyz[0] = Mxyz[0] - mx_centre;
Mxyz[1] = Mxyz[1] - my_centre;
Mxyz[2] = Mxyz[2] - mz_centre;
String msg = String(Axyz[0]+500)+" "+String(Axyz[1]+500)+" "+String(Axyz[2]+500)+" "+String(Gxyz[0]+500)+" "+String(Gxyz[1]+500)+" "+String(Gxyz[2]+500)+" "+String(Mxyz[0]+500)+" "+String(Mxyz[1]+500)+" "+String(Mxyz[2]+500);
Serial.println();
Serial.println();
Serial.println(msg);
LoRa.beginPacket();
LoRa.print(msg);
LoRa.endPacket();
delay(1000);
}
```
### Receiver
```
#include <SPI.h>
#include <LoRa.h>
#include <string.h>
void setup() {
Serial.begin(9600);
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
String str="";
String Axyz0="";
String Axyz1="";
String Axyz2="";
String Gxyz0="";
String Gxyz1="";
String Gxyz2="";
String Mxyz0="";
String Mxyz1="";
String Mxyz2="";
int packetSize = LoRa.parsePacket();
if (packetSize)
{
Serial.println("Received packet: ");
// 讀取封包
while (LoRa.available()) {
str=str+((char)LoRa.read());
}
Axyz0 = str.substring(0,6);
Axyz1 = str.substring(7,13);
Axyz2 = str.substring(14,20);
Gxyz0 = str.substring(21,27);
Gxyz1 = str.substring(28,34);
Gxyz2 = str.substring(35,41);
Mxyz0 = str.substring(42,48);
Mxyz1 = str.substring(49,55);
Mxyz2 = str.substring(56,62);
Serial.println("Acceleration(g) of X,Y,Z:");
Serial.print(Axyz0);
Serial.print(",");
Serial.print(Axyz1);
Serial.print(",");
Serial.println(Axyz2);
Serial.println("Gyro(degress/s) of X,Y,Z:");
Serial.print(Gxyz0);
Serial.print(",");
Serial.print(Gxyz1);
Serial.print(",");
Serial.println(Gxyz2);
Serial.println("Compass Value of X,Y,Z:");
Serial.print(Mxyz0);
Serial.print(",");
Serial.print(Mxyz1);
Serial.print(",");
Serial.println(Mxyz2);
Serial.print("RSSI: ");
Serial.println(LoRa.packetRssi());
Serial.println();
}
// delay(1000);
}
```
## CJMCU-8128+MPU9250
### Sender
```
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Adafruit_CCS811.h"
#include <BMx280_EnvCalc.h>
#include <sSense-BMx280I2C.h>
#include <Wire.h>
#include <SPI.h>
#include <LoRa.h>
#define SERIAL_SPEED 9600
Adafruit_CCS811 ccs;
BMx280I2C ssenseBMx280;
MPU6050 accelgyro;
I2Cdev I2C_M;
uint8_t buffer_m[6];
int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t mx, my, mz;
float heading;
float tiltheading;
float Axyz[3];
float Gxyz[3];
float Mxyz[3];
#define sample_num_mdate 5000
volatile float mx_sample[3];
volatile float my_sample[3];
volatile float mz_sample[3];
static float mx_centre = 0;
static float my_centre = 0;
static float mz_centre = 0;
volatile int mx_max = 0;
volatile int my_max = 0;
volatile int mz_max = 0;
volatile int mx_min = 0;
volatile int my_min = 0;
volatile int mz_min = 0;
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("LoRa Sender");
if (!LoRa.begin(433E6))
{
Serial.println("Starting LoRa failed!");
while(1);
}
Serial.begin(SERIAL_SPEED);
ccs.begin();
DebugPort.begin(SERIAL_SPEED);
while(!DebugPort) {} // Wait
Wire.begin();
while(!ssenseBMx280.begin())
{
DebugPort.println("Could not find BME280 sensor!");
delay(50);
}
// initialize device
while(!Serial);
accelgyro.initialize();
delay(3000);
Mxyz_init_calibrated();
}
void loop()
{
Serial.println();
if(ccs.available())
{
if(!ccs.readData()){
//Serial.print("CO2(ppm):");
//Serial.print(ccs.geteCO2());
}
else{
Serial.println("ERROR!,ERROR!,");
}
}
printBMx280Data(&DebugPort);
delay(2000);
getAccel_Data();
getGyro_Data();
getCompassDate_calibrated(); // compass data has been calibrated here
getHeading(); //before we use this function we should run 'getCompassDate_calibrated()' frist, so that we can get calibrated data ,then we can get correct angle .
getTiltHeading();
Serial.print("Acceleration(g) of X,Y,Z : ");
Serial.print(Axyz[0]);
Serial.print(" , ");
Serial.print(Axyz[1]);
Serial.print(" , ");
Serial.println(Axyz[2]);
Serial.print("Gyro(degress/s) of X,Y,Z : ");
Serial.print(Gxyz[0]);
Serial.print(" , ");
Serial.print(Gxyz[1]);
Serial.print(" , ");
Serial.println(Gxyz[2]);
Serial.print("Compass Value of X,Y,Z : ");
Serial.print(Mxyz[0]);
Serial.print(" , ");
Serial.print(Mxyz[1]);
Serial.print(" , ");
Serial.println(Mxyz[2]);
}
void getHeading(void) {
heading = 180 * atan2(Mxyz[1], Mxyz[0]) / PI;
if (heading < 0) {
heading += 360;
}
}
void getTiltHeading(void) {
float pitch = asin(-Axyz[0]);
float roll = asin(Axyz[1] / cos(pitch));
float xh = Mxyz[0] * cos(pitch) + Mxyz[2] * sin(pitch);
float yh = Mxyz[0] * sin(roll) * sin(pitch) + Mxyz[1] * cos(roll) - Mxyz[2] * sin(roll) * cos(pitch);
float zh = -Mxyz[0] * cos(roll) * sin(pitch) + Mxyz[1] * sin(roll) + Mxyz[2] * cos(roll) * cos(pitch);
tiltheading = 180 * atan2(yh, xh) / PI;
if (yh < 0) {
tiltheading += 360;
}
}
void Mxyz_init_calibrated() {
get_calibration_Data();
Serial.println(" ");
Serial.println("compass calibration parameter ");
Serial.print(mx_centre);
Serial.print(" ");
Serial.print(my_centre);
Serial.print(" ");
Serial.println(mz_centre);
Serial.println(" ");
}
void get_calibration_Data() {
for (int i = 0; i < sample_num_mdate; i++) {
get_one_sample_date_mxyz();
if (mx_sample[2] >= mx_sample[1]) {
mx_sample[1] = mx_sample[2];
}
if (my_sample[2] >= my_sample[1]) {
my_sample[1] = my_sample[2]; //find max value
}
if (mz_sample[2] >= mz_sample[1]) {
mz_sample[1] = mz_sample[2];
}
if (mx_sample[2] <= mx_sample[0]) {
mx_sample[0] = mx_sample[2];
}
if (my_sample[2] <= my_sample[0]) {
my_sample[0] = my_sample[2]; //find min value
}
if (mz_sample[2] <= mz_sample[0]) {
mz_sample[0] = mz_sample[2];
}
}
mx_max = mx_sample[1];
my_max = my_sample[1];
mz_max = mz_sample[1];
mx_min = mx_sample[0];
my_min = my_sample[0];
mz_min = mz_sample[0];
mx_centre = (mx_max + mx_min) / 2;
my_centre = (my_max + my_min) / 2;
mz_centre = (mz_max + mz_min) / 2;
}
void get_one_sample_date_mxyz() {
getCompass_Data();
mx_sample[2] = Mxyz[0];
my_sample[2] = Mxyz[1];
mz_sample[2] = Mxyz[2];
}
void getAccel_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Axyz[0] = (double) ax / 16384;
Axyz[1] = (double) ay / 16384;
Axyz[2] = (double) az / 16384;
}
void getGyro_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Gxyz[0] = (double) gx * 250 / 32768;
Gxyz[1] = (double) gy * 250 / 32768;
Gxyz[2] = (double) gz * 250 / 32768;
}
void getCompass_Data(void) {
I2C_M.writeByte(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x01); //enable the magnetometer
delay(10);
I2C_M.readBytes(MPU9150_RA_MAG_ADDRESS, MPU9150_RA_MAG_XOUT_L, 6, buffer_m);
mx = ((int16_t)(buffer_m[1]) << 8) | buffer_m[0] ;
my = ((int16_t)(buffer_m[3]) << 8) | buffer_m[2] ;
mz = ((int16_t)(buffer_m[5]) << 8) | buffer_m[4] ;
Mxyz[0] = (double) mx * 1200 / 4096;
Mxyz[1] = (double) my * 1200 / 4096;
Mxyz[2] = (double) mz * 1200 / 4096;
}
void getCompassDate_calibrated() {
getCompass_Data();
Mxyz[0] = Mxyz[0] - mx_centre;
Mxyz[1] = Mxyz[1] - my_centre;
Mxyz[2] = Mxyz[2] - mz_centre;
}
void printBMx280Data( Stream* client )
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
/* client->print(temp);
client->print(",");
client->print(pres);
client->print(",");*/
ssenseBMx280.read(pres, temp, hum, tempUnit, presUnit);
BMx280_EnvCalc::AltitudeUnit envAltUnit = BMx280_EnvCalc::AltitudeUnit_Meters;
BMx280_EnvCalc::TempUnit envTempUnit = BMx280_EnvCalc::TempUnit_Celsius;
float altitude = BMx280_EnvCalc::Altitude(pres, envAltUnit);
Serial.print("Co2 : ");
Serial.print(ccs.geteCO2());
Serial.println(" ppm");
Serial.print("Temp : ");
Serial.print(temp);
Serial.println(" C");
Serial.print("Pres : ");
Serial.print(pres);
Serial.println(" Pa");
Serial.print("Alti : ");
Serial.print(altitude);
Serial.println(" m");
Serial.println();
Serial.println("=============================================");
String msg = String(Axyz[0]+500)+" "+String(Axyz[1]+500)+" "+String(Axyz[2]+500)+" "+String(Gxyz[0]+500)+" "+String(Gxyz[1]+500)+" "+String(Gxyz[2]+500)+" "+String(Mxyz[0]+500)+" "+String(Mxyz[1]+500)+" "+String(Mxyz[2]+500)+" "+String(ccs.geteCO2()+1000)+" "+String(temp)+" "+String(pres)+" "+String(altitude);
Serial.print("Send packet:");
Serial.println(msg);
Serial.println();
LoRa.beginPacket();
LoRa.print(msg);
LoRa.endPacket();
delay(1000);
}
```
### Receiver
```
#include <SPI.h>
#include <LoRa.h>
#include <string.h>
void setup() {
Serial.begin(9600);
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
String str="";
String Axyz0="";
String Axyz1="";
String Axyz2="";
String Gxyz0="";
String Gxyz1="";
String Gxyz2="";
String Mxyz0="";
String Mxyz1="";
String Mxyz2="";
String ccsgeteCO2="";
String temp="";
String pres="";
String altitude="";
int packetSize = LoRa.parsePacket();
if (packetSize)
{
Serial.println("Received packet: ");
Serial.println();
// 讀取封包
while (LoRa.available()) {
str=str+((char)LoRa.read());
}
Axyz0 = str.substring(0,6);
Axyz1 = str.substring(7,13);
Axyz2 = str.substring(14,20);
Gxyz0 = str.substring(21,27);
Gxyz1 = str.substring(28,34);
Gxyz2 = str.substring(35,41);
Mxyz0 = str.substring(42,48);
Mxyz1 = str.substring(49,55);
Mxyz2 = str.substring(56,62);
ccsgeteCO2 = str.substring(63,67);
temp = str.substring(68,73);
pres = str.substring(74,83);
altitude = str.substring(84,89);
Serial.print("Acceleration(g) of X,Y,Z : ");
Serial.print(Axyz0);
Serial.print(" , ");
Serial.print(Axyz1);
Serial.print(" , ");
Serial.println(Axyz2);
Serial.print("Gyro(degress/s) of X,Y,Z : ");
Serial.print(Gxyz0);
Serial.print(" , ");
Serial.print(Gxyz1);
Serial.print(" , ");
Serial.println(Gxyz2);
Serial.print("Compass Value of X,Y,Z : ");
Serial.print(Mxyz0);
Serial.print(" , ");
Serial.print(Mxyz1);
Serial.print(" , ");
Serial.println(Mxyz2);
Serial.println();
Serial.print("Co2 : ");
Serial.print(ccsgeteCO2);
Serial.println(" ppm");
Serial.print("Temp : ");
Serial.print(temp);
Serial.println(" C");
Serial.print("Pres : ");
Serial.print(pres);
Serial.println(" Pa");
Serial.print("Alti : ");
Serial.print(altitude);
Serial.println(" m");
Serial.println();
Serial.print("RSSI : ");
Serial.println(LoRa.packetRssi());
Serial.println("=============================================");
}
// delay(1000);
}
```
### Receiver with PLXDAQ
```
#include <SPI.h>
#include <LoRa.h>
#include <string.h>
void setup() {
Serial.begin(9600);
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println("CLEARSHEET");
Serial.println("LABEL,Time,Timer,Acc X,Acc Y,Acc Z,Gyro X,Gyro Y,Gyro Z,Mag X,Mag Y,Mag Z,Co2(ppm),Temp(c),Pressure(Pa),Altitude(m),RSSI");
}
void loop() {
String str="";
String Axyz0="";
String Axyz1="";
String Axyz2="";
String Gxyz0="";
String Gxyz1="";
String Gxyz2="";
String Mxyz0="";
String Mxyz1="";
String Mxyz2="";
String ccsgeteCO2="";
String temp="";
String pres="";
String altitude="";
int packetSize = LoRa.parsePacket();
if (packetSize)
{
//Serial.println("Received packet: ");
Serial.println();
// 讀取封包
while (LoRa.available()) {
str=str+((char)LoRa.read());
}
Axyz0 = str.substring(0,6);
Axyz1 = str.substring(7,13);
Axyz2 = str.substring(14,20);
Gxyz0 = str.substring(21,27);
Gxyz1 = str.substring(28,34);
Gxyz2 = str.substring(35,41);
Mxyz0 = str.substring(42,48);
Mxyz1 = str.substring(49,55);
Mxyz2 = str.substring(56,62);
ccsgeteCO2 = str.substring(63,67);
temp = str.substring(68,73);
pres = str.substring(74,83);
altitude = str.substring(84,89);
Serial.print("DATA, TIME, TIMER,");
Serial.print(Axyz0);
Serial.print(",");
Serial.print(Axyz1);
Serial.print(",");
Serial.print(Axyz2);
Serial.print(",");
Serial.print(Gxyz0);
Serial.print(",");
Serial.print(Gxyz1);
Serial.print(",");
Serial.print(Gxyz2);
Serial.print(",");
Serial.print(Mxyz0);
Serial.print(",");
Serial.print(Mxyz1);
Serial.print(",");
Serial.print(Mxyz2);
Serial.print(",");
Serial.print(ccsgeteCO2);
Serial.print(",");
Serial.print(temp);
Serial.print(",");
Serial.print(pres);
Serial.print(",");
Serial.print(altitude);
Serial.print(",");
/*
Serial.print("Acceleration(g) of X,Y,Z : ");
Serial.print(Axyz0);
Serial.print(" , ");
Serial.print(Axyz1);
Serial.print(" , ");
Serial.println(Axyz2);
Serial.print("Gyro(degress/s) of X,Y,Z : ");
Serial.print(Gxyz0);
Serial.print(" , ");
Serial.print(Gxyz1);
Serial.print(" , ");
Serial.println(Gxyz2);
Serial.print("Compass Value of X,Y,Z : ");
Serial.print(Mxyz0);
Serial.print(" , ");
Serial.print(Mxyz1);
Serial.print(" , ");
Serial.println(Mxyz2);
Serial.println();
Serial.print("Co2 : ");
Serial.print(ccsgeteCO2);
Serial.println(" ppm");
Serial.print("Temp : ");
Serial.print(temp);
Serial.println(" C");
Serial.print("Pres : ");
Serial.print(pres);
Serial.println(" Pa");
Serial.print("Alti : ");
Serial.print(altitude);
Serial.println(" m");
Serial.println();
Serial.print("RSSI : ");
Serial.println(LoRa.packetRssi());
Serial.println("=============================================");
*/
Serial.print(LoRa.packetRssi());
}
// delay(1000);
}
```
## TX RX
### 接收端
```
void setup() {
Serial.begin(9600); //設定通訊速率
}
void loop() {
while (!Serial.available()) {} //直到暫存器出現訊號才跳出迴圈
Serial.write(Serial.read()); //傳輸讀取的訊號
while (Serial.available()>0) { //如果暫存器有訊號則不斷讀取直到沒有
Serial.read();
}
}
```
### 上段航電(下段上傳尚未成功,其餘傳送地面站OK)
5/22 二氧化碳無讀取(其餘正常)
```
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Adafruit_CCS811.h"
#include <BMx280_EnvCalc.h>
#include <sSense-BMx280I2C.h>
#include <BMP180.h>
#include <Wire.h>
#include <SPI.h>
#include <LoRa.h>
#define SERIAL_SPEED 9600
BMP180 bmp180;
Adafruit_CCS811 ccs;
BMx280I2C ssenseBMx280;
MPU6050 accelgyro;
I2Cdev I2C_M;
uint8_t buffer_m[6];
int16_t ax, ay, az;
int16_t gx, gy, gz;
int16_t mx, my, mz;
float heading;
float tiltheading;
float Axyz[3];
float Gxyz[3];
float Mxyz[3];
#define sample_num_mdate 5000
volatile float mx_sample[3];
volatile float my_sample[3];
volatile float mz_sample[3];
static float mx_centre = 0;
static float my_centre = 0;
static float mz_centre = 0;
volatile int mx_max = 0;
volatile int my_max = 0;
volatile int mz_max = 0;
volatile int mx_min = 0;
volatile int my_min = 0;
volatile int mz_min = 0;
void setup()
{
Wire.begin();
Serial.begin(9600);
Serial.println("LoRa Sender");
if (!LoRa.begin(433E6))
{
Serial.println("Starting LoRa failed!");
while(1);
}
Serial.begin(SERIAL_SPEED);
ccs.begin();
DebugPort.begin(SERIAL_SPEED);
while(!DebugPort) {} // Wait
Wire.begin();
while(!ssenseBMx280.begin())
{
DebugPort.println("Could not find BME280 sensor!");
delay(50);
}
// initialize device
while(!Serial);
accelgyro.initialize();
delay(3000);
Mxyz_init_calibrated();
}
void loop()
{
Serial.println();
if(ccs.available())
{
if(!ccs.readData()){
//Serial.print("CO2(ppm):");
//Serial.print(ccs.geteCO2());
}
else{
Serial.println("ERROR!,ERROR!,");
}
}
printBMx280Data(&DebugPort);
delay(2000);
getAccel_Data();
getGyro_Data();
getCompassDate_calibrated(); // compass data has been calibrated here
getHeading(); //before we use this function we should run 'getCompassDate_calibrated()' frist, so that we can get calibrated data ,then we can get correct angle .
getTiltHeading();
Serial.print("Acceleration(g) of X,Y,Z : ");
Serial.print(Axyz[0]);
Serial.print(" , ");
Serial.print(Axyz[1]);
Serial.print(" , ");
Serial.println(Axyz[2]);
Serial.print("Gyro(degress/s) of X,Y,Z : ");
Serial.print(Gxyz[0]);
Serial.print(" , ");
Serial.print(Gxyz[1]);
Serial.print(" , ");
Serial.println(Gxyz[2]);
Serial.print("Compass Value of X,Y,Z : ");
Serial.print(Mxyz[0]);
Serial.print(" , ");
Serial.print(Mxyz[1]);
Serial.print(" , ");
Serial.println(Mxyz[2]);
}
void getHeading(void) {
heading = 180 * atan2(Mxyz[1], Mxyz[0]) / PI;
if (heading < 0) {
heading += 360;
}
}
void getTiltHeading(void) {
float pitch = asin(-Axyz[0]);
float roll = asin(Axyz[1] / cos(pitch));
float xh = Mxyz[0] * cos(pitch) + Mxyz[2] * sin(pitch);
float yh = Mxyz[0] * sin(roll) * sin(pitch) + Mxyz[1] * cos(roll) - Mxyz[2] * sin(roll) * cos(pitch);
float zh = -Mxyz[0] * cos(roll) * sin(pitch) + Mxyz[1] * sin(roll) + Mxyz[2] * cos(roll) * cos(pitch);
tiltheading = 180 * atan2(yh, xh) / PI;
if (yh < 0) {
tiltheading += 360;
}
}
void Mxyz_init_calibrated() {
get_calibration_Data();
Serial.println(" ");
Serial.println("compass calibration parameter ");
Serial.print(mx_centre);
Serial.print(" ");
Serial.print(my_centre);
Serial.print(" ");
Serial.println(mz_centre);
Serial.println(" ");
}
void get_calibration_Data() {
for (int i = 0; i < sample_num_mdate; i++) {
get_one_sample_date_mxyz();
if (mx_sample[2] >= mx_sample[1]) {
mx_sample[1] = mx_sample[2];
}
if (my_sample[2] >= my_sample[1]) {
my_sample[1] = my_sample[2]; //find max value
}
if (mz_sample[2] >= mz_sample[1]) {
mz_sample[1] = mz_sample[2];
}
if (mx_sample[2] <= mx_sample[0]) {
mx_sample[0] = mx_sample[2];
}
if (my_sample[2] <= my_sample[0]) {
my_sample[0] = my_sample[2]; //find min value
}
if (mz_sample[2] <= mz_sample[0]) {
mz_sample[0] = mz_sample[2];
}
}
mx_max = mx_sample[1];
my_max = my_sample[1];
mz_max = mz_sample[1];
mx_min = mx_sample[0];
my_min = my_sample[0];
mz_min = mz_sample[0];
mx_centre = (mx_max + mx_min) / 2;
my_centre = (my_max + my_min) / 2;
mz_centre = (mz_max + mz_min) / 2;
}
void get_one_sample_date_mxyz() {
getCompass_Data();
mx_sample[2] = Mxyz[0];
my_sample[2] = Mxyz[1];
mz_sample[2] = Mxyz[2];
}
void getAccel_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Axyz[0] = (double) ax / 16384;
Axyz[1] = (double) ay / 16384;
Axyz[2] = (double) az / 16384;
}
void getGyro_Data(void) {
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
Gxyz[0] = (double) gx * 250 / 32768;
Gxyz[1] = (double) gy * 250 / 32768;
Gxyz[2] = (double) gz * 250 / 32768;
}
void getCompass_Data(void) {
I2C_M.writeByte(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x01); //enable the magnetometer
delay(10);
I2C_M.readBytes(MPU9150_RA_MAG_ADDRESS, MPU9150_RA_MAG_XOUT_L, 6, buffer_m);
mx = ((int16_t)(buffer_m[1]) << 8) | buffer_m[0] ;
my = ((int16_t)(buffer_m[3]) << 8) | buffer_m[2] ;
mz = ((int16_t)(buffer_m[5]) << 8) | buffer_m[4] ;
Mxyz[0] = (double) mx * 1200 / 4096;
Mxyz[1] = (double) my * 1200 / 4096;
Mxyz[2] = (double) mz * 1200 / 4096;
}
void getCompassDate_calibrated() {
getCompass_Data();
Mxyz[0] = Mxyz[0] - mx_centre;
Mxyz[1] = Mxyz[1] - my_centre;
Mxyz[2] = Mxyz[2] - mz_centre;
}
void printBMx280Data( Stream* client )
{
float temp(NAN), hum(NAN), pres(NAN);
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
/* client->print(temp);
client->print(",");
client->print(pres);
client->print(",");*/
ssenseBMx280.read(pres, temp, hum, tempUnit, presUnit);
BMx280_EnvCalc::AltitudeUnit envAltUnit = BMx280_EnvCalc::AltitudeUnit_Meters;
BMx280_EnvCalc::TempUnit envTempUnit = BMx280_EnvCalc::TempUnit_Celsius;
float altitude = BMx280_EnvCalc::Altitude(pres, envAltUnit);
Serial.print("Co2 : ");
Serial.print(ccs.geteCO2());
Serial.println(" ppm");
Serial.print("Temp : ");
Serial.print(temp);
Serial.println(" C");
Serial.print("Pres : ");
Serial.print(pres);
Serial.println(" Pa");
Serial.print("Alti : ");
Serial.print(altitude);
Serial.println(" m");
Serial.println();
while (!Serial.available()) {} //直到暫存器出現訊號才跳出迴圈
Serial.write(Serial.read()); //傳輸讀取的訊號
while (Serial.available()>0) { //如果暫存器有訊號則不斷讀取直到沒有
Serial.read();
}
Serial.println("=============================================");
String msg = String(Axyz[0]+500)+" "+String(Axyz[1]+500)+" "+String(Axyz[2]+500)+" "+String(Gxyz[0]+500)+" "+String(Gxyz[1]+500)+" "+String(Gxyz[2]+500)+" "+String(Mxyz[0]+500)+" "+String(Mxyz[1]+500)+" "+String(Mxyz[2]+500)+" "+String(ccs.geteCO2()+1000)+" "+String(temp)+" "+String(pres)+" "+String(altitude)+" "+String(bmp180.getTemperature());
Serial.print("Send packet:");
Serial.println(msg);
Serial.println();
LoRa.beginPacket();
LoRa.print(msg);
LoRa.endPacket();
delay(1000);
}
```
### 下段航電(BMP180測試中)
*上傳上段尚未成功
```
#include <Wire.h>
#include <BMP180.h>
BMP180 bmp180;
void setup()
{
// init
bmp180.init();
// welcome
Serial.begin(9600);
Serial.println("BMP180 Demo");
if (!bmp180.hasValidID())
Serial.println("Error - please check the BMP180 board!");
}
void loop() {
Serial.print("Temp2: ");
Serial.print(bmp180.getTemperature());
Serial.println(" C");
delay(1000);
}
```
### 地面站
運作ok(下段航電上傳還沒成功,未能讀取下段資料)
```
#include <SPI.h>
#include <LoRa.h>
#include <string.h>
void setup() {
Serial.begin(9600);
Serial.println("LoRa Receiver");
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println("CLEARSHEET");
Serial.println("LABEL,Time,Timer,Acc X,Acc Y,Acc Z,Gyro X,Gyro Y,Gyro Z,Mag X,Mag Y,Mag Z,Co2(ppm),Temp(c),Pressure(Pa),Altitude(m),Temp2(c),RSSI");
}
void loop() {
String str="";
String Axyz0="";
String Axyz1="";
String Axyz2="";
String Gxyz0="";
String Gxyz1="";
String Gxyz2="";
String Mxyz0="";
String Mxyz1="";
String Mxyz2="";
String ccsgeteCO2="";
String temp="";
String pres="";
String altitude="";
String temp2="";
int packetSize = LoRa.parsePacket();
if (packetSize)
{
//Serial.println("Received packet: ");
Serial.println();
// 讀取封包
while (LoRa.available()) {
str=str+((char)LoRa.read());
}
Axyz0 = str.substring(0,6);
Axyz1 = str.substring(7,13);
Axyz2 = str.substring(14,20);
Gxyz0 = str.substring(21,27);
Gxyz1 = str.substring(28,34);
Gxyz2 = str.substring(35,41);
Mxyz0 = str.substring(42,48);
Mxyz1 = str.substring(49,55);
Mxyz2 = str.substring(56,62);
ccsgeteCO2 = str.substring(63,67);
temp = str.substring(68,73);
pres = str.substring(74,83);
altitude = str.substring(84,89);
temp2 = str.substring(90,94);
Serial.print("DATA, TIME, TIMER,");
Serial.print(Axyz0);
Serial.print(",");
Serial.print(Axyz1);
Serial.print(",");
Serial.print(Axyz2);
Serial.print(",");
Serial.print(Gxyz0);
Serial.print(",");
Serial.print(Gxyz1);
Serial.print(",");
Serial.print(Gxyz2);
Serial.print(",");
Serial.print(Mxyz0);
Serial.print(",");
Serial.print(Mxyz1);
Serial.print(",");
Serial.print(Mxyz2);
Serial.print(",");
Serial.print(ccsgeteCO2);
Serial.print(",");
Serial.print(temp);
Serial.print(",");
Serial.print(pres);
Serial.print(",");
Serial.print(altitude);
Serial.print(",");
Serial.print(temp2);
Serial.print(",");
/*
Serial.print("Acceleration(g) of X,Y,Z : ");
Serial.print(Axyz0);
Serial.print(" , ");
Serial.print(Axyz1);
Serial.print(" , ");
Serial.println(Axyz2);
Serial.print("Gyro(degress/s) of X,Y,Z : ");
Serial.print(Gxyz0);
Serial.print(" , ");
Serial.print(Gxyz1);
Serial.print(" , ");
Serial.println(Gxyz2);
Serial.print("Compass Value of X,Y,Z : ");
Serial.print(Mxyz0);
Serial.print(" , ");
Serial.print(Mxyz1);
Serial.print(" , ");
Serial.println(Mxyz2);
Serial.println();
Serial.print("Co2 : ");
Serial.print(ccsgeteCO2);
Serial.println(" ppm");
Serial.print("Temp : ");
Serial.print(temp);
Serial.println(" C");
Serial.print("Pres : ");
Serial.print(pres);
Serial.println(" Pa");
Serial.print("Alti : ");
Serial.print(altitude);
Serial.println(" m");
Serial.println();
Serial.print("RSSI : ");
Serial.println(LoRa.packetRssi());
Serial.println("=============================================");
*/
Serial.print(LoRa.packetRssi());
}
// delay(1000);
}
```
## Servo控制
測試功能
```
#include <Servo.h>
Servo servo; // servo object representing the MG 996R servo
void setup() {
servo.attach(3); // servo is wired to Arduino on digital pin 3
}
void loop() {
servo.write(0); // move MG996R's shaft to angle 0°
delay(3000); // wait for one second
servo.write(90); // move MG996R's shaft to angle 90°
delay(3000); // wait for one second
servo.write(180); // move MG996R's shaft to angle 180°
delay(3000); // wait for one second
}
```
5/29: 0是OFF;1是ON(開閥關閥)*還沒試過
```
#include <Servo.h>
Servo servo; // 代表 MG996R 伺服馬達的 servo 物件
int servoPin = 3; // 伺服馬達連接至 Arduino 的數位腳位
void setup() {
servo.attach(servoPin);
}
void loop() {
int input = readInput(); // 讀取使用者輸入的數值
if (input == 1) {
servo.write(90); // 將 MG996R 伺服馬達的角度設定為 90°
} else if (input == 0) {
servo.write(0); // 將 MG996R 伺服馬達的角度設定為 0°
}
delay(100); // 延遲一段時間等待馬達轉動到指定角度
}
int readInput() {
while (true) {
if (Serial.available() > 0) {
int value = Serial.parseInt();
// 消耗掉 Serial 緩衝區中的所有字符
while (Serial.available() > 0) {
Serial.read();
}
return value;
}
}
}
```
## Pressure Sensor
https://www.youtube.com/watch?v=UrqPxwsPWGk&t=153s&ab_channel=OvensGarage
```
/* This example demonstrates how to take a standard 3-wire pressure transducer
* and read the analog signal, then convert the signal to a readable output and
* display it onto an LCD screen.
*
* Contact Tyler at tylerovens@me.com if you have any questions
*/
const int pressureInput = A0; //select the analog input pin for the pressure transducer
const int pressureZero = 102.4; //analog reading of pressure transducer at 0psi
const int pressureMax = 921.6; //analog reading of pressure transducer at 100psi
const int pressuretransducermaxPSI = 100; //psi value of transducer being used
const int baudRate = 9600; //constant integer to set the baud rate for serial monitor
const int sensorreadDelay = 250; //constant integer to set the sensor read delay in milliseconds
float pressureValue = 0; //variable to store the value coming from the pressure transducer
void setup() //setup routine, runs once when system turned on or reset
{
Serial.begin(baudRate); //initializes serial communication at set baud rate bits per second
}
void loop() //loop routine runs over and over again forever
{
pressureValue = analogRead(pressureInput); //reads value from input pin and assigns to variable
pressureValue = ((pressureValue-pressureZero)*pressuretransducermaxPSI)/(pressureMax-pressureZero); //conversion equation to convert analog reading to psi
Serial.print(pressureValue, 1); //prints value from previous line to serial
Serial.println("psi"); //prints label to serial
delay(sensorreadDelay); //delay in milliseconds between read values
}
```
*5/28 數值讀取不穩定、吹氣測試數值變低,且後維持在降低後的範圍。