环境
微控制器:ESP-32
传感器:LSM9DS1
IDE:Arduino1.8.9
云服务器:阿里云
协议:MQTT简介
功能:上传采集的螺旋仪信息,用于姿态检测
源码
这只是开发过程中的一次测试文件,感兴趣的可以进一步交流
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "DFRobot_Aliyun.h"
#include "Tone32.h"
#include <Wire.h>
#include <SPI.h>
#include <SparkFunLSM9DS1.h>
#include<cJSON.h>
LSM9DS1 imu;
#define PRINT_CALCULATED
#define PRINT_SPEED 250 // 250 ms between prints
static unsigned long lastPrint = 0; // Keep track of print time
#define DECLINATION -8.58 // Declination (degrees) in Boulder, CO.
const char* WIFI_SSID = "hhh";
const char* WIFI_PASSWORD = "888333111";
String ProductKey = "a1RLLmHnGhG";
String ClientId = "1";
String DeviceName = "taJza41qu4zF0SHu8Lr6";
String DeviceSecret = "27e1e25c4a0ce409f3929166e99c3fa3";
String ALIYUN_SERVER = "iot-as-mqtt.cn-shanghai.aliyuncs.com";
uint16_t PORT = 1883;
String Identifier = "GestureDetect";
const char* subTopic = "/sys/a1RLLmHnGhG/taJza41qu4zF0SHu8Lr6/thing/event/${tsl.event.identifer}/post_reply";//****set
const char* pubTopic = "/sys/a1RLLmHnGhG/taJza41qu4zF0SHu8Lr6/thing/event/property/post";//******post
//------------------------------------------传感器参数(全局变量)
int BUTTON_PIN = 1;
int irValue=random(65,75);
int beatsPerMinute=random(68,72);
int beatAvg=random(69,71);
int Latitude=34.1436;
int Longitude=108.5837;
//-------------------------------------------
DFRobot_Aliyun myAliyun;
WiFiClient espClient;
PubSubClient client(espClient);
void connectWiFi() {
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP Adderss: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int len) {
Serial.print("Recevice [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < len; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
}
void ConnectAliyun() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
/*根据自动计算的用户名和密码连接到Alinyun的设备,不需要更改*/
if (client.connect(myAliyun.client_id, myAliyun.username, myAliyun.password)) {
Serial.println("connected");
}
else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
char* createJSON(int id, int heading, int pitch, int roll,int irValue,int beatsPerMinute,int beatAvg,double Latitude,double Longitude) {
char* jsonStr = NULL;
cJSON* root = cJSON_CreateObject();
cJSON_AddItemToObject(root, "id", cJSON_CreateNumber(id)); //添加id数据
cJSON_AddItemToObject(root, "method", cJSON_CreateString("thing.event.property.post"));
cJSON * params = cJSON_CreateObject();
cJSON_AddItemToObject(params, "heading", cJSON_CreateNumber(heading)); //添加heading
cJSON_AddItemToObject(params, "pitch", cJSON_CreateNumber(pitch)); //添加pitch
cJSON_AddItemToObject(params, "roll", cJSON_CreateNumber(roll)); //添加roll
cJSON_AddItemToObject(params, "irValue", cJSON_CreateNumber(irValue));
cJSON_AddItemToObject(params, "beatsPerMinute", cJSON_CreateNumber(beatsPerMinute));
cJSON_AddItemToObject(params, "beatAvg", cJSON_CreateNumber(beatAvg));
cJSON_AddItemToObject(params, "Latitude", cJSON_CreateNumber(Latitude));
cJSON_AddItemToObject(params, "Longitude", cJSON_CreateNumber(Longitude));
cJSON_AddItemToObject(root, "params", params); //添加params
jsonStr = cJSON_Print(root);
cJSON_Delete(root);
return jsonStr;
}
void printGyro()
{
// Now we can use the gx, gy, and gz variables as we please.
// Either print them as raw ADC values, or calculated in DPS.
Serial.print("G: ");
#ifdef PRINT_CALCULATED
// If you want to print calculated values, you can use the
// calcGyro helper function to convert a raw ADC value to
// DPS. Give the function the value that you want to convert.
Serial.print(imu.calcGyro(imu.gx), 2);
Serial.print(", ");
Serial.print(imu.calcGyro(imu.gy), 2);
Serial.print(", ");
Serial.print(imu.calcGyro(imu.gz), 2);
Serial.println(" deg/s");
#elif defined PRINT_RAW
Serial.print(imu.gx);
Serial.print(", ");
Serial.print(imu.gy);
Serial.print(", ");
Serial.println(imu.gz);
#endif
}
void printAccel()
{
// Now we can use the ax, ay, and az variables as we please.
// Either print them as raw ADC values, or calculated in g's.
Serial.print("A: ");
#ifdef PRINT_CALCULATED
// If you want to print calculated values, you can use the
// calcAccel helper function to convert a raw ADC value to
// g's. Give the function the value that you want to convert.
Serial.print(imu.calcAccel(imu.ax), 2);
Serial.print(", ");
Serial.print(imu.calcAccel(imu.ay), 2);
Serial.print(", ");
Serial.print(imu.calcAccel(imu.az), 2);
Serial.println(" g");
#elif defined PRINT_RAW
Serial.print(imu.ax);
Serial.print(", ");
Serial.print(imu.ay);
Serial.print(", ");
Serial.println(imu.az);
#endif
}
void printMag()
{
// Now we can use the mx, my, and mz variables as we please.
// Either print them as raw ADC values, or calculated in Gauss.
Serial.print("M: ");
#ifdef PRINT_CALCULATED
// If you want to print calculated values, you can use the
// calcMag helper function to convert a raw ADC value to
// Gauss. Give the function the value that you want to convert.
Serial.print(imu.calcMag(imu.mx), 2);
Serial.print(", ");
Serial.print(imu.calcMag(imu.my), 2);
Serial.print(", ");
Serial.print(imu.calcMag(imu.mz), 2);
Serial.println(" gauss");
#elif defined PRINT_RAW
Serial.print(imu.mx);
Serial.print(", ");
Serial.print(imu.my);
Serial.print(", ");
Serial.println(imu.mz);
#endif
}
void printAttitude(float ax, float ay, float az, float mx, float my, float mz)
{
float roll = atan2(ay, az);
float pitch = atan2(-ax, sqrt(ay * ay + az * az));
float heading;
if (my == 0)
heading = (mx < 0) ? PI : 0;
else
heading = atan2(mx, my);
heading -= DECLINATION * PI / 180;
if (heading > PI) heading -= (2 * PI);
else if (heading < -PI) heading += (2 * PI);
// Convert everything from radians to degrees:
heading *= 180.0 / PI;
pitch *= 180.0 / PI;
roll *= 180.0 / PI;
int irValue=random(65,75);
int beatsPerMinute=random(68,72);
int beatAvg=random(69,71);
Serial.print("Pitch, Roll: ");
Serial.print(pitch, 2);
Serial.print(", ");
Serial.println(roll, 2);
Serial.print("Heading: "); Serial.println(heading, 2);
client.publish(pubTopic, createJSON(1, heading,pitch,roll,irValue,beatsPerMinute,beatAvg,Latitude,Longitude));
}
void setup()
{
Serial.begin(115200);
Wire.begin(21, 22);
connectWiFi();
myAliyun.init(ALIYUN_SERVER, ProductKey, ClientId, DeviceName, DeviceSecret);
client.setServer(myAliyun.mqtt_server, PORT);
client.setCallback(callback);
ConnectAliyun();
if (imu.begin() == false) // with no arguments, this uses default addresses (AG:0x6B, M:0x1E) and i2c port (Wire).
{
Serial.println("Failed to communicate with LSM9DS1.");
Serial.println("Double-check wiring.");
Serial.println("Default settings in this sketch will " \
"work for an out of the box LSM9DS1 " \
"Breakout, but may need to be modified " \
"if the board jumpers are.");
while (1);
}
}
void loop()
{
if (imu.gyroAvailable())
{
imu.readGyro();
}
if (imu.accelAvailable())
{
imu.readAccel();
}
if (imu.magAvailable())
{
imu.readMag();
}
if ((lastPrint + PRINT_SPEED) < millis())
{
printGyro(); // Print "G: gx, gy, gz"
printAccel(); // Print "A: ax, ay, az"
printMag(); // Print "M: mx, my, mz"
printAttitude(imu.ax, imu.ay, imu.az,
-imu.my, -imu.mx, imu.mz);
Serial.println();
lastPrint = millis(); // Update lastPrint time
}
if (BUTTON_PIN == 1) {
/*上报按钮的状态*/
client.publish(pubTopic, ("{\"id\":" + ClientId + ",\"params\":{\"" + Identifier + "\":1},\"method\":\"thing.event.property.post\"}").c_str());
delay(1000);
}
else {
}
client.loop();
}